Commit 7a91e4736a

Alexandros Naskos <alex_naskos@hotmail.com>
2018-04-26 13:29:27
Reset parent on cached TypeInfo values if we need to.
1 parent bb56360
Changed files (2)
src/codegen.cpp
@@ -6348,7 +6348,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
         buf_appendf(contents, "};\n\n");
     }
     {
-        // @TODO Add method info where methods are supported.
         // @TODO Add Namespace info.
         buf_appendf(contents,
             "pub const TypeInfo = union(TypeId) {\n"
@@ -6449,6 +6448,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
             "        layout: ContainerLayout,\n"
             "        tag_type: Int,\n"
             "        fields: []EnumField,\n"
+            "        methods: []Method,\n"
             "    };\n"
             "\n"
             "    pub const UnionField = struct {\n"
@@ -6461,6 +6461,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
             "        layout: ContainerLayout,\n"
             "        tag_type: ?Enum,\n"
             "        fields: []UnionField,\n"
+            "        methods: []Method,\n"
             "    };\n"
             "\n"
             "    pub const CallingConvention = enum {\n"
src/ir.cpp
@@ -15810,17 +15810,61 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na
 static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent,
         ssize_t parent_field_index, TypeTableEntry *type_entry)
 {
+    assert(type_entry != nullptr);
+    assert(!type_is_invalid(type_entry));
+
     // Lookup an available value in our cache.
     auto entry = ira->codegen->type_info_cache.maybe_get(type_entry);
     if (entry != nullptr)
-        return entry->value;
+    {
+        // Override the parent if we need to.
+        ConstExprValue *result = entry->value;
 
-    ConstExprValue *result = nullptr;
+        assert(result->type->id == TypeTableEntryIdStruct);
 
-    // @TODO
-    // We should probably cache the values generated with a type_entry key.
-    assert(type_entry != nullptr);
-    assert(!type_is_invalid(type_entry));
+        ConstParent *curr_parent = &result->data.x_struct.parent;
+        if (curr_parent->id == ConstParentIdStruct)
+        {
+            if (curr_parent->data.p_struct.struct_val == parent &&
+                parent_field_index != -1 &&
+                curr_parent->data.p_struct.field_index == (size_t)parent_field_index)
+            {
+                return result;
+            }
+            ConstExprValue *new_result = create_const_vals(1);
+            copy_const_val(new_result, result, true);
+            ir_type_info_struct_set_parent(new_result, parent, parent_field_index);
+            return new_result;
+        }
+        else if (curr_parent->id == ConstParentIdUnion)
+        {
+            if (curr_parent->data.p_union.union_val == parent)
+            {
+                return result;
+            }
+            ConstExprValue *new_result = create_const_vals(1);
+            copy_const_val(new_result, result, true);
+            ir_type_info_struct_set_parent(new_result, parent, parent_field_index);
+            return new_result;
+        }
+        else if (curr_parent->id == ConstParentIdNone)
+        {
+            if (parent->type->id != TypeTableEntryIdStruct &&
+                parent->type->id != TypeTableEntryIdArray &&
+                parent->type->id != TypeTableEntryIdUnion)
+            {
+                return result;
+            }
+            ConstExprValue *new_result = create_const_vals(1);
+            copy_const_val(new_result, result, true);
+            ir_type_info_struct_set_parent(new_result, parent, parent_field_index);
+            return new_result;
+        }
+
+        return result;
+    }
+
+    ConstExprValue *result = nullptr;
 
     switch (type_entry->id)
     {
@@ -16042,6 +16086,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p
             zig_unreachable();
     }
 
+    // Cache the returned value.
     assert(result != nullptr);
     ira->codegen->type_info_cache.put(type_entry, result);
     return result;