diff options
| -rw-r--r-- | src/stage1/all_types.hpp | 17 | ||||
| -rw-r--r-- | src/stage1/analyze.cpp | 49 | ||||
| -rw-r--r-- | src/stage1/ir.cpp | 99 | ||||
| -rw-r--r-- | src/stage1/ir_print.cpp | 19 |
4 files changed, 183 insertions, 1 deletions
diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index e0cbf1c0c5..b1d0bd2ce1 100644 --- a/src/stage1/all_types.hpp +++ b/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; diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index a4e368288e..d46faac2f0 100644 --- a/src/stage1/analyze.cpp +++ b/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: diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index ad45d7682c..16536dc71f 100644 --- a/src/stage1/ir.cpp +++ b/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; diff --git a/src/stage1/ir_print.cpp b/src/stage1/ir_print.cpp index cdbada4f20..22b6c1ed5f 100644 --- a/src/stage1/ir_print.cpp +++ b/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; |
