| author | |
| committer | |
| log | bf3d1c1aab336c4a650bb67dcaca132d4a0f6164 |
| tree | c97dceae3e7ea164cfd3154f91e5b314df762c92 |
| parent | ffb089a9f5fa95fd559a7c88081310d0be73f206 |
4 files changed, 29 insertions(+), 5 deletions(-)
src/analyze.cpp+12-2| ... | @@ -3761,14 +3761,24 @@ static bool is_container(TypeTableEntry *type_entry) { | ... | @@ -3761,14 +3761,24 @@ static bool is_container(TypeTableEntry *type_entry) { |
| 3761 | zig_unreachable(); | 3761 | zig_unreachable(); |
| 3762 | } | 3762 | } |
| 3763 | 3763 | ||
| 3764 | bool is_ref(TypeTableEntry *type_entry) { | ||
| 3765 | return type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle; | ||
| 3766 | } | ||
| 3767 | |||
| 3768 | bool is_array_ref(TypeTableEntry *type_entry) { | ||
| 3769 | TypeTableEntry *array = is_ref(type_entry) ? | ||
| 3770 | type_entry->data.pointer.child_type : type_entry; | ||
| 3771 | return array->id == TypeTableEntryIdArray; | ||
| 3772 | } | ||
| 3773 | |||
| 3764 | bool is_container_ref(TypeTableEntry *type_entry) { | 3774 | bool is_container_ref(TypeTableEntry *type_entry) { |
| 3765 | return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ? | 3775 | return is_ref(type_entry) ? |
| 3766 | is_container(type_entry->data.pointer.child_type) : is_container(type_entry); | 3776 | is_container(type_entry->data.pointer.child_type) : is_container(type_entry); |
| 3767 | } | 3777 | } |
| 3768 | 3778 | ||
| 3769 | TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) { | 3779 | TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) { |
| 3770 | assert(is_container_ref(type_entry)); | 3780 | assert(is_container_ref(type_entry)); |
| 3771 | return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ? | 3781 | return is_ref(type_entry) ? |
| 3772 | type_entry->data.pointer.child_type : type_entry; | 3782 | type_entry->data.pointer.child_type : type_entry; |
| 3773 | } | 3783 | } |
| 3774 | 3784 |
src/analyze.hpp+2| ... | @@ -70,6 +70,8 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name); | ... | @@ -70,6 +70,8 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name); |
| 70 | TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag); | 70 | TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag); |
| 71 | TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag); | 71 | TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag); |
| 72 | 72 | ||
| 73 | bool is_ref(TypeTableEntry *type_entry); | ||
| 74 | bool is_array_ref(TypeTableEntry *type_entry); | ||
| 73 | bool is_container_ref(TypeTableEntry *type_entry); | 75 | bool is_container_ref(TypeTableEntry *type_entry); |
| 74 | void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node); | 76 | void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node); |
| 75 | void scan_import(CodeGen *g, ImportTableEntry *import); | 77 | void scan_import(CodeGen *g, ImportTableEntry *import); |
src/ir.cpp+6-2| ... | @@ -13846,10 +13846,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -13846,10 +13846,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 13846 | ir_link_new_instruction(result, &field_ptr_instruction->base); | 13846 | ir_link_new_instruction(result, &field_ptr_instruction->base); |
| 13847 | return result->value.type; | 13847 | return result->value.type; |
| 13848 | } | 13848 | } |
| 13849 | } else if (container_type->id == TypeTableEntryIdArray) { | 13849 | } else if (is_array_ref(container_type)) { |
| 13850 | if (buf_eql_str(field_name, "len")) { | 13850 | if (buf_eql_str(field_name, "len")) { |
| 13851 | ConstExprValue *len_val = create_const_vals(1); | 13851 | ConstExprValue *len_val = create_const_vals(1); |
| 13852 | init_const_usize(ira->codegen, len_val, container_type->data.array.len); | 13852 | if (container_type->id == TypeTableEntryIdPointer) { |
| 13853 | init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); | ||
| 13854 | } else { | ||
| 13855 | init_const_usize(ira->codegen, len_val, container_type->data.array.len); | ||
| 13856 | } | ||
| 13853 | 13857 | ||
| 13854 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; | 13858 | TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize; |
| 13855 | bool ptr_is_const = true; | 13859 | bool ptr_is_const = true; |
test/cases/array.zig+9-1| ... | @@ -116,6 +116,15 @@ test "array len property" { | ... | @@ -116,6 +116,15 @@ test "array len property" { |
| 116 | assert(@typeOf(x).len == 5); | 116 | assert(@typeOf(x).len == 5); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | test "array len field" { | ||
| 120 | var arr = [4]u8{ 0, 0, 0, 0 }; | ||
| 121 | var ptr = &arr; | ||
| 122 | assert(arr.len == 4); | ||
| 123 | comptime assert(arr.len == 4); | ||
| 124 | assert(ptr.len == 4); | ||
| 125 | comptime assert(ptr.len == 4); | ||
| 126 | } | ||
| 127 | |||
| 119 | test "single-item pointer to array indexing and slicing" { | 128 | test "single-item pointer to array indexing and slicing" { |
| 120 | testSingleItemPtrArrayIndexSlice(); | 129 | testSingleItemPtrArrayIndexSlice(); |
| 121 | comptime testSingleItemPtrArrayIndexSlice(); | 130 | comptime testSingleItemPtrArrayIndexSlice(); |
| ... | @@ -143,4 +152,3 @@ fn testImplicitCastSingleItemPtr() void { | ... | @@ -143,4 +152,3 @@ fn testImplicitCastSingleItemPtr() void { |
| 143 | slice[0] += 1; | 152 | slice[0] += 1; |
| 144 | assert(byte == 101); | 153 | assert(byte == 101); |
| 145 | } | 154 | } |
| 146 |