| ... | @@ -25564,7 +25564,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy | ... | @@ -25564,7 +25564,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25564 | result->special = ConstValSpecialStatic; | 25564 | result->special = ConstValSpecialStatic; |
| 25565 | result->type = ir_type_info_get_type(ira, "Fn", nullptr); | 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 | result->data.x_struct.fields = fields; | 25568 | result->data.x_struct.fields = fields; |
| 25569 | | 25569 | |
| 25570 | // calling_convention: TypeInfo.CallingConvention | 25570 | // calling_convention: TypeInfo.CallingConvention |
| ... | @@ -25572,38 +25572,42 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy | ... | @@ -25572,38 +25572,42 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25572 | fields[0]->special = ConstValSpecialStatic; | 25572 | fields[0]->special = ConstValSpecialStatic; |
| 25573 | fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); | 25573 | fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); |
| 25574 | bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); | 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 | // is_generic: bool | 25580 | // is_generic: bool |
| 25576 | ensure_field_index(result->type, "is_generic", 1); | 25581 | ensure_field_index(result->type, "is_generic", 2); |
| 25577 | bool is_generic = type_entry->data.fn.is_generic; | 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 | fields[2]->special = ConstValSpecialStatic; | 25583 | fields[2]->special = ConstValSpecialStatic; |
| 25585 | fields[2]->type = ira->codegen->builtin_types.entry_bool; | 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; | 25585 | fields[2]->data.x_bool = is_generic; |
| 25587 | // return_type: ?type | 25586 | // is_varargs: bool |
| 25588 | ensure_field_index(result->type, "return_type", 3); | 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 | fields[3]->special = ConstValSpecialStatic; | 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 | if (type_entry->data.fn.fn_type_id.return_type == nullptr) | 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 | else { | 25598 | else { |
| 25594 | ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); | 25599 | ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25595 | return_type->special = ConstValSpecialStatic; | 25600 | return_type->special = ConstValSpecialStatic; |
| 25596 | return_type->type = ira->codegen->builtin_types.entry_type; | 25601 | return_type->type = ira->codegen->builtin_types.entry_type; |
| 25597 | return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; | 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 | // args: []TypeInfo.FnArg | 25605 | // args: []TypeInfo.FnArg |
| 25601 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); | 25606 | ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); |
| 25602 | 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))) { |
| 25603 | zig_unreachable(); | 25608 | zig_unreachable(); |
| 25604 | } | 25609 | } |
| 25605 | 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; |
| 25606 | (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); | | |
| 25607 | | 25611 | |
| 25608 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); | 25612 | ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); |
| 25609 | fn_arg_array->special = ConstValSpecialStatic; | 25613 | fn_arg_array->special = ConstValSpecialStatic; |
| ... | @@ -25611,7 +25615,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy | ... | @@ -25611,7 +25615,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25611 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; | 25615 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 25612 | fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); | 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 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { | 25620 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { |
| 25617 | FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; | 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,10 +26331,105 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26327 | return entry; | 26331 | return entry; |
| 26328 | } | 26332 | } |
| 26329 | case ZigTypeIdFn: | 26333 | case ZigTypeIdFn: |
| 26330 | case ZigTypeIdBoundFn: | 26334 | case ZigTypeIdBoundFn: { |
| 26331 | ir_add_error(ira, source_instr, buf_sprintf( | 26335 | assert(payload->special == ConstValSpecialStatic); |
| 26332 | "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); | 26336 | assert(payload->type == ir_type_info_get_type(ira, "Fn", nullptr)); |
| 26333 | return ira->codegen->invalid_inst_gen->value->type; | 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 | zig_unreachable(); | 26434 | zig_unreachable(); |
| 26336 | } | 26435 | } |