Ejemplo n.º 1
0
void visitorTraversal::visit(SgNode* n)
   {
  // There are three types ir IR nodes that can be queried for scope:
  //   - SgStatement, and 
  //   - SgInitializedName
     SgStatement* statement = isSgStatement(n);
     if (statement != NULL)
        {
          SgScopeStatement* scope = statement->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgStatement       = %12p = %30s has scope = %12p = %s (total number = %d) \n",
               statement,statement->class_name().c_str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }

     SgInitializedName* initializedName = isSgInitializedName(n);
     if (initializedName != NULL)
        {
          SgScopeStatement* scope = initializedName->get_scope();
          ROSE_ASSERT(scope != NULL);
          printf ("SgInitializedName = %12p = %30s has scope = %12p = %s (total number = %d)\n",
               initializedName,initializedName->get_name().str(),
               scope,scope->class_name().c_str(),(int)scope->numberOfNodes());
        }
   }
Ejemplo n.º 2
0
  //Replace the unparsing of expanded macro calls with the actual macro call wherever possible
  void unparseMacroCalls(SgNode* searchTree)
  {
    //Traverse AST to find all macro calls and the nodes they are attached to
    findPreprocInfo findPre;
    findPre.traverse(searchTree, preorder);

    std::vector< std::pair<SgNode*, PreprocessingInfo*> >& wherePreprocIsAttached = findPre.wherePreprocIsAttached;

    //Replace expanded macro calls with actual macro call from pre-cpp wherever possible
    for( std::vector< std::pair<SgNode*, PreprocessingInfo*> >::iterator iItr = wherePreprocIsAttached.begin(); 
        iItr != wherePreprocIsAttached.end(); ++iItr)
    {
      SgStatement*       currentNode = isSgStatement( (*iItr).first );
      PreprocessingInfo* curPreproc  = (*iItr).second;

      ROSE_ASSERT(currentNode != NULL);

      std::vector<SgNode*> matchingSubTree;

      if ( matchMacroToSubtrees(currentNode->get_scope(), curPreproc, matchingSubTree) )
      {
        for(unsigned int i = 0; i < matchingSubTree.size(); i++)
        {
          SgLocatedNode* macroNode = isSgLocatedNode(matchingSubTree[i]);
          ROSE_ASSERT(macroNode != NULL);
          std::string replacementString = ( i ==0 ? curPreproc->getString() : "" );

          if( isSgExpression(macroNode) == NULL )
          {
#ifndef USE_ROSE
#ifndef ROSE_SKIP_COMPILATION_OF_WAVE
         // If we are using ROSE to compile ROSE source code then the Wave support is not present.
            PreprocessingInfo::rose_macro_call* macroCall = curPreproc->get_macro_call();

            if(macroCall->expanded_macro.size() > 0 && boost::wave::token_id(macroCall->expanded_macro.back()) != boost::wave::T_COLON)
              replacementString +=";";
#endif
#endif
          }

          std::cout << "Doing line replacement " << macroNode->unparseToString() << " with " << replacementString << std::endl;

#if 0
          std::string pos;
          curPreproc->display(pos);
          std::cout << macroNode->class_name() << " "<<  pos << std::endl;
#endif

          macroNode->addToAttachedPreprocessingInfo(new PreprocessingInfo(PreprocessingInfo::LineReplacement,
                replacementString,macroNode->get_file_info()->get_filenameString(),1,1,1,PreprocessingInfo::before));
        }

        
      };

       

    }
    
  };
Ejemplo n.º 3
0
/*
 *  The function
 *      findScope()
 *  takes as a parameter a SgNode* which is a SgStatement*. It returns a SgNodePtrVector of all
 *  preceding scopes the SgStatement is in.
 *
 */
SgNodePtrVector
findScopes (SgNode * astNode)
{
  ROSE_ASSERT (isSgStatement (astNode));

  SgNodePtrVector returnVector;
  SgScopeStatement *currentScope;

  if (isSgScopeStatement (astNode))
    {
      currentScope = isSgScopeStatement (astNode);
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (astNode);
    }
  else
    {
      SgStatement *sageStatement = isSgStatement (astNode);
      ROSE_ASSERT (sageStatement != NULL);
      currentScope = sageStatement->get_scope ();
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (currentScope);
    }

  while (currentScope->variantT () != V_SgGlobal)
    {
      currentScope = currentScope->get_scope ();
      ROSE_ASSERT (currentScope != NULL);
      returnVector.push_back (currentScope);
    }

  //Must also include the Global Scopes of the other files in the project
  if (currentScope->variantT () == V_SgGlobal)
    {
      SgFile *sageFile = isSgFile ((currentScope)->get_parent ());
      ROSE_ASSERT (sageFile != NULL);
      SgProject *sageProject = isSgProject (sageFile->get_parent ());
      ROSE_ASSERT (sageProject != NULL);

      //Get a list of all files in the current project
      const SgFilePtrList& sageFilePtrList = sageProject->get_fileList ();

      //Iterate over the list of files to find all Global Scopes
      SgNodePtrVector globalScopes;
      for (unsigned int i = 0; i < sageFilePtrList.size (); i += 1)
	{
	  const SgSourceFile *sageFile = isSgSourceFile (sageFilePtrList[i]);
	  ROSE_ASSERT (sageFile != NULL);
	  SgGlobal *sageGlobal = sageFile->get_globalScope();
	  ROSE_ASSERT (sageGlobal != NULL);

	  returnVector.push_back (sageGlobal);
	}
    }


  return returnVector;
};
Ejemplo n.º 4
0
Archivo: traceCPU.C Proyecto: 8l/rose
int main (int argc, char *argv[])
{
   /* indicate whether include files need to be added */
   bool loopTransformApplied = false ;

   /* more bools at top of file... */
   bool withPAPI = false ;
   bool showStats = false ;
   bool enablePostProcessing = false ;

   /***********************************************/
   /* Process command line options                */
   /***********************************************/

   Rose_STL_Container<string> cmdLineArgs =
     CommandlineProcessing::generateArgListFromArgcArgv(argc,argv) ;

   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(s|stats)", true) )
   {
     showStats = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(p|papi)", true) )
   {
     withPAPI = true ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "(l|loops)", true) )
   {
     emitSeqSeg = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "noiter", true) )
   {
     countIters = false ;
   }
   if ( CommandlineProcessing::isOption(
           cmdLineArgs, "-et:", "fast", true) )
   {
     fullLoopStat = false ;
     emitSeqSeg   = false ;
     countIters   = false ;
     withPAPI     = false ;
     enablePostProcessing = true ;
   }

   dumpFunc = (showStats ? "ET_LogStats" : "ET_Dump") ;

   /***********************************************/
   /*               Invoke ROSE                   */
   /***********************************************/

   /* build AST */
   SgProject* project = frontend(argc, argv);
   ROSE_ASSERT(project);

   if (project->get_fileList().empty() == false) {

     /* make sure AST is well formed */
     AstTests::runAllTests(project);

     /* set up some needed typedefs for runtime support */

     SgGlobal *globalScope = SageInterface::getFirstGlobalScope(project) ;
     ETtype = buildTypedefDeclaration("ET_Idx_t", buildShortType(), globalScope)->get_type() ;

     /* insert probes into each function in this file */

     Rose_STL_Container<SgNode*> funcDefs =
         NodeQuery::querySubTree(project, V_SgFunctionDefinition) ;

     for (Rose_STL_Container<SgNode*>::iterator f_itr = funcDefs.begin();
                f_itr != funcDefs.end(); ++f_itr)
     {
        SgFunctionDefinition *funcDef = isSgFunctionDefinition(*f_itr) ;
        ROSE_ASSERT(funcDef);

#ifdef ET_DEBUG 
        printf("--- %s ---\n", funcDef->get_qualified_name().str()) ;
#endif

        SgBasicBlock *funcBody = funcDef->get_body() ;
        if (funcBody == NULL)
           continue ;  /* should be impossible to get here... */

        SgFunctionDeclaration *funcDecl = funcDef->get_declaration() ;
        ROSE_ASSERT(funcDecl);

        /* don't transform header file code  */
        if (strstr(funcDecl->get_name().str(), "operator"))
           continue ;

#ifdef ET_DEBUG
        printf("--- %s ---\n", funcDecl->get_name().str()) ;
#endif

        int loopCount = 0 ;  /* used to create local variable names */
        int segCount = 0 ;

        TransformFunction(funcDecl, funcBody, funcBody, &loopCount, &segCount) ;

        if (loopCount != 0)
        {
           loopTransformApplied = true ;
        }
     }

     SgFunctionDeclaration *mainFunc = SageInterface::findMain(project) ;
     if (countIters == false && (loopTransformApplied || mainFunc != NULL)) {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#define ET_NO_COUNT_ITERS 1\n")) ;
     }

     /* files containing at least one loop require run-time support */

     if (loopTransformApplied)
     {
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.h\"\n")) ;
     }

     /* fold run-time support code into file containing main() */

     if (mainFunc != NULL)
     {

        SgFunctionDefinition *mainFuncDef = mainFunc->get_definition() ;

        /* include ETrt.c just before main() in this file */
        if (!fullLoopStat) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_SIMPLE_LOOP_STATS 1\n") );
        }
        if (enablePostProcessing) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_POST_PROCESS_SEQ_TO_LOOP 1\n") );
        }
        if (withPAPI) {
          SageInterface::attachArbitraryText(globalScope,
             std::string("#define ET_PAPI 1\n\n") );
        }
        SageInterface::attachArbitraryText(globalScope,
           std::string("#include \"ETrt.c\"\n") );

        if (withPAPI) {
           /* Insert PAPI initialization code at top of main */
           SgBasicBlock *mainBody = mainFuncDef->get_body() ;

           Rose_STL_Container<SgNode*> blockStmts =
               NodeQuery::querySubTree(mainBody, V_SgStatement,
                                       AstQueryNamespace::ChildrenOnly) ;

           for (Rose_STL_Container<SgNode*>::iterator s_itr = blockStmts.begin();
                   s_itr != blockStmts.end(); ++s_itr)
           {
              SgStatement *stmt = isSgStatement(*s_itr) ;
              ROSE_ASSERT(stmt);

              /* skip variable declarations */
              if (isSgDeclarationStatement(stmt))
                 continue ;

              SgExprStatement *initCall = buildFunctionCallStmt(
                 SgName("ET_Init"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              stmt->get_scope()->insert_statement(stmt, initCall) ;

              break ;
           }
        }

        /* insert finalization code at end of main() */
        Rose_STL_Container<SgNode*> retStmts =
            NodeQuery::querySubTree(mainFunc, V_SgReturnStmt) ;

        if (retStmts.size() > 0)
        {
           for (Rose_STL_Container<SgNode*>::iterator r_itr = retStmts.begin();
                   r_itr != retStmts.end(); ++r_itr)
           {
              SgReturnStmt *ret = isSgReturnStmt(*r_itr) ;
              ROSE_ASSERT(ret);

              SgExprStatement *sanityCall = buildFunctionCallStmt(
                 SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, sanityCall) ;

              SgExprStatement *logStatCall = buildFunctionCallStmt(
                 SgName(dumpFunc), buildVoidType(), buildExprListExp(),
                 mainFuncDef->get_body()) ;
              ret->get_scope()->insert_statement(ret, logStatCall) ;
           }
        }
        else
        {
           SgExprStatement *sanityCall = buildFunctionCallStmt(
              SgName("ET_SanityCheck"), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(sanityCall) ;

           SgExprStatement *logStatCall = buildFunctionCallStmt(
              SgName(dumpFunc), buildVoidType(), buildExprListExp(),
              mainFuncDef->get_body()) ;
           mainFuncDef->get_body()->append_statement(logStatCall) ;
        }
     }
   }

   /* make sure AST is well formed */
   AstTests::runAllTests(project);

   // generateDOT (*project);

   return backend(project);
}
Ejemplo n.º 5
0
void generateStencilCode(StencilEvaluationTraversal & traversal, bool generateLowlevelCode)
   {
  // Read the stencil and generate the inner most loop AST for the stencil.

  // Note that generateLowlevelCode controls the generation of low level C code using a
  // base pointer to raw memory and linearized indexing off of that pointer.  The
  // alternative is to use the operator[] member function in the RectMDArray class.

  // Example of code that we want to generate:
  // for (j=0; j < source.size(0); j++)
  //    {
  //      int axis_x_size = source.size(0);
  //      for (i=0; i < source.size(0); i++)
  //         {
  //           destination[j*axis_x_size+i] = source[j*axis_x_size+i];
  //         }
  //    }

  // This function genertes the loop nest only:
  //    SgForStatement* buildLoopNest(int stencilDimension, SgBasicBlock* & innerLoopBody)

  // This function generates the statement in the inner most loop body:
  //    SgExprStatement* assembleStencilSubTreeArray(vector<SgExpression*> & stencilSubTreeArray)

  // This function generates the AST representing the stencil points:
  //    SgExpression* buildStencilPoint (StencilOffsetFSM* stencilOffsetFSM, double stencilCoeficient, int stencilDimension, SgVariableSymbol* destinationVariableSymbol, SgVariableSymbol* sourceVariableSymbol)

  // The generated code should be in terms of the operator[]() functions on the 
  // RectMDArray objects.  Likely we have to support a wider range of generated code later.
  //    const RectMDArray<TDest>& a_LOfPhi,
  //    const RectMDArray<TSrc>& a_phi,

  // std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList;
     std::vector<SgFunctionCallExp*> stencilOperatorFunctionCallList = traversal.get_stencilOperatorFunctionCallList();
     for (size_t i = 0; i < stencilOperatorFunctionCallList.size(); i++)
        {
          SgFunctionCallExp* functionCallExp = stencilOperatorFunctionCallList[i];
          ROSE_ASSERT(functionCallExp != NULL);

          printf ("processing functionCallExp = %p \n",functionCallExp);

          SgStatement* associatedStatement = TransformationSupport::getStatement(functionCallExp);
          ROSE_ASSERT(associatedStatement != NULL);

          string filename = associatedStatement->get_file_info()->get_filename();
          int lineNumber  = associatedStatement->get_file_info()->get_line();

          printf ("Generating code for stencil operator used at file = %s at line = %d \n",filename.c_str(),lineNumber);

          SgExprListExp* argumentList = functionCallExp->get_args();
          ROSE_ASSERT(argumentList != NULL);

       // There should be four elements to a stencil operator.
          ROSE_ASSERT(argumentList->get_expressions().size() == 4);

       // Stencil
          SgExpression* stencilExpression = argumentList->get_expressions()[0];
          SgVarRefExp* stencilVarRefExp = isSgVarRefExp(stencilExpression);
          ROSE_ASSERT(stencilVarRefExp != NULL);

       // RectMDArray (destination)
          SgExpression* destinationArrayReferenceExpression = argumentList->get_expressions()[1];
          SgVarRefExp* destinationArrayVarRefExp = isSgVarRefExp(destinationArrayReferenceExpression);
          ROSE_ASSERT(destinationArrayVarRefExp != NULL);

       // RectMDArray (source)
          SgExpression* sourceArrayReferenceExpression = argumentList->get_expressions()[2];
          SgVarRefExp* sourceArrayVarRefExp = isSgVarRefExp(sourceArrayReferenceExpression);
          ROSE_ASSERT(sourceArrayVarRefExp != NULL);

       // Box
          SgExpression* boxReferenceExpression = argumentList->get_expressions()[3];
          SgVarRefExp* boxVarRefExp = isSgVarRefExp(boxReferenceExpression);
          ROSE_ASSERT(boxVarRefExp != NULL);

          printf ("DONE: processing inputs to stencil operator \n");

          ROSE_ASSERT(stencilVarRefExp->get_symbol() != NULL);
          SgInitializedName* stencilInitializedName = stencilVarRefExp->get_symbol()->get_declaration();
          ROSE_ASSERT(stencilInitializedName != NULL);

          string stencilName = stencilInitializedName->get_name();

          printf ("stencilName = %s \n",stencilName.c_str());

          std::map<std::string,StencilFSM*> & stencilMap = traversal.get_stencilMap();
          
          ROSE_ASSERT(stencilMap.find(stencilName) != stencilMap.end());

          StencilFSM* stencilFSM = stencilMap[stencilName];
          ROSE_ASSERT(stencilFSM != NULL);

       // DQ (2/8/2015): Moved out of loop.
          int stencilDimension = stencilFSM->stencilDimension();
          ROSE_ASSERT(stencilDimension > 0);

       // These are computed values.
          printf ("Stencil dimension = %d \n",stencilDimension);
          printf ("Stencil width     = %d \n",stencilFSM->stencilWidth());

          std::vector<std::pair<StencilOffsetFSM,double> > & stencilPointList = stencilFSM->stencilPointList;

       // This is the scope where the stencil operator is evaluated.
          SgScopeStatement* outerScope = associatedStatement->get_scope();
          ROSE_ASSERT(outerScope != NULL);

          SgVariableSymbol* indexVariableSymbol_X     = NULL;
          SgVariableSymbol* indexVariableSymbol_Y     = NULL;
          SgVariableSymbol* indexVariableSymbol_Z     = NULL;
          SgVariableSymbol* arraySizeVariableSymbol_X = NULL;
          SgVariableSymbol* arraySizeVariableSymbol_Y = NULL;

          SgVariableSymbol* destinationVariableSymbol = destinationArrayVarRefExp->get_symbol();
          ROSE_ASSERT(destinationVariableSymbol != NULL);
          SgVariableSymbol* sourceVariableSymbol = sourceArrayVarRefExp->get_symbol();
          ROSE_ASSERT(sourceVariableSymbol != NULL);
          SgVariableSymbol* boxVariableSymbol = boxVarRefExp->get_symbol();
          ROSE_ASSERT(boxVariableSymbol != NULL);

       // This can be important in handling of comments and CPP directives.
          bool autoMovePreprocessingInfo = true;

          SgStatement* lastStatement = associatedStatement;
          if (generateLowlevelCode == true)
             {
#if 1
               SgVariableDeclaration* sourceDataPointerVariableDeclaration = buildDataPointer("sourceDataPointer",sourceVariableSymbol,outerScope);
#else
            // Optionally build a pointer variable so that we can optionally support a C style indexing for the DTEC DSL blocks.
               SgExpression* sourcePointerExp = buildMemberFunctionCall(sourceVariableSymbol,"getPointer",NULL,false);
               ROSE_ASSERT(sourcePointerExp != NULL);
               SgAssignInitializer* assignInitializer = SageBuilder::buildAssignInitializer_nfi(sourcePointerExp);
               ROSE_ASSERT(assignInitializer != NULL);

            // Build the variable declaration for the pointer to the data.
               string sourcePointerName = "sourceDataPointer";
               SgVariableDeclaration* sourceDataPointerVariableDeclaration  = SageBuilder::buildVariableDeclaration_nfi(sourcePointerName,SageBuilder::buildPointerType(SageBuilder::buildDoubleType()),assignInitializer,outerScope);
               ROSE_ASSERT(sourceDataPointerVariableDeclaration != NULL);
#endif

            // SageInterface::insertStatementAfter(associatedStatement,forStatementScope,autoMovePreprocessingInfo);
               SageInterface::insertStatementAfter(associatedStatement,sourceDataPointerVariableDeclaration,autoMovePreprocessingInfo);

               SgVariableDeclaration* destinationDataPointerVariableDeclaration = buildDataPointer("destinationDataPointer",destinationVariableSymbol,outerScope);
               SageInterface::insertStatementAfter(sourceDataPointerVariableDeclaration,destinationDataPointerVariableDeclaration,autoMovePreprocessingInfo);

            // Reset the variable symbols we will use in the buildStencilPoint() function.
               sourceVariableSymbol      = SageInterface::getFirstVarSym(sourceDataPointerVariableDeclaration);
               destinationVariableSymbol = SageInterface::getFirstVarSym(destinationDataPointerVariableDeclaration);

               lastStatement = destinationDataPointerVariableDeclaration;
             }

          SgBasicBlock* innerLoopBody = NULL;
       // SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,sourceVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y);
          SgForStatement* loopNest = buildLoopNest(stencilFSM->stencilDimension(),innerLoopBody,boxVariableSymbol,indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y);
          ROSE_ASSERT(innerLoopBody != NULL);

          ROSE_ASSERT(lastStatement != NULL);
          SageInterface::insertStatementAfter(lastStatement,loopNest,autoMovePreprocessingInfo);

       // Mark this as compiler generated so that it will not be unparsed.
          associatedStatement->get_file_info()->setCompilerGenerated();

       // Form an array of AST subtrees to represent the different points in the stencil.
       // vector<SgFunctionCallExp*> stencilSubTreeArray;
          vector<SgExpression*> stencilSubTreeArray;
          for (size_t j = 0; j < stencilPointList.size(); j++)
             {
#if 0
               printf ("Forming stencil point subtree for offsetValues[0] = %3d [1] = %3d [2] = %3d \n",stencilPointList[j].first.offsetValues[0],stencilPointList[j].first.offsetValues[1],stencilPointList[j].first.offsetValues[2]);
#endif
               StencilOffsetFSM* stencilOffsetFSM = &(stencilPointList[j].first);
               double stencilCoeficient           = stencilPointList[j].second;

            // SgFunctionCallExp* stencilSubTree = buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilFSM->stencilDimension());
               SgExpression* stencilSubTree = 
                    buildStencilPoint(stencilOffsetFSM,stencilCoeficient,stencilDimension,sourceVariableSymbol,
                         indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode);

               ROSE_ASSERT(stencilSubTree != NULL);

               stencilSubTreeArray.push_back(stencilSubTree);
             }

       // Construct the lhs value for the stencil inner loop statement.
          StencilOffsetFSM* stencilOffsetFSM_lhs = new StencilOffsetFSM(0,0,0);
          double stencilCoeficient_lhs = 1.00;
          SgExpression* stencil_lhs = buildStencilPoint(stencilOffsetFSM_lhs,stencilCoeficient_lhs,stencilDimension,destinationVariableSymbol,
                                           indexVariableSymbol_X,indexVariableSymbol_Y,indexVariableSymbol_Z,arraySizeVariableSymbol_X,arraySizeVariableSymbol_Y,generateLowlevelCode);
          ROSE_ASSERT(stencil_lhs != NULL);

       // Assemble the stencilSubTreeArray into a single expression.
          SgExprStatement* stencilStatement = assembleStencilSubTreeArray(stencil_lhs,stencilSubTreeArray,stencilDimension,destinationVariableSymbol);
          SageInterface::appendStatement(stencilStatement,innerLoopBody);
        }
   }
void
FunctionCallNormalization::visit( SgNode *astNode )
   {
     SgStatement *stm = isSgStatement( astNode );

     // visiting all statements which may contain function calls;
     // Note 1: we do not look at the body of loops, or sequences of statements, but only
     // at statements which may contain directly function calls; all other statements will have their component parts visited in turn
     if ( isSgEnumDeclaration( astNode ) || isSgVariableDeclaration( astNode ) || isSgVariableDefinition( astNode ) ||
                               isSgExprStatement( astNode ) || isSgForStatement( astNode ) || isSgReturnStmt( astNode ) ||
                               isSgSwitchStatement( astNode ) )
        {
       // maintain the mappings from function calls to expressions (variables or dereferenced variables)
          map<SgFunctionCallExp *, SgExpression *> fct2Var;

       // list of Declaration structures, one structure per function call
          DeclarationPtrList declarations;
          bool variablesDefined = false;
             
       // list of function calls, in correnspondence with the inForTest list below
          list<SgNode*> functionCallExpList;
          list<bool> inForTest;

          SgForStatement *forStm = isSgForStatement( stm );
          SgSwitchStatement *swStm = isSgSwitchStatement( stm );
          list<SgNode*> temp1, temp2;

       // for-loops and Switch statements have conditions ( and increment ) expressed as expressions
       // and not as standalone statements; this will change in future Sage versions
       // TODO: when for-loops and switch statements have conditions expressed via SgStatements
       // these cases won't be treated separately; however, do-while will have condition expressed via expression
       // so that will be the only exceptional case to be treated separately
          if (forStm != NULL)
             {
            // create a list of function calls in the condition and increment expression
            // the order is important, the condition is evaluated after the increment expression
            // temp1 = FEOQueryForNodes( forStm->get_increment_expr_root(), V_SgFunctionCallExp );
            // temp2 = FEOQueryForNodes( forStm->get_test_expr_root(), V_SgFunctionCallExp );
               temp1 = FEOQueryForNodes( forStm->get_increment(), V_SgFunctionCallExp );
               temp2 = FEOQueryForNodes( forStm->get_test_expr(), V_SgFunctionCallExp );
               functionCallExpList = temp1;
               functionCallExpList.splice( functionCallExpList.end(), temp2 );
             }
            else
             {
               if (swStm != NULL)
                  {
                 // create a list of function calls in the condition in the order of function evaluation
                 // DQ (11/23/2005): Fixed SgSwitchStmt to have SgStatement for conditional.
                 // list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector_root(), V_SgFunctionCallExp );
                    list<SgNode*> temp1 = FEOQueryForNodes( swStm->get_item_selector(), V_SgFunctionCallExp );
                    functionCallExpList = temp1;
                  }
                 else
                  {
                 // create a list of function calls in the statement in the order of function evaluation
                    functionCallExpList = FEOQueryForNodes( stm, V_SgFunctionCallExp );
                  }
             }

         // all function calls get replaced: this is because they can occur in expressions (e.g. for-loops)
         // which makes it difficult to build control flow graphs
         if ( functionCallExpList.size() > 0 )
           {
             cout << "--------------------------------------\nStatement ";
             cout << stm->unparseToString() << "\n";;
             
             // traverse the list of function calls in the current statement, generate a structure  Declaration for each call
             // put these structures in a list to be inserted in the code later
             for ( list<SgNode *>::iterator i = functionCallExpList.begin(); i != functionCallExpList.end(); i++ )
               {
                 variablesDefined = true;

                 // get function call exp
                 SgFunctionCallExp *exp = isSgFunctionCallExp( *i );
                 ROSE_ASSERT ( exp );
                 
                 // get type of expression, generate unique variable name
                 SgType *expType = exp->get_type();
                 ROSE_ASSERT ( expType );
                 Sg_File_Info *location = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 ROSE_ASSERT ( location );
                 ostringstream os;
                 os << "__tempVar__" << location;
                 SgName name = os.str().c_str();

                 // replace previous variable bindings in the AST
                 SgExprListExp *paramsList = exp->get_args();
                 SgExpression *function = exp->get_function();
                 ROSE_ASSERT ( paramsList && function );
                 replaceFunctionCallsInExpression( paramsList, fct2Var );
                 replaceFunctionCallsInExpression( function, fct2Var );

                 // duplicate function call expression, for the initialization declaration and the assignment
                 SgTreeCopy treeCopy;
                 SgFunctionCallExp *newExpInit = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpInit );
                 SgFunctionCallExp *newExpAssign = isSgFunctionCallExp( exp->copy( treeCopy ) );
                 ROSE_ASSERT ( newExpAssign );

                 // variables
                 Sg_File_Info *initLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *nonInitLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode(),
                   *assignLoc = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
                 Declaration *newDecl = new Declaration();
                 SgStatement *nonInitVarDeclaration, *initVarDeclaration, *assignStmt;
                 SgExpression *varRefExp;
                 SgVariableSymbol *varSymbol;
                 SgAssignOp *assignOp;
                 SgInitializedName *initName;

                 bool pointerTypeNeeded = false;

                 // mark whether to replace inside or outside of ForStatement due to the
                 // function call being inside the test or the increment for a for-loop statement
                 // the 'inForTest' list is in 1:1  ordered correpondence with the 'declarations' list
                 if ( forStm )
                   {
        // SgExpressionRoot
                  //   *testExp = isSgForStatement( astNode )->get_test_expr_root(),
                  //   *incrExp = isSgForStatement( astNode )->get_increment_expr_root();
                     SgExpression
                       *testExp = isSgForStatement( astNode )->get_test_expr(),
                       *incrExp = isSgForStatement( astNode )->get_increment();
                     SgNode *up = exp;
                     while ( up && up != testExp && up != incrExp )
                       up = up->get_parent();
                     ROSE_ASSERT ( up );

                     // function call is in the condition of the for-loop
                     if ( up == testExp )
                       inForTest.push_back( true );
                     // function call is in the increment expression
                     else
                       {
                         inForTest.push_back( false );

                         // for increment expressions we need to be able to reassign the return value
                         // of the function; if the ret value is a reference, we need to generate a
                         // pointer of that type (to be able to reassign it later)
                         if ( isSgReferenceType( expType ) )
                           pointerTypeNeeded = true;
                       }
                   }

                 // for do-while statements:  we need to generate declaration of type pointer to be able to have
                 // non-assigned references when looping and assign them at the end of the body of the loop
                 if ( isSgDoWhileStmt( stm->get_parent() ) && isSgReferenceType( expType ) )
                   pointerTypeNeeded = true;

                 // we have a function call returning a reference and we can't initialize the variable
                 // at the point of declaration; we need to define the variable as a pointer
                 if ( pointerTypeNeeded )
                   {
                     // create 'address of' term for function expression, so we can assign it to the pointer
                     SgAddressOfOp *addressOp = new SgAddressOfOp( assignLoc, newExpAssign, expType );

                     // create noninitialized declaration
                     SgType *base = isSgReferenceType( expType )->get_base_type();
                     ROSE_ASSERT( base );
                     SgPointerType *ptrType = SgPointerType::createType( isSgReferenceType( expType )->get_base_type() );
                     ROSE_ASSERT ( ptrType );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, ptrType );

                     // create assignment (symbol, varRefExp, assignment)
                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );

                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );

                     SgPointerDerefExp *ptrDeref= new SgPointerDerefExp( assignLoc, varRefExp, expType );
                     ROSE_ASSERT ( isSgExpression( varRefExp ) && ptrDeref );
                     assignOp = new SgAssignOp( assignLoc, varRefExp, addressOp, ptrType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt &&  nonInitVarDeclaration );
           
                     // we don't need initialized declarations in this case
                     initVarDeclaration = NULL;

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, ptrDeref ) );
                   }
                 else
                   {
                     // create (non- &)initialized declarations, initialized name & symbol
                     SgAssignInitializer *declInit = new SgAssignInitializer( initLoc, newExpInit, expType );
                     ROSE_ASSERT ( declInit );
                     initVarDeclaration = new SgVariableDeclaration ( initLoc, name, expType, declInit );
                     nonInitVarDeclaration = new SgVariableDeclaration ( nonInitLoc, name, expType );
                     ROSE_ASSERT ( initVarDeclaration && nonInitVarDeclaration );

                     initName = isSgVariableDeclaration( nonInitVarDeclaration )->get_decl_item( name );
                     ROSE_ASSERT ( initName );
                     newExpInit->set_parent( initName );
                     varSymbol = new SgVariableSymbol( initName );
                     ROSE_ASSERT ( varSymbol );

                     // create variable ref exp
                     varRefExp = new SgVarRefExp( assignLoc, varSymbol );
                     ROSE_ASSERT ( isSgVarRefExp( varRefExp ) );

                     // create the assignment
                     assignOp = new SgAssignOp( assignLoc, varRefExp, newExpAssign, expType );
                     assignStmt = new SgExprStatement( assignLoc, assignOp );
                     ROSE_ASSERT ( assignStmt );

                     initVarDeclaration->set_parent( stm->get_parent() );
                     isSgVariableDeclaration( initVarDeclaration )->set_definingDeclaration( isSgDeclarationStatement( initVarDeclaration ) );

                     // save new mapping
                     fct2Var.insert( Fct2Var( exp, varRefExp ) );
                   }

                 // save the 'declaration' structure, with all 3 statements and the variable name
                 newDecl->nonInitVarDeclaration = nonInitVarDeclaration;
                 newDecl->initVarDeclaration = initVarDeclaration;
                 newDecl->assignment = assignStmt;
                 newDecl->name = name;
                 nonInitVarDeclaration->set_parent( stm->get_parent() );
                 isSgVariableDeclaration( nonInitVarDeclaration )->set_definingDeclaration( isSgVariableDeclaration( nonInitVarDeclaration ) );
                 assignStmt->set_parent( stm->get_parent() );
                 declarations.push_back( newDecl );
               } // end for
           } // end if  fct calls in crt stmt > 1

         SgScopeStatement *scope = stm->get_scope();
         ROSE_ASSERT ( scope );
         
         // insert function bindings to variables; each 'declaration' structure in the list
         // corresponds to one function call
         for ( DeclarationPtrList::iterator i = declarations.begin(); i != declarations.end(); i++ )
           {
             Declaration *d = *i;
             ROSE_ASSERT ( d && d->assignment && d->nonInitVarDeclaration );

             // if the current statement is a for-loop, we insert Declarations before & in the loop body, depending on the case
             if ( forStm )
               {
                 SgStatement *parentScope = isSgStatement( stm->get_scope() );
                 SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfFor(forStm);
                 ROSE_ASSERT ( !inForTest.empty() && body && parentScope );
                 // SgStatementPtrList &list = body->get_statements();

                 // if function call is in loop condition, we add initialized variable before the loop and at its end
                 // hoist initialized variable declarations outside the loop
                 if ( inForTest.front() )
                   {
                     ROSE_ASSERT ( d->initVarDeclaration );
                     parentScope->insert_statement( stm, d->initVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
                 // function call is in loop post increment so add noninitialized variable decls above the loop
                 else
                   {
                     parentScope->insert_statement( stm, d->nonInitVarDeclaration );

                     // set the scope of the initializedName
                     SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( isSgScopeStatement( parentScope ) );
                     ROSE_ASSERT ( initName->get_scope() );
                   }

                 // in a for-loop, always insert assignments at the end of the loop
                 body->get_statements().push_back( d->assignment );
                 d->assignment->set_parent( body );

                 // remove marker
                 inForTest.pop_front();
               }
             else
               {
                 // look at the type of the enclosing scope
                 switch ( scope->variantT() )
                   {

                     // while stmts have to repeat the function calls at the end of the loop;
                     // note there is no "break" statement, since we want to also add initialized
                     // declarations before the while-loop
                   case V_SgWhileStmt:
                     {
                       // assignments need to be inserted at the end of each while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfWhile(isSgWhileStmt( scope ) );
                       ROSE_ASSERT ( body );
                       d->assignment->set_parent( body );
                       body->get_statements().push_back( d->assignment );
                     }

                     // SgForInitStatement has scope SgForStatement, move declarations before the for loop;
                     // same thing if the enclosing scope is an If, or Switch statement
                   case V_SgForStatement:
                   case V_SgIfStmt:
                   case V_SgSwitchStatement:
                     {
                       // adding bindings (initialized variable declarations only, not assignments)
                       // outside the statement, in the parent scope
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->initVarDeclaration, true );\

                       // setting the scope of the initializedName
                       SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );
                     }
                     break;

                     // do-while needs noninitialized declarations before the loop, with assignments inside the loop
                   case V_SgDoWhileStmt:
                     {
                       // adding noninitialized variable declarations before the body of the loop
                       SgStatement *parentScope = isSgStatement( scope->get_parent() );
                       ROSE_ASSERT ( parentScope );
                       parentScope->insert_statement( scope, d->nonInitVarDeclaration, true );

                       // initialized name scope setting
                       SgInitializedName *initName = isSgVariableDeclaration( d->nonInitVarDeclaration )->get_decl_item( d->name );
                       ROSE_ASSERT ( initName );
                       initName->set_scope( scope->get_scope() );
                       ROSE_ASSERT ( initName->get_scope() );

                       // adding assignemts at the end of the do-while loop
                       SgBasicBlock *body = SageInterface::ensureBasicBlockAsBodyOfDoWhile( isSgDoWhileStmt(scope) );
                       ROSE_ASSERT ( body );
                       body->get_statements().push_back( d->assignment );
                       d->assignment->set_parent(body);
                     }
                     break;

                     // for all other scopes, add bindings ( initialized declarations ) before the statement, in the same scope
                   default:
                     scope->insert_statement( stm, d->initVarDeclaration, true );

                     // initialized name scope setting
                     SgInitializedName *initName = isSgVariableDeclaration( d->initVarDeclaration )->get_decl_item( d->name );
                     ROSE_ASSERT ( initName );
                     initName->set_scope( scope->get_scope() );
                     ROSE_ASSERT ( initName->get_scope() );
                   }
               }
           }
         
         // once we have inserted all variable declarations, we need to replace top-level calls in the original statement
         if ( variablesDefined )
           {
             cout << "\tReplacing in the expression " << stm->unparseToString() << "\n";

             // for ForStatements, replace expressions in condition and increment expressions,
             // not in the body, since those get replace later
             if ( forStm )
               {
         // SgExpressionRoot *testExp = forStm->get_test_expr_root(), *incrExp = forStm->get_increment_expr_root();
            SgExpression *testExp = forStm->get_test_expr(), *incrExp = forStm->get_increment();
            replaceFunctionCallsInExpression( incrExp, fct2Var );
            replaceFunctionCallsInExpression( testExp, fct2Var );
               }
             else
               if ( swStm )
             {
            // DQ (11/23/2005): Fixed SgSwitch to permit use of declaration for conditional
            // replaceFunctionCallsInExpression( swStm->get_item_selector_root(), fct2Var );
               replaceFunctionCallsInExpression( swStm->get_item_selector(), fct2Var );
             }
               else
             replaceFunctionCallsInExpression( stm, fct2Var );
           }
       } // end if isSgStatement block
   }
Ejemplo n.º 7
0
InheritedAttribute
visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute)
   {
    Sg_File_Info* s = n->get_startOfConstruct();
    Sg_File_Info* e = n->get_endOfConstruct();
    Sg_File_Info* f = n->get_file_info();
    for(int x=0; x < inheritedAttribute.depth; ++x) {
        printf(" ");
    }
    if(s != NULL && e != NULL && !isSgLabelStatement(n)) { 
        printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(),  verbose ? n->unparseToString().c_str() : "" );
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
        SgExprStatement * exprStmt = isSgExprStatement(n);
        if(exprStmt != NULL) {
            printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name());           
            SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression());
            if(fcall != NULL) {
               SgExpression * funcExpr = fcall->get_function();
               if(funcExpr != NULL) {
                    printf(" [function expr: %s]", funcExpr->class_name().c_str());
               }
               SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration();
               if(fdecl != NULL) {
                    printf(" [called function: %s]", fdecl->get_name().str());
               }
            }
        }
        if(isSgFunctionDeclaration(n)) {
            printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str());
        }
        SgStatement * sgStmt = isSgStatement(n);
        if(sgStmt != NULL) {
            printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope());
        }
        //SgLabelStatement * lblStmt = isSgLabelStatement(n);
        //if(lblStmt != NULL) {
        //    SgStatement * lblStmt2 = lblStmt->get_statement();
        //}
    } else if (f != NULL) {
		SgInitializedName * iname = isSgInitializedName(n);
		if(iname != NULL) {
            SgType* inameType = iname->get_type();
			printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str());
			SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent());
			if(ds != NULL) {
				if(ds->get_declarationModifier().get_storageModifier().isStatic()) {
					printf(" static");
				}
			}
			
			SgArrayType * art = isSgArrayType(iname->get_type());
			if(art != NULL) {
				printf(" %d", art->get_rank());
			}
			
			printf("]");
            if(isSgAsmDwarfConstruct(n)) {
                printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
            }
            } else {
        	printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : "");
		}
    } else {
        printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : "");
        if(isSgAsmDwarfConstruct(n)) {
            printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str());
        }
    }
    printf(" succ# %lu", n->get_numberOfTraversalSuccessors());
	printf("\n");
     return InheritedAttribute(inheritedAttribute.depth+1);
   }
Ejemplo n.º 8
0
// schroder3 (2016-07-12): Returns the mangled stable/portable scope of the given statement.
//  FIXME: There are some places (see comment below) in the rose mangling which add the address
//  of the AST node to the mangled name. Due to this, this function currently does not return
//  a stable/portable mangled scope in all cases.
string getScopeAsMangledStableString(SgLocatedNode* stmt) {
  SgNode* parent = stmt;
  // Go up in the AST and look for the closest scope of the given statement:
  while((parent = parent->get_parent())) {
    SgStatement* declScope = 0;
    // Look for a FunctionParameterList or a ScopeStatement:
    if(SgFunctionParameterList* functionParams = isSgFunctionParameterList(parent)) {
      // Special case: Function parameter: The scope is
      //  the corresponding function definition/declaration:
      //  Function declaration is enough, because we only need the function
      //  name and types to create the mangled scope.
      declScope = isSgFunctionDeclaration(functionParams->get_parent());
      ROSE_ASSERT(declScope);
    }
    else if(SgScopeStatement* scope = isSgScopeStatement(parent)) {
      declScope = scope;
    }

    if(declScope) {
      // Found the scope of the given statement.

      // In theory it should work by using
      //   return mangleQualifiersToString(declScope);
      //  but there are the following problems in functions that get called by mangleQualifiersToString(...):
      //   1) SgFunctionDeclaration::get_mangled_name() mangles every function with the name "main" (even
      //      those that are not in the global scope) as
      //       main_<address of the AST node>
      //      .
      //   2) SgTemplateArgument::get_mangled_name(...) adds the address of a AST node to the mangled
      //      name if the template argument is a type and it's parent is a SgTemplateInstantiationDecl.
      //  Especially because of the address we can not use this as a portable scope representation.
      //
      // Workaround for 1): Replace the name of every function definition/declaration that has the name "main" and that
      //  is a direct or indirect scope parent of declScope by a temporary name that is different from "main".
      //  Then use mangleQualifiersToString(...) to mangle the scope. Finally, replace occurrences of the
      //  temporary name in the mangled-scope by "main".
      //
      // Workaround for 2): Currently none.

      // Workaround for 1):
      string tempName = string("(]"); // Something that does not appear in a function or operator name.
      SgName tempSgName = SgName(tempName);
      SgName mainSgName = SgName("main");
      vector<SgFunctionDeclaration*> main_func_decls;
      SgStatement* scopeParent = declScope;
      // Collect all functions that have "main" as their name and replace their name
      //  by the temporary name:
      while((scopeParent = scopeParent->get_scope()) && !isSgGlobal(scopeParent)) {
        SgFunctionDefinition* funcDef = isSgFunctionDefinition(scopeParent);
        if(SgFunctionDeclaration* funcDecl = funcDef ? funcDef->get_declaration() :0) {
          if(funcDecl->get_name() == tempSgName) {
            // There is a function whose name contains tempName. The mangled scope
            //  will probably be wrong:
            throw SPRAY::Exception("Found function whose name contains the reserved text \"" + tempName + "\". "
                                   "Mangling of scope is not possible.");
          }
          else if(funcDecl->get_name() == mainSgName) {
            main_func_decls.push_back(funcDecl);
            funcDecl->set_name(tempSgName);
          }
        }
      }

      // Create the mangled-scope:
      string mangled_scope;
      if(SgFunctionDeclaration* fundDecl = isSgFunctionDeclaration(declScope)) {
        // Special case: A function decl node is not a scope statement:
        mangled_scope = fundDecl->get_mangled_name();
      }
      else if(SgScopeStatement* scope = isSgScopeStatement(declScope)) {
        mangled_scope = mangleQualifiersToString(scope);
      }
      else {
        ROSE_ASSERT(false);
      }

      // Replace occurrences of the temporary name in the mangled-scope
      //  by "main" and restore the previous name ("main") of the functions:
      for(vector<SgFunctionDeclaration*>::const_iterator i = main_func_decls.begin();
          i != main_func_decls.end(); ++i
      ) {
          (*i)->set_name(mainSgName);
          size_t start = mangled_scope.find(tempName);
          // TODO: Functions and local classes (and more?) are mangled as L0R, L1R, ... and not with their
          //  scope. Because of that, there is no corresponding temporary name in
          //  the mangled-scope sometimes:
          if(start != string::npos) {
            mangled_scope.replace(start, tempName.length(), string("main"));
          }
      }
      if(mangled_scope.find(tempName) != string::npos) {
        // There is a function whose name contains tempName. Because we abort above if there is such a function
        //  this should not happen.
        ROSE_ASSERT(false);
      }
      return mangled_scope;
    }
  }
  return string("");
}