| ... | @@ -22869,84 +22869,65 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct | ... | @@ -22869,84 +22869,65 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 22869 | AstNode *proto_node = instruction->base.source_node; | 22869 | AstNode *proto_node = instruction->base.source_node; |
| 22870 | assert(proto_node->type == NodeTypeFnProto); | 22870 | assert(proto_node->type == NodeTypeFnProto); |
| 22871 | | 22871 | |
| | 22872 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); |
| | 22873 | result->value.special = ConstValSpecialLazy; |
| | 22874 | |
| | 22875 | LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); |
| | 22876 | result->value.data.x_lazy = &lazy_fn_type->base; |
| | 22877 | lazy_fn_type->base.id = LazyValueIdFnType; |
| | 22878 | lazy_fn_type->base.exec = ira->new_irb.exec; |
| | 22879 | |
| 22872 | if (proto_node->data.fn_proto.auto_err_set) { | 22880 | if (proto_node->data.fn_proto.auto_err_set) { |
| 22873 | ir_add_error(ira, &instruction->base, | 22881 | ir_add_error(ira, &instruction->base, |
| 22874 | buf_sprintf("inferring error set of return type valid only for function definitions")); | 22882 | buf_sprintf("inferring error set of return type valid only for function definitions")); |
| 22875 | return ira->codegen->invalid_instruction; | 22883 | return ira->codegen->invalid_instruction; |
| 22876 | } | 22884 | } |
| 22877 | | 22885 | |
| 22878 | FnTypeId fn_type_id = {0}; | 22886 | size_t param_count = proto_node->data.fn_proto.params.length; |
| 22879 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); | 22887 | lazy_fn_type->proto_node = proto_node; |
| | 22888 | lazy_fn_type->param_types = allocate<ConstExprValue *>(param_count); |
| 22880 | | 22889 | |
| 22881 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { | 22890 | for (size_t param_index = 0; param_index < param_count; param_index += 1) { |
| 22882 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); | 22891 | AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); |
| 22883 | assert(param_node->type == NodeTypeParamDecl); | 22892 | assert(param_node->type == NodeTypeParamDecl); |
| 22884 | | 22893 | |
| 22885 | bool param_is_var_args = param_node->data.param_decl.is_var_args; | 22894 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 22886 | if (param_is_var_args) { | 22895 | if (param_is_var_args) { |
| 22887 | if (fn_type_id.cc == CallingConventionC) { | 22896 | if (proto_node->data.fn_proto.cc == CallingConventionC) { |
| 22888 | fn_type_id.param_count = fn_type_id.next_param_index; | 22897 | break; |
| 22889 | continue; | 22898 | } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { |
| 22890 | } else if (fn_type_id.cc == CallingConventionUnspecified) { | 22899 | lazy_fn_type->is_generic = true; |
| 22891 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 22900 | return result; |
| 22892 | } else { | 22901 | } else { |
| 22893 | zig_unreachable(); | 22902 | zig_unreachable(); |
| 22894 | } | 22903 | } |
| 22895 | } | 22904 | } |
| 22896 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; | | |
| 22897 | param_info->is_noalias = param_node->data.param_decl.is_noalias; | | |
| 22898 | | 22905 | |
| 22899 | if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { | 22906 | if (instruction->param_types[param_index] == nullptr) { |
| 22900 | param_info->type = nullptr; | 22907 | lazy_fn_type->is_generic = true; |
| 22901 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 22908 | return result; |
| 22902 | } else { | | |
| 22903 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; | | |
| 22904 | ZigType *param_type = ir_resolve_type(ira, param_type_value); | | |
| 22905 | if (type_is_invalid(param_type)) | | |
| 22906 | return ira->codegen->invalid_instruction; | | |
| 22907 | switch (type_requires_comptime(ira->codegen, param_type, nullptr)) { | | |
| 22908 | case ReqCompTimeYes: | | |
| 22909 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | | |
| 22910 | ir_add_error(ira, param_type_value, | | |
| 22911 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | | |
| 22912 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | | |
| 22913 | return ira->codegen->invalid_instruction; | | |
| 22914 | } | | |
| 22915 | param_info->type = param_type; | | |
| 22916 | fn_type_id.next_param_index += 1; | | |
| 22917 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | | |
| 22918 | case ReqCompTimeInvalid: | | |
| 22919 | return ira->codegen->invalid_instruction; | | |
| 22920 | case ReqCompTimeNo: | | |
| 22921 | break; | | |
| 22922 | } | | |
| 22923 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { | | |
| 22924 | ir_add_error(ira, param_type_value, | | |
| 22925 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", | | |
| 22926 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | | |
| 22927 | return ira->codegen->invalid_instruction; | | |
| 22928 | } | | |
| 22929 | param_info->type = param_type; | | |
| 22930 | } | 22909 | } |
| 22931 | | 22910 | |
| | 22911 | IrInstruction *param_type_value = instruction->param_types[param_index]->child; |
| | 22912 | if (type_is_invalid(param_type_value->value.type)) |
| | 22913 | return ira->codegen->invalid_instruction; |
| | 22914 | ConstExprValue *param_type_val = ir_resolve_const(ira, param_type_value, LazyOk); |
| | 22915 | if (param_type_val == nullptr) |
| | 22916 | return ira->codegen->invalid_instruction; |
| | 22917 | lazy_fn_type->param_types[param_index] = param_type_val; |
| 22932 | } | 22918 | } |
| 22933 | | 22919 | |
| 22934 | if (instruction->align_value != nullptr) { | 22920 | if (instruction->align_value != nullptr) { |
| 22935 | if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) | 22921 | lazy_fn_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); |
| | 22922 | if (lazy_fn_type->align_val == nullptr) |
| 22936 | return ira->codegen->invalid_instruction; | 22923 | return ira->codegen->invalid_instruction; |
| 22937 | } | 22924 | } |
| 22938 | | 22925 | |
| 22939 | IrInstruction *return_type_value = instruction->return_type->child; | 22926 | lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); |
| 22940 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); | 22927 | if (lazy_fn_type->return_type == nullptr) |
| 22941 | if (type_is_invalid(fn_type_id.return_type)) | 22928 | return ira->codegen->invalid_instruction; |
| 22942 | return ira->codegen->invalid_instruction; | | |
| 22943 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { | | |
| 22944 | ir_add_error(ira, instruction->return_type, | | |
| 22945 | buf_sprintf("return type cannot be opaque")); | | |
| 22946 | return ira->codegen->invalid_instruction; | | |
| 22947 | } | | |
| 22948 | | 22929 | |
| 22949 | return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); | 22930 | return result; |
| 22950 | } | 22931 | } |
| 22951 | | 22932 | |
| 22952 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { | 22933 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { |
| ... | @@ -25492,6 +25473,82 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -25492,6 +25473,82 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25492 | zig_unreachable(); | 25473 | zig_unreachable(); |
| 25493 | } | 25474 | } |
| 25494 | | 25475 | |
| | 25476 | static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| | 25477 | LazyValueFnType *lazy_fn_type) |
| | 25478 | { |
| | 25479 | AstNode *proto_node = lazy_fn_type->proto_node; |
| | 25480 | |
| | 25481 | FnTypeId fn_type_id = {0}; |
| | 25482 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); |
| | 25483 | |
| | 25484 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { |
| | 25485 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); |
| | 25486 | assert(param_node->type == NodeTypeParamDecl); |
| | 25487 | |
| | 25488 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| | 25489 | if (param_is_var_args) { |
| | 25490 | if (fn_type_id.cc == CallingConventionC) { |
| | 25491 | fn_type_id.param_count = fn_type_id.next_param_index; |
| | 25492 | continue; |
| | 25493 | } else if (fn_type_id.cc == CallingConventionUnspecified) { |
| | 25494 | return get_generic_fn_type(codegen, &fn_type_id); |
| | 25495 | } else { |
| | 25496 | zig_unreachable(); |
| | 25497 | } |
| | 25498 | } |
| | 25499 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; |
| | 25500 | param_info->is_noalias = param_node->data.param_decl.is_noalias; |
| | 25501 | |
| | 25502 | if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { |
| | 25503 | param_info->type = nullptr; |
| | 25504 | return get_generic_fn_type(codegen, &fn_type_id); |
| | 25505 | } else { |
| | 25506 | ZigType *param_type = ir_resolve_const_type(codegen, exec, source_node, |
| | 25507 | lazy_fn_type->param_types[fn_type_id.next_param_index]); |
| | 25508 | if (type_is_invalid(param_type)) |
| | 25509 | return nullptr; |
| | 25510 | switch (type_requires_comptime(codegen, param_type, nullptr)) { |
| | 25511 | case ReqCompTimeYes: |
| | 25512 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| | 25513 | exec_add_error_node(codegen, exec, source_node, |
| | 25514 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", |
| | 25515 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| | 25516 | return nullptr; |
| | 25517 | } |
| | 25518 | param_info->type = param_type; |
| | 25519 | fn_type_id.next_param_index += 1; |
| | 25520 | return get_generic_fn_type(codegen, &fn_type_id); |
| | 25521 | case ReqCompTimeInvalid: |
| | 25522 | return nullptr; |
| | 25523 | case ReqCompTimeNo: |
| | 25524 | break; |
| | 25525 | } |
| | 25526 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { |
| | 25527 | exec_add_error_node(codegen, exec, source_node, |
| | 25528 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", |
| | 25529 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| | 25530 | return nullptr; |
| | 25531 | } |
| | 25532 | param_info->type = param_type; |
| | 25533 | } |
| | 25534 | } |
| | 25535 | |
| | 25536 | if (lazy_fn_type->align_val != nullptr) { |
| | 25537 | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_fn_type->align_val, &fn_type_id.alignment)) |
| | 25538 | return nullptr; |
| | 25539 | } |
| | 25540 | |
| | 25541 | fn_type_id.return_type = ir_resolve_const_type(codegen, exec, source_node, lazy_fn_type->return_type); |
| | 25542 | if (type_is_invalid(fn_type_id.return_type)) |
| | 25543 | return nullptr; |
| | 25544 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { |
| | 25545 | exec_add_error_node(codegen, exec, source_node, buf_create_from_str("return type cannot be opaque")); |
| | 25546 | return nullptr; |
| | 25547 | } |
| | 25548 | |
| | 25549 | return get_fn_type(codegen, &fn_type_id); |
| | 25550 | } |
| | 25551 | |
| 25495 | static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { | 25552 | static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { |
| 25496 | Error err; | 25553 | Error err; |
| 25497 | if (val->special != ConstValSpecialLazy) | 25554 | if (val->special != ConstValSpecialLazy) |
| ... | @@ -25551,6 +25608,16 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx | ... | @@ -25551,6 +25608,16 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx |
| 25551 | val->special = ConstValSpecialStatic; | 25608 | val->special = ConstValSpecialStatic; |
| 25552 | return ErrorNone; | 25609 | return ErrorNone; |
| 25553 | } | 25610 | } |
| | 25611 | case LazyValueIdFnType: { |
| | 25612 | ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, |
| | 25613 | reinterpret_cast<LazyValueFnType *>(val->data.x_lazy)); |
| | 25614 | if (fn_type == nullptr) |
| | 25615 | return ErrorSemanticAnalyzeFail; |
| | 25616 | val->special = ConstValSpecialStatic; |
| | 25617 | assert(val->type->id == ZigTypeIdMetaType); |
| | 25618 | val->data.x_type = fn_type; |
| | 25619 | return ErrorNone; |
| | 25620 | } |
| 25554 | } | 25621 | } |
| 25555 | zig_unreachable(); | 25622 | zig_unreachable(); |
| 25556 | } | 25623 | } |