mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-30 11:20:08 +00:00
Clean up name mangling by using unique package names per project
This commit is contained in:
+12
-11
@@ -1350,7 +1350,6 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
ptr_set_init(&c->info.minimum_dependency_type_info_set, heap_allocator());
|
||||
|
||||
String required_builtin_entities[] = {
|
||||
str_lit("__mem_zero"),
|
||||
str_lit("__init_context"),
|
||||
|
||||
str_lit("__args__"),
|
||||
@@ -1362,12 +1361,13 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
str_lit("Context"),
|
||||
};
|
||||
for (isize i = 0; i < gb_count_of(required_builtin_entities); i++) {
|
||||
add_dependency_to_set(c, scope_lookup_entity(c->runtime_package->scope, required_builtin_entities[i]));
|
||||
add_dependency_to_set(c, scope_lookup_entity(c->info.runtime_package->scope, required_builtin_entities[i]));
|
||||
}
|
||||
|
||||
AstPackage *mem = get_core_package(&c->info, str_lit("mem"));
|
||||
String required_mem_entities[] = {
|
||||
str_lit("default_allocator"),
|
||||
str_lit("zero"),
|
||||
};
|
||||
for (isize i = 0; i < gb_count_of(required_mem_entities); i++) {
|
||||
add_dependency_to_set(c, scope_lookup_entity(mem->scope, required_mem_entities[i]));
|
||||
@@ -1380,7 +1380,7 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
str_lit("__dynamic_array_expr_error"),
|
||||
};
|
||||
for (isize i = 0; i < gb_count_of(bounds_check_entities); i++) {
|
||||
add_dependency_to_set(c, scope_lookup_entity(c->runtime_package->scope, bounds_check_entities[i]));
|
||||
add_dependency_to_set(c, scope_lookup_entity(c->info.runtime_package->scope, bounds_check_entities[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1500,7 +1500,7 @@ Array<EntityGraphNode *> generate_entity_dependency_graph(CheckerInfo *info) {
|
||||
|
||||
|
||||
Entity *find_core_entity(Checker *c, String name) {
|
||||
Entity *e = current_scope_lookup_entity(c->runtime_package->scope, name);
|
||||
Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name);
|
||||
if (e == nullptr) {
|
||||
compiler_error("Could not find type declaration for '%.*s'\n"
|
||||
"Is '_preload.odin' missing from the 'core' directory relative to odin.exe?", LIT(name));
|
||||
@@ -1510,7 +1510,7 @@ Entity *find_core_entity(Checker *c, String name) {
|
||||
}
|
||||
|
||||
Type *find_core_type(Checker *c, String name) {
|
||||
Entity *e = current_scope_lookup_entity(c->runtime_package->scope, name);
|
||||
Entity *e = current_scope_lookup_entity(c->info.runtime_package->scope, name);
|
||||
if (e == nullptr) {
|
||||
compiler_error("Could not find type declaration for '%.*s'\n"
|
||||
"Is '_preload.odin' missing from the 'core' directory relative to odin.exe?", LIT(name));
|
||||
@@ -2513,10 +2513,11 @@ void check_add_import_decl(Checker *c, AstNodeImportDecl *id) {
|
||||
Scope *scope = *found;
|
||||
GB_ASSERT(scope->is_package && scope->package != nullptr);
|
||||
|
||||
if (scope->is_global) {
|
||||
error(token, "Importing a built-in package is disallowed and unnecessary");
|
||||
return;
|
||||
}
|
||||
// TODO(bill): Should this be allowed or not?
|
||||
// if (scope->is_global) {
|
||||
// error(token, "Importing a runtime package is disallowed and unnecessary");
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (ptr_set_exists(&parent_scope->imported, scope)) {
|
||||
// error(token, "Multiple import of the same file within this scope");
|
||||
@@ -2926,8 +2927,8 @@ void check_parsed_files(Checker *c) {
|
||||
c->info.init_scope = scope;
|
||||
}
|
||||
if (p->kind == Package_Runtime) {
|
||||
GB_ASSERT(c->runtime_package == nullptr);
|
||||
c->runtime_package = p;
|
||||
GB_ASSERT(c->info.runtime_package == nullptr);
|
||||
c->info.runtime_package = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -313,6 +313,8 @@ struct CheckerInfo {
|
||||
Array<Type *> type_info_types;
|
||||
Map<isize> type_info_map; // Key: Type *
|
||||
|
||||
|
||||
AstPackage * runtime_package;
|
||||
Scope * init_scope;
|
||||
Entity * entry_point;
|
||||
PtrSet<Entity *> minimum_dependency_set;
|
||||
@@ -326,7 +328,6 @@ struct Checker {
|
||||
|
||||
|
||||
AstFile * curr_ast_file;
|
||||
AstPackage * runtime_package;
|
||||
// NOTE(bill): Procedures to check
|
||||
Array<ProcedureInfo> procs;
|
||||
Map<Scope *> package_scopes; // Key: String (fullpath)
|
||||
|
||||
+56
-11
@@ -1575,8 +1575,9 @@ void ir_emit_zero_init(irProcedure *p, irValue *address, AstNode *expr) {
|
||||
auto args = array_make<irValue *>(a, 2);
|
||||
args[0] = ir_emit_conv(p, address, t_rawptr);
|
||||
args[1] = ir_const_int(a, type_size_of(t));
|
||||
if (p->entity->token.string != "__mem_zero") {
|
||||
ir_emit_global_call(p, "__mem_zero", args, expr);
|
||||
AstPackage *package = get_core_package(p->module->info, str_lit("mem"));
|
||||
if (p->entity->token.string != "zero" && p->entity->package != package) {
|
||||
ir_emit_package_call(p, "mem", "zero", args, expr);
|
||||
}
|
||||
ir_emit(p, ir_instr_zero_init(p, address));
|
||||
}
|
||||
@@ -1701,7 +1702,10 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, Array<irValue *> args) {
|
||||
|
||||
irValue *ir_emit_global_call(irProcedure *proc, char const *name_, Array<irValue *> args, AstNode *expr) {
|
||||
String name = make_string_c(cast(char *)name_);
|
||||
irValue **found = map_get(&proc->module->members, hash_string(name));
|
||||
|
||||
AstPackage *p = proc->module->info->runtime_package;
|
||||
Entity *e = current_scope_lookup_entity(p->scope, name);
|
||||
irValue **found = map_get(&proc->module->values, hash_entity(e));
|
||||
GB_ASSERT_MSG(found != nullptr, "%.*s", LIT(name));
|
||||
irValue *gp = *found;
|
||||
irValue *call = ir_emit_call(proc, gp, args);
|
||||
@@ -3771,13 +3775,15 @@ void ir_emit_dynamic_array_bounds_check(irProcedure *proc, Token token, irValue
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
String ir_mangle_name(irGen *s, Entity *e) {
|
||||
irModule *m = &s->module;
|
||||
CheckerInfo *info = m->info;
|
||||
gbAllocator a = m->allocator;
|
||||
|
||||
#if 0
|
||||
// NOTE(bill): prefix names not in the init scope
|
||||
// TODO(bill): make robust and not just rely on the file's name
|
||||
String path = e->token.pos.file;
|
||||
String name = e->token.string;
|
||||
irModule *m = &s->module;
|
||||
CheckerInfo *info = m->info;
|
||||
gbAllocator a = m->allocator;
|
||||
AstFile *file = ast_file_of_filename(info, path);
|
||||
|
||||
char *str = gb_alloc_array(a, char, path.len+1);
|
||||
@@ -3825,6 +3831,35 @@ String ir_mangle_name(irGen *s, Entity *e) {
|
||||
}
|
||||
|
||||
return make_string(new_name, new_name_len-1);
|
||||
|
||||
#else
|
||||
GB_ASSERT(e->package != nullptr);
|
||||
String pkg = e->package->name;
|
||||
GB_ASSERT(!rune_is_digit(pkg[0]));
|
||||
|
||||
String name = e->token.string;
|
||||
|
||||
|
||||
isize max_len = pkg.len + 1 + name.len + 1;
|
||||
bool require_suffix_id = is_type_polymorphic(e->type);
|
||||
if (require_suffix_id) {
|
||||
max_len += 21;
|
||||
}
|
||||
|
||||
u8 *new_name = gb_alloc_array(a, u8, max_len);
|
||||
isize new_name_len = gb_snprintf(
|
||||
cast(char *)new_name, max_len,
|
||||
"%.*s.%.*s", LIT(pkg), LIT(name)
|
||||
);
|
||||
if (require_suffix_id) {
|
||||
char *str = cast(char *)new_name + new_name_len-1;
|
||||
isize len = max_len-new_name_len;
|
||||
isize extra = gb_snprintf(str, len, "-%llu", cast(unsigned long long)e->id);
|
||||
new_name_len += extra-1;
|
||||
}
|
||||
|
||||
return make_string(new_name, new_name_len-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -4060,7 +4095,9 @@ irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irV
|
||||
|
||||
|
||||
irValue *ir_find_global_variable(irProcedure *proc, String name) {
|
||||
irValue **value = map_get(&proc->module->members, hash_string(name));
|
||||
AstPackage *pkg = proc->module->info->runtime_package;
|
||||
Entity *e = current_scope_lookup_entity(pkg->scope, name);
|
||||
irValue **value = map_get(&proc->module->values, hash_entity(e));
|
||||
GB_ASSERT_MSG(value != nullptr, "Unable to find global variable '%.*s'", LIT(name));
|
||||
return *value;
|
||||
}
|
||||
@@ -8325,12 +8362,9 @@ void ir_gen_tree(irGen *s) {
|
||||
}
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
|
||||
bool is_global = e->package != nullptr;
|
||||
|
||||
bool is_foreign = e->Variable.is_foreign;
|
||||
bool is_export = e->Variable.is_export;
|
||||
bool no_name_mangle = is_global || e->Variable.link_name.len > 0 || is_foreign || is_export;
|
||||
bool no_name_mangle = e->Variable.link_name.len > 0 || is_foreign || is_export;
|
||||
|
||||
String name = e->token.string;
|
||||
if (!no_name_mangle) {
|
||||
@@ -8401,6 +8435,7 @@ void ir_gen_tree(irGen *s) {
|
||||
|
||||
String original_name = name;
|
||||
|
||||
#if 0
|
||||
if (!package_scope->is_global || polymorphic_struct || is_type_polymorphic(e->type)) {
|
||||
if (e->kind == Entity_Procedure && e->Procedure.is_export) {
|
||||
} else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
|
||||
@@ -8409,6 +8444,16 @@ void ir_gen_tree(irGen *s) {
|
||||
name = ir_mangle_name(s, e);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (e->kind == Entity_Procedure && e->Procedure.is_export) {
|
||||
// Okay
|
||||
} else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
|
||||
// Handle later
|
||||
} else {
|
||||
name = ir_mangle_name(s, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
ir_add_entity_name(m, e, name);
|
||||
|
||||
switch (e->kind) {
|
||||
|
||||
@@ -3886,6 +3886,7 @@ void destroy_ast_file(AstFile *f) {
|
||||
bool init_parser(Parser *p) {
|
||||
GB_ASSERT(p != nullptr);
|
||||
map_init(&p->imported_files, heap_allocator());
|
||||
map_init(&p->package_map, heap_allocator());
|
||||
array_init(&p->packages, heap_allocator());
|
||||
array_init(&p->imports, heap_allocator());
|
||||
gb_mutex_init(&p->file_add_mutex);
|
||||
@@ -3911,6 +3912,7 @@ void destroy_parser(Parser *p) {
|
||||
array_free(&p->packages);
|
||||
array_free(&p->imports);
|
||||
map_destroy(&p->imported_files);
|
||||
map_destroy(&p->package_map);
|
||||
gb_mutex_destroy(&p->file_add_mutex);
|
||||
gb_mutex_destroy(&p->file_decl_mutex);
|
||||
}
|
||||
@@ -4234,6 +4236,20 @@ skip:
|
||||
void parser_add_package(Parser *p, AstPackage *package) {
|
||||
package->id = p->packages.count+1;
|
||||
array_add(&p->packages, package);
|
||||
if (package->name.len > 0) {
|
||||
HashKey key = hash_string(package->name);
|
||||
auto found = map_get(&p->package_map, key);
|
||||
if (found) {
|
||||
GB_ASSERT(package->files.count > 0);
|
||||
AstFile *f = package->files[0];
|
||||
error(f->package_token, "Non-unique package name '%.*s'", LIT(package->name));
|
||||
GB_ASSERT((*found)->files.count > 0);
|
||||
TokenPos pos = (*found)->files[0]->package_token.pos;
|
||||
gb_printf_err("\tpreviously declared at %.*s(%td:%td)", LIT(pos.file), pos.line, pos.column);
|
||||
} else {
|
||||
map_set(&p->package_map, key, package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParseFileError parse_import(Parser *p, ImportedPackage imported_package) {
|
||||
|
||||
@@ -99,6 +99,7 @@ struct AstPackage {
|
||||
struct Parser {
|
||||
String init_fullpath;
|
||||
Map<bool> imported_files; // Key: String (fullpath)
|
||||
Map<AstPackage *> package_map; // Key: String (package name)
|
||||
Array<AstPackage *> packages;
|
||||
Array<ImportedPackage> imports;
|
||||
isize total_token_count;
|
||||
|
||||
+7
-5
@@ -9,9 +9,11 @@ extern "C" {
|
||||
|
||||
|
||||
bool rune_is_letter(Rune r) {
|
||||
if ((r < 0x80 && gb_char_is_alpha(cast(char)r)) ||
|
||||
r == '_') {
|
||||
return true;
|
||||
if (r < 0x80) {
|
||||
if (r == '_') {
|
||||
return true;
|
||||
}
|
||||
return gb_char_is_alpha(cast(char)r) != 0;
|
||||
}
|
||||
switch (utf8proc_category(r)) {
|
||||
case UTF8PROC_CATEGORY_LU:
|
||||
@@ -25,8 +27,8 @@ bool rune_is_letter(Rune r) {
|
||||
}
|
||||
|
||||
bool rune_is_digit(Rune r) {
|
||||
if (r < 0x80 && gb_is_between(r, '0', '9')) {
|
||||
return true;
|
||||
if (r < 0x80) {
|
||||
return gb_is_between(r, '0', '9');
|
||||
}
|
||||
return utf8proc_category(r) == UTF8PROC_CATEGORY_ND;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user