| ... | ... | @@ -25607,8 +25607,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25607 | 25607 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { |
| 25608 | 25608 | zig_unreachable(); |
| 25609 | 25609 | } |
| 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); |
| 25610 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count; |
| 25612 | 25611 | |
| 25613 | 25612 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25614 | 25613 | fn_arg_array->special = ConstValSpecialStatic; |
| ... | ... | @@ -25757,6 +25756,17 @@ static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue |
| 25757 | 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 | 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 | 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 | 26342 | return entry; |
| 26333 | 26343 | } |
| 26334 | 26344 | case ZigTypeIdFn: |
| 26335 | | case ZigTypeIdBoundFn: |
| 26336 | | ir_add_error(ira, source_instr, buf_sprintf( |
| 26337 | | "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); |
| 26338 | | return ira->codegen->invalid_inst_gen->value->type; |
| 26345 | case ZigTypeIdBoundFn: { |
| 26346 | assert(payload->special == ConstValSpecialStatic); |
| 26347 | assert(payload->type == ir_type_info_get_type(ira, "Fn", nullptr)); |
| 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 | 26445 | zig_unreachable(); |
| 26341 | 26446 | } |