-
Notifications
You must be signed in to change notification settings - Fork 136
Open
Description
I want to transform static global variables into function arguments for functions that use said variables. For example:
static int n;
int f(int x) {
return x*x + n;
}
int main() {
return 0;
}
Would get converted to:
int f(int x, int n) {
return x*x + n;
}
int main() {
return 0;
}
This is the code that I came up with in an attempt to perform the transformation:
#include <iostream>
#include "rose.h"
using namespace std;
using namespace SageBuilder;
using namespace SageInterface;
int main(int argc, char **argv)
{
ROSE_INITIALIZE;
SgProject *project = frontend(argc, argv);
ROSE_ASSERT(project != NULL);
// Traverse the AST to identify global variables
auto nodes = NodeQuery::querySubTree(project, V_SgInitializedName);
for (auto it = nodes.begin(); it != nodes.end(); ++it) {
SgInitializedName *var = isSgInitializedName(*it);
// Check if the variable is global and static
if (isSgGlobal(var->get_scope()) && var->get_storageModifier().isStatic()) {
auto funcDefs = NodeQuery::querySubTree(project, V_SgFunctionDefinition);
for (auto fd : funcDefs) {
SgFunctionDefinition* funcDef = isSgFunctionDefinition(fd);
if (funcDef == NULL)
continue;
if (funcDef->get_body()->lookup_variable_symbol(var->get_name()) == NULL) {
continue; // Skip if variable is not mentioned in function
}
// Substitute the global variable with a parameter in the function signature
SgFunctionParameterList *params = funcDef->get_declaration()->get_parameterList();
SgInitializedName *param = buildInitializedName(var->get_name(), var->get_type());
params->append_arg(param);
// Replace all references to the original variable with the new parameter
auto refs = NodeQuery::querySubTree(funcDef->get_body(), V_SgVarRefExp);
for (auto refIt = refs.begin(); refIt != refs.end(); ++refIt) {
SgVarRefExp *varRef = isSgVarRefExp(*refIt);
if (varRef->get_symbol() == var->search_for_symbol_from_symbol_table()) {
SgVariableSymbol *paramSymbol = isSgVariableSymbol(param->search_for_symbol_from_symbol_table());
ROSE_ASSERT(paramSymbol != NULL);
varRef->set_symbol(paramSymbol);
// What else?
}
}
}
}
}
return backend(project);
}
Unfortunately, my solution does not work. Some mistakes that I could identify:
- The condition
if (funcDef->get_body()->lookup_variable_symbol(var->get_name()) == NULL)
doesn't work, because it does not traverse the AST searching for uses of the variable - The part where I attempt to set the symbol in the varRef is not enough. The varRef should completely change to be a reference to the new variable in the local scope of the function
I searched the documentation and the tutorials for this information but I still haven't found what I need to do the desired transformation. Any tips?
Metadata
Metadata
Assignees
Labels
No labels