mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Fix rules for recursive initialization with procedure entities; Fix executable name if not given
This commit is contained in:
+88
-15
@@ -1834,11 +1834,37 @@ bool is_entity_a_dependency(Entity *e) {
|
|||||||
case Entity_Constant:
|
case Entity_Constant:
|
||||||
case Entity_Variable:
|
case Entity_Variable:
|
||||||
return e->pkg != nullptr;
|
return e->pkg != nullptr;
|
||||||
|
case Entity_TypeName:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_entity_dependency_from_procedure_parameters(Map<EntityGraphNode *> *M, EntityGraphNode *n, Type *tuple) {
|
||||||
|
if (tuple == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Entity *e = n->entity;
|
||||||
|
bool print_deps = false;
|
||||||
|
|
||||||
|
GB_ASSERT(tuple->kind == Type_Tuple);
|
||||||
|
TypeTuple *t = &tuple->Tuple;
|
||||||
|
for_array(i, t->variables) {
|
||||||
|
Entity *v = t->variables[i];
|
||||||
|
EntityGraphNode **found = map_get(M, hash_pointer(v));
|
||||||
|
if (found == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityGraphNode *m = *found;
|
||||||
|
entity_graph_node_set_add(&n->succ, m);
|
||||||
|
entity_graph_node_set_add(&m->pred, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
||||||
|
#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
|
||||||
|
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
|
|
||||||
Map<EntityGraphNode *> M = {}; // Key: Entity *
|
Map<EntityGraphNode *> M = {}; // Key: Entity *
|
||||||
@@ -1854,20 +1880,20 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
|
|
||||||
|
|
||||||
|
|
||||||
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
|
TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 1");
|
||||||
// Calculate edges for graph M
|
// Calculate edges for graph M
|
||||||
for_array(i, M.entries) {
|
for_array(i, M.entries) {
|
||||||
Entity * e = cast(Entity *)cast(uintptr)M.entries[i].key.key;
|
|
||||||
EntityGraphNode *n = M.entries[i].value;
|
EntityGraphNode *n = M.entries[i].value;
|
||||||
|
Entity *e = n->entity;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
GB_ASSERT(decl != nullptr);
|
GB_ASSERT(decl != nullptr);
|
||||||
|
|
||||||
for_array(j, decl->deps.entries) {
|
for_array(j, decl->deps.entries) {
|
||||||
Entity *dep = decl->deps.entries[j].ptr;
|
Entity *dep = decl->deps.entries[j].ptr;
|
||||||
|
if (dep->flags & EntityFlag_Field) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
GB_ASSERT(dep != nullptr);
|
GB_ASSERT(dep != nullptr);
|
||||||
if (is_entity_a_dependency(dep)) {
|
if (is_entity_a_dependency(dep)) {
|
||||||
EntityGraphNode **m_ = map_get(&M, hash_pointer(dep));
|
EntityGraphNode **m_ = map_get(&M, hash_pointer(dep));
|
||||||
@@ -1924,7 +1950,6 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
|||||||
EntityGraphNode *n = G[i];
|
EntityGraphNode *n = G[i];
|
||||||
n->index = i;
|
n->index = i;
|
||||||
n->dep_count = n->succ.entries.count;
|
n->dep_count = n->succ.entries.count;
|
||||||
|
|
||||||
GB_ASSERT(n->dep_count >= 0);
|
GB_ASSERT(n->dep_count >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3978,7 +4003,42 @@ void check_import_entities(Checker *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *visited = nullptr) {
|
|
||||||
|
Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *visited = nullptr);
|
||||||
|
|
||||||
|
bool find_entity_path_tuple(Type *tuple, Entity *end, Map<Entity *> *visited, Array<Entity *> *path_) {
|
||||||
|
GB_ASSERT(path_ != nullptr);
|
||||||
|
if (tuple == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
GB_ASSERT(tuple->kind == Type_Tuple);
|
||||||
|
for_array(i, tuple->Tuple.variables) {
|
||||||
|
Entity *var = tuple->Tuple.variables[i];
|
||||||
|
DeclInfo *var_decl = var->decl_info;
|
||||||
|
if (var_decl == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for_array(i, var_decl->deps.entries) {
|
||||||
|
Entity *dep = var_decl->deps.entries[i].ptr;
|
||||||
|
if (dep == end) {
|
||||||
|
auto path = array_make<Entity *>(heap_allocator());
|
||||||
|
array_add(&path, dep);
|
||||||
|
*path_ = path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto next_path = find_entity_path(dep, end, visited);
|
||||||
|
if (next_path.count > 0) {
|
||||||
|
array_add(&next_path, dep);
|
||||||
|
*path_ = next_path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *visited) {
|
||||||
Map<Entity *> visited_ = {};
|
Map<Entity *> visited_ = {};
|
||||||
bool made_visited = false;
|
bool made_visited = false;
|
||||||
if (visited == nullptr) {
|
if (visited == nullptr) {
|
||||||
@@ -4001,17 +4061,30 @@ Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *visi
|
|||||||
|
|
||||||
DeclInfo *decl = start->decl_info;
|
DeclInfo *decl = start->decl_info;
|
||||||
if (decl) {
|
if (decl) {
|
||||||
for_array(i, decl->deps.entries) {
|
if (start->kind == Entity_Procedure) {
|
||||||
Entity *dep = decl->deps.entries[i].ptr;
|
Type *t = base_type(start->type);
|
||||||
if (dep == end) {
|
GB_ASSERT(t->kind == Type_Proc);
|
||||||
auto path = array_make<Entity *>(heap_allocator());
|
|
||||||
array_add(&path, dep);
|
Array<Entity *> path = {};
|
||||||
|
if (find_entity_path_tuple(t->Proc.params, end, visited, &path)) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
auto next_path = find_entity_path(dep, end, visited);
|
if (find_entity_path_tuple(t->Proc.results, end, visited, &path)) {
|
||||||
if (next_path.count > 0) {
|
return path;
|
||||||
array_add(&next_path, dep);
|
}
|
||||||
return next_path;
|
} else {
|
||||||
|
for_array(i, decl->deps.entries) {
|
||||||
|
Entity *dep = decl->deps.entries[i].ptr;
|
||||||
|
if (dep == end) {
|
||||||
|
auto path = array_make<Entity *>(heap_allocator());
|
||||||
|
array_add(&path, dep);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
auto next_path = find_entity_path(dep, end, visited);
|
||||||
|
if (next_path.count > 0) {
|
||||||
|
array_add(&next_path, dep);
|
||||||
|
return next_path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ enum EntityFlag : u32 {
|
|||||||
|
|
||||||
enum EntityState {
|
enum EntityState {
|
||||||
EntityState_Unresolved = 0,
|
EntityState_Unresolved = 0,
|
||||||
EntityState_InProgress = 1,
|
EntityState_InProgress = 1,
|
||||||
EntityState_Resolved = 2,
|
EntityState_Resolved = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11485,9 +11485,17 @@ bool ir_gen_init(irGen *s, Checker *c) {
|
|||||||
if (build_context.out_filepath.len == 0) {
|
if (build_context.out_filepath.len == 0) {
|
||||||
s->output_name = remove_directory_from_path(init_fullpath);
|
s->output_name = remove_directory_from_path(init_fullpath);
|
||||||
s->output_name = remove_extension_from_path(s->output_name);
|
s->output_name = remove_extension_from_path(s->output_name);
|
||||||
|
s->output_name = string_trim_whitespace(s->output_name);
|
||||||
|
if (s->output_name.len == 0) {
|
||||||
|
s->output_name = c->info.init_scope->pkg->name;
|
||||||
|
}
|
||||||
s->output_base = s->output_name;
|
s->output_base = s->output_name;
|
||||||
} else {
|
} else {
|
||||||
s->output_name = build_context.out_filepath;
|
s->output_name = build_context.out_filepath;
|
||||||
|
s->output_name = string_trim_whitespace(s->output_name);
|
||||||
|
if (s->output_name.len == 0) {
|
||||||
|
s->output_name = c->info.init_scope->pkg->name;
|
||||||
|
}
|
||||||
isize pos = string_extension_position(s->output_name);
|
isize pos = string_extension_position(s->output_name);
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
s->output_base = s->output_name;
|
s->output_base = s->output_name;
|
||||||
|
|||||||
@@ -10645,9 +10645,17 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) {
|
|||||||
if (build_context.out_filepath.len == 0) {
|
if (build_context.out_filepath.len == 0) {
|
||||||
gen->output_name = remove_directory_from_path(init_fullpath);
|
gen->output_name = remove_directory_from_path(init_fullpath);
|
||||||
gen->output_name = remove_extension_from_path(gen->output_name);
|
gen->output_name = remove_extension_from_path(gen->output_name);
|
||||||
|
gen->output_name = string_trim_whitespace(gen->output_name);
|
||||||
|
if (gen->output_name.len == 0) {
|
||||||
|
gen->output_name = c->info.init_scope->pkg->name;
|
||||||
|
}
|
||||||
gen->output_base = gen->output_name;
|
gen->output_base = gen->output_name;
|
||||||
} else {
|
} else {
|
||||||
gen->output_name = build_context.out_filepath;
|
gen->output_name = build_context.out_filepath;
|
||||||
|
gen->output_name = string_trim_whitespace(gen->output_name);
|
||||||
|
if (gen->output_name.len == 0) {
|
||||||
|
gen->output_name = c->info.init_scope->pkg->name;
|
||||||
|
}
|
||||||
isize pos = string_extension_position(gen->output_name);
|
isize pos = string_extension_position(gen->output_name);
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
gen->output_base = gen->output_name;
|
gen->output_base = gen->output_name;
|
||||||
|
|||||||
Reference in New Issue
Block a user