Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implemented mangling for c back-end as per issue #2359 . #2546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,8 @@ RUN(NAME callback_03 LABELS cpython llvm c)

RUN(NAME lambda_01 LABELS cpython llvm)

RUN(NAME c_mangling LABELS cpython llvm c)

# callback_04 is to test emulation. So just run with cpython
RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython)

Expand Down
23 changes: 23 additions & 0 deletions integration_tests/c_mangling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
def f():
int : str
int = "abc"
print(int)

char : str
char = "char_variable"
print(char)

void : str
void = "void_variable"
print(void)

auto : str
auto = "auto_variable"
print(auto)


case : str
case = "case_variable"
print(case)

f()
2 changes: 2 additions & 0 deletions src/bin/lpython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,7 @@ int main(int argc, char *argv[])
return emit_cpp(arg_file, runtime_library_dir, compiler_options);
}
if (show_c) {
compiler_options.po.c_mangling = true;
return emit_c(arg_file, runtime_library_dir, lpython_pass_manager,
compiler_options);
}
Expand Down Expand Up @@ -1917,6 +1918,7 @@ int main(int argc, char *argv[])
err = compile_to_binary_wasm_to_x86(arg_file, outfile,
runtime_library_dir, compiler_options, time_report, backend);
} else if (backend == Backend::c) {
compiler_options.po.c_mangling = true;
std::string emit_file_name = basename + "__tmp__generated__.c";
err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir,
lpython_pass_manager, compiler_options);
Expand Down
49 changes: 42 additions & 7 deletions src/libasr/pass/unique_symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <libasr/pass/pass_utils.h>
#include <unordered_map>
#include <set>

#include<unordered_set>

extern std::string lcompilers_unique_ID;

Expand Down Expand Up @@ -46,15 +46,28 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
bool all_symbols_mangling;
bool bindc_mangling = false;
bool fortran_mangling;
bool c_mangling;
bool should_mangle = false;
std::vector<std::string> parent_function_name;
std::string module_name = "";
SymbolTable* current_scope = nullptr;

SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm) :
SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm, bool cm) :
module_name_mangling(mm), global_symbols_mangling(gm), intrinsic_symbols_mangling(im),
all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) {}
all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) , c_mangling(cm){}


const std::unordered_set<std::string> reserved_keywords_c = {
"_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", "break", "case", "char", "_Bool", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"
};

//TODO: Implement other backends mangling when refactoring the pass infrastructure
void mangle_c(ASR::symbol_t* sym, const std::string& name){
if (reserved_keywords_c.find(name) != reserved_keywords_c.end()) {
sym_to_renamed[sym] = "_xx_"+std::string(name)+"_xx_";
}
return;
}

std::string update_name(std::string curr_name) {
if (startswith(curr_name, "_lpython") || startswith(curr_name, "_lfortran") ) {
Expand Down Expand Up @@ -147,7 +160,11 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
sym_to_renamed[sym] = current_scope->parent->get_unique_name(
"f" + std::string(x.m_name));
}
}
}
}
if ( c_mangling ) {
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
mangle_c(sym , std::string(x.m_name));
}
for (auto &a : x.m_symtab->get_scope()) {
bool nested_function = is_nested_function(a.second);
Expand Down Expand Up @@ -178,6 +195,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
std::string(x.m_name));
}
}

if ( c_mangling ) {
mangle_c(sym , std::string(x.m_name));
}
}

void visit_GenericProcedure(const ASR::GenericProcedure_t &x) {
Expand All @@ -204,6 +225,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
sym_to_renamed[sym] = update_name(x.m_name);
}
}
if ( c_mangling ) {
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
mangle_c(sym , std::string(x.m_name));
}
for (auto &a : x.m_symtab->get_scope()) {
this->visit_symbol(*a.second);
}
Expand Down Expand Up @@ -232,6 +257,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
sym_to_renamed[sym] = update_name(x.m_name);
}
}
if (c_mangling ) {
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
mangle_c(sym , std::string(x.m_name));
}
}

template <typename T>
Expand All @@ -240,6 +269,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
sym_to_renamed[sym] = update_name(x.m_name);
}
if ( c_mangling ) {
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
mangle_c(sym , std::string(x.m_name));
}
for (auto &a : x.m_symtab->get_scope()) {
this->visit_symbol(*a.second);
}
Expand Down Expand Up @@ -521,8 +554,9 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit,
if (pass_options.mangle_underscore) {
lcompilers_unique_ID = "";
}
if (!any_present || (!(pass_options.mangle_underscore ||
pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) {
if ((!any_present || (!(pass_options.mangle_underscore ||
pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) &&
!pass_options.c_mangling) {
// `--mangle-underscore` doesn't require `lcompilers_unique_ID`
// `lcompilers_unique_ID` is not mandatory for `--apply-fortran-mangling`
return;
Expand All @@ -532,7 +566,8 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit,
pass_options.intrinsic_symbols_mangling,
pass_options.all_symbols_mangling,
pass_options.bindc_mangling,
pass_options.fortran_mangling);
pass_options.fortran_mangling,
pass_options.c_mangling);
v.visit_TranslationUnit(unit);
UniqueSymbolVisitor u(al, v.sym_to_renamed);
u.visit_TranslationUnit(unit);
Expand Down
1 change: 1 addition & 0 deletions src/libasr/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct PassOptions {
bool visualize = false;
bool tree = false;
bool with_intrinsic_mods = false;
bool c_mangling = false;
};

struct CompilerOptions {
Expand Down