mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Fix type cycle bug
This commit is contained in:
+17
-3
@@ -864,13 +864,21 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
||||||
if (e->type != nullptr) {
|
if (e->state == EntityState_Resolved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = e->token.string;
|
||||||
|
|
||||||
|
if (e->type != nullptr || e->state != EntityState_Unresolved) {
|
||||||
|
error(e->token, "Illegal declaration cycle of `%.*s`", LIT(name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GB_ASSERT(e->state == EntityState_Unresolved);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
char buf[256] = {};
|
char buf[256] = {};
|
||||||
isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(e->token.string), e->kind);
|
isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(name), e->kind);
|
||||||
Timings timings = {};
|
Timings timings = {};
|
||||||
timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
|
timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
|
||||||
defer ({
|
defer ({
|
||||||
@@ -887,17 +895,21 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
|||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
// TODO(bill): Err here?
|
// TODO(bill): Err here?
|
||||||
e->type = t_invalid;
|
e->type = t_invalid;
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
set_base_type(named_type, t_invalid);
|
set_base_type(named_type, t_invalid);
|
||||||
return;
|
return;
|
||||||
// GB_PANIC("'%.*s' should been declared!", LIT(e->token.string));
|
// GB_PANIC("'%.*s' should been declared!", LIT(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckerContext prev = c->context;
|
CheckerContext prev = c->context;
|
||||||
c->context.scope = d->scope;
|
c->context.scope = d->scope;
|
||||||
c->context.decl = d;
|
c->context.decl = d;
|
||||||
|
c->context.type_level = 0;
|
||||||
|
|
||||||
e->parent_proc_decl = c->context.curr_proc_decl;
|
e->parent_proc_decl = c->context.curr_proc_decl;
|
||||||
|
e->state = EntityState_InProgress;
|
||||||
|
|
||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_Variable:
|
case Entity_Variable:
|
||||||
@@ -918,6 +930,8 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
|
|
||||||
c->context = prev;
|
c->context = prev;
|
||||||
|
|
||||||
#undef TIME_SECTION
|
#undef TIME_SECTION
|
||||||
|
|||||||
+3
-1
@@ -984,7 +984,9 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_entity_use(c, n, e);
|
add_entity_use(c, n, e);
|
||||||
check_entity_decl(c, e, nullptr, named_type);
|
if (e->state == EntityState_Unresolved) {
|
||||||
|
check_entity_decl(c, e, nullptr, named_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (e->type == nullptr) {
|
if (e->type == nullptr) {
|
||||||
|
|||||||
+4
-2
@@ -1000,7 +1000,7 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
|
|
||||||
check_open_scope(c, stmt);
|
check_open_scope(c, stmt);
|
||||||
{
|
{
|
||||||
Entity *tag_var = make_entity_variable(c->allocator, c->context.scope, lhs->Ident.token, case_type, false);
|
Entity *tag_var = make_entity_variable(c->allocator, c->context.scope, lhs->Ident.token, case_type, false, EntityState_Resolved);
|
||||||
tag_var->flags |= EntityFlag_Used;
|
tag_var->flags |= EntityFlag_Used;
|
||||||
tag_var->flags |= EntityFlag_Value;
|
tag_var->flags |= EntityFlag_Value;
|
||||||
add_entity(c, c->context.scope, lhs, tag_var);
|
add_entity(c, c->context.scope, lhs, tag_var);
|
||||||
@@ -1467,7 +1467,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
bool is_immutable = true;
|
bool is_immutable = true;
|
||||||
entity = make_entity_variable(c->allocator, c->context.scope, token, type, is_immutable);
|
entity = make_entity_variable(c->allocator, c->context.scope, token, type, is_immutable, EntityState_Resolved);
|
||||||
add_entity_definition(&c->info, name, entity);
|
add_entity_definition(&c->info, name, entity);
|
||||||
} else {
|
} else {
|
||||||
TokenPos pos = found->token.pos;
|
TokenPos pos = found->token.pos;
|
||||||
@@ -1858,8 +1858,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
}
|
}
|
||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
|
||||||
|
e->state = EntityState_InProgress;
|
||||||
if (e->type == nullptr) {
|
if (e->type == nullptr) {
|
||||||
e->type = init_type;
|
e->type = init_type;
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
}
|
}
|
||||||
ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
|
||||||
e->Variable.thread_local_model = ac.thread_local_model;
|
e->Variable.thread_local_model = ac.thread_local_model;
|
||||||
|
|||||||
+22
-13
@@ -312,6 +312,7 @@ void add_polymorphic_struct_entity(Checker *c, AstNode *node, Type *named_type,
|
|||||||
node->Ident.token = token;
|
node->Ident.token = token;
|
||||||
|
|
||||||
e = make_entity_type_name(a, s, token, named_type);
|
e = make_entity_type_name(a, s, token, named_type);
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
add_entity_use(c, node, e);
|
add_entity_use(c, node, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,6 +469,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
add_entity(c, scope, name, e);
|
add_entity(c, scope, name, e);
|
||||||
array_add(&entities, e);
|
array_add(&entities, e);
|
||||||
}
|
}
|
||||||
@@ -698,6 +700,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
|||||||
Entity *e = make_entity_constant(c->allocator, c->context.scope, ident->Ident.token, constant_type, iota);
|
Entity *e = make_entity_constant(c->allocator, c->context.scope, ident->Ident.token, constant_type, iota);
|
||||||
e->identifier = ident;
|
e->identifier = ident;
|
||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
|
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
if (map_get(&entity_map, key) != nullptr) {
|
if (map_get(&entity_map, key) != nullptr) {
|
||||||
@@ -1181,7 +1184,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
type = t_invalid;
|
type = t_invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
param = make_entity_type_name(c->allocator, scope, name->Ident.token, type);
|
param = make_entity_type_name(c->allocator, scope, name->Ident.token, type, EntityState_Resolved);
|
||||||
param->TypeName.is_type_alias = true;
|
param->TypeName.is_type_alias = true;
|
||||||
} else {
|
} else {
|
||||||
if (operands != nullptr && variables.count < operands->count) {
|
if (operands != nullptr && variables.count < operands->count) {
|
||||||
@@ -1212,6 +1215,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
if (p->flags&FieldFlag_no_alias) {
|
if (p->flags&FieldFlag_no_alias) {
|
||||||
param->flags |= EntityFlag_NoAlias;
|
param->flags |= EntityFlag_NoAlias;
|
||||||
}
|
}
|
||||||
|
param->state = EntityState_Resolved; // NOTE(bill): This should have be resolved whilst determining it
|
||||||
|
|
||||||
add_entity(c, scope, name, param);
|
add_entity(c, scope, name, param);
|
||||||
array_add(&variables, param);
|
array_add(&variables, param);
|
||||||
@@ -1754,9 +1758,9 @@ void generate_map_entry_type(gbAllocator a, Type *type) {
|
|||||||
Scope *s = create_scope(universal_scope, a);
|
Scope *s = create_scope(universal_scope, a);
|
||||||
|
|
||||||
auto fields = array_make<Entity *>(a, 0, 3);
|
auto fields = array_make<Entity *>(a, 0, 3);
|
||||||
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")), t_map_key, false, 0));
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")), t_map_key, false, 0, EntityState_Resolved));
|
||||||
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")), t_int, false, 1));
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")), t_int, false, 1, EntityState_Resolved));
|
||||||
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2));
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2, EntityState_Resolved));
|
||||||
|
|
||||||
|
|
||||||
entry_type->Struct.fields = fields;
|
entry_type->Struct.fields = fields;
|
||||||
@@ -1793,8 +1797,8 @@ void generate_map_internal_types(gbAllocator a, Type *type) {
|
|||||||
|
|
||||||
|
|
||||||
auto fields = array_make<Entity *>(a, 0, 2);
|
auto fields = array_make<Entity *>(a, 0, 2);
|
||||||
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")), hashes_type, false, 0));
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved));
|
||||||
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1));
|
array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved));
|
||||||
|
|
||||||
generated_struct_type->Struct.fields = fields;
|
generated_struct_type->Struct.fields = fields;
|
||||||
|
|
||||||
@@ -1842,7 +1846,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
case_ast_node(i, Ident, e);
|
case_ast_node(i, Ident, e);
|
||||||
|
|
||||||
Operand o = {};
|
Operand o = {};
|
||||||
check_ident(c, &o, e, named_type, nullptr, false);
|
Entity *entity = check_ident(c, &o, e, named_type, nullptr, false);
|
||||||
|
|
||||||
gbString err_str = nullptr;
|
gbString err_str = nullptr;
|
||||||
defer (gb_string_free(err_str));
|
defer (gb_string_free(err_str));
|
||||||
@@ -1857,8 +1861,13 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
if (t != nullptr && is_type_polymorphic_struct_unspecialized(t)) {
|
if (t != nullptr && is_type_polymorphic_struct_unspecialized(t)) {
|
||||||
err_str = expr_to_string(e);
|
err_str = expr_to_string(e);
|
||||||
error(e, "Invalid use of a non-specialized polymorphic type '%s'", err_str);
|
error(e, "Invalid use of a non-specialized polymorphic type '%s'", err_str);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->context.type_level == 0 && entity->state == EntityState_InProgress) {
|
||||||
|
error(e, "Illegal declaration cycle of `%.*s`", LIT(entity->token.string));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1895,8 +1904,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
Token token = ident->Ident.token;
|
Token token = ident->Ident.token;
|
||||||
Type *specific = nullptr;
|
Type *specific = nullptr;
|
||||||
if (pt->specialization != nullptr) {
|
if (pt->specialization != nullptr) {
|
||||||
auto prev_ips = c->context.in_polymorphic_specialization;
|
CheckerContext prev = c->context; defer (c->context = prev);
|
||||||
defer (c->context.in_polymorphic_specialization = prev_ips);
|
|
||||||
c->context.in_polymorphic_specialization = true;
|
c->context.in_polymorphic_specialization = true;
|
||||||
|
|
||||||
AstNode *s = pt->specialization;
|
AstNode *s = pt->specialization;
|
||||||
@@ -1919,6 +1927,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
}
|
}
|
||||||
Entity *e = make_entity_type_name(c->allocator, entity_scope, token, t);
|
Entity *e = make_entity_type_name(c->allocator, entity_scope, token, t);
|
||||||
e->TypeName.is_type_alias = true;
|
e->TypeName.is_type_alias = true;
|
||||||
|
e->state = EntityState_Resolved;
|
||||||
add_entity(c, ps, ident, e);
|
add_entity(c, ps, ident, e);
|
||||||
add_entity(c, s, ident, e);
|
add_entity(c, s, ident, e);
|
||||||
} else {
|
} else {
|
||||||
@@ -2007,9 +2016,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(st, StructType, e);
|
case_ast_node(st, StructType, e);
|
||||||
bool ips = c->context.in_polymorphic_specialization;
|
CheckerContext prev = c->context; defer (c->context = prev);
|
||||||
defer (c->context.in_polymorphic_specialization = ips);
|
|
||||||
c->context.in_polymorphic_specialization = false;
|
c->context.in_polymorphic_specialization = false;
|
||||||
|
c->context.type_level += 1;
|
||||||
|
|
||||||
*type = make_type_struct(c->allocator);
|
*type = make_type_struct(c->allocator);
|
||||||
set_base_type(named_type, *type);
|
set_base_type(named_type, *type);
|
||||||
@@ -2021,9 +2030,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(ut, UnionType, e);
|
case_ast_node(ut, UnionType, e);
|
||||||
bool ips = c->context.in_polymorphic_specialization;
|
CheckerContext prev = c->context; defer (c->context = prev);
|
||||||
defer (c->context.in_polymorphic_specialization = ips);
|
|
||||||
c->context.in_polymorphic_specialization = false;
|
c->context.in_polymorphic_specialization = false;
|
||||||
|
c->context.type_level += 1;
|
||||||
|
|
||||||
*type = make_type_union(c->allocator);
|
*type = make_type_union(c->allocator);
|
||||||
set_base_type(named_type, *type);
|
set_base_type(named_type, *type);
|
||||||
|
|||||||
@@ -503,6 +503,7 @@ Entity *add_global_entity(Entity *entity) {
|
|||||||
if (scope_insert_entity(universal_scope, entity)) {
|
if (scope_insert_entity(universal_scope, entity)) {
|
||||||
compiler_error("double declaration");
|
compiler_error("double declaration");
|
||||||
}
|
}
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ struct CheckerContext {
|
|||||||
DeclInfo * decl;
|
DeclInfo * decl;
|
||||||
u32 stmt_state_flags;
|
u32 stmt_state_flags;
|
||||||
bool in_defer; // TODO(bill): Actually handle correctly
|
bool in_defer; // TODO(bill): Actually handle correctly
|
||||||
|
isize type_level; // TODO(bill): Actually handle correctly
|
||||||
String proc_name;
|
String proc_name;
|
||||||
Type * type_hint;
|
Type * type_hint;
|
||||||
DeclInfo * curr_proc_decl;
|
DeclInfo * curr_proc_decl;
|
||||||
|
|||||||
+34
-16
@@ -57,25 +57,32 @@ enum OverloadKind {
|
|||||||
Overload_Yes = 2,
|
Overload_Yes = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EntityState {
|
||||||
|
EntityState_Unresolved = 0,
|
||||||
|
EntityState_InProgress = 1,
|
||||||
|
EntityState_Resolved = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// An Entity is a named "thing" in the language
|
// An Entity is a named "thing" in the language
|
||||||
struct Entity {
|
struct Entity {
|
||||||
EntityKind kind;
|
EntityKind kind;
|
||||||
u64 id;
|
u64 id;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
Token token;
|
EntityState state;
|
||||||
Scope * scope;
|
Token token;
|
||||||
Type * type;
|
Scope * scope;
|
||||||
AstNode * identifier; // Can be nullptr
|
Type * type;
|
||||||
DeclInfo * decl_info;
|
AstNode * identifier; // Can be nullptr
|
||||||
DeclInfo * parent_proc_decl; // nullptr if in file/global scope
|
DeclInfo * decl_info;
|
||||||
|
DeclInfo * parent_proc_decl; // nullptr if in file/global scope
|
||||||
|
|
||||||
// TODO(bill): Cleanup how `using` works for entities
|
// TODO(bill): Cleanup how `using` works for entities
|
||||||
Entity * using_parent;
|
Entity * using_parent;
|
||||||
AstNode * using_expr;
|
AstNode * using_expr;
|
||||||
|
|
||||||
isize order_in_src;
|
isize order_in_src;
|
||||||
String deprecated_message;
|
String deprecated_message;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@@ -173,6 +180,7 @@ gb_global u64 global_entity_id = 0;
|
|||||||
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
|
Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
|
||||||
Entity *entity = gb_alloc_item(a, Entity);
|
Entity *entity = gb_alloc_item(a, Entity);
|
||||||
entity->kind = kind;
|
entity->kind = kind;
|
||||||
|
entity->state = EntityState_Unresolved;
|
||||||
entity->scope = scope;
|
entity->scope = scope;
|
||||||
entity->token = token;
|
entity->token = token;
|
||||||
entity->type = type;
|
entity->type = type;
|
||||||
@@ -180,9 +188,10 @@ Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token,
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type, bool is_immutable) {
|
Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type, bool is_immutable, EntityState state = EntityState_Unresolved) {
|
||||||
Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type);
|
||||||
entity->Variable.is_immutable = is_immutable;
|
entity->Variable.is_immutable = is_immutable;
|
||||||
|
entity->state = state;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +203,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
|
|||||||
entity->parent_proc_decl = parent->parent_proc_decl;
|
entity->parent_proc_decl = parent->parent_proc_decl;
|
||||||
entity->flags |= EntityFlag_Using;
|
entity->flags |= EntityFlag_Using;
|
||||||
entity->flags |= EntityFlag_Used;
|
entity->flags |= EntityFlag_Used;
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,8 +214,9 @@ Entity *make_entity_constant(gbAllocator a, Scope *scope, Token token, Type *typ
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type) {
|
Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
|
||||||
Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type);
|
||||||
|
entity->state = state;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +225,7 @@ Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type,
|
|||||||
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;
|
||||||
entity->flags |= EntityFlag_Param;
|
entity->flags |= EntityFlag_Param;
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
if (is_using) entity->flags |= EntityFlag_Using;
|
if (is_using) entity->flags |= EntityFlag_Using;
|
||||||
if (is_value) entity->flags |= EntityFlag_Value;
|
if (is_value) entity->flags |= EntityFlag_Value;
|
||||||
return entity;
|
return entity;
|
||||||
@@ -229,12 +241,13 @@ Entity *make_entity_const_param(gbAllocator a, Scope *scope, Token token, Type *
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index) {
|
Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index, EntityState state = EntityState_Unresolved) {
|
||||||
Entity *entity = make_entity_variable(a, scope, token, type, false);
|
Entity *entity = make_entity_variable(a, scope, token, type, false);
|
||||||
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;
|
||||||
if (is_using) entity->flags |= EntityFlag_Using;
|
if (is_using) entity->flags |= EntityFlag_Using;
|
||||||
entity->flags |= EntityFlag_Field;
|
entity->flags |= EntityFlag_Field;
|
||||||
|
entity->state = state;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,6 +257,7 @@ Entity *make_entity_array_elem(gbAllocator a, Scope *scope, Token token, Type *t
|
|||||||
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_ArrayElem;
|
entity->flags |= EntityFlag_ArrayElem;
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,6 +276,7 @@ Entity *make_entity_proc_group(gbAllocator a, Scope *scope, Token token, Type *t
|
|||||||
Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, i32 id) {
|
Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, i32 id) {
|
||||||
Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type);
|
||||||
entity->Builtin.id = id;
|
entity->Builtin.id = id;
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,6 +292,7 @@ Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *
|
|||||||
entity->ImportName.path = path;
|
entity->ImportName.path = path;
|
||||||
entity->ImportName.name = name;
|
entity->ImportName.name = name;
|
||||||
entity->ImportName.scope = import_scope;
|
entity->ImportName.scope = import_scope;
|
||||||
|
entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,6 +301,7 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
|
|||||||
Entity *entity = alloc_entity(a, Entity_LibraryName, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_LibraryName, scope, token, type);
|
||||||
entity->LibraryName.path = path;
|
entity->LibraryName.path = path;
|
||||||
entity->LibraryName.name = name;
|
entity->LibraryName.name = name;
|
||||||
|
entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +318,7 @@ Entity *make_entity_label(gbAllocator a, Scope *scope, Token token, Type *type,
|
|||||||
AstNode *node) {
|
AstNode *node) {
|
||||||
Entity *entity = alloc_entity(a, Entity_Label, scope, token, type);
|
Entity *entity = alloc_entity(a, Entity_Label, scope, token, type);
|
||||||
entity->Label.node = node;
|
entity->Label.node = node;
|
||||||
|
entity->state = EntityState_Resolved;
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -217,6 +217,7 @@ struct Type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO(bill): Should I add extra information here specifying the kind of selection?
|
// TODO(bill): Should I add extra information here specifying the kind of selection?
|
||||||
// e.g. field, constant, array field, type field, etc.
|
// e.g. field, constant, array field, type field, etc.
|
||||||
struct Selection {
|
struct Selection {
|
||||||
@@ -481,12 +482,6 @@ Type *alloc_type(gbAllocator a, TypeKind kind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type *make_type_basic(gbAllocator a, BasicType basic) {
|
|
||||||
Type *t = alloc_type(a, Type_Basic);
|
|
||||||
t->Basic = basic;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *make_type_generic(gbAllocator a, Scope *scope, i64 id, String name, Type *specialized) {
|
Type *make_type_generic(gbAllocator a, Scope *scope, i64 id, String name, Type *specialized) {
|
||||||
Type *t = alloc_type(a, Type_Generic);
|
Type *t = alloc_type(a, Type_Generic);
|
||||||
t->Generic.id = id;
|
t->Generic.id = id;
|
||||||
|
|||||||
Reference in New Issue
Block a user