mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 06:38:47 +00:00
Patch issue with minimum dependency system and how it interacts with para poly procedures
This commit is contained in:
+58
-11
@@ -14,7 +14,27 @@ enum CallArgumentError {
|
|||||||
CallArgumentError_ParameterMissing,
|
CallArgumentError_ParameterMissing,
|
||||||
CallArgumentError_DuplicateParameter,
|
CallArgumentError_DuplicateParameter,
|
||||||
CallArgumentError_NoneConstantParameter,
|
CallArgumentError_NoneConstantParameter,
|
||||||
|
|
||||||
|
CallArgumentError_MAX,
|
||||||
};
|
};
|
||||||
|
char const *CallArgumentError_strings[CallArgumentError_MAX] = {
|
||||||
|
"None",
|
||||||
|
"NoneProcedureType",
|
||||||
|
"WrongTypes",
|
||||||
|
"NonVariadicExpand",
|
||||||
|
"VariadicTuple",
|
||||||
|
"MultipleVariadicExpand",
|
||||||
|
"AmbiguousPolymorphicVariadic",
|
||||||
|
"ArgumentCount",
|
||||||
|
"TooFewArguments",
|
||||||
|
"TooManyArguments",
|
||||||
|
"InvalidFieldValue",
|
||||||
|
"ParameterNotFound",
|
||||||
|
"ParameterMissing",
|
||||||
|
"DuplicateParameter",
|
||||||
|
"NoneConstantParameter",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum CallArgumentErrorMode {
|
enum CallArgumentErrorMode {
|
||||||
CallArgumentMode_NoErrors,
|
CallArgumentMode_NoErrors,
|
||||||
@@ -25,6 +45,7 @@ struct CallArgumentData {
|
|||||||
Entity *gen_entity;
|
Entity *gen_entity;
|
||||||
i64 score;
|
i64 score;
|
||||||
Type * result_type;
|
Type * result_type;
|
||||||
|
Type * proc_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PolyProcData {
|
struct PolyProcData {
|
||||||
@@ -243,7 +264,6 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
|
|
||||||
Array<Operand> operands = {};
|
Array<Operand> operands = {};
|
||||||
@@ -344,7 +364,6 @@ bool find_or_generate_polymorphic_procedure(CheckerContext *c, Entity *base_enti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ast *proc_lit = clone_ast(old_decl->proc_lit);
|
Ast *proc_lit = clone_ast(old_decl->proc_lit);
|
||||||
ast_node(pl, ProcLit, proc_lit);
|
ast_node(pl, ProcLit, proc_lit);
|
||||||
// NOTE(bill): Associate the scope declared above withinth this procedure declaration's type
|
// NOTE(bill): Associate the scope declared above withinth this procedure declaration's type
|
||||||
@@ -6993,8 +7012,14 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
|
|
||||||
CallArgumentData data = {};
|
CallArgumentData data = {};
|
||||||
CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data);
|
CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data);
|
||||||
|
if (err != CallArgumentError_None) {
|
||||||
|
// handle error
|
||||||
|
}
|
||||||
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
|
||||||
add_entity_use(c, ident, entity_to_use);
|
if (entity_to_use != nullptr) {
|
||||||
|
add_entity_use(c, ident, entity_to_use);
|
||||||
|
data.proc_type = entity_to_use->type;
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -7070,6 +7095,13 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
auto valids = array_make<ValidIndexAndScore>(heap_allocator(), 0, procs.count);
|
auto valids = array_make<ValidIndexAndScore>(heap_allocator(), 0, procs.count);
|
||||||
defer (array_free(&valids));
|
defer (array_free(&valids));
|
||||||
|
|
||||||
|
auto proc_entities = array_make<Entity *>(heap_allocator(), 0, procs.count*2);
|
||||||
|
defer (array_free(&proc_entities));
|
||||||
|
for_array(i, procs) {
|
||||||
|
array_add(&proc_entities, procs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gbString expr_name = expr_to_string(operand->expr);
|
gbString expr_name = expr_to_string(operand->expr);
|
||||||
defer (gb_string_free(expr_name));
|
defer (gb_string_free(expr_name));
|
||||||
|
|
||||||
@@ -7086,10 +7118,10 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
ctx.hide_polymorphic_errors = true;
|
ctx.hide_polymorphic_errors = true;
|
||||||
|
|
||||||
err = call_checker(&ctx, call, pt, p, operands, CallArgumentMode_NoErrors, &data);
|
err = call_checker(&ctx, call, pt, p, operands, CallArgumentMode_NoErrors, &data);
|
||||||
|
|
||||||
if (err != CallArgumentError_None) {
|
if (err != CallArgumentError_None) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
isize index = i;
|
||||||
|
|
||||||
if (data.gen_entity != nullptr) {
|
if (data.gen_entity != nullptr) {
|
||||||
Entity *e = data.gen_entity;
|
Entity *e = data.gen_entity;
|
||||||
@@ -7104,10 +7136,13 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
if (!evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, false)) {
|
if (!evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array_add(&proc_entities, data.gen_entity);
|
||||||
|
index = proc_entities.count-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidIndexAndScore item = {};
|
ValidIndexAndScore item = {};
|
||||||
item.index = i;
|
item.index = index;
|
||||||
item.score = data.score;
|
item.score = data.score;
|
||||||
array_add(&valids, item);
|
array_add(&valids, item);
|
||||||
}
|
}
|
||||||
@@ -7116,13 +7151,13 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
if (valids.count > 1) {
|
if (valids.count > 1) {
|
||||||
gb_sort_array(valids.data, valids.count, valid_index_and_score_cmp);
|
gb_sort_array(valids.data, valids.count, valid_index_and_score_cmp);
|
||||||
i64 best_score = valids[0].score;
|
i64 best_score = valids[0].score;
|
||||||
Entity *best_entity = procs[valids[0].index];
|
Entity *best_entity = proc_entities[valids[0].index];
|
||||||
for (isize i = 1; i < valids.count; i++) {
|
for (isize i = 1; i < valids.count; i++) {
|
||||||
if (best_score > valids[i].score) {
|
if (best_score > valids[i].score) {
|
||||||
valids.count = i;
|
valids.count = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (best_entity == procs[valids[i].index]) {
|
if (best_entity == proc_entities[valids[i].index]) {
|
||||||
valids.count = i;
|
valids.count = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -7200,7 +7235,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
error_line(")\n");
|
error_line(")\n");
|
||||||
|
|
||||||
for (isize i = 0; i < valids.count; i++) {
|
for (isize i = 0; i < valids.count; i++) {
|
||||||
Entity *proc = procs[valids[i].index];
|
Entity *proc = proc_entities[valids[i].index];
|
||||||
TokenPos pos = proc->token.pos;
|
TokenPos pos = proc->token.pos;
|
||||||
Type *t = base_type(proc->type); GB_ASSERT(t->kind == Type_Proc);
|
Type *t = base_type(proc->type); GB_ASSERT(t->kind == Type_Proc);
|
||||||
gbString pt = nullptr;
|
gbString pt = nullptr;
|
||||||
@@ -7248,13 +7283,16 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
ident = s;
|
ident = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *e = procs[valids[0].index];
|
Entity *e = proc_entities[valids[0].index];
|
||||||
|
|
||||||
proc_type = e->type;
|
proc_type = e->type;
|
||||||
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;
|
||||||
add_entity_use(c, ident, entity_to_use);
|
if (entity_to_use != nullptr) {
|
||||||
|
add_entity_use(c, ident, entity_to_use);
|
||||||
|
data.proc_type = entity_to_use->type;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.gen_entity != nullptr) {
|
if (data.gen_entity != nullptr) {
|
||||||
Entity *e = data.gen_entity;
|
Entity *e = data.gen_entity;
|
||||||
@@ -7285,7 +7323,10 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
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;
|
||||||
add_entity_use(c, ident, entity_to_use);
|
if (entity_to_use != nullptr) {
|
||||||
|
add_entity_use(c, ident, entity_to_use);
|
||||||
|
data.proc_type = entity_to_use->type;
|
||||||
|
}
|
||||||
|
|
||||||
if (data.gen_entity != nullptr) {
|
if (data.gen_entity != nullptr) {
|
||||||
Entity *e = data.gen_entity;
|
Entity *e = data.gen_entity;
|
||||||
@@ -7789,6 +7830,10 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *pt = base_type(proc_type);
|
Type *pt = base_type(proc_type);
|
||||||
|
if (data.proc_type != nullptr) {
|
||||||
|
pt = base_type(data.proc_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pt->kind == Type_Proc && pt->Proc.calling_convention == ProcCC_Odin) {
|
if (pt->kind == Type_Proc && pt->Proc.calling_convention == ProcCC_Odin) {
|
||||||
if ((c->scope->flags & ScopeFlag_ContextDefined) == 0) {
|
if ((c->scope->flags & ScopeFlag_ContextDefined) == 0) {
|
||||||
@@ -7852,6 +7897,8 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *pr
|
|||||||
operand->mode = Addressing_OptionalOk;
|
operand->mode = Addressing_OptionalOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value);
|
||||||
|
|
||||||
return Expr_Expr;
|
return Expr_Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1674,6 +1674,25 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (type != t_invalid && !check_is_assignable_to(ctx, &op, type)) {
|
||||||
|
bool ok = true;
|
||||||
|
if (p->flags&FieldFlag_auto_cast) {
|
||||||
|
if (!check_is_castable_to(ctx, &op, type)) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
|
if (false) {
|
||||||
|
gbString got = type_to_string(op.type);
|
||||||
|
gbString expected = type_to_string(type);
|
||||||
|
error(op.expr, "Cannot assigned type to parameter, got type '%s', expected '%s'", got, expected);
|
||||||
|
gb_string_free(expected);
|
||||||
|
gb_string_free(got);
|
||||||
|
}
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_type_untyped(default_type(type))) {
|
if (is_type_untyped(default_type(type))) {
|
||||||
gbString str = type_to_string(type);
|
gbString str = type_to_string(type);
|
||||||
error(op.expr, "Cannot determine type from the parameter, got '%s'", str);
|
error(op.expr, "Cannot determine type from the parameter, got '%s'", str);
|
||||||
|
|||||||
+45
-4
@@ -646,6 +646,7 @@ void add_package_dependency(CheckerContext *c, char const *package_name, char co
|
|||||||
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(p->scope, n);
|
Entity *e = scope_lookup(p->scope, n);
|
||||||
|
e->flags |= EntityFlag_Used;
|
||||||
GB_ASSERT_MSG(e != nullptr, "%s", name);
|
GB_ASSERT_MSG(e != nullptr, "%s", name);
|
||||||
GB_ASSERT(c->decl != nullptr);
|
GB_ASSERT(c->decl != nullptr);
|
||||||
ptr_set_add(&c->decl->deps, e);
|
ptr_set_add(&c->decl->deps, e);
|
||||||
@@ -1721,6 +1722,13 @@ void add_dependency_to_set(Checker *c, Entity *entity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void force_add_dependency_entity(Checker *c, Scope *scope, String const &name) {
|
||||||
|
Entity *e = scope_lookup(scope, name);
|
||||||
|
e->flags |= EntityFlag_Used;
|
||||||
|
add_dependency_to_set(c, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||||
isize entity_count = c->info.entities.count;
|
isize entity_count = c->info.entities.count;
|
||||||
@@ -1775,7 +1783,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("bswap_f64"),
|
str_lit("bswap_f64"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_runtime_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_runtime_entities[i]));
|
force_add_dependency_entity(c, c->info.runtime_package->scope, required_runtime_entities[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (build_context.no_crt) {
|
if (build_context.no_crt) {
|
||||||
@@ -1787,7 +1795,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
str_lit("_fltused"),
|
str_lit("_fltused"),
|
||||||
};
|
};
|
||||||
for (isize i = 0; i < gb_count_of(required_no_crt_entities); i++) {
|
for (isize i = 0; i < gb_count_of(required_no_crt_entities); i++) {
|
||||||
add_dependency_to_set(c, scope_lookup(c->info.runtime_package->scope, required_no_crt_entities[i]));
|
force_add_dependency_entity(c, c->info.runtime_package->scope, required_no_crt_entities[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1796,7 +1804,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(os->scope, required_os_entities[i]));
|
force_add_dependency_entity(c, os->scope, required_os_entities[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1808,7 +1816,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(c->info.runtime_package->scope, bounds_check_entities[i]));
|
force_add_dependency_entity(c, c->info.runtime_package->scope, bounds_check_entities[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1896,6 +1904,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
start->flags |= EntityFlag_Used;
|
||||||
add_dependency_to_set(c, start);
|
add_dependency_to_set(c, start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4358,6 +4367,9 @@ void check_proc_info(Checker *c, ProcInfo pi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_proc_body(&ctx, pi.token, pi.decl, pi.type, pi.body);
|
check_proc_body(&ctx, pi.token, pi.decl, pi.type, pi.body);
|
||||||
|
if (pi.body != nullptr && pi.decl->entity != nullptr) {
|
||||||
|
pi.decl->entity->flags |= EntityFlag_ProcBodyChecked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_THREAD_PROC(check_proc_info_worker_proc) {
|
GB_THREAD_PROC(check_proc_info_worker_proc) {
|
||||||
@@ -4368,6 +4380,33 @@ GB_THREAD_PROC(check_proc_info_worker_proc) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_unchecked_bodies(Checker *c) {
|
||||||
|
// NOTE(2021-02-26, bill): Sanity checker
|
||||||
|
// This is a partial hack to make sure all procedure bodies have been checked
|
||||||
|
// even ones which should not exist, due to the multithreaded nature of the parser
|
||||||
|
// NOTE(2021-02-26, bill): Actually fix this race condition
|
||||||
|
for_array(i, c->info.minimum_dependency_set.entries) {
|
||||||
|
Entity *e = c->info.minimum_dependency_set.entries[i].ptr;
|
||||||
|
if (e != nullptr && e->kind == Entity_Procedure) {
|
||||||
|
if (!e->Procedure.is_foreign && (e->flags & EntityFlag_ProcBodyChecked) == 0) {
|
||||||
|
GB_ASSERT(e->decl_info != nullptr);
|
||||||
|
|
||||||
|
ProcInfo pi = {};
|
||||||
|
pi.file = e->file;
|
||||||
|
pi.token = e->token;
|
||||||
|
pi.decl = e->decl_info;
|
||||||
|
pi.type = e->type;
|
||||||
|
|
||||||
|
Ast *pl = e->decl_info->proc_lit;
|
||||||
|
GB_ASSERT(pl != nullptr);
|
||||||
|
pi.body = pl->ProcLit.body;
|
||||||
|
pi.tags = pl->ProcLit.tags;
|
||||||
|
|
||||||
|
check_proc_info(c, pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void check_parsed_files(Checker *c) {
|
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)
|
#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
|
||||||
@@ -4447,6 +4486,8 @@ void check_parsed_files(Checker *c) {
|
|||||||
// Calculate initialization order of global variables
|
// Calculate initialization order of global variables
|
||||||
calculate_global_init_order(c);
|
calculate_global_init_order(c);
|
||||||
|
|
||||||
|
TIME_SECTION("check bodies have all been checked");
|
||||||
|
check_unchecked_bodies(c);
|
||||||
|
|
||||||
TIME_SECTION("add untyped expression values");
|
TIME_SECTION("add untyped expression values");
|
||||||
// Add untyped expression values
|
// Add untyped expression values
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ enum EntityFlag : u32 {
|
|||||||
|
|
||||||
EntityFlag_SoaPtrField = 1<<19, // to allow s.x[0] where `s.x` is a pointer rather than a slice
|
EntityFlag_SoaPtrField = 1<<19, // to allow s.x[0] where `s.x` is a pointer rather than a slice
|
||||||
|
|
||||||
|
EntityFlag_ProcBodyChecked = 1<<20,
|
||||||
|
|
||||||
EntityFlag_CVarArg = 1<<21,
|
EntityFlag_CVarArg = 1<<21,
|
||||||
EntityFlag_AutoCast = 1<<22,
|
EntityFlag_AutoCast = 1<<22,
|
||||||
|
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
|||||||
if (p->module != e->code_gen_module) {
|
if (p->module != e->code_gen_module) {
|
||||||
gb_mutex_lock(&p->module->mutex);
|
gb_mutex_lock(&p->module->mutex);
|
||||||
}
|
}
|
||||||
|
GB_ASSERT(e->code_gen_module != nullptr);
|
||||||
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
||||||
if (p->module != e->code_gen_module) {
|
if (p->module != e->code_gen_module) {
|
||||||
gb_mutex_unlock(&p->module->mutex);
|
gb_mutex_unlock(&p->module->mutex);
|
||||||
@@ -7109,6 +7110,7 @@ lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue>
|
|||||||
if (p->module != e->code_gen_module) {
|
if (p->module != e->code_gen_module) {
|
||||||
gb_mutex_lock(&p->module->mutex);
|
gb_mutex_lock(&p->module->mutex);
|
||||||
}
|
}
|
||||||
|
GB_ASSERT(e->code_gen_module != nullptr);
|
||||||
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
||||||
if (p->module != e->code_gen_module) {
|
if (p->module != e->code_gen_module) {
|
||||||
gb_mutex_unlock(&p->module->mutex);
|
gb_mutex_unlock(&p->module->mutex);
|
||||||
@@ -8564,6 +8566,7 @@ LLVMValueRef lb_lookup_runtime_procedure(lbModule *m, String const &name) {
|
|||||||
if (m != e->code_gen_module) {
|
if (m != e->code_gen_module) {
|
||||||
gb_mutex_lock(&m->mutex);
|
gb_mutex_lock(&m->mutex);
|
||||||
}
|
}
|
||||||
|
GB_ASSERT(e->code_gen_module != nullptr);
|
||||||
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
found = map_get(&e->code_gen_module->values, hash_entity(e));
|
||||||
if (m != e->code_gen_module) {
|
if (m != e->code_gen_module) {
|
||||||
gb_mutex_unlock(&m->mutex);
|
gb_mutex_unlock(&m->mutex);
|
||||||
@@ -9554,9 +9557,9 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
|
|||||||
|
|
||||||
expr = unparen_expr(expr);
|
expr = unparen_expr(expr);
|
||||||
|
|
||||||
|
TokenPos expr_pos = ast_token(expr).pos;
|
||||||
TypeAndValue tv = type_and_value_of_expr(expr);
|
TypeAndValue tv = type_and_value_of_expr(expr);
|
||||||
GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "%s", expr_to_string(expr));
|
GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %.*s(%td:%td)\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), LIT(expr_pos.file), expr_pos.line, expr_pos.column, LIT(p->name), type_to_string(p->type));
|
||||||
GB_ASSERT(tv.mode != Addressing_Type);
|
|
||||||
|
|
||||||
if (tv.value.kind != ExactValue_Invalid) {
|
if (tv.value.kind != ExactValue_Invalid) {
|
||||||
// NOTE(bill): Short on constant values
|
// NOTE(bill): Short on constant values
|
||||||
|
|||||||
Reference in New Issue
Block a user