mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Remove clutter parameters and begin parallelizing the type checker
This commit is contained in:
+26
-11
@@ -111,7 +111,7 @@ void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Ar
|
|||||||
isize max = gb_min(lhs_count, rhs_count);
|
isize max = gb_min(lhs_count, rhs_count);
|
||||||
for (isize i = 0; i < max; i++) {
|
for (isize i = 0; i < max; i++) {
|
||||||
Entity *e = lhs[i];
|
Entity *e = lhs[i];
|
||||||
DeclInfo *d = decl_info_of_entity(&ctx->checker->info, e);
|
DeclInfo *d = decl_info_of_entity(e);
|
||||||
Operand *o = &operands[i];
|
Operand *o = &operands[i];
|
||||||
check_init_variable(ctx, e, o, context_name);
|
check_init_variable(ctx, e, o, context_name);
|
||||||
if (d != nullptr) {
|
if (d != nullptr) {
|
||||||
@@ -220,7 +220,7 @@ AstNode *remove_type_alias_clutter(AstNode *node) {
|
|||||||
void check_type_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, Type *def) {
|
void check_type_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, Type *def) {
|
||||||
GB_ASSERT(e->type == nullptr);
|
GB_ASSERT(e->type == nullptr);
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(&ctx->checker->info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr && decl->attributes.count > 0) {
|
if (decl != nullptr && decl->attributes.count > 0) {
|
||||||
error(decl->attributes[0], "Attributes are not allowed on type declarations");
|
error(decl->attributes[0], "Attributes are not allowed on type declarations");
|
||||||
}
|
}
|
||||||
@@ -373,7 +373,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, AstNode *type_expr, AstNod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(&ctx->checker->info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr && decl->attributes.count > 0) {
|
if (decl != nullptr && decl->attributes.count > 0) {
|
||||||
error(decl->attributes[0], "Attributes are not allowed on constant value declarations");
|
error(decl->attributes[0], "Attributes are not allowed on constant value declarations");
|
||||||
}
|
}
|
||||||
@@ -544,10 +544,13 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
pt->calling_convention = ProcCC_Contextless;
|
pt->calling_convention = ProcCC_Contextless;
|
||||||
if (e->pkg->kind == Package_Init) {
|
if (e->pkg->kind == Package_Init) {
|
||||||
if (ctx->checker->info.entry_point != nullptr) {
|
gb_mutex_lock(&ctx->info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&ctx->info->mutex));
|
||||||
|
|
||||||
|
if (ctx->info->entry_point != nullptr) {
|
||||||
error(e->token, "Redeclaration of the entry pointer procedure 'main'");
|
error(e->token, "Redeclaration of the entry pointer procedure 'main'");
|
||||||
} else {
|
} else {
|
||||||
ctx->checker->info.entry_point = e;
|
ctx->info->entry_point = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -609,7 +612,10 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
|
|
||||||
init_entity_foreign_library(ctx, e);
|
init_entity_foreign_library(ctx, e);
|
||||||
|
|
||||||
auto *fp = &ctx->checker->info.foreigns;
|
gb_mutex_lock(&ctx->info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&ctx->info->mutex));
|
||||||
|
|
||||||
|
auto *fp = &ctx->info->foreigns;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_get(fp, key);
|
Entity **found = map_get(fp, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -641,7 +647,10 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
name = e->Procedure.link_name;
|
name = e->Procedure.link_name;
|
||||||
}
|
}
|
||||||
if (e->Procedure.link_name.len > 0 || is_export) {
|
if (e->Procedure.link_name.len > 0 || is_export) {
|
||||||
auto *fp = &ctx->checker->info.foreigns;
|
gb_mutex_lock(&ctx->info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&ctx->info->mutex));
|
||||||
|
|
||||||
|
auto *fp = &ctx->info->foreigns;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_get(fp, key);
|
Entity **found = map_get(fp, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -674,7 +683,7 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize ent
|
|||||||
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
||||||
ac.init_expr_list_count = init_expr_list.count;
|
ac.init_expr_list_count = init_expr_list.count;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(&ctx->checker->info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr) {
|
if (decl != nullptr) {
|
||||||
check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
|
check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac);
|
||||||
}
|
}
|
||||||
@@ -717,7 +726,10 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize ent
|
|||||||
if (e->Variable.link_name.len > 0) {
|
if (e->Variable.link_name.len > 0) {
|
||||||
name = e->Variable.link_name;
|
name = e->Variable.link_name;
|
||||||
}
|
}
|
||||||
auto *fp = &ctx->checker->info.foreigns;
|
gb_mutex_lock(&ctx->info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&ctx->info->mutex));
|
||||||
|
|
||||||
|
auto *fp = &ctx->info->foreigns;
|
||||||
HashKey key = hash_string(name);
|
HashKey key = hash_string(name);
|
||||||
Entity **found = map_get(fp, key);
|
Entity **found = map_get(fp, key);
|
||||||
if (found) {
|
if (found) {
|
||||||
@@ -892,7 +904,7 @@ void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
d = decl_info_of_entity(&ctx->checker->info, e);
|
d = decl_info_of_entity(e);
|
||||||
if (d == nullptr) {
|
if (d == nullptr) {
|
||||||
// TODO(bill): Err here?
|
// TODO(bill): Err here?
|
||||||
e->type = t_invalid;
|
e->type = t_invalid;
|
||||||
@@ -978,7 +990,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
|||||||
if (t->kind == Type_Struct) {
|
if (t->kind == Type_Struct) {
|
||||||
Scope *scope = t->Struct.scope;
|
Scope *scope = t->Struct.scope;
|
||||||
if (scope == nullptr) {
|
if (scope == nullptr) {
|
||||||
scope = scope_of_node(&ctx->checker->info, t->Struct.node);
|
scope = scope_of_node(t->Struct.node);
|
||||||
}
|
}
|
||||||
GB_ASSERT(scope != nullptr);
|
GB_ASSERT(scope != nullptr);
|
||||||
for_array(i, scope->elements.entries) {
|
for_array(i, scope->elements.entries) {
|
||||||
@@ -1017,6 +1029,9 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
|
|||||||
check_scope_usage(ctx->checker, ctx->scope);
|
check_scope_usage(ctx->checker, ctx->scope);
|
||||||
|
|
||||||
if (decl->parent != nullptr) {
|
if (decl->parent != nullptr) {
|
||||||
|
gb_mutex_lock(&ctx->checker->mutex);
|
||||||
|
defer (gb_mutex_unlock(&ctx->checker->mutex));
|
||||||
|
|
||||||
// NOTE(bill): Add the dependencies from the procedure literal (lambda)
|
// NOTE(bill): Add the dependencies from the procedure literal (lambda)
|
||||||
for_array(i, decl->deps.entries) {
|
for_array(i, decl->deps.entries) {
|
||||||
Entity *e = decl->deps.entries[i].ptr;
|
Entity *e = decl->deps.entries[i].ptr;
|
||||||
|
|||||||
+10
-10
@@ -123,7 +123,7 @@ void check_scope_decls(CheckerContext *c, Array<AstNode *> nodes, isize reserve_
|
|||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo *d = decl_info_of_entity(&c->checker->info, e);
|
DeclInfo *d = decl_info_of_entity(e);
|
||||||
if (d != nullptr) {
|
if (d != nullptr) {
|
||||||
check_entity_decl(c, e, d, nullptr);
|
check_entity_decl(c, e, d, nullptr);
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeclInfo *old_decl = decl_info_of_entity(&c->checker->info, base_entity);
|
DeclInfo *old_decl = decl_info_of_entity(base_entity);
|
||||||
if (old_decl == nullptr) {
|
if (old_decl == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -267,10 +267,10 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_mutex_lock(&nctx.checker->mutex);
|
gb_mutex_lock(&nctx.info->mutex);
|
||||||
defer (gb_mutex_unlock(&nctx.checker->mutex));
|
defer (gb_mutex_unlock(&nctx.info->mutex));
|
||||||
|
|
||||||
auto *found_gen_procs = map_get(&nctx.checker->info.gen_procs, hash_pointer(base_entity->identifier));
|
auto *found_gen_procs = map_get(&nctx.info->gen_procs, hash_pointer(base_entity->identifier));
|
||||||
if (found_gen_procs) {
|
if (found_gen_procs) {
|
||||||
auto procs = *found_gen_procs;
|
auto procs = *found_gen_procs;
|
||||||
for_array(i, procs) {
|
for_array(i, procs) {
|
||||||
@@ -382,7 +382,7 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti
|
|||||||
|
|
||||||
bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, PolyProcData *poly_proc_data) {
|
bool check_polymorphic_procedure_assignment(CheckerContext *c, Operand *operand, Type *type, PolyProcData *poly_proc_data) {
|
||||||
if (operand->expr == nullptr) return false;
|
if (operand->expr == nullptr) return false;
|
||||||
Entity *base_entity = entity_of_ident(&c->checker->info, operand->expr);
|
Entity *base_entity = entity_of_ident(operand->expr);
|
||||||
if (base_entity == nullptr) return false;
|
if (base_entity == nullptr) return false;
|
||||||
return find_or_generate_polymorphic_procedure(c, base_entity, type, nullptr, poly_proc_data);
|
return find_or_generate_polymorphic_procedure(c, base_entity, type, nullptr, poly_proc_data);
|
||||||
}
|
}
|
||||||
@@ -966,7 +966,7 @@ Entity *check_ident(CheckerContext *c, Operand *o, AstNode *n, Type *named_type,
|
|||||||
if (e->kind == Entity_ProcGroup) {
|
if (e->kind == Entity_ProcGroup) {
|
||||||
auto *pge = &e->ProcGroup;
|
auto *pge = &e->ProcGroup;
|
||||||
|
|
||||||
DeclInfo *d = decl_info_of_entity(&c->checker->info, e);
|
DeclInfo *d = decl_info_of_entity(e);
|
||||||
check_entity_decl(c, e, d, nullptr);
|
check_entity_decl(c, e, d, nullptr);
|
||||||
|
|
||||||
|
|
||||||
@@ -4089,7 +4089,7 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs
|
|||||||
if (lhs != nullptr) {
|
if (lhs != nullptr) {
|
||||||
for (isize j = 0; (tuple_index + j) < lhs_count && j < tuple_count; j++) {
|
for (isize j = 0; (tuple_index + j) < lhs_count && j < tuple_count; j++) {
|
||||||
Entity *e = lhs[tuple_index + j];
|
Entity *e = lhs[tuple_index + j];
|
||||||
DeclInfo *decl = decl_info_of_entity(&c->checker->info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr) {
|
if (decl != nullptr) {
|
||||||
c->decl = decl; // will be reset by the 'defer' any way
|
c->decl = decl; // will be reset by the 'defer' any way
|
||||||
for_array(k, decl->deps.entries) {
|
for_array(k, decl->deps.entries) {
|
||||||
@@ -4117,7 +4117,7 @@ void check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count,
|
|||||||
if (lhs != nullptr && tuple_index < lhs_count) {
|
if (lhs != nullptr && tuple_index < lhs_count) {
|
||||||
// NOTE(bill): override DeclInfo for dependency
|
// NOTE(bill): override DeclInfo for dependency
|
||||||
Entity *e = lhs[tuple_index];
|
Entity *e = lhs[tuple_index];
|
||||||
DeclInfo *decl = decl_info_of_entity(&c->checker->info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl) c->decl = decl;
|
if (decl) c->decl = decl;
|
||||||
type_hint = e->type;
|
type_hint = e->type;
|
||||||
}
|
}
|
||||||
@@ -4722,7 +4722,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
ident = s;
|
ident = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *e = entity_of_ident(&c->checker->info, ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
CallArgumentData data = {};
|
CallArgumentData data = {};
|
||||||
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
|
CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data);
|
||||||
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
||||||
|
|||||||
+3
-3
@@ -501,7 +501,7 @@ bool check_using_stmt_entity(CheckerContext *ctx, AstNodeUsingStmt *us, AstNode
|
|||||||
Type *t = base_type(type_deref(e->type));
|
Type *t = base_type(type_deref(e->type));
|
||||||
if (t->kind == Type_Struct) {
|
if (t->kind == Type_Struct) {
|
||||||
// TODO(bill): Make it work for unions too
|
// TODO(bill): Make it work for unions too
|
||||||
Scope *found = scope_of_node(&ctx->checker->info, t->Struct.node);
|
Scope *found = scope_of_node(t->Struct.node);
|
||||||
for_array(i, found->elements.entries) {
|
for_array(i, found->elements.entries) {
|
||||||
Entity *f = found->elements.entries[i].value;
|
Entity *f = found->elements.entries[i].value;
|
||||||
if (f->kind == Entity_Variable) {
|
if (f->kind == Entity_Variable) {
|
||||||
@@ -1685,7 +1685,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
Type *t = base_type(type_deref(e->type));
|
Type *t = base_type(type_deref(e->type));
|
||||||
if (t->kind == Type_Struct) {
|
if (t->kind == Type_Struct) {
|
||||||
// TODO(bill): Make it work for unions too
|
// TODO(bill): Make it work for unions too
|
||||||
Scope *found = scope_of_node(&ctx->checker->info, t->Struct.node);
|
Scope *found = scope_of_node(t->Struct.node);
|
||||||
for_array(list_index, uis->list) {
|
for_array(list_index, uis->list) {
|
||||||
AstNode *node = uis->list[list_index];
|
AstNode *node = uis->list[list_index];
|
||||||
ast_node(ident, Ident, node);
|
ast_node(ident, Ident, node);
|
||||||
@@ -1933,7 +1933,7 @@ void check_stmt_internal(CheckerContext *ctx, AstNode *node, u32 flags) {
|
|||||||
if (is_blank_ident(name)) {
|
if (is_blank_ident(name)) {
|
||||||
error(token, "'using' cannot be applied variable declared as '_'");
|
error(token, "'using' cannot be applied variable declared as '_'");
|
||||||
} else if (is_type_struct(t) || is_type_raw_union(t)) {
|
} else if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||||
Scope *scope = scope_of_node(&ctx->checker->info, t->Struct.node);
|
Scope *scope = scope_of_node(t->Struct.node);
|
||||||
for_array(i, scope->elements.entries) {
|
for_array(i, scope->elements.entries) {
|
||||||
Entity *f = scope->elements.entries[i].value;
|
Entity *f = scope->elements.entries[i].value;
|
||||||
if (f->kind == Entity_Variable) {
|
if (f->kind == Entity_Variable) {
|
||||||
|
|||||||
+143
-49
@@ -623,6 +623,7 @@ void init_checker_info(CheckerInfo *i) {
|
|||||||
map_init(&i->files, a);
|
map_init(&i->files, a);
|
||||||
map_init(&i->packages, a);
|
map_init(&i->packages, a);
|
||||||
array_init(&i->variable_init_order, a);
|
array_init(&i->variable_init_order, a);
|
||||||
|
gb_mutex_init(&i->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_checker_info(CheckerInfo *i) {
|
void destroy_checker_info(CheckerInfo *i) {
|
||||||
@@ -638,11 +639,13 @@ void destroy_checker_info(CheckerInfo *i) {
|
|||||||
map_destroy(&i->files);
|
map_destroy(&i->files);
|
||||||
map_destroy(&i->packages);
|
map_destroy(&i->packages);
|
||||||
array_free(&i->variable_init_order);
|
array_free(&i->variable_init_order);
|
||||||
|
gb_mutex_destroy(&i->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckerContext make_checker_context(Checker *c) {
|
CheckerContext make_checker_context(Checker *c) {
|
||||||
CheckerContext ctx = c->init_ctx;
|
CheckerContext ctx = c->init_ctx;
|
||||||
ctx.checker = c;
|
ctx.checker = c;
|
||||||
|
ctx.info = &c->info;
|
||||||
ctx.allocator = c->allocator;
|
ctx.allocator = c->allocator;
|
||||||
ctx.scope = universal_scope;
|
ctx.scope = universal_scope;
|
||||||
|
|
||||||
@@ -698,7 +701,7 @@ void destroy_checker(Checker *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
Entity *entity_of_ident(AstNode *identifier) {
|
||||||
if (identifier->kind == AstNode_Ident) {
|
if (identifier->kind == AstNode_Ident) {
|
||||||
return identifier->Ident.entity;
|
return identifier->Ident.entity;
|
||||||
}
|
}
|
||||||
@@ -706,6 +709,9 @@ Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expr) {
|
TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expr) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
|
|
||||||
TypeAndValue result = {};
|
TypeAndValue result = {};
|
||||||
TypeAndValue *found = map_get(&i->types, hash_node(expr));
|
TypeAndValue *found = map_get(&i->types, hash_node(expr));
|
||||||
if (found) result = *found;
|
if (found) result = *found;
|
||||||
@@ -713,12 +719,15 @@ TypeAndValue type_and_value_of_expr(CheckerInfo *i, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
|
Type *type_of_expr(CheckerInfo *i, AstNode *expr) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
|
|
||||||
TypeAndValue tav = type_and_value_of_expr(i, expr);
|
TypeAndValue tav = type_and_value_of_expr(i, expr);
|
||||||
if (tav.mode != Addressing_Invalid) {
|
if (tav.mode != Addressing_Invalid) {
|
||||||
return tav.type;
|
return tav.type;
|
||||||
}
|
}
|
||||||
if (expr->kind == AstNode_Ident) {
|
if (expr->kind == AstNode_Ident) {
|
||||||
Entity *entity = entity_of_ident(i, expr);
|
Entity *entity = entity_of_ident(expr);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
return entity->type;
|
return entity->type;
|
||||||
}
|
}
|
||||||
@@ -747,12 +756,12 @@ Entity *entity_of_node(CheckerInfo *i, AstNode *expr) {
|
|||||||
expr = unparen_expr(expr);
|
expr = unparen_expr(expr);
|
||||||
switch (expr->kind) {
|
switch (expr->kind) {
|
||||||
case_ast_node(ident, Ident, expr);
|
case_ast_node(ident, Ident, expr);
|
||||||
return entity_of_ident(i, expr);
|
return entity_of_ident(expr);
|
||||||
case_end;
|
case_end;
|
||||||
case_ast_node(se, SelectorExpr, expr);
|
case_ast_node(se, SelectorExpr, expr);
|
||||||
AstNode *s = unselector_expr(se->selector);
|
AstNode *s = unselector_expr(se->selector);
|
||||||
if (s->kind == AstNode_Ident) {
|
if (s->kind == AstNode_Ident) {
|
||||||
return entity_of_ident(i, s);
|
return entity_of_ident(s);
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
case_ast_node(cc, CaseClause, expr);
|
case_ast_node(cc, CaseClause, expr);
|
||||||
@@ -763,34 +772,42 @@ Entity *entity_of_node(CheckerInfo *i, AstNode *expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DeclInfo *decl_info_of_entity(CheckerInfo *i, Entity *e) {
|
DeclInfo *decl_info_of_entity(Entity *e) {
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
return e->decl_info;
|
return e->decl_info;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclInfo *decl_info_of_ident(CheckerInfo *i, AstNode *ident) {
|
DeclInfo *decl_info_of_ident(AstNode *ident) {
|
||||||
return decl_info_of_entity(i, entity_of_ident(i, ident));
|
return decl_info_of_entity(entity_of_ident(ident));
|
||||||
}
|
}
|
||||||
|
|
||||||
AstFile *ast_file_of_filename(CheckerInfo *i, String filename) {
|
AstFile *ast_file_of_filename(CheckerInfo *i, String filename) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
AstFile **found = map_get(&i->files, hash_string(filename));
|
AstFile **found = map_get(&i->files, hash_string(filename));
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
return *found;
|
return *found;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Scope *scope_of_node(CheckerInfo *i, AstNode *node) {
|
Scope *scope_of_node(AstNode *node) {
|
||||||
return node->scope;
|
return node->scope;
|
||||||
}
|
}
|
||||||
ExprInfo *check_get_expr_info(CheckerInfo *i, AstNode *expr) {
|
ExprInfo *check_get_expr_info(CheckerInfo *i, AstNode *expr) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
return map_get(&i->untyped, hash_node(expr));
|
return map_get(&i->untyped, hash_node(expr));
|
||||||
}
|
}
|
||||||
void check_set_expr_info(CheckerInfo *i, AstNode *expr, ExprInfo info) {
|
void check_set_expr_info(CheckerInfo *i, AstNode *expr, ExprInfo info) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
map_set(&i->untyped, hash_node(expr), info);
|
map_set(&i->untyped, hash_node(expr), info);
|
||||||
}
|
}
|
||||||
void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
|
void check_remove_expr_info(CheckerInfo *i, AstNode *expr) {
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
map_remove(&i->untyped, hash_node(expr));
|
map_remove(&i->untyped, hash_node(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,6 +819,9 @@ isize type_info_index(CheckerInfo *info, Type *type, bool error_on_failure) {
|
|||||||
type = t_bool;
|
type = t_bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_mutex_lock(&info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&info->mutex));
|
||||||
|
|
||||||
isize entry_index = -1;
|
isize entry_index = -1;
|
||||||
HashKey key = hash_type(type);
|
HashKey key = hash_type(type);
|
||||||
isize *found_entry_index = map_get(&info->type_info_map, key);
|
isize *found_entry_index = map_get(&info->type_info_map, key);
|
||||||
@@ -840,6 +860,8 @@ void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode m
|
|||||||
if (mode == Addressing_Constant && type == t_invalid) {
|
if (mode == Addressing_Constant && type == t_invalid) {
|
||||||
compiler_error("add_untyped - invalid type: %s", type_to_string(type));
|
compiler_error("add_untyped - invalid type: %s", type_to_string(type));
|
||||||
}
|
}
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
map_set(&i->untyped, hash_node(expression), make_expr_info(mode, type, value, lhs));
|
map_set(&i->untyped, hash_node(expression), make_expr_info(mode, type, value, lhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,6 +876,9 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
|
|||||||
compiler_error("add_type_and_value - invalid type: %s", type_to_string(type));
|
compiler_error("add_type_and_value - invalid type: %s", type_to_string(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
|
|
||||||
TypeAndValue tv = {};
|
TypeAndValue tv = {};
|
||||||
tv.type = type;
|
tv.type = type;
|
||||||
tv.value = value;
|
tv.value = value;
|
||||||
@@ -873,6 +898,9 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
|
|||||||
}
|
}
|
||||||
GB_ASSERT(entity != nullptr);
|
GB_ASSERT(entity != nullptr);
|
||||||
|
|
||||||
|
gb_mutex_lock(&i->mutex);
|
||||||
|
defer (gb_mutex_unlock(&i->mutex));
|
||||||
|
|
||||||
identifier->Ident.entity = entity;
|
identifier->Ident.entity = entity;
|
||||||
entity->identifier = identifier;
|
entity->identifier = identifier;
|
||||||
array_add(&i->definitions, entity);
|
array_add(&i->definitions, entity);
|
||||||
@@ -1002,7 +1030,10 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = map_get(&c->checker->info.type_info_map, hash_type(t));
|
gb_mutex_lock(&c->info->mutex);
|
||||||
|
defer (gb_mutex_unlock(&c->info->mutex));
|
||||||
|
|
||||||
|
auto found = map_get(&c->info->type_info_map, hash_type(t));
|
||||||
if (found != nullptr) {
|
if (found != nullptr) {
|
||||||
// Types have already been added
|
// Types have already been added
|
||||||
add_type_info_dependency(c->decl, t);
|
add_type_info_dependency(c->decl, t);
|
||||||
@@ -1011,8 +1042,8 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
|||||||
|
|
||||||
bool prev = false;
|
bool prev = false;
|
||||||
isize ti_index = -1;
|
isize ti_index = -1;
|
||||||
for_array(i, c->checker->info.type_info_map.entries) {
|
for_array(i, c->info->type_info_map.entries) {
|
||||||
auto *e = &c->checker->info.type_info_map.entries[i];
|
auto *e = &c->info->type_info_map.entries[i];
|
||||||
Type *prev_type = cast(Type *)e->key.ptr;
|
Type *prev_type = cast(Type *)e->key.ptr;
|
||||||
if (are_types_identical(t, prev_type)) {
|
if (are_types_identical(t, prev_type)) {
|
||||||
// Duplicate entry
|
// Duplicate entry
|
||||||
@@ -1024,8 +1055,8 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
|||||||
if (ti_index < 0) {
|
if (ti_index < 0) {
|
||||||
// Unique entry
|
// Unique entry
|
||||||
// NOTE(bill): map entries grow linearly and in order
|
// NOTE(bill): map entries grow linearly and in order
|
||||||
ti_index = c->checker->info.type_info_types.count;
|
ti_index = c->info->type_info_types.count;
|
||||||
array_add(&c->checker->info.type_info_types, t);
|
array_add(&c->info->type_info_types, t);
|
||||||
}
|
}
|
||||||
map_set(&c->checker->info.type_info_map, hash_type(t), ti_index);
|
map_set(&c->checker->info.type_info_map, hash_type(t), ti_index);
|
||||||
|
|
||||||
@@ -1140,7 +1171,9 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
|||||||
|
|
||||||
void check_procedure_later(Checker *c, ProcedureInfo info) {
|
void check_procedure_later(Checker *c, ProcedureInfo info) {
|
||||||
GB_ASSERT(info.decl != nullptr);
|
GB_ASSERT(info.decl != nullptr);
|
||||||
|
gb_mutex_lock(&c->mutex);
|
||||||
array_add(&c->procs_to_check, info);
|
array_add(&c->procs_to_check, info);
|
||||||
|
gb_mutex_unlock(&c->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, AstNode *body, u64 tags) {
|
void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *decl, Type *type, AstNode *body, u64 tags) {
|
||||||
@@ -1303,7 +1336,7 @@ void add_dependency_to_set(Checker *c, Entity *entity) {
|
|||||||
if (entity->type != nullptr &&
|
if (entity->type != nullptr &&
|
||||||
is_type_polymorphic(entity->type)) {
|
is_type_polymorphic(entity->type)) {
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(&c->info, entity);
|
DeclInfo *decl = decl_info_of_entity(entity);
|
||||||
if (decl != nullptr && decl->gen_proc_type == nullptr) {
|
if (decl != nullptr && decl->gen_proc_type == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1315,7 +1348,7 @@ void add_dependency_to_set(Checker *c, Entity *entity) {
|
|||||||
|
|
||||||
|
|
||||||
ptr_set_add(set, entity);
|
ptr_set_add(set, entity);
|
||||||
DeclInfo *decl = decl_info_of_entity(info, entity);
|
DeclInfo *decl = decl_info_of_entity(entity);
|
||||||
if (decl == nullptr) {
|
if (decl == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1437,7 +1470,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
|||||||
Entity * e = cast(Entity *)M.entries[i].key.ptr;
|
Entity * e = cast(Entity *)M.entries[i].key.ptr;
|
||||||
EntityGraphNode *n = M.entries[i].value;
|
EntityGraphNode *n = M.entries[i].value;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr) {
|
if (decl != nullptr) {
|
||||||
for_array(j, decl->deps.entries) {
|
for_array(j, decl->deps.entries) {
|
||||||
auto entry = decl->deps.entries[j];
|
auto entry = decl->deps.entries[j];
|
||||||
@@ -2874,7 +2907,7 @@ void calculate_global_init_order(Checker *c) {
|
|||||||
if (e == nullptr || e->kind != Entity_Variable) {
|
if (e == nullptr || e->kind != Entity_Variable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo *d = decl_info_of_entity(info, e);
|
DeclInfo *d = decl_info_of_entity(e);
|
||||||
|
|
||||||
if (ptr_set_exists(&emitted, d)) {
|
if (ptr_set_exists(&emitted, d)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -2908,8 +2941,99 @@ void calculate_global_init_order(Checker *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void check_proc_info(Checker *c, ProcedureInfo pi) {
|
||||||
|
if (pi.type == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckerContext ctx = make_checker_context(c);
|
||||||
|
defer (destroy_checker_context(&ctx));
|
||||||
|
add_curr_ast_file(&ctx, pi.file);
|
||||||
|
|
||||||
|
TypeProc *pt = &pi.type->Proc;
|
||||||
|
String name = pi.token.string;
|
||||||
|
if (pt->is_polymorphic) {
|
||||||
|
GB_ASSERT_MSG(pt->is_poly_specialized, "%.*s", LIT(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool bounds_check = (pi.tags & ProcTag_bounds_check) != 0;
|
||||||
|
bool no_bounds_check = (pi.tags & ProcTag_no_bounds_check) != 0;
|
||||||
|
|
||||||
|
if (bounds_check) {
|
||||||
|
ctx.stmt_state_flags |= StmtStateFlag_bounds_check;
|
||||||
|
ctx.stmt_state_flags &= ~StmtStateFlag_no_bounds_check;
|
||||||
|
} else if (no_bounds_check) {
|
||||||
|
ctx.stmt_state_flags |= StmtStateFlag_no_bounds_check;
|
||||||
|
ctx.stmt_state_flags &= ~StmtStateFlag_bounds_check;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_proc_body(&ctx, pi.token, pi.decl, pi.type, pi.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
GB_THREAD_PROC(check_proc_info_worker_proc) {
|
||||||
|
if (thread == nullptr) return 0;
|
||||||
|
auto *c = cast(Checker *)thread->user_data;
|
||||||
|
isize index = thread->user_index;
|
||||||
|
check_proc_info(c, c->procs_to_check[index]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_proc_bodies(Checker *c) {
|
||||||
|
// IMPORTANT TODO(bill): Figure out why this doesn't work on *nix sometimes
|
||||||
|
#if 0 && defined(GB_SYSTEM_WINDOWS)
|
||||||
|
isize thread_count = gb_max(build_context.thread_count, 1);
|
||||||
|
gb_printf_err("Threads: %td\n", thread_count);
|
||||||
|
// isize thread_count = 1;
|
||||||
|
if (thread_count > 1) {
|
||||||
|
isize volatile curr_proc_index = 0;
|
||||||
|
|
||||||
|
auto worker_threads = array_make<gbThread>(heap_allocator(), thread_count);
|
||||||
|
defer (array_free(&worker_threads));
|
||||||
|
|
||||||
|
for_array(i, worker_threads) {
|
||||||
|
gbThread *t = &worker_threads[i];
|
||||||
|
gb_thread_init(t);
|
||||||
|
}
|
||||||
|
defer (for_array(i, worker_threads) {
|
||||||
|
gb_thread_destroy(&worker_threads[i]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
bool are_any_alive = false;
|
||||||
|
for_array(i, worker_threads) {
|
||||||
|
gbThread *t = &worker_threads[i];
|
||||||
|
if (gb_thread_is_running(t)) {
|
||||||
|
are_any_alive = true;
|
||||||
|
} else if (curr_proc_index < c->procs_to_check.count) {
|
||||||
|
t->user_index = curr_proc_index;
|
||||||
|
curr_proc_index++;
|
||||||
|
gb_thread_start(t, check_proc_info_worker_proc, c);
|
||||||
|
are_any_alive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!are_any_alive && curr_proc_index >= c->procs_to_check.count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for_array(i, c->procs_to_check) {
|
||||||
|
ProcedureInfo pi = c->procs_to_check[i];
|
||||||
|
check_proc_info(c, pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for_array(i, c->procs_to_check) {
|
||||||
|
ProcedureInfo pi = c->procs_to_check[i];
|
||||||
|
check_proc_info(c, pi);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void check_parsed_files(Checker *c) {
|
void check_parsed_files(Checker *c) {
|
||||||
#if 0
|
#if 1
|
||||||
Timings timings = {};
|
Timings timings = {};
|
||||||
timings_init(&timings, str_lit("check_parsed_files"), 16);
|
timings_init(&timings, str_lit("check_parsed_files"), 16);
|
||||||
defer ({
|
defer ({
|
||||||
@@ -2977,37 +3101,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
|
|
||||||
TIME_SECTION("check procedure bodies");
|
TIME_SECTION("check procedure bodies");
|
||||||
// NOTE(bill): Nested procedures bodies will be added to this "queue"
|
// NOTE(bill): Nested procedures bodies will be added to this "queue"
|
||||||
for_array(i, c->procs_to_check) {
|
check_proc_bodies(c);
|
||||||
ProcedureInfo *pi = &c->procs_to_check[i];
|
|
||||||
if (pi->type == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckerContext ctx = make_checker_context(c);
|
|
||||||
defer (destroy_checker_context(&ctx));
|
|
||||||
add_curr_ast_file(&ctx, pi->file);
|
|
||||||
|
|
||||||
TypeProc *pt = &pi->type->Proc;
|
|
||||||
String name = pi->token.string;
|
|
||||||
if (pt->is_polymorphic) {
|
|
||||||
GB_ASSERT_MSG(pt->is_poly_specialized, "%.*s", LIT(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
|
|
||||||
bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
|
|
||||||
|
|
||||||
if (bounds_check) {
|
|
||||||
ctx.stmt_state_flags |= StmtStateFlag_bounds_check;
|
|
||||||
ctx.stmt_state_flags &= ~StmtStateFlag_no_bounds_check;
|
|
||||||
} else if (no_bounds_check) {
|
|
||||||
ctx.stmt_state_flags |= StmtStateFlag_no_bounds_check;
|
|
||||||
ctx.stmt_state_flags &= ~StmtStateFlag_bounds_check;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for_array(i, c->info.files.entries) {
|
for_array(i, c->info.files.entries) {
|
||||||
AstFile *f = c->info.files.entries[i].value;
|
AstFile *f = c->info.files.entries[i].value;
|
||||||
|
|||||||
+8
-4
@@ -6,6 +6,7 @@ struct Scope;
|
|||||||
struct DeclInfo;
|
struct DeclInfo;
|
||||||
struct AstFile;
|
struct AstFile;
|
||||||
struct Checker;
|
struct Checker;
|
||||||
|
struct CheckerInfo;
|
||||||
|
|
||||||
enum AddressingMode {
|
enum AddressingMode {
|
||||||
Addressing_Invalid, // invalid addressing mode
|
Addressing_Invalid, // invalid addressing mode
|
||||||
@@ -279,6 +280,7 @@ typedef Array<Entity *> CheckerTypePath;
|
|||||||
|
|
||||||
struct CheckerContext {
|
struct CheckerContext {
|
||||||
Checker * checker;
|
Checker * checker;
|
||||||
|
CheckerInfo * info;
|
||||||
AstPackage * pkg;
|
AstPackage * pkg;
|
||||||
AstFile * file;
|
AstFile * file;
|
||||||
Scope * scope;
|
Scope * scope;
|
||||||
@@ -327,6 +329,8 @@ struct CheckerInfo {
|
|||||||
Entity * entry_point;
|
Entity * entry_point;
|
||||||
PtrSet<Entity *> minimum_dependency_set;
|
PtrSet<Entity *> minimum_dependency_set;
|
||||||
PtrSet<isize> minimum_dependency_type_info_set;
|
PtrSet<isize> minimum_dependency_type_info_set;
|
||||||
|
|
||||||
|
gbMutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Checker {
|
struct Checker {
|
||||||
@@ -359,11 +363,11 @@ HashKey hash_decl_info(DeclInfo *decl) { return hash_pointer(decl); }
|
|||||||
// CheckerInfo API
|
// CheckerInfo API
|
||||||
TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
|
TypeAndValue type_and_value_of_expr (CheckerInfo *i, AstNode *expr);
|
||||||
Type * type_of_expr (CheckerInfo *i, AstNode *expr);
|
Type * type_of_expr (CheckerInfo *i, AstNode *expr);
|
||||||
Entity * entity_of_ident (CheckerInfo *i, AstNode *identifier);
|
Entity * entity_of_ident (AstNode *identifier);
|
||||||
Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
|
Entity * implicit_entity_of_node(CheckerInfo *i, AstNode *clause);
|
||||||
Scope * scope_of_node (CheckerInfo *i, AstNode *node);
|
Scope * scope_of_node (AstNode *node);
|
||||||
DeclInfo * decl_info_of_ident (CheckerInfo *i, AstNode *ident);
|
DeclInfo * decl_info_of_ident (AstNode *ident);
|
||||||
DeclInfo * decl_info_of_entity (CheckerInfo *i, Entity * e);
|
DeclInfo * decl_info_of_entity (Entity * e);
|
||||||
AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
AstFile * ast_file_of_filename (CheckerInfo *i, String filename);
|
||||||
// IMPORTANT: Only to use once checking is done
|
// IMPORTANT: Only to use once checking is done
|
||||||
isize type_info_index (CheckerInfo *i, Type * type, bool error_on_failure = true);
|
isize type_info_index (CheckerInfo *i, Type * type, bool error_on_failure = true);
|
||||||
|
|||||||
+13
-13
@@ -1199,7 +1199,7 @@ irValue *ir_generate_array(irModule *m, Type *elem_type, i64 count, String prefi
|
|||||||
irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
|
irBlock *ir_new_block(irProcedure *proc, AstNode *node, char *label) {
|
||||||
Scope *scope = nullptr;
|
Scope *scope = nullptr;
|
||||||
if (node != nullptr) {
|
if (node != nullptr) {
|
||||||
scope = scope_of_node(proc->module->info, node);
|
scope = scope_of_node(node);
|
||||||
GB_ASSERT_MSG(scope != nullptr, "Block scope not found for %.*s", LIT(ast_node_strings[node->kind]));
|
GB_ASSERT_MSG(scope != nullptr, "Block scope not found for %.*s", LIT(ast_node_strings[node->kind]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1374,7 +1374,7 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, AstNode *expr, bool zero_ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *ident, bool zero_initialized) {
|
irValue *ir_add_local_for_identifier(irProcedure *proc, AstNode *ident, bool zero_initialized) {
|
||||||
Entity *e = entity_of_ident(proc->module->info, ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
ir_emit_comment(proc, name);
|
ir_emit_comment(proc, name);
|
||||||
@@ -3885,7 +3885,7 @@ void ir_mangle_add_sub_type_name(irModule *m, Entity *field, String parent) {
|
|||||||
|
|
||||||
irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
|
irBranchBlocks ir_lookup_branch_blocks(irProcedure *proc, AstNode *ident) {
|
||||||
GB_ASSERT(ident->kind == AstNode_Ident);
|
GB_ASSERT(ident->kind == AstNode_Ident);
|
||||||
Entity *e = entity_of_ident(proc->module->info, ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
GB_ASSERT(e->kind == Entity_Label);
|
GB_ASSERT(e->kind == Entity_Label);
|
||||||
for_array(i, proc->branch_blocks) {
|
for_array(i, proc->branch_blocks) {
|
||||||
irBranchBlocks *b = &proc->branch_blocks[i];
|
irBranchBlocks *b = &proc->branch_blocks[i];
|
||||||
@@ -4194,7 +4194,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
if (ce->args.count > 0) {
|
if (ce->args.count > 0) {
|
||||||
AstNode *ident = unselector_expr(ce->args[0]);
|
AstNode *ident = unselector_expr(ce->args[0]);
|
||||||
GB_ASSERT(ident->kind == AstNode_Ident);
|
GB_ASSERT(ident->kind == AstNode_Ident);
|
||||||
Entity *e = entity_of_ident(proc->module->info, ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
|
|
||||||
if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity_count > 0) {
|
if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity_count > 0) {
|
||||||
@@ -4906,7 +4906,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(i, Ident, expr);
|
case_ast_node(i, Ident, expr);
|
||||||
Entity *e = entity_of_ident(proc->module->info, expr);
|
Entity *e = entity_of_ident(expr);
|
||||||
GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr));
|
GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr));
|
||||||
if (e->kind == Entity_Builtin) {
|
if (e->kind == Entity_Builtin) {
|
||||||
Token token = ast_node_token(expr);
|
Token token = ast_node_token(expr);
|
||||||
@@ -5158,7 +5158,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
AstNode *p = unparen_expr(ce->proc);
|
AstNode *p = unparen_expr(ce->proc);
|
||||||
if (proc_mode == Addressing_Builtin) {
|
if (proc_mode == Addressing_Builtin) {
|
||||||
Entity *e = entity_of_ident(proc->module->info, p);
|
Entity *e = entity_of_ident(p);
|
||||||
BuiltinProcId id = BuiltinProc_Invalid;
|
BuiltinProcId id = BuiltinProc_Invalid;
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
id = cast(BuiltinProcId)e->Builtin.id;
|
id = cast(BuiltinProcId)e->Builtin.id;
|
||||||
@@ -5481,7 +5481,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
String name = i->token.string;
|
String name = i->token.string;
|
||||||
Entity *e = entity_of_ident(proc->module->info, expr);
|
Entity *e = entity_of_ident(expr);
|
||||||
// GB_ASSERT(name == e->token.string);
|
// GB_ASSERT(name == e->token.string);
|
||||||
return ir_build_addr_from_entity(proc, e, expr);
|
return ir_build_addr_from_entity(proc, e, expr);
|
||||||
case_end;
|
case_end;
|
||||||
@@ -5499,7 +5499,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
|
|||||||
|
|
||||||
if (tav.mode == Addressing_Invalid) {
|
if (tav.mode == Addressing_Invalid) {
|
||||||
// NOTE(bill): Imports
|
// NOTE(bill): Imports
|
||||||
Entity *imp = entity_of_ident(proc->module->info, se->expr);
|
Entity *imp = entity_of_ident(se->expr);
|
||||||
if (imp != nullptr) {
|
if (imp != nullptr) {
|
||||||
GB_ASSERT(imp->kind == Entity_ImportName);
|
GB_ASSERT(imp->kind == Entity_ImportName);
|
||||||
}
|
}
|
||||||
@@ -6189,7 +6189,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
|||||||
for_array(i, vd->names) {
|
for_array(i, vd->names) {
|
||||||
AstNode *ident = vd->names[i];
|
AstNode *ident = vd->names[i];
|
||||||
GB_ASSERT(ident->kind == AstNode_Ident);
|
GB_ASSERT(ident->kind == AstNode_Ident);
|
||||||
Entity *e = entity_of_ident(proc->module->info, ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_TypeName:
|
case Entity_TypeName:
|
||||||
@@ -6228,7 +6228,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
|||||||
ir_gen_global_type_name(m, e, name);
|
ir_gen_global_type_name(m, e, name);
|
||||||
} else if (e->kind == Entity_Procedure) {
|
} else if (e->kind == Entity_Procedure) {
|
||||||
CheckerInfo *info = proc->module->info;
|
CheckerInfo *info = proc->module->info;
|
||||||
DeclInfo *decl = decl_info_of_entity(info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
ast_node(pl, ProcLit, decl->proc_lit);
|
ast_node(pl, ProcLit, decl->proc_lit);
|
||||||
if (pl->body != nullptr) {
|
if (pl->body != nullptr) {
|
||||||
auto *found = map_get(&info->gen_procs, hash_pointer(ident));
|
auto *found = map_get(&info->gen_procs, hash_pointer(ident));
|
||||||
@@ -6239,7 +6239,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
|
|||||||
if (!ir_min_dep_entity(proc->module, e)) {
|
if (!ir_min_dep_entity(proc->module, e)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo *d = decl_info_of_entity(info, e);
|
DeclInfo *d = decl_info_of_entity(e);
|
||||||
ir_build_poly_proc(proc, &d->proc_lit->ProcLit, e);
|
ir_build_poly_proc(proc, &d->proc_lit->ProcLit, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -7406,7 +7406,7 @@ void ir_begin_procedure_body(irProcedure *proc) {
|
|||||||
array_init(&proc->branch_blocks, heap_allocator());
|
array_init(&proc->branch_blocks, heap_allocator());
|
||||||
array_init(&proc->context_stack, heap_allocator());
|
array_init(&proc->context_stack, heap_allocator());
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(proc->module->info, proc->entity);
|
DeclInfo *decl = decl_info_of_entity(proc->entity);
|
||||||
if (decl != nullptr) {
|
if (decl != nullptr) {
|
||||||
for_array(i, decl->labels) {
|
for_array(i, decl->labels) {
|
||||||
BlockLabel bl = decl->labels[i];
|
BlockLabel bl = decl->labels[i];
|
||||||
@@ -8358,7 +8358,7 @@ void ir_gen_tree(irGen *s) {
|
|||||||
if (!ir_min_dep_entity(m, e)) {
|
if (!ir_min_dep_entity(m, e)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo *decl = decl_info_of_entity(info, e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl == nullptr) {
|
if (decl == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -772,7 +772,7 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
found = map_get(&m->anonymous_proc_lits, hash_pointer(expr));
|
found = map_get(&m->anonymous_proc_lits, hash_pointer(expr));
|
||||||
} else {
|
} else {
|
||||||
GB_ASSERT(expr->kind == AstNode_Ident);
|
GB_ASSERT(expr->kind == AstNode_Ident);
|
||||||
Entity *e = entity_of_ident(m->info, expr);
|
Entity *e = entity_of_ident(expr);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
found = map_get(&m->values, hash_entity(e));
|
found = map_get(&m->values, hash_entity(e));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user