| ... | @@ -25607,8 +25607,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy | ... | @@ -25607,8 +25607,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25607 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { | 25607 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { |
| 25608 | zig_unreachable(); | 25608 | zig_unreachable(); |
| 25609 | } | 25609 | } |
| 25610 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - | 25610 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count; |
| 25611 | (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); | | |
| 25612 | | 25611 | |
| 25613 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); | 25612 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25614 | fn_arg_array->special = ConstValSpecialStatic; | 25613 | fn_arg_array->special = ConstValSpecialStatic; |
| ... | @@ -25757,6 +25756,17 @@ static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue | ... | @@ -25757,6 +25756,17 @@ static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue |
| 25757 | return ErrorNone; | 25756 | return ErrorNone; |
| 25758 | } | 25757 | } |
| 25759 | | 25758 | |
| | 25759 | static Error get_const_field_u29(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, |
| | 25760 | const char *name, size_t field_index, uint32_t *out) |
| | 25761 | { |
| | 25762 | ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); |
| | 25763 | if (value == nullptr) |
| | 25764 | return ErrorSemanticAnalyzeFail; |
| | 25765 | assert(value->type == ira->codegen->builtin_types.entry_u29); |
| | 25766 | *out = bigint_as_u32(&value->data.x_bigint); |
| | 25767 | return ErrorNone; |
| | 25768 | } |
| | 25769 | |
| 25760 | static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) | 25770 | static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) |
| 25761 | { | 25771 | { |
| 25762 | ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); | 25772 | ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); |
| ... | @@ -26332,10 +26342,105 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI | ... | @@ -26332,10 +26342,105 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26332 | return entry; | 26342 | return entry; |
| 26333 | } | 26343 | } |
| 26334 | case ZigTypeIdFn: | 26344 | case ZigTypeIdFn: |
| 26335 | case ZigTypeIdBoundFn: | 26345 | case ZigTypeIdBoundFn: { |
| 26336 | ir_add_error(ira, source_instr, buf_sprintf( | 26346 | assert(payload->special == ConstValSpecialStatic); |
| 26337 | "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); | 26347 | assert(payload->type == ir_type_info_get_type(ira, "Fn", nullptr)); |
| 26338 | return ira->codegen->invalid_inst_gen->value->type; | 26348 | |
| | 26349 | ZigValue *cc_value = get_const_field(ira, source_instr->source_node, payload, "calling_convention", 0); |
| | 26350 | if (cc_value == nullptr) |
| | 26351 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26352 | assert(cc_value->special == ConstValSpecialStatic); |
| | 26353 | assert(cc_value->type == get_builtin_type(ira->codegen, "CallingConvention")); |
| | 26354 | CallingConvention cc = (CallingConvention)bigint_as_u32(&cc_value->data.x_enum_tag); |
| | 26355 | |
| | 26356 | uint32_t alignment; |
| | 26357 | if ((err = get_const_field_u29(ira, source_instr->source_node, payload, "alignment", 1, &alignment))) |
| | 26358 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26359 | |
| | 26360 | Error err; |
| | 26361 | bool is_generic; |
| | 26362 | if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_generic", 2, &is_generic))) |
| | 26363 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26364 | if (is_generic) { |
| | 26365 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type")); |
| | 26366 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26367 | } |
| | 26368 | |
| | 26369 | bool is_var_args; |
| | 26370 | if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_var_args", 3, &is_var_args))) |
| | 26371 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26372 | if (is_var_args && cc != CallingConventionC) { |
| | 26373 | ir_add_error(ira, source_instr, buf_sprintf("varargs functions must have C calling convention")); |
| | 26374 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26375 | } |
| | 26376 | |
| | 26377 | ZigType *return_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "return_type", 4); |
| | 26378 | if (return_type == nullptr) { |
| | 26379 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type")); |
| | 26380 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26381 | } |
| | 26382 | |
| | 26383 | ZigValue *args_value = get_const_field(ira, source_instr->source_node, payload, "args", 5); |
| | 26384 | if (args_value == nullptr) |
| | 26385 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26386 | assert(args_value->special == ConstValSpecialStatic); |
| | 26387 | assert(is_slice(args_value->type)); |
| | 26388 | ZigValue *args_ptr = args_value->data.x_struct.fields[slice_ptr_index]; |
| | 26389 | ZigValue *args_len_value = args_value->data.x_struct.fields[slice_len_index]; |
| | 26390 | size_t args_len = bigint_as_usize(&args_len_value->data.x_bigint); |
| | 26391 | |
| | 26392 | FnTypeId fn_type_id = {}; |
| | 26393 | fn_type_id.return_type = return_type; |
| | 26394 | fn_type_id.param_info = heap::c_allocator.allocate<FnTypeParamInfo>(args_len); |
| | 26395 | fn_type_id.param_count = args_len; |
| | 26396 | fn_type_id.next_param_index = args_len; |
| | 26397 | fn_type_id.is_var_args = is_var_args; |
| | 26398 | fn_type_id.cc = cc; |
| | 26399 | fn_type_id.alignment = alignment; |
| | 26400 | |
| | 26401 | assert(args_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| | 26402 | assert(args_ptr->data.x_ptr.data.base_array.elem_index == 0); |
| | 26403 | ZigValue *args_arr = args_ptr->data.x_ptr.data.base_array.array_val; |
| | 26404 | assert(args_arr->special == ConstValSpecialStatic); |
| | 26405 | assert(args_arr->data.x_array.special == ConstArraySpecialNone); |
| | 26406 | for (size_t i = 0; i < args_len; i++) { |
| | 26407 | ZigValue *arg_value = &args_arr->data.x_array.data.s_none.elements[i]; |
| | 26408 | assert(arg_value->type == ir_type_info_get_type(ira, "FnArg", nullptr)); |
| | 26409 | FnTypeParamInfo *info = &fn_type_id.param_info[i]; |
| | 26410 | Error err; |
| | 26411 | bool is_generic; |
| | 26412 | if ((err = get_const_field_bool(ira, source_instr->source_node, arg_value, "is_generic", 0, &is_generic))) |
| | 26413 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26414 | if (is_generic) { |
| | 26415 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.FnArg.is_generic must be false for @Type")); |
| | 26416 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26417 | } |
| | 26418 | if ((err = get_const_field_bool(ira, source_instr->source_node, arg_value, "is_noalias", 1, &info->is_noalias))) |
| | 26419 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26420 | ZigType *type = get_const_field_meta_type_optional( |
| | 26421 | ira, source_instr->source_node, arg_value, "arg_type", 2); |
| | 26422 | if (type == nullptr) { |
| | 26423 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.FnArg.arg_type must be non-null for @Type")); |
| | 26424 | return ira->codegen->invalid_inst_gen->value->type; |
| | 26425 | } |
| | 26426 | info->type = type; |
| | 26427 | } |
| | 26428 | |
| | 26429 | ZigType *entry = get_fn_type(ira->codegen, &fn_type_id); |
| | 26430 | |
| | 26431 | switch (tagTypeId) { |
| | 26432 | case ZigTypeIdFn: |
| | 26433 | return entry; |
| | 26434 | case ZigTypeIdBoundFn: { |
| | 26435 | ZigType *bound_fn_entry = new_type_table_entry(ZigTypeIdBoundFn); |
| | 26436 | bound_fn_entry->name = *buf_sprintf("(bound %s)", buf_ptr(&entry->name)); |
| | 26437 | bound_fn_entry->data.bound_fn.fn_type = entry; |
| | 26438 | return bound_fn_entry; |
| | 26439 | } |
| | 26440 | default: |
| | 26441 | zig_unreachable(); |
| | 26442 | } |
| | 26443 | } |
| 26339 | } | 26444 | } |
| 26340 | zig_unreachable(); | 26445 | zig_unreachable(); |
| 26341 | } | 26446 | } |