i32 use_through_pointer_index;
b32 included_through_use : 1;
b32 used : 1;
+ b32 use_processed : 1;
bh_arr(struct AstTyped *) meta_tags;
} StructMember;
// NOTE: If this member was included into the structure through a "use x: ^T" kind of statement,
// then we have to insert a intermediate field access in order to access the correct member.
if (smem.use_through_pointer_index >= 0) {
- StructMember containing_member;
- assert(type_lookup_member_by_idx(field->expr->type, smem.use_through_pointer_index, &containing_member));
+ StructMember containing_member = smem;
- AstFieldAccess *new_access = onyx_ast_node_new(context.ast_alloc, sizeof(AstFieldAccess), Ast_Kind_Field_Access);
- new_access->token = field->token;
- new_access->offset = containing_member.offset;
- new_access->idx = containing_member.idx;
- new_access->type = containing_member.type;
- new_access->expr = field->expr;
- new_access->flags |= Ast_Flag_Has_Been_Checked;
- new_access->flags |= Ast_Flag_Extra_Field_Access;
+ // TODO: The following code is not right after it loops, but this should never loop
+ // due to a check in types.c line 947.
+ AstTyped **dest = &field->expr;
+ do {
+ assert(type_lookup_member_by_idx((*dest)->type, containing_member.use_through_pointer_index, &containing_member));
- field->expr = (AstTyped *) new_access;
+ AstFieldAccess *new_access = onyx_ast_node_new(context.ast_alloc, sizeof(AstFieldAccess), Ast_Kind_Field_Access);
+ new_access->token = field->token;
+ new_access->offset = containing_member.offset;
+ new_access->idx = containing_member.idx;
+ new_access->type = containing_member.type;
+ new_access->expr = *dest;
+ new_access->flags |= Ast_Flag_Has_Been_Checked;
+ new_access->flags |= Ast_Flag_Extra_Field_Access;
+
+ *dest = (AstTyped *) new_access;
+ dest = &new_access->expr;
+ } while (containing_member.use_through_pointer_index >= 0);
}
field->offset = smem.offset;
ERROR(s_node->token->pos, "Compound types are not allowed as struct member types.");
}
- if ((*smem)->used) {
+ if ((*smem)->used && !(*smem)->use_processed) {
if (!type_struct_member_apply_use(context.ast_alloc, s_node->pending_type, *smem)) {
YIELD((*smem)->token->pos, "Waiting for use to be applied.");
}
+
+ (*smem)->use_processed = 1;
}
}
return 0;
}
- if (used_type->Struct.status == SPS_Start) return 0;
+ if (used_type->Struct.status < SPS_Uses_Done) return 0;
- bh_arr_each(StructMember*, psmem, used_type->Struct.memarr) {
- if (shgeti(s_type->Struct.members, (*psmem)->name) != -1) {
- onyx_report_error(smem->token->pos, Error_Critical, "Used name '%s' conflicts with existing struct member.", (*psmem)->name);
+ fori (i, 0, shlen(used_type->Struct.members)) {
+ StructMember *nsmem = used_type->Struct.members[i].value;
+
+ //
+ // TODO: :Bugfix Currently, nested use through pointers are not
+ // working correctly and I need to rethink them entirely.
+ if (nsmem->use_through_pointer_index >= 0) {
+ continue;
+ }
+
+ if (shgeti(s_type->Struct.members, nsmem->name) != -1) {
+ onyx_report_error(smem->token->pos, Error_Critical, "Used name '%s' conflicts with existing struct member.", nsmem->name);
return 0;
}
StructMember* new_smem = bh_alloc_item(alloc, StructMember);
- new_smem->type = (*psmem)->type;
- new_smem->name = (*psmem)->name;
- new_smem->meta_tags = (*psmem)->meta_tags;
- new_smem->used = 0;
+ new_smem->type = nsmem->type;
+ new_smem->name = nsmem->name;
+ new_smem->meta_tags = nsmem->meta_tags;
+ new_smem->used = nsmem->used;
new_smem->included_through_use = 1;
if (type_is_pointer) {
- new_smem->offset = (*psmem)->offset;
- new_smem->idx = (*psmem)->idx;
+ new_smem->offset = nsmem->offset;
+ new_smem->idx = nsmem->idx;
new_smem->initial_value = NULL;
new_smem->use_through_pointer_index = smem->idx;
} else {
- new_smem->offset = smem->offset + (*psmem)->offset;
- new_smem->idx = -1; // Dummy value because I don't think this is needed.
- new_smem->initial_value = (*psmem)->initial_value;
+ new_smem->offset = smem->offset + nsmem->offset;
+ new_smem->idx = nsmem->idx; // Dummy value because I don't think this is needed.
+ new_smem->initial_value = nsmem->initial_value;
new_smem->use_through_pointer_index = -1;
}
- shput(s_type->Struct.members, (*psmem)->name, new_smem);
+ shput(s_type->Struct.members, nsmem->name, new_smem);
}
return 1;
},
(key: type_expr) -> u32 { return to_u32(cast(u32) key); },
- #precedence 10000 macro (key: $T/HasHashMethod) => key->hash()
+ #precedence 10000
+ macro (key: $T/HasHashMethod) => key->hash()
}
Hashable :: interface (t: $T) {