From 2022a7615aeb476521ad4eac168b2cdc231ba931 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 12 Jun 2023 14:10:18 +0100 Subject: Make all id suffixes use atomics where possible --- src/llvm_backend_general.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index e5f3e3081..176e53042 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1426,7 +1426,7 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur if (p != nullptr) { isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1; char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); - u32 guid = ++p->module->nested_type_name_guid; + u32 guid = 1+p->module->nested_type_name_guid.fetch_add(1); name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%u", LIT(p->name), LIT(ts_name), guid); String name = make_string(cast(u8 *)name_text, name_len-1); @@ -1436,9 +1436,8 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur // NOTE(bill): a nested type be required before its parameter procedure exists. Just give it a temp name for now isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1; char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); - static u32 guid = 0; - guid += 1; - name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), guid); + static std::atomic guid; + name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), 1+guid.fetch_add(1)); String name = make_string(cast(u8 *)name_text, name_len-1); e->TypeName.ir_mangled_name = name; -- cgit v1.2.3 From 581eebb197cc9905248d59a084a68bd2e64c9830 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 13 Jun 2023 13:14:59 +0100 Subject: Fix a race condition when produced anonymous procedure literals with `-use-separate-modules` --- src/checker.hpp | 3 ++ src/llvm_backend.cpp | 53 +------------------------ src/llvm_backend.hpp | 4 +- src/llvm_backend_const.cpp | 1 + src/llvm_backend_general.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 99 insertions(+), 55 deletions(-) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/checker.hpp b/src/checker.hpp index 1a95e2772..b06d0a8f9 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -199,6 +199,9 @@ struct DeclInfo { BlockingMutex type_and_value_mutex; Array labels; + + // NOTE(bill): this is to prevent a race condition since these procedure literals can be created anywhere at any time + struct lbModule *code_gen_module; }; // ProcInfo stores the information needed for checking a procedure diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 525ac8a9d..730610ad9 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -772,56 +772,6 @@ gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) { return {p->value, p->type}; } - -gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) { - mutex_lock(&m->gen->anonymous_proc_lits_mutex); - defer (mutex_unlock(&m->gen->anonymous_proc_lits_mutex)); - - lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, expr); - if (found) { - return lb_find_procedure_value_from_entity(m, (*found)->entity); - } - - ast_node(pl, ProcLit, expr); - - // NOTE(bill): Generate a new name - // parent$count - isize name_len = prefix_name.len + 6 + 11; - char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); - static std::atomic name_id; - name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), 1+name_id.fetch_add(1)); - String name = make_string((u8 *)name_text, name_len-1); - - Type *type = type_of_expr(expr); - - Token token = {}; - token.pos = ast_token(expr).pos; - token.kind = Token_Ident; - token.string = name; - Entity *e = alloc_entity_procedure(nullptr, token, type, pl->tags); - e->file = expr->file(); - e->decl_info = pl->decl; - e->code_gen_module = m; - e->flags |= EntityFlag_ProcBodyChecked; - lbProcedure *p = lb_create_procedure(m, e); - - lbValue value = {}; - value.value = p->value; - value.type = p->type; - - array_add(&m->procedures_to_generate, p); - if (parent != nullptr) { - array_add(&parent->children, p); - } else { - string_map_set(&m->members, name, value); - } - - map_set(&m->gen->anonymous_proc_lits, expr, p); - - return value; -} - - gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) { lbAddr *found = map_get(&m->map_cell_info_map, type); if (found) { @@ -1513,7 +1463,7 @@ gb_internal WORKER_TASK_PROC(lb_generate_missing_procedures_to_check_worker_proc lbModule *m = cast(lbModule *)data; for (isize i = 0; i < m->missing_procedures_to_check.count; i++) { lbProcedure *p = m->missing_procedures_to_check[i]; - debugf("Generate missing procedure: %.*s\n", LIT(p->name)); + debugf("Generate missing procedure: %.*s module %p\n", LIT(p->name), m); lb_generate_procedure(m, p); } return 0; @@ -1577,7 +1527,6 @@ gb_internal void lb_llvm_module_passes(lbGenerator *gen, bool do_threading) { thread_pool_wait(); } - gb_internal String lb_filepath_ll_for_module(lbModule *m) { String path = concatenate3_strings(permanent_allocator(), build_context.build_paths[BuildPath_Output].basename, diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 6e785d492..3aa13b488 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -201,7 +201,7 @@ struct lbGenerator { PtrMap modules_through_ctx; lbModule default_module; - BlockingMutex anonymous_proc_lits_mutex; + RecursiveMutex anonymous_proc_lits_mutex; PtrMap anonymous_proc_lits; BlockingMutex foreign_mutex; @@ -545,6 +545,8 @@ gb_internal gb_inline i64 lb_max_zero_init_size(void) { gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type); gb_internal LLVMTypeRef OdinLLVMGetVectorElementType(LLVMTypeRef type); +gb_internal String lb_filepath_ll_for_module(lbModule *m); + #define LB_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime" #define LB_CLEANUP_RUNTIME_PROC_NAME "__$cleanup_runtime" #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info" diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index c9d2f5b26..efe1e4d45 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -473,6 +473,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo if (value.kind == ExactValue_Procedure) { lbValue res = {}; Ast *expr = unparen_expr(value.value_procedure); + GB_ASSERT(expr != nullptr); if (expr->kind == Ast_ProcLit) { res = lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr); } else { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 176e53042..9333f13a4 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -334,10 +334,35 @@ gb_internal bool lb_is_instr_terminating(LLVMValueRef instr) { return false; } +gb_internal lbModule *lb_module_of_expr(lbGenerator *gen, Ast *expr) { + GB_ASSERT(expr != nullptr); + lbModule **found = nullptr; + AstFile *file = expr->file(); + if (file) { + found = map_get(&gen->modules, cast(void *)file); + if (found) { + return *found; + } + + if (file->pkg) { + found = map_get(&gen->modules, cast(void *)file->pkg); + if (found) { + return *found; + } + } + } + + return &gen->default_module; +} gb_internal lbModule *lb_module_of_entity(lbGenerator *gen, Entity *e) { GB_ASSERT(e != nullptr); lbModule **found = nullptr; + if (e->kind == Entity_Procedure && + e->decl_info && + e->decl_info->code_gen_module) { + return e->decl_info->code_gen_module; + } if (e->file) { found = map_get(&gen->modules, cast(void *)e->file); if (found) { @@ -2661,9 +2686,12 @@ gb_internal lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *e gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) { + lbGenerator *gen = m->gen; + GB_ASSERT(is_type_proc(e->type)); e = strip_entity_wrapping(e); GB_ASSERT(e != nullptr); + GB_ASSERT(e->kind == Entity_Procedure); lbValue *found = nullptr; rw_mutex_shared_lock(&m->values_mutex); @@ -2677,20 +2705,24 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) lbModule *other_module = m; if (USE_SEPARATE_MODULES) { - other_module = lb_module_of_entity(m->gen, e); + other_module = lb_module_of_entity(gen, e); } if (other_module == m) { - debugf("Missing Procedure (lb_find_procedure_value_from_entity): %.*s\n", LIT(e->token.string)); + debugf("Missing Procedure (lb_find_procedure_value_from_entity): %.*s module %p\n", LIT(e->token.string), m); } ignore_body = other_module != m; lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body); if (ignore_body) { + mutex_lock(&gen->anonymous_proc_lits_mutex); + defer (mutex_unlock(&gen->anonymous_proc_lits_mutex)); + GB_ASSERT(other_module != nullptr); rw_mutex_shared_lock(&other_module->values_mutex); auto *found = map_get(&other_module->values, e); rw_mutex_shared_unlock(&other_module->values_mutex); if (found == nullptr) { + // THIS IS THE RACE CONDITION lbProcedure *missing_proc_in_other_module = lb_create_procedure(other_module, e, false); array_add(&other_module->missing_procedures_to_check, missing_proc_in_other_module); } @@ -2707,6 +2739,63 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) } + +gb_internal lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) { + lbGenerator *gen = m->gen; + + mutex_lock(&gen->anonymous_proc_lits_mutex); + defer (mutex_unlock(&gen->anonymous_proc_lits_mutex)); + + TokenPos pos = ast_token(expr).pos; + lbProcedure **found = map_get(&gen->anonymous_proc_lits, expr); + if (found) { + return lb_find_procedure_value_from_entity(m, (*found)->entity); + } + + ast_node(pl, ProcLit, expr); + + // NOTE(bill): Generate a new name + // parent$count + isize name_len = prefix_name.len + 6 + 11; + char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); + static std::atomic name_id; + name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), 1+name_id.fetch_add(1)); + String name = make_string((u8 *)name_text, name_len-1); + + Type *type = type_of_expr(expr); + + GB_ASSERT(pl->decl->entity == nullptr); + Token token = {}; + token.pos = ast_token(expr).pos; + token.kind = Token_Ident; + token.string = name; + Entity *e = alloc_entity_procedure(nullptr, token, type, pl->tags); + e->file = expr->file(); + + // NOTE(bill): this is to prevent a race condition since these procedure literals can be created anywhere at any time + pl->decl->code_gen_module = m; + e->decl_info = pl->decl; + pl->decl->entity = e; + e->flags |= EntityFlag_ProcBodyChecked; + + lbProcedure *p = lb_create_procedure(m, e); + GB_ASSERT(e->code_gen_module == m); + + lbValue value = {}; + value.value = p->value; + value.type = p->type; + + map_set(&gen->anonymous_proc_lits, expr, p); + array_add(&m->procedures_to_generate, p); + if (parent != nullptr) { + array_add(&parent->children, p); + } else { + string_map_set(&m->members, name, value); + } + return value; +} + + gb_internal lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value, Entity **entity_) { GB_ASSERT(type != nullptr); type = default_type(type); -- cgit v1.2.3 From 8b8310711e4924678e605278fca1f8dbf517b903 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 26 Jun 2023 17:36:27 +0100 Subject: Fix #2594 zero sized union code generation --- src/llvm_backend.cpp | 4 +++- src/llvm_backend_general.cpp | 1 + src/llvm_backend_type.cpp | 5 ++--- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 730610ad9..12abe7b16 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -218,7 +218,9 @@ gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) { LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 0, false)); } else if (type->kind == Type_Union) { - if (is_type_union_maybe_pointer(type)) { + if (type_size_of(type) == 0) { + LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false)); + } else if (is_type_union_maybe_pointer(type)) { Type *v = type->Union.variants[0]; Type *pv = alloc_type_pointer(v); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 9333f13a4..017eeca2e 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1323,6 +1323,7 @@ gb_internal lbValue lb_emit_union_tag_value(lbProcedure *p, lbValue u) { gb_internal void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *variant_type) { Type *t = type_deref(parent.type); + GB_ASSERT(is_type_union(t)); if (is_type_union_maybe_pointer(t) || type_size_of(t) == 0) { // No tag needed! diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index a54fde748..4716733cc 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -654,10 +654,9 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup lbValue count = lb_const_int(m, t_int, variant_count); vals[0] = llvm_const_slice(m, memory_types, count); - i64 tag_size = union_tag_size(t); - i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size); - + i64 tag_size = union_tag_size(t); if (tag_size > 0) { + i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size); vals[1] = lb_const_int(m, t_uintptr, tag_offset).value; vals[2] = lb_type_info(m, union_tag_type(t)).value; } else { -- cgit v1.2.3 From 1ff6212ffa32c42be86ee80292401f860435b443 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 7 Jul 2023 22:28:31 +0100 Subject: Always call `lb_run_remove_dead_instruction_pass` to fix `-debug` issues --- src/llvm_backend_general.cpp | 5 +++-- src/llvm_backend_opt.cpp | 10 ---------- 2 files changed, 3 insertions(+), 12 deletions(-) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 017eeca2e..676069120 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -3004,8 +3004,9 @@ gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block); char const *name = ""; - if (e != nullptr) { - // name = alloc_cstring(permanent_allocator(), e->token.string); + if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") { + // NOTE(bill): for debugging purposes only + name = alloc_cstring(permanent_allocator(), e->token.string); } LLVMTypeRef llvm_type = lb_type(p->module, type); diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 141ee88c7..54e667a0b 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -375,16 +375,6 @@ gb_internal void lb_run_function_pass_manager(LLVMPassManagerRef fpm, lbProcedur return; } LLVMRunFunctionPassManager(fpm, p->value); - switch (pass_manager_kind) { - case lbFunctionPassManager_none: - return; - case lbFunctionPassManager_default: - case lbFunctionPassManager_default_without_memcpy: - if (build_context.optimization_level < 0) { - return; - } - break; - } // NOTE(bill): LLVMAddDCEPass doesn't seem to be exported in the official DLL's for LLVM // which means we cannot rely upon it // This is also useful for read the .ll for debug purposes because a lot of instructions -- cgit v1.2.3 From 62031c24a2afeb9dd15a85e3e15a78860900be6a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 7 Jul 2023 23:35:16 +0100 Subject: Add extra mutex guards around module value access --- src/llvm_backend_general.cpp | 3 +++ src/llvm_backend_stmt.cpp | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 676069120..f0bbaafb7 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2730,7 +2730,10 @@ gb_internal lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) } else { array_add(&m->missing_procedures_to_check, missing_proc); } + + rw_mutex_shared_lock(&m->values_mutex); found = map_get(&m->values, e); + rw_mutex_shared_unlock(&m->values_mutex); if (found) { return *found; } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index ae6adb0e2..60420402a 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1878,7 +1878,9 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice const &return } else if (return_count == 1) { Entity *e = tuple->variables[0]; if (res_count == 0) { + rw_mutex_shared_lock(&p->module->values_mutex); lbValue found = map_must_get(&p->module->values, e); + rw_mutex_shared_unlock(&p->module->values_mutex); res = lb_emit_load(p, found); } else { res = lb_build_expr(p, return_results[0]); @@ -1887,7 +1889,9 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice const &return if (p->type->Proc.has_named_results) { // NOTE(bill): store the named values before returning if (e->token.string != "") { + rw_mutex_shared_lock(&p->module->values_mutex); lbValue found = map_must_get(&p->module->values, e); + rw_mutex_shared_unlock(&p->module->values_mutex); lb_emit_store(p, found, lb_emit_conv(p, res, e->type)); } } @@ -1903,7 +1907,9 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice const &return } else { for (isize res_index = 0; res_index < return_count; res_index++) { Entity *e = tuple->variables[res_index]; + rw_mutex_shared_lock(&p->module->values_mutex); lbValue found = map_must_get(&p->module->values, e); + rw_mutex_shared_unlock(&p->module->values_mutex); lbValue res = lb_emit_load(p, found); array_add(&results, res); } @@ -1925,7 +1931,9 @@ gb_internal void lb_build_return_stmt(lbProcedure *p, Slice const &return if (e->token.string == "") { continue; } + rw_mutex_shared_lock(&p->module->values_mutex); named_results[i] = map_must_get(&p->module->values, e); + rw_mutex_shared_unlock(&p->module->values_mutex); values[i] = lb_emit_conv(p, results[i], e->type); } -- cgit v1.2.3 From 3072479c3c3c4818b0a41dc2aed288e8b3ec0582 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 7 Jul 2023 23:52:56 +0100 Subject: Generalize name mangling rule to have a singular definition for a name separator --- src/llvm_backend.hpp | 2 ++ src/llvm_backend_general.cpp | 6 +++--- src/llvm_backend_proc.cpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/llvm_backend_general.cpp') diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 3aa13b488..ce01485ff 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -346,6 +346,8 @@ struct lbProcedure { }; +#define ABI_PKG_NAME_SEPARATOR "." + #if !ODIN_LLVM_MINIMUM_VERSION_14 #define LLVMConstGEP2(Ty__, ConstantVal__, ConstantIndices__, NumIndices__) LLVMConstGEP(ConstantVal__, ConstantIndices__, NumIndices__) diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f0bbaafb7..ad8a1816a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1403,7 +1403,7 @@ gb_internal String lb_mangle_name(lbModule *m, Entity *e) { char *new_name = gb_alloc_array(permanent_allocator(), char, max_len); isize new_name_len = gb_snprintf( new_name, max_len, - "%.*s.%.*s", LIT(pkgn), LIT(name) + "%.*s" ABI_PKG_NAME_SEPARATOR "%.*s", LIT(pkgn), LIT(name) ); if (require_suffix_id) { char *str = new_name + new_name_len-1; @@ -1453,7 +1453,7 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1; char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); u32 guid = 1+p->module->nested_type_name_guid.fetch_add(1); - name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%u", LIT(p->name), LIT(ts_name), guid); + name_len = gb_snprintf(name_text, name_len, "%.*s" ABI_PKG_NAME_SEPARATOR "%.*s-%u", LIT(p->name), LIT(ts_name), guid); String name = make_string(cast(u8 *)name_text, name_len-1); e->TypeName.ir_mangled_name = name; @@ -1463,7 +1463,7 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1; char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); static std::atomic guid; - name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), 1+guid.fetch_add(1)); + name_len = gb_snprintf(name_text, name_len, "_internal" ABI_PKG_NAME_SEPARATOR "%.*s-%u", LIT(ts_name), 1+guid.fetch_add(1)); String name = make_string(cast(u8 *)name_text, name_len-1); e->TypeName.ir_mangled_name = name; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 42ca90828..c27c55337 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -757,7 +757,7 @@ gb_internal void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) char *name_text = gb_alloc_array(permanent_allocator(), char, name_len); i32 guid = cast(i32)p->children.count; - name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid); + name_len = gb_snprintf(name_text, name_len, "%.*s" ABI_PKG_NAME_SEPARATOR "%.*s-%d", LIT(p->name), LIT(pd_name), guid); String name = make_string(cast(u8 *)name_text, name_len-1); e->Procedure.link_name = name; -- cgit v1.2.3