mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 06:38:47 +00:00
Entity aliasing clean up
This commit is contained in:
+21
-29
@@ -260,6 +260,19 @@ void check_type_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, Type *d
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
|
||||||
|
// NOTE(bill): The original_entity's scope may not be same scope that it was inserted into
|
||||||
|
// e.g. file entity inserted into its package scope
|
||||||
|
String original_name = original_entity->token.string;
|
||||||
|
Scope *found_scope = nullptr;
|
||||||
|
Entity *found_entity = nullptr;
|
||||||
|
scope_lookup_parent(original_entity->scope, original_name, &found_scope, &found_entity);
|
||||||
|
GB_ASSERT(found_entity == original_entity);
|
||||||
|
|
||||||
|
map_set(&found_scope->elements, hash_string(original_name), new_entity);
|
||||||
|
}
|
||||||
|
|
||||||
void check_const_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, AstNode *init, Type *named_type) {
|
void check_const_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, AstNode *init, Type *named_type) {
|
||||||
GB_ASSERT(e->type == nullptr);
|
GB_ASSERT(e->type == nullptr);
|
||||||
GB_ASSERT(e->kind == Entity_Constant);
|
GB_ASSERT(e->kind == Entity_Constant);
|
||||||
@@ -321,40 +334,19 @@ void check_const_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, AstNod
|
|||||||
case Addressing_ProcGroup:
|
case Addressing_ProcGroup:
|
||||||
GB_ASSERT(operand.proc_group != nullptr);
|
GB_ASSERT(operand.proc_group != nullptr);
|
||||||
GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
|
GB_ASSERT(operand.proc_group->kind == Entity_ProcGroup);
|
||||||
|
override_entity_in_scope(e, operand.proc_group);
|
||||||
e->kind = Entity_ProcGroup;
|
|
||||||
e->type = t_invalid;
|
|
||||||
gb_memmove(&e->ProcGroup, &operand.proc_group->ProcGroup, gb_size_of(e->ProcGroup));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity != nullptr) {
|
if (entity != nullptr) {
|
||||||
// TODO(bill): Clean up aliasing code
|
|
||||||
|
// NOTE(bill): Override aliased entity
|
||||||
switch (entity->kind) {
|
switch (entity->kind) {
|
||||||
case Entity_Alias:
|
case Entity_ProcGroup:
|
||||||
e->kind = Entity_Alias;
|
|
||||||
e->type = entity->type;
|
|
||||||
e->Alias.base = entity->Alias.base;
|
|
||||||
return;
|
|
||||||
case Entity_Procedure:
|
case Entity_Procedure:
|
||||||
e->kind = Entity_Alias;
|
|
||||||
e->type = entity->type;
|
|
||||||
e->Alias.base = entity;
|
|
||||||
return;
|
|
||||||
case Entity_ImportName:
|
|
||||||
e->kind = Entity_ImportName;
|
|
||||||
e->type = entity->type;
|
|
||||||
e->ImportName.path = entity->ImportName.path;
|
|
||||||
e->ImportName.name = entity->ImportName.path;
|
|
||||||
e->ImportName.scope = entity->ImportName.scope;
|
|
||||||
e->flags &= ~EntityFlag_Used;
|
|
||||||
return;
|
|
||||||
case Entity_LibraryName:
|
case Entity_LibraryName:
|
||||||
e->kind = Entity_LibraryName;
|
case Entity_ImportName:
|
||||||
e->type = entity->type;
|
override_entity_in_scope(e, entity);
|
||||||
e->LibraryName.path = entity->LibraryName.path;
|
|
||||||
e->LibraryName.name = entity->LibraryName.path;
|
|
||||||
e->flags &= ~EntityFlag_Used;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,7 +449,7 @@ void init_entity_foreign_library(CheckerContext *ctx, Entity *e) {
|
|||||||
error(ident, "foreign library names must be an identifier");
|
error(ident, "foreign library names must be an identifier");
|
||||||
} else {
|
} else {
|
||||||
String name = ident->Ident.token.string;
|
String name = ident->Ident.token.string;
|
||||||
Entity *found = scope_lookup_entity(ctx->scope, name);
|
Entity *found = scope_lookup(ctx->scope, name);
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
// NOTE(bill): link against nothing
|
// NOTE(bill): link against nothing
|
||||||
@@ -992,7 +984,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
|||||||
uvar->Variable.is_immutable = is_immutable;
|
uvar->Variable.is_immutable = is_immutable;
|
||||||
if (is_value) uvar->flags |= EntityFlag_Value;
|
if (is_value) uvar->flags |= EntityFlag_Value;
|
||||||
|
|
||||||
Entity *prev = scope_insert_entity(ctx->scope, uvar);
|
Entity *prev = scope_insert(ctx->scope, uvar);
|
||||||
if (prev != nullptr) {
|
if (prev != nullptr) {
|
||||||
error(e->token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
|
error(e->token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
|
||||||
break;
|
break;
|
||||||
|
|||||||
+5
-87
@@ -782,7 +782,7 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source,
|
|||||||
if (poly->Array.generic_count != nullptr) {
|
if (poly->Array.generic_count != nullptr) {
|
||||||
Type *gt = poly->Array.generic_count;
|
Type *gt = poly->Array.generic_count;
|
||||||
GB_ASSERT(gt->kind == Type_Generic);
|
GB_ASSERT(gt->kind == Type_Generic);
|
||||||
Entity *e = scope_lookup_entity(gt->Generic.scope, gt->Generic.name);
|
Entity *e = scope_lookup(gt->Generic.scope, gt->Generic.name);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
if (e->kind == Entity_TypeName) {
|
if (e->kind == Entity_TypeName) {
|
||||||
poly->Array.generic_count = nullptr;
|
poly->Array.generic_count = nullptr;
|
||||||
@@ -927,7 +927,7 @@ Entity *check_ident(CheckerContext *c, Operand *o, AstNode *n, Type *named_type,
|
|||||||
o->expr = n;
|
o->expr = n;
|
||||||
String name = n->Ident.token.string;
|
String name = n->Ident.token.string;
|
||||||
|
|
||||||
Entity *e = scope_lookup_entity(c->scope, name);
|
Entity *e = scope_lookup(c->scope, name);
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
error(n, "'_' cannot be used as a value type");
|
error(n, "'_' cannot be used as a value type");
|
||||||
@@ -951,12 +951,6 @@ Entity *check_ident(CheckerContext *c, Operand *o, AstNode *n, Type *named_type,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool is_alias = false;
|
|
||||||
while (e->kind == Entity_Alias) {
|
|
||||||
GB_ASSERT(e->Alias.base != nullptr);
|
|
||||||
e = e->Alias.base;
|
|
||||||
is_alias = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
HashKey key = hash_string(e->token.string);
|
HashKey key = hash_string(e->token.string);
|
||||||
|
|
||||||
@@ -2536,7 +2530,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, AstNode *node, Type
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selector->kind != AstNode_Ident && selector->kind != AstNode_BasicLit) {
|
if (selector->kind != AstNode_Ident) {
|
||||||
// if (selector->kind != AstNode_Ident) {
|
// if (selector->kind != AstNode_Ident) {
|
||||||
error(selector, "Illegal selector kind: '%.*s'", LIT(ast_node_strings[selector->kind]));
|
error(selector, "Illegal selector kind: '%.*s'", LIT(ast_node_strings[selector->kind]));
|
||||||
operand->mode = Addressing_Invalid;
|
operand->mode = Addressing_Invalid;
|
||||||
@@ -2546,15 +2540,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, AstNode *node, Type
|
|||||||
|
|
||||||
if (op_expr->kind == AstNode_Ident) {
|
if (op_expr->kind == AstNode_Ident) {
|
||||||
String op_name = op_expr->Ident.token.string;
|
String op_name = op_expr->Ident.token.string;
|
||||||
Entity *e = scope_lookup_entity(c->scope, op_name);
|
Entity *e = scope_lookup(c->scope, op_name);
|
||||||
|
|
||||||
bool is_alias = false;
|
|
||||||
while (e != nullptr && e->kind == Entity_Alias) {
|
|
||||||
GB_ASSERT(e->Alias.base != nullptr);
|
|
||||||
e = e->Alias.base;
|
|
||||||
is_alias = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_entity_use(c, op_expr, e);
|
add_entity_use(c, op_expr, e);
|
||||||
expr_entity = e;
|
expr_entity = e;
|
||||||
|
|
||||||
@@ -2568,7 +2554,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, AstNode *node, Type
|
|||||||
String entity_name = selector->Ident.token.string;
|
String entity_name = selector->Ident.token.string;
|
||||||
|
|
||||||
check_op_expr = false;
|
check_op_expr = false;
|
||||||
entity = current_scope_lookup_entity(import_scope, entity_name);
|
entity = scope_lookup_current(import_scope, entity_name);
|
||||||
bool is_declared = entity != nullptr;
|
bool is_declared = entity != nullptr;
|
||||||
if (is_declared) {
|
if (is_declared) {
|
||||||
if (entity->kind == Entity_Builtin) {
|
if (entity->kind == Entity_Builtin) {
|
||||||
@@ -2587,24 +2573,10 @@ Entity *check_selector(CheckerContext *c, Operand *operand, AstNode *node, Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_alias = false;
|
|
||||||
while (entity->kind == Entity_Alias) {
|
|
||||||
GB_ASSERT(e->Alias.base != nullptr);
|
|
||||||
entity = entity->Alias.base;
|
|
||||||
is_alias = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_entity_decl(c, entity, nullptr, nullptr);
|
check_entity_decl(c, entity, nullptr, nullptr);
|
||||||
GB_ASSERT(entity->type != nullptr);
|
GB_ASSERT(entity->type != nullptr);
|
||||||
|
|
||||||
|
|
||||||
if (is_alias) {
|
|
||||||
// TODO(bill): Which scope do you search for for an alias?
|
|
||||||
// import_scope = entity->scope;
|
|
||||||
entity_name = entity->token.string;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool implicit_is_found = is_entity_implicitly_imported(e, entity);
|
bool implicit_is_found = is_entity_implicitly_imported(e, entity);
|
||||||
bool is_not_exported = !is_entity_exported(entity);
|
bool is_not_exported = !is_entity_exported(entity);
|
||||||
if (entity->kind == Entity_ImportName) {
|
if (entity->kind == Entity_ImportName) {
|
||||||
@@ -2681,60 +2653,6 @@ Entity *check_selector(CheckerContext *c, Operand *operand, AstNode *node, Type
|
|||||||
add_type_info_type(c, operand->type);
|
add_type_info_type(c, operand->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (entity == nullptr && selector->kind == AstNode_BasicLit) {
|
|
||||||
if (is_type_struct(operand->type) || is_type_tuple(operand->type)) {
|
|
||||||
Type *type = base_type(operand->type);
|
|
||||||
Operand o = {};
|
|
||||||
check_expr(c, &o, selector);
|
|
||||||
if (o.mode != Addressing_Constant ||
|
|
||||||
!is_type_integer(o.type)) {
|
|
||||||
error(op_expr, "Indexed based selectors must be a constant integer %s");
|
|
||||||
operand->mode = Addressing_Invalid;
|
|
||||||
operand->expr = node;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
i64 index = o.value.value_integer;
|
|
||||||
if (index < 0) {
|
|
||||||
error(o.expr, "Index %lld cannot be a negative value", index);
|
|
||||||
operand->mode = Addressing_Invalid;
|
|
||||||
operand->expr = node;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
i64 max_count = 0;
|
|
||||||
switch (type->kind) {
|
|
||||||
case Type_Struct: max_count = type->Struct.fields.count; break;
|
|
||||||
case Type_Tuple: max_count = type->Tuple.variables.count; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= max_count) {
|
|
||||||
error(o.expr, "Index %lld is out of bounds range 0..<%lld", index, max_count);
|
|
||||||
operand->mode = Addressing_Invalid;
|
|
||||||
operand->expr = node;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
sel = lookup_field_from_index(type, index);
|
|
||||||
entity = sel.entity;
|
|
||||||
|
|
||||||
GB_ASSERT(entity != nullptr);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
error(op_expr, "Indexed based selectors may only be used on structs or tuples");
|
|
||||||
operand->mode = Addressing_Invalid;
|
|
||||||
operand->expr = node;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity == nullptr &&
|
|
||||||
operand->type != nullptr && is_type_untyped(operand->type) && is_type_string(operand->type)) {
|
|
||||||
String s = operand->value.value_string;
|
|
||||||
operand->mode = Addressing_Constant;
|
|
||||||
operand->value = exact_value_i64(s.len);
|
|
||||||
operand->type = t_untyped_integer;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity == nullptr) {
|
if (entity == nullptr) {
|
||||||
gbString op_str = expr_to_string(op_expr);
|
gbString op_str = expr_to_string(op_expr);
|
||||||
|
|||||||
+11
-11
@@ -236,7 +236,7 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
|
|||||||
} else {
|
} else {
|
||||||
if (node->kind == AstNode_Ident) {
|
if (node->kind == AstNode_Ident) {
|
||||||
ast_node(i, Ident, node);
|
ast_node(i, Ident, node);
|
||||||
e = scope_lookup_entity(ctx->scope, i->token.string);
|
e = scope_lookup(ctx->scope, i->token.string);
|
||||||
if (e != nullptr && e->kind == Entity_Variable) {
|
if (e != nullptr && e->kind == Entity_Variable) {
|
||||||
used = (e->flags & EntityFlag_Used) != 0; // TODO(bill): Make backup just in case
|
used = (e->flags & EntityFlag_Used) != 0; // TODO(bill): Make backup just in case
|
||||||
}
|
}
|
||||||
@@ -456,7 +456,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstNodeUsingStmt *us, AstNode
|
|||||||
Entity *f = t->Enum.fields[i];
|
Entity *f = t->Enum.fields[i];
|
||||||
if (!is_entity_exported(f)) continue;
|
if (!is_entity_exported(f)) continue;
|
||||||
|
|
||||||
Entity *found = scope_insert_entity(ctx->scope, f);
|
Entity *found = scope_insert(ctx->scope, f);
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
gbString expr_str = expr_to_string(expr);
|
gbString expr_str = expr_to_string(expr);
|
||||||
error(us->token, "Namespace collision while 'using' '%s' of: %.*s", expr_str, LIT(found->token.string));
|
error(us->token, "Namespace collision while 'using' '%s' of: %.*s", expr_str, LIT(found->token.string));
|
||||||
@@ -478,7 +478,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstNodeUsingStmt *us, AstNode
|
|||||||
Entity *decl = scope->elements.entries[i].value;
|
Entity *decl = scope->elements.entries[i].value;
|
||||||
if (!is_entity_exported(decl)) continue;
|
if (!is_entity_exported(decl)) continue;
|
||||||
|
|
||||||
Entity *found = scope_insert_entity(ctx->scope, decl);
|
Entity *found = scope_insert(ctx->scope, decl);
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
gbString expr_str = expr_to_string(expr);
|
gbString expr_str = expr_to_string(expr);
|
||||||
error(us->token,
|
error(us->token,
|
||||||
@@ -507,7 +507,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstNodeUsingStmt *us, AstNode
|
|||||||
if (f->kind == Entity_Variable) {
|
if (f->kind == Entity_Variable) {
|
||||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
||||||
uvar->using_expr = expr;
|
uvar->using_expr = expr;
|
||||||
Entity *prev = scope_insert_entity(ctx->scope, uvar);
|
Entity *prev = scope_insert(ctx->scope, uvar);
|
||||||
if (prev != nullptr) {
|
if (prev != nullptr) {
|
||||||
gbString expr_str = expr_to_string(expr);
|
gbString expr_str = expr_to_string(expr);
|
||||||
error(us->token, "Namespace collision while using '%s' of: '%.*s'", expr_str, LIT(prev->token.string));
|
error(us->token, "Namespace collision while using '%s' of: '%.*s'", expr_str, LIT(prev->token.string));
|
||||||
@@ -1464,7 +1464,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
Entity *found = nullptr;
|
Entity *found = nullptr;
|
||||||
|
|
||||||
if (!is_blank_ident(str)) {
|
if (!is_blank_ident(str)) {
|
||||||
found = current_scope_lookup_entity(ctx->scope, str);
|
found = scope_lookup_current(ctx->scope, str);
|
||||||
}
|
}
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
bool is_immutable = true;
|
bool is_immutable = true;
|
||||||
@@ -1630,7 +1630,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
AstNode *node = uis->list[list_index];
|
AstNode *node = uis->list[list_index];
|
||||||
ast_node(ident, Ident, node);
|
ast_node(ident, Ident, node);
|
||||||
String name = ident->token.string;
|
String name = ident->token.string;
|
||||||
Entity *f = scope_lookup_entity(t->Enum.scope, name);
|
Entity *f = scope_lookup(t->Enum.scope, name);
|
||||||
|
|
||||||
if (f == nullptr || !is_entity_exported(f)) {
|
if (f == nullptr || !is_entity_exported(f)) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
@@ -1658,7 +1658,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
ast_node(ident, Ident, node);
|
ast_node(ident, Ident, node);
|
||||||
String name = ident->token.string;
|
String name = ident->token.string;
|
||||||
|
|
||||||
Entity *f = scope_lookup_entity(scope, name);
|
Entity *f = scope_lookup(scope, name);
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
error(node, "'_' cannot be used as a value");
|
error(node, "'_' cannot be used as a value");
|
||||||
@@ -1691,7 +1691,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
ast_node(ident, Ident, node);
|
ast_node(ident, Ident, node);
|
||||||
String name = ident->token.string;
|
String name = ident->token.string;
|
||||||
|
|
||||||
Entity *f = scope_lookup_entity(found, name);
|
Entity *f = scope_lookup(found, name);
|
||||||
if (f == nullptr || f->kind != Entity_Variable) {
|
if (f == nullptr || f->kind != Entity_Variable) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
error(node, "'_' cannot be used as a value");
|
error(node, "'_' cannot be used as a value");
|
||||||
@@ -1703,7 +1703,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
|
|
||||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
||||||
uvar->using_expr = expr;
|
uvar->using_expr = expr;
|
||||||
Entity *prev = scope_insert_entity(ctx->scope, uvar);
|
Entity *prev = scope_insert(ctx->scope, uvar);
|
||||||
if (prev != nullptr) {
|
if (prev != nullptr) {
|
||||||
gbString expr_str = expr_to_string(expr);
|
gbString expr_str = expr_to_string(expr);
|
||||||
error(node, "Namespace collision while using '%s' of: '%.*s'", expr_str, LIT(prev->token.string));
|
error(node, "Namespace collision while using '%s' of: '%.*s'", expr_str, LIT(prev->token.string));
|
||||||
@@ -1792,7 +1792,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
Entity *found = nullptr;
|
Entity *found = nullptr;
|
||||||
// NOTE(bill): Ignore assignments to '_'
|
// NOTE(bill): Ignore assignments to '_'
|
||||||
if (!is_blank_ident(str)) {
|
if (!is_blank_ident(str)) {
|
||||||
found = current_scope_lookup_entity(ctx->scope, str);
|
found = scope_lookup_current(ctx->scope, str);
|
||||||
new_name_count += 1;
|
new_name_count += 1;
|
||||||
}
|
}
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
@@ -1939,7 +1939,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
if (f->kind == Entity_Variable) {
|
if (f->kind == Entity_Variable) {
|
||||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type);
|
||||||
uvar->Variable.is_immutable = is_immutable;
|
uvar->Variable.is_immutable = is_immutable;
|
||||||
Entity *prev = scope_insert_entity(ctx->scope, uvar);
|
Entity *prev = scope_insert(ctx->scope, uvar);
|
||||||
if (prev != nullptr) {
|
if (prev != nullptr) {
|
||||||
error(token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
|
error(token, "Namespace collision while 'using' '%.*s' of: %.*s", LIT(name), LIT(prev->token.string));
|
||||||
return;
|
return;
|
||||||
|
|||||||
+3
-3
@@ -12,7 +12,7 @@ void populate_using_entity_scope(CheckerContext *ctx, AstNode *node, Type *t) {
|
|||||||
Entity *f = t->Struct.fields[i];
|
Entity *f = t->Struct.fields[i];
|
||||||
GB_ASSERT(f->kind == Entity_Variable);
|
GB_ASSERT(f->kind == Entity_Variable);
|
||||||
String name = f->token.string;;
|
String name = f->token.string;;
|
||||||
Entity *e = current_scope_lookup_entity(ctx->scope, name);
|
Entity *e = scope_lookup_current(ctx->scope, name);
|
||||||
if (e != nullptr && name != "_") {
|
if (e != nullptr && name != "_") {
|
||||||
// TODO(bill): Better type error
|
// TODO(bill): Better type error
|
||||||
if (str != nullptr) {
|
if (str != nullptr) {
|
||||||
@@ -589,7 +589,7 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
|
|||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
e->state = EntityState_Resolved;
|
e->state = EntityState_Resolved;
|
||||||
|
|
||||||
if (current_scope_lookup_entity(ctx->scope, name) != nullptr) {
|
if (scope_lookup_current(ctx->scope, name) != nullptr) {
|
||||||
error(ident, "'%.*s' is already declared in this enumeration", LIT(name));
|
error(ident, "'%.*s' is already declared in this enumeration", LIT(name));
|
||||||
} else {
|
} else {
|
||||||
add_entity(ctx->checker, ctx->scope, nullptr, e);
|
add_entity(ctx->checker, ctx->scope, nullptr, e);
|
||||||
@@ -674,7 +674,7 @@ void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, AstNode *no
|
|||||||
e->flags |= EntityFlag_BitFieldValue;
|
e->flags |= EntityFlag_BitFieldValue;
|
||||||
|
|
||||||
if (!is_blank_ident(name) &&
|
if (!is_blank_ident(name) &&
|
||||||
current_scope_lookup_entity(ctx->scope, name) != nullptr) {
|
scope_lookup_current(ctx->scope, name) != nullptr) {
|
||||||
error(ident, "'%.*s' is already declared in this bit field", LIT(name));
|
error(ident, "'%.*s' is already declared in this bit field", LIT(name));
|
||||||
} else {
|
} else {
|
||||||
add_entity(ctx->checker, ctx->scope, nullptr, e);
|
add_entity(ctx->checker, ctx->scope, nullptr, e);
|
||||||
|
|||||||
+19
-20
@@ -341,7 +341,7 @@ void check_close_scope(CheckerContext *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity *current_scope_lookup_entity(Scope *s, String name) {
|
Entity *scope_lookup_current(Scope *s, String name) {
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_get(&s->elements, key);
|
Entity **found = map_get(&s->elements, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -350,7 +350,7 @@ Entity *current_scope_lookup_entity(Scope *s, String name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entity **entity_) {
|
void scope_lookup_parent(Scope *scope, String name, Scope **scope_, Entity **entity_) {
|
||||||
bool gone_thru_proc = false;
|
bool gone_thru_proc = false;
|
||||||
bool gone_thru_package = false;
|
bool gone_thru_package = false;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
@@ -387,15 +387,15 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
|
|||||||
if (scope_) *scope_ = nullptr;
|
if (scope_) *scope_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *scope_lookup_entity(Scope *s, String name) {
|
Entity *scope_lookup(Scope *s, String name) {
|
||||||
Entity *entity = nullptr;
|
Entity *entity = nullptr;
|
||||||
scope_lookup_parent_entity(s, name, nullptr, &entity);
|
scope_lookup_parent(s, name, nullptr, &entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
Entity *scope_insert(Scope *s, Entity *entity) {
|
||||||
String name = entity->token.string;
|
String name = entity->token.string;
|
||||||
if (name == "") {
|
if (name == "") {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -485,7 +485,7 @@ AstPackage *get_core_package(CheckerInfo *info, String name) {
|
|||||||
void add_package_dependency(CheckerContext *c, char *package_name, char *name) {
|
void add_package_dependency(CheckerContext *c, char *package_name, char *name) {
|
||||||
String n = make_string_c(name);
|
String n = make_string_c(name);
|
||||||
AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name));
|
AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name));
|
||||||
Entity *e = scope_lookup_entity(p->scope, n);
|
Entity *e = scope_lookup(p->scope, n);
|
||||||
GB_ASSERT_MSG(e != nullptr, "%s", name);
|
GB_ASSERT_MSG(e != nullptr, "%s", name);
|
||||||
ptr_set_add(&c->decl->deps, e);
|
ptr_set_add(&c->decl->deps, e);
|
||||||
// add_type_info_type(c, e->type);
|
// add_type_info_type(c, e->type);
|
||||||
@@ -496,7 +496,6 @@ void add_declaration_dependency(CheckerContext *c, Entity *e) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (c->decl != nullptr) {
|
if (c->decl != nullptr) {
|
||||||
// DeclInfo *decl = decl_info_of_entity(&c->info, e);
|
|
||||||
add_dependency(c->decl, e);
|
add_dependency(c->decl, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,7 +506,7 @@ Entity *add_global_entity(Entity *entity) {
|
|||||||
if (gb_memchr(name.text, ' ', name.len)) {
|
if (gb_memchr(name.text, ' ', name.len)) {
|
||||||
return entity; // NOTE(bill): 'untyped thing'
|
return entity; // NOTE(bill): 'untyped thing'
|
||||||
}
|
}
|
||||||
if (scope_insert_entity(universal_scope, entity)) {
|
if (scope_insert(universal_scope, entity)) {
|
||||||
compiler_error("double declaration");
|
compiler_error("double declaration");
|
||||||
}
|
}
|
||||||
entity->state = EntityState_Resolved;
|
entity->state = EntityState_Resolved;
|
||||||
@@ -849,7 +848,7 @@ bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
|||||||
}
|
}
|
||||||
String name = entity->token.string;
|
String name = entity->token.string;
|
||||||
if (!is_blank_ident(name)) {
|
if (!is_blank_ident(name)) {
|
||||||
Entity *ie = scope_insert_entity(scope, entity);
|
Entity *ie = scope_insert(scope, entity);
|
||||||
if (ie != nullptr) {
|
if (ie != nullptr) {
|
||||||
TokenPos pos = ie->token.pos;
|
TokenPos pos = ie->token.pos;
|
||||||
Entity *up = ie->using_parent;
|
Entity *up = ie->using_parent;
|
||||||
@@ -1320,7 +1319,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("Context"),
|
str_lit("Context"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_builtin_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_builtin_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup_entity(c->info.runtime_package->scope, required_builtin_entities[i]));
|
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_builtin_entities[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
AstPackage *mem = get_core_package(&c->info, str_lit("mem"));
|
AstPackage *mem = get_core_package(&c->info, str_lit("mem"));
|
||||||
@@ -1329,7 +1328,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("Allocator"),
|
str_lit("Allocator"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_mem_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_mem_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup_entity(mem->scope, required_mem_entities[i]));
|
add_dependency_to_set(c, scope_lookup(mem->scope, required_mem_entities[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
AstPackage *os = get_core_package(&c->info, str_lit("os"));
|
AstPackage *os = get_core_package(&c->info, str_lit("os"));
|
||||||
@@ -1337,7 +1336,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("heap_allocator"),
|
str_lit("heap_allocator"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_os_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_os_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup_entity(os->scope, required_mem_entities[i]));
|
add_dependency_to_set(c, scope_lookup(os->scope, required_mem_entities[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1348,7 +1347,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("dynamic_array_expr_error"),
|
str_lit("dynamic_array_expr_error"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) {
|
for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup_entity(c->info.runtime_package->scope, bounds_check_entities[i]));
|
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, bounds_check_entities[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1468,7 +1467,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
|||||||
|
|
||||||
|
|
||||||
Entity *find_core_entity(Checker *c, String name) {
|
Entity *find_core_entity(Checker *c, String name) {
|
||||||
Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name);
|
Entity *e = scope_lookup_current(c->info.runtime_package->scope, name);
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
compiler_error("Could not find type declaration for '%.*s'\n"
|
compiler_error("Could not find type declaration for '%.*s'\n"
|
||||||
, LIT(name));
|
, LIT(name));
|
||||||
@@ -1478,7 +1477,7 @@ Entity *find_core_entity(Checker *c, String name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *find_core_type(Checker *c, String name) {
|
Type *find_core_type(Checker *c, String name) {
|
||||||
Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name);
|
Entity *e = scope_lookup_current(c->info.runtime_package->scope, name);
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
compiler_error("Could not find type declaration for '%.*s'\n"
|
compiler_error("Could not find type declaration for '%.*s'\n"
|
||||||
, LIT(name));
|
, LIT(name));
|
||||||
@@ -1601,7 +1600,7 @@ void init_core_allocator(Checker *c) {
|
|||||||
AstPackage *pkg = get_core_package(&c->info, str_lit("mem"));
|
AstPackage *pkg = get_core_package(&c->info, str_lit("mem"));
|
||||||
|
|
||||||
String name = str_lit("Allocator");
|
String name = str_lit("Allocator");
|
||||||
Entity *e = current_scope_lookup_entity(pkg->scope, name);
|
Entity *e = scope_lookup_current(pkg->scope, name);
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
compiler_error("Could not find type declaration for '%.*s'\n", LIT(name));
|
compiler_error("Could not find type declaration for '%.*s'\n", LIT(name));
|
||||||
// NOTE(bill): This will exit the program as it's cannot continue without it!
|
// NOTE(bill): This will exit the program as it's cannot continue without it!
|
||||||
@@ -1956,7 +1955,7 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array<AstNode *> *
|
|||||||
|
|
||||||
if (name == "builtin") {
|
if (name == "builtin") {
|
||||||
add_entity(ctx->checker, universal_scope, nullptr, e);
|
add_entity(ctx->checker, universal_scope, nullptr, e);
|
||||||
GB_ASSERT(scope_lookup_entity(universal_scope, e->token.string) != nullptr);
|
GB_ASSERT(scope_lookup(universal_scope, e->token.string) != nullptr);
|
||||||
if (value != nullptr) {
|
if (value != nullptr) {
|
||||||
error(value, "'builtin' cannot have a field value");
|
error(value, "'builtin' cannot have a field value");
|
||||||
}
|
}
|
||||||
@@ -2591,7 +2590,7 @@ void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) {
|
|||||||
ast_node(ident, Ident, node);
|
ast_node(ident, Ident, node);
|
||||||
String name = ident->token.string;
|
String name = ident->token.string;
|
||||||
|
|
||||||
Entity *e = scope_lookup_entity(scope, name);
|
Entity *e = scope_lookup(scope, name);
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
error(node, "'_' cannot be used as a value");
|
error(node, "'_' cannot be used as a value");
|
||||||
@@ -2621,7 +2620,7 @@ void check_add_import_decl(CheckerContext *ctx, AstNodeImportDecl *id) {
|
|||||||
|
|
||||||
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
|
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
|
||||||
if (is_entity_exported(e) && !implicit_is_found) {
|
if (is_entity_exported(e) && !implicit_is_found) {
|
||||||
Entity *prev = scope_lookup_entity(parent_scope, e->token.string);
|
Entity *prev = scope_lookup(parent_scope, e->token.string);
|
||||||
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
|
bool ok = add_entity(ctx->checker, parent_scope, e->identifier, e);
|
||||||
if (ok) ptr_set_add(&parent_scope->implicit, e);
|
if (ok) ptr_set_add(&parent_scope->implicit, e);
|
||||||
}
|
}
|
||||||
@@ -3308,7 +3307,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
Scope *s = c->info.init_scope;
|
Scope *s = c->info.init_scope;
|
||||||
GB_ASSERT(s != nullptr);
|
GB_ASSERT(s != nullptr);
|
||||||
GB_ASSERT(s->is_init);
|
GB_ASSERT(s->is_init);
|
||||||
Entity *e = current_scope_lookup_entity(s, str_lit("main"));
|
Entity *e = scope_lookup_current(s, str_lit("main"));
|
||||||
if (e == nullptr) {
|
if (e == nullptr) {
|
||||||
Token token = {};
|
Token token = {};
|
||||||
token.pos.file = s->package->fullpath;
|
token.pos.file = s->package->fullpath;
|
||||||
|
|||||||
+4
-4
@@ -387,10 +387,10 @@ isize type_info_index (CheckerInfo *i, Type * type, bool error_o
|
|||||||
Entity *entity_of_node(CheckerInfo *i, AstNode *expr);
|
Entity *entity_of_node(CheckerInfo *i, AstNode *expr);
|
||||||
|
|
||||||
|
|
||||||
Entity *current_scope_lookup_entity(Scope *s, String name);
|
Entity *scope_lookup_current(Scope *s, String name);
|
||||||
Entity *scope_lookup_entity (Scope *s, String name);
|
Entity *scope_lookup (Scope *s, String name);
|
||||||
void scope_lookup_parent_entity (Scope *s, String name, Scope **scope_, Entity **entity_);
|
void scope_lookup_parent (Scope *s, String name, Scope **scope_, Entity **entity_);
|
||||||
Entity *scope_insert_entity (Scope *s, Entity *entity);
|
Entity *scope_insert (Scope *s, Entity *entity);
|
||||||
|
|
||||||
|
|
||||||
ExprInfo *check_get_expr_info (CheckerInfo *i, AstNode *expr);
|
ExprInfo *check_get_expr_info (CheckerInfo *i, AstNode *expr);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ struct DeclInfo;
|
|||||||
ENTITY_KIND(Procedure) \
|
ENTITY_KIND(Procedure) \
|
||||||
ENTITY_KIND(ProcGroup) \
|
ENTITY_KIND(ProcGroup) \
|
||||||
ENTITY_KIND(Builtin) \
|
ENTITY_KIND(Builtin) \
|
||||||
ENTITY_KIND(Alias) \
|
|
||||||
ENTITY_KIND(ImportName) \
|
ENTITY_KIND(ImportName) \
|
||||||
ENTITY_KIND(LibraryName) \
|
ENTITY_KIND(LibraryName) \
|
||||||
ENTITY_KIND(Nil) \
|
ENTITY_KIND(Nil) \
|
||||||
@@ -119,9 +118,6 @@ struct Entity {
|
|||||||
struct {
|
struct {
|
||||||
i32 id;
|
i32 id;
|
||||||
} Builtin;
|
} Builtin;
|
||||||
struct {
|
|
||||||
Entity *base;
|
|
||||||
} Alias;
|
|
||||||
struct {
|
struct {
|
||||||
String path;
|
String path;
|
||||||
String name;
|
String name;
|
||||||
@@ -271,12 +267,6 @@ Entity *alloc_entity_builtin(Scope *scope, Token token, Type *type, i32 id) {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *alloc_entity_alias(Scope *scope, Token token, Type *type, Entity *base) {
|
|
||||||
Entity *entity = alloc_entity(Entity_Alias, scope, token, type);
|
|
||||||
entity->Alias.base = base;
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type,
|
||||||
String path, String name, Scope *import_scope) {
|
String path, String name, Scope *import_scope) {
|
||||||
Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
|
Entity *entity = alloc_entity(Entity_ImportName, scope, token, type);
|
||||||
|
|||||||
+3
-3
@@ -1706,7 +1706,7 @@ irValue *ir_emit_runtime_call(irProcedure *proc, char const *name_, Array<irValu
|
|||||||
String name = make_string_c(cast(char *)name_);
|
String name = make_string_c(cast(char *)name_);
|
||||||
|
|
||||||
AstPackage *p = proc->module->info->runtime_package;
|
AstPackage *p = proc->module->info->runtime_package;
|
||||||
Entity *e = current_scope_lookup_entity(p->scope, name);
|
Entity *e = scope_lookup_current(p->scope, name);
|
||||||
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
||||||
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
|
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
|
||||||
irValue *gp = *found;
|
irValue *gp = *found;
|
||||||
@@ -1719,7 +1719,7 @@ irValue *ir_emit_package_call(irProcedure *proc, char const *package_name_, char
|
|||||||
String package_name = make_string_c(cast(char *)package_name_);
|
String package_name = make_string_c(cast(char *)package_name_);
|
||||||
|
|
||||||
AstPackage *p = get_core_package(proc->module->info, package_name);
|
AstPackage *p = get_core_package(proc->module->info, package_name);
|
||||||
Entity *e = current_scope_lookup_entity(p->scope, name);
|
Entity *e = scope_lookup_current(p->scope, name);
|
||||||
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
||||||
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
|
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
|
||||||
irValue *gp = *found;
|
irValue *gp = *found;
|
||||||
@@ -4089,7 +4089,7 @@ irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irV
|
|||||||
|
|
||||||
irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
||||||
AstPackage *pkg = proc->module->info->runtime_package;
|
AstPackage *pkg = proc->module->info->runtime_package;
|
||||||
Entity *e = current_scope_lookup_entity(pkg->scope, name);
|
Entity *e = scope_lookup_current(pkg->scope, name);
|
||||||
irValue **value = map_get(&proc->module->values, hash_entity(e));
|
irValue **value = map_get(&proc->module->values, hash_entity(e));
|
||||||
GB_ASSERT_MSG(value != nullptr, "Unable to find global variable '%.*s'", LIT(name));
|
GB_ASSERT_MSG(value != nullptr, "Unable to find global variable '%.*s'", LIT(name));
|
||||||
return *value;
|
return *value;
|
||||||
|
|||||||
+2
-2
@@ -1595,7 +1595,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity *current_scope_lookup_entity(Scope *s, String name);
|
Entity *scope_lookup_current(Scope *s, String name);
|
||||||
|
|
||||||
Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel) {
|
Selection lookup_field_with_selection(Type *type_, String field_name, bool is_type, Selection sel) {
|
||||||
GB_ASSERT(type_ != nullptr);
|
GB_ASSERT(type_ != nullptr);
|
||||||
@@ -1712,7 +1712,7 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
|||||||
if (type->kind == Type_Struct) {
|
if (type->kind == Type_Struct) {
|
||||||
Scope *s = type->Struct.scope;
|
Scope *s = type->Struct.scope;
|
||||||
if (s != nullptr) {
|
if (s != nullptr) {
|
||||||
Entity *found = current_scope_lookup_entity(s, field_name);
|
Entity *found = scope_lookup_current(s, field_name);
|
||||||
if (found != nullptr && found->kind != Entity_Variable) {
|
if (found != nullptr && found->kind != Entity_Variable) {
|
||||||
sel.entity = found;
|
sel.entity = found;
|
||||||
return sel;
|
return sel;
|
||||||
|
|||||||
Reference in New Issue
Block a user