Commit 9b29c872ce

Jimmi HC <jhc@liab.dk>
2018-05-09 09:34:04
Added Slice as it's own type info in userland
1 parent 670c9f9
src/analyze.cpp
@@ -5931,8 +5931,8 @@ size_t type_id_len() {
     return array_length(all_type_ids);
 }
 
-size_t type_id_index(TypeTableEntryId id) {
-    switch (id) {
+size_t type_id_index(TypeTableEntry *entry) {
+    switch (entry->id) {
         case TypeTableEntryIdInvalid:
             zig_unreachable();
         case TypeTableEntryIdMetaType:
@@ -5952,6 +5952,8 @@ size_t type_id_index(TypeTableEntryId id) {
         case TypeTableEntryIdArray:
             return 7;
         case TypeTableEntryIdStruct:
+            if (entry->data.structure.is_slice)
+                return 25;
             return 8;
         case TypeTableEntryIdNumLitFloat:
             return 9;
src/analyze.hpp
@@ -174,7 +174,7 @@ void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
 const char *type_id_name(TypeTableEntryId id);
 TypeTableEntryId type_id_at_index(size_t index);
 size_t type_id_len();
-size_t type_id_index(TypeTableEntryId id);
+size_t type_id_index(TypeTableEntry *entry);
 TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id);
 bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry);
 LinkLib *create_link_lib(Buf *name);
src/codegen.cpp
@@ -6345,6 +6345,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
             const TypeTableEntryId id = type_id_at_index(i);
             buf_appendf(contents, "    %s,\n", type_id_name(id));
         }
+        buf_appendf(contents, "    Slice,\n");
         buf_appendf(contents, "};\n\n");
     }
     {
@@ -6357,6 +6358,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
             "    Int: Int,\n"
             "    Float: Float,\n"
             "    Pointer: Pointer,\n"
+            "    Slice: Slice,\n"
             "    Array: Array,\n"
             "    Struct: Struct,\n"
             "    FloatLiteral: void,\n"
@@ -6392,6 +6394,8 @@ static void define_builtin_compile_vars(CodeGen *g) {
             "        child: type,\n"
             "    };\n"
             "\n"
+            "    pub const Slice = Pointer;\n"
+            "\n"
             "    pub const Array = struct {\n"
             "        len: usize,\n"
             "        child: type,\n"
src/ir.cpp
@@ -15785,11 +15785,10 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na
 
     Buf field_name = BUF_INIT;
     buf_init_from_str(&field_name, type_name);
-    auto entry = type_info_scope->decl_table.maybe_get(&field_name);
+    auto entry = type_info_scope->decl_table.get(&field_name);
     buf_deinit(&field_name);
-    assert(entry != nullptr);
 
-    TldVar *tld = (TldVar *)entry->value;
+    TldVar *tld = (TldVar *)entry;
     assert(tld->base.id == TldIdVar);
 
     VariableTableEntry *var = tld->var;
@@ -16071,6 +16070,38 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
         enum_field_val->data.x_struct.fields = inner_fields;
     };
 
+    const auto create_ptr_like_type_info = [ira](const char *name, TypeTableEntry *ptr_type_entry) {
+        ConstExprValue *result = create_const_vals(1);
+        result->special = ConstValSpecialStatic;
+        result->type = ir_type_info_get_type(ira, name);
+
+        ConstExprValue *fields = create_const_vals(4);
+        result->data.x_struct.fields = fields;
+
+        // is_const: bool
+        ensure_field_index(result->type, "is_const", 0);
+        fields[0].special = ConstValSpecialStatic;
+        fields[0].type = ira->codegen->builtin_types.entry_bool;
+        fields[0].data.x_bool = ptr_type_entry->data.pointer.is_const;
+        // is_volatile: bool
+        ensure_field_index(result->type, "is_volatile", 1);
+        fields[1].special = ConstValSpecialStatic;
+        fields[1].type = ira->codegen->builtin_types.entry_bool;
+        fields[1].data.x_bool = ptr_type_entry->data.pointer.is_volatile;
+        // alignment: u32
+        ensure_field_index(result->type, "alignment", 2);
+        fields[2].special = ConstValSpecialStatic;
+        fields[2].type = ira->codegen->builtin_types.entry_u32;
+        bigint_init_unsigned(&fields[2].data.x_bigint, ptr_type_entry->data.pointer.alignment);
+        // child: type
+        ensure_field_index(result->type, "child", 3);
+        fields[3].special = ConstValSpecialStatic;
+        fields[3].type = ira->codegen->builtin_types.entry_type;
+        fields[3].data.x_type = ptr_type_entry->data.pointer.child_type;
+
+        return result;
+    };
+
     ConstExprValue *result = nullptr;
     switch (type_entry->id)
     {
@@ -16139,34 +16170,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
             }
         case TypeTableEntryIdPointer:
             {
-                result = create_const_vals(1);
-                result->special = ConstValSpecialStatic;
-                result->type = ir_type_info_get_type(ira, "Pointer");
-
-                ConstExprValue *fields = create_const_vals(4);
-                result->data.x_struct.fields = fields;
-
-                // is_const: bool
-                ensure_field_index(result->type, "is_const", 0);
-                fields[0].special = ConstValSpecialStatic;
-                fields[0].type = ira->codegen->builtin_types.entry_bool;
-                fields[0].data.x_bool = type_entry->data.pointer.is_const;
-                // is_volatile: bool
-                ensure_field_index(result->type, "is_volatile", 1);
-                fields[1].special = ConstValSpecialStatic;
-                fields[1].type = ira->codegen->builtin_types.entry_bool;
-                fields[1].data.x_bool = type_entry->data.pointer.is_volatile;
-                // alignment: u32
-                ensure_field_index(result->type, "alignment", 2);
-                fields[2].special = ConstValSpecialStatic;
-                fields[2].type = ira->codegen->builtin_types.entry_u32;
-                bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment);
-                // child: type
-                ensure_field_index(result->type, "child", 3);
-                fields[3].special = ConstValSpecialStatic;
-                fields[3].type = ira->codegen->builtin_types.entry_type;
-                fields[3].data.x_type = type_entry->data.pointer.child_type;
-
+                result = create_ptr_like_type_info("Pointer", type_entry);
                 break;
             }
         case TypeTableEntryIdArray:
@@ -16436,6 +16440,16 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
             }
         case TypeTableEntryIdStruct:
             {
+                if (type_entry->data.structure.is_slice) {
+                    Buf ptr_field_name = BUF_INIT;
+                    buf_init_from_str(&ptr_field_name, "ptr");
+                    TypeTableEntry *ptr_type = type_entry->data.structure.fields_by_name.get(&ptr_field_name)->type_entry;
+                    ensure_complete_type(ira->codegen, ptr_type);
+
+                    result = create_ptr_like_type_info("Slice", ptr_type);
+                    break;
+                }
+
                 result = create_const_vals(1);
                 result->special = ConstValSpecialStatic;
                 result->type = ir_type_info_get_type(ira, "Struct");
@@ -16622,7 +16636,7 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
 
     ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
     out_val->type = result_type;
-    bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id));
+    bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry));
 
     ConstExprValue *payload = ir_make_type_info_value(ira, type_entry);
     out_val->data.x_union.payload = payload;
@@ -16650,7 +16664,7 @@ static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
     TypeTableEntry *result_type = var_value->data.x_type;
 
     ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
-    bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry->id));
+    bigint_init_unsigned(&out_val->data.x_enum_tag, type_id_index(type_entry));
     return result_type;
 }
 
test/cases/type_info.zig
@@ -25,7 +25,7 @@ test "type info: integer, floating point type info" {
     }
 }
 
-test "type info: pointer, array and nullable type info" {
+test "type info: pointer type info" {
     comptime {
         const u32_ptr_info = @typeInfo(&u32);
         assert(TypeId(u32_ptr_info) == TypeId.Pointer);
@@ -33,12 +33,31 @@ test "type info: pointer, array and nullable type info" {
         assert(u32_ptr_info.Pointer.is_volatile == false);
         assert(u32_ptr_info.Pointer.alignment == 4);
         assert(u32_ptr_info.Pointer.child == u32);
+    }
+}
+
+test "type info: slice type info" {
+    comptime {
+        const u32_slice_info = @typeInfo([]u32);
+        assert(TypeId(u32_slice_info) == TypeId.Slice);
+        assert(u32_slice_info.Slice.is_const == false);
+        assert(u32_slice_info.Slice.is_volatile == false);
+        assert(u32_slice_info.Slice.alignment == 4);
+        assert(u32_slice_info.Slice.child == u32);
+    }
+}
 
+test "type info: array type info" {
+    comptime {
         const arr_info = @typeInfo([42]bool);
         assert(TypeId(arr_info) == TypeId.Array);
         assert(arr_info.Array.len == 42);
         assert(arr_info.Array.child == bool);
+    }
+}
 
+test "type info: nullable type info" {
+    comptime {
         const null_info = @typeInfo(?void);
         assert(TypeId(null_info) == TypeId.Nullable);
         assert(null_info.Nullable.child == void);
@@ -100,11 +119,11 @@ test "type info: union info" {
         assert(TypeId(typeinfo_info) == TypeId.Union);
         assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
         assert(typeinfo_info.Union.tag_type == TypeId);
-        assert(typeinfo_info.Union.fields.len == 25);
+        assert(typeinfo_info.Union.fields.len == 26);
         assert(typeinfo_info.Union.fields[4].enum_field != null);
         assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
         assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
-        assert(typeinfo_info.Union.defs.len == 20);
+        assert(typeinfo_info.Union.defs.len == 21);
 
         const TestNoTagUnion = union {
             Foo: void,