aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-05-30 12:23:41 +0100
committergingerBill <bill@gingerbill.org>2020-05-30 12:23:41 +0100
commit84fd40de77deb71544fce7c3c34177ee2f9c4405 (patch)
tree0f2c55f474c411343a6668b5c9af9791e8de8963 /src/checker.cpp
parent1d7f99cbdf28236e8d55e7c36ec14c693d139f3f (diff)
Fix rules for recursive initialization with procedure entities; Fix executable name if not given
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp103
1 files changed, 88 insertions, 15 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<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) {
+#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<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");
// 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<EntityGraphNode *> 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<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_ = {};
bool made_visited = false;
if (visited == nullptr) {
@@ -4001,17 +4061,30 @@ Array<Entity *> find_entity_path(Entity *start, Entity *end, Map<Entity *> *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<Entity *>(heap_allocator());
- array_add(&path, dep);
+ if (start->kind == Entity_Procedure) {
+ Type *t = base_type(start->type);
+ GB_ASSERT(t->kind == Type_Proc);
+
+ Array<Entity *> 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<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;
+ }
}
}
}