| ... | ... | @@ -25564,7 +25564,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25564 | 25564 | result->special = ConstValSpecialStatic; |
| 25565 | 25565 | result->type = ir_type_info_get_type(ira, "Fn", nullptr); |
| 25566 | 25566 | |
| 25567 | | ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); |
| 25567 | ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 6); |
| 25568 | 25568 | result->data.x_struct.fields = fields; |
| 25569 | 25569 | |
| 25570 | 25570 | // calling_convention: TypeInfo.CallingConvention |
| ... | ... | @@ -25572,38 +25572,42 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25572 | 25572 | fields[0]->special = ConstValSpecialStatic; |
| 25573 | 25573 | fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); |
| 25574 | 25574 | bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); |
| 25575 | // alignment: u29 |
| 25576 | ensure_field_index(result->type, "alignment", 1); |
| 25577 | fields[1]->special = ConstValSpecialStatic; |
| 25578 | fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; |
| 25579 | bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.fn.fn_type_id.alignment); |
| 25575 | 25580 | // is_generic: bool |
| 25576 | | ensure_field_index(result->type, "is_generic", 1); |
| 25581 | ensure_field_index(result->type, "is_generic", 2); |
| 25577 | 25582 | bool is_generic = type_entry->data.fn.is_generic; |
| 25578 | | fields[1]->special = ConstValSpecialStatic; |
| 25579 | | fields[1]->type = ira->codegen->builtin_types.entry_bool; |
| 25580 | | fields[1]->data.x_bool = is_generic; |
| 25581 | | // is_varargs: bool |
| 25582 | | ensure_field_index(result->type, "is_var_args", 2); |
| 25583 | | bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; |
| 25584 | 25583 | fields[2]->special = ConstValSpecialStatic; |
| 25585 | 25584 | fields[2]->type = ira->codegen->builtin_types.entry_bool; |
| 25586 | | fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; |
| 25587 | | // return_type: ?type |
| 25588 | | ensure_field_index(result->type, "return_type", 3); |
| 25585 | fields[2]->data.x_bool = is_generic; |
| 25586 | // is_varargs: bool |
| 25587 | ensure_field_index(result->type, "is_var_args", 3); |
| 25588 | bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; |
| 25589 | 25589 | fields[3]->special = ConstValSpecialStatic; |
| 25590 | | fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); |
| 25590 | fields[3]->type = ira->codegen->builtin_types.entry_bool; |
| 25591 | fields[3]->data.x_bool = is_varargs; |
| 25592 | // return_type: ?type |
| 25593 | ensure_field_index(result->type, "return_type", 4); |
| 25594 | fields[4]->special = ConstValSpecialStatic; |
| 25595 | fields[4]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); |
| 25591 | 25596 | if (type_entry->data.fn.fn_type_id.return_type == nullptr) |
| 25592 | | fields[3]->data.x_optional = nullptr; |
| 25597 | fields[4]->data.x_optional = nullptr; |
| 25593 | 25598 | else { |
| 25594 | 25599 | ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25595 | 25600 | return_type->special = ConstValSpecialStatic; |
| 25596 | 25601 | return_type->type = ira->codegen->builtin_types.entry_type; |
| 25597 | 25602 | return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; |
| 25598 | | fields[3]->data.x_optional = return_type; |
| 25603 | fields[4]->data.x_optional = return_type; |
| 25599 | 25604 | } |
| 25600 | 25605 | // args: []TypeInfo.FnArg |
| 25601 | 25606 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); |
| 25602 | 25607 | if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { |
| 25603 | 25608 | zig_unreachable(); |
| 25604 | 25609 | } |
| 25605 | | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - |
| 25606 | | (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; |
| 25607 | 25611 | |
| 25608 | 25612 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25609 | 25613 | fn_arg_array->special = ConstValSpecialStatic; |
| ... | ... | @@ -25611,7 +25615,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25611 | 25615 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 25612 | 25616 | fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); |
| 25613 | 25617 | |
| 25614 | | init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); |
| 25618 | init_const_slice(ira->codegen, fields[5], fn_arg_array, 0, fn_arg_count, false); |
| 25615 | 25619 | |
| 25616 | 25620 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { |
| 25617 | 25621 | FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; |
| ... | ... | @@ -26327,10 +26331,105 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26327 | 26331 | return entry; |
| 26328 | 26332 | } |
| 26329 | 26333 | case ZigTypeIdFn: |
| 26330 | | case ZigTypeIdBoundFn: |
| 26331 | | ir_add_error(ira, source_instr, buf_sprintf( |
| 26332 | | "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); |
| 26333 | | return ira->codegen->invalid_inst_gen->value->type; |
| 26334 | case ZigTypeIdBoundFn: { |
| 26335 | assert(payload->special == ConstValSpecialStatic); |
| 26336 | assert(payload->type == ir_type_info_get_type(ira, "Fn", nullptr)); |
| 26337 | |
| 26338 | ZigValue *cc_value = get_const_field(ira, source_instr->source_node, payload, "calling_convention", 0); |
| 26339 | if (cc_value == nullptr) |
| 26340 | return ira->codegen->invalid_inst_gen->value->type; |
| 26341 | assert(cc_value->special == ConstValSpecialStatic); |
| 26342 | assert(cc_value->type == get_builtin_type(ira->codegen, "CallingConvention")); |
| 26343 | CallingConvention cc = (CallingConvention)bigint_as_u32(&cc_value->data.x_enum_tag); |
| 26344 | |
| 26345 | BigInt *alignment = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 1); |
| 26346 | if (alignment == nullptr) |
| 26347 | return ira->codegen->invalid_inst_gen->value->type; |
| 26348 | |
| 26349 | Error err; |
| 26350 | bool is_generic; |
| 26351 | if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_generic", 2, &is_generic))) |
| 26352 | return ira->codegen->invalid_inst_gen->value->type; |
| 26353 | if (is_generic) { |
| 26354 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type")); |
| 26355 | return ira->codegen->invalid_inst_gen->value->type; |
| 26356 | } |
| 26357 | |
| 26358 | bool is_var_args; |
| 26359 | if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_var_args", 3, &is_var_args))) |
| 26360 | return ira->codegen->invalid_inst_gen->value->type; |
| 26361 | if (is_var_args && cc != CallingConventionC) { |
| 26362 | ir_add_error(ira, source_instr, buf_sprintf("varargs functions must have C calling convention")); |
| 26363 | return ira->codegen->invalid_inst_gen->value->type; |
| 26364 | } |
| 26365 | |
| 26366 | ZigType *return_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "return_type", 4); |
| 26367 | if (return_type == nullptr) { |
| 26368 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type")); |
| 26369 | return ira->codegen->invalid_inst_gen->value->type; |
| 26370 | } |
| 26371 | |
| 26372 | ZigValue *args_value = get_const_field(ira, source_instr->source_node, payload, "args", 5); |
| 26373 | if (args_value == nullptr) |
| 26374 | return ira->codegen->invalid_inst_gen->value->type; |
| 26375 | assert(args_value->special == ConstValSpecialStatic); |
| 26376 | assert(is_slice(args_value->type)); |
| 26377 | ZigValue *args_ptr = args_value->data.x_struct.fields[slice_ptr_index]; |
| 26378 | ZigValue *args_len_value = args_value->data.x_struct.fields[slice_len_index]; |
| 26379 | size_t args_len = bigint_as_usize(&args_len_value->data.x_bigint); |
| 26380 | |
| 26381 | FnTypeId fn_type_id = {}; |
| 26382 | fn_type_id.return_type = return_type; |
| 26383 | fn_type_id.param_info = heap::c_allocator.allocate<FnTypeParamInfo>(args_len); |
| 26384 | fn_type_id.param_count = args_len; |
| 26385 | fn_type_id.next_param_index = args_len; |
| 26386 | fn_type_id.is_var_args = is_var_args; |
| 26387 | fn_type_id.cc = cc; |
| 26388 | fn_type_id.alignment = bigint_as_u32(alignment); |
| 26389 | |
| 26390 | assert(args_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 26391 | assert(args_ptr->data.x_ptr.data.base_array.elem_index == 0); |
| 26392 | ZigValue *args_arr = args_ptr->data.x_ptr.data.base_array.array_val; |
| 26393 | assert(args_arr->special == ConstValSpecialStatic); |
| 26394 | assert(args_arr->data.x_array.special == ConstArraySpecialNone); |
| 26395 | for (size_t i = 0; i < args_len; i++) { |
| 26396 | ZigValue *arg_value = &args_arr->data.x_array.data.s_none.elements[i]; |
| 26397 | assert(arg_value->type == ir_type_info_get_type(ira, "FnArg", nullptr)); |
| 26398 | FnTypeParamInfo *info = &fn_type_id.param_info[i]; |
| 26399 | Error err; |
| 26400 | bool is_generic; |
| 26401 | if ((err = get_const_field_bool(ira, source_instr->source_node, arg_value, "is_generic", 0, &is_generic))) |
| 26402 | return ira->codegen->invalid_inst_gen->value->type; |
| 26403 | if (is_generic) { |
| 26404 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.FnArg.is_generic must be false for @Type")); |
| 26405 | return ira->codegen->invalid_inst_gen->value->type; |
| 26406 | } |
| 26407 | if ((err = get_const_field_bool(ira, source_instr->source_node, arg_value, "is_noalias", 1, &info->is_noalias))) |
| 26408 | return ira->codegen->invalid_inst_gen->value->type; |
| 26409 | ZigType *type = get_const_field_meta_type_optional( |
| 26410 | ira, source_instr->source_node, arg_value, "arg_type", 2); |
| 26411 | if (type == nullptr) { |
| 26412 | ir_add_error(ira, source_instr, buf_sprintf("TypeInfo.FnArg.arg_type must be non-null for @Type")); |
| 26413 | return ira->codegen->invalid_inst_gen->value->type; |
| 26414 | } |
| 26415 | info->type = type; |
| 26416 | } |
| 26417 | |
| 26418 | ZigType *entry = get_fn_type(ira->codegen, &fn_type_id); |
| 26419 | |
| 26420 | switch (tagTypeId) { |
| 26421 | case ZigTypeIdFn: |
| 26422 | return entry; |
| 26423 | case ZigTypeIdBoundFn: { |
| 26424 | ZigType *bound_fn_entry = new_type_table_entry(ZigTypeIdBoundFn); |
| 26425 | bound_fn_entry->name = *buf_sprintf("(bound %s)", buf_ptr(&entry->name)); |
| 26426 | bound_fn_entry->data.bound_fn.fn_type = entry; |
| 26427 | return bound_fn_entry; |
| 26428 | } |
| 26429 | default: |
| 26430 | zig_unreachable(); |
| 26431 | } |
| 26432 | } |
| 26334 | 26433 | } |
| 26335 | 26434 | zig_unreachable(); |
| 26336 | 26435 | } |