diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 715b29eadd..bcdd839974 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -243,6 +243,11 @@ int emit_asr(const std::string &infile, pass_options.always_run = true; pass_options.verbose = compiler_options.verbose; pass_options.pass_cumulative = compiler_options.pass_cumulative; + pass_options.all_symbols_mangling = compiler_options.all_symbols_mangling; + pass_options.module_name_mangling = compiler_options.module_name_mangling; + pass_options.global_symbols_mangling = compiler_options.global_symbols_mangling; + pass_options.intrinsic_symbols_mangling = compiler_options.intrinsic_symbols_mangling; + pass_manager.apply_passes(al, asr, pass_options, diagnostics); @@ -345,6 +350,10 @@ int emit_c(const std::string &infile, pass_options.run_fun = "f"; pass_options.always_run = true; pass_options.verbose = compiler_options.verbose; + pass_options.all_symbols_mangling = compiler_options.all_symbols_mangling; + pass_options.module_name_mangling = compiler_options.module_name_mangling; + pass_options.global_symbols_mangling = compiler_options.global_symbols_mangling; + pass_options.intrinsic_symbols_mangling = compiler_options.intrinsic_symbols_mangling; pass_manager.apply_passes(al, asr, pass_options, diagnostics); @@ -398,6 +407,10 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, pass_options.run_fun = "f"; pass_options.always_run = true; pass_options.verbose = compiler_options.verbose; + pass_options.all_symbols_mangling = compiler_options.all_symbols_mangling; + pass_options.module_name_mangling = compiler_options.module_name_mangling; + pass_options.global_symbols_mangling = compiler_options.global_symbols_mangling; + pass_options.intrinsic_symbols_mangling = compiler_options.intrinsic_symbols_mangling; pass_manager.apply_passes(al, asr, pass_options, diagnostics); @@ -1501,6 +1514,7 @@ int main(int argc, char *argv[]) bool print_targets = false; bool print_rtl_header_dir = false; bool print_rtl_dir = false; + bool separate_compilation = false; std::string arg_fmt_file; // int arg_fmt_indent = 4; @@ -1579,6 +1593,11 @@ int main(int argc, char *argv[]) app.add_flag("--enable-cpython", compiler_options.enable_cpython, "Enable CPython runtime"); app.add_flag("--enable-symengine", compiler_options.enable_symengine, "Enable Symengine runtime"); app.add_flag("--link-numpy", compiler_options.link_numpy, "Enable NumPy runtime (implies --enable-cpython)"); + app.add_flag("--separate-compilation", separate_compilation, "Generates unique names for all the symbols"); + app.add_flag("--module-mangling", compiler_options.module_name_mangling, "Mangles the module name"); + app.add_flag("--global-mangling", compiler_options.global_symbols_mangling, "Mangles all the global symbols"); + app.add_flag("--intrinsic-mangling", compiler_options.intrinsic_symbols_mangling, "Mangles all the intrinsic symbols"); + app.add_flag("--all-mangling", compiler_options.all_symbols_mangling, "Mangles all possible symbols"); // LSP specific options app.add_flag("--show-errors", show_errors, "Show errors when LSP is running in the background"); @@ -1616,7 +1635,7 @@ int main(int argc, char *argv[]) app.require_subcommand(0, 1); CLI11_PARSE(app, argc, argv); - lcompilers_unique_ID = LCompilers::get_unique_ID(); + lcompilers_unique_ID = separate_compilation ? LCompilers::get_unique_ID(): ""; if( compiler_options.fast && compiler_options.enable_bounds_checking ) { diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index fcd1ea6af3..bac6d4aa74 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -62,6 +62,7 @@ set(SRC pass/pass_array_by_data.cpp pass/pass_list_expr.cpp pass/pass_compare.cpp + pass/unique_symbols.cpp asr_verify.cpp asr_utils.cpp diff --git a/src/libasr/asr_scopes.cpp b/src/libasr/asr_scopes.cpp index 91fe330963..a47eba63d2 100644 --- a/src/libasr/asr_scopes.cpp +++ b/src/libasr/asr_scopes.cpp @@ -4,8 +4,8 @@ #include #include -std::string lcompilers_unique_ID; +std::string lcompilers_unique_ID; namespace LCompilers { template< typename T > @@ -53,6 +53,7 @@ void SymbolTable::mark_all_variables_external(Allocator &al) { } } + ASR::symbol_t *SymbolTable::find_scoped_symbol(const std::string &name, size_t n_scope_names, char **m_scope_names) { const SymbolTable *s = this; @@ -84,7 +85,7 @@ ASR::symbol_t *SymbolTable::find_scoped_symbol(const std::string &name, std::string SymbolTable::get_unique_name(const std::string &name, bool use_unique_id) { std::string unique_name = name; - if( use_unique_id ) { + if( use_unique_id && !lcompilers_unique_ID.empty()) { unique_name += "_" + lcompilers_unique_ID; } int counter = 1; diff --git a/src/libasr/gen_pass.py b/src/libasr/gen_pass.py index 560ea4d71d..428565cde3 100644 --- a/src/libasr/gen_pass.py +++ b/src/libasr/gen_pass.py @@ -32,6 +32,7 @@ "unused_functions", "update_array_dim_intrinsic_calls", "replace_where", + "unique_symbols", ] diff --git a/src/libasr/pass/pass_manager.h b/src/libasr/pass/pass_manager.h index 801719367f..80f21c2c21 100644 --- a/src/libasr/pass/pass_manager.h +++ b/src/libasr/pass/pass_manager.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,8 @@ namespace LCompilers { {"init_expr", &pass_replace_init_expr}, {"nested_vars", &pass_nested_vars}, {"where", &pass_replace_where}, - {"print_struct_type", &pass_replace_print_struct_type} + {"print_struct_type", &pass_replace_print_struct_type}, + {"unique_symbols", &pass_unique_symbols} }; bool is_fast; @@ -213,7 +215,8 @@ namespace LCompilers { "select_case", "inline_function_calls", "unused_functions", - "transform_optional_argument_functions" + "transform_optional_argument_functions", + "unique_symbols" }; _with_optimization_passes = { @@ -244,7 +247,8 @@ namespace LCompilers { "div_to_mul", "fma", "transform_optional_argument_functions", - "inline_function_calls" + "inline_function_calls", + "unique_symbols" }; // These are re-write passes which are already handled diff --git a/src/libasr/pass/unique_symbols.cpp b/src/libasr/pass/unique_symbols.cpp new file mode 100644 index 0000000000..30578fb605 --- /dev/null +++ b/src/libasr/pass/unique_symbols.cpp @@ -0,0 +1,627 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +extern std::string lcompilers_unique_ID; + +/* +ASR pass for replacing symbol names with some new name, mostly because +we want to generate unique symbols for each generated ASR output +so that it doesn't give linking errors for the generated backend code like C. + +This is done using two classes: +1. SymbolRenameVisitor - This captures symbols to be renamed based on the options + provided: + 1.1: module_name_mangling - Mangles the module name. + 1.2: global_symbols_mangling - Mangles all the global symbols. + 1.3: intrinsic_symbols_mangling - Mangles all the intrinsic symbols. + 1.4: all_symbols_mangling - Mangles all possible symbols. + + Note: this skips BindC functions and symbols starting with `_lpython` or `_lfortran` + +2. UniqueSymbolVisitor: Renames all the captured symbols from SymbolRenameVisitor. +*/ +namespace LCompilers { + +using ASR::down_cast; + +class SymbolRenameVisitor: public ASR::BaseWalkVisitor { + public: + std::unordered_map sym_to_renamed; + bool module_name_mangling; + bool global_symbols_mangling; + bool intrinsic_symbols_mangling; + bool all_symbols_mangling; + bool should_mangle = false; + + SymbolRenameVisitor( + bool mm, bool gm, bool im, bool am) : module_name_mangling(mm), + global_symbols_mangling(gm), intrinsic_symbols_mangling(im), + all_symbols_mangling(am){} + + + std::string update_name(std::string curr_name) { + if (startswith(curr_name, "_lpython") || startswith(curr_name, "_lfortran") ) { + return curr_name; + } + return curr_name + "_" + lcompilers_unique_ID; + } + + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + ASR::TranslationUnit_t& xx = const_cast(x); + std::unordered_map tmp_scope; + for (auto &a : xx.m_global_scope->get_scope()) { + visit_symbol(*a.second); + } + } + + void visit_Program(const ASR::Program_t &x) { + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + } + + void visit_Module(const ASR::Module_t &x) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + bool should_mangle_copy = should_mangle; + if (all_symbols_mangling || module_name_mangling || should_mangle) { + sym_to_renamed[sym] = update_name(x.m_name); + } + if ((x.m_intrinsic && intrinsic_symbols_mangling) || + (global_symbols_mangling && startswith(x.m_name, "_global_symbols"))) { + should_mangle = true; + } + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + should_mangle = should_mangle_copy; + } + + void visit_Function(const ASR::Function_t &x) { + ASR::FunctionType_t *f_type = ASRUtils::get_FunctionType(x); + if (f_type->m_abi != ASR::abiType::BindC) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (all_symbols_mangling || should_mangle) { + sym_to_renamed[sym] = update_name(x.m_name); + } + } + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + } + + void visit_GenericProcedure(const ASR::GenericProcedure_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + + void visit_CustomOperator(const ASR::CustomOperator_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + + void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + + void visit_StructType(const ASR::StructType_t &x) { + if (x.m_abi != ASR::abiType::BindC) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_EnumType(const ASR::EnumType_t &x) { + if (x.m_abi != ASR::abiType::BindC) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_UnionType(const ASR::UnionType_t &x) { + if (x.m_abi != ASR::abiType::BindC) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_Variable(const ASR::Variable_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + + void visit_ClassType(const ASR::ClassType_t &x) { + if (x.m_abi != ASR::abiType::BindC) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_ClassProcedure(const ASR::ClassProcedure_t &x) { + if (x.m_abi != ASR::abiType::BindC) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + } + } + + void visit_AssociateBlock(const ASR::AssociateBlock_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_Block(const ASR::Block_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_Requirement(const ASR::Requirement_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + + void visit_Template(const ASR::Template_t &x) { + if (all_symbols_mangling || should_mangle) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + sym_to_renamed[sym] = update_name(x.m_name); + } + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + } + +}; + + +class UniqueSymbolVisitor: public ASR::BaseWalkVisitor { + private: + + Allocator& al; + + public: + std::unordered_map& sym_to_new_name; + std::map current_scope; + + UniqueSymbolVisitor(Allocator& al_, + std::unordered_map &sn) : al(al_), sym_to_new_name(sn){} + + + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + ASR::TranslationUnit_t& xx = const_cast(x); + std::map current_scope_copy = current_scope; + current_scope = x.m_global_scope->get_scope(); + for (auto &a : xx.m_global_scope->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_global_scope->erase_symbol(a.first); + xx.m_global_scope->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Program(const ASR::Program_t &x) { + ASR::Program_t& xx = const_cast(x); + std::map current_scope_copy = current_scope; + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + for (size_t i=0; iget_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Module(const ASR::Module_t &x) { + ASR::Module_t& xx = const_cast(x); + std::map current_scope_copy = current_scope; + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + for (size_t i=0; iget_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Function(const ASR::Function_t &x) { + ASR::Function_t& xx = const_cast(x); + std::map current_scope_copy = current_scope; + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + for (size_t i=0; iget_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_GenericProcedure(const ASR::GenericProcedure_t &x) { + ASR::GenericProcedure_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + } + + void visit_CustomOperator(const ASR::CustomOperator_t &x) { + ASR::CustomOperator_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + } + + void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { + ASR::ExternalSymbol_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + SymbolTable* s = ASRUtils::symbol_parent_symtab(x.m_external); + ASR::symbol_t *asr_owner = ASR::down_cast(s->asr_owner); + if (sym_to_new_name.find(x.m_external) != sym_to_new_name.end()) { + xx.m_original_name = s2c(al, sym_to_new_name[x.m_external]); + } + if (sym_to_new_name.find(asr_owner) != sym_to_new_name.end()) { + xx.m_module_name = s2c(al, sym_to_new_name[asr_owner]); + } + } + + void visit_StructType(const ASR::StructType_t &x) { + ASR::StructType_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + for (size_t i=0; iget_scope(); + for (size_t i=0; iget_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_EnumType(const ASR::EnumType_t &x) { + ASR::EnumType_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + for (size_t i=0; iget_scope(); + for (size_t i=0; iget_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_UnionType(const ASR::UnionType_t &x) { + ASR::UnionType_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + for (size_t i=0; iget_scope(); + for (size_t i=0; iget_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Variable(const ASR::Variable_t &x) { + ASR::Variable_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + for (size_t i=0; i(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + current_scope = x.m_symtab->get_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_ClassProcedure(const ASR::ClassProcedure_t &x) { + ASR::ClassProcedure_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + } + + void visit_AssociateBlock(const ASR::AssociateBlock_t &x) { + ASR::AssociateBlock_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + current_scope = x.m_symtab->get_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Block(const ASR::Block_t &x) { + ASR::Block_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + current_scope = x.m_symtab->get_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Requirement(const ASR::Requirement_t &x) { + ASR::Requirement_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + current_scope = x.m_symtab->get_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Template(const ASR::Template_t &x) { + ASR::Template_t& xx = const_cast(x); + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + if (sym_to_new_name.find(sym) != sym_to_new_name.end()) { + xx.m_name = s2c(al, sym_to_new_name[sym]); + } + std::map current_scope_copy = current_scope; + current_scope = x.m_symtab->get_scope(); + for (auto &a : x.m_symtab->get_scope()) { + visit_symbol(*a.second); + } + for (auto &a: current_scope) { + if (sym_to_new_name.find(a.second) != sym_to_new_name.end()) { + xx.m_symtab->erase_symbol(a.first); + xx.m_symtab->add_symbol(sym_to_new_name[a.second], a.second); + } + } + current_scope = current_scope_copy; + } + +}; + + +void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& pass_options) { + bool any_present = (pass_options.module_name_mangling || pass_options.global_symbols_mangling || + pass_options.intrinsic_symbols_mangling || pass_options.all_symbols_mangling); + if (!any_present || lcompilers_unique_ID.empty()) { + return; + } + SymbolRenameVisitor v(pass_options.module_name_mangling, + pass_options.global_symbols_mangling, + pass_options.intrinsic_symbols_mangling, + pass_options.all_symbols_mangling); + v.visit_TranslationUnit(unit); + UniqueSymbolVisitor u(al, v.sym_to_renamed); + u.visit_TranslationUnit(unit); + PassUtils::UpdateDependenciesVisitor x(al); + x.visit_TranslationUnit(unit); +} + + +} // namespace LCompilers diff --git a/src/libasr/pass/unique_symbols.h b/src/libasr/pass/unique_symbols.h new file mode 100644 index 0000000000..4d69b71a38 --- /dev/null +++ b/src/libasr/pass/unique_symbols.h @@ -0,0 +1,14 @@ +#ifndef LIBASR_PASS_UNIQUE_SYMBOLS_H +#define LIBASR_PASS_UNIQUE_SYMBOLS_H + +#include +#include + +namespace LCompilers { + + void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit, + const PassOptions &pass_options); + +} // namespace LCompilers + +#endif // LIBASR_PASS_UNIQUE_SYMBOLS_H diff --git a/src/libasr/utils.h b/src/libasr/utils.h index 39f3422f05..768d689fa8 100644 --- a/src/libasr/utils.h +++ b/src/libasr/utils.h @@ -64,6 +64,10 @@ struct CompilerOptions { bool enable_cpython = false; bool enable_symengine = false; bool link_numpy = false; + bool module_name_mangling = false; + bool global_symbols_mangling = false; + bool intrinsic_symbols_mangling = false; + bool all_symbols_mangling = false; std::vector import_paths; Platform platform; @@ -93,6 +97,10 @@ namespace LCompilers { bool verbose = false; // For developer debugging bool pass_cumulative = false; // Apply passes cumulatively bool disable_main = false; + bool module_name_mangling = false; + bool global_symbols_mangling = false; + bool intrinsic_symbols_mangling = false; + bool all_symbols_mangling = false; }; }