diff options
| author | Jimmi HC <jhc@liab.dk> | 2018-06-08 09:21:31 +0200 |
|---|---|---|
| committer | Jimmi HC <jhc@liab.dk> | 2018-06-08 09:21:31 +0200 |
| commit | bf3d1c1aab336c4a650bb67dcaca132d4a0f6164 (patch) | |
| tree | c97dceae3e7ea164cfd3154f91e5b314df762c92 /src | |
| parent | ffb089a9f5fa95fd559a7c88081310d0be73f206 (diff) | |
| download | zig-bf3d1c1aab336c4a650bb67dcaca132d4a0f6164.tar.gz zig-bf3d1c1aab336c4a650bb67dcaca132d4a0f6164.zip | |
Allow access of array.len through a pointer
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 14 | ||||
| -rw-r--r-- | src/analyze.hpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 8 |
3 files changed, 20 insertions, 4 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index e05fb23237..84f1473ea1 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -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; } diff --git a/src/analyze.hpp b/src/analyze.hpp index 25bda198d6..88e06b2390 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -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); diff --git a/src/ir.cpp b/src/ir.cpp index cc4ffb44a9..4766bff5e7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -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; |
