int main ( int argc, char* argv[] ) { // Main Function for default example ROSE Preprocessor // This is an example of a preprocessor that can be built with ROSE // This example can be used to test the ROSE infrastructure ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! if (SgProject::get_verbose() > 0) printf ("In preprocessor.C: main() \n"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); #if 0 // This fails for test2005_63.C but Rich has fixed this // by updating the pdf library we are using within ROSE. printf ("Generate the pdf output of the SAGE III AST \n"); generatePDF ( *project ); #endif #if 0 printf ("Generate the dot output of the SAGE III AST \n"); generateDOT ( *project ); #endif #if 1 // DQ (2/6/2004): These tests fail in Coco for test2004_14.C AstTests::runAllTests(const_cast<SgProject*>(project)); #else printf ("Skipped agressive (slow) internal consistancy tests! \n"); #endif if (project->get_verbose() > 0) printf ("Calling the AST copy mechanism \n"); // Demonstrate the copying of the whole AST SgProject* newProject = static_cast<SgProject*>(copyAST(project)); ROSE_ASSERT(newProject != NULL); printf ("Running tests on copy of AST \n"); AstTests::runAllTests(newProject); if (project->get_verbose() > 0) printf ("Calling the backend() \n"); int errorCode = 0; errorCode = backend(project); // DQ (7/7/2005): Only output the performance report if verbose is set (greater than zero) if (project->get_verbose() > 0) { // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h) AstPerformance::generateReport(); } // printf ("Exiting with errorCode = %d \n",errorCode); return errorCode; }
int main ( int argc, char* argv[] ) { ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! ofstream datfile ( "ProblemVariableDeclarations.data" , ios::out | ios::app ); if ( datfile.good() == false ) { printf ("File failed to open \n"); } // datfile << "This is a test!" << std::endl; #if 1 SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); Traversal traversal(&datfile); traversal.traverse(project,preorder); #endif datfile.close(); #if 1 // Run AST consistancy tests (so that we can test them while we analize KULL AstTests::runAllTests(const_cast<SgProject*>(project)); #else printf ("Skipped agressive (slow) internal consistancy tests! \n"); #endif #if 0 return 0; #else // Output the source code and generate the object file so that // we can test these parts of KULL processing as well if (project->get_verbose() > 0) printf ("Calling the backend() \n"); int errorCode = 0; errorCode = backend(project); // DQ (12/3/2004): Test use of AST delete // DeleteSgTree(project); project = NULL; // DQ (7/7/2005): Only output the performance report if verbose is set (greater than zero) if (project->get_verbose() > 0) { // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h) AstPerformance::generateReport(); } return errorCode; #endif }
int main ( int argc, char* argv[] ) { // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer ("AST check Main:"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); findSwitchWithoutDefault(project); // if (project->get_verbose() > 0) // printf ("Calling the backend() \n"); int errorCode = 0; // errorCode = backend(project); // Just set the project, the report will be generated upon calling the destructor for "timer" timer.set_project(project); if (project->get_verbose() > 0) { // Output any saved performance data (see ROSE/src/astDiagnostics/AstPerformance.h) AstPerformance::generateReport(); } // return 0; // printf ("Exiting with errorCode = %d \n",errorCode); return errorCode; }
int main( int argc, char * argv[] ) { // Introduces tracking of performance of ROSE at the top most level. TimingPerformance timer ("AST translation (main): time (sec) = ",true); SgProject* project = frontend(argc,argv); AstTests::runAllTests(project); // Output statistics about how ROSE was used... if (project->get_verbose() > 1) { std::cout << AstNodeStatistics::traversalStatistics(project); std::cout << AstNodeStatistics::IRnodeUsageStatistics(); } // Just set the project, the report will be generated upon calling the destructor for "timer" // Use option "-rose:verbose 2" to see the report. timer.set_project(project); // Skip calling the typical backend for ROSE (not required for just testing analysis) // This backend calls the backend compiler using the original input source file list. return backendCompilesUsingOriginalInputFile(project); }
int main ( int argc, char* argv[] ) { ROSE_INITIALIZE; if (SgProject::get_verbose() > 0) printf ("In preprocessor.C: main() \n"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); Rose_STL_Container<SgNode*> nodeList; nodeList = NodeQuery::querySubTree (project,V_SgForStatement); printf ("\nnodeList.size() = %zu \n",nodeList.size()); Rose_STL_Container<SgNode*>::iterator i = nodeList.begin(); while (i != nodeList.end()) { Sg_File_Info & fileInfo = *((*i)->get_file_info()); printf ("Query node = %p = %s in %s \n ----- at line %d on column %d \n", *i,(*i)->sage_class_name(),fileInfo.get_filename(), fileInfo.get_line(), fileInfo.get_col()); i++; } if (project->get_verbose() > 0) printf ("Calling the backend() \n"); return 0; }
int main( int argc, char * argv[] ) { // Introduces tracking of performance of ROSE at the top most level. TimingPerformance timer ("AST translation (main): time (sec) = ",true); // Build a vector of strings to represent the command line arguments. std::vector<std::string> sourceCommandline = std::vector<std::string>(argv, argv + argc); sourceCommandline.push_back("-rose:unparse_tokens"); SgProject* project = frontend(sourceCommandline); AstTests::runAllTests(project); // Evaluate the number of tokens generated for each file on the command line. SgFilePtrList & fileList = project->get_fileList(); for (size_t i=0; i < fileList.size(); i++) { SgSourceFile* sourceFile = isSgSourceFile(fileList[i]); if (sourceFile != NULL) { size_t numberOfTokens = sourceFile->get_token_list().size(); printf ("Number of tokens in file %s = %zu \n",sourceFile->get_sourceFileNameWithPath().c_str(),numberOfTokens); if (numberOfTokens == 0) { // We output an error, but since this test is only presently valid for fortran files it is not serious. if (sourceFile->get_Fortran_only() == true) { printf ("Warning: numberOfTokens in file equal zero (could be an error). \n"); } else { printf ("Warning: token evaluation only valid for Fortran files at present. \n"); } } } else { printf ("Warning, token evaluation only valid for source files. \n"); } } // Output statistics about how ROSE was used... if (project->get_verbose() > 1) { std::cout << AstNodeStatistics::traversalStatistics(project); std::cout << AstNodeStatistics::IRnodeUsageStatistics(); } // Just set the project, the report will be generated upon calling the destructor for "timer" // Use option "-rose:verbose 2" to see the report. timer.set_project(project); // Skip calling the typical backend for ROSE (not required for just testing analysis) // This backend calls the backend compiler using the original input source file list. return backendCompilesUsingOriginalInputFile(project); }
int main ( int argc, char* argv[] ) { ios::sync_with_stdio(); // Syncs C++ and C I/O subsystems! if (SgProject::get_verbose() > 0) printf ("In preprocessor.C: main() \n"); SgProject* project = frontend(argc,argv); ROSE_ASSERT (project != NULL); // AST diagnostic tests AstTests::runAllTests(const_cast<SgProject*>(project)); // test statistics if (project->get_verbose() > 1) { cout << AstNodeStatistics::traversalStatistics(project); cout << AstNodeStatistics::IRnodeUsageStatistics(); } if (project->get_verbose() > 0) printf ("Generate the pdf output of the SAGE III AST \n"); generatePDF ( *project ); if (project->get_verbose() > 0) printf ("Generate the DOT output of the SAGE III AST \n"); generateDOT ( *project ); Rose_STL_Container<SgNode*> nodeList; // nodeList = NodeQuery::querySubTree (project,V_SgType,NodeQuery::ExtractTypes); nodeList = NodeQuery::querySubTree (project,V_SgForStatement); printf ("\nnodeList.size() = %zu \n",nodeList.size()); Rose_STL_Container<SgNode*>::iterator i = nodeList.begin(); while (i != nodeList.end()) { printf ("Query node = %p = %s = %s \n",*i,(*i)->sage_class_name(),(*i)->unparseToString().c_str()); i++; } return 0; }
static void run(Compass::Parameters parameters, Compass::OutputObject* output) { // We only care about source code in the user's space, not, // for example, Boost or system files. string target_directory = parameters["general::target_directory"].front(); CompassAnalyses::AllocateAndFreeInTheSameModule::source_directory.assign(target_directory); // Use the pre-built ROSE AST SgProject* sageProject = Compass::projectPrerequisite.getProject(); ROSE_ASSERT(sageProject != NULL); SgNode* root_node = (SgNode*) sageProject; ROSE_ASSERT(root_node != NULL); bool verbose = sageProject->get_verbose(); // maps variables in the symbol table to a boolean // determining whether that variable has been freed // or not boost::unordered_map<SgSymbol*, bool> var_free_status; // maps variables in the symbol table to the original malloc // call that was performed on them so we can return this // as checker output if no matching frees are found boost::unordered_map<SgSymbol*, SgNode*> malloc_nodes; // keeps track of the dynamically allocated variables in the // symbol table that were freed boost::unordered_set<SgSymbol*> freed; // keeps track of the dynamically allocated variables in the // symbol table std::vector<SgSymbol*> unfreed; // tracks function calls that explicitly return a malloc (e.g. return malloc()...) boost::unordered_set<SgFunctionCallExp*> explicit_malloc_func_calls; // keeps track of the inner variable being returned by a pointer function // e.g. return var1; appearing in the function func1 would map func1 to var1 boost::unordered_map<SgFunctionCallExp*, SgSymbol*> func_inner_var_mappings; // keeps track of the outer variable that receives the value of a pointer function // e.g. var2 = func1(); would map func1 to var2 boost::unordered_map<SgFunctionCallExp*, SgSymbol*> func_outer_var_mappings; // keeps a list of all functions added to either of the above two hash maps boost::unordered_set<SgFunctionCallExp*> tracked_functions; // for each pointer variable, tracks the list of all other pointer // variables in the program that are ever set to the value (and are thus // associated with) this pointer variable boost::unordered_map<SgSymbol*, boost::unordered_set<SgSymbol*> > var_mappings; std::vector<SgSymbol*> var_mappings_list; VariableIdMapping var_ids; var_ids.computeVariableSymbolMapping(sageProject); // we have to do SgFunctionCallExp's first because the inner/outer // variable mappings require this to be pre-processed AstMatching func_call_matcher; MatchResult func_call_matches = func_call_matcher .performMatching("$f=SgFunctionCallExp", root_node); BOOST_FOREACH(SingleMatchVarBindings match, func_call_matches) { SgFunctionCallExp *func_call = (SgFunctionCallExp *)match["$f"]; SgFunctionRefExp *func_ref = isSgFunctionRefExp(func_call->get_traversalSuccessorByIndex(0)); if(func_ref == NULL) continue; std::string func_str = func_ref->get_symbol()->get_name().getString(); if(func_str.compare("free") == 0) { AstMatching var_matcher; SgVarRefExp *var_ref = isSgVarRefExp(var_matcher .performMatching("$r=SgVarRefExp", func_call) .back()["$r"]); if(var_ref) { SgSymbol *var_ref_symbol = var_ref->get_symbol(); if(verbose) std::cout << "FREE FOUND ON: " << var_ref_symbol->get_name() << std::endl; freed.insert(var_ref_symbol); } } else { SgExprListExp *expr_list = func_call->get_args(); SgFunctionDefinition *func_def = SgNodeHelper::determineFunctionDefinition(func_call); if(func_def == NULL) continue; SgFunctionDeclaration *func_dec = func_def->get_declaration(); if(func_dec == NULL) continue; SgFunctionParameterList *func_params = func_dec->get_parameterList(); if(func_params == NULL) continue; for(int i = 0; i < expr_list->get_numberOfTraversalSuccessors(); i++) { if(i >= func_params->get_numberOfTraversalSuccessors()) break; SgNode* param = expr_list->get_traversalSuccessorByIndex(i); SgInitializedName* func_param = isSgInitializedName(func_params->get_traversalSuccessorByIndex(i)); VariableId func_param_id = var_ids.variableId(func_param); SgSymbol *func_param_sym = var_ids.getSymbol(func_param_id); ROSE_ASSERT(func_param != NULL); ROSE_ASSERT(func_param_sym != NULL); // we use an AST match in case this is a container type // the last match will be a reference to the actual variable SgVarRefExp *param_var = NULL; AstMatching param_var_matcher; MatchResult param_var_matches = param_var_matcher .performMatching("$v=SgVarRefExp", param); if(param_var_matches.size() > 0) { param_var = (SgVarRefExp *)param_var_matches.back()["$v"]; } if(param_var != NULL) { SgSymbol *param_sym = param_var->get_symbol(); // now we must add var mappings from the inner parameter of the function if(var_mappings.find(param_sym) == var_mappings.end()) { var_mappings_list.push_back(param_sym); boost::unordered_set<SgSymbol*> set; set.insert(func_param_sym); var_mappings[param_sym] = set; } else { var_mappings[param_sym].insert(func_param_sym); } } else { // handle the case of malloc() or calloc() being passed as a function parameter AstMatching func_ref_matcher; MatchResult found_func_matches = func_ref_matcher.performMatching("$r=SgFunctionRefExp", param); if(found_func_matches.size() > 0) { SgFunctionRefExp *found_func = isSgFunctionRefExp( found_func_matches.front()["$r"]); if(!found_func->isDefinable()) continue; std::string found_func_str = found_func->get_symbol() ->get_name().getString(); if(found_func_str.compare("malloc") == 0 || found_func_str.compare("calloc") == 0) { // found a malloc call within a function parameter // we must map this to whatever variable it would be assigned in the // parent function var_free_status[func_param_sym] = false; malloc_nodes[func_param_sym] = found_func->get_symbol(); unfreed.push_back(func_param_sym); } } } } // figure out if a malloc is returned (directly) by this function AstMatching return_matcher; MatchResult return_matches = return_matcher .performMatching("$r=SgReturnStmt", func_def); BOOST_FOREACH(SingleMatchVarBindings return_match, return_matches) { SgReturnStmt *func_ret = (SgReturnStmt *)return_match["$r"]; // map MALLOCS & CALLOC out AstMatching return_func_matcher; MatchResult return_func_matches = return_func_matcher .performMatching("$f=SgFunctionRefExp", func_ret); BOOST_FOREACH(SingleMatchVarBindings return_func_match, return_func_matches) { SgFunctionRefExp *return_func_ref = (SgFunctionRefExp *)return_func_match["$f"]; SgFunctionCallExp *return_func_call = isSgFunctionCallExp(return_func_ref->get_parent()); if(return_func_call == NULL) continue; std::string return_func_str = return_func_ref->get_symbol()->get_name().getString(); if(return_func_str.compare("malloc") == 0 || return_func_str.compare("calloc") == 0) { if(verbose && explicit_malloc_func_calls.find(func_call) == explicit_malloc_func_calls.end()) { std::cout << "MALLOC FOUND ON: \"" << func_str << "\" return statement" << std::endl; } explicit_malloc_func_calls.insert(func_call); // once we have one malloc we can ignore the rest of the return statement break; } } // do inner var mappings AstMatching return_var_matcher; MatchResult return_var_matches = return_var_matcher .performMatching("$v=SgVarRefExp", func_ret); BOOST_FOREACH(SingleMatchVarBindings return_var_match, return_var_matches) { SgVarRefExp *return_var = (SgVarRefExp *)return_var_match["$v"]; // skip non pointer variables if(!SageInterface::isPointerType(return_var->get_type())) continue; SgSymbol *return_var_sym = return_var->get_symbol(); if(return_var_sym == NULL) continue; func_inner_var_mappings[func_call] = return_var_sym; tracked_functions.insert(func_call); if(verbose) std::cout << "INNER VARIABLE MAPPING: " << func_str << " returns " << return_var_sym->get_name() << std::endl; }