Browse Source

Fix rules for recursive initialization with procedure entities; Fix executable name if not given

gingerBill 5 years ago
parent
commit
84fd40de77
4 changed files with 105 additions and 16 deletions
  1. 88 15
      src/checker.cpp
  2. 1 1
      src/entity.cpp
  3. 8 0
      src/ir.cpp
  4. 8 0
      src/llvm_backend.cpp

+ 88 - 15
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;
+				}
 			}
 		}
 	}

+ 1 - 1
src/entity.cpp

@@ -66,7 +66,7 @@ enum EntityFlag : u32 {
 
 enum EntityState {
 	EntityState_Unresolved = 0,
-	EntityState_InProgress  = 1,
+	EntityState_InProgress = 1,
 	EntityState_Resolved   = 2,
 };
 

+ 8 - 0
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;

+ 8 - 0
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;