| ... | @@ -617,6 +617,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { | ... | @@ -617,6 +617,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { |
| 617 | return IrInstructionIdOffsetOf; | 617 | return IrInstructionIdOffsetOf; |
| 618 | } | 618 | } |
| 619 | | 619 | |
| | 620 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { |
| | 621 | return IrInstructionIdTypeInfo; |
| | 622 | } |
| | 623 | |
| 620 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { | 624 | static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { |
| 621 | return IrInstructionIdTypeId; | 625 | return IrInstructionIdTypeId; |
| 622 | } | 626 | } |
| ... | @@ -2442,6 +2446,16 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode * | ... | @@ -2442,6 +2446,16 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode * |
| 2442 | return &instruction->base; | 2446 | return &instruction->base; |
| 2443 | } | 2447 | } |
| 2444 | | 2448 | |
| | 2449 | static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| | 2450 | IrInstruction *type_value) { |
| | 2451 | IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); |
| | 2452 | instruction->type_value = type_value; |
| | 2453 | |
| | 2454 | ir_ref_instruction(type_value, irb->current_basic_block); |
| | 2455 | |
| | 2456 | return &instruction->base; |
| | 2457 | } |
| | 2458 | |
| 2445 | static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2459 | static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2446 | IrInstruction *type_value) | 2460 | IrInstruction *type_value) |
| 2447 | { | 2461 | { |
| ... | @@ -4085,6 +4099,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4085,6 +4099,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4085 | | 4099 | |
| 4086 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); | 4100 | return ir_build_load_ptr(irb, scope, node, ptr_instruction); |
| 4087 | } | 4101 | } |
| | 4102 | case BuiltinFnIdTypeInfo: |
| | 4103 | { |
| | 4104 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 4105 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); |
| | 4106 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 4107 | return arg0_value; |
| | 4108 | |
| | 4109 | IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); |
| | 4110 | return ir_lval_wrap(irb, scope, type_info, lval); |
| | 4111 | } |
| 4088 | case BuiltinFnIdBreakpoint: | 4112 | case BuiltinFnIdBreakpoint: |
| 4089 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); | 4113 | return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); |
| 4090 | case BuiltinFnIdReturnAddress: | 4114 | case BuiltinFnIdReturnAddress: |
| ... | @@ -13388,7 +13412,6 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -13388,7 +13412,6 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 13388 | return ira->codegen->invalid_instruction; | 13412 | return ira->codegen->invalid_instruction; |
| 13389 | } | 13413 | } |
| 13390 | | 13414 | |
| 13391 | | | |
| 13392 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, | 13415 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 13393 | IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type) | 13416 | IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type) |
| 13394 | { | 13417 | { |
| ... | @@ -13450,6 +13473,51 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -13450,6 +13473,51 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 13450 | } else if (bare_type->id == TypeTableEntryIdUnion) { | 13473 | } else if (bare_type->id == TypeTableEntryIdUnion) { |
| 13451 | TypeUnionField *field = find_union_type_field(bare_type, field_name); | 13474 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 13452 | if (field) { | 13475 | if (field) { |
| | 13476 | if (instr_is_comptime(container_ptr)) { |
| | 13477 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| | 13478 | if (!ptr_val) |
| | 13479 | return ira->codegen->invalid_instruction; |
| | 13480 | |
| | 13481 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 13482 | ConstExprValue *union_val = const_ptr_pointee(ira->codegen, ptr_val); |
| | 13483 | if (type_is_invalid(union_val->type)) |
| | 13484 | return ira->codegen->invalid_instruction; |
| | 13485 | |
| | 13486 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| | 13487 | if (actual_field == nullptr) |
| | 13488 | zig_unreachable(); |
| | 13489 | |
| | 13490 | if (field != actual_field) { |
| | 13491 | ir_add_error_node(ira, source_instr->source_node, |
| | 13492 | buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), |
| | 13493 | buf_ptr(actual_field->name))); |
| | 13494 | return ira->codegen->invalid_instruction; |
| | 13495 | } |
| | 13496 | |
| | 13497 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| | 13498 | |
| | 13499 | TypeTableEntry *field_type = field->type_entry; |
| | 13500 | if (field_type->id == TypeTableEntryIdVoid) |
| | 13501 | { |
| | 13502 | assert(payload_val == nullptr); |
| | 13503 | payload_val = create_const_vals(1); |
| | 13504 | payload_val->special = ConstValSpecialStatic; |
| | 13505 | payload_val->type = field_type; |
| | 13506 | } |
| | 13507 | |
| | 13508 | TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile, |
| | 13509 | get_abi_alignment(ira->codegen, field_type), 0, 0); |
| | 13510 | |
| | 13511 | IrInstruction *result = ir_get_const(ira, source_instr); |
| | 13512 | ConstExprValue *const_val = &result->value; |
| | 13513 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 13514 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| | 13515 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| | 13516 | const_val->type = ptr_type; |
| | 13517 | return result; |
| | 13518 | } |
| | 13519 | } |
| | 13520 | |
| 13453 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); | 13521 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); |
| 13454 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | 13522 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 13455 | get_abi_alignment(ira->codegen, field->type_entry), 0, 0); | 13523 | get_abi_alignment(ira->codegen, field->type_entry), 0, 0); |
| ... | @@ -15679,6 +15747,895 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, | ... | @@ -15679,6 +15747,895 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, |
| 15679 | return ira->codegen->builtin_types.entry_num_lit_int; | 15747 | return ira->codegen->builtin_types.entry_num_lit_int; |
| 15680 | } | 15748 | } |
| 15681 | | 15749 | |
| | 15750 | static void ensure_field_index(TypeTableEntry *type, const char *field_name, size_t index) |
| | 15751 | { |
| | 15752 | Buf *field_name_buf; |
| | 15753 | |
| | 15754 | assert(type != nullptr && !type_is_invalid(type)); |
| | 15755 | // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't |
| | 15756 | // leak memory in debug mode. |
| | 15757 | assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && |
| | 15758 | (buf_deinit(field_name_buf), true)); |
| | 15759 | } |
| | 15760 | |
| | 15761 | static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, TypeTableEntry *root = nullptr) |
| | 15762 | { |
| | 15763 | static ConstExprValue *type_info_var = nullptr; |
| | 15764 | static TypeTableEntry *type_info_type = nullptr; |
| | 15765 | if (type_info_var == nullptr) |
| | 15766 | { |
| | 15767 | type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); |
| | 15768 | assert(type_info_var->type->id == TypeTableEntryIdMetaType); |
| | 15769 | |
| | 15770 | ensure_complete_type(ira->codegen, type_info_var->data.x_type); |
| | 15771 | type_info_type = type_info_var->data.x_type; |
| | 15772 | assert(type_info_type->id == TypeTableEntryIdUnion); |
| | 15773 | } |
| | 15774 | |
| | 15775 | if (type_name == nullptr && root == nullptr) |
| | 15776 | return type_info_type; |
| | 15777 | else if (type_name == nullptr) |
| | 15778 | return root; |
| | 15779 | |
| | 15780 | TypeTableEntry *root_type = (root == nullptr) ? type_info_type : root; |
| | 15781 | |
| | 15782 | ScopeDecls *type_info_scope = get_container_scope(root_type); |
| | 15783 | assert(type_info_scope != nullptr); |
| | 15784 | |
| | 15785 | Buf field_name = BUF_INIT; |
| | 15786 | buf_init_from_str(&field_name, type_name); |
| | 15787 | auto entry = type_info_scope->decl_table.maybe_get(&field_name); |
| | 15788 | buf_deinit(&field_name); |
| | 15789 | assert(entry != nullptr); |
| | 15790 | |
| | 15791 | TldVar *tld = (TldVar *)entry->value; |
| | 15792 | assert(tld->base.id == TldIdVar); |
| | 15793 | |
| | 15794 | VariableTableEntry *var = tld->var; |
| | 15795 | |
| | 15796 | ensure_complete_type(ira->codegen, var->value->type); |
| | 15797 | assert(var->value->type->id == TypeTableEntryIdMetaType); |
| | 15798 | return var->value->data.x_type; |
| | 15799 | } |
| | 15800 | |
| | 15801 | static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) |
| | 15802 | { |
| | 15803 | TypeTableEntry *type_info_definition_type = ir_type_info_get_type(ira, "Definition"); |
| | 15804 | ensure_complete_type(ira->codegen, type_info_definition_type); |
| | 15805 | ensure_field_index(type_info_definition_type, "name", 0); |
| | 15806 | ensure_field_index(type_info_definition_type, "is_pub", 1); |
| | 15807 | ensure_field_index(type_info_definition_type, "data", 2); |
| | 15808 | |
| | 15809 | TypeTableEntry *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); |
| | 15810 | ensure_complete_type(ira->codegen, type_info_definition_data_type); |
| | 15811 | |
| | 15812 | TypeTableEntry *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); |
| | 15813 | ensure_complete_type(ira->codegen, type_info_fn_def_type); |
| | 15814 | |
| | 15815 | TypeTableEntry *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); |
| | 15816 | ensure_complete_type(ira->codegen, type_info_fn_def_inline_type); |
| | 15817 | |
| | 15818 | // Loop through our definitions once to figure out how many definitions we will generate info for. |
| | 15819 | auto decl_it = decls_scope->decl_table.entry_iterator(); |
| | 15820 | decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; |
| | 15821 | int definition_count = 0; |
| | 15822 | |
| | 15823 | while ((curr_entry = decl_it.next()) != nullptr) |
| | 15824 | { |
| | 15825 | // If the definition is unresolved, force it to be resolved again. |
| | 15826 | if (curr_entry->value->resolution == TldResolutionUnresolved) |
| | 15827 | { |
| | 15828 | resolve_top_level_decl(ira->codegen, curr_entry->value, false, curr_entry->value->source_node); |
| | 15829 | if (curr_entry->value->resolution != TldResolutionOk) |
| | 15830 | { |
| | 15831 | return; |
| | 15832 | } |
| | 15833 | } |
| | 15834 | |
| | 15835 | // Skip comptime blocks and test functions. |
| | 15836 | if (curr_entry->value->id != TldIdCompTime) |
| | 15837 | { |
| | 15838 | if (curr_entry->value->id == TldIdFn) |
| | 15839 | { |
| | 15840 | FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; |
| | 15841 | if (fn_entry->is_test) |
| | 15842 | continue; |
| | 15843 | } |
| | 15844 | |
| | 15845 | definition_count += 1; |
| | 15846 | } |
| | 15847 | } |
| | 15848 | |
| | 15849 | ConstExprValue *definition_array = create_const_vals(1); |
| | 15850 | definition_array->special = ConstValSpecialStatic; |
| | 15851 | definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); |
| | 15852 | definition_array->data.x_array.special = ConstArraySpecialNone; |
| | 15853 | definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 15854 | definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); |
| | 15855 | init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); |
| | 15856 | |
| | 15857 | // Loop through the definitions and generate info. |
| | 15858 | decl_it = decls_scope->decl_table.entry_iterator(); |
| | 15859 | curr_entry = nullptr; |
| | 15860 | int definition_index = 0; |
| | 15861 | while ((curr_entry = decl_it.next()) != nullptr) |
| | 15862 | { |
| | 15863 | // Skip comptime blocks and test functions. |
| | 15864 | if (curr_entry->value->id == TldIdCompTime) |
| | 15865 | continue; |
| | 15866 | else if (curr_entry->value->id == TldIdFn) |
| | 15867 | { |
| | 15868 | FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; |
| | 15869 | if (fn_entry->is_test) |
| | 15870 | continue; |
| | 15871 | } |
| | 15872 | |
| | 15873 | ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; |
| | 15874 | |
| | 15875 | definition_val->special = ConstValSpecialStatic; |
| | 15876 | definition_val->type = type_info_definition_type; |
| | 15877 | |
| | 15878 | ConstExprValue *inner_fields = create_const_vals(3); |
| | 15879 | ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); |
| | 15880 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); |
| | 15881 | inner_fields[1].special = ConstValSpecialStatic; |
| | 15882 | inner_fields[1].type = ira->codegen->builtin_types.entry_bool; |
| | 15883 | inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; |
| | 15884 | inner_fields[2].special = ConstValSpecialStatic; |
| | 15885 | inner_fields[2].type = type_info_definition_data_type; |
| | 15886 | inner_fields[2].data.x_union.parent.id = ConstParentIdStruct; |
| | 15887 | inner_fields[2].data.x_union.parent.data.p_struct.struct_val = definition_val; |
| | 15888 | inner_fields[2].data.x_union.parent.data.p_struct.field_index = 1; |
| | 15889 | |
| | 15890 | switch (curr_entry->value->id) |
| | 15891 | { |
| | 15892 | case TldIdVar: |
| | 15893 | { |
| | 15894 | VariableTableEntry *var = ((TldVar *)curr_entry->value)->var; |
| | 15895 | ensure_complete_type(ira->codegen, var->value->type); |
| | 15896 | if (var->value->type->id == TypeTableEntryIdMetaType) |
| | 15897 | { |
| | 15898 | // We have a variable of type 'type', so it's actually a type definition. |
| | 15899 | // 0: Data.Type: type |
| | 15900 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); |
| | 15901 | inner_fields[2].data.x_union.payload = var->value; |
| | 15902 | } |
| | 15903 | else |
| | 15904 | { |
| | 15905 | // We have a variable of another type, so we store the type of the variable. |
| | 15906 | // 1: Data.Var: type |
| | 15907 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); |
| | 15908 | |
| | 15909 | ConstExprValue *payload = create_const_vals(1); |
| | 15910 | payload->type = ira->codegen->builtin_types.entry_type; |
| | 15911 | payload->data.x_type = var->value->type; |
| | 15912 | |
| | 15913 | inner_fields[2].data.x_union.payload = payload; |
| | 15914 | } |
| | 15915 | |
| | 15916 | break; |
| | 15917 | } |
| | 15918 | case TldIdFn: |
| | 15919 | { |
| | 15920 | // 2: Data.Fn: Data.FnDef |
| | 15921 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); |
| | 15922 | |
| | 15923 | FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; |
| | 15924 | assert(!fn_entry->is_test); |
| | 15925 | |
| | 15926 | analyze_fn_body(ira->codegen, fn_entry); |
| | 15927 | if (fn_entry->anal_state == FnAnalStateInvalid) |
| | 15928 | return; |
| | 15929 | |
| | 15930 | AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); |
| | 15931 | |
| | 15932 | ConstExprValue *fn_def_val = create_const_vals(1); |
| | 15933 | fn_def_val->special = ConstValSpecialStatic; |
| | 15934 | fn_def_val->type = type_info_fn_def_type; |
| | 15935 | fn_def_val->data.x_struct.parent.id = ConstParentIdUnion; |
| | 15936 | fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; |
| | 15937 | |
| | 15938 | ConstExprValue *fn_def_fields = create_const_vals(9); |
| | 15939 | fn_def_val->data.x_struct.fields = fn_def_fields; |
| | 15940 | |
| | 15941 | // fn_type: type |
| | 15942 | ensure_field_index(fn_def_val->type, "fn_type", 0); |
| | 15943 | fn_def_fields[0].special = ConstValSpecialStatic; |
| | 15944 | fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; |
| | 15945 | fn_def_fields[0].data.x_type = fn_entry->type_entry; |
| | 15946 | // inline_type: Data.FnDef.Inline |
| | 15947 | ensure_field_index(fn_def_val->type, "inline_type", 1); |
| | 15948 | fn_def_fields[1].special = ConstValSpecialStatic; |
| | 15949 | fn_def_fields[1].type = type_info_fn_def_inline_type; |
| | 15950 | bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); |
| | 15951 | // calling_convention: TypeInfo.CallingConvention |
| | 15952 | ensure_field_index(fn_def_val->type, "calling_convention", 2); |
| | 15953 | fn_def_fields[2].special = ConstValSpecialStatic; |
| | 15954 | fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention"); |
| | 15955 | bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); |
| | 15956 | // is_var_args: bool |
| | 15957 | ensure_field_index(fn_def_val->type, "is_var_args", 3); |
| | 15958 | bool is_varargs = fn_node->is_var_args; |
| | 15959 | fn_def_fields[3].special = ConstValSpecialStatic; |
| | 15960 | fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; |
| | 15961 | fn_def_fields[3].data.x_bool = is_varargs; |
| | 15962 | // is_extern: bool |
| | 15963 | ensure_field_index(fn_def_val->type, "is_extern", 4); |
| | 15964 | fn_def_fields[4].special = ConstValSpecialStatic; |
| | 15965 | fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; |
| | 15966 | fn_def_fields[4].data.x_bool = fn_node->is_extern; |
| | 15967 | // is_export: bool |
| | 15968 | ensure_field_index(fn_def_val->type, "is_export", 5); |
| | 15969 | fn_def_fields[5].special = ConstValSpecialStatic; |
| | 15970 | fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; |
| | 15971 | fn_def_fields[5].data.x_bool = fn_node->is_export; |
| | 15972 | // lib_name: ?[]const u8 |
| | 15973 | ensure_field_index(fn_def_val->type, "lib_name", 6); |
| | 15974 | fn_def_fields[6].special = ConstValSpecialStatic; |
| | 15975 | fn_def_fields[6].type = get_maybe_type(ira->codegen, |
| | 15976 | get_slice_type(ira->codegen, get_pointer_to_type(ira->codegen, |
| | 15977 | ira->codegen->builtin_types.entry_u8, true))); |
| | 15978 | if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) |
| | 15979 | { |
| | 15980 | fn_def_fields[6].data.x_maybe = create_const_vals(1); |
| | 15981 | ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); |
| | 15982 | init_const_slice(ira->codegen, fn_def_fields[6].data.x_maybe, lib_name, 0, buf_len(fn_node->lib_name), true); |
| | 15983 | } |
| | 15984 | else |
| | 15985 | fn_def_fields[6].data.x_maybe = nullptr; |
| | 15986 | // return_type: type |
| | 15987 | ensure_field_index(fn_def_val->type, "return_type", 7); |
| | 15988 | fn_def_fields[7].special = ConstValSpecialStatic; |
| | 15989 | fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; |
| | 15990 | if (fn_entry->src_implicit_return_type != nullptr) |
| | 15991 | fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type; |
| | 15992 | else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr) |
| | 15993 | fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.gen_return_type; |
| | 15994 | else |
| | 15995 | fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| | 15996 | // arg_names: [][] const u8 |
| | 15997 | ensure_field_index(fn_def_val->type, "arg_names", 8); |
| | 15998 | size_t fn_arg_count = fn_entry->variable_list.length; |
| | 15999 | ConstExprValue *fn_arg_name_array = create_const_vals(1); |
| | 16000 | fn_arg_name_array->special = ConstValSpecialStatic; |
| | 16001 | fn_arg_name_array->type = get_array_type(ira->codegen, get_slice_type(ira->codegen, |
| | 16002 | get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true)), fn_arg_count); |
| | 16003 | fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; |
| | 16004 | fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16005 | fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); |
| | 16006 | |
| | 16007 | init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); |
| | 16008 | |
| | 16009 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) |
| | 16010 | { |
| | 16011 | VariableTableEntry *arg_var = fn_entry->variable_list.at(fn_arg_index); |
| | 16012 | ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index]; |
| | 16013 | ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); |
| | 16014 | init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); |
| | 16015 | fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16016 | fn_arg_name_val->data.x_struct.parent.data.p_array.array_val = fn_arg_name_array; |
| | 16017 | fn_arg_name_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; |
| | 16018 | } |
| | 16019 | |
| | 16020 | inner_fields[2].data.x_union.payload = fn_def_val; |
| | 16021 | break; |
| | 16022 | } |
| | 16023 | case TldIdContainer: |
| | 16024 | { |
| | 16025 | TypeTableEntry *type_entry = ((TldContainer *)curr_entry->value)->type_entry; |
| | 16026 | ensure_complete_type(ira->codegen, type_entry); |
| | 16027 | // This is a type. |
| | 16028 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); |
| | 16029 | |
| | 16030 | ConstExprValue *payload = create_const_vals(1); |
| | 16031 | payload->type = ira->codegen->builtin_types.entry_type; |
| | 16032 | payload->data.x_type = type_entry; |
| | 16033 | |
| | 16034 | inner_fields[2].data.x_union.payload = payload; |
| | 16035 | |
| | 16036 | break; |
| | 16037 | } |
| | 16038 | default: |
| | 16039 | zig_unreachable(); |
| | 16040 | } |
| | 16041 | |
| | 16042 | definition_val->data.x_struct.fields = inner_fields; |
| | 16043 | definition_index++; |
| | 16044 | } |
| | 16045 | |
| | 16046 | assert(definition_index == definition_count); |
| | 16047 | } |
| | 16048 | |
| | 16049 | static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) |
| | 16050 | { |
| | 16051 | assert(type_entry != nullptr); |
| | 16052 | assert(!type_is_invalid(type_entry)); |
| | 16053 | |
| | 16054 | ensure_complete_type(ira->codegen, type_entry); |
| | 16055 | |
| | 16056 | const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, |
| | 16057 | TypeTableEntry *type_info_enum_field_type) { |
| | 16058 | enum_field_val->special = ConstValSpecialStatic; |
| | 16059 | enum_field_val->type = type_info_enum_field_type; |
| | 16060 | |
| | 16061 | ConstExprValue *inner_fields = create_const_vals(2); |
| | 16062 | inner_fields[1].special = ConstValSpecialStatic; |
| | 16063 | inner_fields[1].type = ira->codegen->builtin_types.entry_usize; |
| | 16064 | |
| | 16065 | ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); |
| | 16066 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); |
| | 16067 | |
| | 16068 | bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); |
| | 16069 | |
| | 16070 | enum_field_val->data.x_struct.fields = inner_fields; |
| | 16071 | }; |
| | 16072 | |
| | 16073 | ConstExprValue *result = nullptr; |
| | 16074 | switch (type_entry->id) |
| | 16075 | { |
| | 16076 | case TypeTableEntryIdInvalid: |
| | 16077 | zig_unreachable(); |
| | 16078 | case TypeTableEntryIdMetaType: |
| | 16079 | case TypeTableEntryIdVoid: |
| | 16080 | case TypeTableEntryIdBool: |
| | 16081 | case TypeTableEntryIdUnreachable: |
| | 16082 | case TypeTableEntryIdNumLitFloat: |
| | 16083 | case TypeTableEntryIdNumLitInt: |
| | 16084 | case TypeTableEntryIdUndefLit: |
| | 16085 | case TypeTableEntryIdNullLit: |
| | 16086 | case TypeTableEntryIdNamespace: |
| | 16087 | case TypeTableEntryIdBlock: |
| | 16088 | case TypeTableEntryIdArgTuple: |
| | 16089 | case TypeTableEntryIdOpaque: |
| | 16090 | return nullptr; |
| | 16091 | default: |
| | 16092 | { |
| | 16093 | // Lookup an available value in our cache. |
| | 16094 | auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); |
| | 16095 | if (entry != nullptr) |
| | 16096 | return entry->value; |
| | 16097 | |
| | 16098 | // Fallthrough if we don't find one. |
| | 16099 | } |
| | 16100 | case TypeTableEntryIdInt: |
| | 16101 | { |
| | 16102 | result = create_const_vals(1); |
| | 16103 | result->special = ConstValSpecialStatic; |
| | 16104 | result->type = ir_type_info_get_type(ira, "Int"); |
| | 16105 | |
| | 16106 | ConstExprValue *fields = create_const_vals(2); |
| | 16107 | result->data.x_struct.fields = fields; |
| | 16108 | |
| | 16109 | // is_signed: bool |
| | 16110 | ensure_field_index(result->type, "is_signed", 0); |
| | 16111 | fields[0].special = ConstValSpecialStatic; |
| | 16112 | fields[0].type = ira->codegen->builtin_types.entry_bool; |
| | 16113 | fields[0].data.x_bool = type_entry->data.integral.is_signed; |
| | 16114 | // bits: u8 |
| | 16115 | ensure_field_index(result->type, "bits", 1); |
| | 16116 | fields[1].special = ConstValSpecialStatic; |
| | 16117 | fields[1].type = ira->codegen->builtin_types.entry_u8; |
| | 16118 | bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); |
| | 16119 | |
| | 16120 | break; |
| | 16121 | } |
| | 16122 | case TypeTableEntryIdFloat: |
| | 16123 | { |
| | 16124 | result = create_const_vals(1); |
| | 16125 | result->special = ConstValSpecialStatic; |
| | 16126 | result->type = ir_type_info_get_type(ira, "Float"); |
| | 16127 | |
| | 16128 | ConstExprValue *fields = create_const_vals(1); |
| | 16129 | result->data.x_struct.fields = fields; |
| | 16130 | |
| | 16131 | // bits: u8 |
| | 16132 | ensure_field_index(result->type, "bits", 0); |
| | 16133 | fields[0].special = ConstValSpecialStatic; |
| | 16134 | fields[0].type = ira->codegen->builtin_types.entry_u8; |
| | 16135 | bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); |
| | 16136 | |
| | 16137 | break; |
| | 16138 | } |
| | 16139 | case TypeTableEntryIdPointer: |
| | 16140 | { |
| | 16141 | result = create_const_vals(1); |
| | 16142 | result->special = ConstValSpecialStatic; |
| | 16143 | result->type = ir_type_info_get_type(ira, "Pointer"); |
| | 16144 | |
| | 16145 | ConstExprValue *fields = create_const_vals(4); |
| | 16146 | result->data.x_struct.fields = fields; |
| | 16147 | |
| | 16148 | // is_const: bool |
| | 16149 | ensure_field_index(result->type, "is_const", 0); |
| | 16150 | fields[0].special = ConstValSpecialStatic; |
| | 16151 | fields[0].type = ira->codegen->builtin_types.entry_bool; |
| | 16152 | fields[0].data.x_bool = type_entry->data.pointer.is_const; |
| | 16153 | // is_volatile: bool |
| | 16154 | ensure_field_index(result->type, "is_volatile", 1); |
| | 16155 | fields[1].special = ConstValSpecialStatic; |
| | 16156 | fields[1].type = ira->codegen->builtin_types.entry_bool; |
| | 16157 | fields[1].data.x_bool = type_entry->data.pointer.is_volatile; |
| | 16158 | // alignment: u32 |
| | 16159 | ensure_field_index(result->type, "alignment", 2); |
| | 16160 | fields[2].special = ConstValSpecialStatic; |
| | 16161 | fields[2].type = ira->codegen->builtin_types.entry_u32; |
| | 16162 | bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); |
| | 16163 | // child: type |
| | 16164 | ensure_field_index(result->type, "child", 3); |
| | 16165 | fields[3].special = ConstValSpecialStatic; |
| | 16166 | fields[3].type = ira->codegen->builtin_types.entry_type; |
| | 16167 | fields[3].data.x_type = type_entry->data.pointer.child_type; |
| | 16168 | |
| | 16169 | break; |
| | 16170 | } |
| | 16171 | case TypeTableEntryIdArray: |
| | 16172 | { |
| | 16173 | result = create_const_vals(1); |
| | 16174 | result->special = ConstValSpecialStatic; |
| | 16175 | result->type = ir_type_info_get_type(ira, "Array"); |
| | 16176 | |
| | 16177 | ConstExprValue *fields = create_const_vals(2); |
| | 16178 | result->data.x_struct.fields = fields; |
| | 16179 | |
| | 16180 | // len: usize |
| | 16181 | ensure_field_index(result->type, "len", 0); |
| | 16182 | fields[0].special = ConstValSpecialStatic; |
| | 16183 | fields[0].type = ira->codegen->builtin_types.entry_usize; |
| | 16184 | bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); |
| | 16185 | // child: type |
| | 16186 | ensure_field_index(result->type, "child", 1); |
| | 16187 | fields[1].special = ConstValSpecialStatic; |
| | 16188 | fields[1].type = ira->codegen->builtin_types.entry_type; |
| | 16189 | fields[1].data.x_type = type_entry->data.array.child_type; |
| | 16190 | |
| | 16191 | break; |
| | 16192 | } |
| | 16193 | case TypeTableEntryIdMaybe: |
| | 16194 | { |
| | 16195 | result = create_const_vals(1); |
| | 16196 | result->special = ConstValSpecialStatic; |
| | 16197 | result->type = ir_type_info_get_type(ira, "Nullable"); |
| | 16198 | |
| | 16199 | ConstExprValue *fields = create_const_vals(1); |
| | 16200 | result->data.x_struct.fields = fields; |
| | 16201 | |
| | 16202 | // child: type |
| | 16203 | ensure_field_index(result->type, "child", 0); |
| | 16204 | fields[0].special = ConstValSpecialStatic; |
| | 16205 | fields[0].type = ira->codegen->builtin_types.entry_type; |
| | 16206 | fields[0].data.x_type = type_entry->data.maybe.child_type; |
| | 16207 | |
| | 16208 | break; |
| | 16209 | } |
| | 16210 | case TypeTableEntryIdPromise: |
| | 16211 | { |
| | 16212 | result = create_const_vals(1); |
| | 16213 | result->special = ConstValSpecialStatic; |
| | 16214 | result->type = ir_type_info_get_type(ira, "Promise"); |
| | 16215 | |
| | 16216 | ConstExprValue *fields = create_const_vals(1); |
| | 16217 | result->data.x_struct.fields = fields; |
| | 16218 | |
| | 16219 | // @TODO ?type instead of using @typeOf(undefined) when we have no type. |
| | 16220 | // child: type |
| | 16221 | ensure_field_index(result->type, "child", 0); |
| | 16222 | fields[0].special = ConstValSpecialStatic; |
| | 16223 | fields[0].type = ira->codegen->builtin_types.entry_type; |
| | 16224 | |
| | 16225 | if (type_entry->data.promise.result_type == nullptr) |
| | 16226 | fields[0].data.x_type = ira->codegen->builtin_types.entry_undef; |
| | 16227 | else |
| | 16228 | fields[0].data.x_type = type_entry->data.promise.result_type; |
| | 16229 | |
| | 16230 | break; |
| | 16231 | } |
| | 16232 | case TypeTableEntryIdEnum: |
| | 16233 | { |
| | 16234 | result = create_const_vals(1); |
| | 16235 | result->special = ConstValSpecialStatic; |
| | 16236 | result->type = ir_type_info_get_type(ira, "Enum"); |
| | 16237 | |
| | 16238 | ConstExprValue *fields = create_const_vals(4); |
| | 16239 | result->data.x_struct.fields = fields; |
| | 16240 | |
| | 16241 | // layout: ContainerLayout |
| | 16242 | ensure_field_index(result->type, "layout", 0); |
| | 16243 | fields[0].special = ConstValSpecialStatic; |
| | 16244 | fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); |
| | 16245 | bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); |
| | 16246 | // tag_type: type |
| | 16247 | ensure_field_index(result->type, "tag_type", 1); |
| | 16248 | fields[1].special = ConstValSpecialStatic; |
| | 16249 | fields[1].type = ira->codegen->builtin_types.entry_type; |
| | 16250 | fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; |
| | 16251 | // fields: []TypeInfo.EnumField |
| | 16252 | ensure_field_index(result->type, "fields", 2); |
| | 16253 | |
| | 16254 | TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); |
| | 16255 | uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; |
| | 16256 | |
| | 16257 | ConstExprValue *enum_field_array = create_const_vals(1); |
| | 16258 | enum_field_array->special = ConstValSpecialStatic; |
| | 16259 | enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); |
| | 16260 | enum_field_array->data.x_array.special = ConstArraySpecialNone; |
| | 16261 | enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16262 | enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count); |
| | 16263 | |
| | 16264 | init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); |
| | 16265 | |
| | 16266 | for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) |
| | 16267 | { |
| | 16268 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; |
| | 16269 | ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; |
| | 16270 | make_enum_field_val(enum_field_val, enum_field, type_info_enum_field_type); |
| | 16271 | enum_field_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16272 | enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; |
| | 16273 | enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; |
| | 16274 | } |
| | 16275 | // defs: []TypeInfo.Definition |
| | 16276 | ensure_field_index(result->type, "defs", 3); |
| | 16277 | ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope); |
| | 16278 | |
| | 16279 | break; |
| | 16280 | } |
| | 16281 | case TypeTableEntryIdErrorSet: |
| | 16282 | { |
| | 16283 | result = create_const_vals(1); |
| | 16284 | result->special = ConstValSpecialStatic; |
| | 16285 | result->type = ir_type_info_get_type(ira, "ErrorSet"); |
| | 16286 | |
| | 16287 | ConstExprValue *fields = create_const_vals(1); |
| | 16288 | result->data.x_struct.fields = fields; |
| | 16289 | |
| | 16290 | // errors: []TypeInfo.Error |
| | 16291 | ensure_field_index(result->type, "errors", 0); |
| | 16292 | |
| | 16293 | TypeTableEntry *type_info_error_type = ir_type_info_get_type(ira, "Error"); |
| | 16294 | uint32_t error_count = type_entry->data.error_set.err_count; |
| | 16295 | ConstExprValue *error_array = create_const_vals(1); |
| | 16296 | error_array->special = ConstValSpecialStatic; |
| | 16297 | error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); |
| | 16298 | error_array->data.x_array.special = ConstArraySpecialNone; |
| | 16299 | error_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16300 | error_array->data.x_array.s_none.elements = create_const_vals(error_count); |
| | 16301 | |
| | 16302 | init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); |
| | 16303 | for (uint32_t error_index = 0; error_index < error_count; error_index++) |
| | 16304 | { |
| | 16305 | ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; |
| | 16306 | ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index]; |
| | 16307 | |
| | 16308 | error_val->special = ConstValSpecialStatic; |
| | 16309 | error_val->type = type_info_error_type; |
| | 16310 | |
| | 16311 | ConstExprValue *inner_fields = create_const_vals(2); |
| | 16312 | inner_fields[1].special = ConstValSpecialStatic; |
| | 16313 | inner_fields[1].type = ira->codegen->builtin_types.entry_usize; |
| | 16314 | |
| | 16315 | ConstExprValue *name = nullptr; |
| | 16316 | if (error->cached_error_name_val != nullptr) |
| | 16317 | name = error->cached_error_name_val; |
| | 16318 | if (name == nullptr) |
| | 16319 | name = create_const_str_lit(ira->codegen, &error->name); |
| | 16320 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); |
| | 16321 | bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); |
| | 16322 | |
| | 16323 | error_val->data.x_struct.fields = inner_fields; |
| | 16324 | error_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16325 | error_val->data.x_struct.parent.data.p_array.array_val = error_array; |
| | 16326 | error_val->data.x_struct.parent.data.p_array.elem_index = error_index; |
| | 16327 | } |
| | 16328 | |
| | 16329 | break; |
| | 16330 | } |
| | 16331 | case TypeTableEntryIdErrorUnion: |
| | 16332 | { |
| | 16333 | result = create_const_vals(1); |
| | 16334 | result->special = ConstValSpecialStatic; |
| | 16335 | result->type = ir_type_info_get_type(ira, "ErrorUnion"); |
| | 16336 | |
| | 16337 | ConstExprValue *fields = create_const_vals(2); |
| | 16338 | result->data.x_struct.fields = fields; |
| | 16339 | |
| | 16340 | // error_set: type |
| | 16341 | ensure_field_index(result->type, "error_set", 0); |
| | 16342 | fields[0].special = ConstValSpecialStatic; |
| | 16343 | fields[0].type = ira->codegen->builtin_types.entry_type; |
| | 16344 | fields[0].data.x_type = type_entry->data.error_union.err_set_type; |
| | 16345 | |
| | 16346 | // payload: type |
| | 16347 | ensure_field_index(result->type, "payload", 1); |
| | 16348 | fields[1].special = ConstValSpecialStatic; |
| | 16349 | fields[1].type = ira->codegen->builtin_types.entry_type; |
| | 16350 | fields[1].data.x_type = type_entry->data.error_union.payload_type; |
| | 16351 | |
| | 16352 | break; |
| | 16353 | } |
| | 16354 | case TypeTableEntryIdUnion: |
| | 16355 | { |
| | 16356 | result = create_const_vals(1); |
| | 16357 | result->special = ConstValSpecialStatic; |
| | 16358 | result->type = ir_type_info_get_type(ira, "Union"); |
| | 16359 | |
| | 16360 | ConstExprValue *fields = create_const_vals(4); |
| | 16361 | result->data.x_struct.fields = fields; |
| | 16362 | |
| | 16363 | // layout: ContainerLayout |
| | 16364 | ensure_field_index(result->type, "layout", 0); |
| | 16365 | fields[0].special = ConstValSpecialStatic; |
| | 16366 | fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); |
| | 16367 | bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); |
| | 16368 | // tag_type: type |
| | 16369 | ensure_field_index(result->type, "tag_type", 1); |
| | 16370 | fields[1].special = ConstValSpecialStatic; |
| | 16371 | fields[1].type = ira->codegen->builtin_types.entry_type; |
| | 16372 | // @TODO ?type instead of using @typeOf(undefined) when we have no type. |
| | 16373 | AstNode *union_decl_node = type_entry->data.unionation.decl_node; |
| | 16374 | if (union_decl_node->data.container_decl.auto_enum || |
| | 16375 | union_decl_node->data.container_decl.init_arg_expr != nullptr) |
| | 16376 | { |
| | 16377 | fields[1].data.x_type = type_entry->data.unionation.tag_type; |
| | 16378 | } |
| | 16379 | else |
| | 16380 | fields[1].data.x_type = ira->codegen->builtin_types.entry_undef; |
| | 16381 | // fields: []TypeInfo.UnionField |
| | 16382 | ensure_field_index(result->type, "fields", 2); |
| | 16383 | |
| | 16384 | TypeTableEntry *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField"); |
| | 16385 | uint32_t union_field_count = type_entry->data.unionation.src_field_count; |
| | 16386 | |
| | 16387 | ConstExprValue *union_field_array = create_const_vals(1); |
| | 16388 | union_field_array->special = ConstValSpecialStatic; |
| | 16389 | union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); |
| | 16390 | union_field_array->data.x_array.special = ConstArraySpecialNone; |
| | 16391 | union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16392 | union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count); |
| | 16393 | |
| | 16394 | init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); |
| | 16395 | |
| | 16396 | TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); |
| | 16397 | |
| | 16398 | for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) |
| | 16399 | { |
| | 16400 | TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; |
| | 16401 | ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index]; |
| | 16402 | |
| | 16403 | union_field_val->special = ConstValSpecialStatic; |
| | 16404 | union_field_val->type = type_info_union_field_type; |
| | 16405 | |
| | 16406 | ConstExprValue *inner_fields = create_const_vals(3); |
| | 16407 | inner_fields[1].special = ConstValSpecialStatic; |
| | 16408 | inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type); |
| | 16409 | |
| | 16410 | if (fields[1].data.x_type == ira->codegen->builtin_types.entry_undef) |
| | 16411 | inner_fields[1].data.x_maybe = nullptr; |
| | 16412 | else |
| | 16413 | { |
| | 16414 | inner_fields[1].data.x_maybe = create_const_vals(1); |
| | 16415 | make_enum_field_val(inner_fields[1].data.x_maybe, union_field->enum_field, type_info_enum_field_type); |
| | 16416 | } |
| | 16417 | |
| | 16418 | inner_fields[2].special = ConstValSpecialStatic; |
| | 16419 | inner_fields[2].type = ira->codegen->builtin_types.entry_type; |
| | 16420 | inner_fields[2].data.x_type = union_field->type_entry; |
| | 16421 | |
| | 16422 | ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); |
| | 16423 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); |
| | 16424 | |
| | 16425 | union_field_val->data.x_struct.fields = inner_fields; |
| | 16426 | union_field_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16427 | union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; |
| | 16428 | union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; |
| | 16429 | } |
| | 16430 | // defs: []TypeInfo.Definition |
| | 16431 | ensure_field_index(result->type, "defs", 3); |
| | 16432 | ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope); |
| | 16433 | |
| | 16434 | break; |
| | 16435 | } |
| | 16436 | case TypeTableEntryIdStruct: |
| | 16437 | { |
| | 16438 | result = create_const_vals(1); |
| | 16439 | result->special = ConstValSpecialStatic; |
| | 16440 | result->type = ir_type_info_get_type(ira, "Struct"); |
| | 16441 | |
| | 16442 | ConstExprValue *fields = create_const_vals(3); |
| | 16443 | result->data.x_struct.fields = fields; |
| | 16444 | |
| | 16445 | // layout: ContainerLayout |
| | 16446 | ensure_field_index(result->type, "layout", 0); |
| | 16447 | fields[0].special = ConstValSpecialStatic; |
| | 16448 | fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); |
| | 16449 | bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); |
| | 16450 | // fields: []TypeInfo.StructField |
| | 16451 | ensure_field_index(result->type, "fields", 1); |
| | 16452 | |
| | 16453 | TypeTableEntry *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField"); |
| | 16454 | uint32_t struct_field_count = type_entry->data.structure.src_field_count; |
| | 16455 | |
| | 16456 | ConstExprValue *struct_field_array = create_const_vals(1); |
| | 16457 | struct_field_array->special = ConstValSpecialStatic; |
| | 16458 | struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); |
| | 16459 | struct_field_array->data.x_array.special = ConstArraySpecialNone; |
| | 16460 | struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16461 | struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count); |
| | 16462 | |
| | 16463 | init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); |
| | 16464 | |
| | 16465 | for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) |
| | 16466 | { |
| | 16467 | TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; |
| | 16468 | ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index]; |
| | 16469 | |
| | 16470 | struct_field_val->special = ConstValSpecialStatic; |
| | 16471 | struct_field_val->type = type_info_struct_field_type; |
| | 16472 | |
| | 16473 | ConstExprValue *inner_fields = create_const_vals(3); |
| | 16474 | inner_fields[1].special = ConstValSpecialStatic; |
| | 16475 | inner_fields[1].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_usize); |
| | 16476 | |
| | 16477 | if (!type_has_bits(struct_field->type_entry)) |
| | 16478 | inner_fields[1].data.x_maybe = nullptr; |
| | 16479 | else |
| | 16480 | { |
| | 16481 | size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index); |
| | 16482 | inner_fields[1].data.x_maybe = create_const_vals(1); |
| | 16483 | inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize; |
| | 16484 | bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset); |
| | 16485 | } |
| | 16486 | |
| | 16487 | inner_fields[2].special = ConstValSpecialStatic; |
| | 16488 | inner_fields[2].type = ira->codegen->builtin_types.entry_type; |
| | 16489 | inner_fields[2].data.x_type = struct_field->type_entry; |
| | 16490 | |
| | 16491 | ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); |
| | 16492 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); |
| | 16493 | |
| | 16494 | struct_field_val->data.x_struct.fields = inner_fields; |
| | 16495 | struct_field_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16496 | struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; |
| | 16497 | struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; |
| | 16498 | } |
| | 16499 | // defs: []TypeInfo.Definition |
| | 16500 | ensure_field_index(result->type, "defs", 2); |
| | 16501 | ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope); |
| | 16502 | |
| | 16503 | break; |
| | 16504 | } |
| | 16505 | case TypeTableEntryIdFn: |
| | 16506 | { |
| | 16507 | result = create_const_vals(1); |
| | 16508 | result->special = ConstValSpecialStatic; |
| | 16509 | result->type = ir_type_info_get_type(ira, "Fn"); |
| | 16510 | |
| | 16511 | ConstExprValue *fields = create_const_vals(6); |
| | 16512 | result->data.x_struct.fields = fields; |
| | 16513 | |
| | 16514 | // @TODO Fix type = undefined with ?type |
| | 16515 | |
| | 16516 | // calling_convention: TypeInfo.CallingConvention |
| | 16517 | ensure_field_index(result->type, "calling_convention", 0); |
| | 16518 | fields[0].special = ConstValSpecialStatic; |
| | 16519 | fields[0].type = ir_type_info_get_type(ira, "CallingConvention"); |
| | 16520 | bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); |
| | 16521 | // is_generic: bool |
| | 16522 | ensure_field_index(result->type, "is_generic", 1); |
| | 16523 | bool is_generic = type_entry->data.fn.is_generic; |
| | 16524 | fields[1].special = ConstValSpecialStatic; |
| | 16525 | fields[1].type = ira->codegen->builtin_types.entry_bool; |
| | 16526 | fields[1].data.x_bool = is_generic; |
| | 16527 | // is_varargs: bool |
| | 16528 | ensure_field_index(result->type, "is_var_args", 2); |
| | 16529 | bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; |
| | 16530 | fields[2].special = ConstValSpecialStatic; |
| | 16531 | fields[2].type = ira->codegen->builtin_types.entry_bool; |
| | 16532 | fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; |
| | 16533 | // return_type: type |
| | 16534 | ensure_field_index(result->type, "return_type", 3); |
| | 16535 | fields[3].special = ConstValSpecialStatic; |
| | 16536 | fields[3].type = ira->codegen->builtin_types.entry_type; |
| | 16537 | if (type_entry->data.fn.fn_type_id.return_type == nullptr) |
| | 16538 | fields[3].data.x_type = ira->codegen->builtin_types.entry_undef; |
| | 16539 | else |
| | 16540 | fields[3].data.x_type = type_entry->data.fn.fn_type_id.return_type; |
| | 16541 | // async_allocator_type: type |
| | 16542 | ensure_field_index(result->type, "async_allocator_type", 4); |
| | 16543 | fields[4].special = ConstValSpecialStatic; |
| | 16544 | fields[4].type = ira->codegen->builtin_types.entry_type; |
| | 16545 | if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) |
| | 16546 | fields[4].data.x_type = ira->codegen->builtin_types.entry_undef; |
| | 16547 | else |
| | 16548 | fields[4].data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; |
| | 16549 | // args: []TypeInfo.FnArg |
| | 16550 | TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg"); |
| | 16551 | size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - |
| | 16552 | (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); |
| | 16553 | |
| | 16554 | ConstExprValue *fn_arg_array = create_const_vals(1); |
| | 16555 | fn_arg_array->special = ConstValSpecialStatic; |
| | 16556 | fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); |
| | 16557 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| | 16558 | fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 16559 | fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); |
| | 16560 | |
| | 16561 | init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); |
| | 16562 | |
| | 16563 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) |
| | 16564 | { |
| | 16565 | FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; |
| | 16566 | ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index]; |
| | 16567 | |
| | 16568 | fn_arg_val->special = ConstValSpecialStatic; |
| | 16569 | fn_arg_val->type = type_info_fn_arg_type; |
| | 16570 | |
| | 16571 | bool arg_is_generic = fn_param_info->type == nullptr; |
| | 16572 | if (arg_is_generic) assert(is_generic); |
| | 16573 | |
| | 16574 | ConstExprValue *inner_fields = create_const_vals(3); |
| | 16575 | inner_fields[0].special = ConstValSpecialStatic; |
| | 16576 | inner_fields[0].type = ira->codegen->builtin_types.entry_bool; |
| | 16577 | inner_fields[0].data.x_bool = arg_is_generic; |
| | 16578 | inner_fields[1].special = ConstValSpecialStatic; |
| | 16579 | inner_fields[1].type = ira->codegen->builtin_types.entry_bool; |
| | 16580 | inner_fields[1].data.x_bool = fn_param_info->is_noalias; |
| | 16581 | inner_fields[2].special = ConstValSpecialStatic; |
| | 16582 | inner_fields[2].type = ira->codegen->builtin_types.entry_type; |
| | 16583 | |
| | 16584 | if (arg_is_generic) |
| | 16585 | inner_fields[2].data.x_type = ira->codegen->builtin_types.entry_undef; |
| | 16586 | else |
| | 16587 | inner_fields[2].data.x_type = fn_param_info->type; |
| | 16588 | |
| | 16589 | fn_arg_val->data.x_struct.fields = inner_fields; |
| | 16590 | fn_arg_val->data.x_struct.parent.id = ConstParentIdArray; |
| | 16591 | fn_arg_val->data.x_struct.parent.data.p_array.array_val = fn_arg_array; |
| | 16592 | fn_arg_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; |
| | 16593 | } |
| | 16594 | |
| | 16595 | break; |
| | 16596 | } |
| | 16597 | case TypeTableEntryIdBoundFn: |
| | 16598 | { |
| | 16599 | TypeTableEntry *fn_type = type_entry->data.bound_fn.fn_type; |
| | 16600 | assert(fn_type->id == TypeTableEntryIdFn); |
| | 16601 | result = ir_make_type_info_value(ira, fn_type); |
| | 16602 | |
| | 16603 | break; |
| | 16604 | } |
| | 16605 | } |
| | 16606 | |
| | 16607 | assert(result != nullptr); |
| | 16608 | ira->codegen->type_info_cache.put(type_entry, result); |
| | 16609 | return result; |
| | 16610 | } |
| | 16611 | |
| | 16612 | static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, |
| | 16613 | IrInstructionTypeInfo *instruction) |
| | 16614 | { |
| | 16615 | IrInstruction *type_value = instruction->type_value->other; |
| | 16616 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| | 16617 | if (type_is_invalid(type_entry)) |
| | 16618 | return ira->codegen->builtin_types.entry_invalid; |
| | 16619 | |
| | 16620 | TypeTableEntry *result_type = ir_type_info_get_type(ira, nullptr); |
| | 16621 | |
| | 16622 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| | 16623 | out_val->type = result_type; |
| | 16624 | bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); |
| | 16625 | |
| | 16626 | ConstExprValue *payload = ir_make_type_info_value(ira, type_entry); |
| | 16627 | out_val->data.x_union.payload = payload; |
| | 16628 | |
| | 16629 | if (payload != nullptr) |
| | 16630 | { |
| | 16631 | assert(payload->type->id == TypeTableEntryIdStruct); |
| | 16632 | payload->data.x_struct.parent.id = ConstParentIdUnion; |
| | 16633 | payload->data.x_struct.parent.data.p_union.union_val = out_val; |
| | 16634 | } |
| | 16635 | |
| | 16636 | return result_type; |
| | 16637 | } |
| | 16638 | |
| 15682 | static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira, | 16639 | static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira, |
| 15683 | IrInstructionTypeId *instruction) | 16640 | IrInstructionTypeId *instruction) |
| 15684 | { | 16641 | { |
| ... | @@ -18580,6 +19537,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -18580,6 +19537,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 18580 | return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); | 19537 | return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); |
| 18581 | case IrInstructionIdOffsetOf: | 19538 | case IrInstructionIdOffsetOf: |
| 18582 | return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); | 19539 | return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); |
| | 19540 | case IrInstructionIdTypeInfo: |
| | 19541 | return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); |
| 18583 | case IrInstructionIdTypeId: | 19542 | case IrInstructionIdTypeId: |
| 18584 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); | 19543 | return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); |
| 18585 | case IrInstructionIdSetEvalBranchQuota: | 19544 | case IrInstructionIdSetEvalBranchQuota: |
| ... | @@ -18846,6 +19805,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -18846,6 +19805,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 18846 | case IrInstructionIdTagName: | 19805 | case IrInstructionIdTagName: |
| 18847 | case IrInstructionIdFieldParentPtr: | 19806 | case IrInstructionIdFieldParentPtr: |
| 18848 | case IrInstructionIdOffsetOf: | 19807 | case IrInstructionIdOffsetOf: |
| | 19808 | case IrInstructionIdTypeInfo: |
| 18849 | case IrInstructionIdTypeId: | 19809 | case IrInstructionIdTypeId: |
| 18850 | case IrInstructionIdAlignCast: | 19810 | case IrInstructionIdAlignCast: |
| 18851 | case IrInstructionIdOpaqueType: | 19811 | case IrInstructionIdOpaqueType: |