#include #include #include #include #include "Utils/SgUtils.h" #include "RenameSymbols/rename_symbols.h" using std::vector; using std::map; using std::multimap; using std::set; using std::make_pair; using std::string; using std::to_string; static set allNames; static map> usesByModSym; static multimap saves; //for saves static multimap params; //for params inline static string generateUnique(const set &banned, const string &old) { static int counter = 0; string new_name = old + "_" + to_string(++counter); while (banned.count(new_name)) new_name = old + "_" + to_string(++counter); return new_name; } inline static void renameUnique(SgSymbol* s, const set& banned = allNames) { string new_name = generateUnique(banned, s->identifier()); allNames.insert(new_name); SgSymbol* orig = OriginalSymbol(s); orig->changeName(new_name.c_str()); if (usesByModSym.count(orig)) for (auto& e : usesByModSym[orig]) e->changeName(new_name.c_str()); } static void addToScope(SgSymbol* s, SgProject* project) { if (isSgVariableSymb(s) || isSgConstantSymb(s)) { SgSymbol* orig_mod = OriginalSymbol(s); if (orig_mod != s) { usesByModSym[orig_mod].insert(s); return; } if (s->scope() && s->scope()->variant() == MODULE_STMT) usesByModSym[s]; if (s->attributes() & SAVE_BIT) saves.insert(make_pair(s->identifier(), s)); if (s->attributes() & PARAMETER_BIT) params.insert(make_pair(s->identifier(), s)); } } void runRenameSymbolsByFiles(SgFile* file, SgProject* project) { for (SgSymbol* s = file->firstSymbol(); s; s = s->next()) { allNames.insert(s->identifier()); if (s->variant() == VARIABLE_NAME || isSgConstantSymb(s)) addToScope(s, project); } } void runRenameSymbols(SgProject* project, const map &commonBlocks) { int n = project->numberOfFiles(); for (int i = 0; i < n; i++) { SgFile* f = &(project->file(i)); for (SgSymbol* s = f->firstSymbol(); s; s = s->next()) { if (s->variant() == VARIABLE_NAME || isSgConstantSymb(s)) { string name = s->identifier(); SgSymbol* orig = OriginalSymbol(s); bool is_mod_sym = (usesByModSym.find(orig) != usesByModSym.end()); auto is_mod_iter = std::find_if(usesByModSym.begin(), usesByModSym.end(), [&name, orig](const std::pair> &p) { return (name == p.first->identifier()) && (p.first != orig); }); bool intersect_with_mod = (is_mod_iter != usesByModSym.end()); //fix intersects with MODULE symbols if (intersect_with_mod) { renameUnique(s); continue; } if (is_mod_sym) continue; //fix intersects inside SAVE variables if ((s->attributes() & SAVE_BIT) ? saves.count(name) > 1 : saves.count(name)) { renameUnique(s); name = s->identifier(); if (s->attributes() & SAVE_BIT) { saves.erase(find_if(saves.begin(), saves.end(), [&s](const std::pair& p) { return p.second == s; })); saves.insert(make_pair(name, s)); } continue; } //fix intersects inside PARAMETER variables if ((s->attributes() & PARAMETER_BIT) ? params.count(name) > 1 : params.count(name)) { SgConstantSymb* cSym; bool need_to_rename = false; if (cSym = isSgConstantSymb(s)) { string val = cSym->constantValue()->unparse(); string const_name = cSym->identifier(); auto found = find_if(params.begin(), params.end(), [&const_name, &val, project, i](const std::pair& p) { SgConstantSymb* cmpSym = isSgConstantSymb(p.second); project->file(cmpSym->getFileId()); string cmp_val = cmpSym->constantValue()->unparse(); project->file(i); return (const_name == cmpSym->identifier()) && (cmp_val != val); }); need_to_rename = (found != params.end()); } else need_to_rename = true; if (need_to_rename) { renameUnique(s); name = s->identifier(); if (s->attributes() & PARAMETER_BIT) { params.erase(find_if(params.begin(), params.end(), [&s](const std::pair& p) { return p.second == s; })); params.insert(make_pair(name, s)); } } } } } } for (auto& e : commonBlocks) { const CommonBlock& block = *e.second; for (auto& grouped : block.getGroupedVars()) { const vector& vars = grouped.second; string new_name = generateUnique(allNames, vars[0]->getName()); for (auto& var : vars) for (auto& varUse : var->getAllUse()) varUse.getUseS()->changeName(new_name.c_str()); } } }