aboutsummaryrefslogtreecommitdiff
path: root/src/checker/type.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-10-10 10:27:50 +0100
committerGinger Bill <bill@gingerbill.org>2016-10-10 10:27:50 +0100
commitf5318c46d13ed3f3de20e0f61c4193e6ad46a42b (patch)
tree89f62b9ea2e6b07816335c6695e358051e8152f1 /src/checker/type.cpp
parent90babbfbf30cc9c611af74e8c0af3562faf4d58b (diff)
Implicit Values: `context`; Fix lvalue selector assignments; Fix offset_of* for `using` fields.
Diffstat (limited to 'src/checker/type.cpp')
-rw-r--r--src/checker/type.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/src/checker/type.cpp b/src/checker/type.cpp
index c077ed94d..bf8a0bd6b 100644
--- a/src/checker/type.cpp
+++ b/src/checker/type.cpp
@@ -812,6 +812,8 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
Type *type = type_deref(type_);
b32 is_ptr = type != type_;
+ sel.indirect = sel.indirect || is_ptr;
+
type = base_type(type);
if (type->kind == Type_Basic) {
@@ -918,7 +920,6 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
String str = f->token.string;
if (field_name == str) {
- Selection sel = {};
sel.entity = f;
selection_add_index(&sel, i);
return sel;
@@ -932,7 +933,6 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
String str = f->token.string;
if (field_name == str) {
- Selection sel = {};
sel.entity = f;
selection_add_index(&sel, i);
return sel;
@@ -955,7 +955,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
} else if (!is_type_enum(type) && !is_type_union(type)) {
for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[i];
- GB_ASSERT(f->kind == Entity_Variable && f->Variable.is_field);
+ GB_ASSERT(f->kind == Entity_Variable && f->Variable.field);
String str = f->token.string;
if (field_name == str) {
selection_add_index(&sel, i); // HACK(bill): Leaky memory
@@ -970,8 +970,9 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
sel = lookup_field(a, f->type, field_name, is_type, sel);
if (sel.entity != NULL) {
- if (is_type_pointer(f->type))
+ if (is_type_pointer(f->type)) {
sel.indirect = true;
+ }
return sel;
}
sel.index.count = prev_count;
@@ -1199,26 +1200,48 @@ i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
}
i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index) {
+ t = base_type(t);
if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
type_set_offsets(s, allocator, t);
if (gb_is_between(index, 0, t->Record.field_count-1)) {
return t->Record.struct_offsets[index];
}
+ } else if (t->kind == Type_Basic) {
+ gb_printf_err("here!!\n");
+ if (t->Basic.kind == Basic_string) {
+ switch (index) {
+ case 0: return 0;
+ case 1: return s.word_size;
+ }
+ } else if (t->Basic.kind == Basic_any) {
+ switch (index) {
+ case 0: return 0;
+ case 1: return s.word_size;
+ }
+ }
+ } else if (t->kind == Type_Slice) {
+ switch (index) {
+ case 0: return 0;
+ case 1: return 1*s.word_size;
+ case 2: return 2*s.word_size;
+ }
}
return 0;
}
i64 type_offset_of_from_selection(BaseTypeSizes s, gbAllocator allocator, Type *t, Selection sel) {
+ GB_ASSERT(sel.indirect == false);
+
i64 offset = 0;
for_array(i, sel.index) {
isize index = sel.index[i];
t = base_type(t);
+ offset += type_offset_of(s, allocator, t, index);
if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
- type_set_offsets(s, allocator, t);
- GB_ASSERT(gb_is_between(index, 0, t->Record.field_count-1));
- offset += t->Record.struct_offsets[index];
t = t->Record.fields[index]->type;
+ } else {
+ // NOTE(bill): string/any/slices don't have record fields so this case doesn't need to be handled
}
}
return offset;