Esempio n. 1
0
SgFunctionDeclaration *CudaOutliner::createFuncSkeleton (const string& name, SgType* ret_type,
							 SgFunctionParameterList* params, SgScopeStatement* scope)
{
  ROSE_ASSERT(scope != NULL);
  ROSE_ASSERT(isSgGlobal(scope)!=NULL);
  SgFunctionDeclaration* func;
  SgProcedureHeaderStatement* fortranRoutine;
  if (SageInterface::is_Fortran_language())
    {
      fortranRoutine = SageBuilder::buildProcedureHeaderStatement(name.c_str(),ret_type, params, SgProcedureHeaderStatement::e_subroutine_subprogram_kind,scope);
      func = isSgFunctionDeclaration(fortranRoutine);
    }
  else
    {
      func = SageBuilder::buildDefiningFunctionDeclaration(name,ret_type,params,scope);
    }

  ROSE_ASSERT (func != NULL);
  SgFunctionSymbol* func_symbol = scope->lookup_function_symbol(func->get_name());
  ROSE_ASSERT(func_symbol != NULL);
  if (0)//Outliner::enable_debug)
    {
      printf("Found function symbol in %p for function:%s\n",scope,func->get_name().getString().c_str());
    }
  return func;
}
Esempio n. 2
0
void SecureFunctionTypeTraversal::visit(SgNode* sgn)
{
    if(isSgFunctionCallExp(sgn)) {
        SgFunctionDeclaration* fndecl = isSgFunctionCallExp(sgn)->getAssociatedFunctionDeclaration();
        string filename = fndecl->get_file_info()->get_filename();
        if(filename != "compilerGenerated") {
            StringUtility::FileNameClassification classification;
            classification = StringUtility::classifyFileName(filename, this->sourcedir, this->trustedlibs);
            //StringUtility::FileNameLocation filetypeclassification = classification.getLocation();
            //cout << sgn->unparseToString() <<  filename << " : "  << classification.getLocation() << ", " <<  classification.getLibrary() << endl;
            bool isSecure;
            if(untrustedFunctions.find(fndecl->get_name().getString()) != untrustedFunctions.end()) {
                isSecure = false;
            }                 
                
            else if(classification.isLibraryCode() || classification.isUserCode()) {
                isSecure = true;
            }

            else {
                isSecure = false;
            }
            AstAttribute* attr = dynamic_cast<AstAttribute*> ( new SecureFunctionType(isSecure) );
            sgn->setAttribute("SECURE_TYPE", attr);            
        }
    }
}
Esempio n. 3
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameFunctionDeclarationNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

  SgFunctionDeclaration *sageFunctionDeclaration =
    isSgFunctionDeclaration (astNode);

  if (sageFunctionDeclaration != NULL)
    {
      string name = sageFunctionDeclaration->get_name ().str ();

#if DEBUG_NAMEQUERY
      printf ("In case: CLASS_DECL_STMT name = %s \n", name.c_str ());
#endif

      returnNameList.push_back (name);
    }


  return returnNameList;

}                               /* End function queryNameFunctionDeclarationNames() */
Esempio n. 4
0
string
Doxygen::getDeclStmtName(SgDeclarationStatement *st)
{
    SgFunctionDeclaration *fn = isSgFunctionDeclaration(st);
    SgVariableDeclaration *vn = isSgVariableDeclaration(st);
    SgClassDeclaration *cn = isSgClassDeclaration(st);
    if (fn)
    {
        return fn->get_name().str();
    }
    else if (vn)
    {
        /* XXX The following is a bit dodgy since single
         * SgVariableDeclaration may declare multiple
         * variables.  But doxygen doesn't handle this case
         * properly.  A useful transform may split up the
         * SgVariableDeclaration for doxygen's sake */
        return (*(vn->get_variables().begin()))->get_name().str();
    }
    else if (cn)
    {
        return cn->get_name().str();
    }
    else
    {
        fprintf(stderr, "Cannot handle this case: %s\n", st->sage_class_name());
        abort();
    }
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
        std::string filename;

    SgProject *project = frontend(argc, argv);
    EDefUse *edu=new EDefUse(project);
    if (edu->run(false)==1)
        {
              std::cerr<<"createFDG:: DFAnalysis failed!   -- edu->run(false)==0"<<endl;
              exit(0);
        }
                std::vector<InterproceduralInfo*> ip;

    list < SgNode * >functionDeclarations = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);

    for (list < SgNode * >::iterator i = functionDeclarations.begin(); i != functionDeclarations.end(); i++)
    {
        ControlDependenceGraph *cdg;
        DataDependenceGraph *ddg;
        InterproceduralInfo *ipi;

        SgFunctionDeclaration *fD = isSgFunctionDeclaration(*i);

        // SGFunctionDefinition * fDef;
        ROSE_ASSERT(fD != NULL);

        // CI (01/08/2007): A missing function definition is an indicator to a 
        // 
        // 
        // librarycall. 
        // * An other possibility would be a programmer-mistake, which we
        // don't treat at this point.  // I assume librarycall
        if (fD->get_definition() == NULL)
        {
        }
        else
        {
            // get the control depenence for this function
                                                ipi=new InterproceduralInfo(fD);

            ROSE_ASSERT(ipi != NULL);
            
            ddg = new DataDependenceGraph(fD->get_definition(),edu);

            // get control dependence for this function defintion
            cdg = new ControlDependenceGraph(fD->get_definition(), ipi);
            cdg->computeAdditionalFunctioncallDepencencies();
                                                cdg->computeInterproceduralInformation(ipi);
//                                              cdg->debugCoutNodeList();
            FunctionDependenceGraph *fdg=new FunctionDependenceGraph(cdg,ddg,ipi);

            filename =
                                                                (fD->get_definition()->get_file_info()->get_filenameString ())
                 + "." +
                (fD->get_name().getString()) + ".fdg.dot";
            fdg->writeDot((char *)filename.c_str());
            
        }   
    }
}
Esempio n. 6
0
static string
chooseConstructor(SgProject* project)
{
  static const char * const d_constructor_names[] = {
    "init",
    "initialize",
    "prepare",
    "ready",
    "outfit",
    NULL
  };
  static 
    FunctionNameSet functionNames;
  Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);
  for(Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); ++i) {
    SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
    ROSE_ASSERT(functionDeclaration != NULL);
    functionNames.insert(functionDeclaration->get_name().str());
  }
  FunctionNameSet::iterator notFound = functionNames.end();
  for(const char * const *j = d_constructor_names; *j ; ++j) {
    string candidate = *j;
    if (functionNames.find(candidate) == notFound) return candidate;
  }
  return "";
}
Esempio n. 7
0
void
RtedTransformation::insertVariableCreateInitForParams( SgFunctionDefinition& fndef)
{
    SgBasicBlock* body = fndef.get_body();
    ROSE_ASSERT( body);

    SgInitializedNamePtrList names = fndef.get_declaration()->get_parameterList()->get_args();

    BOOST_FOREACH( SgInitializedName* param, names)
    {
      SgType* initType = param->get_type();

      // nov2010 code:
      // reference variables don't allocate new memory
      // if we call createVariable the RTS will think it's a double
      // allocation fault

      // \pp we skip array types because they will be handled elsewhere
      // \todo not sure if this is correct here, b/c arrays would decay
      //       to pointers anyway. However, this decay is not represented
      //       in the nov2010 code, thus we skip these initializations
      //       here.
      if ( isSgReferenceType(initType) || isSgArrayType(skip_ModifierType(initType)) )
        continue;

      SgFunctionDeclaration* fndecl = fndef.get_declaration();
      std::cerr << ">>> " << fndecl->get_name() << std::endl;
      ROSE_ASSERT(isSgFunctionDefinition(param->get_scope()));

      body->prepend_statement( buildVariableCreateCallStmt(param, true) );
    }
Esempio n. 8
0
int main(int argc, char *argv[])
{
    std::string filename;

    SgProject *project = frontend(argc, argv);
    std::vector<InterproceduralInfo*> ip;

// list < SgNode * >functionDeclarations = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);
    NodeQuerySynthesizedAttributeType functionDeclarations = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);

// for (list < SgNode * >::iterator i = functionDeclarations.begin(); i != functionDeclarations.end(); i++)
    for (NodeQuerySynthesizedAttributeType::iterator i = functionDeclarations.begin(); i != functionDeclarations.end(); i++)
    {
        ControlDependenceGraph *cdg;
        InterproceduralInfo *ipi;

        SgFunctionDeclaration *fD = isSgFunctionDeclaration(*i);

        // SGFunctionDefinition * fDef;
        ROSE_ASSERT(fD != NULL);

        // CI (01/08/2007): A missing function definition is an indicator to a
        //
        //
        // librarycall.
        // * An other possibility would be a programmer-mistake, which we
        // don't treat at this point.  // I assume librarycall
        if (fD->get_definition() == NULL)
        {
        }
        else
        {
            // get the control depenence for this function
            ipi=new InterproceduralInfo(fD);

            ROSE_ASSERT(ipi != NULL);

            // get control dependence for this function defintion
            cdg = new ControlDependenceGraph(fD->get_definition(), ipi);
            cdg->computeAdditionalFunctioncallDepencencies();
//						cdg->computeInterproceduralInformation(ipi);
//						cdg->debugCoutNodeList();

// Liao, Feb. 7/2008,
//strip off absolute path to avoid polluting the source tree with generated .dot files
            filename = StringUtility::stripPathFromFileName((fD->get_definition()->get_file_info()->get_filenameString ()))
                       + "." +
                       (fD->get_name().getString()) + ".cdg.dot";
            cdg->writeDot((char *)filename.c_str());

        }
    }
}
void
Traversal::processNode(SgNode* n, SynthesizedAttribute& synthesizedAttribute )
  {
    // Look for names of functions
    SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(n);
    if (functionDeclaration != NULL)
    {
        string name = functionDeclaration->get_name().str();

        #if DEBUG > 3
          SgFunctionDefinition* functionDefinition =
              functionDeclaration->get_definition();
          if (functionDefinition != NULL)
              printf ("SgFunctionDefinition: %s \n",name.c_str());
          else
              printf ("SgFunctionDeclaration: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }

    SgInitializedName* initializedName = isSgInitializedName(n);
    if (initializedName != NULL)
    {
        string name = initializedName->get_name().str();

        #if DEBUG > 3
          printf ("SgInitializedName: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }

    SgNamespaceDeclarationStatement* namespaceDeclaration = isSgNamespaceDeclarationStatement(n);
    if (namespaceDeclaration != NULL)
    {
        string name = namespaceDeclaration->get_name().str();

        #if DEBUG > 3
          printf ("SgNamespaceDeclaration: %s \n",name.c_str());
        #endif

        synthesizedAttribute.nameList.push_back(
            NameStructureType(name,n));
        // nameSet.insert(name);
    }
  }
Esempio n. 10
0
void PreAndPostOrderTraversal::preOrderVisit(SgNode* n) {

        SgFunctionDeclaration * dec = isSgFunctionDeclaration(n);
        if (dec != NULL) {
                cout << "Found function declaration " << dec->get_name().getString();
                Sg_File_Info * start = dec->get_startOfConstruct();
                Sg_File_Info * end = dec->get_endOfConstruct();
                if(start->isCompilerGenerated()) {
                        cout << ", which is compiler-generated" << endl;
                } else {
                        cout << " in file " << start->get_raw_filename() << ", " << start->get_file_id() << " from line " << 
                            start->get_line() << ", col " << start->get_col() << " to line " << 
                            end->get_line() << ", col " << end->get_col() << endl;
                }
                SgFunctionType * type = dec->get_type();
                SgType * retType = type->get_return_type();
        cout << "Return type: " << retType->unparseToString() << endl;
        SgFunctionParameterList * params = dec->get_parameterList();
        SgInitializedNamePtrList & ptrList = params->get_args();
        if(!ptrList.empty()) {
            cout << "Parameter types: ";
            for(SgInitializedNamePtrList::iterator j = ptrList.begin(); j != ptrList.end(); j++) {
                SgType * pType = (*j)->get_type();
                cout << pType->unparseToString() << " ";
            }
            cout << endl;
        }
        cout << "Linkage: " << dec->get_linkage() << endl;
               cout << endl;
        }


        SgFunctionDefinition * def = isSgFunctionDefinition(n);
        if (def != NULL) {
                cout << "Found function definition " << def->get_declaration()->get_name().getString();
                Sg_File_Info * start = def->get_startOfConstruct();
                Sg_File_Info * end = def->get_endOfConstruct();
                if(start->isCompilerGenerated()) {
                        cout << ", which is compiler-generated" << endl;
                } else {
                        cout << " in file " << start->get_raw_filename() << " from line " << start->get_line() << ", col " << start->get_col() << " to line " << end->get_line() << ", col " << end->get_col() << endl;
                SgBasicBlock * body = def->get_body();
        Sg_File_Info * bodyStart = body->get_startOfConstruct();
        Sg_File_Info * bodyEnd =   body->get_endOfConstruct();
        cout << "Function body from line " << bodyStart->get_line() << ", col " << bodyStart->get_col() << " to line " << bodyEnd->get_line() << ", col " << bodyEnd->get_col() << endl; 
 }
        cout << endl;
        }
}
int main( int argc, char * argv[] )
   {
  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT(project != NULL);

  // Build a list of functions within the AST
     Rose_STL_Container<SgNode*> functionDeclarationList = NodeQuery::querySubTree (project,V_SgFunctionDeclaration);

     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          ROSE_ASSERT(functionDeclaration != NULL);

       // DQ (3/5/2006): Only output the non-compiler generated IR nodes
          if ( (*i)->get_file_info()->isCompilerGenerated() == false)
             {
            // output the function number and the name of the function
               printf ("Function #%2d name is %s at line %d \n",
                    counter++,functionDeclaration->get_name().str(),
                    functionDeclaration->get_file_info()->get_line());
             }
            else
             {
            // Output something about the compiler-generated builtin functions
               printf ("Compiler-generated (builtin) function #%2d name is %s \n",
                    counter++,functionDeclaration->get_name().str());
             }
        }

  // Note: Show composition of AST queries

     return 0;
   }
Esempio n. 12
0
 foreach (SgFunctionCallExp *nfce, callExprs) {
   SgFunctionDeclaration *CFD = nfce->getAssociatedFunctionDeclaration();
   std::string fname = CFD->get_name().getString();
   size_t pos = 0;
   if (((pos = fname.find("RecvReturnPause_")) != std::string::npos)
       || ((pos = fname.find("WriteMemPause")) != std::string::npos 
           && lastStmt != nfce->get_parent())
       || ((pos = fname.find("SendReturn_")) != std::string::npos 
           && lastStmt != nfce->get_parent())
       && pos == 0) {
     SgStatement *brkStmt = SageBuilder::buildBreakStmt();
     SgStatement *parent = isSgStatement(nfce->get_parent());
     SageInterface::insertStatementAfter(parent, brkStmt);
   }
 }
Esempio n. 13
0
// Function printFunctionDeclarationList will print all function names in the list
void printFunctionDeclarationList(Rose_STL_Container<SgNode*> functionDeclarationList)
   {
     int counter = 0;
     for (Rose_STL_Container<SgNode*>::iterator i = functionDeclarationList.begin(); i != functionDeclarationList.end(); i++)
        {
       // Build a pointer to the current type so that we can call the get_name() member function.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
          ROSE_ASSERT(functionDeclaration != NULL);

       // output the function number and the name of the function
          printf ("function name #%d is %s at line %d \n",
               counter++,functionDeclaration->get_name().str(),
               functionDeclaration->get_file_info()->get_line());
        }
   }
Esempio n. 14
0
void findCandidateFunctionDefinitions (SgProject* project, std::vector<SgFunctionDefinition* >& candidateFuncDefs)
{
  ROSE_ASSERT (project != NULL);
  // For each source file in the project
  SgFilePtrList & ptr_list = project->get_fileList();
  for (SgFilePtrList::iterator iter = ptr_list.begin(); iter!=ptr_list.end();
      iter++)
  {
    SgFile* sageFile = (*iter);
    SgSourceFile * sfile = isSgSourceFile(sageFile);
    ROSE_ASSERT(sfile);
//    SgGlobal *root = sfile->get_globalScope();

    if (enable_debug)
      cout<<"Processing each function within the files "<< sfile->get_file_info()->get_filename() <<endl;
    //      cout<<"\t loop at:"<< cur_loop->get_file_info()->get_line() <<endl;

    // This is wrong, many functions in question are not top level declarations!!
    //SgDeclarationStatementPtrList& declList = root->get_declarations ();
    //VariantVector vv;
    Rose_STL_Container<SgNode*> defList = NodeQuery::querySubTree(sfile, V_SgFunctionDefinition); 
//    bool hasOpenMP= false; // flag to indicate if omp.h is needed in this file

    //For each function body in the scope
    //for (SgDeclarationStatementPtrList::iterator p = declList.begin(); p != declList.end(); ++p) 
    for (Rose_STL_Container<SgNode*>::iterator p = defList.begin(); p != defList.end(); ++p) 
    {
      SgFunctionDefinition *defn = isSgFunctionDefinition(*p);
      ROSE_ASSERT (defn != NULL);

      SgFunctionDeclaration *func = defn->get_declaration();
      ROSE_ASSERT (func != NULL);

      if (enable_debug)
        cout<<"\t considering function "<< func->get_name() << " at "<< func->get_file_info()->get_line()<<endl;
      //ignore functions in system headers, Can keep them to test robustness
      if (defn->get_file_info()->get_filename()!=sageFile->get_file_info()->get_filename())
      {
        if (enable_debug)
          cout<<"\t Skipped since the function's associated file name does not match current file being considered. Mostly from a header. "<<endl;
        continue;
      }
      candidateFuncDefs.push_back(defn);
    } // end for def list
  } // end for file list
}
Esempio n. 15
0
 // Function querySolverAccessFunctions() 
 // find access functions (function name starts with "get_" or "set_")
NodeQuerySynthesizedAttributeType
querySolverAccessFunctions (SgNode * astNode)
   {
     ROSE_ASSERT (astNode != 0);
     NodeQuerySynthesizedAttributeType returnNodeList;

     SgFunctionDeclaration* funcDecl = isSgFunctionDeclaration(astNode);

     if (funcDecl != NULL)
        {
          string functionName = funcDecl->get_name().str();
          if ( (functionName.length() >= 4) && ((functionName.substr(0,4) == "get_") || (functionName.substr(0,4) == "set_")) )
               returnNodeList.push_back (astNode);
        }

     return returnNodeList;
   }
Esempio n. 16
0
bool isHtThreadControlStmt(SgStatement *S)
{
  SgExprStatement *es = isSgExprStatement(S);
  SgFunctionCallExp *fce = 0;
  if (es && (fce = isSgFunctionCallExp(es->get_expression()))) {
    SgFunctionDeclaration *calleeFD = fce->getAssociatedFunctionDeclaration();
    std::string fname = calleeFD->get_name().getString();
    size_t pos = 0;
    if (fname == "WriteMemPause" ||
        fname == "ReadMemPause" ||
        fname == "HtBarrier" ||
        (((pos = fname.find("SendCall_")) != std::string::npos
         /*  || (pos = fname.find("SendCallFork_")) != std::string::npos */
           || (pos = fname.find("SendReturn_")) != std::string::npos
           || (pos = fname.find("RecvReturnJoin_")) != std::string::npos)
         && pos == 0)) {
      return true;
    }
  }
  return false;
}
Esempio n. 17
0
void visitorTraversal::visit(SgNode* n)
   {
     SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(n);
     if (functionDeclaration != NULL)
        {
          SgFunctionDefinition* functionDefinition = functionDeclaration->get_definition();
          if (functionDefinition != NULL)
             {
               SgBasicBlock* functionBody = functionDefinition->get_body();
               ROSE_ASSERT(functionBody != NULL);

               ControlFlowGraph controlflow;

            // The CFG can only be called on a function definition (at present)
               makeCfg(functionDefinition,controlflow);
               string fileName = functionDeclaration->get_name().str();
               fileName += ".dot";
               ofstream dotfile(fileName.c_str());
               printCfgAsDot(dotfile, controlflow);
             }
        }
   }
Esempio n. 18
0
void
SimpleInstrumentation::visit ( SgNode* astNode )
   {
  // Demonstrate and test append mechanism for statements

  // printf ("In assemblyFunction(): astNode->sage_class_name() = %s \n",astNode->sage_class_name());

     if (isSgFunctionDeclaration(astNode) != NULL)
        {
       // printf ("Found a function declaration \n");
          SgFunctionDeclaration* functionDeclarationStatement = isSgFunctionDeclaration(astNode);
          SgName sageName = functionDeclarationStatement->get_name();
          string functionNameString = sageName.str();

       // Make sure this is the "main" function before we insert new code
          if (functionNameString == "main")
             {
               string globalDeclarations = "int k;";
               string functionSource = "";
	       string localDeclarations = "\
void myTimerFunctionStart(void) \n\
   { \n\
     int xyzVariable; \n\
   } \n\n\
Esempio n. 19
0
int main(int argc, char * argv[]) 
{       
        // Build the AST used by ROSE
        project = frontend(argc,argv);
        
        /*convertToOMPNormalForm(project, project);
        
        // Run internal consistancy tests on AST
        AstTests::runAllTests(project); 
        
        Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition);
        for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) {
                SgFunctionDefinition* func = isSgFunctionDefinition(*i);
                ROSE_ASSERT(func);
        
                printf("func = %s\n", func->unparseToString().c_str());
                
                // output the CFG to a file
                ofstream fileCFG;
                fileCFG.open((func->get_declaration()->get_name().getString()+"_cfg.dot").c_str());
                cout << "    writing to file "<<(func->get_declaration()->get_name().getString()+"_cfg.dot")<<"\n";
                cfgToDot(fileCFG, func->get_declaration()->get_name(), func->cfgForBeginning());
                fileCFG.close();
        }
        
        backend(project);*/
        
        //generatePDF ( *project );
        
        // find a declaration for foo()
        Rose_STL_Container<SgNode*> funcDecls = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);      
        for(Rose_STL_Container<SgNode*>::iterator it = funcDecls.begin(); it!=funcDecls.end(); it++)
        {
                SgFunctionDeclaration* decl = isSgFunctionDeclaration(*it); ROSE_ASSERT(decl);
                if(decl->get_name().getString() == "foo")
                {
                        fooDecl = decl;
                        break;
                }
        }
        if(!fooDecl) { printf("ERROR: could not find declaration of function foo()!\n"); numFails++; }
        
        testParsing();
                
        convertToOMPNormalForm(project, project);
        
        testOMPForSensitiveInsertion();
        
        AstTests::runAllTests(project);
        
        insertTopBottomOmpDirectives(project, ompUtils::omp_critical, true, &fooCallStmtCreate);
        insertTopBottomOmpDirectives(project, ompUtils::omp_single, false, &fooCallStmtCreate);
        
        // Run internal consistancy tests on AST
        //
        
        // Generate the CFGs of all the functions to ensure that all CFG data is good
        Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition);
        for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) {
                SgFunctionDefinition* func = isSgFunctionDefinition(*i);
                ROSE_ASSERT(func);
        
                printf("func = %s\n", func->unparseToString().c_str());
                
                // output the CFG to a file
                ofstream fileCFG;
                fileCFG.open((func->get_declaration()->get_name().getString()+"_cfg.dot").c_str());
                cout << "    writing to file "<<(func->get_declaration()->get_name().getString()+"_cfg.dot")<<"\n";
                cfgToDot(fileCFG, func->get_declaration()->get_name(), func->cfgForBeginning());
                fileCFG.close();
        }
        
        backend(project);
        system("diff rose_test_example.c test_example.valid_rose_output.c > selfTest.out");
        struct stat file;
   stat("selfTest.out",&file);
        if(file.st_size!=0)
        {
                printf("Error: found differences between rose_test_example.c and the canonical test_example.valid_rose_output.c! Details in selfTest.out.\n");
                numFails++;
        }
        
        if(numFails==0) 
                cout << "PASSED\n";
        else
                cout << "FAILED!\n";
}
Esempio n. 20
0
int main( int argc, char * argv[] )
   {
  // Build the AST used by ROSE
     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT(project != NULL);

  // Build a list of functions within the AST and find all access functions 
  // (function name starts with "get_" or "set_")

  // Build list using a query of the whole AST
     Rose_STL_Container<SgNode*> functionDefinitionList = NodeQuery::querySubTree (project,V_SgFunctionDefinition);

  // Build list using nested Queries (operating on return result of previous query)
  //   Rose_STL_Container<SgNode*> accessFunctionsList;
  //   accessFunctionsList = NodeQuery::queryNodeList (functionDeclarationList,&querySolverAccessFunctions);
  //   printFunctionDeclarationList(accessFunctionsList);

  // Alternative form of same query building the list using a query of the whole AST
   //  accessFunctionsList = NodeQuery::querySubTree (project,&querySolverAccessFunctions);
   //  printFunctionDeclarationList(accessFunctionsList);
int counter = 0;
for (Rose_STL_Container<SgNode*>::iterator i = functionDefinitionList.begin(); i != functionDefinitionList.end(); i++) {
   SgFunctionDefinition* fnc = isSgFunctionDefinition(*i);
  stringstream ss; 
  SgFunctionDeclaration* functionDeclaration = fnc->get_declaration();
  string fileName= functionDeclaration->get_name().str();//StringUtility::stripPathFromFileName(mainDef->get_file_info()->get_filenameString());
    string dotFileName1;
ss << fileName << "." << counter << ".dot";
    counter++;
    dotFileName1 = ss.str();
    //SgFunctionDefinition* fnc = functionDeclaration->get_definition();
    if (fnc != NULL) {
    StaticCFG::CFG* cfg = new StaticCFG::CFG(fnc);
    SgIncidenceDirectedGraph* g = new SgIncidenceDirectedGraph();
     visitorTraversal* vis = new visitorTraversal();
    g = cfg->getGraph();
    myGraph* mg = new myGraph();
    mg = instantiateGraph(g, (*cfg));
    vis->tltnodes = 0;
    vis->paths = 0;
 std::cout << dotFileName1 << std::endl;
 cfgToDot(fnc,dotFileName1);
    //vis->firstPrepGraph(constcfg);
    //t1 = getCPUTime();
    vis->constructPathAnalyzer(mg, true, 0, 0, true);
    
    //t2 = getCPUTim
    std::cout << "function: " << fileName << std::endl;
    std::cout << "paths: " << vis->paths << std::endl;
    delete vis;
    delete cfg;
    delete g;
    delete mg;
    //std::cout << "took: " << timeDifference(t2, t1) << std::endl;
    }
    }
   SgProject* proj = project; 
   SgFunctionDeclaration* mainDefDecl = SageInterface::findMain(proj);
   if (mainDefDecl != NULL) {
  SgFunctionDefinition* mainDef = mainDefDecl->get_definition();
   visitorTraversal* vis = new visitorTraversal();
    StaticCFG::CFG cfg(mainDef);
   //cfg.buildFullCFG();
    stringstream ss;
    string fileName= StringUtility::stripPathFromFileName(mainDef->get_file_info()->get_filenameString());
    string dotFileName1=fileName+"."+ mainDef->get_declaration()->get_name() +".dot";

    cfgToDot(mainDef,dotFileName1);
    //cfg->buildFullCFG();
    SgIncidenceDirectedGraph* g = new SgIncidenceDirectedGraph();
    g = cfg.getGraph();
    myGraph* mg = new myGraph();
    mg = instantiateGraph(g, cfg);
    vis->tltnodes = 0;
    vis->paths = 0;
    //vis->firstPrepGraph(constcfg);
    vis->constructPathAnalyzer(mg, true, 0, 0, true);
    //std::cout << "took: " << timeDifference(t2, t1) << std::endl;
    //cfg.clearNodesAndEdges();
    std::cout << "finished" << std::endl;
    std::cout << "tltnodes: " << vis->tltnodes << " paths: " << vis->paths << std::endl;
    //std::cout << "ipaths: " << ipaths << std::endl;
    delete vis;

    }

// Another way to query for collections of IR nodes
     VariantVector vv1 = V_SgClassDefinition;
     std::cout << "Number of class definitions in the memory pool is: " << NodeQuery::queryMemoryPool(vv1).size() << std::endl;

  // Another way to query for collections of multiple IR nodes.
  // VariantVector(V_SgType) is internally expanded to all IR nodes derived from SgType.
     VariantVector vv2 = VariantVector(V_SgClassDefinition) + VariantVector(V_SgType);
     std::cout << "Number of class definitions AND types in the memory pool is: " << NodeQuery::queryMemoryPool(vv2).size() << std::endl;

  // Note: Show composition of AST queries

     return 0;
   }
Esempio n. 21
0
DOTSynthesizedAttribute
AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l)
   {
     SubTreeSynthesizedAttributes::iterator iter;
     ROSE_ASSERT(node);

  // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str());

  // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute
     if (ia.skipSubTree == true)
        {
       // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute
       // Figured this out: if we return a valid pointer then we get a node in the DOT graph 
       // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute 
       // with a NUL pointer then the node will NOT appear in the DOT graph.
       // return DOTSynthesizedAttribute(node);
          return DOTSynthesizedAttribute(NULL);
        }

     string nodeoption;
     if(AstTests::isProblematic(node))
        {
       // cout << "problematic node found." << endl;
          nodeoption="color=\"orange\" ";
        }
     string nodelabel=string("\\n")+node->class_name();

  // DQ (1/24/2009): Added support for output of isForward flag in the dot graph.
     SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node);
     if (genericDeclaration != NULL)
        {
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
          string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward";
          ROSE_ASSERT(name.empty() == false);

       // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST.
          SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration);
          if (classDeclaration != NULL)
             {
               nodelabel += string("\\n") + classDeclaration->get_name();
             }

       // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration);
          if (functionDeclaration != NULL)
             {
               nodelabel += string("\\n") + functionDeclaration->get_name();
             }

          nodelabel += string("\\n") + name;
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgInitializedName* initializedName = isSgInitializedName(node);
     if (initializedName != NULL)
        {
          nodelabel += string("\\n") + initializedName->get_name();
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgIntVal* intValue = isSgIntVal(node);
     if (intValue != NULL)
        {
          nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value());
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgVarRefExp* varRefExp = isSgVarRefExp(node);
     if (varRefExp != NULL)
        {
          SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
          ROSE_ASSERT(variableSymbol != NULL);
          string name = variableSymbol->get_name();
          nodelabel += string("\\n name = ") + name;
        }

  // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph.
     SgAsmInstruction* genericInstruction = isSgAsmInstruction(node);
     if (genericInstruction != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
#if 1
          string unparsedInstruction = unparseInstruction(genericInstruction);
          string addressString       = StringUtility::numberToString( (void*) genericInstruction->get_address() );
       // string name = genericInstruction->get_mnemonic();
          string name = unparsedInstruction + "\\n address: " + addressString;
#else
          string name = unparsedInstruction + "\\n" + addressString;
#endif
          ROSE_ASSERT(name.empty() == false);

          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

     SgAsmExpression* genericExpression = isSgAsmExpression(node);
     if (genericExpression != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
          string name = unparseExpression(genericExpression, NULL, NULL);
          ROSE_ASSERT(name.empty() == false);
          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes.
  // In generall there are long list of these IR nodes in the binary and this helps make some sense of 
  // the lists (sections, symbols, etc.).
     SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node);
     if (binaryFileFormatNode != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // The case of binary file format IR nodes can be especially confusing so we want the 
       // default to output some more specific information for some IR nodes (e.g. sections).
          string name;

          SgAsmGenericSection* genericSection = isSgAsmGenericSection(node);
          if (genericSection != NULL)
             {
               SgAsmGenericString* genericString = genericSection->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node);
          if (genericSymbol != NULL)
             {
               SgAsmGenericString* genericString = genericSymbol->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();

               if (name.empty() == true)
                    name = "no_name_for_symbol";
             }

          SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node);
          if (genericDLL != NULL)
             {
               SgAsmGenericString* genericString = genericDLL->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node);
          if (peImportItem != NULL)
             {
               SgAsmGenericString* genericString = peImportItem->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node);
          if (asmDwarfLine != NULL)
             {
               char buffer[100];

            // It does not work to embed the "\n" into the single sprintf parameter.
            // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column());

               sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address());
               name = buffer;
               sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column());
               name += string("\\n") + buffer;
             }

          SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node);
          if (asmDwarfConstruct != NULL)
             {
               name = asmDwarfConstruct->get_name();
             }

#if 0
       // This might not be the best way to implement this, since we want to detect common base classes of IR nodes.
          switch (node->variantT())
             {
               case V_SgAsmElfSection:
                  {
                    SgAsmElfSection* n = isSgAsmElfSection(node);
                    name = n->get_name();
                    break;
                  }

               default:
                  {
                 // No additional information is suggested for the default case!
                  }
             }
#endif

          if (name.empty() == false)
               nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (11/29/2008): Output the directives in the label of the IR node.
     SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node);
     if (preprocessorDirective != NULL)
        {
          string s = preprocessorDirective->get_directiveString();

       // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables.
          while (s.find("\"") != string::npos)
             {
               s.replace(s.find("\""),1,"\'");
             }

          if (s.empty() == false)
               nodelabel += string("\\n") + s;
        }

     nodelabel += additionalNodeInfo(node);

  // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.)
  // nodeoption += additionalNodeOptions(node);
     string additionalOptions = additionalNodeOptions(node);
  // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size());
  // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size());

     string x;
     string y;
     x += additionalOptions;

     nodeoption += additionalOptions;

     DOTSynthesizedAttribute d(0);

  // DQ (7/27/2008): Added mechanism to support pruning of AST
     bool commentoutNode = commentOutNodeInGraph(node);
     if (commentoutNode == true)
        {
       // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option.
       // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file.
          if (SgProject::get_verbose() > 0)
             {
               printf ("Skipping the use of this IR node in the DOT Graph \n");
             }
        }
       else
        {

// **************************

     switch(traversal)
        {
          case TOPDOWNBOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption);
               break;
          case PREORDER:
          case TOPDOWN:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
               break;
          case POSTORDER:
          case BOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption);
               break;
          default:
               assert(false);
        }
  
     ++tdbuTrace;
     ++buTrace;

  // add edges or null values
     int testnum=0;
     for (iter = l.begin(); iter != l.end(); iter++)
        {
          string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]);
          string toErasePrefix = "p_";

          if (AstTests::isPrefix(toErasePrefix,edgelabel))
             {
               edgelabel.erase(0, toErasePrefix.size());
             }

          if ( iter->node == NULL)
             {
            // SgNode* snode=node->get_traversalSuccessorContainer()[testnum];
               AstSuccessorsSelectors::SuccessorsContainer c;
               AstSuccessorsSelectors::selectDefaultSuccessors(node,c);
               SgNode* snode=c[testnum];

            // isDefault shows that the default constructor for synth attribute was used
               if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) )
                  {
                 // handle bugs in SAGE
                    dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red ");
                  }
                 else
                  {
                    if (snode == NULL)
                       {
                         dotrep.addNullValue(node,"",edgelabel,"");
                       }
                  }
             }
            else
             {
            // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.)
               string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel);

               switch(traversal)
                  {
                    case TOPDOWNBOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both");
                         break;
                    case PREORDER:
                    case TOPDOWN:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward");
                         break;
                    case POSTORDER:
                    case BOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back");
                         break;
                    default:
                         assert(false);
                  }
             }

          testnum++;
        }

// **************************
        }



  // DQ (7/4/2008): Support for edges specified in AST attributes
     AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism();
     if (astAttributeContainer != NULL)
        {
       // Loop over all the attributes at this IR node
          for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++)
             {
            // std::string name = i->first;
               AstAttribute* attribute = i->second;
               ROSE_ASSERT(attribute != NULL);

            // This can return a non-empty list in user-defined attributes (derived from AstAttribute).
            // printf ("Calling attribute->additionalNodeInfo() \n");
               std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo();
            // printf ("nodeList.size() = %lu \n",nodeList.size());

               for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++)
                  {
                    SgNode* nodePtr   = i_node->nodePtr;
                    string nodelabel  = i_node->label;
                    string nodeoption = i_node->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str());
                 // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
                    dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption );
                  }

            // printf ("Calling attribute->additionalEdgeInfo() \n");
               std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo();
            // printf ("edgeList.size() = %lu \n",edgeList.size());
               for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++)
                  {
                    string edgelabel  = i_edge->label;
                    string edgeoption = i_edge->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str());
                    dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward");
                  }
             }
        }



     switch(node->variantT())
        {
       // DQ (9/1/2008): Added case for output of SgProject rooted DOT file.
       // This allows source code and binary files to be combined into the same DOT file.
          case V_SgProject: 
             {
               SgProject* project = dynamic_cast<SgProject*>(node);
               ROSE_ASSERT(project != NULL);

               string generatedProjectName = SageInterface::generateProjectName( project );
            // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
               if (generatedProjectName.length() > 40)
                  {
                 // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
                    generatedProjectName = "aggregatedFileNameTooLong";
                    printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str());
                  }

               string filename = string("./") + generatedProjectName + ".dot";

            // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str());
               if ( SgProject::get_verbose() >= 1 )
                    printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str());

               dotrep.writeToFileAsGraph(filename);
               break;
             }

       // case V_SgFile: 
          case V_SgSourceFile: 
          case V_SgBinaryComposite: 
             {
               SgFile* file = dynamic_cast<SgFile*>(node);
               ROSE_ASSERT(file != NULL);

               string original_filename = file->getFileName();

            // DQ (7/4/2008): Fix filenamePostfix to go before the "."
            // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot";
               string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot";

            // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent());

            // printf ("file->get_parent() = %p \n",file->get_parent());
            // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... ";

            // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified 
            // on the command line.  A SgProject is still built even when a single file is specificed 
            // on the command line, however there are cases where a SgFile can be built without a 
            // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files.
            // If there is a SgProject then output the dot file from there, else output as a SgFile.
               if (file->get_parent() == NULL)
                  {
                 // If there is no SgProject then output the file now!
                    if ( SgProject::get_verbose() >= 1 )
                         printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n");

                    dotrep.writeToFileAsGraph(filename);
                  }
                 else
                  {
                 // There is a SgProject IR node, but if we will be traversing it we want to output the 
                 // graph then (so that the graph will include the SgProject IR nodes and connect multiple 
                 // files (SgSourceFile or SgBinaryComposite IR nodes).
                    if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() )
                       {
                      // This SgProject node was not input as part of the traversal, 
                      // so we will not be traversing the SgProject IR nodes and we 
                      // have to output the graph now!

                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n");

                         dotrep.writeToFileAsGraph(filename);
                       }
                      else
                       {
                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n");
                       }
                  }
               
            // cout << "done." << endl;
               break;
             }

       // DQ (7/23/2005): Implemented default case to avoid g++ warnings 
       // about enum values not handled by this switch
          default: 
             {
            // nothing to do here
               break;
             }
        }

     d.node = node;
     return d;
   }
DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute 
DetectMacroExpansionsToBeUnparsedAsAstTransformations::evaluateSynthesizedAttribute ( 
   SgNode* n, 
   DetectMacroExpansionsToBeUnparsedAsAstTransformationsInheritedAttribute inheritedAttribute, 
   SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     DetectMacroExpansionsToBeUnparsedAsAstTransformationsSynthesizedAttribute returnAttribute(n);

#if 0
     printf ("In (Detect Transformations in Macro Expansions) evaluateSynthesizedAttribute(): n = %s n->get_containsTransformation() = %s \n",n->class_name().c_str(),n->get_containsTransformation() ? "true" : "false");
#endif

  // DQ (11/8/2015): This has to be moved to after the tokenStreamSequenceMap has been setup since we need that to determine if 
  // IR nodes have a token mapping or not (subparts of macros expansions will not and we need this infor to recognize parts of 
  // the AST that are associated with macro expansions.
  // DQ (11/8/2015): If this has been marked as containing a transformation then check if there is token info for each of the children.
  // If there is not token info for each of the children then this currentStatement (e.g. n) must be marked as a transformation.
  // This case happens when a transformation is done to a child of a statement that is part of a macro.  In this case the parent will
  // have token information which is the macro call, but since there is a transformation, we have to unparse the fully expanded form 
  // of the macro (from the AST), so the whole subtree must be unparsed.  NOTE: this case might be more complex if multiple statements
  // are associated with a macro (so that there is not a single root of the subtree.  I need to build an example of this to better 
  // understand if there is a problem and if so just what would be the best solution.  It will b at least an iterative refinement of
  // this specific problem.  See tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_135.C for an example
  // of this problem.
     if (n->get_containsTransformation() == true)
        {
#if 0
          printf ("Found case of statement marked as containing a transforamtion \n");
#endif
          SgStatement* currentStatement = isSgStatement(n);
#if 0
          if (currentStatement != NULL)
             {
            // printf ("currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str());
               printf ("currentStatement = %s \n",currentStatement->class_name().c_str());
               printf ("   --- currentStatement->isTransformation()    = %s \n",currentStatement->isTransformation() ? "true" : "false");
             }
#endif
       // We have to test for a macro exapansion (will only work on statement level grainularity where parent statement has child statements).
          bool all_children_have_token_info = true;
          for (size_t i = 0; i < synthesizedAttributeList.size(); i++)
             {
               SgStatement* statement = isSgStatement(synthesizedAttributeList[i].node);
               if (statement != NULL)
                  {
#if 0
                 // printf ("(child) statement = %p = %s \n",statement,statement->class_name().c_str());
                    printf ("(child) statement = %s \n",statement->class_name().c_str());
                    printf ("   --- statement->isTransformation()           = %s \n",statement->isTransformation() ? "true" : "false");
                    printf ("   --- statement->get_containsTransformation() = %s \n",statement->get_containsTransformation() ? "true" : "false");
#endif
                 // DQ (11/8/2015): We might need to also check the surrounding white space as well (except that I think this is set later).
                    if (tokenStreamSequenceMap.find(statement) != tokenStreamSequenceMap.end())
                       {
                      // If we have a token mapping then we don't have to do anything.
                         TokenStreamSequenceToNodeMapping* mapping = tokenStreamSequenceMap[statement];
                         ROSE_ASSERT(mapping != NULL);
                       }
                      else
                       {
#if 0
                      // printf ("Parent statement = %p = %s No token stream information found for child statement = %p = %s \n",
                      //      currentStatement,currentStatement->class_name().c_str(),statement,statement->class_name().c_str());
                         printf ("Parent statement = %s No token stream information found for child statement = %s \n",
                              currentStatement->class_name().c_str(),statement->class_name().c_str());
                         printf ("   --- at line: %d \n",statement->get_file_info()->get_line());

                      // When this is a function declaration, try to understand more about it.
                         SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(statement);
                         if (functionDeclaration != NULL)
                            {
                              printf ("   --- functionDeclaration name = %s \n",functionDeclaration->get_name().str());
                            }
#endif
                         all_children_have_token_info = false;
                       }
                  }
             }

          if (currentStatement != NULL && all_children_have_token_info == false)
             {
#if 0
            // printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %p = %s \n",currentStatement,currentStatement->class_name().c_str());
               printf ("*** Found case of statement marked as containing a transforamtion, but all children without token info (detected a macro expansion): currentStatement = %s \n",currentStatement->class_name().c_str());
#endif

            // DQ (11/9/2015): Added support for specific scopes where we don't want them the be 
            // unparsed from the token stream when children of them are transformed.
            // DQ (11/8/2015): I think that this should not apply to a SgBasicBlock (for example see 
            // tests/roseTests/astInterfaceTests/inputmoveDeclarationToInnermostScope_test2015_94.C).
            // The reason is that a block is not the same sort for compound statement as a SgForStatement.
            // if (isSgBasicBlock(currentStatement) == NULL)
               bool current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences = 
                    ( (isSgGlobal(currentStatement) != NULL)          || 
                      (isSgBasicBlock(currentStatement) != NULL)      ||
                   // (isSgEnumDefinition(currentStatement) != NULL)  ||
                      (isSgClassDefinition(currentStatement) != NULL) );

               if (current_statement_is_allowed_to_have_statements_with_unmapped_token_sequences == false)
                  {
                 // Mark as a transformation instead of containing a transformation.
                    currentStatement->setTransformation();

                 // We also need to mark this too!
                    currentStatement->setOutputInCodeGeneration();

                 // And reset this to NOT contain a transformation.
                    currentStatement->set_containsTransformation(false);
#if 0
                    printf ("Exiting as a test! \n");
                    ROSE_ASSERT(false);
#endif
                  }
                 else
                  {
#if 0
                 // printf ("This currentStatement = %p = %s is allowed to have a child without a token sequence mapping \n",currentStatement,currentStatement->class_name().c_str());
                    printf ("This currentStatement = %s is allowed to have a child without a token sequence mapping \n",currentStatement->class_name().c_str());
#endif
                  }
             }
#if 0
       // Debugging code.
          if (isSgForStatement(n) != NULL)
             {
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
             }
#endif
        }

     return returnAttribute;
   }
SynthesizedAttribute
Traversal::evaluateSynthesizedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute, SynthesizedAttributesList childAttributes )
   {
     SynthesizedAttribute localResult;

  // printf ("evaluateSynthesizedAttribute(): astNode = %p = %s inheritedAttribute.isFirstFile = %s \n",astNode,astNode->class_name().c_str(),inheritedAttribute.isFirstFile ? "true" : "false");

  // Accumulate any valid pointer to main on a child node and pass it to the local synthesized attribute.
     for (size_t i = 0; i < childAttributes.size(); i++)
        {
          if (childAttributes[i].main_function != NULL)
             {
               localResult.main_function = childAttributes[i].main_function;
             }
        }

     if (inheritedAttribute.isFirstFile == true)
        {
          SgGlobal* globalScope = isSgGlobal(astNode);
          if (globalScope != NULL)
             {
            // Gather all of the functions in global scope of the first file.

               vector<SgDeclarationStatement*> globalScopeDeclarationsToMove = globalScope->get_declarations();
               inheritedAttribute.statements_from_first_file = globalScopeDeclarationsToMove;

            // printf ("evaluateSynthesizedAttribute(): Gather all of the functions in global scope of the first file inheritedAttribute.statements_from_first_file.size() = %zu \n",inheritedAttribute.statements_from_first_file.size());

            // Erase the declarations in the global scope of the first file.
               globalScope->get_declarations().clear();
             }

          SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(astNode);
          if (declarationStatement != NULL && isSgGlobal(declarationStatement->get_parent()) != NULL)
             {
            // Mark as a transformation (recursively mark the whole subtree).
            // printf ("*** Mark as a transformation: declarationStatement = %p \n",declarationStatement);
               markAsTransformation(declarationStatement);
               if (declarationStatement->get_firstNondefiningDeclaration() != NULL)
                    markAsTransformation(declarationStatement->get_firstNondefiningDeclaration());
             }
        }
       else
        {
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(astNode);
          if (functionDeclaration != NULL && functionDeclaration->get_name() == "main")
             {
            // Save the pointer to the main function (in the second file).
               localResult.main_function = functionDeclaration;
            // printf ("Found the main function ...(saved pointer) inheritedAttribute.main_function = %p \n",localResult.main_function);
             }

       // printf ("evaluateSynthesizedAttribute(): localResult.main_function = %p \n",localResult.main_function);

       // Test for the selected insertion point in the 2nd file for the declarations gathered from the first file.
          SgGlobal* globalScope = isSgGlobal(astNode);
          if (globalScope != NULL && localResult.main_function != NULL)
             {
               printf ("evaluateSynthesizedAttribute(): Found the main function ...\n");
               vector<SgDeclarationStatement*>::iterator i = find(globalScope->get_declarations().begin(),globalScope->get_declarations().end(),localResult.main_function);
               globalScope->get_declarations().insert(i,inheritedAttribute.statements_from_first_file.begin(),inheritedAttribute.statements_from_first_file.end());
#if 0
            // Set the parents of each declaration to match the new location (avoids warning that might later be an error).
               for (size_t i = 0; i < inheritedAttribute.statements_from_first_file.size(); i++)
                  {
                    inheritedAttribute.statements_from_first_file[i]->set_parent(globalScope);
                  }
#endif
             }
        }

     return localResult;
   }
Esempio n. 24
0
ATerm convertNodeToAterm(SgNode* n) 
   {
     if (n == NULL)
        {
#if 0
          printf ("convertNodeToAterm(): n = %p = %s \n",n,"NULL");
#endif
          return ATmake("NULL");
        }

     ROSE_ASSERT(n != NULL);
#if 0
     printf ("convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif

     ATerm term;
     switch (n->variantT())
        {
       // case V_SgFile:
          case V_SgSourceFile:
            // Special case needed to include file name
            // term = ATmake("File(<str>, <term>)", isSgFile(n)->getFileName(), convertNodeToAterm(isSgFile(n)->get_root()));
               term = ATmake("File(<str>, <term>)", isSgSourceFile(n)->getFileName().c_str(), convertNodeToAterm(isSgSourceFile(n)->get_globalScope()));
               break;

          case V_SgPlusPlusOp:
          case V_SgMinusMinusOp:
            // Special cases needed to include prefix/postfix status
               term = ATmake("<appl(<appl>, <term>)>",
                  getShortVariantName((VariantT)(n->variantT())).c_str(),
                  (isSgUnaryOp(n)->get_mode() == SgUnaryOp::prefix ? "Prefix" :
                   isSgUnaryOp(n)->get_mode() == SgUnaryOp::postfix ? "Postfix" :
                   "Unknown"),
                   convertNodeToAterm(isSgUnaryOp(n)->get_operand()));
               break;

          case V_SgExpressionRoot:
            // Special case to remove this node
               term = convertNodeToAterm(isSgExpressionRoot(n)->get_operand());
               break;

    case V_SgCastExp:
    // Special case needed to include type
    term = ATmake("Cast(<term>, <term>)>",
	    convertNodeToAterm(isSgUnaryOp(n)->get_operand()),
	    convertNodeToAterm(isSgCastExp(n)->get_type()));
    break;

    case V_SgVarRefExp:
    // Special case needed to include id
    term = ATmake("Var(<str>)", 
		  uniqueId(isSgVarRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgFunctionRefExp:
    // Special case needed to include id
    term = ATmake(
                  "Func(<str>)", 
                  uniqueId(isSgFunctionRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgIntVal:
    // Special case needed to include value
    term = ATmake("IntC(<int>)", isSgIntVal(n)->get_value());
    break;

    case V_SgUnsignedIntVal:
    term = ATmake("UnsignedIntC(<int>)", isSgUnsignedIntVal(n)->get_value());
    break;

    case V_SgUnsignedLongVal: {
      ostringstream s;
      s << isSgUnsignedLongVal(n)->get_value();
      term = ATmake("UnsignedLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgUnsignedLongLongIntVal: {
      ostringstream s;
      s << isSgUnsignedLongLongIntVal(n)->get_value();
      term = ATmake("UnsignedLongLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgDoubleVal:
    term = ATmake("DoubleC(<real>)", isSgDoubleVal(n)->get_value());
    break;

          case V_SgInitializedName:
             {
            // Works around double initname problem
               SgInitializer* initializer = isSgInitializedName(n)->get_initializer();
               const SgName& name = isSgInitializedName(n)->get_name();
               SgType* type = isSgInitializedName(n)->get_type();

               ROSE_ASSERT(type != NULL);
#if 0
               printf ("convertNodeToAterm(): case V_SgInitializedName: name = %s initializer = %p type = %p = %s \n",name.str(),initializer,type,type->class_name().c_str());
#endif
            // Works around fact that ... is not really an initname and shouldn't be a type either
               if (isSgTypeEllipse(type))
                  {
                    term = ATmake("Ellipses");
                  }
                 else
                  {
                    std::string uniqueIdString = uniqueId(n);
#if 0
                    printf ("uniqueIdString = %s \n",uniqueIdString.c_str());
                    printf ("Calling generate ATerm for SgInitializedName->get_name() name = %s \n",name.str());
                    ATerm name_aterm = ATmake("Name(<str>)",name.str());
                 // ATerm name_aterm = ATmake(name.str());
                    printf ("Calling convertNodeToAterm(type) \n");
                    ATerm type_aterm = convertNodeToAterm(type);
                    printf ("Calling convertNodeToAterm(initializer) \n");
#endif
                    ATerm initializer_aterm = convertNodeToAterm(initializer);
#if 0
                    printf ("Calling ATmake() \n");
#endif
#if 1
                    term = ATmake("InitName(<str>, <term>, <term>) {[id, <str>]}", 
                                    (name.str() ? name.str() : ""), 
                                    convertNodeToAterm(type), 
                                    convertNodeToAterm(initializer),
                                    uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
#else
                    term = ATmake("InitName(<term>,<term>)",
                                  //(name.str() ? name.str() : ""), 
                                  // name_aterm,
                                    type_aterm, 
                                    initializer_aterm
                                 // uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
                                    );
#endif
#if 0
                    printf ("Calling ATsetAnnotation() \n");
#endif
                    term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str()));
#if 0
                    printf ("DONE: Calling ATsetAnnotation() \n");
#endif
                  }

               break;
             }

    case V_SgFunctionDeclaration: {
      // Special case needed to include name
      SgFunctionDeclaration* fd = isSgFunctionDeclaration(n);
      term = ATmake("Function(<str>, <term>, <term>, <term>)", 
		    fd->get_name().str(), 
		    convertNodeToAterm(fd->get_orig_return_type()),
		    convertSgNodeRangeToAterm(fd->get_args().begin(),
					      fd->get_args().end()),
		    convertNodeToAterm(fd->get_definition()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgClassDeclaration: {
      // Special case needed to distinguish forward/full definitions and to
      // include class name
      SgClassDeclaration* decl = isSgClassDeclaration(n);
      assert (decl);
      SgName sname = decl->get_name();
      const char* name = sname.str();
      // Suggestion: have a field named local_definition in each class
      // declaration that is 0 whenever the current declaration doesn't
      // have a definition attached, even if there is another declaration
      // which does have a definition attached.
      SgClassDefinition* defn = decl->get_definition();
      // cout << "defn = 0x" << hex << defn << endl << dec;
      if (decl->isForward())
	defn = 0;
      if (defn)
	term = ATmake("Class(<str>, <term>)", 
		      (name ? name : ""), // Will be simpler when SgName
		      // becomes string
		      convertNodeToAterm(defn));
      else
	term = ATmake("ClassFwd(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgEnumDeclaration: {
      // Special case to include enum name and enumerator names which are not
      // traversal children
      SgName sname = isSgEnumDeclaration(n)->get_name();
      const char* name = sname.str();
      const SgInitializedNamePtrList& enumerators = 
	isSgEnumDeclaration(n)->get_enumerators();
      term = ATmake("Enum(<str>, <term>)",
		    (name ? name : "{anonymous}"), 
		    convertSgNodeRangeToAterm(enumerators.begin(),
					      enumerators.end()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgPointerType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgPointerType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Pointer(<term>)", t);
    }
    break;

    case V_SgReferenceType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgReferenceType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Reference(<term>)", t);
    }
    break;

    case V_SgModifierType: {
      // Special case for type traversal and to prettify modifier names
      SgType* type = isSgModifierType(n)->get_base_type();
      SgTypeModifier& modifier = isSgModifierType(n)->get_typeModifier();
      SgConstVolatileModifier& cvmod = modifier.get_constVolatileModifier();
      term = convertNodeToAterm(type);
      if (cvmod.isConst())
	term = ATmake("Const(<term>)", term);
      if (cvmod.isVolatile())
	term = ATmake("Volatile(<term>)", term);
    }
    break;

    case V_SgArrayType: {
      // Special case because types can't be traversed yet, and to get length
      SgType* type = isSgArrayType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Array(<term>, <term>)", t, (isSgArrayType(n)->get_index() ? convertNodeToAterm((n->get_traversalSuccessorContainer())[4]) : ATmake("<str>", "NULL")));
      assert (term);
    }
    break;

    case V_SgFunctionType: {
      // Special case to allow argument list to be traversed
      SgFunctionType* ft = isSgFunctionType(n);
      ATerm ret = convertNodeToAterm(ft->get_return_type());
      ATerm args_list = convertSgNodeRangeToAterm(ft->get_arguments().begin(),
						  ft->get_arguments().end());
      term = ATmake("FunctionType(<term>, <term>)", ret, args_list);
    }
    break;

    case V_SgEnumType:
    case V_SgClassType: 
    case V_SgTypedefType: {
      // Special cases to optionally put in type definition instead of
      // reference
      SgNamedType* nt = isSgNamedType(n);
      assert (nt);
      SgName sname = nt->get_name();
   // char* name = sname.str();
      SgDeclarationStatement* decl = nt->get_declaration();
      assert (decl);
      SgClassDefinition* defn = isSgClassDeclaration(decl) ?
				isSgClassDeclaration(decl)->get_definition() :
				0;
      term = ATmake("Type(<term>)",
		    (nt->get_autonomous_declaration() || !defn ? 
                     ATmake("id(<str>)", uniqueId(decl).c_str()) :
		     convertNodeToAterm(nt->get_declaration())));
    }
    break;

    case V_SgLabelStatement: {
      // Special case to put in label id
      const char* name = isSgLabelStatement(n)->get_name().str();
      term = ATmake("Label(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgGotoStatement: {
      // Special case to put in label id
      term = ATmake("Goto(<str>)", 
                    uniqueId(isSgGotoStatement(n)->get_label()).c_str());
    }
    break;

    case V_SgTypedefDeclaration: {
      // Special case to put in typedef name
      const SgName& name = isSgTypedefDeclaration(n)->get_name();
      SgType* type = isSgTypedefDeclaration(n)->get_base_type();
      term = ATmake("Typedef(<str>, <term>)", (name.str() ? name.str() : ""), 
		      convertNodeToAterm(type));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgTemplateDeclaration: {
      // Traversal doesn't work for these
      SgTemplateDeclaration* td = isSgTemplateDeclaration(n);
      ROSE_ASSERT (td);
   // SgTemplateParameterPtrListPtr paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList & paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList params =	paramsPtr ? *paramsPtr : SgTemplateParameterPtrList();
      SgTemplateParameterPtrList & params =	td->get_templateParameters();
      string templateKindString;
      switch (td->get_template_kind()) {
	case SgTemplateDeclaration::e_template_none:
	  templateKindString = "None"; break;
	case SgTemplateDeclaration::e_template_class:
	  templateKindString = "Class"; break;
	case SgTemplateDeclaration::e_template_m_class:
	  templateKindString = "MemberClass"; break;
	case SgTemplateDeclaration::e_template_function:
	  templateKindString = "Function"; break;
	case SgTemplateDeclaration::e_template_m_function:
	  templateKindString = "MemberFunction"; break;
	case SgTemplateDeclaration::e_template_m_data:
	  templateKindString = "MemberData"; break;
	default: templateKindString = "Unknown"; break;
      }
      term = ATmake("TemplateDeclaration(<appl>, <str>, <term>, <str>)",
		    templateKindString.c_str(),
		    td->get_name().str(),
		    convertSgNodeRangeToAterm(params.begin(), params.end()),
		    td->get_string().str());
    }
    break;

    case V_SgTemplateInstantiationDecl: {
      // Traversal doesn't work for these
      SgTemplateInstantiationDecl* td = isSgTemplateInstantiationDecl(n);
      ROSE_ASSERT (td);
   // SgTemplateArgumentPtrListPtr argsPtr = td->get_templateArguments();
   // SgTemplateArgumentPtrList args = argsPtr ? *argsPtr : SgTemplateArgumentPtrList();
      SgTemplateArgumentPtrList & args = td->get_templateArguments();
      term = ATmake("TemplateInstantiationDecl(<str>, <term>)", td->get_templateDeclaration()->get_name().str(), convertSgNodeRangeToAterm(args.begin(), args.end()));
    }
    break;

    case V_SgTemplateParameter: {
      // Traversal doesn't work for these
      SgTemplateParameter* tp = isSgTemplateParameter(n);
      ROSE_ASSERT (tp);
      switch (tp->get_parameterType()) {
	case SgTemplateParameter::parameter_undefined: {
	  term = ATmake("Undefined");
	}
	break;

	case SgTemplateParameter::type_parameter: {
	  term = ATmake("Type(<term>)",
			convertNodeToAterm(tp->get_defaultTypeParameter()));
	}
	break;

	case SgTemplateParameter::nontype_parameter: {
	  term = ATmake("Nontype(<term>, <term>)",
			convertNodeToAterm(tp->get_type()),
			convertNodeToAterm(tp->get_defaultExpressionParameter()));
	}
	break;

	case SgTemplateParameter::template_parameter: {
	  term = ATmake("Template");
	}
	break;

	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    case V_SgTemplateArgument: {
      // Traversal doesn't work for these
      SgTemplateArgument* ta = isSgTemplateArgument(n);
      ROSE_ASSERT (ta);
      switch (ta->get_argumentType()) {
	case SgTemplateArgument::argument_undefined:
	  term = ATmake("Undefined");
	  break;
	case SgTemplateArgument::type_argument:
	  term = ATmake("Type(<term>)", 
			convertNodeToAterm(ta->get_type()));
	  break;
	case SgTemplateArgument::nontype_argument:
	  term = ATmake("Nontype(<term>)", 
			convertNodeToAterm(ta->get_expression()));
	  break;
	// case SgTemplateArgument::template_argument:
	  // term = ATmake("Template");
	  // break;
	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    default: {
      bool isContainer = 
	(AstTests::numSuccContainers(n) == 1) ||
	(!isSgType(n) && (n->get_traversalSuccessorContainer().size() == 0));
      term = ATmake((isContainer ? "<appl(<term>)>" : "<appl(<list>)>"), 
                    getShortVariantName((VariantT)(n->variantT())).c_str(),
                    (isSgType(n) ? ATmake("[]") : getTraversalChildrenAsAterm(n)));
               // Special case for types is because of traversal problems
    }
    break;
  }

#if 0
     printf ("Base of switch statement in convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
     assert (term);

     term = ATsetAnnotation(term, ATmake("ptr"), pointerAsAterm(n));

#if 1
     if (n->get_file_info() != NULL)
        {
          term = ATsetAnnotation(term, ATmake("location"),convertFileInfoToAterm(n->get_file_info()));
        }

     if (isSgExpression(n))
        term = ATsetAnnotation(term, ATmake("type"), convertNodeToAterm(isSgExpression(n)->get_type()));
#endif

#if 0
     printf ("Leaving convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
#if 0
     printf ("--- n->class_name() = %s ATwriteToString(term) = %s \n",n->class_name().c_str(),ATwriteToString(term));
#endif

  // cout << n->sage_class_name() << " -> " << ATwriteToString(term) << endl;
     return term;
   }
Esempio n. 25
0
void SystemDependenceGraph::build()
{
    boost::unordered_map<CFGVertex, Vertex> cfgVerticesToSdgVertices;
    boost::unordered_map<SgNode*, Vertex>   astNodesToSdgVertices;

    //map<SgFunctionCallExp*, vector<SDGNode*> > funcCallToArgs;

    vector<CallSiteInfo> functionCalls;


    map<SgNode*, vector<Vertex> > actualInParameters;
    map<SgNode*, vector<Vertex> > actualOutParameters;

    map<SgNode*, Vertex> formalInParameters;
    map<SgNode*, Vertex> formalOutParameters;

    vector<SgFunctionDefinition*> funcDefs = 
        SageInterface::querySubTree<SgFunctionDefinition>(project_, V_SgFunctionDefinition);
    foreach (SgFunctionDefinition* funcDef, funcDefs)
    {
        SgFunctionDeclaration* funcDecl = funcDef->get_declaration();

        CFG* cfg = new CFG(funcDef, cfgNodefilter_);
        functionsToCFGs_[funcDecl] = cfg;

        // For each function, build an entry node for it.
        SDGNode* entry = new SDGNode(SDGNode::Entry);
        entry->astNode = funcDef;
        //entry->funcDef = funcDef;
        Vertex entryVertex = addVertex(entry);
        functionsToEntries_[funcDecl] = entryVertex;

        // Add all out formal parameters to SDG.
        const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();
        foreach (SgInitializedName* initName, formalArgs)
        {
            // If the parameter is passed by reference, create a formal-out node.
            if (isParaPassedByRef(initName->get_type()))
            {
                SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
                formalOutNode->astNode = initName;
                Vertex formalOutVertex = addVertex(formalOutNode);
                formalOutParameters[initName] = formalOutVertex;

                // Add a CD edge from call node to this formal-out node.
                addTrueCDEdge(entryVertex, formalOutVertex);
            }
        }

        // A vertex representing the returned value.
        Vertex returnVertex;

        // If the function returns something, build a formal-out node.
        if (!isSgTypeVoid(funcDecl->get_type()->get_return_type()))
        {
            SDGNode* formalOutNode = new SDGNode(SDGNode::FormalOut);
            // Assign the function declaration to the AST node of this vertex to make
            // it possible to classify this node into the subgraph of this function.
            formalOutNode->astNode = funcDecl;
            returnVertex = addVertex(formalOutNode);
            formalOutParameters[funcDecl] = returnVertex;

            // Add a CD edge from call node to this formal-out node.
            addTrueCDEdge(entryVertex, returnVertex);
        }

        // Add all CFG vertices to SDG.
        foreach (CFGVertex cfgVertex, boost::vertices(*cfg))
        {
            if (cfgVertex == cfg->getEntry() || cfgVertex == cfg->getExit())
                continue;

            SgNode* astNode = (*cfg)[cfgVertex]->getNode();

            // If this node is an initialized name and it is a parameter, make it 
            // as a formal in node.
            SgInitializedName* initName = isSgInitializedName(astNode);
            if (initName && isSgFunctionParameterList(initName->get_parent()))
            {
                SDGNode* formalInNode = new SDGNode(SDGNode::FormalIn);
                formalInNode->astNode = initName;
                Vertex formalInVertex = addVertex(formalInNode);
                formalInParameters[initName] = formalInVertex;

                cfgVerticesToSdgVertices[cfgVertex] = formalInVertex;
                astNodesToSdgVertices[astNode] = formalInVertex;

                // Add a CD edge from call node to this formal-in node.
                addTrueCDEdge(entryVertex, formalInVertex);
                continue;
            }

            // Add a new node to SDG.
            SDGNode* newSdgNode = new SDGNode(SDGNode::ASTNode);
            //newSdgNode->cfgNode = (*cfg)[cfgVertex];
            newSdgNode->astNode = astNode;
            Vertex sdgVertex = addVertex(newSdgNode);

            cfgVerticesToSdgVertices[cfgVertex] = sdgVertex;
            astNodesToSdgVertices[astNode] = sdgVertex;


            // Connect a vertex containing the return statement to the formal-out return vertex.
            if (isSgReturnStmt(astNode)
                    || isSgReturnStmt(astNode->get_parent()))
            {
                SDGEdge* newEdge = new SDGEdge(SDGEdge::DataDependence);
                addEdge(sdgVertex, returnVertex, newEdge);                
            }

            // If this CFG node contains a function call expression, extract its all parameters
            // and make them as actual-in nodes.

            if (SgFunctionCallExp* funcCallExpr = isSgFunctionCallExp(astNode))
            {
                CallSiteInfo callInfo;
                callInfo.funcCall = funcCallExpr;
                callInfo.vertex = sdgVertex;

                // Change the node type.
                newSdgNode->type = SDGNode::FunctionCall;
                vector<SDGNode*> argsNodes;

                // Get the associated function declaration.
                SgFunctionDeclaration* funcDecl = funcCallExpr->getAssociatedFunctionDeclaration();
                
                if (funcDecl == NULL) 
                    continue;
                    
                ROSE_ASSERT(funcDecl);
                const SgInitializedNamePtrList& formalArgs = funcDecl->get_args();

                SgExprListExp* args = funcCallExpr->get_args();
                const SgExpressionPtrList& actualArgs = args->get_expressions();
                
                if (formalArgs.size() != actualArgs.size())
                {
                    cout << "The following function has variadic arguments:\n";
                    cout << funcDecl->get_file_info()->get_filename() << endl;
                    cout << funcDecl->get_name() << formalArgs.size() << " " << actualArgs.size() << endl;
                    continue;
                }

                for (int i = 0, s = actualArgs.size(); i < s; ++i)
                {
                    // Make sure that this parameter node is added to SDG then we
                    // change its node type from normal AST node to a ActualIn arg.
                    ROSE_ASSERT(astNodesToSdgVertices.count(actualArgs[i]));

                    Vertex paraInVertex = astNodesToSdgVertices.at(actualArgs[i]);
                    SDGNode* paraInNode = (*this)[paraInVertex]; 
                    paraInNode->type = SDGNode::ActualIn;

                    actualInParameters[formalArgs[i]].push_back(paraInVertex);
                    callInfo.inPara.push_back(paraInVertex);

                    // Add a CD edge from call node to this actual-in node.
                    addTrueCDEdge(sdgVertex, paraInVertex);

                    // If the parameter is passed by reference, create a parameter-out node.
                    if (isParaPassedByRef(formalArgs[i]->get_type()))
                    {
                        SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                        paraOutNode->astNode = actualArgs[i];
                        //argsNodes.push_back(paraInNode);

                        // Add an actual-out parameter node.
                        Vertex paraOutVertex = addVertex(paraOutNode);
                        actualOutParameters[formalArgs[i]].push_back(paraOutVertex);
                        callInfo.outPara.push_back(paraOutVertex);

                        // Add a CD edge from call node to this actual-out node.
                        addTrueCDEdge(sdgVertex, paraOutVertex);
                    }
                }

                if (!isSgTypeVoid(funcDecl->get_type()->get_return_type())) 
                {
                    // If this function returns a value, create a actual-out vertex.
                    SDGNode* paraOutNode = new SDGNode(SDGNode::ActualOut);
                    paraOutNode->astNode = funcCallExpr;

                    // Add an actual-out parameter node.
                    Vertex paraOutVertex = addVertex(paraOutNode);
                    actualOutParameters[funcDecl].push_back(paraOutVertex);
                    callInfo.outPara.push_back(paraOutVertex);
                    callInfo.isVoid = false;
                    callInfo.returned = paraOutVertex;

                    // Add a CD edge from call node to this actual-out node.
                    addTrueCDEdge(sdgVertex, paraOutVertex);
                }

                functionCalls.push_back(callInfo);
                //funcCallToArgs[funcCallExpr] = argsNodes;
            }
        }

        // Add control dependence edges.
        addControlDependenceEdges(cfgVerticesToSdgVertices, *cfg, entryVertex);
    }
Esempio n. 26
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);
   }
Esempio n. 27
0
SgFunctionDeclaration * CudaOutliner::generateFunction ( SgBasicBlock* s,
                                                         const string& func_name_str,
                                                         ASTtools::VarSymSet_t& syms,
							 MintHostSymToDevInitMap_t hostToDevVars,
							 const ASTtools::VarSymSet_t& pdSyms,
                                                         const ASTtools::VarSymSet_t& psyms,
                                                         SgScopeStatement* scope)
{
  //Create a function named 'func_name_str', with a parameter list from 'syms'                                                             
  //pdSyms specifies symbols which must use pointer dereferencing if replaced during outlining,  
  //only used when -rose:outline:temp_variable is used                                                                                     
  //psyms are the symbols for OpenMP private variables, or dead variables (not live-in, not live-out)    

  ROSE_ASSERT ( s && scope);
  ROSE_ASSERT(isSgGlobal(scope));

  // step 1: perform necessary liveness and side effect analysis, if requested.     
  // ---------------------------------------------------------                                                                           
  std::set< SgInitializedName *> liveIns, liveOuts;
  // Collect read-only variables of the outlining target                                                                                
  std::set<SgInitializedName*> readOnlyVars;
  if (Outliner::temp_variable||Outliner::enable_classic)
    {
      SgStatement* firstStmt = (s->get_statements())[0];
      if (isSgForStatement(firstStmt)&& Outliner::enable_liveness)
        {
          LivenessAnalysis * liv = SageInterface::call_liveness_analysis (SageInterface::getProject());
	  SageInterface::getLiveVariables(liv, isSgForStatement(firstStmt), liveIns, liveOuts);
        }
      SageInterface::collectReadOnlyVariables(s,readOnlyVars);
      if (0)//Outliner::enable_debug)
        {
          cout<<"  INFO:Mint: CudaOutliner::generateFunction()---Found "<<readOnlyVars.size()<<" read only variables..:";
          for (std::set<SgInitializedName*>::const_iterator iter = readOnlyVars.begin();
               iter!=readOnlyVars.end(); iter++)
            cout<<" "<<(*iter)->get_name().getString()<<" ";
          cout<<endl;
          cout<<"CudaOutliner::generateFunction() -----Found "<<liveOuts.size()<<" live out variables..:";
          for (std::set<SgInitializedName*>::const_iterator iter = liveOuts.begin();
               iter!=liveOuts.end(); iter++)
            cout<<" "<<(*iter)->get_name().getString()<<" ";
          cout<<endl;
        }
    }
    //step 2. Create function skeleton, 'func'.             
    // -----------------------------------------                
  SgName func_name (func_name_str);
  SgFunctionParameterList *parameterList = buildFunctionParameterList();
  
  SgType* func_Type = SgTypeVoid::createType ();
  SgFunctionDeclaration* func = createFuncSkeleton (func_name, func_Type ,parameterList, scope);

  //adds __global__ keyword 
  func->get_functionModifier().setCudaKernel();
 
  ROSE_ASSERT (func);

  // Liao, 4/15/2009 , enforce C-bindings  for C++ outlined code 
  // enable C code to call this outlined function                                                                                
  // Only apply to C++ , pure C has trouble in recognizing extern "C"                                                    
  // Another way is to attach the function with preprocessing info:                                                     
  // #if __cplusplus                                                                                                           
  // extern "C"                                                                                                              
  // #endif                                                                                                                                
  // We don't choose it since the language linkage information is not explicit in AST                                                           
  if ( SageInterface::is_Cxx_language() || is_mixed_C_and_Cxx_language() \
       || is_mixed_Fortran_and_Cxx_language() || is_mixed_Fortran_and_C_and_Cxx_language() )
    {
      // Make function 'extern "C"'                                                                                                                                         
      func->get_declarationModifier().get_storageModifier().setExtern();
      func->set_linkage ("C");
    }

  //step 3. Create the function body                                                                                       
  // -----------------------------------------                                                                                              
  // Generate the function body by deep-copying 's'.                                                                                       
              
  SgBasicBlock* func_body = func->get_definition()->get_body();
  ROSE_ASSERT (func_body != NULL);

  // This does a copy of the statements in "s" to the function body of the outlined function.                                             
  ROSE_ASSERT(func_body->get_statements().empty() == true);

  // This calls AST copy on each statement in the SgBasicBlock, but not on the block, so the                                          
  // symbol table is setup by AST copy mechanism and it is  setup properly
  SageInterface::moveStatementsBetweenBlocks (s, func_body);

  if (Outliner::useNewFile)
    ASTtools::setSourcePositionAtRootAndAllChildrenAsTransformation(func_body);

  //step 4: variable handling, including:                                                                                                  
  // -----------------------------------------                                                                                             
  //   create parameters of the outlined functions                                                                                        
  //   add statements to unwrap the parameters if wrapping is requested
  //   add repacking statements if necessary                                                                                               
  //   replace variables to access to parameters, directly or indirectly                                                                  
  //   do not wrap parameters 
  Outliner::enable_classic = true;

  functionParameterHandling(syms, hostToDevVars, pdSyms, psyms, readOnlyVars, liveOuts, func);
  ROSE_ASSERT (func != NULL);
  
  // Retest this...  // Copied the similar fix from the rose outliner                        
  //     Liao 2/6/2013. It is essential to rebuild function type after the parameter list is finalized.
  //     The original function type was build using empty parameter list.
  SgType* stale_func_type = func->get_type();
  func->set_type(buildFunctionType(func->get_type()->get_return_type(), buildFunctionParameterTypeList(func->get_parameterList())));
  SgFunctionDeclaration* non_def_func = isSgFunctionDeclaration(func->get_firstNondefiningDeclaration ()) ;
  ROSE_ASSERT (non_def_func != NULL);
  ROSE_ASSERT (stale_func_type == non_def_func->get_type());
  non_def_func->set_type(func->get_type());

  ROSE_ASSERT(func->get_definition()->get_body()->get_parent() == func->get_definition());

  ROSE_ASSERT(scope->lookup_function_symbol(func->get_name()));

  return func;
}  
Esempio n. 28
0
int main(int argc, char *argv[])
{
	std::string filename;

    SgProject *project = frontend(argc, argv);
#ifdef NEWDU
    EDefUse *edu=new EDefUse(project);
		// Create the global def-use analysis
		if (edu->run(false)==0)
		{
			std::cerr<<"DFAnalysis failed!"<<endl;
		}
#endif
		std::vector<InterproceduralInfo*> ip;

 // list < SgNode * >functionDeclarations = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);
    NodeQuerySynthesizedAttributeType functionDeclarations = NodeQuery::querySubTree(project, V_SgFunctionDeclaration);

 // for (list < SgNode * >::iterator i = functionDeclarations.begin(); i != functionDeclarations.end(); i++)
    for (NodeQuerySynthesizedAttributeType::iterator i = functionDeclarations.begin(); i != functionDeclarations.end(); i++)
    {
        DataDependenceGraph *ddg;
        InterproceduralInfo *ipi;

        SgFunctionDeclaration *fD = isSgFunctionDeclaration(*i);

        // SGFunctionDefinition * fDef;
        ROSE_ASSERT(fD != NULL);

        // CI (01/08/2007): A missing function definition is an indicator to a 
        // 
        // 
        // librarycall. 
        // * An other possibility would be a programmer-mistake, which we
        // don't treat at this point.  // I assume librarycall
        if (fD->get_definition() == NULL)
        {
        }
        else
        {
            // get the control depenence for this function
						ipi=new InterproceduralInfo(fD);

            ROSE_ASSERT(ipi != NULL);

            // get the data dependence for this function
#ifdef NEWDU
            ddg = new DataDependenceGraph(fD->get_definition(),edu);
#else
            ddg = new DataDependenceGraph(fD->get_definition());
#endif
						//printf("DDG for %s:\n", fD->get_name().str());
						
// Liao, Feb. 7/2008,
//strip off absolute path to avoid polluting the source tree with generated .dot files
            //filename = (fD->get_definition()->get_file_info()->get_filenameString ()) 
            filename = StringUtility::stripPathFromFileName((fD->get_definition()->get_file_info()->get_filenameString ()))
         + "." + (fD->get_name().getString()) + ".ddg.dot";
            ddg->writeDot((char *)filename.c_str());

        }   
    }
		return 0;
}
Esempio n. 29
0
File: traceCPU.C Progetto: 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);
}
Esempio n. 30
0
// Main inliner code.  Accepts a function call as a parameter, and inlines
// only that single function call.  Returns true if it succeeded, and false
// otherwise.  The function call must be to a named function, static member
// function, or non-virtual non-static member function, and the function
// must be known (not through a function pointer or member function
// pointer).  Also, the body of the function must already be visible.
// Recursive procedures are handled properly (when allowRecursion is set), by
// inlining one copy of the procedure into itself.  Any other restrictions on
// what can be inlined are bugs in the inliner code.
bool
doInline(SgFunctionCallExp* funcall, bool allowRecursion)
{
    SgExpression* funname = funcall->get_function();
    SgExpression* funname2 = isSgFunctionRefExp(funname);
    SgDotExp* dotexp = isSgDotExp(funname);
    SgArrowExp* arrowexp = isSgArrowExp(funname);
    SgExpression* thisptr = 0;
    if (dotexp || arrowexp)
    {
        funname2 = isSgBinaryOp(funname)->get_rhs_operand();
        if (dotexp) {
            SgExpression* lhs = dotexp->get_lhs_operand();

            // FIXME -- patch this into p_lvalue
            bool is_lvalue = lhs->get_lvalue();
            if (isSgInitializer(lhs)) is_lvalue = false;

            if (!is_lvalue) {
                SgAssignInitializer* ai = SageInterface::splitExpression(lhs);
                ROSE_ASSERT (isSgInitializer(ai->get_operand()));
                SgInitializedName* in = isSgInitializedName(ai->get_parent());
                ROSE_ASSERT (in);
                removeRedundantCopyInConstruction(in);
                lhs = dotexp->get_lhs_operand(); // Should be a var ref now
            }
            thisptr = new SgAddressOfOp(SgNULL_FILE, lhs);
        } else if (arrowexp) {
            thisptr = arrowexp->get_lhs_operand();
        } else {
            assert (false);
        }
    }

    if (!funname2)
    {
        // std::cout << "Inline failed: not a call to a named function" << std::endl;
        return false; // Probably a call through a fun ptr
    }

    SgFunctionSymbol* funsym = 0;
    if (isSgFunctionRefExp(funname2))
        funsym = isSgFunctionRefExp(funname2)->get_symbol();
    else if (isSgMemberFunctionRefExp(funname2))
        funsym = isSgMemberFunctionRefExp(funname2)->get_symbol();
    else
        assert (false);

    assert (funsym);
    if (isSgMemberFunctionSymbol(funsym) && isSgMemberFunctionSymbol(funsym)->get_declaration()->get_functionModifier().isVirtual())
    {
        // std::cout << "Inline failed: cannot inline virtual member functions" << std::endl;
        return false;
    }

    SgFunctionDeclaration* fundecl = funsym->get_declaration();
    SgFunctionDefinition* fundef = fundecl->get_definition();
    if (!fundef)
    {
        // std::cout << "Inline failed: no definition is visible" << std::endl;
        return false; // No definition of the function is visible
    }
    if (!allowRecursion)
    {
        SgNode* my_fundef = funcall;
        while (my_fundef && !isSgFunctionDefinition(my_fundef))
        {
            // printf ("Before reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
            my_fundef = my_fundef->get_parent();
            ROSE_ASSERT(my_fundef != NULL);
            // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        }
        // printf ("After reset: my_fundef = %p = %s \n",my_fundef,my_fundef->class_name().c_str());
        assert (isSgFunctionDefinition(my_fundef));
        if (isSgFunctionDefinition(my_fundef) == fundef)
        {
            std::cout << "Inline failed: trying to inline a procedure into itself" << std::endl;
            return false;
        }
    }

    SgVariableDeclaration* thisdecl = 0;
    SgName thisname("this__");
    thisname << ++gensym_counter;
    SgInitializedName* thisinitname = 0;
    if (isSgMemberFunctionSymbol(funsym) && !fundecl->get_declarationModifier().get_storageModifier().isStatic())
    {
        assert (thisptr != NULL);
        SgType* thisptrtype = thisptr->get_type();
        const SgSpecialFunctionModifier& specialMod =
            funsym->get_declaration()->get_specialFunctionModifier();
        if (specialMod.isConstructor()) {
            SgFunctionType* ft = funsym->get_declaration()->get_type();
            ROSE_ASSERT (ft);
            SgMemberFunctionType* mft = isSgMemberFunctionType(ft);
            ROSE_ASSERT (mft);
            SgType* ct = mft->get_class_type();
            thisptrtype = new SgPointerType(ct);
        }
        SgConstVolatileModifier& thiscv = fundecl->get_declarationModifier().get_typeModifier().get_constVolatileModifier();
        // if (thiscv.isConst() || thiscv.isVolatile()) { FIXME
        thisptrtype = new SgModifierType(thisptrtype);
        isSgModifierType(thisptrtype)->get_typeModifier().get_constVolatileModifier() = thiscv;
        // }
        // cout << thisptrtype->unparseToString() << " --- " << thiscv.isConst() << " " << thiscv.isVolatile() << endl;
        SgAssignInitializer* assignInitializer = new SgAssignInitializer(SgNULL_FILE, thisptr);
        assignInitializer->set_endOfConstruct(SgNULL_FILE);
        // thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, new SgAssignInitializer(SgNULL_FILE, thisptr));
        thisdecl = new SgVariableDeclaration(SgNULL_FILE, thisname, thisptrtype, assignInitializer);
        thisdecl->set_endOfConstruct(SgNULL_FILE);
        thisdecl->get_definition()->set_endOfConstruct(SgNULL_FILE);
        thisdecl->set_definingDeclaration(thisdecl);

        thisinitname = (thisdecl->get_variables()).back();
        //thisinitname = lastElementOfContainer(thisdecl->get_variables());
        // thisinitname->set_endOfConstruct(SgNULL_FILE);
        assignInitializer->set_parent(thisinitname);

        // printf ("Built new SgVariableDeclaration #1 = %p \n",thisdecl);

        // DQ (6/23/2006): New test
        ROSE_ASSERT(assignInitializer->get_parent() != NULL);
    }

    std::cout << "Trying to inline function " << fundecl->get_name().str() << std::endl;
    SgBasicBlock* funbody_raw = fundef->get_body();
    SgInitializedNamePtrList& params = fundecl->get_args();
    SgInitializedNamePtrList::iterator i;
    SgExpressionPtrList& funargs = funcall->get_args()->get_expressions();
    SgExpressionPtrList::iterator j;
    //int ctr; // unused variable, Liao
    std::vector<SgInitializedName*> inits;
    SgTreeCopy tc;
    SgFunctionDefinition* function_copy = isSgFunctionDefinition(fundef->copy(tc));
    ROSE_ASSERT (function_copy);
    SgBasicBlock* funbody_copy = function_copy->get_body();


    SgFunctionDefinition* targetFunction = PRE::getFunctionDefinition(funcall);

    renameLabels(funbody_copy, targetFunction);
    std::cout << "Original symbol count: " << funbody_raw->get_symbol_table()->size() << std::endl;
    std::cout << "Copied symbol count: " << funbody_copy->get_symbol_table()->size() << std::endl;
    // std::cout << "Original symbol count f: " << fundef->get_symbol_table()->size() << std::endl;
    // std::cout << "Copied symbol count f: " << function_copy->get_symbol_table()->size() << std::endl;
    // We don't need to keep the copied function definition now that the
    // labels in it have been moved to the target function.  Having it in the
    // memory pool confuses the AST tests.
    function_copy->set_declaration(NULL);
    function_copy->set_body(NULL);
    delete function_copy;
    function_copy = NULL;
#if 0
    SgPragma* pragmaBegin = new SgPragma("start_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaBeginDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaBegin);
    pragmaBeginDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaBegin->set_parent(pragmaBeginDecl);
    pragmaBeginDecl->set_definingDeclaration(pragmaBeginDecl);
    funbody_copy->prepend_statement(pragmaBeginDecl);
    pragmaBeginDecl->set_parent(funbody_copy);
#endif
    ReplaceParameterUseVisitor::paramMapType paramMap;
    for (i = params.begin(), j = funargs.begin(); i != params.end() && j != funargs.end(); ++i, ++j)
    {
        SgAssignInitializer* ai = new SgAssignInitializer(SgNULL_FILE, *j, (*i)->get_type());
        ROSE_ASSERT(ai != NULL);
        ai->set_endOfConstruct(SgNULL_FILE);
        SgName shadow_name((*i)->get_name());
        shadow_name << "__" << ++gensym_counter;
        SgVariableDeclaration* vardecl = new SgVariableDeclaration(SgNULL_FILE,shadow_name,(*i)->get_type(),ai);
        vardecl->set_definingDeclaration(vardecl);
        vardecl->set_endOfConstruct(SgNULL_FILE);
        vardecl->get_definition()->set_endOfConstruct(SgNULL_FILE);

        printf ("Built new SgVariableDeclaration #2 = %p = %s initializer = %p \n",vardecl,shadow_name.str(),(*(vardecl->get_variables().begin()))->get_initializer());

        vardecl->set_parent(funbody_copy);
        SgInitializedName* init = (vardecl->get_variables()).back();
        // init->set_endOfConstruct(SgNULL_FILE);
        inits.push_back(init);
        ai->set_parent(init);
        init->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin() + (i - params.begin()), vardecl);
        SgVariableSymbol* sym = new SgVariableSymbol(init);
        paramMap[*i] = sym;
        funbody_copy->insert_symbol(shadow_name, sym);
        sym->set_parent(funbody_copy->get_symbol_table());
    }

    if (thisdecl)
    {
        thisdecl->set_parent(funbody_copy);
        thisinitname->set_scope(funbody_copy);
        funbody_copy->get_statements().insert(funbody_copy->get_statements().begin(), thisdecl);
        SgVariableSymbol* thisSym = new SgVariableSymbol(thisinitname);
        funbody_copy->insert_symbol(thisname, thisSym);
        thisSym->set_parent(funbody_copy->get_symbol_table());
        ReplaceThisWithRefVisitor(thisSym).traverse(funbody_copy, postorder);
    }
    ReplaceParameterUseVisitor(paramMap).traverse(funbody_copy, postorder);

    SgName end_of_inline_name = "rose_inline_end__";
    end_of_inline_name << ++gensym_counter;
    SgLabelStatement* end_of_inline_label = new SgLabelStatement(SgNULL_FILE, end_of_inline_name);
    end_of_inline_label->set_endOfConstruct(SgNULL_FILE);

#if 0
    printf ("\n\nCalling AST copy mechanism on a SgBasicBlock \n");

    // Need to set the parent of funbody_copy to avoid error.
    funbody_copy->set_parent(funbody_raw->get_parent());

    printf ("This is a copy of funbody_raw = %p to build funbody_copy = %p \n",funbody_raw,funbody_copy);

    printf ("funbody_raw->get_statements().size()  = %zu \n",funbody_raw->get_statements().size());
    printf ("funbody_copy->get_statements().size() = %zu \n",funbody_copy->get_statements().size());

    printf ("funbody_raw->get_symbol_table()->size()  = %d \n",(int)funbody_raw->get_symbol_table()->size());
    printf ("funbody_copy->get_symbol_table()->size() = %d \n",(int)funbody_copy->get_symbol_table()->size());

    printf ("Output the symbol table for funbody_raw \n");
    funbody_raw->get_symbol_table()->print("debugging copy problem");

    // printf ("Output the symbol table for funbody_copy \n");
    // funbody_copy->get_symbol_table()->print("debugging copy problem");

    SgProject* project_copy = TransformationSupport::getProject(funbody_raw);
    ROSE_ASSERT(project_copy != NULL);

    const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 4000;
    generateAstGraph(project_copy,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH);
#endif

    // printf ("Exiting as a test after testing the symbol table \n");
    // ROSE_ASSERT(false);

    funbody_copy->append_statement(end_of_inline_label);
    end_of_inline_label->set_scope(targetFunction);
    SgLabelSymbol* end_of_inline_label_sym = new SgLabelSymbol(end_of_inline_label);
    end_of_inline_label_sym->set_parent(targetFunction->get_symbol_table());
    targetFunction->get_symbol_table()->insert(end_of_inline_label->get_name(), end_of_inline_label_sym);
    // To ensure that there is some statement after the label
    SgExprStatement* dummyStatement = SageBuilder::buildExprStatement(SageBuilder::buildNullExpression());
    dummyStatement->set_endOfConstruct(SgNULL_FILE);
    funbody_copy->append_statement(dummyStatement);
    dummyStatement->set_parent(funbody_copy);
#if 0
    SgPragma* pragmaEnd = new SgPragma("end_of_inline_function", SgNULL_FILE);
    SgPragmaDeclaration* pragmaEndDecl = new SgPragmaDeclaration(SgNULL_FILE, pragmaEnd);
    pragmaEndDecl->set_endOfConstruct(SgNULL_FILE);
    pragmaEnd->set_parent(pragmaEndDecl);
    pragmaEndDecl->set_definingDeclaration(pragmaEndDecl);
    funbody_copy->append_statement(pragmaEndDecl);
    pragmaEndDecl->set_parent(funbody_copy);
#endif
    // std::cout << "funbody_copy is " << funbody_copy->unparseToString() << std::endl;

    ChangeReturnsToGotosPrevisitor previsitor = ChangeReturnsToGotosPrevisitor(end_of_inline_label, funbody_copy);
    // std::cout << "funbody_copy 2 is " << funbody_copy->unparseToString() << std::endl;
    replaceExpressionWithStatement(funcall, &previsitor);
    // std::cout << "Inline succeeded " << funcall->get_parent()->unparseToString() << std::endl;
    return true;
}