authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-06-08 09:21:31+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-06-08 09:21:31+02:00
logbf3d1c1aab336c4a650bb67dcaca132d4a0f6164
treec97dceae3e7ea164cfd3154f91e5b314df762c92
parentffb089a9f5fa95fd559a7c88081310d0be73f206

Allow access of array.len through a pointer


4 files changed, 29 insertions(+), 5 deletions(-)

src/analyze.cpp+12-2
......@@ -3761,14 +3761,24 @@ static bool is_container(TypeTableEntry *type_entry) {
37613761 zig_unreachable();
37623762}
37633763
3764bool is_ref(TypeTableEntry *type_entry) {
3765 return type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle;
3766}
3767
3768bool 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
37643774bool 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) ?
37663776 is_container(type_entry->data.pointer.child_type) : is_container(type_entry);
37673777}
37683778
37693779TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) {
37703780 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) ?
37723782 type_entry->data.pointer.child_type : type_entry;
37733783}
37743784
src/analyze.hpp+2
......@@ -70,6 +70,8 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name);
7070TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag);
7171TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag);
7272
73bool is_ref(TypeTableEntry *type_entry);
74bool is_array_ref(TypeTableEntry *type_entry);
7375bool is_container_ref(TypeTableEntry *type_entry);
7476void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
7577void 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
1384613846 ir_link_new_instruction(result, &field_ptr_instruction->base);
1384713847 return result->value.type;
1384813848 }
13849 } else if (container_type->id == TypeTableEntryIdArray) {
13849 } else if (is_array_ref(container_type)) {
1385013850 if (buf_eql_str(field_name, "len")) {
1385113851 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 }
1385313857
1385413858 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
1385513859 bool ptr_is_const = true;
test/cases/array.zig+9-1
......@@ -116,6 +116,15 @@ test "array len property" {
116116 assert(@typeOf(x).len == 5);
117117}
118118
119test "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
119128test "single-item pointer to array indexing and slicing" {
120129 testSingleItemPtrArrayIndexSlice();
121130 comptime testSingleItemPtrArrayIndexSlice();
......@@ -143,4 +152,3 @@ fn testImplicitCastSingleItemPtr() void {
143152 slice[0] += 1;
144153 assert(byte == 101);
145154}
146