mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Minor Entity refactor
This commit is contained in:
@@ -301,7 +301,7 @@ void destroy_scope(Scope *scope) {
|
||||
for_array(i, scope->elements.entries) {
|
||||
Entity *e =scope->elements.entries[i].value;
|
||||
if (e->kind == Entity_Variable) {
|
||||
if (!e->Variable.used) {
|
||||
if (!(e->flags & EntityFlag_Used)) {
|
||||
#if 0
|
||||
warning(e->token, "Unused variable `%.*s`", LIT(e->token.string));
|
||||
#endif
|
||||
|
||||
@@ -198,11 +198,11 @@ void check_var_decl_node(Checker *c, AstNode *node) {
|
||||
for (isize i = 0; i < entity_count; i++) {
|
||||
Entity *e = entities[i];
|
||||
GB_ASSERT(e != NULL);
|
||||
if (e->Variable.visited) {
|
||||
if (e->flags & EntityFlag_Visited) {
|
||||
e->type = t_invalid;
|
||||
continue;
|
||||
}
|
||||
e->Variable.visited = true;
|
||||
e->flags |= EntityFlag_Visited;
|
||||
|
||||
if (e->type == NULL)
|
||||
e->type = init_type;
|
||||
@@ -270,11 +270,11 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_e
|
||||
|
||||
GB_ASSERT(e->type == NULL);
|
||||
|
||||
if (e->Variable.visited) {
|
||||
if (e->flags & EntityFlag_Visited) {
|
||||
e->type = t_invalid;
|
||||
return;
|
||||
}
|
||||
e->Variable.visited = true;
|
||||
e->flags |= EntityFlag_Visited;
|
||||
|
||||
if (type_expr) {
|
||||
Type *t = check_type(c, type_expr);
|
||||
@@ -463,11 +463,11 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
|
||||
GB_ASSERT(e->type == NULL);
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
if (e->Variable.visited) {
|
||||
if (e->flags & EntityFlag_Visited) {
|
||||
e->type = t_invalid;
|
||||
return;
|
||||
}
|
||||
e->Variable.visited = true;
|
||||
e->flags |= EntityFlag_Visited;
|
||||
|
||||
if (type_expr != NULL)
|
||||
e->type = check_type(c, type_expr, NULL);
|
||||
@@ -511,7 +511,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
if (!e->Variable.anonymous) {
|
||||
if (!(e->flags & EntityFlag_Anonymous)) {
|
||||
continue;
|
||||
}
|
||||
String name = e->token.string;
|
||||
|
||||
+18
-19
@@ -28,10 +28,19 @@ String const entity_strings[] = {
|
||||
#undef ENTITY_KIND
|
||||
};
|
||||
|
||||
enum EntityFlag : u32 {
|
||||
EntityFlag_Visited = 1<<0,
|
||||
EntityFlag_Used = 1<<1,
|
||||
EntityFlag_Anonymous = 1<<2,
|
||||
EntityFlag_Field = 1<<3,
|
||||
EntityFlag_Param = 1<<4,
|
||||
};
|
||||
|
||||
struct Entity {
|
||||
EntityKind kind;
|
||||
Scope * scope;
|
||||
u32 flags;
|
||||
Token token;
|
||||
Scope * scope;
|
||||
Type * type;
|
||||
AstNode * identifier; // Can be NULL
|
||||
|
||||
@@ -44,21 +53,11 @@ struct Entity {
|
||||
ExactValue value;
|
||||
} Constant;
|
||||
struct {
|
||||
b8 visited;
|
||||
b8 used;
|
||||
b8 anonymous;
|
||||
b8 field;
|
||||
b8 param;
|
||||
|
||||
i32 field_index;
|
||||
i32 field_src_index;
|
||||
} Variable;
|
||||
struct {
|
||||
b32 used;
|
||||
} TypeName;
|
||||
struct {
|
||||
b32 used;
|
||||
} Procedure;
|
||||
struct {} TypeName;
|
||||
struct {} Procedure;
|
||||
struct {
|
||||
BuiltinProcId id;
|
||||
} Builtin;
|
||||
@@ -109,7 +108,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
|
||||
GB_ASSERT(parent != NULL);
|
||||
Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
|
||||
entity->using_parent = parent;
|
||||
entity->Variable.anonymous = true;
|
||||
entity->flags |= EntityFlag_Anonymous;
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -127,9 +126,9 @@ 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, b32 anonymous) {
|
||||
Entity *entity = make_entity_variable(a, scope, token, type);
|
||||
entity->Variable.used = true;
|
||||
entity->Variable.anonymous = cast(b8)anonymous;
|
||||
entity->Variable.param = true;
|
||||
entity->flags |= EntityFlag_Used;
|
||||
entity->flags |= EntityFlag_Anonymous*(anonymous != 0);
|
||||
entity->flags |= EntityFlag_Param;
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -137,8 +136,8 @@ Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
Entity *entity = make_entity_variable(a, scope, token, type);
|
||||
entity->Variable.field_src_index = field_src_index;
|
||||
entity->Variable.field_index = field_src_index;
|
||||
entity->Variable.field = true;
|
||||
entity->Variable.anonymous = cast(b8)anonymous;
|
||||
entity->flags |= EntityFlag_Field;
|
||||
entity->flags |= EntityFlag_Anonymous*(anonymous != 0);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
if (is_type_struct(src)) {
|
||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||
Entity *f = src->Record.fields[i];
|
||||
if (f->kind == Entity_Variable && f->Variable.anonymous) {
|
||||
if (f->kind == Entity_Variable && (f->flags & EntityFlag_Anonymous)) {
|
||||
if (are_types_identical(dst, f->type)) {
|
||||
return true;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *>
|
||||
} else {
|
||||
map_set(entity_map, key, f);
|
||||
add_entity(c, c->context.scope, NULL, f);
|
||||
if (f->Variable.anonymous) {
|
||||
if (f->flags & EntityFlag_Anonymous) {
|
||||
populate_using_entity_map(c, node, f->type, entity_map);
|
||||
}
|
||||
}
|
||||
@@ -435,7 +435,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
b32 ok = true;
|
||||
for_array(emi, entity_map.entries) {
|
||||
Entity *e = entity_map.entries[emi].value;
|
||||
if (e->kind == Entity_Variable && e->Variable.anonymous) {
|
||||
if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
||||
if (is_type_indexable(e->type)) {
|
||||
if (e->identifier != vd->names[0]) {
|
||||
ok = false;
|
||||
@@ -448,7 +448,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
if (ok) {
|
||||
using_index_expr = fields[field_index-1];
|
||||
} else {
|
||||
fields[field_index-1]->Variable.anonymous = false;
|
||||
fields[field_index-1]->flags &= ~EntityFlag_Anonymous;
|
||||
error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string));
|
||||
}
|
||||
} else {
|
||||
@@ -936,7 +936,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
|
||||
break;
|
||||
|
||||
case Entity_Variable:
|
||||
e->Variable.used = true;
|
||||
e->flags |= EntityFlag_Used;
|
||||
if (type == t_invalid) {
|
||||
o->type = t_invalid;
|
||||
return;
|
||||
@@ -1748,8 +1748,8 @@ String check_down_cast_name(Type *dst_, Type *src_) {
|
||||
GB_ASSERT(is_type_struct(dst_s) || is_type_raw_union(dst_s));
|
||||
for (isize i = 0; i < dst_s->Record.field_count; i++) {
|
||||
Entity *f = dst_s->Record.fields[i];
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->Variable.field);
|
||||
if (f->Variable.anonymous) {
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||
if (f->flags & EntityFlag_Anonymous) {
|
||||
if (are_types_identical(f->type, src_)) {
|
||||
return f->token.string;
|
||||
}
|
||||
@@ -3490,7 +3490,7 @@ Entity *find_using_index_expr(Type *t) {
|
||||
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||
Entity *f = t->Record.fields[i];
|
||||
if (f->kind == Entity_Variable &&
|
||||
f->Variable.field && f->Variable.anonymous) {
|
||||
f->flags & (EntityFlag_Anonymous|EntityFlag_Field)) {
|
||||
if (is_type_indexable(f->type)) {
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -252,14 +252,16 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
||||
ast_node(i, Ident, node);
|
||||
e = scope_lookup_entity(c->context.scope, i->string);
|
||||
if (e != NULL && e->kind == Entity_Variable) {
|
||||
used = e->Variable.used; // TODO(bill): Make backup just in case
|
||||
used = (e->flags & EntityFlag_Used) != 0; // TODO(bill): Make backup just in case
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Operand op_b = {Addressing_Invalid};
|
||||
check_expr(c, &op_b, lhs);
|
||||
if (e) e->Variable.used = used;
|
||||
if (e) {
|
||||
e->flags |= EntityFlag_Used*used;
|
||||
}
|
||||
|
||||
if (op_b.mode == Addressing_Invalid ||
|
||||
op_b.type == t_invalid) {
|
||||
@@ -829,7 +831,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
||||
// NOTE(bill): Dummy type
|
||||
Type *tag_ptr_type = make_type_pointer(c->allocator, tag_type);
|
||||
Entity *tag_var = make_entity_variable(c->allocator, c->context.scope, ms->var->Ident, tag_ptr_type);
|
||||
tag_var->Variable.used = true;
|
||||
tag_var->flags |= EntityFlag_Used;
|
||||
add_entity(c, c->context.scope, ms->var, tag_var);
|
||||
add_entity_use(c, ms->var, tag_var);
|
||||
}
|
||||
|
||||
+32
-34
@@ -94,7 +94,6 @@ enum TypeRecordKind {
|
||||
|
||||
struct Type {
|
||||
TypeKind kind;
|
||||
u32 flags; // See parser.cpp `enum TypeFlag`
|
||||
union {
|
||||
BasicType Basic;
|
||||
struct {
|
||||
@@ -120,7 +119,7 @@ struct Type {
|
||||
// All record types
|
||||
// Theses are arrays
|
||||
Entity **fields; // Entity_Variable (otherwise Entity_TypeName if union)
|
||||
isize field_count; // == offset_count is struct
|
||||
i32 field_count; // == offset_count is struct
|
||||
AstNode *node;
|
||||
|
||||
union { // NOTE(bill): Reduce size_of Type
|
||||
@@ -141,7 +140,7 @@ struct Type {
|
||||
|
||||
// Entity_Constant or Entity_TypeName
|
||||
Entity **other_fields;
|
||||
isize other_field_count;
|
||||
i32 other_field_count;
|
||||
} Record;
|
||||
struct {
|
||||
String name;
|
||||
@@ -150,14 +149,14 @@ struct Type {
|
||||
} Named;
|
||||
struct {
|
||||
Entity **variables; // Entity_Variable
|
||||
isize variable_count;
|
||||
i32 variable_count;
|
||||
} Tuple;
|
||||
struct {
|
||||
Scope *scope;
|
||||
Type * params; // Type_Tuple
|
||||
Type * results; // Type_Tuple
|
||||
isize param_count;
|
||||
isize result_count;
|
||||
i32 param_count;
|
||||
i32 result_count;
|
||||
b32 variadic;
|
||||
} Proc;
|
||||
};
|
||||
@@ -306,34 +305,34 @@ Type *type_deref(Type *t) {
|
||||
|
||||
#define STR_LIT(x) {cast(u8 *)(x), gb_size_of(x)-1}
|
||||
gb_global Type basic_types[] = {
|
||||
{Type_Basic, 0, {Basic_Invalid, 0, STR_LIT("invalid type")}},
|
||||
{Type_Basic, 0, {Basic_bool, BasicFlag_Boolean, STR_LIT("bool")}},
|
||||
{Type_Basic, 0, {Basic_i8, BasicFlag_Integer, STR_LIT("i8")}},
|
||||
{Type_Basic, 0, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u8")}},
|
||||
{Type_Basic, 0, {Basic_i16, BasicFlag_Integer, STR_LIT("i16")}},
|
||||
{Type_Basic, 0, {Basic_u16, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u16")}},
|
||||
{Type_Basic, 0, {Basic_i32, BasicFlag_Integer, STR_LIT("i32")}},
|
||||
{Type_Basic, 0, {Basic_u32, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u32")}},
|
||||
{Type_Basic, 0, {Basic_i64, BasicFlag_Integer, STR_LIT("i64")}},
|
||||
{Type_Basic, 0, {Basic_u64, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u64")}},
|
||||
{Type_Basic, 0, {Basic_f32, BasicFlag_Float, STR_LIT("f32")}},
|
||||
{Type_Basic, 0, {Basic_f64, BasicFlag_Float, STR_LIT("f64")}},
|
||||
{Type_Basic, 0, {Basic_int, BasicFlag_Integer, STR_LIT("int")}},
|
||||
{Type_Basic, 0, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("uint")}},
|
||||
{Type_Basic, 0, {Basic_rawptr, BasicFlag_Pointer, STR_LIT("rawptr")}},
|
||||
{Type_Basic, 0, {Basic_string, BasicFlag_String, STR_LIT("string")}},
|
||||
{Type_Basic, 0, {Basic_any, 0, STR_LIT("any")}},
|
||||
{Type_Basic, 0, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, STR_LIT("untyped bool")}},
|
||||
{Type_Basic, 0, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped integer")}},
|
||||
{Type_Basic, 0, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, STR_LIT("untyped float")}},
|
||||
{Type_Basic, 0, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, STR_LIT("untyped string")}},
|
||||
{Type_Basic, 0, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped rune")}},
|
||||
{Type_Basic, 0, {Basic_UntypedNil, BasicFlag_Untyped, STR_LIT("untyped nil")}},
|
||||
{Type_Basic, {Basic_Invalid, 0, STR_LIT("invalid type")}},
|
||||
{Type_Basic, {Basic_bool, BasicFlag_Boolean, STR_LIT("bool")}},
|
||||
{Type_Basic, {Basic_i8, BasicFlag_Integer, STR_LIT("i8")}},
|
||||
{Type_Basic, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u8")}},
|
||||
{Type_Basic, {Basic_i16, BasicFlag_Integer, STR_LIT("i16")}},
|
||||
{Type_Basic, {Basic_u16, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u16")}},
|
||||
{Type_Basic, {Basic_i32, BasicFlag_Integer, STR_LIT("i32")}},
|
||||
{Type_Basic, {Basic_u32, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u32")}},
|
||||
{Type_Basic, {Basic_i64, BasicFlag_Integer, STR_LIT("i64")}},
|
||||
{Type_Basic, {Basic_u64, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u64")}},
|
||||
{Type_Basic, {Basic_f32, BasicFlag_Float, STR_LIT("f32")}},
|
||||
{Type_Basic, {Basic_f64, BasicFlag_Float, STR_LIT("f64")}},
|
||||
{Type_Basic, {Basic_int, BasicFlag_Integer, STR_LIT("int")}},
|
||||
{Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("uint")}},
|
||||
{Type_Basic, {Basic_rawptr, BasicFlag_Pointer, STR_LIT("rawptr")}},
|
||||
{Type_Basic, {Basic_string, BasicFlag_String, STR_LIT("string")}},
|
||||
{Type_Basic, {Basic_any, 0, STR_LIT("any")}},
|
||||
{Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, STR_LIT("untyped bool")}},
|
||||
{Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped integer")}},
|
||||
{Type_Basic, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, STR_LIT("untyped float")}},
|
||||
{Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, STR_LIT("untyped string")}},
|
||||
{Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped rune")}},
|
||||
{Type_Basic, {Basic_UntypedNil, BasicFlag_Untyped, STR_LIT("untyped nil")}},
|
||||
};
|
||||
|
||||
gb_global Type basic_type_aliases[] = {
|
||||
{Type_Basic, 0, {Basic_byte, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("byte")}},
|
||||
{Type_Basic, 0, {Basic_rune, BasicFlag_Integer, STR_LIT("rune")}},
|
||||
{Type_Basic, {Basic_byte, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("byte")}},
|
||||
{Type_Basic, {Basic_rune, BasicFlag_Integer, STR_LIT("rune")}},
|
||||
};
|
||||
|
||||
gb_global Type *t_invalid = &basic_types[Basic_Invalid];
|
||||
@@ -970,7 +969,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.field);
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
|
||||
String str = f->token.string;
|
||||
if (field_name == str) {
|
||||
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
||||
@@ -978,7 +977,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
|
||||
return sel;
|
||||
}
|
||||
|
||||
if (f->Variable.anonymous) {
|
||||
if (f->flags & EntityFlag_Anonymous) {
|
||||
isize prev_count = sel.index.count;
|
||||
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
||||
|
||||
@@ -1121,7 +1120,6 @@ b32 type_set_offsets(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
|
||||
i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
t = base_type(t);
|
||||
|
||||
switch (t->kind) {
|
||||
case Type_Basic: {
|
||||
GB_ASSERT(is_type_typed(t));
|
||||
|
||||
Reference in New Issue
Block a user