authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2018-04-28 17:01:19+03:00
committergravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2018-04-28 17:01:19+03:00
log61b01805968939669a29f7189f4ce7fab46ab2da
treeda70f1522d2fc6b5a180069fffbd9c3b59322603
parentea2596280fc2c78f71b08921db3a4c9826eb93e0

Added definition TypeInfo generation, except for function definitions.


2 files changed, 154 insertions(+), 26 deletions(-)

src/codegen.cpp+15-15
...@@ -6348,13 +6348,6 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6348,13 +6348,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
6348 buf_appendf(contents, "};\n\n");6348 buf_appendf(contents, "};\n\n");
6349 }6349 }
6350 {6350 {
6351 // @TODO Add Namespace info.
6352 // @TODO Methods -> definitions
6353 // @TODO Includes type definitions (name + type bound) + functions + const variable definitions (+ type of variable)
6354 // @TODO Type definitions are defined as variable definitions of type 'type'
6355 // @TODO This should give us everything available.
6356 // @TODO An alternative is exposing the value of every variable definition, check out if it's possible and wether we want that.
6357 // @TODO I don't think so, @field gives it to us for free.
6358 buf_appendf(contents,6351 buf_appendf(contents,
6359 "pub const TypeInfo = union(TypeId) {\n"6352 "pub const TypeInfo = union(TypeId) {\n"
6360 " Type: void,\n"6353 " Type: void,\n"
...@@ -6410,11 +6403,6 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6410,11 +6403,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
6410 " Packed,\n"6403 " Packed,\n"
6411 " };\n"6404 " };\n"
6412 "\n"6405 "\n"
6413 " pub const Method = struct {\n"
6414 " name: []const u8,\n"
6415 " fn_info: Fn,\n"
6416 " };\n"
6417 "\n"
6418 " pub const StructField = struct {\n"6406 " pub const StructField = struct {\n"
6419 " name: []const u8,\n"6407 " name: []const u8,\n"
6420 " offset: ?usize,\n"6408 " offset: ?usize,\n"
...@@ -6424,7 +6412,7 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6424,7 +6412,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
6424 " pub const Struct = struct {\n"6412 " pub const Struct = struct {\n"
6425 " layout: ContainerLayout,\n"6413 " layout: ContainerLayout,\n"
6426 " fields: []StructField,\n"6414 " fields: []StructField,\n"
6427 " methods: []Method,\n"6415 " defs: []Definition,\n"
6428 " };\n"6416 " };\n"
6429 "\n"6417 "\n"
6430 " pub const Nullable = struct {\n"6418 " pub const Nullable = struct {\n"
...@@ -6454,7 +6442,7 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6454,7 +6442,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
6454 " layout: ContainerLayout,\n"6442 " layout: ContainerLayout,\n"
6455 " tag_type: type,\n"6443 " tag_type: type,\n"
6456 " fields: []EnumField,\n"6444 " fields: []EnumField,\n"
6457 " methods: []Method,\n"6445 " defs: []Definition,\n"
6458 " };\n"6446 " };\n"
6459 "\n"6447 "\n"
6460 " pub const UnionField = struct {\n"6448 " pub const UnionField = struct {\n"
...@@ -6467,7 +6455,7 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6467,7 +6455,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
6467 " layout: ContainerLayout,\n"6455 " layout: ContainerLayout,\n"
6468 " tag_type: type,\n"6456 " tag_type: type,\n"
6469 " fields: []UnionField,\n"6457 " fields: []UnionField,\n"
6470 " methods: []Method,\n"6458 " defs: []Definition,\n"
6471 " };\n"6459 " };\n"
6472 "\n"6460 "\n"
6473 " pub const CallingConvention = enum {\n"6461 " pub const CallingConvention = enum {\n"
...@@ -6497,6 +6485,18 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6497,6 +6485,18 @@ static void define_builtin_compile_vars(CodeGen *g) {
6497 " pub const Promise = struct {\n"6485 " pub const Promise = struct {\n"
6498 " child: type,\n"6486 " child: type,\n"
6499 " };\n"6487 " };\n"
6488 "\n"
6489 " pub const Definition = struct {\n"
6490 " name: []const u8,\n"
6491 " is_pub: bool,\n"
6492 " data: Data,\n"
6493 "\n"
6494 " const Data = union(enum) {\n"
6495 " Type: type,\n"
6496 " Var: type,\n"
6497 " Fn: void,\n"
6498 " };\n"
6499 " };\n"
6500 "};\n\n");6500 "};\n\n");
6501 assert(ContainerLayoutAuto == 0);6501 assert(ContainerLayoutAuto == 0);
6502 assert(ContainerLayoutExtern == 1);6502 assert(ContainerLayoutExtern == 1);
src/ir.cpp+139-11
...@@ -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}
1575015750
15751static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name)15751static 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 }
1576315763
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;
1576615768
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);
1576915773
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}
1578415788
15789static 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
15785static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry)15911static 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
1579115917
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;
1580015922
...@@ -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);
1601516140
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);
1616816295
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 Definitions16361 // 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);