diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-04-01 17:46:31 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-04-02 18:31:18 -0400 |
| commit | d3f2fe2cef7de1173a038365f91e8a574a08f21a (patch) | |
| tree | 51c8833d1ebcc92460fb1ee2eb3b05060fc97f4d /src | |
| parent | 3dc8448680cfea2b55a6064c655e400e31e5d3dd (diff) | |
| download | zig-d3f2fe2cef7de1173a038365f91e8a574a08f21a.tar.gz zig-d3f2fe2cef7de1173a038365f91e8a574a08f21a.zip | |
remove the lazy value stuff
let's try to keep this branch to solving one problem at a time
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 43 | ||||
| -rw-r--r-- | src/analyze.cpp | 271 | ||||
| -rw-r--r-- | src/analyze.hpp | 2 | ||||
| -rw-r--r-- | src/codegen.cpp | 6 | ||||
| -rw-r--r-- | src/ir.cpp | 436 | ||||
| -rw-r--r-- | src/ir.hpp | 3 |
6 files changed, 196 insertions, 565 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index b61a0ba520..5d06f7e883 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -256,7 +256,6 @@ enum ConstValSpecial { ConstValSpecialRuntime, ConstValSpecialStatic, ConstValSpecialUndef, - ConstValSpecialLazy, }; enum RuntimeHintErrorUnion { @@ -292,43 +291,6 @@ struct ConstGlobalRefs { LLVMValueRef llvm_global; }; -enum LazyValueId { - LazyValueIdInvalid, - LazyValueIdAlignOf, - LazyValueIdSliceType, - LazyValueIdFnType, -}; - -struct LazyValue { - LazyValueId id; - IrExecutable *exec; -}; - -struct LazyValueAlignOf { - LazyValue base; - ZigType *target_type; -}; - -struct LazyValueSliceType { - LazyValue base; - ZigType *elem_type; - ConstExprValue *align_val; // can be null - bool is_const; - bool is_volatile; - bool is_allowzero; -}; - -struct LazyValueFnType { - LazyValue base; - AstNode *proto_node; - ConstExprValue **param_types; - ConstExprValue *align_val; // can be null - ConstExprValue *return_type; - ConstExprValue *async_allocator_type; - bool is_generic; - bool is_var_args; -}; - struct ConstExprValue { ZigType *type; ConstValSpecial special; @@ -356,7 +318,6 @@ struct ConstExprValue { ConstPtrValue x_ptr; ConstArgTuple x_arg_tuple; Buf *x_enum_literal; - LazyValue *x_lazy; // populated if special == ConstValSpecialRuntime RuntimeHintErrorUnion rh_error_union; @@ -398,7 +359,6 @@ enum TldResolution { TldResolutionUnresolved, TldResolutionResolving, TldResolutionInvalid, - TldResolutionOkLazy, TldResolutionOk, }; @@ -1104,8 +1064,7 @@ struct ZigTypeArray { struct TypeStructField { Buf *name; - ZigType *type_entry; // available after ResolveStatusSizeKnown - ConstExprValue *type_val; // available after ResolveStatusZeroBitsKnown + ZigType *type_entry; size_t src_index; size_t gen_index; size_t offset; // byte offset from beginning of struct diff --git a/src/analyze.cpp b/src/analyze.cpp index 811d1a1c02..0f1767c76d 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -902,10 +902,10 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { } buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); + // The fn_type is a pointer; not to be confused with the raw function type. fn_type->size_in_bits = g->builtin_types.entry_usize->size_in_bits; fn_type->abi_size = g->builtin_types.entry_usize->abi_size; - // see also type_val_resolve_abi_align - fn_type->abi_align = (fn_type_id->alignment == 0) ? 1 : fn_type_id->alignment; + fn_type->abi_align = g->builtin_types.entry_usize->abi_align; g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type); @@ -963,134 +963,15 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind return entry; } -static ConstExprValue *analyze_const_value_allow_lazy(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, - Buf *type_name, bool allow_lazy) +static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, + Buf *type_name) { size_t backward_branch_count = 0; return ir_eval_const_value(g, scope, node, type_entry, &backward_branch_count, default_backward_branch_quota, - nullptr, nullptr, node, type_name, nullptr, nullptr, allow_lazy); + nullptr, nullptr, node, type_name, nullptr, nullptr); } -static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, - Buf *type_name) -{ - return analyze_const_value_allow_lazy(g, scope, node, type_entry, type_name, false); -} - -static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, bool *is_zero_bits) { - Error err; - if (type_val->special != ConstValSpecialLazy) { - assert(type_val->special == ConstValSpecialStatic); - if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown))) - return err; - *is_zero_bits = (type_val->data.x_type->abi_size == 0); - return ErrorNone; - } - switch (type_val->data.x_lazy->id) { - case LazyValueIdInvalid: - case LazyValueIdAlignOf: - zig_unreachable(); - case LazyValueIdSliceType: - *is_zero_bits = false; - return ErrorNone; - case LazyValueIdFnType: { - LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); - *is_zero_bits = lazy_fn_type->is_generic; - return ErrorNone; - } - } - zig_unreachable(); -} - -static Error type_val_resolve_is_opaque_type(CodeGen *g, ConstExprValue *type_val, bool *is_opaque_type) { - if (type_val->special != ConstValSpecialLazy) { - assert(type_val->special == ConstValSpecialStatic); - *is_opaque_type = (type_val->data.x_type->id == ZigTypeIdOpaque); - return ErrorNone; - } - switch (type_val->data.x_lazy->id) { - case LazyValueIdInvalid: - case LazyValueIdAlignOf: - zig_unreachable(); - case LazyValueIdSliceType: - case LazyValueIdFnType: - *is_opaque_type = false; - return ErrorNone; - } - zig_unreachable(); -} - -static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue *type_val) { - if (type_val->special != ConstValSpecialLazy) { - return type_requires_comptime(g, type_val->data.x_type); - } - switch (type_val->data.x_lazy->id) { - case LazyValueIdInvalid: - case LazyValueIdAlignOf: - zig_unreachable(); - case LazyValueIdSliceType: { - LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy); - return type_requires_comptime(g, lazy_slice_type->elem_type); - } - case LazyValueIdFnType: { - LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); - if (lazy_fn_type->is_generic) - return ReqCompTimeYes; - switch (type_val_resolve_requires_comptime(g, lazy_fn_type->return_type)) { - case ReqCompTimeInvalid: - return ReqCompTimeInvalid; - case ReqCompTimeYes: - return ReqCompTimeYes; - case ReqCompTimeNo: - break; - } - size_t param_count = lazy_fn_type->proto_node->data.fn_proto.params.length; - if (lazy_fn_type->is_var_args) param_count -= 1; - for (size_t i = 0; i < param_count; i += 1) { - switch (type_val_resolve_requires_comptime(g, lazy_fn_type->param_types[i])) { - case ReqCompTimeInvalid: - return ReqCompTimeInvalid; - case ReqCompTimeYes: - return ReqCompTimeYes; - case ReqCompTimeNo: - break; - } - } - return ReqCompTimeNo; - } - } - zig_unreachable(); -} - -static Error type_val_resolve_abi_align(CodeGen *g, ConstExprValue *type_val, size_t *abi_align) { - Error err; - if (type_val->special != ConstValSpecialLazy) { - assert(type_val->special == ConstValSpecialStatic); - if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusAlignmentKnown))) - return err; - *abi_align = type_val->data.x_type->abi_align; - return ErrorNone; - } - switch (type_val->data.x_lazy->id) { - case LazyValueIdInvalid: - case LazyValueIdAlignOf: - zig_unreachable(); - case LazyValueIdSliceType: - *abi_align = g->builtin_types.entry_usize->abi_align; - return ErrorNone; - case LazyValueIdFnType: { - LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy); - if (lazy_fn_type->align_val != nullptr) - return type_val_resolve_abi_align(g, lazy_fn_type->align_val, abi_align); - *abi_align = 1; - return ErrorNone; - } - } - zig_unreachable(); -} - - ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { ConstExprValue *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); if (type_is_invalid(result->type)) @@ -1656,9 +1537,17 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na size_t next_offset = 0; for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = &struct_type->data.structure.fields[i]; + if (field->gen_index == SIZE_MAX) + continue; field->offset = next_offset; - size_t next_abi_align = (i + 1 == field_count) ? - abi_align : struct_type->data.structure.fields[i + 1].type_entry->abi_align; + size_t next_src_field_index = i + 1; + for (; next_src_field_index < field_count; next_src_field_index += 1) { + if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) { + break; + } + } + size_t next_abi_align = (next_src_field_index == field_count) ? + abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align; next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align); } @@ -1716,43 +1605,6 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { size_t size_in_bits = 0; size_t abi_align = struct_type->abi_align; - // Resolve types for fields - for (size_t i = 0; i < field_count; i += 1) { - AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); - TypeStructField *field = &struct_type->data.structure.fields[i]; - - if ((err = ir_resolve_lazy(g, field_source_node, field->type_val))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; - } - ZigType *field_type = field->type_val->data.x_type; - field->type_entry = field_type; - - if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; - } - - if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) { - return ErrorSemanticAnalyzeFail; - } - - if (packed) { - if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_source_node))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return ErrorSemanticAnalyzeFail; - } - } else if (struct_type->data.structure.layout == ContainerLayoutExtern && - !type_allowed_in_extern(g, field_type)) - { - add_node_error(g, field_source_node, - buf_sprintf("extern structs cannot contain fields of type '%s'", - buf_ptr(&field_type->name))); - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return ErrorSemanticAnalyzeFail; - } - } - // Calculate offsets for (size_t i = 0; i < field_count; i += 1) { TypeStructField *field = &struct_type->data.structure.fields[i]; @@ -2186,8 +2038,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { assert(struct_type->id == ZigTypeIdStruct); - Error err; - if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) return ErrorSemanticAnalyzeFail; if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) @@ -2238,36 +2088,29 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { return ErrorSemanticAnalyzeFail; } - ConstExprValue *field_type_val = analyze_const_value_allow_lazy(g, scope, - field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, true); - if (type_is_invalid(field_type_val->type)) { + ZigType *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); + type_struct_field->type_entry = field_type; + if (type_is_invalid(field_type)) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; } - assert(field_type_val->special != ConstValSpecialRuntime); - type_struct_field->type_val = field_type_val; - type_struct_field->src_index = i; - type_struct_field->gen_index = SIZE_MAX; - if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) return ErrorSemanticAnalyzeFail; + type_struct_field->src_index = i; + type_struct_field->gen_index = SIZE_MAX; + if (field_node->data.struct_field.value != nullptr) { add_node_error(g, field_node->data.struct_field.value, buf_sprintf("enums, not structs, support field assignment")); } - bool field_is_opaque_type; - if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return ErrorSemanticAnalyzeFail; - } - if (field_is_opaque_type) { + if (field_type->id == ZigTypeIdOpaque) { add_node_error(g, field_node->data.struct_field.type, buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); struct_type->data.structure.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; } - switch (type_val_resolve_requires_comptime(g, field_type_val)) { + switch (type_requires_comptime(g, field_type)) { case ReqCompTimeYes: struct_type->data.structure.requires_comptime = true; break; @@ -2278,12 +2121,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { break; } - bool field_is_zero_bits; - if ((err = type_val_resolve_zero_bits(g, field_type_val, &field_is_zero_bits))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return ErrorSemanticAnalyzeFail; - } - if (field_is_zero_bits) + if (!type_has_bits(field_type)) continue; type_struct_field->gen_index = gen_field_index; @@ -2338,7 +2176,31 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { bool packed = struct_type->data.structure.layout == ContainerLayoutPacked; for (size_t i = 0; i < field_count; i += 1) { + AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); TypeStructField *field = &struct_type->data.structure.fields[i]; + ZigType *field_type = field->type_entry; + assert(field_type != nullptr); + + if ((err = type_resolve(g, field_type, ResolveStatusAlignmentKnown))) { + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + return ErrorSemanticAnalyzeFail; + } + + if (struct_type->data.structure.layout == ContainerLayoutExtern && + !type_allowed_in_extern(g, field_type)) + { + add_node_error(g, field_source_node, + buf_sprintf("extern structs cannot contain fields of type '%s'", + buf_ptr(&field_type->name))); + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + return ErrorSemanticAnalyzeFail; + } else if (packed) { + if ((err = emit_error_unless_type_allowed_in_packed_struct(g, field_type, field_source_node))) { + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + return ErrorSemanticAnalyzeFail; + } + } + if (field->gen_index == SIZE_MAX) continue; @@ -2349,13 +2211,8 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { } } else { // TODO: https://github.com/ziglang/zig/issues/1512 - size_t field_align; - if ((err = type_val_resolve_abi_align(g, field->type_val, &field_align))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; - } - if (field_align > abi_align) { - abi_align = field_align; + if (field_type->abi_align > abi_align) { + abi_align = field_type->abi_align; } } } @@ -2993,7 +2850,7 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { Tld *tld = get_container_scope(g->compile_var_import)->decl_table.get(name); - resolve_top_level_decl(g, tld, tld->source_node, false); + resolve_top_level_decl(g, tld, tld->source_node); assert(tld->id == TldIdVar); TldVar *tld_var = (TldVar *)tld; tld_var->var->const_value = value; @@ -3232,7 +3089,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf return variable_entry; } -static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { +static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { AstNode *source_node = tld_var->base.source_node; AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; @@ -3273,8 +3130,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { if (explicit_type && explicit_type->id == ZigTypeIdInvalid) { implicit_type = explicit_type; } else if (var_decl->expr) { - init_value = analyze_const_value_allow_lazy(g, tld_var->base.parent_scope, var_decl->expr, - explicit_type, var_decl->symbol, allow_lazy); + init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); assert(init_value); implicit_type = init_value->type; @@ -3337,11 +3193,11 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { g->global_vars.append(tld_var); } -void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool allow_lazy) { - bool want_resolve_lazy = tld->resolution == TldResolutionOkLazy && !allow_lazy; - if (tld->resolution != TldResolutionUnresolved && !want_resolve_lazy) +void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { + if (tld->resolution != TldResolutionUnresolved) return; + assert(tld->resolution != TldResolutionResolving); tld->resolution = TldResolutionResolving; g->tld_ref_source_node_stack.append(source_node); @@ -3349,11 +3205,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool all case TldIdVar: { TldVar *tld_var = (TldVar *)tld; - if (want_resolve_lazy) { - ir_resolve_lazy(g, source_node, tld_var->var->const_value); - } else { - resolve_decl_var(g, tld_var, allow_lazy); - } + resolve_decl_var(g, tld_var); break; } case TldIdFn: @@ -3376,7 +3228,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node, bool all } } - tld->resolution = allow_lazy ? TldResolutionOkLazy : TldResolutionOk; + tld->resolution = TldResolutionOk; g->tld_ref_source_node_stack.pop(); } @@ -4045,7 +3897,7 @@ void semantic_analyze(CodeGen *g) { for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { Tld *tld = g->resolve_queue.at(g->resolve_queue_index); AstNode *source_node = nullptr; - resolve_top_level_decl(g, tld, source_node, false); + resolve_top_level_decl(g, tld, source_node); } for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { @@ -5479,9 +5331,6 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { case ConstValSpecialRuntime: buf_appendf(buf, "(runtime value)"); return; - case ConstValSpecialLazy: - buf_appendf(buf, "(lazy value)"); - return; case ConstValSpecialUndef: buf_appendf(buf, "undefined"); return; @@ -6098,7 +5947,7 @@ bool type_ptr_eql(const ZigType *a, const ZigType *b) { ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name)); - resolve_top_level_decl(codegen, tld, nullptr, false); + resolve_top_level_decl(codegen, tld, nullptr); assert(tld->id == TldIdVar); TldVar *tld_var = (TldVar *)tld; ConstExprValue *var_value = tld_var->var->const_value; diff --git a/src/analyze.hpp b/src/analyze.hpp index 48f07fd633..a3246fdf4d 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -61,7 +61,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *abs_full_path, Bu ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **crossed_fndef_scope); Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); 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); +void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node); ZigType *get_src_ptr_type(ZigType *type); ZigType *get_codegen_ptr_type(ZigType *type); diff --git a/src/codegen.cpp b/src/codegen.cpp index f5b15bbeb4..476efd53c1 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3358,8 +3358,6 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) { static bool value_is_all_undef(ConstExprValue *const_val) { switch (const_val->special) { - case ConstValSpecialLazy: - zig_unreachable(); case ConstValSpecialRuntime: return false; case ConstValSpecialUndef: @@ -5824,7 +5822,6 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *un static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ConstExprValue *const_val) { switch (const_val->special) { - case ConstValSpecialLazy: case ConstValSpecialRuntime: zig_unreachable(); case ConstValSpecialUndef: @@ -6082,7 +6079,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c assert(type_has_bits(type_entry)); switch (const_val->special) { - case ConstValSpecialLazy: case ConstValSpecialRuntime: zig_unreachable(); case ConstValSpecialUndef: @@ -8249,7 +8245,7 @@ static void gen_root_source(CodeGen *g) { } Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic")); assert(panic_tld != nullptr); - resolve_top_level_decl(g, panic_tld, nullptr, false); + resolve_top_level_decl(g, panic_tld, nullptr); } diff --git a/src/ir.cpp b/src/ir.cpp index a4d7cf271b..405dc16ca8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -154,7 +154,6 @@ struct ConstCastBadAllowsZero { enum UndefAllowed { UndefOk, UndefBad, - LazyOk, }; static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); @@ -10257,57 +10256,32 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio return const_instr; } -static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, - ConstExprValue *val, UndefAllowed undef_allowed) -{ - Error err; - for (;;) { - switch (val->special) { - case ConstValSpecialStatic: - return ErrorNone; - case ConstValSpecialRuntime: - if (!type_has_bits(val->type)) - return ErrorNone; - - exec_add_error_node(codegen, exec, source_node, - buf_sprintf("unable to evaluate constant expression")); - return ErrorSemanticAnalyzeFail; - case ConstValSpecialUndef: - if (undef_allowed == UndefOk) - return ErrorNone; - - exec_add_error_node(codegen, exec, source_node, - buf_sprintf("use of undefined value here causes undefined behavior")); - return ErrorSemanticAnalyzeFail; - case ConstValSpecialLazy: - if (undef_allowed == LazyOk) - return ErrorNone; - - if ((err = ir_resolve_lazy(codegen, source_node, val))) - return err; - - continue; - } - } -} - static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { - Error err; - if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, - &value->value, undef_allowed))) - { - return nullptr; + switch (value->value.special) { + case ConstValSpecialStatic: + return &value->value; + case ConstValSpecialRuntime: + if (!type_has_bits(value->value.type)) { + return &value->value; + } + ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); + return nullptr; + case ConstValSpecialUndef: + if (undef_allowed == UndefOk) { + return &value->value; + } else { + ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); + return nullptr; + } } - return &value->value; + zig_unreachable(); } ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, - IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy) + IrExecutable *parent_exec, AstNode *expected_type_source_node) { - Error err; - if (expected_type != nullptr && type_is_invalid(expected_type)) return &codegen->invalid_instruction->value; @@ -10352,24 +10326,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod fprintf(stderr, "}\n"); } - ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); - - if (!allow_lazy) { - if ((err = ir_resolve_lazy(codegen, node, result))) - return &codegen->invalid_instruction->value; - } - return result; -} - -static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, - ConstExprValue *val) -{ - Error err; - if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) - return codegen->builtin_types.entry_invalid; - - assert(val->data.x_type != nullptr); - return val->data.x_type; + return ir_exec_const_result(codegen, analyzed_executable); } static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { @@ -10382,7 +10339,12 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { return ira->codegen->builtin_types.entry_invalid; } - return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value); + ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); + if (!const_val) + return ira->codegen->builtin_types.entry_invalid; + + assert(const_val->data.x_type != nullptr); + return const_val->data.x_type; } static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { @@ -11873,38 +11835,33 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc } } -static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, - ConstExprValue *const_val, uint32_t *out) -{ - Error err; - if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) +static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { + if (type_is_invalid(value->value.type)) + return false; + + IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); + if (type_is_invalid(casted_value->value.type)) + return false; + + ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); + if (!const_val) return false; uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); if (align_bytes == 0) { - exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); + ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); return false; } if (!is_power_of_2(align_bytes)) { - exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); + ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); return false; } + *out = align_bytes; return true; } -static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { - if (type_is_invalid(value->value.type)) - return false; - - IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); - if (type_is_invalid(casted_value->value.type)) - return false; - - return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, &casted_value->value, out); -} - static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { if (type_is_invalid(value->value.type)) return false; @@ -12072,140 +12029,6 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { return result; } -static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, - LazyValueFnType *lazy_fn_type) -{ - AstNode *proto_node = lazy_fn_type->proto_node; - - FnTypeId fn_type_id = {0}; - init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); - - for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { - AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); - assert(param_node->type == NodeTypeParamDecl); - - bool param_is_var_args = param_node->data.param_decl.is_var_args; - if (param_is_var_args) { - if (fn_type_id.cc == CallingConventionC) { - fn_type_id.param_count = fn_type_id.next_param_index; - continue; - } else if (fn_type_id.cc == CallingConventionUnspecified) { - return get_generic_fn_type(codegen, &fn_type_id); - } else { - zig_unreachable(); - } - } - FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; - param_info->is_noalias = param_node->data.param_decl.is_noalias; - - if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { - param_info->type = nullptr; - return get_generic_fn_type(codegen, &fn_type_id); - } else { - ZigType *param_type = ir_resolve_const_type(codegen, exec, source_node, - lazy_fn_type->param_types[fn_type_id.next_param_index]); - if (type_is_invalid(param_type)) - return nullptr; - switch (type_requires_comptime(codegen, param_type)) { - case ReqCompTimeYes: - if (!calling_convention_allows_zig_types(fn_type_id.cc)) { - exec_add_error_node(codegen, exec, source_node, - buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", - buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); - return nullptr; - } - param_info->type = param_type; - fn_type_id.next_param_index += 1; - return get_generic_fn_type(codegen, &fn_type_id); - case ReqCompTimeInvalid: - return nullptr; - case ReqCompTimeNo: - break; - } - if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { - exec_add_error_node(codegen, exec, source_node, - buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", - buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); - return nullptr; - } - param_info->type = param_type; - } - - } - - if (lazy_fn_type->align_val != nullptr) { - if (!ir_resolve_const_align(codegen, exec, source_node, lazy_fn_type->align_val, &fn_type_id.alignment)) - return nullptr; - } - - fn_type_id.return_type = ir_resolve_const_type(codegen, exec, source_node, lazy_fn_type->return_type); - if (type_is_invalid(fn_type_id.return_type)) - return nullptr; - if (fn_type_id.return_type->id == ZigTypeIdOpaque) { - exec_add_error_node(codegen, exec, source_node, - buf_sprintf("return type cannot be opaque")); - return nullptr; - } - - if (lazy_fn_type->async_allocator_type != nullptr) { - fn_type_id.async_allocator_type = ir_resolve_const_type(codegen, exec, source_node, - lazy_fn_type->async_allocator_type); - if (type_is_invalid(fn_type_id.async_allocator_type)) - return nullptr; - } - - return get_fn_type(codegen, &fn_type_id); -} - -Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { - Error err; - if (val->special != ConstValSpecialLazy) - return ErrorNone; - IrExecutable *exec = val->data.x_lazy->exec; - switch (val->data.x_lazy->id) { - case LazyValueIdInvalid: - zig_unreachable(); - case LazyValueIdAlignOf: { - LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); - if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown))) - return err; - uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); - val->special = ConstValSpecialStatic; - assert(val->type->id == ZigTypeIdComptimeInt); - bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); - return ErrorNone; - } - case LazyValueIdSliceType: { - LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); - uint32_t align_bytes = 0; - if (lazy_slice_type->align_val != nullptr) { - if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes)) - return ErrorSemanticAnalyzeFail; - } - if ((err = type_resolve(codegen, lazy_slice_type->elem_type, ResolveStatusZeroBitsKnown))) - return err; - ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type, - lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, - 0, 0, lazy_slice_type->is_allowzero); - val->special = ConstValSpecialStatic; - assert(val->type->id == ZigTypeIdMetaType); - val->data.x_type = get_slice_type(codegen, slice_ptr_type); - return ErrorNone; - } - case LazyValueIdFnType: { - ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, - reinterpret_cast<LazyValueFnType *>(val->data.x_lazy)); - if (fn_type == nullptr) - return ErrorSemanticAnalyzeFail; - val->special = ConstValSpecialStatic; - assert(val->type->id == ZigTypeIdMetaType); - val->data.x_type = fn_type; - return ErrorNone; - } - } - zig_unreachable(); -} - static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, IrInstructionAddImplicitReturnType *instruction) { @@ -14179,7 +14002,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, if (linkage_makes_it_runtime) goto no_mem_slot; - if (value_is_comptime(var->const_value)) { + if (var->const_value->special == ConstValSpecialStatic) { mem_slot = var->const_value; } else { if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { @@ -14197,7 +14020,6 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, case ConstValSpecialRuntime: goto no_mem_slot; case ConstValSpecialStatic: // fallthrough - case ConstValSpecialLazy: // fallthrough case ConstValSpecialUndef: { ConstPtrMut ptr_mut; if (comptime_var_mem) { @@ -14478,7 +14300,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call AstNode *body_node = fn_entry->body_node; result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, - nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false); + nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); if (inferred_err_set_type != nullptr) { inferred_err_set_type->data.error_set.infer_fn = nullptr; @@ -14674,8 +14496,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, - nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr, - false); + nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); const_instruction->base.value = *align_result; @@ -15808,7 +15629,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, auto entry = container_scope->decl_table.maybe_get(field_name); Tld *tld = entry ? entry->value : nullptr; if (tld && tld->id == TldIdFn) { - resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); + resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); if (tld->resolution == TldResolutionInvalid) return ira->codegen->invalid_instruction; TldFn *tld_fn = (TldFn *)tld; @@ -15999,7 +15820,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { - resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, false); + resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); if (tld->resolution == TldResolutionInvalid) return ira->codegen->invalid_instruction; @@ -16655,29 +16476,22 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstructionSliceType *slice_type_instruction) { - IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); - result->value.special = ConstValSpecialLazy; - - LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); - result->value.data.x_lazy = &lazy_slice_type->base; - lazy_slice_type->base.id = LazyValueIdSliceType; - lazy_slice_type->base.exec = ira->new_irb.exec; - + Error err; + uint32_t align_bytes = 0; if (slice_type_instruction->align_value != nullptr) { - lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk); - if (lazy_slice_type->align_val == nullptr) + if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) return ira->codegen->invalid_instruction; } - lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); - if (type_is_invalid(lazy_slice_type->elem_type)) + ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); + if (type_is_invalid(child_type)) return ira->codegen->invalid_instruction; - lazy_slice_type->is_const = slice_type_instruction->is_const; - lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; - lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; + bool is_const = slice_type_instruction->is_const; + bool is_volatile = slice_type_instruction->is_volatile; + bool is_allow_zero = slice_type_instruction->is_allow_zero; - switch (lazy_slice_type->elem_type->id) { + switch (child_type->id) { case ZigTypeIdInvalid: // handled above zig_unreachable(); case ZigTypeIdUnreachable: @@ -16686,7 +16500,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, case ZigTypeIdArgTuple: case ZigTypeIdOpaque: ir_add_error_node(ira, slice_type_instruction->base.source_node, - buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name))); + buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); return ira->codegen->invalid_instruction; case ZigTypeIdMetaType: case ZigTypeIdVoid: @@ -16708,7 +16522,14 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, case ZigTypeIdBoundFn: case ZigTypeIdPromise: case ZigTypeIdVector: - return result; + { + if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_instruction; + ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, + is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); + ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); + return ir_const_type(ira, &slice_type_instruction->base, result_type); + } } zig_unreachable(); } @@ -16815,7 +16636,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, case ZigTypeIdPromise: case ZigTypeIdVector: { - if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) + if ((err = ensure_complete_type(ira->codegen, child_type))) return ira->codegen->invalid_instruction; ZigType *result_type = get_array_type(ira->codegen, child_type, size); return ir_const_type(ira, &array_type_instruction->base, result_type); @@ -18172,7 +17993,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, while ((curr_entry = decl_it.next()) != nullptr) { // If the definition is unresolved, force it to be resolved again. if (curr_entry->value->resolution == TldResolutionUnresolved) { - resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); + resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); if (curr_entry->value->resolution != TldResolutionOk) { return ErrorSemanticAnalyzeFail; } @@ -19161,7 +18982,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct ZigType *void_type = ira->codegen->builtin_types.entry_void; ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, - &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false); + &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); if (type_is_invalid(cimport_result->type)) return ira->codegen->invalid_instruction; @@ -20708,11 +20529,15 @@ static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructio } static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { + Error err; IrInstruction *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value.type)) return ira->codegen->invalid_instruction; ZigType *type_entry = ir_resolve_type(ira, type_value); + if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) + return ira->codegen->invalid_instruction; + switch (type_entry->id) { case ZigTypeIdInvalid: zig_unreachable(); @@ -20744,25 +20569,12 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdVector: - break; + { + uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); + return ir_const_unsigned(ira, &instruction->base, align_in_bytes); + } } - if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) { - uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); - return ir_const_unsigned(ira, &instruction->base, align_in_bytes); - } - // Here we create a lazy value in order to avoid resolving the alignment of the type - // immediately. This avoids false positive dependency loops such as: - // const Node = struct { - // field: []align(@alignOf(Node)) Node, - // }; - LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); - lazy_align_of->base.id = LazyValueIdAlignOf; - lazy_align_of->base.exec = ira->new_irb.exec; - lazy_align_of->target_type = type_entry; - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); - result->value.special = ConstValSpecialLazy; - result->value.data.x_lazy = &lazy_align_of->base; - return result; + zig_unreachable(); } static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { @@ -21017,77 +20829,96 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct AstNode *proto_node = instruction->base.source_node; assert(proto_node->type == NodeTypeFnProto); - IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); - result->value.special = ConstValSpecialLazy; - - LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); - result->value.data.x_lazy = &lazy_fn_type->base; - lazy_fn_type->base.id = LazyValueIdFnType; - lazy_fn_type->base.exec = ira->new_irb.exec; - if (proto_node->data.fn_proto.auto_err_set) { ir_add_error(ira, &instruction->base, buf_sprintf("inferring error set of return type valid only for function definitions")); return ira->codegen->invalid_instruction; } - size_t param_count = proto_node->data.fn_proto.params.length; - lazy_fn_type->proto_node = proto_node; - lazy_fn_type->param_types = allocate<ConstExprValue *>(param_count); + FnTypeId fn_type_id = {0}; + init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); - for (size_t i = 0; i < param_count; i += 1) { - AstNode *param_node = proto_node->data.fn_proto.params.at(i); + for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { + AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); assert(param_node->type == NodeTypeParamDecl); bool param_is_var_args = param_node->data.param_decl.is_var_args; - lazy_fn_type->is_var_args = true; if (param_is_var_args) { - if (proto_node->data.fn_proto.cc == CallingConventionC) { - break; - } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { - lazy_fn_type->is_generic = true; - return result; + if (fn_type_id.cc == CallingConventionC) { + fn_type_id.param_count = fn_type_id.next_param_index; + continue; + } else if (fn_type_id.cc == CallingConventionUnspecified) { + return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); } else { zig_unreachable(); } } + FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; + param_info->is_noalias = param_node->data.param_decl.is_noalias; - if (instruction->param_types[i] == nullptr) { - lazy_fn_type->is_generic = true; - return result; + if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { + param_info->type = nullptr; + return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); + } else { + IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; + if (type_is_invalid(param_type_value->value.type)) + return ira->codegen->invalid_instruction; + ZigType *param_type = ir_resolve_type(ira, param_type_value); + switch (type_requires_comptime(ira->codegen, param_type)) { + case ReqCompTimeYes: + if (!calling_convention_allows_zig_types(fn_type_id.cc)) { + ir_add_error(ira, param_type_value, + buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", + buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); + return ira->codegen->invalid_instruction; + } + param_info->type = param_type; + fn_type_id.next_param_index += 1; + return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); + case ReqCompTimeInvalid: + return ira->codegen->invalid_instruction; + case ReqCompTimeNo: + break; + } + if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { + ir_add_error(ira, param_type_value, + buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", + buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); + return ira->codegen->invalid_instruction; + } + param_info->type = param_type; } - IrInstruction *param_type_value = instruction->param_types[i]->child; - if (type_is_invalid(param_type_value->value.type)) - return ira->codegen->invalid_instruction; - ConstExprValue *param_type_val = ir_resolve_const(ira, param_type_value, LazyOk); - if (param_type_val == nullptr) - return ira->codegen->invalid_instruction; - lazy_fn_type->param_types[i] = param_type_val; } if (instruction->align_value != nullptr) { - lazy_fn_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); - if (lazy_fn_type->align_val == nullptr) + if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) return ira->codegen->invalid_instruction; } - lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); - if (lazy_fn_type->return_type == nullptr) + IrInstruction *return_type_value = instruction->return_type->child; + fn_type_id.return_type = ir_resolve_type(ira, return_type_value); + if (type_is_invalid(fn_type_id.return_type)) return ira->codegen->invalid_instruction; + if (fn_type_id.return_type->id == ZigTypeIdOpaque) { + ir_add_error(ira, instruction->return_type, + buf_sprintf("return type cannot be opaque")); + return ira->codegen->invalid_instruction; + } - if (proto_node->data.fn_proto.cc == CallingConventionAsync) { + if (fn_type_id.cc == CallingConventionAsync) { if (instruction->async_allocator_type_value == nullptr) { ir_add_error(ira, &instruction->base, buf_sprintf("async fn proto missing allocator type")); return ira->codegen->invalid_instruction; } - lazy_fn_type->async_allocator_type = ir_resolve_const(ira, instruction->async_allocator_type_value->child, LazyOk); - if (lazy_fn_type->async_allocator_type == nullptr) + IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; + fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); + if (type_is_invalid(fn_type_id.async_allocator_type)) return ira->codegen->invalid_instruction; } - return result; + return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); } static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { @@ -21756,11 +21587,8 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou val->type->data.vector.len); case ZigTypeIdEnum: switch (val->type->data.enumeration.layout) { - case ContainerLayoutAuto: { - opt_ir_add_error_node(ira, codegen, source_node, - buf_sprintf("compiler bug: TODO: implement enum byte reinterpretation")); - return ErrorSemanticAnalyzeFail; - } + case ContainerLayoutAuto: + zig_panic("TODO buf_read_value_bytes enum auto"); case ContainerLayoutPacked: zig_panic("TODO buf_read_value_bytes enum packed"); case ContainerLayoutExtern: { @@ -22056,7 +21884,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, Tld *tld = instruction->tld; LVal lval = instruction->lval; - resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node, true); + resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); if (tld->resolution == TldResolutionInvalid) return ira->codegen->invalid_instruction; diff --git a/src/ir.hpp b/src/ir.hpp index bf65328f70..0b85ad2c55 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -16,8 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry); ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, - IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy); -Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val); + IrExecutable *parent_exec, AstNode *expected_type_source_node); ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, ZigType *expected_type, AstNode *expected_type_source_node); |
