Skip to content

Commit

Permalink
Allow access of array.len through a pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
Hejsil committed Jun 8, 2018
1 parent ffb089a commit bf3d1c1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
14 changes: 12 additions & 2 deletions src/analyze.cpp
Expand Up @@ -3761,14 +3761,24 @@ static bool is_container(TypeTableEntry *type_entry) {
zig_unreachable();
}

bool is_ref(TypeTableEntry *type_entry) {
return type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle;
}

bool is_array_ref(TypeTableEntry *type_entry) {
TypeTableEntry *array = is_ref(type_entry) ?
type_entry->data.pointer.child_type : type_entry;
return array->id == TypeTableEntryIdArray;
}

bool is_container_ref(TypeTableEntry *type_entry) {
return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ?
return is_ref(type_entry) ?
is_container(type_entry->data.pointer.child_type) : is_container(type_entry);
}

TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) {
assert(is_container_ref(type_entry));
return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ?
return is_ref(type_entry) ?
type_entry->data.pointer.child_type : type_entry;
}

Expand Down
2 changes: 2 additions & 0 deletions src/analyze.hpp
Expand Up @@ -70,6 +70,8 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name);
TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag);
TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag);

bool is_ref(TypeTableEntry *type_entry);
bool is_array_ref(TypeTableEntry *type_entry);
bool is_container_ref(TypeTableEntry *type_entry);
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
void scan_import(CodeGen *g, ImportTableEntry *import);
Expand Down
8 changes: 6 additions & 2 deletions src/ir.cpp
Expand Up @@ -13846,10 +13846,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
ir_link_new_instruction(result, &field_ptr_instruction->base);
return result->value.type;
}
} else if (container_type->id == TypeTableEntryIdArray) {
} else if (is_array_ref(container_type)) {
if (buf_eql_str(field_name, "len")) {
ConstExprValue *len_val = create_const_vals(1);
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
if (container_type->id == TypeTableEntryIdPointer) {
init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len);
} else {
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
}

TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
bool ptr_is_const = true;
Expand Down
10 changes: 9 additions & 1 deletion test/cases/array.zig
Expand Up @@ -116,6 +116,15 @@ test "array len property" {
assert(@typeOf(x).len == 5);
}

test "array len field" {
var arr = [4]u8{ 0, 0, 0, 0 };
var ptr = &arr;
assert(arr.len == 4);
comptime assert(arr.len == 4);
assert(ptr.len == 4);
comptime assert(ptr.len == 4);
}

test "single-item pointer to array indexing and slicing" {
testSingleItemPtrArrayIndexSlice();
comptime testSingleItemPtrArrayIndexSlice();
Expand Down Expand Up @@ -143,4 +152,3 @@ fn testImplicitCastSingleItemPtr() void {
slice[0] += 1;
assert(byte == 101);
}

0 comments on commit bf3d1c1

Please sign in to comment.