| ... | @@ -15748,7 +15748,7 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz | ... | @@ -15748,7 +15748,7 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz |
| 15748 | (buf_deinit(field_name_buf), true)); | 15748 | (buf_deinit(field_name_buf), true)); |
| 15749 | } | 15749 | } |
| 15750 | | 15750 | |
| 15751 | static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name) | 15751 | static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, TypeTableEntry *root = nullptr) |
| 15752 | { | 15752 | { |
| 15753 | static ConstExprValue *type_info_var = nullptr; | 15753 | static ConstExprValue *type_info_var = nullptr; |
| 15754 | static TypeTableEntry *type_info_type = nullptr; | 15754 | static TypeTableEntry *type_info_type = nullptr; |
| ... | @@ -15761,10 +15761,14 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na | ... | @@ -15761,10 +15761,14 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na |
| 15761 | assert(type_info_type->id == TypeTableEntryIdUnion); | 15761 | assert(type_info_type->id == TypeTableEntryIdUnion); |
| 15762 | } | 15762 | } |
| 15763 | | 15763 | |
| 15764 | if (type_name == nullptr) | 15764 | if (type_name == nullptr && root == nullptr) |
| 15765 | return type_info_type; | 15765 | return type_info_type; |
| | 15766 | else if (type_name == nullptr) |
| | 15767 | return root; |
| 15766 | | 15768 | |
| 15767 | ScopeDecls *type_info_scope = get_container_scope(type_info_type); | 15769 | TypeTableEntry *root_type = (root == nullptr) ? type_info_type : root; |
| | 15770 | |
| | 15771 | ScopeDecls *type_info_scope = get_container_scope(root_type); |
| 15768 | assert(type_info_scope != nullptr); | 15772 | assert(type_info_scope != nullptr); |
| 15769 | | 15773 | |
| 15770 | Buf field_name = BUF_INIT; | 15774 | Buf field_name = BUF_INIT; |
| ... | @@ -15782,6 +15786,128 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na | ... | @@ -15782,6 +15786,128 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na |
| 15782 | return var->value->data.x_type; | 15786 | return var->value->data.x_type; |
| 15783 | } | 15787 | } |
| 15784 | | 15788 | |
| | 15789 | static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) |
| | 15790 | { |
| | 15791 | TypeTableEntry *type_info_definition_type = ir_type_info_get_type(ira, "Definition"); |
| | 15792 | ensure_complete_type(ira->codegen, type_info_definition_type); |
| | 15793 | ensure_field_index(type_info_definition_type, "name", 0); |
| | 15794 | ensure_field_index(type_info_definition_type, "is_pub", 1); |
| | 15795 | ensure_field_index(type_info_definition_type, "data", 2); |
| | 15796 | |
| | 15797 | TypeTableEntry *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); |
| | 15798 | ensure_complete_type(ira->codegen, type_info_definition_data_type); |
| | 15799 | |
| | 15800 | // Loop through our definitions once to figure out how many definitions we will generate info for. |
| | 15801 | auto decl_it = decls_scope->decl_table.entry_iterator(); |
| | 15802 | decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; |
| | 15803 | int definition_count = 0; |
| | 15804 | |
| | 15805 | while ((curr_entry = decl_it.next()) != nullptr) |
| | 15806 | { |
| | 15807 | // Skip comptime blocks. |
| | 15808 | if (curr_entry->value->id != TldIdCompTime) |
| | 15809 | { |
| | 15810 | definition_count += 1; |
| | 15811 | } |
| | 15812 | } |
| | 15813 | |
| | 15814 | ConstExprValue *definition_array = create_const_vals(1); |
| | 15815 | definition_array->special = ConstValSpecialStatic; |
| | 15816 | definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); |
| | 15817 | definition_array->data.x_array.special = ConstArraySpecialNone; |
| | 15818 | definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; |
| | 15819 | definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); |
| | 15820 | init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); |
| | 15821 | |
| | 15822 | // Loop through the definitions and generate info. |
| | 15823 | decl_it = decls_scope->decl_table.entry_iterator(); |
| | 15824 | curr_entry = nullptr; |
| | 15825 | int definition_index = 0; |
| | 15826 | while ((curr_entry = decl_it.next()) != nullptr) |
| | 15827 | { |
| | 15828 | // Skip comptime blocks |
| | 15829 | if (curr_entry->value->id == TldIdCompTime) |
| | 15830 | continue; |
| | 15831 | |
| | 15832 | ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; |
| | 15833 | |
| | 15834 | definition_val->special = ConstValSpecialStatic; |
| | 15835 | definition_val->type = type_info_definition_type; |
| | 15836 | |
| | 15837 | ConstExprValue *inner_fields = create_const_vals(3); |
| | 15838 | ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); |
| | 15839 | init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); |
| | 15840 | inner_fields[1].special = ConstValSpecialStatic; |
| | 15841 | inner_fields[1].type = ira->codegen->builtin_types.entry_bool; |
| | 15842 | inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; |
| | 15843 | inner_fields[2].special = ConstValSpecialStatic; |
| | 15844 | inner_fields[2].type = type_info_definition_data_type; |
| | 15845 | inner_fields[2].data.x_union.parent.id = ConstParentIdStruct; |
| | 15846 | inner_fields[2].data.x_union.parent.data.p_struct.struct_val = definition_val; |
| | 15847 | inner_fields[2].data.x_union.parent.data.p_struct.field_index = 1; |
| | 15848 | |
| | 15849 | switch (curr_entry->value->id) |
| | 15850 | { |
| | 15851 | case TldIdVar: |
| | 15852 | { |
| | 15853 | VariableTableEntry *var = ((TldVar *)curr_entry->value)->var; |
| | 15854 | ensure_complete_type(ira->codegen, var->value->type); |
| | 15855 | if (var->value->type->id == TypeTableEntryIdMetaType) |
| | 15856 | { |
| | 15857 | // We have a variable of type 'type', so it's actually a type definition. |
| | 15858 | // 0: Data.Type: type |
| | 15859 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); |
| | 15860 | inner_fields[2].data.x_union.payload = var->value; |
| | 15861 | } |
| | 15862 | else |
| | 15863 | { |
| | 15864 | // We have a variable of another type, so we store the type of the variable. |
| | 15865 | // 1: Data.Var: type |
| | 15866 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); |
| | 15867 | |
| | 15868 | ConstExprValue *payload = create_const_vals(1); |
| | 15869 | payload->type = ira->codegen->builtin_types.entry_type; |
| | 15870 | payload->data.x_type = var->value->type; |
| | 15871 | |
| | 15872 | inner_fields[2].data.x_union.payload = payload; |
| | 15873 | } |
| | 15874 | |
| | 15875 | break; |
| | 15876 | } |
| | 15877 | case TldIdFn: |
| | 15878 | { |
| | 15879 | // 2: Data.Fn: Data.FnDef |
| | 15880 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); |
| | 15881 | // @TODO Data.FnDef |
| | 15882 | inner_fields[2].data.x_union.payload = nullptr; |
| | 15883 | break; |
| | 15884 | } |
| | 15885 | case TldIdContainer: |
| | 15886 | { |
| | 15887 | TypeTableEntry *type_entry = ((TldContainer *)curr_entry->value)->type_entry; |
| | 15888 | ensure_complete_type(ira->codegen, type_entry); |
| | 15889 | // This is a type. |
| | 15890 | bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); |
| | 15891 | |
| | 15892 | ConstExprValue *payload = create_const_vals(1); |
| | 15893 | payload->type = ira->codegen->builtin_types.entry_type; |
| | 15894 | payload->data.x_type = type_entry; |
| | 15895 | |
| | 15896 | inner_fields[2].data.x_union.payload = payload; |
| | 15897 | |
| | 15898 | break; |
| | 15899 | } |
| | 15900 | default: |
| | 15901 | zig_unreachable(); |
| | 15902 | } |
| | 15903 | |
| | 15904 | definition_val->data.x_struct.fields = inner_fields; |
| | 15905 | definition_index++; |
| | 15906 | } |
| | 15907 | |
| | 15908 | assert(definition_index == definition_count); |
| | 15909 | } |
| | 15910 | |
| 15785 | static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) | 15911 | static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) |
| 15786 | { | 15912 | { |
| 15787 | assert(type_entry != nullptr); | 15913 | assert(type_entry != nullptr); |
| ... | @@ -15791,10 +15917,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t | ... | @@ -15791,10 +15917,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t |
| 15791 | | 15917 | |
| 15792 | const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, | 15918 | const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, |
| 15793 | TypeTableEntry *type_info_enum_field_type) { | 15919 | TypeTableEntry *type_info_enum_field_type) { |
| 15794 | // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) | | |
| 15795 | // ensure_field_index(type_info_enum_field_type, "name", 0); | | |
| 15796 | // ensure_field_index(type_info_enum_field_type, "value", 1); | | |
| 15797 | | | |
| 15798 | enum_field_val->special = ConstValSpecialStatic; | 15920 | enum_field_val->special = ConstValSpecialStatic; |
| 15799 | enum_field_val->type = type_info_enum_field_type; | 15921 | enum_field_val->type = type_info_enum_field_type; |
| 15800 | | 15922 | |
| ... | @@ -16012,8 +16134,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t | ... | @@ -16012,8 +16134,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t |
| 16012 | enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; | 16134 | enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; |
| 16013 | enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; | 16135 | enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; |
| 16014 | } | 16136 | } |
| | 16137 | // defs: []TypeInfo.Definition |
| | 16138 | ensure_field_index(result->type, "defs", 3); |
| | 16139 | ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope); |
| 16015 | | 16140 | |
| 16016 | // @TODO Definitions | | |
| 16017 | break; | 16141 | break; |
| 16018 | } | 16142 | } |
| 16019 | case TypeTableEntryIdErrorSet: | 16143 | case TypeTableEntryIdErrorSet: |
| ... | @@ -16165,8 +16289,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t | ... | @@ -16165,8 +16289,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t |
| 16165 | union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; | 16289 | union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; |
| 16166 | union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; | 16290 | union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; |
| 16167 | } | 16291 | } |
| | 16292 | // defs: []TypeInfo.Definition |
| | 16293 | ensure_field_index(result->type, "defs", 3); |
| | 16294 | ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope); |
| 16168 | | 16295 | |
| 16169 | // @TODO Definitions | | |
| 16170 | break; | 16296 | break; |
| 16171 | } | 16297 | } |
| 16172 | case TypeTableEntryIdStruct: | 16298 | case TypeTableEntryIdStruct: |
| ... | @@ -16232,7 +16358,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t | ... | @@ -16232,7 +16358,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t |
| 16232 | struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; | 16358 | struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; |
| 16233 | struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; | 16359 | struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; |
| 16234 | } | 16360 | } |
| 16235 | // @TODO Definitions | 16361 | // defs: []TypeInfo.Definition |
| | 16362 | ensure_field_index(result->type, "defs", 2); |
| | 16363 | ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope); |
| | 16364 | |
| 16236 | break; | 16365 | break; |
| 16237 | } | 16366 | } |
| 16238 | case TypeTableEntryIdFn: | 16367 | case TypeTableEntryIdFn: |
| ... | @@ -16329,7 +16458,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t | ... | @@ -16329,7 +16458,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t |
| 16329 | } | 16458 | } |
| 16330 | case TypeTableEntryIdBoundFn: | 16459 | case TypeTableEntryIdBoundFn: |
| 16331 | { | 16460 | { |
| 16332 | // @TODO figure out memory corruption error. | | |
| 16333 | TypeTableEntry *fn_type = type_entry->data.bound_fn.fn_type; | 16461 | TypeTableEntry *fn_type = type_entry->data.bound_fn.fn_type; |
| 16334 | assert(fn_type->id == TypeTableEntryIdFn); | 16462 | assert(fn_type->id == TypeTableEntryIdFn); |
| 16335 | result = ir_make_type_info_value(ira, fn_type); | 16463 | result = ir_make_type_info_value(ira, fn_type); |