Skip to content

Commit c53ffed

Browse files
authored
Implemented mangling for c back-end as per issue #2359 . (#2546)
* Implemented mangling for c backend * Added integration test
1 parent 8beb328 commit c53ffed

File tree

5 files changed

+70
-7
lines changed

5 files changed

+70
-7
lines changed

integration_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,8 @@ RUN(NAME callback_03 LABELS cpython llvm c)
817817

818818
RUN(NAME lambda_01 LABELS cpython llvm)
819819

820+
RUN(NAME c_mangling LABELS cpython llvm c)
821+
820822
# callback_04 is to test emulation. So just run with cpython
821823
RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython)
822824

integration_tests/c_mangling.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
def f():
2+
int : str
3+
int = "abc"
4+
print(int)
5+
6+
char : str
7+
char = "char_variable"
8+
print(char)
9+
10+
void : str
11+
void = "void_variable"
12+
print(void)
13+
14+
auto : str
15+
auto = "auto_variable"
16+
print(auto)
17+
18+
19+
case : str
20+
case = "case_variable"
21+
print(case)
22+
23+
f()

src/bin/lpython.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,6 +1842,7 @@ int main(int argc, char *argv[])
18421842
return emit_cpp(arg_file, runtime_library_dir, compiler_options);
18431843
}
18441844
if (show_c) {
1845+
compiler_options.po.c_mangling = true;
18451846
return emit_c(arg_file, runtime_library_dir, lpython_pass_manager,
18461847
compiler_options);
18471848
}
@@ -1920,6 +1921,7 @@ int main(int argc, char *argv[])
19201921
err = compile_to_binary_wasm_to_x86(arg_file, outfile,
19211922
runtime_library_dir, compiler_options, time_report, backend);
19221923
} else if (backend == Backend::c) {
1924+
compiler_options.po.c_mangling = true;
19231925
std::string emit_file_name = basename + "__tmp__generated__.c";
19241926
err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir,
19251927
lpython_pass_manager, compiler_options);

src/libasr/pass/unique_symbols.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <libasr/pass/pass_utils.h>
88
#include <unordered_map>
99
#include <set>
10-
10+
#include<unordered_set>
1111

1212
extern std::string lcompilers_unique_ID;
1313

@@ -46,15 +46,28 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
4646
bool all_symbols_mangling;
4747
bool bindc_mangling = false;
4848
bool fortran_mangling;
49+
bool c_mangling;
4950
bool should_mangle = false;
5051
std::vector<std::string> parent_function_name;
5152
std::string module_name = "";
5253
SymbolTable* current_scope = nullptr;
5354

54-
SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm) :
55+
SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm, bool cm) :
5556
module_name_mangling(mm), global_symbols_mangling(gm), intrinsic_symbols_mangling(im),
56-
all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) {}
57+
all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) , c_mangling(cm){}
58+
59+
60+
const std::unordered_set<std::string> reserved_keywords_c = {
61+
"_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"
62+
};
5763

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

5972
std::string update_name(std::string curr_name) {
6073
if (startswith(curr_name, "_lpython") || startswith(curr_name, "_lfortran") ) {
@@ -147,7 +160,11 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
147160
sym_to_renamed[sym] = current_scope->parent->get_unique_name(
148161
"f" + std::string(x.m_name));
149162
}
150-
}
163+
}
164+
}
165+
if ( c_mangling ) {
166+
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
167+
mangle_c(sym , std::string(x.m_name));
151168
}
152169
for (auto &a : x.m_symtab->get_scope()) {
153170
bool nested_function = is_nested_function(a.second);
@@ -178,6 +195,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
178195
std::string(x.m_name));
179196
}
180197
}
198+
199+
if ( c_mangling ) {
200+
mangle_c(sym , std::string(x.m_name));
201+
}
181202
}
182203

183204
void visit_GenericProcedure(const ASR::GenericProcedure_t &x) {
@@ -204,6 +225,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
204225
sym_to_renamed[sym] = update_name(x.m_name);
205226
}
206227
}
228+
if ( c_mangling ) {
229+
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
230+
mangle_c(sym , std::string(x.m_name));
231+
}
207232
for (auto &a : x.m_symtab->get_scope()) {
208233
this->visit_symbol(*a.second);
209234
}
@@ -232,6 +257,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
232257
sym_to_renamed[sym] = update_name(x.m_name);
233258
}
234259
}
260+
if (c_mangling ) {
261+
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
262+
mangle_c(sym , std::string(x.m_name));
263+
}
235264
}
236265

237266
template <typename T>
@@ -240,6 +269,10 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor<SymbolRenameVisitor> {
240269
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
241270
sym_to_renamed[sym] = update_name(x.m_name);
242271
}
272+
if ( c_mangling ) {
273+
ASR::symbol_t *sym = ASR::down_cast<ASR::symbol_t>((ASR::asr_t*)&x);
274+
mangle_c(sym , std::string(x.m_name));
275+
}
243276
for (auto &a : x.m_symtab->get_scope()) {
244277
this->visit_symbol(*a.second);
245278
}
@@ -521,8 +554,9 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit,
521554
if (pass_options.mangle_underscore) {
522555
lcompilers_unique_ID = "";
523556
}
524-
if (!any_present || (!(pass_options.mangle_underscore ||
525-
pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) {
557+
if ((!any_present || (!(pass_options.mangle_underscore ||
558+
pass_options.fortran_mangling) && lcompilers_unique_ID.empty())) &&
559+
!pass_options.c_mangling) {
526560
// `--mangle-underscore` doesn't require `lcompilers_unique_ID`
527561
// `lcompilers_unique_ID` is not mandatory for `--apply-fortran-mangling`
528562
return;
@@ -532,7 +566,8 @@ void pass_unique_symbols(Allocator &al, ASR::TranslationUnit_t &unit,
532566
pass_options.intrinsic_symbols_mangling,
533567
pass_options.all_symbols_mangling,
534568
pass_options.bindc_mangling,
535-
pass_options.fortran_mangling);
569+
pass_options.fortran_mangling,
570+
pass_options.c_mangling);
536571
v.visit_TranslationUnit(unit);
537572
UniqueSymbolVisitor u(al, v.sym_to_renamed);
538573
u.visit_TranslationUnit(unit);

src/libasr/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct PassOptions {
5555
bool visualize = false;
5656
bool tree = false;
5757
bool with_intrinsic_mods = false;
58+
bool c_mangling = false;
5859
};
5960

6061
struct CompilerOptions {

0 commit comments

Comments
 (0)