From 84fd40de77deb71544fce7c3c34177ee2f9c4405 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 May 2020 12:23:41 +0100 Subject: [PATCH] Fix rules for recursive initialization with procedure entities; Fix executable name if not given --- src/checker.cpp | 103 ++++++++++++++++++++++++++++++++++++------- src/entity.cpp | 2 +- src/ir.cpp | 8 ++++ src/llvm_backend.cpp | 8 ++++ 4 files changed, 105 insertions(+), 16 deletions(-) diff --git a/src/checker.cpp b/src/checker.cpp index a08f04945..41453dc99 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1834,11 +1834,37 @@ bool is_entity_a_dependency(Entity *e) { case Entity_Constant: case Entity_Variable: return e->pkg != nullptr; + case Entity_TypeName: + return false; } return false; } +void add_entity_dependency_from_procedure_parameters(Map *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 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(); Map M = {}; // Key: Entity * @@ -1854,20 +1880,20 @@ Array 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"); // Calculate edges for graph M for_array(i, M.entries) { - Entity * e = cast(Entity *)cast(uintptr)M.entries[i].key.key; EntityGraphNode *n = M.entries[i].value; + Entity *e = n->entity; DeclInfo *decl = decl_info_of_entity(e); GB_ASSERT(decl != nullptr); for_array(j, decl->deps.entries) { Entity *dep = decl->deps.entries[j].ptr; + if (dep->flags & EntityFlag_Field) { + continue; + } GB_ASSERT(dep != nullptr); if (is_entity_a_dependency(dep)) { EntityGraphNode **m_ = map_get(&M, hash_pointer(dep)); @@ -1924,7 +1950,6 @@ Array generate_entity_dependency_graph(CheckerInfo *info) { EntityGraphNode *n = G[i]; n->index = i; n->dep_count = n->succ.entries.count; - GB_ASSERT(n->dep_count >= 0); } @@ -3978,7 +4003,42 @@ void check_import_entities(Checker *c) { } } -Array find_entity_path(Entity *start, Entity *end, Map *visited = nullptr) { + +Array find_entity_path(Entity *start, Entity *end, Map *visited = nullptr); + +bool find_entity_path_tuple(Type *tuple, Entity *end, Map *visited, Array *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(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 find_entity_path(Entity *start, Entity *end, Map *visited) { Map visited_ = {}; bool made_visited = false; if (visited == nullptr) { @@ -4001,17 +4061,30 @@ Array find_entity_path(Entity *start, Entity *end, Map *visi DeclInfo *decl = start->decl_info; if (decl) { - for_array(i, decl->deps.entries) { - Entity *dep = decl->deps.entries[i].ptr; - if (dep == end) { - auto path = array_make(heap_allocator()); - array_add(&path, dep); + if (start->kind == Entity_Procedure) { + Type *t = base_type(start->type); + GB_ASSERT(t->kind == Type_Proc); + + Array path = {}; + if (find_entity_path_tuple(t->Proc.params, end, visited, &path)) { return path; } - auto next_path = find_entity_path(dep, end, visited); - if (next_path.count > 0) { - array_add(&next_path, dep); - return next_path; + if (find_entity_path_tuple(t->Proc.results, end, visited, &path)) { + return path; + } + } else { + for_array(i, decl->deps.entries) { + Entity *dep = decl->deps.entries[i].ptr; + if (dep == end) { + auto path = array_make(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; + } } } } diff --git a/src/entity.cpp b/src/entity.cpp index dba289305..ab4d6fd40 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -66,7 +66,7 @@ enum EntityFlag : u32 { enum EntityState { EntityState_Unresolved = 0, - EntityState_InProgress = 1, + EntityState_InProgress = 1, EntityState_Resolved = 2, }; diff --git a/src/ir.cpp b/src/ir.cpp index 020b4ce44..f08c3569d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11485,9 +11485,17 @@ bool ir_gen_init(irGen *s, Checker *c) { if (build_context.out_filepath.len == 0) { s->output_name = remove_directory_from_path(init_fullpath); 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; } else { 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); if (pos < 0) { s->output_base = s->output_name; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index f152c7596..4266d5921 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -10645,9 +10645,17 @@ bool lb_init_generator(lbGenerator *gen, Checker *c) { if (build_context.out_filepath.len == 0) { gen->output_name = remove_directory_from_path(init_fullpath); 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; } else { 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); if (pos < 0) { gen->output_base = gen->output_name;