Commit 5e5b35f107
Changed files (4)
src/stage1/all_types.hpp
@@ -391,6 +391,8 @@ enum LazyValueId {
LazyValueIdAlignOf,
LazyValueIdSizeOf,
LazyValueIdPtrType,
+ LazyValueIdPtrTypeSimple,
+ LazyValueIdPtrTypeSimpleConst,
LazyValueIdOptType,
LazyValueIdSliceType,
LazyValueIdFnType,
@@ -467,6 +469,13 @@ struct LazyValuePtrType {
bool is_allowzero;
};
+struct LazyValuePtrTypeSimple {
+ LazyValue base;
+
+ IrAnalyze *ira;
+ IrInstGen *elem_type;
+};
+
struct LazyValueOptType {
LazyValue base;
@@ -2625,6 +2634,8 @@ enum IrInstSrcId {
IrInstSrcIdHasField,
IrInstSrcIdSetEvalBranchQuota,
IrInstSrcIdPtrType,
+ IrInstSrcIdPtrTypeSimple,
+ IrInstSrcIdPtrTypeSimpleConst,
IrInstSrcIdAlignCast,
IrInstSrcIdImplicitCast,
IrInstSrcIdResolveResult,
@@ -3296,6 +3307,12 @@ struct IrInstSrcArrayType {
IrInstSrc *child_type;
};
+struct IrInstSrcPtrTypeSimple {
+ IrInstSrc base;
+
+ IrInstSrc *child_type;
+};
+
struct IrInstSrcPtrType {
IrInstSrc base;
src/stage1/analyze.cpp
@@ -1237,6 +1237,22 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
parent_type_val, is_zero_bits);
}
}
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst: {
+ LazyValuePtrTypeSimple *lazy_ptr_type = reinterpret_cast<LazyValuePtrTypeSimple *>(type_val->data.x_lazy);
+
+ if (parent_type_val == lazy_ptr_type->elem_type->value) {
+ // Does a struct which contains a pointer field to itself have bits? Yes.
+ *is_zero_bits = false;
+ return ErrorNone;
+ } else {
+ if (parent_type_val == nullptr) {
+ parent_type_val = type_val;
+ }
+ return type_val_resolve_zero_bits(g, lazy_ptr_type->elem_type->value, parent_type,
+ parent_type_val, is_zero_bits);
+ }
+ }
case LazyValueIdArrayType: {
LazyValueArrayType *lazy_array_type =
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
@@ -1285,6 +1301,8 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o
zig_unreachable();
case LazyValueIdSliceType:
case LazyValueIdPtrType:
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst:
case LazyValueIdFnType:
case LazyValueIdOptType:
case LazyValueIdErrUnionType:
@@ -1313,6 +1331,11 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type->value);
}
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst: {
+ LazyValuePtrTypeSimple *lazy_ptr_type = reinterpret_cast<LazyValuePtrTypeSimple *>(type_val->data.x_lazy);
+ return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type->value);
+ }
case LazyValueIdOptType: {
LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
return type_val_resolve_requires_comptime(g, lazy_opt_type->payload_type->value);
@@ -1413,6 +1436,24 @@ start_over:
}
return ErrorNone;
}
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst: {
+ LazyValuePtrTypeSimple *lazy_ptr_type = reinterpret_cast<LazyValuePtrTypeSimple *>(type_val->data.x_lazy);
+ bool is_zero_bits;
+ if ((err = type_val_resolve_zero_bits(g, lazy_ptr_type->elem_type->value, nullptr,
+ nullptr, &is_zero_bits)))
+ {
+ return err;
+ }
+ if (is_zero_bits) {
+ *abi_size = 0;
+ *size_in_bits = 0;
+ } else {
+ *abi_size = g->builtin_types.entry_usize->abi_size;
+ *size_in_bits = g->builtin_types.entry_usize->size_in_bits;
+ }
+ return ErrorNone;
+ }
case LazyValueIdFnType:
*abi_size = g->builtin_types.entry_usize->abi_size;
*size_in_bits = g->builtin_types.entry_usize->size_in_bits;
@@ -1449,6 +1490,8 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
zig_unreachable();
case LazyValueIdSliceType:
case LazyValueIdPtrType:
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst:
case LazyValueIdFnType:
*abi_align = g->builtin_types.entry_usize->abi_align;
return ErrorNone;
@@ -1506,7 +1549,9 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
return OnePossibleValueYes;
return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
}
- case LazyValueIdPtrType: {
+ case LazyValueIdPtrType:
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst: {
Error err;
bool zero_bits;
if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, nullptr, &zero_bits))) {
@@ -5758,6 +5803,8 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
case LazyValueIdAlignOf:
case LazyValueIdSizeOf:
case LazyValueIdPtrType:
+ case LazyValueIdPtrTypeSimple:
+ case LazyValueIdPtrTypeSimpleConst:
case LazyValueIdOptType:
case LazyValueIdSliceType:
case LazyValueIdFnType:
src/stage1/ir.cpp
@@ -487,6 +487,9 @@ static void destroy_instruction_src(IrInstSrc *inst) {
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst));
case IrInstSrcIdPtrType:
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst));
+ case IrInstSrcIdPtrTypeSimple:
+ case IrInstSrcIdPtrTypeSimpleConst:
+ return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrTypeSimple *>(inst));
case IrInstSrcIdDeclRef:
return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst));
case IrInstSrcIdPanic:
@@ -2609,11 +2612,35 @@ static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicB
return &inst->base;
}
+static IrInstSrc *ir_build_ptr_type_simple(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
+ IrInstSrc *child_type, bool is_const)
+{
+ IrInstSrcPtrTypeSimple *inst = heap::c_allocator.create<IrInstSrcPtrTypeSimple>();
+ inst->base.id = is_const ? IrInstSrcIdPtrTypeSimpleConst : IrInstSrcIdPtrTypeSimple;
+ inst->base.base.scope = scope;
+ inst->base.base.source_node = source_node;
+ inst->base.base.debug_id = exec_next_debug_id(irb->exec);
+ inst->base.owner_bb = irb->current_basic_block;
+ ir_instruction_append(irb->current_basic_block, &inst->base);
+
+ inst->child_type = child_type;
+
+ ir_ref_instruction(child_type, irb->current_basic_block);
+
+ return &inst->base;
+}
+
static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
IrInstSrc *sentinel, IrInstSrc *align_value,
uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero)
{
+ if (!is_volatile && ptr_len == PtrLenSingle && sentinel == nullptr && align_value == nullptr &&
+ bit_offset_start == 0 && host_int_bytes == 0 && is_allow_zero == 0)
+ {
+ return ir_build_ptr_type_simple(irb, scope, source_node, child_type, is_const);
+ }
+
IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node);
inst->sentinel = sentinel;
inst->align_value = align_value;
@@ -30878,6 +30905,24 @@ static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtr
return ir_build_ptr_to_int_gen(ira, &instruction->base.base, target);
}
+static IrInstGen *ir_analyze_instruction_ptr_type_simple(IrAnalyze *ira,
+ IrInstSrcPtrTypeSimple *instruction, bool is_const)
+{
+ IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
+ result->value->special = ConstValSpecialLazy;
+
+ LazyValuePtrTypeSimple *lazy_ptr_type = heap::c_allocator.create<LazyValuePtrTypeSimple>();
+ lazy_ptr_type->ira = ira; ira_ref(ira);
+ result->value->data.x_lazy = &lazy_ptr_type->base;
+ lazy_ptr_type->base.id = is_const ? LazyValueIdPtrTypeSimpleConst : LazyValueIdPtrTypeSimple;
+
+ lazy_ptr_type->elem_type = instruction->child_type->child;
+ if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
+ return result;
+}
+
static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrType *instruction) {
IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type);
result->value->special = ConstValSpecialLazy;
@@ -32384,6 +32429,10 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction);
case IrInstSrcIdPtrType:
return ir_analyze_instruction_ptr_type(ira, (IrInstSrcPtrType *)instruction);
+ case IrInstSrcIdPtrTypeSimple:
+ return ir_analyze_instruction_ptr_type_simple(ira, (IrInstSrcPtrTypeSimple *)instruction, false);
+ case IrInstSrcIdPtrTypeSimpleConst:
+ return ir_analyze_instruction_ptr_type_simple(ira, (IrInstSrcPtrTypeSimple *)instruction, true);
case IrInstSrcIdAlignCast:
return ir_analyze_instruction_align_cast(ira, (IrInstSrcAlignCast *)instruction);
case IrInstSrcIdImplicitCast:
@@ -32757,6 +32806,8 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
case IrInstSrcIdPanic:
case IrInstSrcIdSetEvalBranchQuota:
case IrInstSrcIdPtrType:
+ case IrInstSrcIdPtrTypeSimple:
+ case IrInstSrcIdPtrTypeSimpleConst:
case IrInstSrcIdSetAlignStack:
case IrInstSrcIdExport:
case IrInstSrcIdExtern:
@@ -33264,6 +33315,54 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
// We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
return ErrorNone;
}
+ case LazyValueIdPtrTypeSimple: {
+ LazyValuePtrTypeSimple *lazy_ptr_type = reinterpret_cast<LazyValuePtrTypeSimple *>(val->data.x_lazy);
+ IrAnalyze *ira = lazy_ptr_type->ira;
+
+ ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type);
+ if (type_is_invalid(elem_type))
+ return ErrorSemanticAnalyzeFail;
+
+ if (elem_type->id == ZigTypeIdUnreachable) {
+ ir_add_error(ira, &lazy_ptr_type->elem_type->base,
+ buf_create_from_str("pointer to noreturn not allowed"));
+ return ErrorSemanticAnalyzeFail;
+ }
+
+ assert(val->type->id == ZigTypeIdMetaType);
+ val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
+ false, false, PtrLenSingle, 0,
+ 0, 0,
+ false, VECTOR_INDEX_NONE, nullptr, nullptr);
+ val->special = ConstValSpecialStatic;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
+ return ErrorNone;
+ }
+ case LazyValueIdPtrTypeSimpleConst: {
+ LazyValuePtrTypeSimple *lazy_ptr_type = reinterpret_cast<LazyValuePtrTypeSimple *>(val->data.x_lazy);
+ IrAnalyze *ira = lazy_ptr_type->ira;
+
+ ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type);
+ if (type_is_invalid(elem_type))
+ return ErrorSemanticAnalyzeFail;
+
+ if (elem_type->id == ZigTypeIdUnreachable) {
+ ir_add_error(ira, &lazy_ptr_type->elem_type->base,
+ buf_create_from_str("pointer to noreturn not allowed"));
+ return ErrorSemanticAnalyzeFail;
+ }
+
+ assert(val->type->id == ZigTypeIdMetaType);
+ val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
+ true, false, PtrLenSingle, 0,
+ 0, 0,
+ false, VECTOR_INDEX_NONE, nullptr, nullptr);
+ val->special = ConstValSpecialStatic;
+
+ // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
+ return ErrorNone;
+ }
case LazyValueIdArrayType: {
LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(val->data.x_lazy);
IrAnalyze *ira = lazy_array_type->ira;
src/stage1/ir_print.cpp
@@ -300,6 +300,10 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
return "SrcSetEvalBranchQuota";
case IrInstSrcIdPtrType:
return "SrcPtrType";
+ case IrInstSrcIdPtrTypeSimple:
+ return "SrcPtrTypeSimple";
+ case IrInstSrcIdPtrTypeSimpleConst:
+ return "SrcPtrTypeSimpleConst";
case IrInstSrcIdAlignCast:
return "SrcAlignCast";
case IrInstSrcIdImplicitCast:
@@ -2245,6 +2249,15 @@ static void ir_print_ptr_type(IrPrintSrc *irp, IrInstSrcPtrType *instruction) {
ir_print_other_inst_src(irp, instruction->child_type);
}
+static void ir_print_ptr_type_simple(IrPrintSrc *irp, IrInstSrcPtrTypeSimple *instruction,
+ bool is_const)
+{
+ fprintf(irp->f, "&");
+ const char *const_str = is_const ? "const " : "";
+ fprintf(irp->f, "*%s", const_str);
+ ir_print_other_inst_src(irp, instruction->child_type);
+}
+
static void ir_print_decl_ref(IrPrintSrc *irp, IrInstSrcDeclRef *instruction) {
const char *ptr_str = (instruction->lval != LValNone) ? "ptr " : "";
fprintf(irp->f, "declref %s%s", ptr_str, buf_ptr(instruction->tld->name));
@@ -2917,6 +2930,12 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
case IrInstSrcIdPtrType:
ir_print_ptr_type(irp, (IrInstSrcPtrType *)instruction);
break;
+ case IrInstSrcIdPtrTypeSimple:
+ ir_print_ptr_type_simple(irp, (IrInstSrcPtrTypeSimple *)instruction, false);
+ break;
+ case IrInstSrcIdPtrTypeSimpleConst:
+ ir_print_ptr_type_simple(irp, (IrInstSrcPtrTypeSimple *)instruction, true);
+ break;
case IrInstSrcIdDeclRef:
ir_print_decl_ref(irp, (IrInstSrcDeclRef *)instruction);
break;