mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 22:28:46 +00:00
Fix find_using_index_expr
This commit is contained in:
+1
-1
@@ -531,7 +531,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
|||||||
for (isize i = 0; i < params->variable_count; i++) {
|
for (isize i = 0; i < params->variable_count; i++) {
|
||||||
Entity *e = params->variables[i];
|
Entity *e = params->variables[i];
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
if (!(e->flags & EntityFlag_Anonymous)) {
|
if (!(e->flags & EntityFlag_Using)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool is_immutable = e->Variable.is_immutable;
|
bool is_immutable = e->Variable.is_immutable;
|
||||||
|
|||||||
+9
-17
@@ -89,7 +89,7 @@ bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
|||||||
if (is_type_struct(src)) {
|
if (is_type_struct(src)) {
|
||||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||||
Entity *f = src->Record.fields[i];
|
Entity *f = src->Record.fields[i];
|
||||||
if (f->kind == Entity_Variable && (f->flags & EntityFlag_Anonymous)) {
|
if (f->kind == Entity_Variable && (f->flags & EntityFlag_Using)) {
|
||||||
if (are_types_identical(dst, f->type)) {
|
if (are_types_identical(dst, f->type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -323,7 +323,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
|
|||||||
} else {
|
} else {
|
||||||
map_entity_set(entity_map, key, f);
|
map_entity_set(entity_map, key, f);
|
||||||
add_entity(c, c->context.scope, NULL, f);
|
add_entity(c, c->context.scope, NULL, f);
|
||||||
if (f->flags & EntityFlag_Anonymous) {
|
if (f->flags & EntityFlag_Using) {
|
||||||
populate_using_entity_map(c, node, f->type, entity_map);
|
populate_using_entity_map(c, node, f->type, entity_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -406,7 +406,7 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
|||||||
bool ok = true;
|
bool ok = true;
|
||||||
for_array(emi, entity_map.entries) {
|
for_array(emi, entity_map.entries) {
|
||||||
Entity *e = entity_map.entries.e[emi].value;
|
Entity *e = entity_map.entries.e[emi].value;
|
||||||
if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
if (is_type_indexable(e->type)) {
|
if (is_type_indexable(e->type)) {
|
||||||
if (e->identifier != f->names.e[0]) {
|
if (e->identifier != f->names.e[0]) {
|
||||||
ok = false;
|
ok = false;
|
||||||
@@ -419,7 +419,7 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
using_index_expr = fields[field_index-1];
|
using_index_expr = fields[field_index-1];
|
||||||
} else {
|
} else {
|
||||||
fields[field_index-1]->flags &= ~EntityFlag_Anonymous;
|
fields[field_index-1]->flags &= ~EntityFlag_Using;
|
||||||
error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string));
|
error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -603,6 +603,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
|
|||||||
union_type->Record.fields_in_src_order = fields;
|
union_type->Record.fields_in_src_order = fields;
|
||||||
union_type->Record.field_count = field_count;
|
union_type->Record.field_count = field_count;
|
||||||
union_type->Record.are_offsets_set = false;
|
union_type->Record.are_offsets_set = false;
|
||||||
|
union_type->Record.is_ordered = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for_array(i, ut->variants) {
|
for_array(i, ut->variants) {
|
||||||
@@ -2056,17 +2058,6 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// CLEANUP(bill) NOTE(bill): there is an auto assignment to `any` which needs to be checked
|
|
||||||
if (is_type_any(x->type) && !is_type_any(y->type)) {
|
|
||||||
err_type = x->type;
|
|
||||||
defined = false;
|
|
||||||
} else if (is_type_any(y->type) && !is_type_any(x->type)) {
|
|
||||||
err_type = y->type;
|
|
||||||
defined = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!defined) {
|
if (!defined) {
|
||||||
if (x->type == err_type && is_operand_nil(*x)) {
|
if (x->type == err_type && is_operand_nil(*x)) {
|
||||||
err_type = y->type;
|
err_type = y->type;
|
||||||
@@ -2223,7 +2214,7 @@ String check_down_cast_name(Type *dst_, Type *src_) {
|
|||||||
for (isize i = 0; i < dst_s->Record.field_count; i++) {
|
for (isize i = 0; i < dst_s->Record.field_count; i++) {
|
||||||
Entity *f = dst_s->Record.fields[i];
|
Entity *f = dst_s->Record.fields[i];
|
||||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||||
if (f->flags & EntityFlag_Anonymous) {
|
if (f->flags & EntityFlag_Using) {
|
||||||
if (are_types_identical(f->type, src_)) {
|
if (are_types_identical(f->type, src_)) {
|
||||||
return f->token.string;
|
return f->token.string;
|
||||||
}
|
}
|
||||||
@@ -4705,7 +4696,8 @@ Entity *find_using_index_expr(Type *t) {
|
|||||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||||
Entity *f = t->Record.fields[i];
|
Entity *f = t->Record.fields[i];
|
||||||
if (f->kind == Entity_Variable &&
|
if (f->kind == Entity_Variable &&
|
||||||
f->flags & (EntityFlag_Anonymous|EntityFlag_Field)) {
|
(f->flags & EntityFlag_Field) != 0 &&
|
||||||
|
(f->flags & EntityFlag_Using) != 0) {
|
||||||
if (is_type_indexable(f->type)) {
|
if (is_type_indexable(f->type)) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1984,6 +1984,8 @@ void check_parsed_files(Checker *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE(bill): Check for illegal cyclic type declarations
|
// NOTE(bill): Check for illegal cyclic type declarations
|
||||||
for_array(i, c->info.definitions.entries) {
|
for_array(i, c->info.definitions.entries) {
|
||||||
Entity *e = c->info.definitions.entries.e[i].value;
|
Entity *e = c->info.definitions.entries.e[i].value;
|
||||||
@@ -1991,10 +1993,15 @@ void check_parsed_files(Checker *c) {
|
|||||||
if (e->type != NULL) {
|
if (e->type != NULL) {
|
||||||
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
// i64 size = type_size_of(c->sizes, c->allocator, e->type);
|
||||||
i64 align = type_align_of(c->allocator, e->type);
|
i64 align = type_align_of(c->allocator, e->type);
|
||||||
|
if (align > 0) {
|
||||||
|
// add_type_info_type(c, e->type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gb_printf_err("Count: %td\n", c->info.type_info_count++);
|
||||||
|
|
||||||
for_array(i, file_scopes.entries) {
|
for_array(i, file_scopes.entries) {
|
||||||
Scope *s = file_scopes.entries.e[i].value;
|
Scope *s = file_scopes.entries.e[i].value;
|
||||||
if (s->is_init) {
|
if (s->is_init) {
|
||||||
|
|||||||
+4
-4
@@ -33,7 +33,7 @@ String const entity_strings[] = {
|
|||||||
typedef enum EntityFlag {
|
typedef enum EntityFlag {
|
||||||
EntityFlag_Visited = 1<<0,
|
EntityFlag_Visited = 1<<0,
|
||||||
EntityFlag_Used = 1<<1,
|
EntityFlag_Used = 1<<1,
|
||||||
EntityFlag_Anonymous = 1<<2,
|
EntityFlag_Using = 1<<2,
|
||||||
EntityFlag_Field = 1<<3,
|
EntityFlag_Field = 1<<3,
|
||||||
EntityFlag_Param = 1<<4,
|
EntityFlag_Param = 1<<4,
|
||||||
EntityFlag_VectorElem = 1<<5,
|
EntityFlag_VectorElem = 1<<5,
|
||||||
@@ -159,7 +159,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
|
|||||||
token.pos = parent->token.pos;
|
token.pos = parent->token.pos;
|
||||||
Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
|
||||||
entity->using_parent = parent;
|
entity->using_parent = parent;
|
||||||
entity->flags |= EntityFlag_Anonymous;
|
entity->flags |= EntityFlag_Using;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *ty
|
|||||||
Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous, bool is_immutable) {
|
Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous, bool is_immutable) {
|
||||||
Entity *entity = make_entity_variable(a, scope, token, type, is_immutable);
|
Entity *entity = make_entity_variable(a, scope, token, type, is_immutable);
|
||||||
entity->flags |= EntityFlag_Used;
|
entity->flags |= EntityFlag_Used;
|
||||||
if (anonymous) entity->flags |= EntityFlag_Anonymous;
|
if (anonymous) entity->flags |= EntityFlag_Using;
|
||||||
entity->flags |= EntityFlag_Param;
|
entity->flags |= EntityFlag_Param;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type,
|
|||||||
entity->Variable.field_src_index = field_src_index;
|
entity->Variable.field_src_index = field_src_index;
|
||||||
entity->Variable.field_index = field_src_index;
|
entity->Variable.field_index = field_src_index;
|
||||||
entity->flags |= EntityFlag_Field;
|
entity->flags |= EntityFlag_Field;
|
||||||
entity->flags |= EntityFlag_Anonymous*(anonymous != 0);
|
entity->flags |= EntityFlag_Using*(anonymous != 0);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ struct irProcedure {
|
|||||||
#define IR_TYPE_INFO_TYPES_NAME "__$type_info_types_data"
|
#define IR_TYPE_INFO_TYPES_NAME "__$type_info_types_data"
|
||||||
#define IR_TYPE_INFO_NAMES_NAME "__$type_info_names_data"
|
#define IR_TYPE_INFO_NAMES_NAME "__$type_info_names_data"
|
||||||
#define IR_TYPE_INFO_OFFSETS_NAME "__$type_info_offsets_data"
|
#define IR_TYPE_INFO_OFFSETS_NAME "__$type_info_offsets_data"
|
||||||
|
#define IR_TYPE_INFO_USINGS_NAME "__$type_info_usings_data"
|
||||||
|
|
||||||
|
|
||||||
#define IR_INSTR_KINDS \
|
#define IR_INSTR_KINDS \
|
||||||
@@ -2596,7 +2597,7 @@ String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
|||||||
GB_ASSERT(is_type_struct(src));
|
GB_ASSERT(is_type_struct(src));
|
||||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||||
Entity *f = src->Record.fields[i];
|
Entity *f = src->Record.fields[i];
|
||||||
if (f->kind == Entity_Variable && f->flags & EntityFlag_Anonymous) {
|
if (f->kind == Entity_Variable && f->flags & EntityFlag_Using) {
|
||||||
if (are_types_identical(dst, f->type)) {
|
if (are_types_identical(dst, f->type)) {
|
||||||
return f->token.string;
|
return f->token.string;
|
||||||
}
|
}
|
||||||
@@ -3123,11 +3124,13 @@ gb_global irValue *ir_global_type_info_data = NULL;
|
|||||||
gb_global irValue *ir_global_type_info_member_types = NULL;
|
gb_global irValue *ir_global_type_info_member_types = NULL;
|
||||||
gb_global irValue *ir_global_type_info_member_names = NULL;
|
gb_global irValue *ir_global_type_info_member_names = NULL;
|
||||||
gb_global irValue *ir_global_type_info_member_offsets = NULL;
|
gb_global irValue *ir_global_type_info_member_offsets = NULL;
|
||||||
|
gb_global irValue *ir_global_type_info_member_usings = NULL;
|
||||||
|
|
||||||
gb_global i32 ir_global_type_info_data_index = 0;
|
gb_global i32 ir_global_type_info_data_index = 0;
|
||||||
gb_global i32 ir_global_type_info_member_types_index = 0;
|
gb_global i32 ir_global_type_info_member_types_index = 0;
|
||||||
gb_global i32 ir_global_type_info_member_names_index = 0;
|
gb_global i32 ir_global_type_info_member_names_index = 0;
|
||||||
gb_global i32 ir_global_type_info_member_offsets_index = 0;
|
gb_global i32 ir_global_type_info_member_offsets_index = 0;
|
||||||
|
gb_global i32 ir_global_type_info_member_usings_index = 0;
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_type_info(irProcedure *proc, Type *type) {
|
irValue *ir_type_info(irProcedure *proc, Type *type) {
|
||||||
@@ -4550,7 +4553,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
|
irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
|
||||||
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
|
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
Entity *parent = e->using_parent;
|
Entity *parent = e->using_parent;
|
||||||
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
||||||
@@ -4594,7 +4597,7 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
|
|||||||
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
|
irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
v = *found;
|
v = *found;
|
||||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
// NOTE(bill): Calculate the using variable every time
|
// NOTE(bill): Calculate the using variable every time
|
||||||
v = ir_get_using_variable(proc, e);
|
v = ir_get_using_variable(proc, e);
|
||||||
}
|
}
|
||||||
@@ -6741,6 +6744,16 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
map_ir_value_set(&m->members, hash_string(name), g);
|
map_ir_value_set(&m->members, hash_string(name), g);
|
||||||
ir_global_type_info_member_offsets = g;
|
ir_global_type_info_member_offsets = g;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
String name = str_lit(IR_TYPE_INFO_USINGS_NAME);
|
||||||
|
Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
|
||||||
|
make_type_array(m->allocator, t_bool, count), false);
|
||||||
|
irValue *g = ir_value_global(m->allocator, e, NULL);
|
||||||
|
ir_module_add_value(m, e, g);
|
||||||
|
map_ir_value_set(&m->members, hash_string(name), g);
|
||||||
|
ir_global_type_info_member_usings = g;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6832,6 +6845,11 @@ irValue *ir_type_info_member_offsets_offset(irProcedure *proc, isize count) {
|
|||||||
ir_global_type_info_member_offsets_index += count;
|
ir_global_type_info_member_offsets_index += count;
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
irValue *ir_type_info_member_usings_offset(irProcedure *proc, isize count) {
|
||||||
|
irValue *offset = ir_emit_array_epi(proc, ir_global_type_info_member_usings, ir_global_type_info_member_usings_index);
|
||||||
|
ir_global_type_info_member_usings_index += count;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -7393,14 +7411,15 @@ void ir_gen_tree(irGen *s) {
|
|||||||
irValue *packed = ir_const_bool(a, t->Record.is_packed);
|
irValue *packed = ir_const_bool(a, t->Record.is_packed);
|
||||||
irValue *ordered = ir_const_bool(a, t->Record.is_ordered);
|
irValue *ordered = ir_const_bool(a, t->Record.is_ordered);
|
||||||
irValue *custom_align = ir_const_bool(a, t->Record.custom_align);
|
irValue *custom_align = ir_const_bool(a, t->Record.custom_align);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), packed);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), packed);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), ordered);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 5), ordered);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 5), custom_align);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, record, 6), custom_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Record.field_count);
|
irValue *memory_types = ir_type_info_member_types_offset(proc, t->Record.field_count);
|
||||||
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Record.field_count);
|
irValue *memory_names = ir_type_info_member_names_offset(proc, t->Record.field_count);
|
||||||
irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
|
irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
|
||||||
|
irValue *memory_usings = ir_type_info_member_usings_offset(proc, t->Record.field_count);
|
||||||
|
|
||||||
type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
|
||||||
for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
|
for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
|
||||||
@@ -7413,6 +7432,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
irValue *index = ir_const_int(a, source_index);
|
irValue *index = ir_const_int(a, source_index);
|
||||||
irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
irValue *type_info = ir_emit_ptr_offset(proc, memory_types, index);
|
||||||
irValue *offset = ir_emit_ptr_offset(proc, memory_offsets, index);
|
irValue *offset = ir_emit_ptr_offset(proc, memory_offsets, index);
|
||||||
|
irValue *is_using = ir_emit_ptr_offset(proc, memory_usings, index);
|
||||||
|
|
||||||
ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
|
||||||
if (f->token.string.len > 0) {
|
if (f->token.string.len > 0) {
|
||||||
@@ -7420,12 +7440,14 @@ void ir_gen_tree(irGen *s) {
|
|||||||
ir_emit_store(proc, name, ir_const_string(a, f->token.string));
|
ir_emit_store(proc, name, ir_const_string(a, f->token.string));
|
||||||
}
|
}
|
||||||
ir_emit_store(proc, offset, ir_const_int(a, foffset));
|
ir_emit_store(proc, offset, ir_const_int(a, foffset));
|
||||||
|
ir_emit_store(proc, is_using, ir_const_bool(a, f->flags&EntityFlag_Using));
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *count = ir_const_int(a, t->Record.field_count);
|
irValue *count = ir_const_int(a, t->Record.field_count);
|
||||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, count, count);
|
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types, count, count);
|
||||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, count, count);
|
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names, count, count);
|
||||||
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, count, count);
|
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, count, count);
|
||||||
|
ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 3), memory_usings, count, count);
|
||||||
} break;
|
} break;
|
||||||
case TypeRecord_Union: {
|
case TypeRecord_Union: {
|
||||||
ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
ir_emit_comment(proc, str_lit("Type_Info_Union"));
|
||||||
|
|||||||
@@ -700,7 +700,7 @@ ssaValue *ssa_addr_load(ssaProc *p, ssaAddr addr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
|
ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
|
||||||
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
|
GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
Entity *parent = e->using_parent;
|
Entity *parent = e->using_parent;
|
||||||
Selection sel = lookup_field(p->allocator, parent->type, name, false);
|
Selection sel = lookup_field(p->allocator, parent->type, name, false);
|
||||||
@@ -724,7 +724,7 @@ ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
|
|||||||
ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
|
ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
|
||||||
if (found) {
|
if (found) {
|
||||||
v = *found;
|
v = *found;
|
||||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
|
||||||
// NOTE(bill): Calculate the using variable every time
|
// NOTE(bill): Calculate the using variable every time
|
||||||
v = ssa_get_using_variable(p, e);
|
v = ssa_get_using_variable(p, e);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-3
@@ -935,13 +935,21 @@ bool are_types_identical(Type *x, Type *y) {
|
|||||||
x->Record.custom_align == y->Record.custom_align) {
|
x->Record.custom_align == y->Record.custom_align) {
|
||||||
// TODO(bill); Fix the custom alignment rule
|
// TODO(bill); Fix the custom alignment rule
|
||||||
for (isize i = 0; i < x->Record.field_count; i++) {
|
for (isize i = 0; i < x->Record.field_count; i++) {
|
||||||
if (!are_types_identical(x->Record.fields[i]->type, y->Record.fields[i]->type)) {
|
Entity *xf = x->Record.fields[i];
|
||||||
|
Entity *yf = y->Record.fields[i];
|
||||||
|
if (!are_types_identical(xf->type, yf->type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (str_ne(x->Record.fields[i]->token.string, y->Record.fields[i]->token.string)) {
|
if (str_ne(xf->token.string, yf->token.string)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool xf_is_using = (xf->flags&EntityFlag_Using) != 0;
|
||||||
|
bool yf_is_using = (yf->flags&EntityFlag_Using) != 0;
|
||||||
|
if (xf_is_using ^ yf_is_using) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// NOTE(bill): zeroth variant is NULL
|
||||||
for (isize i = 1; i < x->Record.variant_count; i++) {
|
for (isize i = 1; i < x->Record.variant_count; i++) {
|
||||||
if (!are_types_identical(x->Record.variants[i]->type, y->Record.variants[i]->type)) {
|
if (!are_types_identical(x->Record.variants[i]->type, y->Record.variants[i]->type)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1340,7 +1348,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
|
|||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->flags & EntityFlag_Anonymous) {
|
if (f->flags & EntityFlag_Using) {
|
||||||
isize prev_count = sel.index.count;
|
isize prev_count = sel.index.count;
|
||||||
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user