Improve CheckerContext usage

This commit is contained in:
gingerBill
2021-07-10 13:02:13 +01:00
parent 73fe36f19c
commit 4a932616fc
7 changed files with 134 additions and 115 deletions
+3 -3
View File
@@ -1934,7 +1934,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Entity *new_field = alloc_entity_field(scope, token, array_type, false, cast(i32)i);
soa_struct->Struct.fields[i] = new_field;
add_entity(c->checker, scope, nullptr, new_field);
add_entity(c, scope, nullptr, new_field);
add_entity_use(c, nullptr, new_field);
}
@@ -1959,7 +1959,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Type *array_type = alloc_type_array(old_field->type, count);
Entity *new_field = alloc_entity_field(scope, old_field->token, array_type, false, old_field->Variable.field_src_index);
soa_struct->Struct.fields[i] = new_field;
add_entity(c->checker, scope, nullptr, new_field);
add_entity(c, scope, nullptr, new_field);
} else {
soa_struct->Struct.fields[i] = old_field;
}
@@ -1971,7 +1971,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
Token token = {};
token.string = str_lit("Base_Type");
Entity *base_type_entity = alloc_entity_type_name(scope, token, elem, EntityState_Resolved);
add_entity(c->checker, scope, nullptr, base_type_entity);
add_entity(c, scope, nullptr, base_type_entity);
add_type_info_type(c, soa_struct);
+1 -1
View File
@@ -313,7 +313,7 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def)
if (is_blank_ident(name)) {
continue;
}
add_entity(ctx->checker, parent, nullptr, f);
add_entity(ctx, parent, nullptr, f);
}
}
}
+9 -11
View File
@@ -2889,8 +2889,8 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
GB_ASSERT(e != nullptr);
ExprInfo *found = check_get_expr_info(&c->checker->info, e);
if (found == nullptr) {
ExprInfo *old = check_get_expr_info(&c->checker->info, e);
if (old == nullptr) {
if (type != nullptr && type != t_invalid) {
if (e->tav.type == nullptr || e->tav.type == t_invalid) {
add_type_and_value(&c->checker->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value);
@@ -2898,11 +2898,10 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
}
return;
}
ExprInfo old = *found;
switch (e->kind) {
case_ast_node(ue, UnaryExpr, e);
if (old.value.kind != ExactValue_Invalid) {
if (old->value.kind != ExactValue_Invalid) {
// NOTE(bill): if 'e' is constant, the operands will be constant too.
// They don't need to be updated as they will be updated later and
// checked at the end of general checking stage.
@@ -2912,7 +2911,7 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
case_end;
case_ast_node(be, BinaryExpr, e);
if (old.value.kind != ExactValue_Invalid) {
if (old->value.kind != ExactValue_Invalid) {
// See above note in UnaryExpr case
break;
}
@@ -2927,7 +2926,7 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
case_end;
case_ast_node(te, TernaryIfExpr, e);
if (old.value.kind != ExactValue_Invalid) {
if (old->value.kind != ExactValue_Invalid) {
// See above note in UnaryExpr case
break;
}
@@ -2937,7 +2936,7 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
case_end;
case_ast_node(te, TernaryWhenExpr, e);
if (old.value.kind != ExactValue_Invalid) {
if (old->value.kind != ExactValue_Invalid) {
// See above note in UnaryExpr case
break;
}
@@ -2952,15 +2951,14 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
}
if (!final && is_type_untyped(type)) {
old.type = base_type(type);
check_set_expr_info(&c->checker->info, e, old);
old->type = base_type(type);
return;
}
// We need to remove it and then give it a new one
check_remove_expr_info(&c->checker->info, e);
if (old.is_lhs && !is_type_integer(type)) {
if (old->is_lhs && !is_type_integer(type)) {
gbString expr_str = expr_to_string(e);
gbString type_str = type_to_string(type);
error(e, "Shifted operand %s must be an integer, got %s", expr_str, type_str);
@@ -2969,7 +2967,7 @@ void update_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
return;
}
add_type_and_value(&c->checker->info, e, old.mode, type, old.value);
add_type_and_value(&c->checker->info, e, old->mode, type, old->value);
}
void update_expr_value(CheckerContext *c, Ast *e, ExactValue value) {
+5 -5
View File
@@ -558,7 +558,7 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
}
Entity *e = alloc_entity_label(ctx->scope, l->name->Ident.token, t_invalid, label, parent);
add_entity(ctx->checker, ctx->scope, l->name, e);
add_entity(ctx, ctx->scope, l->name, e);
e->parent_proc_decl = ctx->curr_proc_decl;
if (ok) {
@@ -861,7 +861,7 @@ void check_inline_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
}
for (isize i = 0; i < entity_count; i++) {
add_entity(ctx->checker, ctx->scope, entities[i]->identifier, entities[i]);
add_entity(ctx, ctx->scope, entities[i]->identifier, entities[i]);
}
@@ -1344,7 +1344,7 @@ void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
if (!is_reference) {
tag_var->flags |= EntityFlag_Value;
}
add_entity(ctx->checker, ctx->scope, lhs, tag_var);
add_entity(ctx, ctx->scope, lhs, tag_var);
add_entity_use(ctx, lhs, tag_var);
add_implicit_entity(ctx, stmt, tag_var);
}
@@ -1966,7 +1966,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
Entity *e = entities[i];
DeclInfo *d = decl_info_of_entity(e);
GB_ASSERT(d == nullptr);
add_entity(ctx->checker, ctx->scope, e->identifier, e);
add_entity(ctx, ctx->scope, e->identifier, e);
d = make_decl_info(ctx->scope, ctx->decl);
add_entity_and_decl_info(ctx, e->identifier, e, d);
}
@@ -2286,7 +2286,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
}
}
}
add_entity(ctx->checker, ctx->scope, e->identifier, e);
add_entity(ctx, ctx->scope, e->identifier, e);
}
if (vd->is_using != 0) {
+15 -15
View File
@@ -23,7 +23,7 @@ void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field,
tok.pos = ast_token(field->type).pos;
}
Entity *f = alloc_entity_array_elem(nullptr, tok, t->Array.elem, idx);
add_entity(ctx->checker, ctx->scope, nullptr, f);
add_entity(ctx, ctx->scope, nullptr, f);
}
}
@@ -52,7 +52,7 @@ void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field
error(e->token, "'%.*s' is already declared", LIT(name));
}
} else {
add_entity(ctx->checker, ctx->scope, nullptr, f);
add_entity(ctx, ctx->scope, nullptr, f);
if (f->flags & EntityFlag_Using) {
populate_using_entity_scope(ctx, node, field, f->type);
}
@@ -157,7 +157,7 @@ void check_struct_fields(CheckerContext *ctx, Ast *node, Array<Entity *> *fields
Token name_token = name->Ident.token;
Entity *field = alloc_entity_field(ctx->scope, name_token, type, is_using, field_src_index);
add_entity(ctx->checker, ctx->scope, name, field);
add_entity(ctx, ctx->scope, name, field);
array_add(fields, field);
array_add(tags, p->tag.string);
@@ -483,7 +483,7 @@ Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_para
}
e->state = EntityState_Resolved;
add_entity(ctx->checker, scope, name, e);
add_entity(ctx, scope, name, e);
array_add(&entities, e);
}
}
@@ -795,7 +795,7 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
if (scope_lookup_current(ctx->scope, name) != nullptr) {
error(ident, "'%.*s' is already declared in this enumeration", LIT(name));
} else {
add_entity(ctx->checker, ctx->scope, nullptr, e);
add_entity(ctx, ctx->scope, nullptr, e);
array_add(&fields, e);
// TODO(bill): Should I add a use for the enum value?
add_entity_use(ctx, field, e);
@@ -1622,7 +1622,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
}
param->state = EntityState_Resolved; // NOTE(bill): This should have be resolved whilst determining it
add_entity(ctx->checker, scope, name, param);
add_entity(ctx, scope, name, param);
if (is_using) {
add_entity_use(ctx, name, param);
}
@@ -1749,7 +1749,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
param->flags |= EntityFlag_Result;
param->Variable.param_value = param_value;
array_add(&variables, param);
add_entity(ctx->checker, scope, name, param);
add_entity(ctx, scope, name, param);
// NOTE(bill): Removes `declared but not used` when using -vet
add_entity_use(ctx, name, param);
}
@@ -2243,7 +2243,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
Entity *new_field = alloc_entity_field(scope, token, field_type, false, cast(i32)i);
soa_struct->Struct.fields[i] = new_field;
add_entity(ctx->checker, scope, nullptr, new_field);
add_entity(ctx, scope, nullptr, new_field);
add_entity_use(ctx, nullptr, new_field);
}
@@ -2277,7 +2277,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
}
Entity *new_field = alloc_entity_field(scope, old_field->token, field_type, false, old_field->Variable.field_src_index);
soa_struct->Struct.fields[i] = new_field;
add_entity(ctx->checker, scope, nullptr, new_field);
add_entity(ctx, scope, nullptr, new_field);
add_entity_use(ctx, nullptr, new_field);
} else {
soa_struct->Struct.fields[i] = old_field;
@@ -2290,13 +2290,13 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
if (soa_kind != StructSoa_Fixed) {
Entity *len_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+0);
soa_struct->Struct.fields[field_count+0] = len_field;
add_entity(ctx->checker, scope, nullptr, len_field);
add_entity(ctx, scope, nullptr, len_field);
add_entity_use(ctx, nullptr, len_field);
if (soa_kind == StructSoa_Dynamic) {
Entity *cap_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+1);
soa_struct->Struct.fields[field_count+1] = cap_field;
add_entity(ctx->checker, scope, nullptr, cap_field);
add_entity(ctx, scope, nullptr, cap_field);
add_entity_use(ctx, nullptr, cap_field);
Token token = {};
@@ -2304,7 +2304,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
init_mem_allocator(ctx->checker);
Entity *allocator_field = alloc_entity_field(scope, token, t_allocator, false, cast(i32)field_count+2);
soa_struct->Struct.fields[field_count+2] = allocator_field;
add_entity(ctx->checker, scope, nullptr, allocator_field);
add_entity(ctx, scope, nullptr, allocator_field);
add_entity_use(ctx, nullptr, allocator_field);
}
}
@@ -2312,7 +2312,7 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el
Token token = {};
token.string = str_lit("Base_Type");
Entity *base_type_entity = alloc_entity_type_name(scope, token, elem, EntityState_Resolved);
add_entity(ctx->checker, scope, nullptr, base_type_entity);
add_entity(ctx, scope, nullptr, base_type_entity);
add_type_info_type(ctx, soa_struct);
@@ -2425,8 +2425,8 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
t->Generic.entity = e;
e->TypeName.is_type_alias = true;
e->state = EntityState_Resolved;
add_entity(ctx->checker, ps, ident, e);
add_entity(ctx->checker, s, ident, e);
add_entity(ctx, ps, ident, e);
add_entity(ctx, s, ident, e);
} else {
error(ident, "Invalid use of a polymorphic parameter '$%.*s'", LIT(token.string));
*type = t_invalid;
+79 -61
View File
@@ -242,7 +242,7 @@ Scope *create_scope(Scope *parent, isize init_elements_capacity=DEFAULT_SCOPE_CA
return s;
}
Scope *create_scope_from_file(CheckerContext *c, AstFile *f) {
Scope *create_scope_from_file(AstFile *f) {
GB_ASSERT(f != nullptr);
GB_ASSERT(f->pkg != nullptr);
GB_ASSERT(f->pkg->scope != nullptr);
@@ -870,7 +870,7 @@ void destroy_checker_info(CheckerInfo *i) {
}
CheckerContext make_checker_context(Checker *c) {
CheckerContext ctx = c->init_ctx;
CheckerContext ctx = {};
ctx.checker = c;
ctx.info = &c->info;
ctx.scope = builtin_pkg->scope;
@@ -883,6 +883,40 @@ CheckerContext make_checker_context(Checker *c) {
return ctx;
}
void add_curr_ast_file(CheckerContext *ctx, AstFile *file) {
if (file != nullptr) {
TokenPos zero_pos = {};
global_error_collector.prev = zero_pos;
ctx->file = file;
ctx->decl = file->pkg->decl_info;
ctx->scope = file->scope;
ctx->pkg = file->pkg;
}
}
void reset_checker_context(CheckerContext *ctx, AstFile *file) {
if (ctx == nullptr) {
return;
}
auto checker = ctx->checker;
auto info = ctx->info;
auto type_path = ctx->type_path;
auto poly_path = ctx->poly_path;
array_clear(type_path);
array_clear(poly_path);
gb_zero_item(ctx);
ctx->checker = checker;
ctx->info = info;
ctx->type_path = type_path;
ctx->poly_path = poly_path;
ctx->scope = builtin_pkg->scope;
ctx->pkg = builtin_pkg;
add_curr_ast_file(ctx, file);
}
void destroy_checker_context(CheckerContext *ctx) {
destroy_checker_type_path(ctx->type_path);
destroy_checker_poly_path(ctx->poly_path);
@@ -907,7 +941,7 @@ bool init_checker(Checker *c, Parser *parser) {
isize total_token_count = c->parser->total_token_count;
isize arena_size = 2 * item_size * total_token_count;
c->init_ctx = make_checker_context(c);
c->builtin_ctx = make_checker_context(c);
return true;
}
@@ -917,7 +951,7 @@ void destroy_checker(Checker *c) {
array_free(&c->procs_to_check);
array_free(&c->procs_with_deferred_to_check);
destroy_checker_context(&c->init_ctx);
destroy_checker_context(&c->builtin_ctx);
}
@@ -994,10 +1028,11 @@ Scope *scope_of_node(Ast *node) {
return node->scope;
}
ExprInfo *check_get_expr_info(CheckerInfo *i, Ast *expr) {
return map_get(&i->untyped, hash_node(expr));
}
void check_set_expr_info(CheckerInfo *i, Ast *expr, ExprInfo info) {
map_set(&i->untyped, hash_node(expr), info);
ExprInfo **found = map_get(&i->untyped, hash_node(expr));
if (found) {
return *found;
}
return nullptr;
}
void check_remove_expr_info(CheckerInfo *i, Ast *expr) {
map_remove(&i->untyped, hash_node(expr));
@@ -1143,7 +1178,7 @@ bool redeclaration_error(String name, Entity *prev, Entity *found) {
return false;
}
bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *entity, String name) {
bool add_entity_with_name(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity, String name) {
if (scope == nullptr) {
return false;
}
@@ -1155,14 +1190,13 @@ bool add_entity_with_name(Checker *c, Scope *scope, Ast *identifier, Entity *ent
}
if (identifier != nullptr) {
if (entity->file == nullptr) {
GB_ASSERT(c->curr_ctx != nullptr);
entity->file = c->curr_ctx->file;
entity->file = c->file;
}
add_entity_definition(&c->info, identifier, entity);
add_entity_definition(c->info, identifier, entity);
}
return true;
}
bool add_entity(Checker *c, Scope *scope, Ast *identifier, Entity *entity) {
bool add_entity(CheckerContext *c, Scope *scope, Ast *identifier, Entity *entity) {
return add_entity_with_name(c, scope, identifier, entity, entity->token.string);
}
@@ -1213,7 +1247,7 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec
scope = pkg->scope;
}
}
add_entity(c->checker, scope, identifier, e);
add_entity(c, scope, identifier, e);
}
add_entity_definition(&c->checker->info, identifier, e);
@@ -1460,17 +1494,6 @@ void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *dec
check_procedure_later(c, info);
}
void add_curr_ast_file(CheckerContext *ctx, AstFile *file) {
if (file != nullptr) {
TokenPos zero_pos = {};
global_error_collector.prev = zero_pos;
ctx->file = file;
ctx->decl = file->pkg->decl_info;
ctx->scope = file->scope;
ctx->pkg = file->pkg;
ctx->checker->curr_ctx = ctx;
}
}
void add_min_dep_type_info(Checker *c, Type *t) {
if (t == nullptr) {
@@ -1488,7 +1511,7 @@ void add_min_dep_type_info(Checker *c, Type *t) {
isize ti_index = type_info_index(&c->info, t, false);
if (ti_index < 0) {
add_type_info_type(&c->init_ctx, t); // Missing the type information
add_type_info_type(&c->builtin_ctx, t); // Missing the type information
ti_index = type_info_index(&c->info, t, false);
}
GB_ASSERT(ti_index >= 0);
@@ -2282,8 +2305,7 @@ void init_core_map_type(Checker *c) {
if (t_map_hash == nullptr) {
Entity *e = find_core_entity(c, str_lit("Map_Hash"));
if (e->state == EntityState_Unresolved) {
auto ctx = c->init_ctx;
check_entity_decl(&ctx, e, nullptr, nullptr);
check_entity_decl(&c->builtin_ctx, e, nullptr, nullptr);
}
t_map_hash = e->type;
GB_ASSERT(t_map_hash != nullptr);
@@ -2292,8 +2314,7 @@ void init_core_map_type(Checker *c) {
if (t_map_header == nullptr) {
Entity *e = find_core_entity(c, str_lit("Map_Header"));
if (e->state == EntityState_Unresolved) {
auto ctx = c->init_ctx;
check_entity_decl(&ctx, e, nullptr, nullptr);
check_entity_decl(&c->builtin_ctx, e, nullptr, nullptr);
}
t_map_header = e->type;
GB_ASSERT(t_map_header != nullptr);
@@ -2887,7 +2908,7 @@ void check_builtin_attributes(CheckerContext *ctx, Entity *e, Array<Ast *> *attr
}
if (name == "builtin") {
add_entity(ctx->checker, builtin_pkg->scope, nullptr, e);
add_entity(ctx, builtin_pkg->scope, nullptr, e);
GB_ASSERT(scope_lookup(builtin_pkg->scope, e->token.string) != nullptr);
if (value != nullptr) {
error(value, "'builtin' cannot have a field value");
@@ -3236,8 +3257,8 @@ void check_collect_entities(CheckerContext *c, Slice<Ast *> const &nodes) {
}
CheckerContext *create_checker_context(Checker *c) {
CheckerContext *ctx = gb_alloc_item(heap_allocator(), CheckerContext);
*ctx = c->init_ctx;
CheckerContext *ctx = gb_alloc_item(permanent_allocator(), CheckerContext);
*ctx = make_checker_context(c);
return ctx;
}
@@ -3611,7 +3632,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
id->fullpath, id->import_name.string,
scope);
add_entity(ctx->checker, parent_scope, nullptr, e);
add_entity(ctx, parent_scope, nullptr, e);
if (force_use || id->is_using) {
add_entity_use(ctx, nullptr, e);
}
@@ -3638,7 +3659,7 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
// file scope otherwise the error would be the wrong way around
redeclaration_error(name, found, e);
} else {
add_entity_with_name(ctx->checker, parent_scope, e->identifier, e, name);
add_entity_with_name(ctx, parent_scope, e->identifier, e, name);
}
}
}
@@ -3700,7 +3721,7 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) {
Entity *e = alloc_entity_library_name(parent_scope, fl->library_name, t_invalid,
fl->fullpaths, library_name);
add_entity(ctx->checker, parent_scope, nullptr, e);
add_entity(ctx, parent_scope, nullptr, e);
AttributeContext ac = {};
@@ -3958,6 +3979,8 @@ void check_import_entities(Checker *c) {
}
}
CheckerContext ctx = make_checker_context(c);
for (isize loop_count = 0; ; loop_count++) {
bool new_files = false;
for_array(i, package_order) {
@@ -3970,8 +3993,7 @@ void check_import_entities(Checker *c) {
for_array(i, pkg->files) {
AstFile *f = pkg->files[i];
CheckerContext ctx = c->init_ctx;
add_curr_ast_file(&ctx, f);
reset_checker_context(&ctx, f);
new_files |= collect_checked_packages_from_decl_list(c, f->decls);
}
}
@@ -3994,9 +4016,8 @@ void check_import_entities(Checker *c) {
for_array(i, pkg->files) {
AstFile *f = pkg->files[i];
CheckerContext ctx = c->init_ctx;
reset_checker_context(&ctx, f);
ctx.collect_delayed_decls = true;
add_curr_ast_file(&ctx, f);
if (collect_file_decls(&ctx, f->decls)) {
new_packages = true;
@@ -4017,8 +4038,7 @@ void check_import_entities(Checker *c) {
for_array(i, pkg->files) {
AstFile *f = pkg->files[i];
CheckerContext ctx = c->init_ctx;
add_curr_ast_file(&ctx, f);
reset_checker_context(&ctx, f);
for_array(j, f->scope->delayed_imports) {
Ast *decl = f->scope->delayed_imports[j];
@@ -4027,8 +4047,7 @@ void check_import_entities(Checker *c) {
}
for_array(i, pkg->files) {
AstFile *f = pkg->files[i];
CheckerContext ctx = c->init_ctx;
add_curr_ast_file(&ctx, f);
reset_checker_context(&ctx, f);
for_array(j, f->scope->delayed_directives) {
Ast *expr = f->scope->delayed_directives[j];
@@ -4214,7 +4233,7 @@ void check_proc_info(Checker *c, ProcInfo pi) {
CheckerContext ctx = make_checker_context(c);
defer (destroy_checker_context(&ctx));
add_curr_ast_file(&ctx, pi.file);
reset_checker_context(&ctx, pi.file);
ctx.decl = pi.decl;
TypeProc *pt = &pi.type->Proc;
@@ -4332,13 +4351,13 @@ void check_parsed_files(Checker *c) {
#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
TIME_SECTION("map full filepaths to scope");
add_type_info_type(&c->init_ctx, t_invalid);
add_type_info_type(&c->builtin_ctx, t_invalid);
// Map full filepaths to Scopes
for_array(i, c->parser->packages) {
AstPackage *p = c->parser->packages[i];
Scope *scope = create_scope_from_package(&c->init_ctx, p);
p->decl_info = make_decl_info(scope, c->init_ctx.decl);
Scope *scope = create_scope_from_package(&c->builtin_ctx, p);
p->decl_info = make_decl_info(scope, c->builtin_ctx.decl);
string_map_set(&c->info.packages, p->fullpath, p);
if (scope->flags&ScopeFlag_Init) {
@@ -4353,21 +4372,20 @@ void check_parsed_files(Checker *c) {
TIME_SECTION("collect entities");
// Collect Entities
CheckerContext collect_entity_ctx = make_checker_context(c);
defer (destroy_checker_context(&collect_entity_ctx));
for_array(i, c->parser->packages) {
AstPackage *pkg = c->parser->packages[i];
CheckerContext ctx = make_checker_context(c);
defer (destroy_checker_context(&ctx));
ctx.pkg = pkg;
ctx.collect_delayed_decls = false;
CheckerContext *ctx = &collect_entity_ctx;
for_array(j, pkg->files) {
AstFile *f = pkg->files[j];
create_scope_from_file(&ctx, f);
string_map_set(&c->info.files, f->fullpath, f);
add_curr_ast_file(&ctx, f);
check_collect_entities(&ctx, f->decls);
create_scope_from_file(f);
reset_checker_context(ctx, f);
check_collect_entities(ctx, f->decls);
}
pkg->used = true;
@@ -4382,9 +4400,9 @@ void check_parsed_files(Checker *c) {
TIME_SECTION("init preload");
init_preload(c);
CheckerContext prev_context = c->init_ctx;
defer (c->init_ctx = prev_context);
c->init_ctx.decl = make_decl_info(nullptr, nullptr);
CheckerContext prev_context = c->builtin_ctx;
defer (c->builtin_ctx = prev_context);
c->builtin_ctx.decl = make_decl_info(nullptr, nullptr);
TIME_SECTION("check procedure bodies");
// NOTE(bill): Nested procedures bodies will be added to this "queue"
@@ -4418,7 +4436,7 @@ void check_parsed_files(Checker *c) {
auto *entry = &c->info.untyped.entries[i];
HashKey key = entry->key;
Ast *expr = cast(Ast *)cast(uintptr)key.key;
ExprInfo *info = &entry->value;
ExprInfo *info = entry->value;
if (info != nullptr && expr != nullptr) {
if (is_type_typed(info->type)) {
compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type));
@@ -4444,7 +4462,7 @@ void check_parsed_files(Checker *c) {
Type *t = &basic_types[i];
if (t->Basic.size > 0 &&
(t->Basic.flags & BasicFlag_LLVM) == 0) {
add_type_info_type(&c->init_ctx, t);
add_type_info_type(&c->builtin_ctx, t);
}
}
@@ -4456,7 +4474,7 @@ void check_parsed_files(Checker *c) {
// i64 size = type_size_of(c->allocator, e->type);
i64 align = type_align_of(e->type);
if (align > 0 && ptr_set_exists(&c->info.minimum_dependency_set, e)) {
add_type_info_type(&c->init_ctx, e->type);
add_type_info_type(&c->builtin_ctx, e->type);
}
} else if (e->kind == Entity_Procedure) {
+22 -19
View File
@@ -20,12 +20,12 @@ struct ExprInfo {
bool is_lhs; // Debug info
};
gb_inline ExprInfo make_expr_info(AddressingMode mode, Type *type, ExactValue value, bool is_lhs) {
ExprInfo ei = {};
ei.mode = mode;
ei.type = type;
ei.value = value;
ei.is_lhs = is_lhs;
gb_inline ExprInfo *make_expr_info(AddressingMode mode, Type *type, ExactValue const &value, bool is_lhs) {
ExprInfo *ei = gb_alloc_item(permanent_allocator(), ExprInfo);
ei->mode = mode;
ei->type = type;
ei->value = value;
ei->is_lhs = is_lhs;
return ei;
}
@@ -262,9 +262,6 @@ struct CheckerContext;
struct CheckerInfo {
Checker *checker;
Map<ExprInfo> untyped; // Key: Ast * | Expression -> ExprInfo
// NOTE(bill): This needs to be a map and not on the Ast
// as it needs to be iterated across
StringMap<AstFile *> files; // Key (full path)
StringMap<AstPackage *> packages; // Key (full path)
StringMap<Entity *> foreigns;
@@ -272,12 +269,6 @@ struct CheckerInfo {
Array<Entity *> entities;
Array<DeclInfo *> variable_init_order;
Map<Array<Entity *> > gen_procs; // Key: Ast * | Identifier -> Entity
Map<Array<Entity *> > gen_types; // Key: Type *
Array<Type *> type_info_types;
Map<isize> type_info_map; // Key: Type *
AstPackage * builtin_package;
AstPackage * runtime_package;
@@ -294,6 +285,20 @@ struct CheckerInfo {
bool allow_identifier_uses;
Array<Ast *> identifier_uses; // only used by 'odin query'
// Below are accessed within procedures
// NOTE(bill): If the semantic checker (check_proc_body) is to ever to be multithreaded,
// these variables will be of contention
Map<ExprInfo *> untyped; // Key: Ast * | Expression -> ExprInfo *
// NOTE(bill): This needs to be a map and not on the Ast
// as it needs to be iterated across
Map<Array<Entity *> > gen_procs; // Key: Ast * | Identifier -> Entity
Map<Array<Entity *> > gen_types; // Key: Type *
Array<Type *> type_info_types;
Map<isize> type_info_map; // Key: Type *
};
struct CheckerContext {
@@ -339,11 +344,10 @@ struct Checker {
Parser * parser;
CheckerInfo info;
CheckerContext builtin_ctx;
Array<ProcInfo> procs_to_check;
Array<Entity *> procs_with_deferred_to_check;
CheckerContext *curr_ctx;
CheckerContext init_ctx;
};
@@ -382,7 +386,6 @@ Entity *scope_insert (Scope *s, Entity *entity);
ExprInfo *check_get_expr_info (CheckerInfo *i, Ast *expr);
void check_set_expr_info (CheckerInfo *i, Ast *expr, ExprInfo info);
void check_remove_expr_info (CheckerInfo *i, Ast *expr);
void add_untyped (CheckerInfo *i, Ast *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value);
void add_type_and_value (CheckerInfo *i, Ast *expression, AddressingMode mode, Type *type, ExactValue value);