AST construction is a fundamental operation needed for building ROSE source-to-source translators.
Several levels of interfaces are available in ROSE for users to build AST from scratch. High-level interfaces are recommended whenever possible for their simplicity. Low-level interfaces can give users maximum freedom to manipulate details in AST trees.
This tutorial demonstrates how to create AST fragments for common language constructs (such as variable declarations, functions, function calls, etc.) and how to insert them into an existing AST tree.
Variable Declarations
Example 1: High-Level Variable Declaration
Building a variable declaration using the high-level AST construction and manipulation interfaces defined in the SageBuilder and SageInterface namespaces.
   16SimpleInstrumentation::visit (
SgNode * astNode)
 
   22                buildVariableDeclaration (
"newVariable", buildIntType ());
 
   23      prependStatement (variableDeclaration, block);
 
   28main (
int argc, 
char *argv[])
 
   33  SgProject *project = frontend (argc, argv);
 
   34  ROSE_ASSERT (project != NULL);
 
   36  SimpleInstrumentation treeTraversal;
 
   37  treeTraversal.traverseInputFiles (project, preorder);
 
   39  AstTests::runAllTests (project);
 
   40  return backend (project);
 
virtual void visit(SgNode *astNode)=0
this method is called at every traversed node.
This class represents the concept of a block (not a basic block from control flow analysis).
This class represents the base class for all IR nodes within Sage III.
This class represents a source project, with a list of SgFile objects and global information about th...
This class represents the concept of a C or C++ variable declaration.
Functions that build an AST.
Functions that are useful when operating on the AST.
 The high-level construction builds a variable declaration node using buildVariableDeclaration() and inserts it into the AST with prependStatement(). Scope pointers, symbol tables, and source file position information are handled transparently.
Example 2: Low-Level Variable Declaration
Building the variable declaration using low-level member functions of SAGE III node classes. The low-level approach requires manual handling of scope, parent pointers, and symbol tables.
   12          void visit ( 
SgNode* astNode );
 
   16SimpleInstrumentation::visit ( 
SgNode* astNode )
 
   23          ROSE_ASSERT(sourceLocation != NULL);
 
   26          ROSE_ASSERT(type != NULL);
 
   28          SgName name = 
"newVariable";
 
   31          ROSE_ASSERT(variableDeclaration != NULL);
 
   37          initializedName->set_scope(block);
 
   54main ( 
int argc, 
char * argv[] )
 
   60     ROSE_ASSERT(project != NULL);
 
   62     SimpleInstrumentation treeTraversal;
 
   63     treeTraversal.traverseInputFiles ( project, preorder );
 
   65     AstTests::runAllTests(project);
 
   66     return backend(project);
 
const SgStatementPtrList & get_statements() const
Returns a const STL list by reference.
void set_firstNondefiningDeclaration(SgDeclarationStatement *firstNondefiningDeclaration)
This is an access function for the SgDeclarationStatement::p_firstNondefiningDeclaration data member ...
This class represents the notion of a declared variable.
virtual void set_file_info(Sg_File_Info *X)
Access function calls set_startingConstruct(Sg_File_Info*) member function.
This class represents strings within the IR nodes.
void set_parent(SgNode *parent)
All nodes in the AST contain a reference to a parent node.
void insert_symbol(const SgName &n, SgSymbol *s)
Puts a SgSymbol object into the local symbol table.
This class represents the base class for all types.
const SgInitializedNamePtrList & get_variables() const
Access function for p_variables.
This class represents the concept of a variable name within the compiler (a shared container for the ...
This class represents the location of the code associated with the IR node in the original source cod...
static Sg_File_Info * generateDefaultFileInfoForTransformationNode()
Static function to return new Sg_File_Info object set to default values appropriate for transformatio...
 
Adding Expressions
A translator using the high-level AST builder interface can be used to add an assignment statement before the last statement in a main() function.
    9int main (
int argc, 
char *argv[])
 
   14  SgProject *project = frontend (argc, argv);
 
   24            buildMultiplyOp(buildDoubleVal(2.0),
 
   25                 buildSubtractOp(buildDoubleVal(1.0), 
 
   26                      buildMultiplyOp (buildVarRefExp(
"gama"),buildVarRefExp(
"gama")
 
   28  SgVariableDeclaration* decl = buildVariableDeclaration(
"result",buildDoubleType(),buildAssignInitializer(init_exp));
 
   30  SgStatement* laststmt = getLastStatement(topScopeStack());
 
   31  insertStatementBefore(laststmt,decl);
 
   36  setLhsOperand(init_exp2,buildVarRefExp(
"alpha"));
 
   37  setRhsOperand(init_exp2,buildVarRefExp(
"beta"));
 
   39  SgVariableDeclaration* decl2 = buildVariableDeclaration(
"result2",buildDoubleType(),buildAssignInitializer(init_exp2));
 
   40  laststmt = getLastStatement(topScopeStack());
 
   41  insertStatementBefore(laststmt,decl2);
 
   44  AstTests::runAllTests(project);
 
   47   return backend (project);
 
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes,...
This class represents the concept of a function declaration statement.
SgBasicBlock * get_body() const
Access function for p_body.
This class represents the notion of a statement.
 
Assignment Statements
Adding an assignment statement before the last statement in a main() function using the high-level AST builder interface.
    9int main (
int argc, 
char *argv[])
 
   14  SgProject *project = frontend (argc, argv);
 
   25  SgExprStatement* assignStmt = buildAssignStatement(buildVarRefExp(
"i"),buildIntVal(9));
 
   28  SgStatement* lastStmt = getLastStatement(topScopeStack());
 
   29  insertStatementBefore(lastStmt,assignStmt); 
 
   34  AstTests::runAllTests(project);
 
   35  return backend (project);
 
This class represents the concept of a C or C++ statement which contains a expression.
 
Function Declarations
Adding a function at the top of a global scope using both high-level and low-level constructions.
High-Level Function Declaration
   11          void visit ( 
SgNode* astNode );
 
   15SimpleInstrumentation::visit ( 
SgNode* astNode )
 
   17     SgGlobal* globalScope = isSgGlobal(astNode);
 
   18     if (globalScope != NULL)
 
   23          SgName var1_name = 
"var_name";
 
   27          appendArg(parameterList,var1_init_name);
 
   32          SgName func_name                    = 
"my_function";
 
   34                        (func_name, buildIntType(), parameterList,globalScope);
 
   41          SgVarRefExp *var_ref = buildVarRefExp(var1_name,func_body);
 
   46          prependStatement(new_stmt,func_body);
 
   47          prependStatement(func,globalScope);
 
   53main ( 
int argc, 
char * argv[] )
 
   59     ROSE_ASSERT(project != NULL);
 
   61     SimpleInstrumentation treeTraversal;
 
   62     treeTraversal.traverseInputFiles ( project, preorder );
 
   64     AstTests::runAllTests(project);
 
   65     return backend(project);
 
This class represents the concept of a declaration list.
This class represents the concept of a namespace definition.
This class represents the variable refernece in expressions.
 
High-Level Function Declaration with Scope Stack
    9main ( 
int argc, 
char * argv[] )
 
   15     ROSE_ASSERT(project != NULL);
 
   16     SgGlobal *globalScope = getFirstGlobalScope (project);
 
   19     pushScopeStack (isSgScopeStatement (globalScope));
 
   22    SgName var1_name = 
"var_name";
 
   26    appendArg(parameterList,var1_init_name);
 
   29    SgName func_name                    = 
"my_function";
 
   31                  (func_name, buildIntType(), parameterList);
 
   35    pushScopeStack(isSgScopeStatement(func_body));
 
   43    appendStatement(new_stmt);
 
   48    prependStatement(func);
 
   51    AstTests::runAllTests(project);
 
   52    return backend(project);
 
 
Low-Level Function Declaration
Function Calls
Adding function calls to instrument code using the AST string-based rewrite mechanism or the AST builder interface.
AST Builder Interface Example
   13  void visit (
SgNode * astNode);
 
   17SimpleInstrumentation::visit (
SgNode * astNode)
 
   22      const unsigned int SIZE_OF_BLOCK = 1;
 
   25          SgName name1(
"myTimerFunctionStart");
 
   28              (name1,buildVoidType(),buildFunctionParameterList(),block);
 
   29          ((decl_1->get_declarationModifier()).get_storageModifier()).setExtern();
 
   32              (name1,buildVoidType(), buildExprListExp(),block);
 
   34          prependStatement(callStmt_1,block);
 
   35          prependStatement(decl_1,block);
 
   37          SgName name2(
"myTimerFunctionEnd");
 
   40              (name2,buildVoidType(),buildFunctionParameterList(),block);
 
   41          ((decl_2->get_declarationModifier()).get_storageModifier()).setExtern();
 
   44              (name2,buildVoidType(), buildExprListExp(),block);
 
   46          appendStatement(decl_2,block);
 
   47          appendStatement(callStmt_2,block);
 
   53main (
int argc, 
char *argv[])
 
   58  SgProject *project = frontend (argc, argv);
 
   59  ROSE_ASSERT (project != NULL);
 
   61  SimpleInstrumentation treeTraversal;
 
   62  treeTraversal.traverseInputFiles (project, preorder);
 
   64  AstTests::runAllTests (project);
 
   65  return backend (project);
 
 
Creating a 'struct' for Global Variables
This tutorial demonstrates how to repackage global variables into a struct to support Charm++. The translator also updates all references to global variables so that they reference the variables indirectly through the struct. This is a preprocessing step required to use Charm++ and AMPI.
The example uses low-level AST manipulation at the level of the IR. More concise versions using SageInterface and SageBuilder functions should be considered for high-level manipulation.
Repackaging Global Variables
The following example repackages global variables in an application into a struct.
    1// ROSE is a tool for building preprocessors, this file is an example preprocessor built with ROSE.
 
    2// Specifically it shows the design of a transformation to do a transformation specific for Charm++.
 
    8Rose_STL_Container<SgInitializedName*>
 
    9buildListOfGlobalVariables ( SgSourceFile* file )
 
   11  // This function builds a list of global variables (from a SgFile).
 
   14     Rose_STL_Container<SgInitializedName*> globalVariableList;
 
   16     SgGlobal* globalScope = file->get_globalScope();
 
   17     assert(globalScope != NULL);
 
   18     Rose_STL_Container<SgDeclarationStatement*>::iterator i = globalScope->get_declarations().begin();
 
   19     while(i != globalScope->get_declarations().end())
 
   21          SgVariableDeclaration *variableDeclaration = isSgVariableDeclaration(*i);
 
   22          if (variableDeclaration != NULL)
 
   24               Rose_STL_Container<SgInitializedName*> & variableList = variableDeclaration->get_variables();
 
   25               Rose_STL_Container<SgInitializedName*>::iterator var = variableList.begin();
 
   26               while(var != variableList.end())
 
   28                    globalVariableList.push_back(*var);
 
   35     return globalVariableList;
 
   38// This function is not used, but is useful for 
 
   39// generating the list of all global variables
 
   40Rose_STL_Container<SgInitializedName*>
 
   41buildListOfGlobalVariables ( SgProject* project )
 
   43  // This function builds a list of global variables (from a SgProject).
 
   45     Rose_STL_Container<SgInitializedName*> globalVariableList;
 
   47     const SgFilePtrList& fileList = project->get_fileList();
 
   48     SgFilePtrList::const_iterator file = fileList.begin();
 
   50  // Loop over the files in the project (multiple files exist 
 
   51  // when multiple source files are placed on the command line).
 
   52     while(file != fileList.end())
 
   54          Rose_STL_Container<SgInitializedName*> fileGlobalVariableList = buildListOfGlobalVariables(isSgSourceFile(*file));
 
   56       // DQ (9/26/2007): Moved from std::list to std::vector
 
   57       // globalVariableList.merge(fileGlobalVariableList);
 
   58          globalVariableList.insert(globalVariableList.begin(),fileGlobalVariableList.begin(),fileGlobalVariableList.end());
 
   63     return globalVariableList;
 
   66Rose_STL_Container<SgVarRefExp*>
 
   67buildListOfVariableReferenceExpressionsUsingGlobalVariables ( SgNode* node )
 
   69  // This function builds a list of "uses" of variables (SgVarRefExp IR nodes) within the AST.
 
   72     Rose_STL_Container<SgVarRefExp*> globalVariableUseList;
 
   74  // list of all variables (then select out the global variables by testing the scope)
 
   75     Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree ( node, V_SgVarRefExp );
 
   77     Rose_STL_Container<SgNode*>::iterator i = nodeList.begin();
 
   78     while(i != nodeList.end())
 
   80          SgVarRefExp *variableReferenceExpression = isSgVarRefExp(*i);
 
Referencing Global Variables via Struct (Part 2)
This part shows the continuation of the repackaging of global variables into a struct.
    1          assert(variableReferenceExpression != NULL);
 
    3          assert(variableReferenceExpression->get_symbol() != NULL);
 
    4          assert(variableReferenceExpression->get_symbol()->get_declaration() != NULL);
 
    5          assert(variableReferenceExpression->get_symbol()->get_declaration()->get_scope() != NULL);
 
    7       // Note that variableReferenceExpression->get_symbol()->get_declaration() returns the 
 
    8       // SgInitializedName (not the SgVariableDeclaration where it was declared)!
 
    9          SgInitializedName* variable = variableReferenceExpression->get_symbol()->get_declaration();
 
   11          SgScopeStatement* variableScope = variable->get_scope();
 
   13       // Check if this is a variable declared in global scope, if so, then save it
 
   14          if (isSgGlobal(variableScope) != NULL)
 
   16               globalVariableUseList.push_back(variableReferenceExpression);
 
   21     return globalVariableUseList;
 
   26buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope)
 
   28  // This function builds a class declaration and definition 
 
   29  // (both the defining and nondefining declarations as required).
 
   31  // Build a file info object marked as a transformation
 
   32     Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
 
   33     assert(fileInfo != NULL);
 
   35  // This is the class definition (the fileInfo is the position of the opening brace)
 
   36     SgClassDefinition* classDefinition   = new SgClassDefinition(fileInfo);
 
   37     assert(classDefinition != NULL);
 
   39  // Set the end of construct explictly (where not a transformation this is the location of the closing brace)
 
   40     classDefinition->set_endOfConstruct(fileInfo);
 
   42  // This is the defining declaration for the class (with a reference to the class definition)
 
   43     SgClassDeclaration* classDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition);
 
   44     assert(classDeclaration != NULL);
 
   46  // Set the defining declaration in the defining declaration!
 
   47     classDeclaration->set_definingDeclaration(classDeclaration);
 
   49  // Set the non defining declaration in the defining declaration (both are required)
 
   50     SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL);
 
   51     assert(classDeclaration != NULL);
 
   52     nondefiningClassDeclaration->set_scope(scope);
 
   53     nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration));
 
   55  // Set the internal reference to the non-defining declaration
 
   56     classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
 
   57     classDeclaration->set_type(nondefiningClassDeclaration->get_type());
 
   59  // Set the defining and no-defining declarations in the non-defining class declaration!
 
   60     nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
 
   61     nondefiningClassDeclaration->set_definingDeclaration(classDeclaration);
 
   63  // Set the nondefining declaration as a forward declaration!
 
   64     nondefiningClassDeclaration->setForward();
 
   66  // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)!
 
   67     classDefinition->set_declaration(classDeclaration);
 
   69  // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!)
 
   70     classDeclaration->set_scope(scope);
 
   72  // some error checking
 
   73     assert(classDeclaration->get_definingDeclaration() != NULL);
 
   74     assert(classDeclaration->get_firstNondefiningDeclaration() != NULL);
 
   75     assert(classDeclaration->get_definition() != NULL);
 
   77  // DQ (9/8/2007): Need to add function symbol to global scope!
 
   78     printf ("Fixing up the symbol table in scope = %p = %s for class = %p = %s \n",scope,scope->class_name().c_str(),classDeclaration,classDeclaration->get_name().str());
 
   79     SgClassSymbol* classSymbol = new SgClassSymbol(classDeclaration);
 
   80     scope->insert_symbol(classDeclaration->get_name(),classSymbol);
 
Handling Global Variables (Part 3)
The third part of the example, continuing the transformation of global variables into a struct.
    1     ROSE_ASSERT(scope->lookup_class_symbol(classDeclaration->get_name()) != NULL);
 
    3     return classDeclaration;
 
    9putGlobalVariablesIntoClass (Rose_STL_Container<SgInitializedName*> & globalVariables, SgClassDeclaration* classDeclaration )
 
   11  // This function iterates over the list of global variables and inserts them into the iput class definition
 
   13     SgVariableSymbol* globalClassVariableSymbol = NULL;
 
   15     for (Rose_STL_Container<SgInitializedName*>::iterator var = globalVariables.begin(); var != globalVariables.end(); var++)
 
   17       // printf ("Appending global variable = %s to new globalVariableContainer \n",(*var)->get_name().str());
 
   18          SgVariableDeclaration* globalVariableDeclaration = isSgVariableDeclaration((*var)->get_parent());
 
   19          assert(globalVariableDeclaration != NULL);
 
   21       // Get the global scope from the global variable directly
 
   22          SgGlobal* globalScope = isSgGlobal(globalVariableDeclaration->get_scope());
 
   23          assert(globalScope != NULL);
 
   25          if (var == globalVariables.begin())
 
   27            // This is the first time in this loop, replace the first global variable with 
 
   28            // the class declaration/definition containing all the global variables!
 
   29            // Note that initializers in the global variable declarations require modification 
 
   30            // of the preinitialization list in the class's constructor!  I am ignoring this for now!
 
   31               globalScope->replace_statement(globalVariableDeclaration,classDeclaration);
 
   33            // Build source position informaiton (marked as transformation)
 
   34               Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
 
   35               assert(fileInfo != NULL);
 
   37            // Add the variable of the class type to the global scope!
 
   38               SgClassType* variableType = new SgClassType(classDeclaration->get_firstNondefiningDeclaration());
 
   39               assert(variableType != NULL);
 
   40               SgVariableDeclaration* variableDeclaration = new SgVariableDeclaration(fileInfo,"AMPI_globals",variableType);
 
   41               assert(variableDeclaration != NULL);
 
   43               globalScope->insert_statement(classDeclaration,variableDeclaration,false);
 
   45               assert(variableDeclaration->get_variables().empty() == false);
 
   46               SgInitializedName* variableName = *(variableDeclaration->get_variables().begin());
 
   47               assert(variableName != NULL);
 
   49            // DQ (9/8/2007): Need to set the scope of the new variable.
 
   50               variableName->set_scope(globalScope);
 
   52            // build the return value
 
   53               globalClassVariableSymbol = new SgVariableSymbol(variableName);
 
   55            // DQ (9/8/2007): Need to add the symbol to the global scope (new testing requires this).
 
   56               globalScope->insert_symbol(variableName->get_name(),globalClassVariableSymbol);
 
   57               ROSE_ASSERT(globalScope->lookup_variable_symbol(variableName->get_name()) != NULL);
 
   61            // for all other iterations of this loop ... 
 
   62            // remove variable declaration from the global scope
 
   63               globalScope->remove_statement(globalVariableDeclaration);
 
   66       // add the variable declaration to the class definition
 
   67          classDeclaration->get_definition()->append_member(globalVariableDeclaration);
 
   70     return globalClassVariableSymbol;
 
   75fixupReferencesToGlobalVariables ( Rose_STL_Container<SgVarRefExp*> & variableReferenceList, SgVariableSymbol* globalClassVariableSymbol)
 
   77  // Now fixup the SgVarRefExp to reference the global variables through a struct
 
   78     for (Rose_STL_Container<SgVarRefExp*>::iterator var = variableReferenceList.begin(); var != variableReferenceList.end(); var++)
 
Final Steps of Global Variable Repackaging (Part 4)
This part completes the transformation and repackaging of global variables into a struct.
    1       // printf ("Variable reference for %s \n",(*var)->get_symbol()->get_declaration()->get_name().str());
 
    3          SgNode* parent = (*var)->get_parent();
 
    4          assert(parent != NULL);
 
    6       // If this is not an expression then is likely a meaningless statement such as ("x;")
 
    7          SgExpression* parentExpression = isSgExpression(parent);
 
    8          assert(parentExpression != NULL);
 
   10       // Build the reference through the global class variable ("x" --> "AMPI_globals.x")
 
   12       // Build source position informaiton (marked as transformation)
 
   13          Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
 
   14          assert(fileInfo != NULL);
 
   16       // Build "AMPI_globals"
 
   17          SgExpression* lhs = new SgVarRefExp(fileInfo,globalClassVariableSymbol);
 
   19       // Build "AMPI_globals.x" from "x"
 
   20          SgDotExp* globalVariableReference = new SgDotExp(fileInfo,lhs,*var);
 
   21          assert(globalVariableReference != NULL);
 
   23          if (parentExpression != NULL)
 
   25            // Introduce reference to *var through the data structure
 
   27            // case of binary operator
 
   28               SgUnaryOp* unaryOperator = isSgUnaryOp(parentExpression);
 
   29               if (unaryOperator != NULL)
 
   31                    unaryOperator->set_operand(globalVariableReference);
 
   35                 // case of binary operator
 
   36                    SgBinaryOp* binaryOperator = isSgBinaryOp(parentExpression);
 
   37                    if (binaryOperator != NULL)
 
   39                      // figure out if the *var is on the lhs or the rhs
 
   40                         if (binaryOperator->get_lhs_operand() == *var)
 
   42                              binaryOperator->set_lhs_operand(globalVariableReference);
 
   46                              assert(binaryOperator->get_rhs_operand() == *var);
 
   47                              binaryOperator->set_rhs_operand(globalVariableReference);
 
   52                      // ignore these cases for now!
 
   53                         switch(parentExpression->variantT())
 
   55                           // Where the variable appers in the function argument list the parent is a SgExprListExp
 
   58                                   printf ("Sorry not implemented, case of global variable in function argument list ... \n");
 
   66                                   printf ("Error: default reached in switch  parentExpression = %p = %s \n",parentExpression,parentExpression->class_name().c_str());
 
   76#define OUTPUT_NAMES_OF_GLOBAL_VARIABLES           0
 
   77#define OUTPUT_NAMES_OF_GLOBAL_VARIABLE_REFERENCES 0
 
   80transformGlobalVariablesToUseStruct ( SgSourceFile *file )
 
Struct Usage Finalization (Part 5)
This is the final part of the global variable repackaging and struct manipulation process.
    4  // These are the global variables in the input program (provided as helpful information)
 
    5     Rose_STL_Container<SgInitializedName*> globalVariables = buildListOfGlobalVariables(file);
 
    7#if OUTPUT_NAMES_OF_GLOBAL_VARIABLES
 
    8     printf ("global variables (declared in global scope): \n");
 
    9     for (Rose_STL_Container<SgInitializedName*>::iterator var = globalVariables.begin(); var != globalVariables.end(); var++)
 
   11          printf ("   %s \n",(*var)->get_name().str());
 
   16  // get the global scope within the first file (currently ignoring all other files)
 
   17     SgGlobal* globalScope = file->get_globalScope();
 
   18     assert(globalScope != NULL);
 
   20  // Build the class declaration
 
   21     SgClassDeclaration* classDeclaration = buildClassDeclarationAndDefinition("AMPI_globals_t",globalScope);
 
   23  // Put the global variables intothe class
 
   24     SgVariableSymbol* globalClassVariableSymbol = putGlobalVariablesIntoClass(globalVariables,classDeclaration);
 
   26  // Their associated symbols will be located within the project's AST 
 
   27  // (where they occur in variable reference expressions).
 
   28     Rose_STL_Container<SgVarRefExp*> variableReferenceList = buildListOfVariableReferenceExpressionsUsingGlobalVariables(file);
 
   30#if OUTPUT_NAMES_OF_GLOBAL_VARIABLE_REFERENCES
 
   31     printf ("global variables appearing in the application: \n");
 
   32     for (Rose_STL_Container<SgVarRefExp*>::iterator var = variableReferenceList.begin(); var != variableReferenceList.end(); var++)
 
   34          printf ("   %s \n",(*var)->get_symbol()->get_declaration()->get_name().str());
 
   39  // Fixup all references to global variable to access the variable through the class ("x" --> "AMPI_globals.x")
 
   40     fixupReferencesToGlobalVariables(variableReferenceList,globalClassVariableSymbol);
 
   45transformGlobalVariablesToUseStruct ( SgProject *project )
 
   47  // Call the transformation of each file (there are multiple SgFile 
 
   48  // objects when multiple files are specfied on the command line!).
 
   49     assert(project != NULL);
 
   51     const SgFilePtrList& fileList = project->get_fileList();
 
   52     SgFilePtrList::const_iterator file = fileList.begin();
 
   53     while(file != fileList.end())
 
   55          transformGlobalVariablesToUseStruct(isSgSourceFile(*file));
 
   60// ******************************************
 
   62// ******************************************
 
   64main( int argc, char * argv[] )
 
   66  // Initialize and check compatibility. See Rose::initialize
 
   69  // Build the AST used by ROSE
 
   70     SgProject* project = frontend(argc,argv);
 
   71     assert(project != NULL);
 
   73  // transform application as required
 
   74     transformGlobalVariablesToUseStruct(project);
 
   76  // Code generation phase (write out new application "rose_<input file name>")
 
   77     return backend(project);
 
 
Example Input Code for Struct Repackaging
Example source code used as input to the translator for repackaging global variables into a struct.
Example Output of Global Variable Repackaging
The output of the input after the translator repackages the global variables into a struct.
   10struct AMPI_globals_t AMPI_globals;
 
   19  AMPI_globals . x = a + AMPI_globals . y;