aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJimmi HC <jhc@liab.dk>2018-06-08 09:21:31 +0200
committerJimmi HC <jhc@liab.dk>2018-06-08 09:21:31 +0200
commitbf3d1c1aab336c4a650bb67dcaca132d4a0f6164 (patch)
treec97dceae3e7ea164cfd3154f91e5b314df762c92 /src
parentffb089a9f5fa95fd559a7c88081310d0be73f206 (diff)
downloadzig-bf3d1c1aab336c4a650bb67dcaca132d4a0f6164.tar.gz
zig-bf3d1c1aab336c4a650bb67dcaca132d4a0f6164.zip
Allow access of array.len through a pointer
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp14
-rw-r--r--src/analyze.hpp2
-rw-r--r--src/ir.cpp8
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;