Commit 0e5fb035e3

Alexandros Naskos <alex_naskos@hotmail.com>
2018-04-24 15:23:22
Added (broken) pointer info, float info
1 parent e9309d3
Changed files (1)
src
src/ir.cpp
@@ -15728,27 +15728,13 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira,
     return ira->codegen->builtin_types.entry_num_lit_int;
 }
 
-static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
-        IrInstructionTypeInfo *instruction)
+static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, TypeTableEntry *type_entry)
 {
-    IrInstruction *type_value = instruction->type_value->other;
-    TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
-    if (type_is_invalid(type_entry))
-        return ira->codegen->builtin_types.entry_invalid;
+    assert(type_entry != nullptr);
+    assert(!type_is_invalid(type_entry));
 
-    ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo");
-    assert(var_value->type->id == TypeTableEntryIdMetaType);
-    TypeTableEntry *result_type = var_value->data.x_type;
-
-    ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
-    // TODO: Do I need those? probably set in ir_build_const_from
-    //out_val->special = ConstValSpecialStatic;
-    //out_val->type = result_type;
-
-    bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id));
-    //out_val->data.x_union.parent.id = ConstParentIdNone;
-
-    switch (type_entry->id) {
+    switch (type_entry->id)
+    {
         case TypeTableEntryIdInvalid:
             zig_unreachable();
         case TypeTableEntryIdMetaType:
@@ -15763,14 +15749,11 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
         case TypeTableEntryIdBlock:
         case TypeTableEntryIdArgTuple:
         case TypeTableEntryIdOpaque:
-            out_val->data.x_union.payload = nullptr;
-            break;
+            // TODO: Construct a valid void payload.
+            return nullptr;
         case TypeTableEntryIdInt:
             {
-                // Error from 'ir_resolve_const': "unable to evaluate constant expression"
                 ConstExprValue *payload = create_const_vals(1);
-                out_val->data.x_union.payload = payload;
-
                 payload->special = ConstValSpecialStatic;
 
                 ConstExprValue *int_info_type = get_builtin_value(ira->codegen, "IntInfo");
@@ -15780,23 +15763,135 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
                 ConstExprValue *fields = create_const_vals(2);
                 payload->data.x_struct.fields = fields;
 
-                payload->data.x_struct.parent.id = ConstParentIdUnion;
-                payload->data.x_struct.parent.data.p_union.union_val = out_val;
+                if (parent->type->id == TypeTableEntryIdStruct)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdStruct;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else if (parent->type->id == TypeTableEntryIdUnion)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdUnion;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdNone;
+                }
 
-                // TODO: See what happens if we don't set the field type (set it to nullptr)
+                // is_signed: bool
                 fields[0].special = ConstValSpecialStatic;
                 fields[0].type = ira->codegen->builtin_types.entry_bool;
                 fields[0].data.x_bool = type_entry->data.integral.is_signed;
-
+                // bits: u8
                 fields[1].special = ConstValSpecialStatic;
                 fields[1].type = ira->codegen->builtin_types.entry_u8;
                 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count);
 
-                break;
+                return payload;
+            }
+        case TypeTableEntryIdFloat:
+            {
+                ConstExprValue *payload = create_const_vals(1);
+                payload->special = ConstValSpecialStatic;
+
+                ConstExprValue *float_info_type = get_builtin_value(ira->codegen, "FloatInfo");
+                assert(float_info_type->type->id == TypeTableEntryIdMetaType);
+                payload->type = float_info_type->data.x_type;
+
+                ConstExprValue *fields = create_const_vals(1);
+                payload->data.x_struct.fields = fields;
+
+                if (parent->type->id == TypeTableEntryIdStruct)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdStruct;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else if (parent->type->id == TypeTableEntryIdUnion)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdUnion;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdNone;
+                }
+                // bits: u8
+                fields[0].special = ConstValSpecialStatic;
+                fields[0].type = ira->codegen->builtin_types.entry_u8;
+                bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count);
+
+                return payload;
+            }
+        case TypeTableEntryIdPointer:
+            {
+                ConstExprValue *payload = create_const_vals(1);
+                payload->special = ConstValSpecialStatic;
+
+                ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "PointerInfo");
+                assert(pointer_info_type->type->id == TypeTableEntryIdMetaType);
+                payload->type = pointer_info_type->data.x_type;
+
+                ConstExprValue *fields = create_const_vals(4);
+                payload->data.x_struct.fields = fields;
+
+                if (parent->type->id == TypeTableEntryIdStruct)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdStruct;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else if (parent->type->id == TypeTableEntryIdUnion)
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdUnion;
+                    payload->data.x_struct.parent.data.p_union.union_val = parent;
+                }
+                else
+                {
+                    payload->data.x_struct.parent.id = ConstParentIdNone;
+                }
+                // is_const: bool
+                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
+                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
+                fields[2].special = ConstValSpecialStatic;
+                fields[2].type = ira->codegen->builtin_types.entry_u32;
+                bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.pointer.alignment);
+                // child: &TypeInfo
+                ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo");
+                assert(type_info_type->type->id == TypeTableEntryIdMetaType);
+                fields[3].special = ConstValSpecialStatic;
+                fields[3].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false);
+                fields[3].data.x_ptr.special = ConstPtrSpecialRef;
+                fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar;
+                fields[3].data.x_ptr.data.ref.pointee = ir_make_type_info_value(ira, &fields[3], type_entry->data.pointer.child_type);
+                return payload;
             }
         default:
-            zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name));
+            zig_unreachable();
     }
+}
+
+static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira,
+        IrInstructionTypeInfo *instruction)
+{
+    IrInstruction *type_value = instruction->type_value->other;
+    TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
+    if (type_is_invalid(type_entry))
+        return ira->codegen->builtin_types.entry_invalid;
+
+    ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo");
+    assert(var_value->type->id == TypeTableEntryIdMetaType);
+    TypeTableEntry *result_type = var_value->data.x_type;
+
+    // TODO: We need to return a const pointer to the typeinfo, not the typeinfo by value.
+    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));
+    out_val->data.x_union.payload = ir_make_type_info_value(ira, out_val, type_entry);
 
     return result_type;
 }