diff options
| author | Alexandros Naskos <alex_naskos@hotmail.com> | 2018-04-26 14:29:27 +0300 |
|---|---|---|
| committer | Alexandros Naskos <alex_naskos@hotmail.com> | 2018-04-26 14:29:27 +0300 |
| commit | 7a91e4736a4151bd41b65b6e3b395cc51c443162 (patch) | |
| tree | 700ba05610f280b9a4045929b7973d80a53fb58a /src/ir.cpp | |
| parent | bb56360bfaa317809bd3c742a655b357bd5b6226 (diff) | |
| download | zig-7a91e4736a4151bd41b65b6e3b395cc51c443162.tar.gz zig-7a91e4736a4151bd41b65b6e3b395cc51c443162.zip | |
Reset parent on cached TypeInfo values if we need to.
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 9229e4e89d..5cffb882f2 100644 --- a/src/ir.cpp +++ b/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; |
