From 821f96c3b796592cd95b0e7e6d19fddbdc327cd2 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sat, 2 Sep 2023 01:28:50 -0400 Subject: [PATCH 01/42] [REX]:deBoost: replace boost::replace_all_copy with Rose::StringUtility::replaceAllCopy --- .../FortranModuleInfo.C | 4 +-- src/frontend/SageIII/sage_support/cmdline.cpp | 4 +-- src/util/StringUtility/CMakeLists.txt | 4 +-- src/util/StringUtility/Escape.C | 6 ++--- src/util/StringUtility/Makefile.am | 5 ++-- src/util/StringUtility/Replace.C | 15 +++++++++++ src/util/StringUtility/Replace.h | 26 +++++++++++++++++++ src/util/StringUtility/StringUtility.h | 1 + 8 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 src/util/StringUtility/Replace.C create mode 100644 src/util/StringUtility/Replace.h diff --git a/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C b/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C index be9bc3b4a5e..97c3cc70d5d 100644 --- a/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C +++ b/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C @@ -1,8 +1,8 @@ #include "sage3basic.h" +#include "Replace.h" #include "FortranModuleInfo.h" #include "boost/filesystem.hpp" -#include "boost/algorithm/string/replace.hpp" using namespace std; using std::string; @@ -85,7 +85,7 @@ FortranModuleInfo::set_inputDirs(SgProject* project) { if (args[i].find("-I",0)==0) { rmodDir = args[i].substr(2); std::string rmodDir_no_quotes = - boost::replace_all_copy(rmodDir, "\"", ""); + Rose::StringUtility::replaceAllCopy(rmodDir, "\"", ""); if (boost::filesystem::exists(rmodDir_no_quotes.c_str())) { inputDirs.push_back(rmodDir_no_quotes); diff --git a/src/frontend/SageIII/sage_support/cmdline.cpp b/src/frontend/SageIII/sage_support/cmdline.cpp index 33bf686c4ad..2721a2566e7 100644 --- a/src/frontend/SageIII/sage_support/cmdline.cpp +++ b/src/frontend/SageIII/sage_support/cmdline.cpp @@ -11,12 +11,12 @@ #include "cmdline.h" #include "keep_going.h" #include "FileUtility.h" +#include "Replace.h" #include "omp_simd.h" #include "Outliner.hh" #include -#include using namespace Rose; // temporary, until this file lives in namespace Rose @@ -1463,7 +1463,7 @@ SgProject::processCommandLine(const vector& input_argv) p_includeDirectorySpecifierList.push_back("-I" + include_path); - std::string include_path_no_quotes = boost::replace_all_copy(include_path, "\"", ""); + std::string include_path_no_quotes = Rose::StringUtility::replaceAllCopy(include_path, "\"", ""); try { bool is_directory = boost::filesystem::is_directory(include_path_no_quotes); diff --git a/src/util/StringUtility/CMakeLists.txt b/src/util/StringUtility/CMakeLists.txt index 5b2f972d82d..056bed2f07e 100644 --- a/src/util/StringUtility/CMakeLists.txt +++ b/src/util/StringUtility/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(util_StringUtility OBJECT - Convert.C Escape.C FileNameClassifier.C FileUtility.C NumberToString.C Predicate.C SplitJoin.C StringToNumber.C) + Convert.C Escape.C FileNameClassifier.C FileUtility.C NumberToString.C Predicate.C Replace.C SplitJoin.C StringToNumber.C) install( - FILES Convert.h Escape.h FileUtility.h NumberToString.h Predicate.h SplitJoin.h StringToNumber.h BitOps.h Constants.h StringUtility.h + FILES Convert.h Escape.h FileUtility.h NumberToString.h Predicate.h Replace.h SplitJoin.h StringToNumber.h BitOps.h Constants.h StringUtility.h DESTINATION ${INCLUDE_INSTALL_DIR}/util/StringUtility) \ No newline at end of file diff --git a/src/util/StringUtility/Escape.C b/src/util/StringUtility/Escape.C index 0b96a59e3ef..965ae282c4c 100644 --- a/src/util/StringUtility/Escape.C +++ b/src/util/StringUtility/Escape.C @@ -3,8 +3,8 @@ #include #include #include +#include #include -#include namespace Rose { namespace StringUtility { @@ -187,7 +187,7 @@ bourneEscape(const std::string &s) { // and escape backslashes. for (char ch: s) { if (!::isalnum(ch) && !strchr("_-+./", ch)) - return "'" + boost::replace_all_copy(s, "\\", "\\\\") + "'"; + return "'" + Rose::StringUtility::replaceAllCopy(s, "\\", "\\\\") + "'"; } // No quoting or escaping necessary @@ -214,7 +214,7 @@ yamlEscape(const std::string &s) { std::string csvEscape(const std::string &s) { const std::string quote = s.find_first_of(",\r\n\"") == std::string::npos ? "" : "\""; - return quote + boost::replace_all_copy(s, "\"", "\"\"") + quote; + return quote + Rose::StringUtility::replaceAllCopy(s, "\"", "\"\"") + quote; } // DQ (12/8/2016): This version fixed most of the issues that Robb raised with the escapeNewLineCharaters() function. diff --git a/src/util/StringUtility/Makefile.am b/src/util/StringUtility/Makefile.am index f48a5afac64..8bb02f57c83 100644 --- a/src/util/StringUtility/Makefile.am +++ b/src/util/StringUtility/Makefile.am @@ -12,6 +12,7 @@ libRoseStringUtility_la_SOURCES = \ FileUtility.C \ NumberToString.C \ Predicate.C \ + Replace.C \ SplitJoin.C \ StringToNumber.C @@ -24,6 +25,7 @@ pkginclude_HEADERS = \ FileUtility.h \ NumberToString.h \ Predicate.h \ + Replace.h \ SplitJoin.h \ StringToNumber.h @@ -34,5 +36,4 @@ clean-local: distclean-local: rm -rf Templates.DB -EXTRA_DIST = CMakeLists.txt stringSupportDocumentation.docs - +EXTRA_DIST = CMakeLists.txt stringSupportDocumentation.docs \ No newline at end of file diff --git a/src/util/StringUtility/Replace.C b/src/util/StringUtility/Replace.C new file mode 100644 index 00000000000..89ca31997bf --- /dev/null +++ b/src/util/StringUtility/Replace.C @@ -0,0 +1,15 @@ +#include + +namespace Rose { +namespace StringUtility { + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Replace +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +std::string replaceAllCopy(const std::string& input, const std::string& search, const std::string & replacedWith) { + return boost::replace_all_copy(input, search, replacedWith); + //TODO: for deBoost, this can be replaced with std::replace_copy when the compiler bumps to support c++17 by default +} + +} // namespace +} // namespace diff --git a/src/util/StringUtility/Replace.h b/src/util/StringUtility/Replace.h new file mode 100644 index 00000000000..8411d3852ce --- /dev/null +++ b/src/util/StringUtility/Replace.h @@ -0,0 +1,26 @@ +#ifndef ROSE_StringUtility_Replace_H +#define ROSE_StringUtility_Replace_H + +#include +#include +#include "boost/algorithm/string/replace.hpp" + + +namespace Rose { +namespace StringUtility { + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Functions for replacing a pattern with another one in a string +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** Replace a pattern with another one in a string + * + * These functions are wrappers around boost::replace_all_copy. + * + * @{ */ +ROSE_UTIL_API std::string replaceAllCopy(const std::string& input, const std::string& search, const std::string & replacedWith); + +} // namespace +} // namespace + +#endif diff --git a/src/util/StringUtility/StringUtility.h b/src/util/StringUtility/StringUtility.h index 9420d18df5e..e5f99e24bde 100644 --- a/src/util/StringUtility/StringUtility.h +++ b/src/util/StringUtility/StringUtility.h @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace Rose { From f134187c1ab6399acc94fe0e8b8082d0d9c11071 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Wed, 6 Sep 2023 13:15:36 -0400 Subject: [PATCH 02/42] Replaced boost::filesystem with std::filesystem --- .gitmodules | 6 +- CMakeLists.txt | 6 +- src/backend/unparser/unparser.C | 45 +++++++------- .../FortranModuleInfo.C | 12 ++-- .../SageIII/attachPreprocessingInfo.C | 4 +- src/frontend/SageIII/sage_support/cmdline.cpp | 10 ++-- .../SageIII/sage_support/keep_going.cpp | 7 ++- .../SageIII/sage_support/sage_support.cpp | 16 ++--- .../SageIII/sage_support/sage_support.h | 4 +- .../astOutlining/Outliner.cc | 6 +- src/rose-config.C | 10 ++-- src/util/FileSystem.C | 58 +++++++++++++------ src/util/FileSystem.h | 37 ++++++------ src/util/StringUtility/FileNameClassifier.C | 12 ++-- src/util/StringUtility/FileUtility.h | 16 ++--- src/util/support/FileHelper.h | 26 ++++----- 16 files changed, 150 insertions(+), 125 deletions(-) diff --git a/.gitmodules b/.gitmodules index 672019caae0..abb0f8de5f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "src/frontend/CxxFrontend/EDG"] path = src/frontend/CxxFrontend/EDG - url = https://github.com/passlab/EDG.git + url = git@github.com:passlab/EDG.git [submodule "src/frontend/SageIII/ompparser"] path = src/frontend/SageIII/ompparser - url = https://github.com/passlab/ompparser.git + url = git@github.com:passlab/ompparser.git [submodule "src/frontend/SageIII/accparser"] path = src/frontend/SageIII/accparser - url = https://github.com/passlab/accparser.git + url = git@github.com:passlab/accparser.git diff --git a/CMakeLists.txt b/CMakeLists.txt index bce626bc786..136eb806802 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ else() set(CMAKE_VERBOSE_MAKEFILE FALSE) endif() -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) option(BUILD_SHARED_LIBS "Build all libraries shared" FALSE) @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time filesystem iostreams program_options random regex system wave thread + COMPONENTS chrono date_time iostreams program_options random regex system wave thread REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time filesystem iostreams program_options random regex system wave thread serialization) + COMPONENTS chrono date_time iostreams program_options random regex system wave thread serialization) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries diff --git a/src/backend/unparser/unparser.C b/src/backend/unparser/unparser.C index 0c173f4adb8..66bb664816b 100644 --- a/src/backend/unparser/unparser.C +++ b/src/backend/unparser/unparser.C @@ -18,6 +18,7 @@ #include "rose_config.h" #include +#include #if _MSC_VER #include #include @@ -2971,8 +2972,8 @@ unparseFile ( SgFile* file, UnparseFormatHelp *unparseHelp, UnparseDelegate* unp outFolder += package_name; outFolder += (package_name.size() > 0 ? "/" : ""); // Create package folder structure - boost::filesystem::create_directories(outFolder); - ROSE_ASSERT(boost::filesystem::exists(outFolder)); + std::filesystem::create_directories(outFolder); + ROSE_ASSERT(std::filesystem::exists(outFolder)); outputFilename = outFolder + file -> get_sourceFileNameWithoutPath(); // Convert Windows-style paths to POSIX-style. #ifdef _MSC_VER @@ -3290,14 +3291,14 @@ unparseFile ( SgFile* file, UnparseFormatHelp *unparseHelp, UnparseDelegate* unp printf ("In unparseFile(SgFile*): open file for output of generated source code: outputFilename = %s \n",outputFilename.c_str()); #endif // DQ (3/19/2014): Added support for noclobber option. - boost::filesystem::path output_file = outputFilename; + std::filesystem::path output_file = outputFilename; bool trigger_file_comparision = false; string saved_filename = outputFilename; string alternative_filename = outputFilename + ".noclobber_compare"; - if (boost::filesystem::exists(output_file)) + if (std::filesystem::exists(output_file)) { if ( SgProject::get_verbose() > 0 ) { @@ -3530,13 +3531,13 @@ unparseFile ( SgFile* file, UnparseFormatHelp *unparseHelp, UnparseDelegate* unp if ( SgProject::get_verbose() > 0 ) { - printf ("Testing saved_filename against alternative_filename (using boost::filesystem::equivalent()): \n"); + printf ("Testing saved_filename against alternative_filename (using std::filesystem::equivalent()): \n"); printf (" --- saved_filename = %s \n",saved_filename.c_str()); printf (" --- alternative_filename = %s \n",alternative_filename.c_str()); } - boost::filesystem::path saved_output_file = saved_filename; - boost::filesystem::path alternative_output_file = alternative_filename; + std::filesystem::path saved_output_file = saved_filename; + std::filesystem::path alternative_output_file = alternative_filename; std::ifstream ifs1(saved_filename.c_str()); std::ifstream ifs2(alternative_filename.c_str()); @@ -3601,7 +3602,7 @@ unparseFile ( SgFile* file, UnparseFormatHelp *unparseHelp, UnparseDelegate* unp printf ("****************************************************************************************************** \n\n\n"); // remove the generated file or leave in place to allow users to examine file differences. - // boost::filesystem::remove(unparsed_file); + // std::filesystem::remove(unparsed_file); ROSE_ABORT(); } @@ -4786,11 +4787,11 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat #endif string newFileName = adjusted_header_file_directory + filenameWithOutPath; - boost::filesystem::path pathPrefix(adjusted_header_file_directory); + std::filesystem::path pathPrefix(adjusted_header_file_directory); create_directories(pathPrefix); - boost::filesystem::path originalFileNamePath(originalFileName); - boost::filesystem::path newFileNamePath(newFileName); + std::filesystem::path originalFileNamePath(originalFileName); + std::filesystem::path newFileNamePath(newFileName); #if 0 // printf ("Copy this file: \n"); // printf ("Copy this file: unparsedFile = %p filename = %s \n",unparsedFile,unparsedFile->getFileName().c_str()); @@ -4809,7 +4810,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat printf ("Copying file = %s to newFileName = %s \n",originalFileName.c_str(),newFileName.c_str()); #endif // syntax: copy_file(from, to, copy_option::fail_if_exists); - copy_file(originalFileNamePath, newFileNamePath, boost::filesystem::copy_option::fail_if_exists); + copy_file(originalFileNamePath, newFileNamePath, std::filesystem::copy_options::none); } else { @@ -4875,11 +4876,11 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat if (isApplicationFile == true) { - boost::filesystem::path pathPrefix(adjusted_header_file_directory); + std::filesystem::path pathPrefix(adjusted_header_file_directory); create_directories(pathPrefix); - boost::filesystem::path originalFileNamePath(originalFileName); - boost::filesystem::path newFileNamePath(newFileName); + std::filesystem::path originalFileNamePath(originalFileName); + std::filesystem::path newFileNamePath(newFileName); if (exists(newFileNamePath) == true) { @@ -4895,7 +4896,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat else { // syntax: copy_file(from, to, copy_option::fail_if_exists); - copy_file(originalFileNamePath, newFileNamePath, boost::filesystem::copy_option::fail_if_exists); + copy_file(originalFileNamePath, newFileNamePath, std::filesystem::copy_options::none); } } else @@ -5213,7 +5214,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat printf ("Modified adjusted_header_file_directory = %s (part 2) \n",adjusted_header_file_directory.c_str()); #endif // DQ (11/6/2018): Build the path. - boost::filesystem::path pathPrefix(adjusted_header_file_directory); + std::filesystem::path pathPrefix(adjusted_header_file_directory); create_directories(pathPrefix); // DQ (11/8/2018): Adding the "-I" prefix required for use on the command line. @@ -5273,8 +5274,8 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat printf ("applicationRootDirectory = %s \n",applicationRootDirectory.c_str()); } #endif - boost::filesystem::path applicationRootDirectoryPath(applicationRootDirectory); - boost::filesystem::path currentDirectoryPath(adjusted_header_file_directory); + std::filesystem::path applicationRootDirectoryPath(applicationRootDirectory); + std::filesystem::path currentDirectoryPath(adjusted_header_file_directory); string source_filename = unparsedFile->getFileName(); string source_file_directory = Rose::getPathFromFileName(source_filename); @@ -5287,7 +5288,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat printf ("adjusted_header_file_directory = %s \n",adjusted_header_file_directory.c_str()); } #endif - boost::filesystem::path source_file_directory_path(source_file_directory); + std::filesystem::path source_file_directory_path(source_file_directory); #if 1 // DQ (4/4/2020): Added header file unparsing feature specific debug level. if (SgProject::get_unparseHeaderFilesDebug() >= 4) @@ -5297,7 +5298,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat } #endif #if 0 - string canonical_path = boost::filesystem::canonical(source_file_directory_path).string(); + string canonical_path = std::filesystem::canonical(source_file_directory_path).string(); printf ("canonical_path = %s \n",canonical_path.c_str()); #endif @@ -5353,7 +5354,7 @@ void unparseIncludedFiles ( SgProject* project, UnparseFormatHelp *unparseFormat #endif // We might need to build the added directory. - boost::filesystem::path adjusted_header_file_directory_path(adjusted_header_file_directory); + std::filesystem::path adjusted_header_file_directory_path(adjusted_header_file_directory); create_directories(adjusted_header_file_directory_path); #if 0 printf ("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ \n"); diff --git a/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C b/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C index 97c3cc70d5d..0a3bdc3b2e5 100644 --- a/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C +++ b/src/frontend/OpenFortranParser_SAGE_Connection/FortranModuleInfo.C @@ -1,8 +1,8 @@ +#include #include "sage3basic.h" #include "Replace.h" #include "FortranModuleInfo.h" -#include "boost/filesystem.hpp" using namespace std; using std::string; @@ -45,7 +45,7 @@ FortranModuleInfo::find_file_from_inputDirs(string basename ) { name = dir+"/"+ basename; string tmp = name + module_file_suffix(); - if (boost::filesystem::exists(tmp.c_str())) { + if (std::filesystem::exists(tmp.c_str())) { return name; } } @@ -76,7 +76,7 @@ FortranModuleInfo::set_inputDirs(SgProject* project) { rmodDir = args[i+1]; - if (boost::filesystem::exists(rmodDir.c_str())) { + if (std::filesystem::exists(rmodDir.c_str())) { inputDirs.push_back(rmodDir); } else cout << "WARNING: the input directory is not exist : " << rmodDir<< endl; @@ -87,7 +87,7 @@ FortranModuleInfo::set_inputDirs(SgProject* project) { std::string rmodDir_no_quotes = Rose::StringUtility::replaceAllCopy(rmodDir, "\"", ""); - if (boost::filesystem::exists(rmodDir_no_quotes.c_str())) { + if (std::filesystem::exists(rmodDir_no_quotes.c_str())) { inputDirs.push_back(rmodDir_no_quotes); } else { @@ -259,10 +259,10 @@ FortranModuleInfo::createSgSourceFile(string modName) #if 0 printf ("In FortranModuleInfo::createSgSourceFile(): Searching for file rmodFileName = %s \n",rmodFileName.c_str()); - printf ("In FortranModuleInfo::createSgSourceFile(): boost::filesystem::exists(rmodFileName.c_str()) = %s \n",boost::filesystem::exists(rmodFileName.c_str()) ? "true" : "false"); + printf ("In FortranModuleInfo::createSgSourceFile(): std::filesystem::exists(rmodFileName.c_str()) = %s \n",std::filesystem::exists(rmodFileName.c_str()) ? "true" : "false"); #endif - if (boost::filesystem::exists(rmodFileName.c_str()) == false) + if (std::filesystem::exists(rmodFileName.c_str()) == false) { printf ("File rmodFileName = %s NOT FOUND (expected to be present) \n",rmodFileName.c_str()); return NULL; diff --git a/src/frontend/SageIII/attachPreprocessingInfo.C b/src/frontend/SageIII/attachPreprocessingInfo.C index 8499f46be6f..53b09763794 100644 --- a/src/frontend/SageIII/attachPreprocessingInfo.C +++ b/src/frontend/SageIII/attachPreprocessingInfo.C @@ -10,6 +10,8 @@ // This fixed a reported bug which caused conflicts with autoconf macros (e.g. PACKAGE_BUGREPORT). #include "rose_config.h" +#include + // DQ (12/31/2005): This is OK if not declared in a header file using namespace std; @@ -128,7 +130,7 @@ attachPreprocessingInfoUsingWave (SgSourceFile *sageFilePtr, AttributeMapType& a //SageInterface::buildFile(..) generates files in memory where the source file has not yet //been written to disk. We consider any case where the file does not exist on disk to be this //case. - if( ! boost::filesystem::exists(sourceFileName) ) + if( ! std::filesystem::exists(sourceFileName) ) return; // DQ (11/30/2008): diff --git a/src/frontend/SageIII/sage_support/cmdline.cpp b/src/frontend/SageIII/sage_support/cmdline.cpp index 2721a2566e7..a65366f484d 100644 --- a/src/frontend/SageIII/sage_support/cmdline.cpp +++ b/src/frontend/SageIII/sage_support/cmdline.cpp @@ -7,6 +7,8 @@ /*----------------------------------------------------------------------------- * Dependencies *---------------------------------------------------------------------------*/ +#include + #include "sage3basic.h" #include "cmdline.h" #include "keep_going.h" @@ -283,7 +285,7 @@ CommandlineProcessing::isValidFileWithExecutableFileSuffixes ( string name ) printf ("In CommandlineProcessing::isValidFileWithExecutableFileSuffixes(): name = %s \n",name.c_str()); #endif // Open file for reading - if ( boost::filesystem::exists(name.c_str()) ) + if ( std::filesystem::exists(name.c_str()) ) { returnValue = true; @@ -1466,7 +1468,7 @@ SgProject::processCommandLine(const vector& input_argv) std::string include_path_no_quotes = Rose::StringUtility::replaceAllCopy(include_path, "\"", ""); try { - bool is_directory = boost::filesystem::is_directory(include_path_no_quotes); + bool is_directory = std::filesystem::is_directory(include_path_no_quotes); if (false == is_directory) { // DQ (3/15/2017): Fixed to use mlog message logging. @@ -1476,7 +1478,7 @@ SgProject::processCommandLine(const vector& input_argv) << std::endl; } } - catch (const boost::filesystem::filesystem_error& ex) + catch (const std::filesystem::filesystem_error& ex) { MLOG_ERROR_CXX("sage_support") << "Exception processing argument to -I: " @@ -1575,7 +1577,7 @@ NormalizeIncludePathOptions (std::vector& argv) looking_for_include_path_arg = false; // reset for next iteration // Sanity check - bool is_directory = boost::filesystem::is_directory(arg); + bool is_directory = std::filesystem::is_directory(arg); if (false == is_directory) { // DQ (3/15/2017): Fixed to use mlog message logging. diff --git a/src/frontend/SageIII/sage_support/keep_going.cpp b/src/frontend/SageIII/sage_support/keep_going.cpp index 721fdbbc8f4..9b7ff843008 100644 --- a/src/frontend/SageIII/sage_support/keep_going.cpp +++ b/src/frontend/SageIII/sage_support/keep_going.cpp @@ -6,6 +6,7 @@ #include "sage3basic.h" #include +#include #include "keep_going.h" #include "processSupport.h" // ROSE_ASSERT in ROSE/src/util @@ -393,7 +394,7 @@ void Rose::KeepGoing::commandLineProcessing else { expectations_filename__fail = arg; - if (!boost::filesystem::exists(expectations_filename__fail)) + if (!std::filesystem::exists(expectations_filename__fail)) { std::cerr << "[FATAL] " @@ -420,7 +421,7 @@ void Rose::KeepGoing::commandLineProcessing else { expectations_filename__pass = arg; - if (!boost::filesystem::exists(expectations_filename__pass)) + if (!std::filesystem::exists(expectations_filename__pass)) { std::cerr << "[FATAL] " @@ -857,7 +858,7 @@ Rose::KeepGoing::AppendToFile(const std::string& filename, const std::string& ms fout.close(); } } // end scope for the scoped lock - boost::filesystem::remove (lock_file_name); + std::filesystem::remove (lock_file_name); } std::map diff --git a/src/frontend/SageIII/sage_support/sage_support.cpp b/src/frontend/SageIII/sage_support/sage_support.cpp index b94129c9199..fb4642250a5 100644 --- a/src/frontend/SageIII/sage_support/sage_support.cpp +++ b/src/frontend/SageIII/sage_support/sage_support.cpp @@ -21,9 +21,9 @@ #endif #include +#include #include -#include #include // DQ (12/22/2019): I don't need this now, and it is an issue for some compilers (e.g. GNU 4.9.4). @@ -556,7 +556,7 @@ bool roseInstallPrefix(std::string& result) { pathToCache += "/CMakeCache.txt"; if ( SgProject::get_verbose() > 1 ) printf ("Inside of roseInstallPrefix libdir = %s pathToCache = %s \n",libdir, pathToCache.c_str()); - if (boost::filesystem::exists(pathToCache)) { + if (std::filesystem::exists(pathToCache)) { return false; } else { result = ROSE_AUTOMAKE_PREFIX; @@ -3619,7 +3619,7 @@ SgSourceFile::build_Fortran_AST( vector argv, vector inputComman FileSystem::Path abs_path = FileSystem::makeAbsolute(this->get_unparse_output_filename()); FileSystem::Path abs_dir = abs_path.parent_path(); FileSystem::Path base = abs_dir.filename().stem(); - string preprocessFilename = (abs_dir / boost::filesystem::unique_path(base.string() + "-%%%%%%%%.F90")).string(); + string preprocessFilename = (abs_dir / std::filesystem::unique_path(base.string() + "-%%%%%%%%.F90")).string(); // The Sawyer::FileSystem::TemporaryFile d'tor will delete the file. We close the file after it's created because // Rose::FileSystem::copyFile will reopen it in binary mode anyway. @@ -4947,8 +4947,8 @@ SgFile::compileOutput ( vector& argv, int fileNameIndex ) } else { - boost::filesystem::path original_file = outputFilename; - boost::filesystem::path unparsed_file = get_unparse_output_filename(); + std::filesystem::path original_file = outputFilename; + std::filesystem::path unparsed_file = get_unparse_output_filename(); if (SgProject::get_verbose() >= 2) { @@ -4958,7 +4958,7 @@ SgFile::compileOutput ( vector& argv, int fileNameIndex ) << "'" << unparsed_file << "' " << "exists = " << std::boolalpha - << boost::filesystem::exists(unparsed_file) + << std::filesystem::exists(unparsed_file) << std::endl; } // Don't replace the original input file with itself @@ -4977,9 +4977,9 @@ SgFile::compileOutput ( vector& argv, int fileNameIndex ) // copy_file will only completely override the existing file in Boost 1.46+ // http://stackoverflow.com/questions/14628836/boost-copy-file-has-inconsistent-behavior-when-overwrite-if-exists-is-used - if (boost::filesystem::exists(unparsed_file)) + if (std::filesystem::exists(unparsed_file)) { - boost::filesystem::remove(unparsed_file); + std::filesystem::remove(unparsed_file); } #if 0 printf ("NOTE: keep_going option supporting direct copy of original input file to overwrite the unparsed file \n"); diff --git a/src/frontend/SageIII/sage_support/sage_support.h b/src/frontend/SageIII/sage_support/sage_support.h index a7bdf58c4b8..263c3cf3140 100644 --- a/src/frontend/SageIII/sage_support/sage_support.h +++ b/src/frontend/SageIII/sage_support/sage_support.h @@ -53,8 +53,8 @@ #include #endif -// Needed for boost::filesystem::exists(...) -#include "boost/filesystem.hpp" +// Needed for std::filesystem::exists(...) +#include #include // Liao 10/8/2010, refactored OpenMP related code to ompAstConstruction.C diff --git a/src/midend/programTransformation/astOutlining/Outliner.cc b/src/midend/programTransformation/astOutlining/Outliner.cc index 99cd18896ee..654406c70c4 100644 --- a/src/midend/programTransformation/astOutlining/Outliner.cc +++ b/src/midend/programTransformation/astOutlining/Outliner.cc @@ -7,7 +7,7 @@ #include #include #include - +#include #include "NameGenerator.hh" @@ -15,8 +15,8 @@ #include "Preprocess.hh" //#include "Transform.hh" #include "commandline_processing.h" -#include "boost/filesystem.hpp" -namespace bfs=boost::filesystem; + +namespace bfs=std::filesystem; // ===================================================================== using namespace std; diff --git a/src/rose-config.C b/src/rose-config.C index 04eaa6a2fda..bc04497d1df 100644 --- a/src/rose-config.C +++ b/src/rose-config.C @@ -49,7 +49,7 @@ typedef std::map Configuration; struct Settings { std::string searchDirs; - boost::filesystem::path configFile; + std::filesystem::path configFile; // When compiling this program, LIBDIR C preprocessor symbol should be the name of the installation path for libraries. Settings() @@ -97,7 +97,7 @@ std::string toOldKeyFormat(std::string& key) // Read a specific configuration file static Configuration -readConfigFile(const boost::filesystem::path &configName) { +readConfigFile(const std::filesystem::path &configName) { struct Resources { FILE *file; char *line; @@ -186,8 +186,8 @@ readConfigFile(const Settings &settings) { std::vector dirs; boost::split(dirs, settings.searchDirs, boost::is_any_of(":;")); BOOST_FOREACH (const std::string &dir, dirs) { - boost::filesystem::path configFile = boost::filesystem::path(dir) / CONFIG_NAME; - if (boost::filesystem::exists(configFile)) + std::filesystem::path configFile = std::filesystem::path(dir) / CONFIG_NAME; + if (std::filesystem::exists(configFile)) return readConfigFile(configFile); } @@ -276,7 +276,7 @@ main(int argc, char *argv[]) { } else if (argc == 4) { //--config std::string configflag ("--config"); if (configflag.compare(argv[1]) == 0) { - settings.configFile = boost::filesystem::path(argv[2]); + settings.configFile = std::filesystem::path(argv[2]); key = std::string(argv[3]); } else { MLOG_FATAL_C("rose-config", "incorrect usage; see --help\n"); diff --git a/src/util/FileSystem.C b/src/util/FileSystem.C index 7b166f38dde..bde3946a96a 100644 --- a/src/util/FileSystem.C +++ b/src/util/FileSystem.C @@ -1,6 +1,11 @@ #include #include #include +#include +#include +#include +#include +#include namespace Rose { namespace FileSystem { @@ -9,45 +14,62 @@ const char *tempNamePattern = "rose-%%%%%%%-%%%%%%%"; bool baseNameMatches::operator()(const Path &path) { - return boost::regex_match(path.filename().string(), re_); + return std::regex_match(path.filename().string(), re_); } bool isExisting(const Path &path) { - return boost::filesystem::exists(path); + return std::filesystem::exists(path); } bool isFile(const Path &path) { - return boost::filesystem::is_regular_file(path); + return std::filesystem::is_regular_file(path); } bool isDirectory(const Path &path) { - return boost::filesystem::is_directory(path); + return std::filesystem::is_directory(path); } bool isSymbolicLink(const Path &path) { - return boost::filesystem::is_symlink(path); + return std::filesystem::is_symlink(path); } bool isNotSymbolicLink(const Path &path) { - return !boost::filesystem::is_symlink(path); + return !std::filesystem::is_symlink(path); } Path createTemporaryDirectory() { - Path dirName = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(tempNamePattern); - boost::filesystem::create_directory(dirName); + // Generate a unique name based on timestamp and random number + auto now = std::chrono::system_clock::now(); + std::time_t now_c = std::chrono::system_clock::to_time_t(now); + + // Convert time to a string + std::string timeStr = std::to_string(now_c); + + // Generate a random number + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, 10000); + std::string randomStr = std::to_string(dis(gen)); + + // Combine time and random number into the directory name + std::string dirNameStr = "temp_" + timeStr + "_" + randomStr; + + std::filesystem::path dirName = std::filesystem::temp_directory_path() / dirNameStr; + std::filesystem::create_directory(dirName); + return dirName; } Path makeNormal(const Path &path) { std::vector components; - for (boost::filesystem::path::const_iterator i=path.begin(); i!=path.end(); ++i) { + for (std::filesystem::path::const_iterator i=path.begin(); i!=path.end(); ++i) { if (0 == i->string().compare("..") && !components.empty()) { components.pop_back(); } else if (0 != i->string().compare(".")) { @@ -70,8 +92,8 @@ makeRelative(const Path &path_, const Path &root_) { Path path = makeAbsolute(path_); Path root = makeAbsolute(root_); - boost::filesystem::path::const_iterator rootIter = root.begin(); - boost::filesystem::path::const_iterator pathIter = path.begin(); + std::filesystem::path::const_iterator rootIter = root.begin(); + std::filesystem::path::const_iterator pathIter = path.begin(); // Skip past common prefix while (rootIter!=root.end() && pathIter!=path.end() && *rootIter==*pathIter) { @@ -115,7 +137,7 @@ findNamesRecursively(const Path &root) { void copyFile(const Path &src, const Path &dst) { - // Do not use boost::filesystem::copy_file in boost 1.56 and earlier because it is not possible to cross link c++11 rose + // Do not use std::filesystem::copy_file in boost 1.56 and earlier because it is not possible to cross link c++11 rose // with c++89 boost when using this symbol. Boost issue #6124 fixed in boost 1.57 and later. Our solution is to use C++ // stream I/O instead, which should still work on non-POSIX systems (Microsoft) although the exception situations might not // be exactly precise as POSIX. Use path::string rather than path::native in order to support Filesystem version 2. @@ -123,12 +145,12 @@ copyFile(const Path &src, const Path &dst) { std::ofstream out(dst.string().c_str(), std::ios::binary); out < &fileNames, const Path &root, const Path &dstD for (const Path &fileName: fileNames) { Path dirName = dstDir / makeRelative(fileName.parent_path(), root); if (dirs.insert(dirName).second) - boost::filesystem::create_directories(dirName); + std::filesystem::create_directories(dirName); Path outputName = dirName / fileName.filename(); copyFile(fileName, outputName); } @@ -147,7 +169,7 @@ copyFiles(const std::vector &fileNames, const Path &root, const Path &dstD std::vector findRoseFilesRecursively(const Path &root) { - return findNamesRecursively(root, baseNameMatches(boost::regex("rose_.*")), isDirectory); + return findNamesRecursively(root, baseNameMatches(std::regex("rose_.*")), isDirectory); } // Don't use this if you can help it! diff --git a/src/util/FileSystem.h b/src/util/FileSystem.h index 1c22d499b24..45226678990 100644 --- a/src/util/FileSystem.h +++ b/src/util/FileSystem.h @@ -1,9 +1,8 @@ #ifndef ROSE_FileSystem_H #define ROSE_FileSystem_H -#include -#include -#include +#include +#include #include #include #include @@ -20,13 +19,13 @@ namespace FileSystem { extern const char *tempNamePattern; /** Name of entities in a filesystem. */ -typedef boost::filesystem::path Path; +typedef std::filesystem::path Path; /** Iterate over directory contents non-recursively. */ -typedef boost::filesystem::directory_iterator DirectoryIterator; +typedef std::filesystem::directory_iterator DirectoryIterator; /** Iterate recursively into subdirectories. */ -typedef boost::filesystem::recursive_directory_iterator RecursiveDirectoryIterator; +typedef std::filesystem::recursive_directory_iterator RecursiveDirectoryIterator; /** Predicate returning true if path exists. */ ROSE_UTIL_API bool isExisting(const Path &path); @@ -56,9 +55,9 @@ ROSE_UTIL_API bool isNotSymbolicLink(const Path &path); * std::vector roseFiles = findAllNames(top, baseNameMatches(boost::regex("rose_.*"))); * @endcode */ class ROSE_UTIL_API baseNameMatches { - const boost::regex &re_; + const std::regex &re_; public: - baseNameMatches(const boost::regex &re): re_(re) {} + baseNameMatches(const std::regex &re): re_(re) {} bool operator()(const Path &path); }; @@ -66,7 +65,7 @@ class ROSE_UTIL_API baseNameMatches { * * The temporary directory is created as a subdirectory of the directory which is suitable for temporary files under the * conventions of the operating system. The specifics of how this path is determined are implementation defined (see - * boost::filesystem::temp_directory_path). The created subdirectory has a name of the form + * std::filesystem::temp_directory_path). The created subdirectory has a name of the form * "rose-%%%%%%%%-%%%%%%%%" where each "%" is a random hexadecimal digit. Returns the path to this directory. */ ROSE_UTIL_API Path createTemporaryDirectory(); @@ -83,13 +82,13 @@ ROSE_UTIL_API Path makeNormal(const Path&); /** Make path relative. * * Makes the specified path relative to another path or the current working directory. */ -ROSE_UTIL_API Path makeRelative(const Path &path, const Path &root = boost::filesystem::current_path()); +ROSE_UTIL_API Path makeRelative(const Path &path, const Path &root = std::filesystem::current_path()); /** Make path absolute. * * Makes the specified path an absolute path if it is a relative path. If relative, then assume @p root is what the path is * relative to. */ -ROSE_UTIL_API Path makeAbsolute(const Path &path, const Path &root = boost::filesystem::current_path()); +ROSE_UTIL_API Path makeAbsolute(const Path &path, const Path &root = std::filesystem::current_path()); /** Entries within a directory. * @@ -138,7 +137,7 @@ std::vector findNamesRecursively(const Path &root, Select select, Descend if (select(dentry->path())) matching.push_back(dentry->path()); if (!descend(dentry->path())) - dentry.no_push(); + dentry.disable_recursion_pending(); } std::sort(matching.begin(), matching.end()); return matching; @@ -166,7 +165,7 @@ ROSE_UTIL_API void copyFile(const Path &sourceFileName, const Path &destinationF * For instance, copyFiles(["bar/baz"], "foo", "frob") will copy "bar/baz" to "frob/../bar/baz" since "bar" is apparently * a sibling of "foo", and therefore must be a sibling of "frob". * - * Throws a boost::filesystem::filesystem_error on failure. */ + * Throws a std::filesystem::filesystem_error on failure. */ ROSE_UTIL_API void copyFiles(const std::vector &files, const Path &root, const Path &destinationDirectory); /** Recursively copy files. @@ -191,30 +190,30 @@ ROSE_UTIL_API std::string toString(const Path&); /** Load an entire file into an STL container. */ template -Container readFile(const boost::filesystem::path &fileName, +Container readFile(const std::filesystem::path &fileName, std::ios_base::openmode openMode = std::ios_base::in | std::ios_base::binary) { using streamIterator = std::istreambuf_iterator; std::ifstream stream(fileName.c_str(), openMode); if (!stream.good()) - MLOG_ERROR_CXX("UTIL") << "unable to open file " << boost::lexical_cast(fileName); + MLOG_ERROR_CXX("UTIL") << "unable to open file " << fileName.string(); Container container; std::copy(streamIterator(stream), streamIterator(), std::back_inserter(container)); if (stream.fail()) - MLOG_ERROR_CXX("UTIL") << "unable to read from file " << boost::lexical_cast(fileName); + MLOG_ERROR_CXX("UTIL") << "unable to read from file " << fileName.string(); return container; } template -void writeFile(const boost::filesystem::path &fileName, const Container &data, +void writeFile(const std::filesystem::path &fileName, const Container &data, std::ios_base::openmode openMode = std::ios_base::out | std::ios_base::binary) { std::ofstream stream(fileName.c_str(),openMode); if (!stream.good()) - MLOG_ERROR_CXX("UTIL") << "unable to open file " << boost::lexical_cast(fileName); + MLOG_ERROR_CXX("UTIL") << "unable to open file " << fileName.string(); std::ostream_iterator streamIterator(stream); std::copy(data.begin(), data.end(), streamIterator); stream.close(); if (stream.fail()) - MLOG_ERROR_CXX("UTIL") << "unable to write to file " << boost::lexical_cast(fileName); + MLOG_ERROR_CXX("UTIL") << "unable to write to file " << fileName.string(); } } // namespace diff --git a/src/util/StringUtility/FileNameClassifier.C b/src/util/StringUtility/FileNameClassifier.C index 71838a7f73a..4841b820f39 100644 --- a/src/util/StringUtility/FileNameClassifier.C +++ b/src/util/StringUtility/FileNameClassifier.C @@ -22,6 +22,7 @@ #include #include +#include #include "FileUtility.h" #include #include "mlog.h" @@ -34,9 +35,6 @@ #include -// CH (1/29/2010): Needed for boost::filesystem::exists(...) -#include - #include #if BOOST_VERSION >= 103600 # define BOOST_HAS_BRANCH_PATH has_parent_path @@ -325,7 +323,7 @@ using namespace Rose; classifyLibrary(const string& fileName) { #ifndef CXX_IS_ROSE_CODE_GENERATION - using namespace boost::filesystem; + using namespace std::filesystem; if (charListMatches(LINUX_INCLUDES, "include/", fileName)) { @@ -363,9 +361,9 @@ using namespace Rose; } path p = fileName; - while (p.BOOST_HAS_BRANCH_PATH()) + while (!p.empty()) { - p = p.branch_path(); + p = p.parent_path(); if(exists(p / path("rose.h"))) return Rose::StringUtility::FILENAME_LIBRARY_ROSE; @@ -514,7 +512,7 @@ Rose::StringUtility::homeDir(string& dir) { // First, check if this file exists. Filename may be changed // into an illegal one by #line directive - if(!boost::filesystem::exists(fileName)) + if(!std::filesystem::exists(fileName)) return FileNameClassification(FILENAME_LOCATION_NOT_EXIST, "Unknown", 0); diff --git a/src/util/StringUtility/FileUtility.h b/src/util/StringUtility/FileUtility.h index f1be313bb56..babf0dcaef5 100644 --- a/src/util/StringUtility/FileUtility.h +++ b/src/util/StringUtility/FileUtility.h @@ -14,8 +14,8 @@ namespace StringUtility { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // This part of the StringUtility API deals with file names and should be moved to some other name space. In particular, it // provides no definitions for "path", "filename", "extension", etc. and many of these functions won't work properly on a -// non-POSIX system. Therefore, consider using Rose::FileSystem, which is mostly a thin wrapper around boost::filesystem. The -// boost::filesystem documentation has good definitions for what the various terms should mean and works on non-POSIX file +// non-POSIX system. Therefore, consider using Rose::FileSystem, which is mostly a thin wrapper around std::filesystem. The +// std::filesystem documentation has good definitions for what the various terms should mean and works on non-POSIX file // systems. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -90,7 +90,7 @@ ROSE_UTIL_API void homeDir(std::string& dir); * * Removes the "path" part of a "filename" (if there is one) and returns just the file name. * - * Terms are loosely defined and not likely to work for non-POSIX systems; consider using boost::filesystem instead. */ + * Terms are loosely defined and not likely to work for non-POSIX systems; consider using std::filesystem instead. */ ROSE_UTIL_API std::string stripPathFromFileName(const std::string &fileNameWithPath); /** Returns all but the last component of a path in a filesystem. @@ -99,18 +99,18 @@ ROSE_UTIL_API std::string stripPathFromFileName(const std::string &fileNameWithP * Make it safe to input a filename without a path name (return the filename). * * Terms are loosely defined and this function possibly doesn't work for non-POSIX file systems; consider using - * boost::filesystem instead. */ + * std::filesystem instead. */ ROSE_UTIL_API std::string getPathFromFileName(const std::string &fileNameWithPath); /** Get the file name without the ".suffix". * * Terms are loosely defined and it's not clear what happens for inputs like ".", ".foo", "..", ".foo.bar", "/.", - * etc. Consider using boost::filesystem instead. */ + * etc. Consider using std::filesystem instead. */ ROSE_UTIL_API std::string stripFileSuffixFromFileName(const std::string & fileNameWithSuffix); /** Get the absolute path from the relative path. * - * Terms are loosely defined and this function is not likely to work on non-POSIX systems. Consider using boost::filesystem + * Terms are loosely defined and this function is not likely to work on non-POSIX systems. Consider using std::filesystem * instead. */ ROSE_UTIL_API std::string getAbsolutePathFromRelativePath(const std::string &relativePath, bool printErrorIfAny = false); @@ -120,7 +120,7 @@ ROSE_UTIL_API std::string getAbsolutePathFromRelativePath(const std::string &rel * returns the original fileName. * * Terms are loosely defined and this function is not likely to work correctly in some situations, such as when the "." is not - * in the last component of the file name. Consider using boost::filesystem instead. */ + * in the last component of the file name. Consider using std::filesystem instead. */ ROSE_UTIL_API std::string fileNameSuffix(const std::string &fileName); @@ -136,7 +136,7 @@ ROSE_UTIL_API std::string fileNameSuffix(const std::string &fileName); * substring of their name. Note that @p patternString is not a glob or regular expression. The return value strings are * formed by concatenating the @p pathString and the file name with an intervening slash. * - * This function does not work for non-POSIX systems. Consider using boost::filesystem instead, which has a directory iterator + * This function does not work for non-POSIX systems. Consider using std::filesystem instead, which has a directory iterator * that works for non-POSIX systems also. */ //ROSE_UTIL_API std::list findfile(std::string patternString, std::string pathString) //SAWYER_DEPRECATED("use Rose::FileSystem functions instead"); // ROSE_DEPRECATED is not defined here diff --git a/src/util/support/FileHelper.h b/src/util/support/FileHelper.h index 47ef84d2d50..81c505d3527 100644 --- a/src/util/support/FileHelper.h +++ b/src/util/support/FileHelper.h @@ -1,24 +1,24 @@ // Consider using $ROSE/src/util/FileSystem.h since that one is documented and uses a proper path type and supports both -// version 2 and version 3 of boost::filesystem. +// version 2 and version 3 of std::filesystem. // UNDER NO CIRCUMSTANCES SHOULD BOOST_FILESYSTEM_VERSION BE SET!!! // -// The boost::filesystem version is not dependent on which compiler we're using, but rather which version +// The std::filesystem version is not dependent on which compiler we're using, but rather which version // of boost is installed. Hard-coding a boost version number based on the compiler version has a couple of problems: // 1. We don't know whether that filesystem version is available on a user's machine since ROSE supports multiple // versions of boost (e.g., filesystem 3 is not available before boost 1.44) // 2. It pollutes things for the user, who might not want the version we select here (e.g., most users of recent // versions of boost will almost certainly want version 3, not the version 2 we select). // Therefore, we should never select a filesystem version explicitly here, but rather be prepared to handle any version -// that is installed. If ROSE cannot support a particular version of boost::filesystem on a particular architecture with a +// that is installed. If ROSE cannot support a particular version of std::filesystem on a particular architecture with a // particular file then that should be documented where we state which versions of boost are supported, and possibly // checked during configuration. [Matzke 11/17/2014]: #include -#include #include #include +#include class FileHelper { public: @@ -31,12 +31,12 @@ class FileHelper { } static void ensureFolderExists(const std::string& folder){ - boost::filesystem::path boostPath(folder); + std::filesystem::path boostPath(folder); create_directories(boostPath); } static void eraseFolder(const std::string& folder) { - boost::filesystem::path boostPath(folder); + std::filesystem::path boostPath(folder); remove_all(boostPath); } @@ -51,12 +51,12 @@ class FileHelper { } static std::string getParentFolder(const std::string& aPath) { - boost::filesystem::path boostPath(aPath); + std::filesystem::path boostPath(aPath); return boostPath.parent_path().string(); } static std::string getFileName(const std::string& aPath) { - return Rose::FileSystem::toString(boost::filesystem::path(aPath).filename()); + return Rose::FileSystem::toString(std::filesystem::path(aPath).filename()); } static std::string makeAbsoluteNormalizedPath(const std::string& path, const std::string& workingDirectory) { @@ -74,7 +74,7 @@ class FileHelper { //Expects both paths to be absolute. static bool areEquivalentPaths(const std::string& path1, const std::string& path2) { - //Note: Do not use boost::filesystem::equivalent since the compared paths might not exist, which will cause an error. + //Note: Do not use std::filesystem::equivalent since the compared paths might not exist, which will cause an error. return normalizePath(path1).compare(normalizePath(path2)) == 0; } @@ -96,16 +96,16 @@ class FileHelper { } static bool fileExists(const std::string& fullFileName) { - return boost::filesystem::exists(fullFileName); + return std::filesystem::exists(fullFileName); } static bool isNotEmptyFolder(const std::string& fullFolderName) { - return boost::filesystem::exists(fullFolderName) && !boost::filesystem::is_empty(fullFolderName); + return std::filesystem::exists(fullFolderName) && !std::filesystem::is_empty(fullFolderName); } static std::string normalizePath(const std::string& aPath) { - boost::filesystem::path boostPath(aPath); - std::string normalizedPath = boostPath.normalize().string(); + std::filesystem::path boostPath(aPath); + std::string normalizedPath = std::filesystem::canonical(boostPath).string(); return normalizedPath; } From 403c8d273c150f45256e64480035a016c3ca09bd Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 20:05:21 -0400 Subject: [PATCH 03/42] Removed Boost Wave/Filesystem dependencies (dependency removal; not all code) --- CMakeLists.txt | 4 +- .../SageIII/attachPreprocessingInfo.C | 531 ------------------ .../SageIII/attachPreprocessingInfo.h | 2 - 3 files changed, 2 insertions(+), 535 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 136eb806802..e2ed0072c20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system wave thread + COMPONENTS chrono date_time iostreams program_options random regex system thread REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system wave thread serialization) + COMPONENTS chrono date_time iostreams program_options random regex system thread serialization) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries diff --git a/src/frontend/SageIII/attachPreprocessingInfo.C b/src/frontend/SageIII/attachPreprocessingInfo.C index 53b09763794..e8b23a21d61 100644 --- a/src/frontend/SageIII/attachPreprocessingInfo.C +++ b/src/frontend/SageIII/attachPreprocessingInfo.C @@ -108,540 +108,9 @@ attachPreprocessingInfo(SgSourceFile *sageFilePtr, std::map AttributeMapType; -void -attachPreprocessingInfoUsingWave (SgSourceFile *sageFilePtr, AttributeMapType& attributeMapForAllFiles) - { -#ifndef CXX_IS_ROSE_CODE_GENERATION - -// CH (4/7/2010): Wave issue fixed. -//#ifndef _MSCx_VER -//#pragma message ("WARNING: Wave support not ported to Windows MSVC.") -// printf ("ERROR: Wave support not ported to Windows MSVC. \n"); -// ROSE_ASSERT(false); -//#else - ROSE_ASSERT(sageFilePtr != NULL); - std::string sourceFileName = sageFilePtr->getFileName(); - - //SageInterface::buildFile(..) generates files in memory where the source file has not yet - //been written to disk. We consider any case where the file does not exist on disk to be this - //case. - if( ! std::filesystem::exists(sourceFileName) ) - return; - - // DQ (11/30/2008): - // 1) Where are the tokens generated by Wave? - // 2) Where are the PreprocessorInfo objects generated? - // 3) Why is the commandline processed (redundantly with information already in SgSourceFile)? - - std::cerr << "Using WAVE" << std::endl; - - // DQ (7/6/2005): Introduce tracking of performance of ROSE. - TimingPerformance timer ("AST Comment and CPP Directive Processing (using Wave, outer part):"); - - // Build the AST used by ROSE - // SgProject* project = frontend(argc,argv); - std::vector includeSpecifierlist; - - // Build the list that we will hand off to boost-wave - // std::vector includeSpecifierlist; - std::vector macroList; - std::vector preincludeList; - -#if 0 -// .mine - string predefinedMacros = CXX_SPEC_DEF; - - if (SgProject::get_verbose() >= 1) - std::cout << "XXXXXXXXXXXX: " << CXX_SPEC_DEF << std::endl; - - // DQ (11/30/2008): This information is already available in the SgSourceFile - // or SgProject IR nodes so it is not required to reparse the commandline here. - - vector predefinedMacroList = CommandlineProcessing::generateArgListFromString(predefinedMacros); -#else - // DQ (12/22/2008): I expect that this is the better version... - const char* predefinedMacroListRaw[] = CXX_SPEC_DEF; - vector predefinedMacroList(predefinedMacroListRaw, predefinedMacroListRaw + sizeof(predefinedMacroListRaw) / sizeof(*predefinedMacroListRaw)); -#endif - // for (vector::iterator i = predefinedMacroList.begin(); i != predefinedMacroList.end(); i++) - vector::iterator i = predefinedMacroList.begin(); - while (i != predefinedMacroList.end()) - { - // AS(03/12/08) CXX_SPEC_DEF has been changed to only contain macro defs - if (i->substr(0,2) == "-D") - { - string macro = i->substr(2); - - if (SgProject::get_verbose() >= 1) - printf ("Adding predefined macro to the macroList macro = %s \n",macro.c_str()); - - macroList.push_back(macro); - } - else - { - string preincludeMarker = "--preinclude"; - if (i->substr(0,preincludeMarker.size()) == preincludeMarker) - { - i++; - // The following option is the file name associated with the "--preinclude" option - preincludeList.push_back(*i); - - if(SgProject::get_verbose() >= 1) - std::cout << "Predefined macro: " << *i << std::endl; - } - else - { - if(i->empty()) - { - } - else - { - printf ("Found a non -D macro definition (and non preinclude file) in the predefined macro list substring = %s *i = %s \n",i->substr(0,2).c_str(),i->c_str()); - } - } - } - - i++; - } - - - // Now add the entries specified on the commandline - if (SgProject::get_verbose() >= 1) - std::cout << "INCLUDES FROM COMMANDLINE" << std::endl; - - std::vector commandLine = sageFilePtr->get_originalCommandLineArgumentList(); - for (vector::iterator i = commandLine.begin(); i != commandLine.end(); i++) - { - ROSE_ASSERT((*i)[0] != ' '); - // printf ("Command line argument: *i = %s \n",i->c_str()); - if (i->substr(0,2) == "-I") - { - includeSpecifierlist.push_back(*i); - if(SgProject::get_verbose() >= 1) - std::cout << *i << std::endl; - } - if (i->substr(0,2) == "-D") - { - string macro = i->substr(2); - - if(SgProject::get_verbose() >= 1) - printf ("Adding macro to the macroList macro = %s \n",macro.c_str()); - macroList.push_back(macro); - } - } - - if(SgProject::get_verbose() >= 1) - std::cout << "DONE INCLUDES FROM COMMANDLINE" << std::endl; - - std::vector accessFunctionsList; - - // DQ (11/30/2008): Why are we getting all the SgFloatValExp and SgDoubleValExp IR nodes? - - // Build list of value expressions - std::vector valueExp = NodeQuery::querySubTree (sageFilePtr,&queryFloatDoubleValExp); - - // Open and read in the specified input file. - - if (SgProject::get_verbose() >= 1) - { - std::cout << "Source file name: \"" << sourceFileName << "\"" << std::endl; - std::cout << "Source file name: \"" << sageFilePtr->getFileName()<< "\"" << std::endl; - } - - // Here we open the input file for processing using WAVE. - // sourceFileName = string(CurrentPath)+"/"+sourceFileName; - std::ifstream instream(sourceFileName.c_str()); - std::string instring; - - if (!instream.is_open()) - { - std::cerr << "Could not open input file: " << sourceFileName << std::endl; - ROSE_ABORT(); - } - - // DQ (11/30/2008): What does this do? Please document why this is required. - instream.unsetf(std::ios::skipws); - instring = std::string(std::istreambuf_iterator(instream.rdbuf()),std::istreambuf_iterator()); - - // DQ (11/30/2008): Is there no namespace for the Wave types? - // Also which of these three statements builds the token list? - - // The template boost::wave::cpplexer::lex_token<> is the token type to be used by the Wave library. - ::token_type x; - - // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to - // be used by the Wave library. - typedef boost::wave::cpplexer::lex_iterator< ::token_type> lex_iterator_type; - - // This is the resulting context type to use. The first template parameter - // should match the iterator type to be used during construction of the - // corresponding context object (see below). - typedef boost::wave::context context_type; - - // The preprocessor iterator shouldn't be constructed directly. It is - // to be generated through a wave::context<> object. This wave:context<> - // object is to be used additionally to initialize and define different - // parameters of the actual preprocessing (not done here). - // - // The preprocessing of the input stream is done on the fly behind the - // scenes during iteration over the context_type::iterator_type stream. - - ROSE_ASSERT(sourceFileName.size() > 0); - - //Files, like for instance those generated by SageInterface::buildFile(..), - //can be empty. In those cases ship wave - if(instring.begin() == instring.end()) - return; - - - // DQ (11/30/2008): What does this do? - context_type ctx (instring.begin(), instring.end(), sourceFileName.c_str()); - - // std::cout << "Current file name: " << get_current_filename() - - // DQ (11/30/2008): Andreas just mentioned that the AttributeListMap is not required and could be eliminated. - - // This get_hooks() member function was added by the Author of boost-wave to handle - // a problem pointed out by Andreas. - AttributeListMap attributeListMap(sageFilePtr); - ctx.get_hooks().attributeListMap = &attributeListMap; - - // printf ("specify the languge \n"); - - // Preserve comments through preprocessing so that the output token-stream - // contains the comments. - if (SgProject::get_verbose() >= 1) - std::cout << "BEFORE ADDING PREDEFINES" << std::endl; - - if( sageFilePtr->get_C_only() == true){ - // Tentaive support for C. For now treat it like C99 since Wave does not - // have an option for just C. - ctx.set_language(boost::wave::support_c99); - }else if( sageFilePtr->get_C99_only() == true ){ - ctx.set_language(boost::wave::support_c99); - }else{ - ctx.set_language(boost::wave::support_cpp); - } - - ctx.set_language(boost::wave::enable_long_long(ctx.get_language())); -// ctx.set_language(boost::wave::enable_preserve_comments(ctx.get_language())); - ctx.set_language(boost::wave::enable_variadics(ctx.get_language())); - // Force a specific file to be included before all others - - -#if ((ROSE_BOOST_VERSION == 105300) && (__cplusplus == 201103L)) - printf ("ERROR: WAVE support not available using BOOST version 1.53 in C++11 mode (fails to compile in C++11 mode) \n"); - ROSE_ABORT(); -#else - // DQ (2/13/2016): The function ctx.add_macro_definition() does not compile with Boost 1.53 - // in C++11 mode. So this combination is detected and disabled locally where it is a problem. - // Note that wave is off by default at runtime, though it appears to always be compiled - // (so it is not a configuration option, I gather). Maybe it should be a configuration option? - - if( sageFilePtr->get_C_only() == true){ - // Tentaive support for C. For now treat it like C99 since Wave does not - // have an option for just C. - ctx.add_macro_definition(std::string("ROSE_LANGUAGE_MODE=0"),true); - }else if( sageFilePtr->get_C99_only() == true ){ - ctx.add_macro_definition(std::string("ROSE_LANGUAGE_MODE=0"),true); - }else{ - ctx.add_macro_definition(std::string("ROSE_LANGUAGE_MODE=1"),true); - } - - if (SgProject::get_verbose() >= 1) - std::cout << "MIDDLE OF ADDING PREDEFINES" << std::endl; - - for (std::vector::iterator it_beg = macroList.begin(); it_beg != macroList.end(); ++it_beg) - { - if (SgProject::get_verbose() >= 1) - std::cout << "Predef macro:\"" << *it_beg << "\""<= 1) - std::cout << "AFTER ADDING PREDEFINES" << std::endl; - - // Add include paths specified on commandline to the context object - std::vector::const_iterator firstInclude = includeSpecifierlist.begin(); - std::vector::const_iterator lastInclude = includeSpecifierlist.end(); - - if (SgProject::get_verbose() >= 1) - printf ("Adding the /usr/include/ file \n"); - - // DQ (4/7/2006): Not sure we want to do this, if we did want to do so then it should - // be in the list of EDG as well and in which case, what order should it be placed? - - string internalIncludePaths[] = CXX_INCLUDE_STRING; - // if(SgProject::get_verbose() >= 1) - // std::cout << "INTERNAL INCLUDE PATHS " << CXX_INCLUDE_STRING << std::endl; - - vector internalIncludePathList(internalIncludePaths, internalIncludePaths + sizeof(internalIncludePaths)/sizeof(string)); - // internalIncludePathList.push_back("-I"+string(CurrentPath)+"/"); - - string includeBase = findRoseSupportPathFromBuild("include-staging", "include"); - for (vector::iterator i = internalIncludePathList.begin(); i != internalIncludePathList.end(); i++) - { - ROSE_ASSERT (!i->empty()); - string fullPath = (*i)[0] == '/' ? *i : (includeBase + "/" + *i); - - ctx.add_sysinclude_path(fullPath.c_str()); - } - - std::string sys_include = "/usr/include/"; - ctx.add_sysinclude_path(sys_include.c_str()); - - if (SgProject::get_verbose() >= 1) - printf ("DONE: Adding the /usr/include/ file \n"); - - while(firstInclude != lastInclude) - { - string includeDir=(*firstInclude).substr(2,(*firstInclude).length()); - ctx.add_sysinclude_path((*firstInclude).substr(2,(*firstInclude).length()).c_str()); - ctx.add_include_path((*firstInclude).c_str()); - ++firstInclude; - } - - // DQ (11/30/2008): What bug does this refer to in ROSE? - // variable needed by the program to account for the bug in the column - // position of value expressions within ROSE. - context_type::token_type lastOperatorToken(boost::wave::T_RIGHTPAREN,")",boost::wave::util::file_position_type("",0,0)); - - // Attaching an attribute list to the current hooks object so that - // preprocessing infos can be extracted - map currentMapOfAttributes; - - // std::string x,y; - // current file position is saved for exception handling - boost::wave::util::file_position_type current_position; - - // DQ (11/30/2008): Andreas says this AST Query is part of the alternative approach to extract - // the strings used for floating point values (this work later was implemented in EDG directly). - // So this feature of the Wave preprocessing is not used currently, but it appears to be - // exectuted (it should be commented out). - accessFunctionsList = NodeQuery::querySubTree (sageFilePtr,&queryFloatDoubleValExp); - - std::cerr << "For some reason we have " << std::endl; - - // Locate all value expression with Wave and set the string value of the - // corresponding value expressions within the ROSE AST to the string value found - // by Wave. - context_type::iterator_type first = ctx.begin(); - context_type::iterator_type last = ctx.end(); - - // analyze the input file, print out the preprocessed hooks - if (SgProject::get_verbose() >= 1) - printf ("Adding the preinclude file \n"); - - ROSE_ASSERT(preincludeList.size() == 1); - for (vector::reverse_iterator i = preincludeList.rbegin(); i != preincludeList.rend(); ++i) - { - vector::reverse_iterator copyOf_i = i; - copyOf_i++; - - if (SgProject::get_verbose() >= 1) - printf ("Adding preinclude file = %s \n",i->c_str()); - -// DQ (8/29/2009): It appears that this test fails to compile using ROSE (some template name contains "____L" as a substring). -#ifndef USE_ROSE - // DQ (4/7/2006): This currently fails - first.force_include( i->c_str(), copyOf_i == preincludeList.rend() ); - // first.force_include( i->c_str(), false); -#endif - - if (SgProject::get_verbose() >= 1) - printf ("DONE: Adding preinclude file = %s \n",i->c_str()); - } - - if (SgProject::get_verbose() >= 1) - printf ("DONE: Adding the preinclude file \n"); - - // Start Lexing - try{ -// DQ (8/29/2009): It appears that this test fails to compile using ROSE (some template name contains "____L" as a substring). -#ifndef USE_ROSE - while (first != last) -#else - while (true) -#endif - { - using namespace boost::wave; - - try{ -// DQ (8/29/2009): It appears that this test fails to compile using ROSE (some template name contains "____L" as a substring). -// Each reference to "first" appears to generate an error. It appears that this test fails to compile using ROSE. -#ifndef USE_ROSE - current_position = (*first).get_position(); - - if (first->get_position().get_file()!="") - { - // std::cout << first->get_position().get_file() << " l" << first->get_position().get_line() - // << " " << (*first).get_value() << std::endl; - } - - token_id id = token_id(*first); - - // Attach comments found by Wave to the AST - if ((T_CCOMMENT == id) | (T_CPPCOMMENT == id)) - { - attributeListMap.found_directive(*first); - } - - wave_tokenStream.push_back(*first); - first++; -#endif - } - - catch (boost::wave::cpp_exception &e) - { - // some preprocessing error - // This is a problem for using compass with emacs (see testEmacs.C). - // cerr << "WAVE 1: " << e.file_name() << "(" << e.line_no() << "): " - // << e.description() << endl; - } - - catch (boost::wave::cpplexer::lexing_exception &e) - { - // some lexing error - cerr << "WAVE 2:" << e.file_name() << "(" << e.line_no() << "): " - << e.description() << endl; - } - } - } - - catch (boost::wave::cpp_exception &e) - { - // some preprocessing error - cerr << "WAVE 3 (boost::wave::cpp_exception): " << e.file_name() << "(" << e.line_no() << "): " - << e.description() << endl; - } - - catch (boost::wave::cpplexer::lexing_exception &e) - { - // some lexing error - cerr << "WAVE 4 (boost::wave::cpplexer::lexing_exception):" << e.file_name() << "(" << e.line_no() << "): " - << e.description() << endl; - } - catch (std::exception &e) - { - // use last recognized token to retrieve the error position - cerr << "WAVE 5 (std::exception):" << current_position.get_file() - << "(" << current_position.get_line() << "): " - << "exception caught: " << e.what() - << endl; - } - catch (...) - { - // use last recognized token to retrieve the error position - cerr << "WAVE 6 (all other exceptions):" << current_position.get_file() - << "(" << current_position.get_line() << "): " - << "unexpected exception caught." << endl; - } - // End Lexing - - attributeListMap.attach_line_to_macro_call(); - -#if 1 - // King84 (2010.09.23): We capture the raw token stream because the tokens that aren't pre-processed tokens don't show up in the individual file's list of tokens. Also, #line directives get obeyed and mapped into different files. If we want to reproduce the original file failthfully, we have to use the raw list. I leave the rest here for future reference, since it took some figuring out to get right. - if (SgProject::get_verbose() >= 1) - std::cout << "File " << sourceFileName << " has " << ctx.get_hooks().tokens.size() << " tokens." << std::endl; - for (std::list< token_type >::iterator i = ctx.get_hooks().tokens.begin(); i != ctx.get_hooks().tokens.end(); ++i) - { - sageFilePtr->get_rawTokenStream().push_back(*i); - } -#else -// sageFilePtr->get_rawTokenStream().clear(); - assert(attributeListMap.currentMapOfAttributes.find(sourceFileName) != attributeListMap.currentMapOfAttributes.end()); - for (std::vector::iterator i = attributeListMap.currentMapOfAttributes[sourceFileName]->getList().begin(); i != attributeListMap.currentMapOfAttributes[sourceFileName]->getList().end(); ++i) - { - // King84 (2010.09.23): We aren't doing tokens, so we cheat by stringizing everything. I guess we could get the tokens out of here, but I'm lazy, since we aren't doing this for real anyway - { - token_type holder = token_type(boost::wave::T_CPPCOMMENT, (**i).getString().c_str(), boost::wave::util::file_position_type(BOOST_WAVE_STRINGTYPE(), 0, 0)); - sageFilePtr->get_rawTokenStream().push_back( holder ); - } - } -#endif - -#if 0 - // Get all SgFile nodes in the AST so that the attributes can be attached to them - // std::vector sgFileList = NodeQuery::querySubTree(project,&findNodes); - std::vector sgFileList = NodeQuery::querySubTree(sageFilePtr,&findNodes); - - // Attache the map of attributes belonging to the current file to the AST - for(std::vector::iterator it = sgFileList.begin(); it != sgFileList.end(); ++it) - { - SgFile* sgFile = isSgFile(*it); - attachPreprocessingInfo(sgFile,&attributeListMap.currentMapOfAttributes); - } -#else - // AS(01/04/07) Create a global map of filenames to PreprocessingInfo*'s as it is inefficient - // to get this by a traversal of the AST - for(AttributeListMap::attribute_map_type::iterator it_files = attributeListMap.currentMapOfAttributes.begin(); it_files != attributeListMap.currentMapOfAttributes.end(); ++it_files) - { - std::string filename2 = it_files->first; - - /* - Sg_File_Info* sourceFileInfo = sageFilePtr->get_file_info(); - int sourceFileNameId = (sageFilePtr->get_requires_C_preprocessor() == true) ? Sg_File_Info::getIDFromFilename(filename2) : sourceFileInfo->get_file_id(); - int sourceFileNameId = (sageFilePtr->get_requires_C_preprocessor() == true) ? - Sg_File_Info::getIDFromFilename(sageFilePtr->generate_C_preprocessor_intermediate_filename(filename2)) : - sourceFileInfo->get_file_id(); - */ - - - ROSEAttributesList* attrList = it_files->second; - mapFilenameToAttributes[filename2] = attrList; - - // TODO: - // King84 (2010.09.22) Add preprocessing info vector to file object, so we can access it later for unparsing - - if (SgProject::get_verbose() >= 1) - std::cout << "source file name:" << sageFilePtr->generate_C_preprocessor_intermediate_filename(filename2) << std::endl; -// std::vector* preproc_info = new std::vector(); - // attributeMapForAllFiles[sourceFileNameId] = attrList; - -#if 1 - for (std::vector::iterator it_preproc = attrList->getList().begin(); it_preproc != attrList->getList().end(); ++it_preproc) - { - //preproc_info->push_back(*it_preproc); -// returnListOfAttributes->addElement(**it_preproc); - ROSE_ASSERT(*it_preproc != NULL); - if( SgProject::get_verbose() >= 1 ) - std::cerr << "Added Macro " << (*it_preproc)->getString() << std::endl; - } -#endif - - if (SgProject::get_verbose() >= 1) - { - std::cout << "Size of vector: " << attrList->size() << std::endl; - std::cout << "Iterating over filename:" << filename2 << std::endl; - } - } - - if (SgProject::get_verbose() >= 1) - std::cout << "Size of mapFilenameToAttributes:" << mapFilenameToAttributes.size() << std::endl; - -#endif - -// endif for ifdef _MSCx_VER -//#endif - -// endif for ifndef CXX_IS_ROSE_CODE_GENERATION -#endif - -#if 0 - printf ("Ending at base of attachPreprocessingInfoUsingWave(SgSourceFile*) \n"); - ROSE_ABORT(); -#endif - } -// Only compiled if using Boost::wave. -#endif // DQ (12/3/2020): We sometimes want to read a file twice, and gather the comments // and CPP directives twice, but the second time the file is read it is read so that diff --git a/src/frontend/SageIII/attachPreprocessingInfo.h b/src/frontend/SageIII/attachPreprocessingInfo.h index 8789fcaac61..a281c8111df 100644 --- a/src/frontend/SageIII/attachPreprocessingInfo.h +++ b/src/frontend/SageIII/attachPreprocessingInfo.h @@ -31,8 +31,6 @@ ROSEAttributesList *getPreprocessorDirectives( std::string fileName, std::string // void attachPreprocessingInfo(SgSourceFile *sageFile); void attachPreprocessingInfo(SgSourceFile *sageFile, const std::string & new_filename = ""); -// DQ (11/30/2008): Part of refactoring of code specific to Wave. -void attachPreprocessingInfoUsingWave(SgSourceFile *sageFile); #if 0 // DQ (12/16/2008): comment out while I debug the non-wave support. From 040d5cc4e99740a810df58bf8242344a7e93223a Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 20:16:29 -0400 Subject: [PATCH 04/42] Removed Boost thread dependency --- CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e2ed0072c20..04788c2e185 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system thread + COMPONENTS chrono date_time iostreams program_options random regex system REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system thread serialization) + COMPONENTS chrono date_time iostreams program_options random regex system serialization) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries @@ -228,13 +228,13 @@ set(USE_CMAKE 1) set(HAVE_BOOST ${Boost_FOUND}) set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) -set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) +#set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) -set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) -set(HAVE_BOOST_WAVE ${Boost_WAVE_FOUND}) -set(USE_ROSE_BOOST_WAVE_SUPPORT ${Boost_WAVE_FOUND}) +#set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) +#set(HAVE_BOOST_WAVE ${Boost_WAVE_FOUND}) +#set(USE_ROSE_BOOST_WAVE_SUPPORT ${Boost_WAVE_FOUND}) ######################################################################################################################## # ROSETTA From a104e37c3bb935fae271f5e5d5149a5a2a8d11bb Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 21:55:49 -0400 Subject: [PATCH 05/42] Removed Boost regex/random dependencies --- CMakeLists.txt | 6 +++--- src/rose-config.C | 19 ++++++++++--------- src/util/StringUtility/Convert.C | 8 ++++---- src/util/StringUtility/Trim.h | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 src/util/StringUtility/Trim.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 04788c2e185..9069088b51f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system + COMPONENTS chrono date_time iostreams program_options system REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options random regex system serialization) + COMPONENTS chrono date_time iostreams program_options system serialization) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries @@ -230,7 +230,7 @@ set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) #set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) -set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) +#set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) #set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) #set(HAVE_BOOST_WAVE ${Boost_WAVE_FOUND}) diff --git a/src/rose-config.C b/src/rose-config.C index bc04497d1df..69333919dab 100644 --- a/src/rose-config.C +++ b/src/rose-config.C @@ -35,14 +35,14 @@ static const char *description = #include // POLICY_OK -- this is not a ROSE library source file #include -#include -#include #include -#include +#include #include #include #include +#include + using namespace Rose; typedef std::map Configuration; @@ -121,7 +121,7 @@ readConfigFile(const std::filesystem::path &configName) { exit(1); } - boost::regex keyRe("[a-zA-Z][a-zA-Z_0-9]*"); + std::regex keyRe("[a-zA-Z][a-zA-Z_0-9]*"); size_t lineNumber = 0; while (ssize_t nchars = rose_getline(&r.line, &r.linesz, r.file)) { ++lineNumber; @@ -134,17 +134,17 @@ readConfigFile(const std::filesystem::path &configName) { } std::string s = r.line; - boost::trim(s); + s = trim(s); if (s.empty() || '#' == s[0]) continue; // Parse the "key=value" line size_t equal = s.find('='); std::string key = s.substr(0, equal); - boost::trim(key); + key = trim(key); std::string value = equal == std::string::npos ? std::string() : s.substr(equal+1); - boost::trim(value); - if (equal == std::string::npos || !boost::regex_match(key, keyRe)) { + value = trim(value); + if (equal == std::string::npos || !std::regex_match(key, keyRe)) { MLOG_FATAL_CXX("rose-config") < dirs; - boost::split(dirs, settings.searchDirs, boost::is_any_of(":;")); + //boost::split(dirs, settings.searchDirs, boost::is_any_of(":;")); + dirs = Rose::StringUtility::split(settings.searchDirs, ":;"); BOOST_FOREACH (const std::string &dir, dirs) { std::filesystem::path configFile = std::filesystem::path(dir) / CONFIG_NAME; if (std::filesystem::exists(configFile)) diff --git a/src/util/StringUtility/Convert.C b/src/util/StringUtility/Convert.C index dbbef35fbd7..3657d8d533c 100644 --- a/src/util/StringUtility/Convert.C +++ b/src/util/StringUtility/Convert.C @@ -4,7 +4,7 @@ #include #include // rose -#include +#include #include #include @@ -188,13 +188,13 @@ removeRedundantSubstrings(const std::string &s) { std::string removeAnsiEscapes(const std::string &s) { - boost::regex csiSequences("\\033\\[[\\x30-\\x3f]*[\\x20-\\x2f]*[\\x40-x7e]"); + std::regex csiSequences("\\033\\[[\\x30-\\x3f]*[\\x20-\\x2f]*[\\x40-x7e]"); std::string retval; const char *iter = s.c_str(); const char *end = s.c_str() + s.size(); - boost::cmatch found; - while (boost::regex_search(iter, end, found, csiSequences)) { + std::cmatch found; + while (std::regex_search(iter, end, found, csiSequences)) { retval += std::string(iter, iter + found.position()); iter += found.position() + found.length(); } diff --git a/src/util/StringUtility/Trim.h b/src/util/StringUtility/Trim.h new file mode 100644 index 00000000000..8eaca6a8e77 --- /dev/null +++ b/src/util/StringUtility/Trim.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +// To replace boost::trim +std::string trim(const std::string& str) { + size_t start = str.find_first_not_of(" \t\n\r"); + if (start == std::string::npos) + return ""; + + size_t end = str.find_last_not_of(" \t\n\r"); + size_t length = end - start + 1; + + return str.substr(start, length); +} + From 29dd1f11bc34be35a4984aacb8d9e26d7724dc98 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 22:06:18 -0400 Subject: [PATCH 06/42] Removed boost system/serialization dependencies --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9069088b51f..c6d8c5a2a37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options system + COMPONENTS chrono date_time iostreams program_options REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options system serialization) + COMPONENTS chrono date_time iostreams program_options) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries @@ -226,12 +226,12 @@ set(USE_CMAKE 1) # ROSE configuration variables for Boost set(HAVE_BOOST ${Boost_FOUND}) -set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) +#set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) #set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) #set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) -set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) +#set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) #set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) #set(HAVE_BOOST_WAVE ${Boost_WAVE_FOUND}) #set(USE_ROSE_BOOST_WAVE_SUPPORT ${Boost_WAVE_FOUND}) From 48a7c9bc47052e0e0ea2f502ccb685441d03662c Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 22:17:08 -0400 Subject: [PATCH 07/42] Removed boost iostreams/program options dependencies --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6d8c5a2a37..683bf14c8c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -201,13 +201,13 @@ endif(WIN32) # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options + COMPONENTS chrono date_time REQUIRED) if(NOT Boost_FOUND) message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") endif() find_package(Boost 1.47.0 - COMPONENTS chrono date_time iostreams program_options) + COMPONENTS chrono date_time) include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries @@ -229,7 +229,7 @@ set(HAVE_BOOST ${Boost_FOUND}) #set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) #set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) -set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) +#set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) #set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) #set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) #set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) From 5ceb91a4dde6e7f3e111613448daf893234c8148 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 12 Sep 2023 22:30:06 -0400 Subject: [PATCH 08/42] Initial boost removal (note: things still commented out) --- CMakeLists.txt | 32 ++++++++++++++++---------------- src/CMakeLists.txt | 8 +++++--- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 683bf14c8c3..515f3c623df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,34 +200,34 @@ endif(WIN32) # REQUIRED clause after the first one has succeeded. That way the first clause checks for requires components, and the # second can check again including optional components. If the version of cmake is high enough you can use an # OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." -find_package(Boost 1.47.0 - COMPONENTS chrono date_time - REQUIRED) -if(NOT Boost_FOUND) - message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") -endif() -find_package(Boost 1.47.0 - COMPONENTS chrono date_time) -include_directories(${Boost_INCLUDE_DIRS}) +#find_package(Boost 1.47.0 +# COMPONENTS chrono date_time +# REQUIRED) +#if(NOT Boost_FOUND) +# message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") +#endif() +#find_package(Boost 1.47.0 +# COMPONENTS chrono date_time) +#include_directories(${Boost_INCLUDE_DIRS}) # Paths to install header, executable, and libraries set(INCLUDE_INSTALL_DIR "include/rose") set(BIN_INSTALL_DIR "bin") set(LIB_INSTALL_DIR "${ROSE_LIB_DIR_NAME}") -set(INSTALL_TARGETS_DEFAULT_ARGS - RUNTIME DESTINATION "${BIN_INSTALL_DIR}" - LIBRARY DESTINATION "${LIB_INSTALL_DIR}" - ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" - COMPONENT Devel) +#set(INSTALL_TARGETS_DEFAULT_ARGS +# RUNTIME DESTINATION "${BIN_INSTALL_DIR}" +# LIBRARY DESTINATION "${LIB_INSTALL_DIR}" +# ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" +# COMPONENT Devel) # A new definition to tweak code for cmake set(USE_CMAKE 1) # ROSE configuration variables for Boost -set(HAVE_BOOST ${Boost_FOUND}) +#set(HAVE_BOOST ${Boost_FOUND}) #set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) -set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) +#set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) #set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) #set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) #set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c96b8524856..52df41d63e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,7 +26,7 @@ add_custom_target( # Header files needed to build ROSETTA include_directories( - ${Boost_INCLUDE_DIRS} + #${Boost_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/src/midend/programTransformation/transformationTracking ${CMAKE_BINARY_DIR}/src/3rdPartyLibraries/fortran-parser ${JAVA_INCLUDE_PATH} @@ -241,7 +241,8 @@ install(TARGETS rose-compiler DESTINATION bin) set(rose_config_installed_cppflags "-I${CMAKE_INSTALL_PREFIX}/include/rose") set(rose_library_dir_list "${CMAKE_INSTALL_PREFIX}/${ROSE_LIB_DIR_NAME}") -set(rose_library_dir_list "${rose_library_dir_list};${Boost_LIBRARY_DIRS}") +#set(rose_library_dir_list "${rose_library_dir_list};${Boost_LIBRARY_DIRS}") +set(rose_library_dir_list "${rose_library_dir_list}") foreach(X IN LISTS rose_library_dir_list) set(rose_config_installed_ldflags "${rose_config_installed_ldflags} -L${X}") endforeach() @@ -249,7 +250,8 @@ set(rose_config_installed_cppflags "${rose_config_installed_cppflags} -I/usr/inc set(rose_library_list "rose") -set(rose_library_list "${rose_library_list};${Boost_LIBRARIES}") +#set(rose_library_list "${rose_library_list};${Boost_LIBRARIES}") +set(rose_library_list "${rose_library_list}") set(rose_library_list "${rose_library_list};m;quadmath") foreach(X IN LISTS rose_library_list) From e27f2f581ff883fcf6146b9b65368d6aecb79519 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Wed, 13 Sep 2023 11:41:21 -0400 Subject: [PATCH 09/42] Removed Boost fields from CMake --- CMakeLists.txt | 87 +++------------------------------------------- src/CMakeLists.txt | 3 -- 2 files changed, 4 insertions(+), 86 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 515f3c623df..78f99030c86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ if(WIN32) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() -add_definitions(-DBOOST_ALL_NO_LIB=1) +#add_definitions(-DBOOST_ALL_NO_LIB=1) # FIXME: Why do we have to have a copy of some standard built-in modules inside rose? set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH}) @@ -148,93 +148,14 @@ file(READ ${ROSE_SCM_DATE_FILE} ROSE_VERSION) message(STATUS "The ROSE version integer is ${ROSE_VERSION}") message(STATUS "The ROSE version string is ${ROSE_PACKAGE_VERSION}") -######################################################################################################################## -# Boost libraries -######################################################################################################################## - -message(STATUS - "If you get a whole bunch of warnings saying 'New Boost version may have incorrect or missing dependencies and " - "imported targets' it is probably because you're using a Boost version that was released after your CMake version. " - "See [https://github.com/Kitware/CMake/commits/master/Modules/FindBoost.cmake] to see latest supported version and " - "[https://github.com/Microsoft/vcpkg/issues/2459] for a description of the problem. Note that CMake versions " - "3.11.0 through 3.13.2 and possibly later) cannot be compiled (syntax errors) with a GNU C++ compiler that's " - "configured to use a non-default language standard (e.g., C++11 with GCC-5.4 whose default is GNU++03).") - -set(Boost_USE_STATIC_LIBS FALSE) -set(Boost_DEBUG ${VERBOSE}) - -# Honor BOOST_HOME environment variable -if(DEFINED ENV{BOOST_HOME}) - set(BOOST_ROOT "$ENV{BOOST_HOME}") -endif() - -option(Boost_USE_MULTITHREADED "Should Boost multithreaded libraries be used?" OFF) - -if(WIN32) - find_package(Boost REQUIRED) - set(BOOST_LIBRARYDIR ${Boost_LIBRARY_DIRS}) - set(BOOST_INCLUDEDIR ${Boost_INCLUDE_DIRS}/) - - message("Boost information:") - message(" BOOST_ROOT: ${BOOST_ROOT}") - message(" Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}") - message(" Boost_LIBRARIES: ${Boost_LIBRARIES}") - message(" Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}") - message(" BOOST_LIBRARYDIR : ${BOOST_LIBRARYDIR}") - message(" BOOST_INCLUDEDIR : ${BOOST_INCLUDEDIR}") - - include_directories(${Boost_INCLUDE_DIRS}) - link_directories(${Boost_LIBRARY_DIRS}) -endif(WIN32) - -# FIXME: 1.47 is no longer supported by ROSE, but is what's installed on Jenkins' CMake test machine. This should -# be changed to the actual minimum supported version once Pei-Hung upgrades the machine. [Matzke 2019-01-21] -# -# First look for the Boost libraries that are required in order to compile ROSE, then additionally look for any optional -# libraries that are useful to ROSE but not required. From a user: "The find_package() change is required for boost -# 1.70 or above on any system when using a recent enough version of cmake. Without it, serialization support will not -# be used. Before boost 1.70, the findBoost() in cmake is used directly, and it will look for boost components that are -# not in the find_package clause. Since 1.70, cmake will load the findBoost() provided by the boost package itself. -# Unfortunately, that findBoost() will only check for components in the find_package() clause. This means that -# serialization is considered not to exist, even if it is there. My change calls find_package again without the -# REQUIRED clause after the first one has succeeded. That way the first clause checks for requires components, and the -# second can check again including optional components. If the version of cmake is high enough you can use an -# OPTIONAL_COMPONENTS clause instead, but that wasn't introduced until 3.11." -#find_package(Boost 1.47.0 -# COMPONENTS chrono date_time -# REQUIRED) -#if(NOT Boost_FOUND) -# message(FATAL_ERROR "Could not find Boost version 1.35.0 or newer command") -#endif() -#find_package(Boost 1.47.0 -# COMPONENTS chrono date_time) -#include_directories(${Boost_INCLUDE_DIRS}) - # Paths to install header, executable, and libraries set(INCLUDE_INSTALL_DIR "include/rose") set(BIN_INSTALL_DIR "bin") set(LIB_INSTALL_DIR "${ROSE_LIB_DIR_NAME}") -#set(INSTALL_TARGETS_DEFAULT_ARGS -# RUNTIME DESTINATION "${BIN_INSTALL_DIR}" -# LIBRARY DESTINATION "${LIB_INSTALL_DIR}" -# ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" -# COMPONENT Devel) - # A new definition to tweak code for cmake set(USE_CMAKE 1) -# ROSE configuration variables for Boost -#set(HAVE_BOOST ${Boost_FOUND}) -#set(HAVE_BOOST_SERIALIZATION_LIB ${Boost_SERIALIZATION_FOUND}) -#set(HAVE_BOOST_DATE_TIME ${Boost_DATE_TIME_FOUND}) -#set(HAVE_BOOST_FILESYSTEM ${Boost_FILESYSTEM_FOUND}) -#set(HAVE_BOOST_PROGRAM_OPTIONS ${Boost_PROGRAM_OPTIONS_FOUND}) -#set(HAVE_BOOST_REGEX ${Boost_REGEX_FOUND}) -#set(HAVE_BOOST_SYSTEM ${Boost_SYSTEM_FOUND}) -#set(HAVE_BOOST_THREAD ${Boost_THREAD_FOUND}) -#set(HAVE_BOOST_WAVE ${Boost_WAVE_FOUND}) -#set(USE_ROSE_BOOST_WAVE_SUPPORT ${Boost_WAVE_FOUND}) ######################################################################################################################## # ROSETTA @@ -621,12 +542,12 @@ endif() # define a global variable to collect all common linked third-party libraries for rose if(NOT WIN32) if(NOT APPLE) - set(link_with_libraries ${Boost_LIBRARIES} ${M_LIB} ${RT_LIB} ${CMAKE_THREAD_LIBS_INIT}) + set(link_with_libraries ${M_LIB} ${RT_LIB} ${CMAKE_THREAD_LIBS_INIT}) else() - set(link_with_libraries ${Boost_LIBRARIES} ${M_LIB} ${CMAKE_THREAD_LIBS_INIT}) + set(link_with_libraries ${M_LIB} ${CMAKE_THREAD_LIBS_INIT}) endif() else() - set(link_with_libraries ${Boost_LIBRARIES} shlwapi.lib psapi.lib) + set(link_with_libraries shlwapi.lib psapi.lib) endif() # Check compilers and version numbers. The module is located in src/cmake/modules. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52df41d63e6..dff7202eb85 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,7 +26,6 @@ add_custom_target( # Header files needed to build ROSETTA include_directories( - #${Boost_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/src/midend/programTransformation/transformationTracking ${CMAKE_BINARY_DIR}/src/3rdPartyLibraries/fortran-parser ${JAVA_INCLUDE_PATH} @@ -241,7 +240,6 @@ install(TARGETS rose-compiler DESTINATION bin) set(rose_config_installed_cppflags "-I${CMAKE_INSTALL_PREFIX}/include/rose") set(rose_library_dir_list "${CMAKE_INSTALL_PREFIX}/${ROSE_LIB_DIR_NAME}") -#set(rose_library_dir_list "${rose_library_dir_list};${Boost_LIBRARY_DIRS}") set(rose_library_dir_list "${rose_library_dir_list}") foreach(X IN LISTS rose_library_dir_list) set(rose_config_installed_ldflags "${rose_config_installed_ldflags} -L${X}") @@ -250,7 +248,6 @@ set(rose_config_installed_cppflags "${rose_config_installed_cppflags} -I/usr/inc set(rose_library_list "rose") -#set(rose_library_list "${rose_library_list};${Boost_LIBRARIES}") set(rose_library_list "${rose_library_list}") set(rose_library_list "${rose_library_list};m;quadmath") From c2c3d20cd861c48c70c98720601e5e360faf721f Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Wed, 13 Sep 2023 12:02:45 -0400 Subject: [PATCH 10/42] Partially removed Boost from Node.code --- src/ROSETTA/Grammar/Node.code | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/ROSETTA/Grammar/Node.code b/src/ROSETTA/Grammar/Node.code index 1864f985b31..d787ca122ea 100644 --- a/src/ROSETTA/Grammar/Node.code +++ b/src/ROSETTA/Grammar/Node.code @@ -3,18 +3,17 @@ HEADER_NODE_PREDECLARATION_START #include -// tps (01/27/10): Added essential files.. -//#include "sage3basic.h" -#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include +#include + +// tps (01/27/10): Added essential files.. +//#include "sage3basic.h" +#include #include "Cxx_Grammar.h" @@ -350,12 +349,11 @@ typedef SgTokenPtrList* SgTokenPtrListPtr; // DQ (11/4/2009): Trying to use the boost hash_map support namespace rose_hash { - // The condition here is not needed for GCC 4.2, but is needed (and does not completely work) for earlier versions - using boost::unordered_map; - using boost::unordered_multimap; - using boost::unordered_set; - using boost::hash; - + using std::unordered_map; + using std::unordered_multimap; + using std::unordered_set; + using std::hash; + // DQ (4/23/2009): These should be put into this namespace so that we don't contaminate the global scope. // DQ (8/19/2008): This is already defined in src/frontend/SageIII/astMerge/buildMangledNameMap.h struct eqstr_string From 7ee15636dc04e5670090fa5312bfaef27b470ea8 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Wed, 13 Sep 2023 12:21:17 -0400 Subject: [PATCH 11/42] Removed more boost code; removed dead extractFunctionArgumentsNormalization --- .../programTransformation/CMakeLists.txt | 1 - .../astOutlining/GenerateFunc.cc | 5 +- .../astOutlining/PragmaInterface.cc | 4 +- .../CMakeLists.txt | 3 - .../ExtractFunctionArguments.C | 379 ------------------ .../ExtractFunctionArguments.h | 83 ---- .../Makefile.am | 22 - .../functionEvaluationOrderTraversal.C | 166 -------- .../functionEvaluationOrderTraversal.h | 89 ---- 9 files changed, 5 insertions(+), 747 deletions(-) delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C delete mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h diff --git a/src/midend/programTransformation/CMakeLists.txt b/src/midend/programTransformation/CMakeLists.txt index cba1b50a9ae..6a28cf5c3c1 100644 --- a/src/midend/programTransformation/CMakeLists.txt +++ b/src/midend/programTransformation/CMakeLists.txt @@ -7,7 +7,6 @@ add_subdirectory(astInlining) add_subdirectory(astOutlining) add_subdirectory(ompLowering) add_subdirectory(transformationTracking) -add_subdirectory(extractFunctionArgumentsNormalization) add_subdirectory(singleStatementToBlockNormalization) if(NOT enable-internalFrontendDevelopment) add_subdirectory(loopProcessing) diff --git a/src/midend/programTransformation/astOutlining/GenerateFunc.cc b/src/midend/programTransformation/astOutlining/GenerateFunc.cc index 226b88b2f9f..57853a80c01 100644 --- a/src/midend/programTransformation/astOutlining/GenerateFunc.cc +++ b/src/midend/programTransformation/astOutlining/GenerateFunc.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include "Outliner.hh" #include "ASTtools.hh" @@ -1397,8 +1398,8 @@ class SymbolMapOfTwoFiles dict[i1->second]=i2->second; #endif rose_hash_multimap::iterator i1, i2; - boost::unordered_map varSymDict; - boost::unordered_map funcSymDict; + std::unordered_map varSymDict; + std::unordered_map funcSymDict; // cache mapping of new symbols,indexed by qualified name : qualified name to symbol for (i2=set2->begin(); i2!=set2->end(); i2++) diff --git a/src/midend/programTransformation/astOutlining/PragmaInterface.cc b/src/midend/programTransformation/astOutlining/PragmaInterface.cc index af02e2f3021..4c9035e53d0 100644 --- a/src/midend/programTransformation/astOutlining/PragmaInterface.cc +++ b/src/midend/programTransformation/astOutlining/PragmaInterface.cc @@ -19,7 +19,7 @@ #include "Outliner.hh" #include "ASTtools.hh" #include "PreprocessingInfo.hh" -#include +#include //! Simplest outlining directives, applied to a single statement. static const std::string PRAGMA_OUTLINE ("rose_outline"); @@ -89,7 +89,7 @@ processFortranComment(SgLocatedNode* node) if ((*i)->getTypeOfDirective() == PreprocessingInfo::FortranStyleComment) { string commentString = (*i)->getString(); - boost::algorithm::trim(commentString); + trim(commentString); if ( (commentString == "!$"+PRAGMA_OUTLINE) || (commentString == "c$"+PRAGMA_OUTLINE) || (commentString == "*$"+PRAGMA_OUTLINE)) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt b/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt deleted file mode 100644 index 859357b7396..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -install(FILES - ExtractFunctionArguments.h functionEvaluationOrderTraversal.h - DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C deleted file mode 100644 index ff84237e9f8..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C +++ /dev/null @@ -1,379 +0,0 @@ -#include "ExtractFunctionArguments.h" -#include -#include -#include -#include "SingleStatementToBlockNormalization.h" - -#define foreach BOOST_FOREACH - -using namespace std; -using namespace boost; - - -/** Performs the function argument extraction on all function calls in the given subtree of the AST. */ -/** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all callsites ignoring the safety (Suggested by Markus Schordan) */ - -void ExtractFunctionArguments::NormalizeTree(SgNode* tree, bool doUnsafeNormalization) { - // First Normalize each single statememnt body into a block body - // This transformation is necessary to provide scope to newly created temporaries - // Note: if this transofrmation is already done, it is benign to rerun it - // and this would act as a NOP transformation. - - SingleStatementToBlockNormalizer singleStatementToBlockNormalizer; - singleStatementToBlockNormalizer.Normalize(tree); - - - - // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) - // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} - this->functionCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); - - // Normalize each function from safe place - foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.first) { - RewriteFunctionCallArguments(functionCallInfo); - } - - // if doUnsafeNormalization is true, we will normalize calls which are not safe - if(doUnsafeNormalization){ - foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.second) { - RewriteFunctionCallArguments(functionCallInfo); - } - } - -} - - -/* - return a vector of temporaries introduced during the translation process - */ -std::vector ExtractFunctionArguments::GetTemporariesIntroduced() { - return this->temporariesIntroduced; -} - -/** Returns true if the given expression refers to a variable. This could include using the - * dot and arrow operator to access member variables. A comma op counts as a variable references - * if all its members are variable references (not just the last expression in the list). */ -bool isVariableReference(SgExpression* expression) -{ - if (isSgVarRefExp(expression)) - { - return true; - } - else if (isSgThisExp(expression)) - { - return true; - } - else if (isSgDotExp(expression)) - { - SgDotExp* dotExpression = isSgDotExp(expression); - return isVariableReference(dotExpression->get_lhs_operand()) && - isVariableReference(dotExpression->get_rhs_operand()); - } - else if (isSgArrowExp(expression)) - { - SgArrowExp* arrowExpression = isSgArrowExp(expression); - return isVariableReference(arrowExpression->get_lhs_operand()) && - isVariableReference(arrowExpression->get_rhs_operand()); - } - else if (isSgCommaOpExp(expression)) - { - //Comma op where both the lhs and th rhs are variable references. - //The lhs would be semantically meaningless since it doesn't have any side effects - SgCommaOpExp* commaOp = isSgCommaOpExp(expression); - return isVariableReference(commaOp->get_lhs_operand()) && - isVariableReference(commaOp->get_rhs_operand()); - } - else if (isSgPointerDerefExp(expression) || isSgCastExp(expression) || isSgAddressOfOp(expression)) - { - return isVariableReference(isSgUnaryOp(expression)->get_operand()); - } - else - { - return false; - } -} - -/* Given the expression which is the argument to a function call, returns true if that - expression is trivial. Trivial expressions are those which are simple variable references or constants. - */ - -bool ExtractFunctionArguments::IsFunctionArgumentTrivial(SgExpression* argument) { - while ((isSgPointerDerefExp(argument) || isSgCastExp(argument) || isSgAddressOfOp(argument))) { - argument = isSgUnaryOp(argument)->get_operand(); - } - - SgArrowExp* arrowExp = isSgArrowExp(argument); - if (arrowExp && isSgThisExp(arrowExp->get_lhs_operand())) - return true; - - // We don't lift these simple types - if (isVariableReference(argument) || isSgValueExp(argument)) - return true; - - return false; -} - - -/* Given a vector of function call sites returns true if every argument of every function call is a trivial expression - (IsFunctionArgumentTrivial). Such functions don't need to be normalized. - */ -bool ExtractFunctionArguments::AreAllFunctionCallsTrivial(std::vector functions){ - foreach(FunctionCallInfo functionCallInfo, functions){ - foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ - if (!IsFunctionArgumentTrivial(arg)) { - return false; - } - } - } - return true; -} - -/* Given a vector of function call sites, returns true if every argument - at every function call site is either trivial (IsFunctionArgumentTrivial) or can be normalized (FunctionArgumentCanBeNormalized). - */ -bool ExtractFunctionArguments::AreAllFunctionCallsNormalizable(std::vector functions){ - foreach(FunctionCallInfo functionCallInfo, functions){ - foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ - if (!IsFunctionArgumentTrivial(arg) && !FunctionArgumentCanBeNormalized(arg)) { - return false; - } - } - } - return true; -} - - -/* - IsNormalized: Given a subtree, returns true if every argument of every function call is a trivial arguemnt. -*/ - -bool ExtractFunctionArguments::IsNormalized(SgNode* tree){ - // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) - // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} - pair< std::vector, std::vector > fCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); - - //Make sure all arguemnts of all SAFE place functions calls are trivial - if(!AreAllFunctionCallsTrivial(fCalls.first)) - return false; - - //Make sure all arguemnts of all NON-SAFE place functions calls are also trivial - if(!AreAllFunctionCallsTrivial(fCalls.second)) - return false; - - // All are trivial - return true; -} - - -/* - IsNormalizable: Given a subtree, returns true if every argument of every function call is a either trivial arguemnt or - present in a SAFE place from where lifting is possible. -*/ - -bool ExtractFunctionArguments::IsNormalizable(SgNode* tree){ - // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) - // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} - pair< std::vector, std::vector > fCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); - - //Make sure all arguemnts of all SAFE place functions calls are either trivial or normalizable - if(!AreAllFunctionCallsNormalizable(fCalls.first)) - return false; - - // Must be trivail in NON SAFE places - if(!AreAllFunctionCallsTrivial(fCalls.second)) - return false; - - // We can normalize - return true; -} - - -/** Given the information about a function call (obtained through a traversal), extract its arguments - * into temporary variables where it is necessary. - * Returns true on success, false on failure (unsupported code). */ -void ExtractFunctionArguments::RewriteFunctionCallArguments(const FunctionCallInfo& functionCallInfo) -{ - SgFunctionCallExp* functionCall = functionCallInfo.functionCall; - - // Force the function call to NOT use operator syntax - functionCall->set_uses_operator_syntax(false); - - SgExprListExp* functionArgs = functionCall->get_args(); - ROSE_ASSERT(functionArgs != NULL); - - SgExpressionPtrList argumentList = functionArgs->get_expressions(); - - // We also normalize the caller if the function called is a member function. - if (SgBinaryOp * binExp = isSgBinaryOp(functionCall->get_function())) { - argumentList.push_back(binExp->get_lhs_operand()); - } - - //Go over all the function arguments, pull them out - - foreach(SgExpression* arg, argumentList) - { - //No need to pull out parameters that are not complex expressions and - //thus don't have side effects - if (!FunctionArgumentNeedsNormalization(arg)) - continue; - - //Build a declaration for the temporary variable - SgScopeStatement* scope = functionCallInfo.tempVarDeclarationLocation->get_scope(); - ROSE_ASSERT(scope != NULL ); - - // DQ (3/1/2015): Added initialization to these local variables. - // SgVariableDeclaration* tempVarDeclaration; - // SgExpression* tempVarReference; - SgVariableDeclaration* tempVarDeclaration = NULL; - SgExpression* tempVarReference = NULL; - - // DQ (3/1/2015): Avoid normalization of function arguments of type SgFunctionType (see inputBug317.C). - // This might be an issue more narrowly defined for compiler-generated functions, this is less clear. - SgFunctionType* functionType = isSgFunctionType(arg->get_type()); - if (functionType == NULL) - { - tie(tempVarDeclaration, tempVarReference) = SageInterface::createTempVariableAndReferenceForExpression(arg, scope); - - // createTempVariableOrReferenceForExpression does not set the parent if the scope stack is empty. Hence set it manually to the currect scope. - tempVarDeclaration->set_parent(scope); -#if 0 - { - std::cout<<"\n"<get_file_info()->get_filenameString () << ":" << functionCall->get_file_info()->get_line() << ":" << functionCall->get_file_info()->get_col(); - std::cout<<"\n Name = "<< tempVarDeclaration->get_mangled_name().getString()<< " : type : " << arg->get_type()->class_name() << " Expr class : " << arg->class_name(); - } -#endif - ROSE_ASSERT(tempVarDeclaration != NULL ); - - // DQ (3/1/2015): This is not always true (see inputBug317.C). - ROSE_ASSERT(tempVarDeclaration->get_definition(0) != NULL); - ROSE_ASSERT(isSgVariableDefinition(tempVarDeclaration->get_definition()) != NULL); - - //Insert the temporary variable declaration - InsertStatement(tempVarDeclaration, functionCallInfo.tempVarDeclarationLocation, functionCallInfo); - - // remember the introduced temp so that it can be queried - temporariesIntroduced.push_back(tempVarDeclaration); - - //Replace the argument with the new temporary variable - SageInterface::replaceExpression(arg, tempVarReference); - } - else - { - printf ("In ExtractFunctionArguments::RewriteFunctionCallArguments(): Skipping normalization of function arguments of type SgFunctionType \n"); - } - } -} - - -// If we have a limitation in normalizing the function return false -bool ExtractFunctionArguments::FunctionArgumentCanBeNormalized(SgExpression* argument) -{ - while ((isSgPointerDerefExp(argument) || isSgCastExp(argument) || isSgAddressOfOp(argument))) - { - argument = isSgUnaryOp(argument)->get_operand(); - } - // Don't include SgConstructorInitializer since it will be called even on the temporary, so avoid double copy. - if (isSgFunctionRefExp(argument) || isSgMemberFunctionRefExp(argument) || isSgConstructorInitializer(argument)) - return false; - - // Unknow Template type expressions can't be normalized. - if (isSgTypeUnknown(argument->get_type()) || isSgMemberFunctionType(argument->get_type())) { - //printf("\n Skipping over SgTypeUnknown/SgMemberFunctionType expr"); - return false; - } - - return true; -} - - - -/** Given the expression which is the argument to a function call, returns true if that - * expression should be pulled out into a temporary variable on a separate line. - * E.g. if the expression contains a function call, it needs to be normalized, while if it - * is a constant, there is no need to change it. */ - -bool ExtractFunctionArguments::FunctionArgumentNeedsNormalization(SgExpression* argument) -{ - // Trivial argument don't need to be listed - - if (IsFunctionArgumentTrivial(argument)) - return false; - - // true/false based on our ability to normalize the argument - return FunctionArgumentCanBeNormalized(argument); -} - - -/** Returns true if any of the arguments of the given function call will need to - * be extracted. */ -bool ExtractFunctionArguments::FunctionArgsNeedNormalization(SgExprListExp* functionArgs) -{ - ROSE_ASSERT(functionArgs != NULL); - SgExpressionPtrList& argumentList = functionArgs->get_expressions(); - - foreach(SgExpression* functionArgument, argumentList) - { - if (FunctionArgumentNeedsNormalization(functionArgument)) - return true; - } - return false; -} - -/** Returns true if any function calls in the given subtree will need to be - * instrumented. (to extract function arguments). */ -bool ExtractFunctionArguments::SubtreeNeedsNormalization(SgNode* top) -{ - ROSE_ASSERT(top != NULL); - Rose_STL_Container functionCalls = NodeQuery::querySubTree(top, V_SgFunctionCallExp); - for (Rose_STL_Container::const_iterator iter = functionCalls.begin(); iter != functionCalls.end(); iter++) - { - SgExpression* functionCall = isSgFunctionCallExp(*iter); - ROSE_ASSERT(functionCall != NULL); - if (FunctionArgumentNeedsNormalization(functionCall)) - return true; - } - - return false; -} - -/** Insert a new statement in the specified location. The actual insertion can occur either before or after the location - * depending on the insertion mode. */ -void ExtractFunctionArguments::InsertStatement(SgStatement* newStatement, SgStatement* location, const FunctionCallInfo& insertionMode) -{ - switch (insertionMode.tempVarDeclarationInsertionMode) - { - case FunctionCallInfo::INSERT_BEFORE: - SageInterface::insertStatementBefore(location, newStatement); - break; - case FunctionCallInfo::APPEND_SCOPE: - { - SgScopeStatement* scopeStatement = isSgScopeStatement(location); - if (scopeStatement == NULL) - { - //scopeStatement = isSgScopeStatement(SageInterface::ensureBasicBlockAsParent(location)); - if (SageInterface::isBodyStatement(location)) // if the location is a single body statement (not a basic block) at this point - scopeStatement = SageInterface::makeSingleStatementBodyToBlock (location); - else - scopeStatement = isSgScopeStatement(location->get_parent()); - } - ROSE_ASSERT(scopeStatement != NULL); - - SageInterface::appendStatement(newStatement, scopeStatement); - break; - } - case FunctionCallInfo::INVALID: - default: - ROSE_ABORT(); - } -} - -/** Traverses the subtree of the given AST node and finds all function calls in - * function-evaluation order. */ -/*static*/pair< std::vector, std::vector > FunctionEvaluationOrderTraversal::GetFunctionCalls(SgNode* root) -{ - FunctionEvaluationOrderTraversal t; - FunctionCallInheritedAttribute rootAttribute; - t.traverse(root, rootAttribute); - - return pair< std::vector, std::vector > (t.normalizableFunctionCalls, t.nonNormalizableFunctionCalls); -} diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h deleted file mode 100644 index 7bd0d37c3f3..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -// DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h. -// #include "rose.h" -#include "sage3basic.h" - -#include "functionEvaluationOrderTraversal.h" - -//class FunctionCallInfo; - -//! This normalization makes sure each function call argument is a side-effect free expression of only one variable. -//! To accomplish this, temporary variables are declared and the arguments of a function are evaluated before the function itself. -//! Note: Normalization is not performed if it is unsafe. E,g.: while(Foo(Bar()) {} is not equal to t = Bar(); while(Foo(t) {} -//! Note that only SgFunctionCall arguments are normalized. For example the arguments of the constructor initializer -//! MyObject o(foo(), bar()) will not be extracted. -class ExtractFunctionArguments -{ -public: - - /** Performs the function argument extraction on all function calls in the given subtree of the AST. */ - /** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all call sites ignoring the safety (Suggested by Markus Schordan) */ - void NormalizeTree(SgNode* tree, bool doUnsafeNormalization = false); - - // returns a vector of newly introduced temporaries - std::vector GetTemporariesIntroduced(); - - /* - IsNormalized: Given a subtree, returns true if every argument of every function call is a trivial arguemnt. - */ - bool IsNormalized(SgNode* tree); - - /* - IsNormalizable: Given a subtree, returns true if every argument of every function call is a either trivial arguemnt or - is present in a SAFE place from where lifting is possible. - */ - bool IsNormalizable(SgNode* tree); - - -private: - - std::vector temporariesIntroduced; - std::pair< std::vector, std::vector > functionCalls; - - /** Given the expression which is the argument to a function call, returns true if that - * expression should be pulled out into a temporary variable on a separate line. - * E.g. if the expression contains a function call, it needs to be normalized, while if it - * is a constant, there is no need to change it. */ - bool FunctionArgumentNeedsNormalization(SgExpression* argument); - - /** Returns true if any of the arguments of the given function call will need to - * be extracted. */ - bool FunctionArgsNeedNormalization(SgExprListExp* functionArgs); - - /** Returns true if any function calls in the given subtree will need to be - * instrumented. (to extract function arguments). */ - bool SubtreeNeedsNormalization(SgNode* top); - - /** Given the information about a function call (obtained through a traversal), extract its arguments - * into temporary variables where it is necessary. */ - void RewriteFunctionCallArguments(const FunctionCallInfo& functionCallInfo); - - /** Insert a new statement in the specified location. The actual insertion can occur either before or after the location - * depending on the insertion mode. */ - void InsertStatement(SgStatement* newStatement, SgStatement* location, const FunctionCallInfo& insertionMode); - - bool FunctionArgumentCanBeNormalized(SgExpression* argument); - - - /* Given the expression which is the argument to a function call, returns true if that - expression is trivial. Trivial expressions are those which are simple variable references or constants. - */ - bool IsFunctionArgumentTrivial(SgExpression* argument); - - /* Given a vector of function call sites returns true if every argument of every function call is a trivial expression - (IsFunctionArgumentTrivial). Such functions don't need to be normalized. - */ - bool AreAllFunctionCallsTrivial(std::vector functions); - - /* Given a vector of function call sites, returns true if every argument - at every function call site is either trivial (IsFunctionArgumentTrivial) or can be normalized (FunctionArgumentCanBeNormalized). - */ - bool AreAllFunctionCallsNormalizable(std::vector functions); -}; diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am b/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am deleted file mode 100644 index 4d9b1a853a7..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs - -AM_CPPFLAGS = $(ROSE_INCLUDES) -#LINK = $(CXXLINK) - -# noinst_LTLIBRARIES lists all the libraries that should be built, but not installed -noinst_LTLIBRARIES = libExtractFunctionArgumentsNormalization.la - -libExtractFunctionArgumentsNormalization_la_DEPENDENCIES = $(srcdir)/../singleStatementToBlockNormalization/SingleStatementToBlockNormalization.h -libExtractFunctionArgumentsNormalization_la_CXXFLAGS = -I$(srcdir)/../singleStatementToBlockNormalization -libExtractFunctionArgumentsNormalization_la_SOURCES = ExtractFunctionArguments.C functionEvaluationOrderTraversal.C -pkginclude_HEADERS = ExtractFunctionArguments.h functionEvaluationOrderTraversal.h - - -# EXTRA_DIST are files that are not compiled or installed. These include readme's, internal header files, etc. -EXTRA_DIST = - -CLEANFILES = - - -check-local: - diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C deleted file mode 100644 index 175939503f8..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C +++ /dev/null @@ -1,166 +0,0 @@ -#include "sage3basic.h" // every librose .C file must start with this -#include - - -bool IsStatusSafe(int status){ - if (status == FunctionCallInheritedAttribute::IN_SAFE_PLACE) - return true; - if (status == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) - return true; - return false; -} - -/** Visits AST nodes in pre-order */ -FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute) -{ - FunctionCallInheritedAttribute result = parentAttribute; - SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope); - SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope); - SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope); - - SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL; - SgAndOp* parentAndOp = astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL; - SgOrOp* parentOrOp = astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL; - - if (isSgForStatement(astNode)) - result.currentScope = isSgForStatement(astNode); - else if (isSgWhileStmt(astNode)) - result.currentScope = isSgWhileStmt(astNode); - else if (isSgDoWhileStmt(astNode)) - result.currentScope = isSgDoWhileStmt(astNode); - //else if (isSgConditionalExp(astNode)) - // result.currentScope = isSgConditionalExp(astNode); - //else if (isSgAndOp(astNode)) - // result.currentScope = isSgAndOp(astNode); - //else if (isSgOrOp(astNode)) - // result.currentScope = isSgOrOp(astNode); - else if (isSgForInitStatement(astNode)) { - ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT; - ROSE_ASSERT(isSgForStatement(result.currentScope)); - } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) { - ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST; - } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) { - ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT; - } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) { - ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION; - } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) { - ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION; - } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) { - // if the scope status was safe, turn it into unsafe - if (IsStatusSafe(result.scopeStatus)) - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM; - } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) { - // if the scope status was safe, turn it into unsafe - if (IsStatusSafe(result.scopeStatus)) - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM; - } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) { - // if the scope status was safe, turn it into unsafe - if (IsStatusSafe(result.scopeStatus)) - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; - } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode) { - // if the scope status was safe, turn it into unsafe - if (IsStatusSafe(result.scopeStatus)) - result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; - } - - //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc. - if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) { - //We can't insert a variable declaration at these locations. Use the parent statement - } else if (isSgStatement(astNode)) { - result.lastStatement = isSgStatement(astNode); - } - - return result; -} - -// Returns false in the absence of any analysis information -bool FunctionEvaluationOrderTraversal::IsFunctionCallSideEffectFree(SgFunctionCallExp* functionCall) { - return false; -} - - -/** Visits AST nodes in post-order. This is function-evaluation order. */ -bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList) -{ - SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode); - if (functionCall == NULL) - return false; //dummy return value - - FunctionCallInfo functionCallInfo(functionCall); - - // Can't lift function call arguments from the following: - // 1. For loop test and increment - // 2. While loop test - // 3. Do-While loop test - // 4. Either arms of ternary op - // 5. RHS of any short circuit expression - // An alternative is to use comma operators and use assignemnt op as done by the original author. - // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);) - // But using assignement op is not always safe and it requires us to always have a default constructor - // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer - // but if & op is overloaded we may not get the pointer. - // Taking all these in view, I am simpling not lifting such expressions. - - if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST || - parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT || - parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION || - parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) { - - // ***** FOR UNSAFE TRANSFORMATION ******* - //Temporary variables should be declared before the stmt - ROSE_ASSERT(isSgStatement(parentAttribute.currentScope)); - functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope); - functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; - - nonNormalizableFunctionCalls.push_back(functionCallInfo); - return false; - } - - // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions - if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM || - parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM || - parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){ - - if(!IsFunctionCallSideEffectFree(functionCall)) { - - // ***** FOR UNSAFE TRANSFORMATION ******* - //Temporary variables should be declared before the stmt - ROSE_ASSERT(parentAttribute.lastStatement); - functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; - functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; - - nonNormalizableFunctionCalls.push_back(functionCallInfo); - return false; - } - } - - //Handle for loops (being inside the body of a for loop doesn't need special handling) - if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) - { - SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope); - ROSE_ASSERT(forLoop != NULL); - //Temporary variables should be declared before the loop - functionCallInfo.tempVarDeclarationLocation = forLoop; - functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; - } - else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE) - { - //Assume we're in a basic block. Then just insert right before the current statement - ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE); - functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; - functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; - } - else - { - //Unhandled condition?! - ROSE_ABORT(); - } - - normalizableFunctionCalls.push_back(functionCallInfo); - return false; //dummy return value -} diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h deleted file mode 100644 index e00d7203382..00000000000 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -// DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h. -// #include "rose.h" -// rose.h and sage3basic.h should not be included in librose header files. [Robb P. Matzke 2014-10-15] -// #include "sage3basic.h" - -struct FunctionCallInheritedAttribute -{ - /** The innermost scope inside of which this AST node resides. It is either a for-loop, - a do-loop, a while-loop or a conditioanl expression. */ - SgNode* currentScope; - - /** The last statement encountered before the current node in the AST. */ - SgStatement* lastStatement; - - /** Is the current node inside a for loop or conditional expresion structure (not the body). */ - enum - { - INSIDE_FOR_INIT, INSIDE_FOR_TEST, INSIDE_FOR_INCREMENT, INSIDE_WHILE_CONDITION, - INSIDE_DO_WHILE_CONDITION, IN_SAFE_PLACE, INSIDE_CONDITIONAL_EXP_TRUE_ARM, INSIDE_CONDITIONAL_EXP_FALSE_ARM, INSIDE_SHORT_CIRCUIT_EXP_RHS - } - scopeStatus; - - /** Default constructor. Initializes everything to NULL. */ - FunctionCallInheritedAttribute() : currentScope(NULL), lastStatement(NULL), scopeStatus(IN_SAFE_PLACE) { } -}; - -/** Stores a function call expression, along with associated information about its context. */ -struct FunctionCallInfo -{ - /** The function call expression. */ - SgFunctionCallExp* functionCall; - - /** When a variable is created to replace one of the arguments of this function, where should it be inserted? - * The declaration of the variable will occur right before this statement. */ - SgStatement* tempVarDeclarationLocation; - - /** How a statement should be inserted. */ - enum InsertionMode - { - /** Insert right before the given statement. */ - INSERT_BEFORE, - /** Insert at the bottom of the scope defined by the given statement. */ - APPEND_SCOPE, - INVALID - }; - - /** How to insert the temporary variable declaration. */ - InsertionMode tempVarDeclarationInsertionMode; - - FunctionCallInfo(SgFunctionCallExp * function) : - functionCall(function), - tempVarDeclarationLocation(NULL), - tempVarDeclarationInsertionMode(INVALID) { } -}; - - -//! Traverses a given AST and finds all function calls in the order in which they're evaluated -//! Also, for each function we find where to put declarations of temporary variables so that they're accessible at the function call - -class FunctionEvaluationOrderTraversal : public AstTopDownBottomUpProcessing -{ -public: - /** Traverses the subtree of the given AST node and finds all function calls in - * function-evaluation order. */ - static std::pair< std::vector, std::vector > GetFunctionCalls(SgNode* root); - - /** Visits AST nodes in pre-order */ - FunctionCallInheritedAttribute evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute); - - /** Visits AST nodes in post-order. This is function-evaluation order. */ - bool evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList); - - /// Returns true if the function call has no side effects. - virtual bool IsFunctionCallSideEffectFree(SgFunctionCallExp* functionCall); - -private: - - //! Private constructor. Use the static method to access the functionality of this class. - - FunctionEvaluationOrderTraversal() { } - - /** All the function calls seen so far that can be normalized. */ - std::vector normalizableFunctionCalls; - /** All the function calls seen so far that can't be normalized. */ - std::vector nonNormalizableFunctionCalls; -}; - From f9e8ad7bd34ea0db3daee2a3cb315b7a3608ec8f Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Wed, 13 Sep 2023 12:41:37 -0400 Subject: [PATCH 12/42] Removed potentially dead midend code --- src/midend/astProcessing/CMakeLists.txt | 7 +- src/midend/astProcessing/SgGraphTemplate.h | 201 -- src/midend/astProcessing/graphProcessing.h | 1560 -------------- .../astProcessing/graphProcessingSgIncGraph.h | 1865 ----------------- src/midend/astProcessing/graphTemplate.h | 533 ----- .../functional/roseTests/CMakeLists.txt | 2 +- .../astProcessingTests/CMakeLists.txt | 24 +- 7 files changed, 18 insertions(+), 4174 deletions(-) delete mode 100644 src/midend/astProcessing/SgGraphTemplate.h delete mode 100644 src/midend/astProcessing/graphProcessing.h delete mode 100644 src/midend/astProcessing/graphProcessingSgIncGraph.h delete mode 100644 src/midend/astProcessing/graphTemplate.h diff --git a/src/midend/astProcessing/CMakeLists.txt b/src/midend/astProcessing/CMakeLists.txt index 075c79f514e..ec4582f4c22 100644 --- a/src/midend/astProcessing/CMakeLists.txt +++ b/src/midend/astProcessing/CMakeLists.txt @@ -32,10 +32,13 @@ set(files_to_install AstReverseSimpleProcessing.h AstRestructure.h AstClearVisitFlags.h AstTraversal.h AstCombinedProcessing.h AstCombinedProcessingImpl.h AstCombinedSimpleProcessing.h StackFrameVector.h - graphProcessing.h graphProcessingSgIncGraph.h graphTemplate.h + #graphProcessing.h + #graphProcessingSgIncGraph.h + #graphTemplate.h AstSharedMemoryParallelProcessing.h AstSharedMemoryParallelProcessingImpl.h AstSharedMemoryParallelSimpleProcessing.h - SgGraphTemplate.h TreeTraversal.h) + #SgGraphTemplate.h + TreeTraversal.h) if(NOT WIN32) #tps commented out AstSharedMemoryParallelProcessing.h for Windows diff --git a/src/midend/astProcessing/SgGraphTemplate.h b/src/midend/astProcessing/SgGraphTemplate.h deleted file mode 100644 index 9429026a6b4..00000000000 --- a/src/midend/astProcessing/SgGraphTemplate.h +++ /dev/null @@ -1,201 +0,0 @@ -#include -#include -//#include -#include -#include -#include -struct Vertex{ - SgGraphNode* sg; - CFGNode cfgnd; -}; - -struct Edge { - SgDirectedGraphEdge* gedge; -}; - -typedef boost::adjacency_list< - boost::vecS, - boost::vecS, - boost::bidirectionalS, - Vertex, - Edge -> myGraph; - -typedef myGraph::vertex_descriptor VertexID; -typedef myGraph::edge_descriptor EdgeID; - -//myGraph* instantiateGraph(SgIncidencedDirectedGraph* g, StaticCFG::CFG cfg); -std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start); -std::map getGraphNode; -std::map VSlink; - -myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::InterproceduralCFG& cfg, SgNode* pstart) { - //SgNode* prestart = cfg.getEntry(); - //cfg.buildFullCFG(); - CFGNode startN = cfg.getEntry(); - SgGraphNode* start = cfg.toGraphNode(startN); - ROSE_ASSERT(startN != NULL); - ROSE_ASSERT(start != NULL); - myGraph* graph = new myGraph; - //std::map VSlink; - std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); - std::vector nods = alledsnds.first; - std::vector eds = alledsnds.second; - std::set > prs; - //for (std::vector i = nods.begin(); i != nods.end(); i++) { - // VertexID vID = boost::add_vertex(graph); - // graph[vID].cfgnd = cfg->toCFGNode(*i); - //} - for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { - SgDirectedGraphEdge* u = *j; - SgGraphNode* u1 = u->get_from(); - SgGraphNode* u2 = u->get_to(); - VertexID v1; - VertexID v2; - if (VSlink.find(u1) == VSlink.end()) { - v1 = boost::add_vertex(*graph); - getGraphNode[v1] = u1; - VSlink[u1] = v1; - (*graph)[v1].sg = u1; - (*graph)[v1].cfgnd = cfg.toCFGNode(u1); - } - else { - v1 = VSlink[u1]; - } - if (VSlink.find(u2) != VSlink.end()) { - v2 = VSlink[u2]; - } - else { - v2 = boost::add_vertex(*graph); - VSlink[u2] = v2; - (*graph)[v2].sg = u2; - getGraphNode[v2] = u2; - (*graph)[v2].cfgnd = cfg.toCFGNode(u2); - } - bool ok; - EdgeID uE; - std::pair pr; - pr.first = v1; - pr.second = v2; - if (prs.find(pr) == prs.end()) { - prs.insert(pr); - boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); - } - } - //std::cout << "prs.size: " << prs.size() << std::endl; - return graph; -} - - - -myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::CFG& cfg) { - SgGraphNode* start = cfg.getEntry(); - myGraph* graph = new myGraph; - //std::map VSlink; - std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); - std::vector nods = alledsnds.first; - std::vector eds = alledsnds.second; - std::set > prs; - //for (std::vector i = nods.begin(); i != nods.end(); i++) { - // VertexID vID = boost::add_vertex(graph); - // graph[vID].cfgnd = cfg->toCFGNode(*i); - //} - for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { - SgDirectedGraphEdge* u = *j; - SgGraphNode* u1 = u->get_from(); - SgGraphNode* u2 = u->get_to(); - VertexID v1; - VertexID v2; - if (VSlink.find(u1) == VSlink.end()) { - v1 = boost::add_vertex(*graph); - getGraphNode[v1] = u1; - VSlink[u1] = v1; - (*graph)[v1].sg = u1; - (*graph)[v1].cfgnd = cfg.toCFGNode(u1); - } - else { - v1 = VSlink[u1]; - } - if (VSlink.find(u2) != VSlink.end()) { - v2 = VSlink[u2]; - } - else { - v2 = boost::add_vertex(*graph); - VSlink[u2] = v2; - (*graph)[v2].sg = u2; - getGraphNode[v2] = u2; - (*graph)[v2].cfgnd = cfg.toCFGNode(u2); - } - bool ok; - EdgeID uE; - std::pair pr; - pr.first = v1; - pr.second = v2; - if (prs.find(pr) == prs.end()) { - prs.insert(pr); - boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); - } - } - //std::cout << "prs.size: " << prs.size() << std::endl; - return graph; -} - - - - -std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start) { - //for (int i = 0; i < starts.size(); i++) { - SgGraphNode* n = start; - std::vector nods; - std::vector newnods; - std::set edsnew; - std::vector eds; - std::vector feds; - std::vector fnods; - std::set > prs; - std::set oeds = g->computeEdgeSetOut(start); - fnods.push_back(start); - newnods.push_back(n); - - while (oeds.size() > 0) { - for (std::set::iterator j = oeds.begin(); j != oeds.end(); j++) { - //if (find(eds.begin(), eds.end(), *j) == eds.end()) { - if (find(feds.begin(), feds.end(), *j) == feds.end()) { - feds.push_back(*j); - edsnew.insert(*j); - } - if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { - fnods.push_back((*j)->get_to()); - } - newnods.push_back((*j)->get_to()); - //} - } - - for (unsigned int i = 0; i < newnods.size(); i++) { - std::set oedsp = g->computeEdgeSetOut(newnods[i]); - for (std::set::iterator j = oedsp.begin(); j != oedsp.end(); j++) { - if (find(feds.begin(), feds.end(), *j) == feds.end()) { - // feds.push_back(*j); - edsnew.insert(*j); - - } - //if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { - // fnods.push_back((*j)->get_to()); - // newnods.push_back((*j)->get_to()); - // } - // newnods.push_back((*j)->get_to()); - } - } - nods = newnods; - oeds = edsnew; - edsnew.clear(); - newnods.clear(); - } - std::pair, std::vector > retpr; - retpr.first = fnods; - retpr.second = feds; - //std::cout << "fnods.size()" << fnods.size() << std::endl; - //std::cout << "feds.size()" << feds.size() << std::endl; - return retpr; -} - diff --git a/src/midend/astProcessing/graphProcessing.h b/src/midend/astProcessing/graphProcessing.h deleted file mode 100644 index 07cdbd35235..00000000000 --- a/src/midend/astProcessing/graphProcessing.h +++ /dev/null @@ -1,1560 +0,0 @@ -/* - -FINISH TEMPFLATPATH CODE - -AS WRITTEN, THESE FUNCTIONS WILL ONLY WORK WITH GRAPHS THAT ARE IMPLEMENTED IN THE boost NAMESPACE. - -*/ - - - - -#define LP 1 -#define PERFDEBUG 0 -//#define FULLDEBUG 1 -#ifdef _OPENMP -#include -#endif -#include -#include -#include -#include -#include -#include - -/** -*@file graphProcessing.h - -*Brief Overview of Algorithm: - -*********************** -*Current Implementation -*********************** - -*This implementation uses BOOSTs graph structure to analyze the paths of the graph - -*The path analyzer sends the user paths to be evaluated by the "analyzePath" function that is user defined - -************************** -*Further Improvements: TODO -************************** - -@todo utilize BOOST visitors to take advantage of the BOOST graph structures abilities - -*************** -*Contact Info -*************** - -*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed - -*if I'm still at Lawrence -*hoffman34 AT llnl DOT gov -*@author Michael Hoffman -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -#include -#include -#include -#include -#include -#include -#include - - - - - - -template -class SgGraphTraversal -{ -public: - - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits:: edge_descriptor Edge; - - void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); - virtual void analyzePath(std::vector& pth) = 0; - std::vector getInEdges(int& node, CFG*& g); - std::vector getOutEdges(int& node, CFG*& g); - int getTarget(int& n, CFG*& g); - int getSource(int& n, CFG*& g); - std::map vertintmap; - std::map edgeintmap; - std::map intvertmap; - std::map intedgemap; - SgGraphTraversal(); - virtual ~SgGraphTraversal(); - SgGraphTraversal( SgGraphTraversal &); - SgGraphTraversal &operator=( SgGraphTraversal &); - int pathnum; - - - void firstPrepGraph(CFG*& g); - -private: - - int normals; - int abnormals; - bool needssafety; - int recursed; - int checkedfound; - // typedef typename boost::graph_traits::vertex_descriptor Vertex; - // typedef typename boost::graph_traits:: edge_descriptor Edge; - // std::vector getInEdges(int& node, CFG*& g); - // std::vector getOutEdges(int& node, CFG*& g); - void prepareGraph(CFG*& g); - void findClosuresAndMarkersAndEnumerate(CFG*& g); - // void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); - // virtual void analyzePath(std::vector& pth) = 0; - // void firstPrepGraph(CFG*& g); - int stoppedpaths; - std::set > traversePath(int begin, int end, CFG*& g, bool loop=false); - std::set > uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& localLoops); - std::vector > bfsTraversePath(int begin, int end, CFG*& g, bool loop=false); - std::vector unzipPath(std::vector& path, CFG*& g, int start, int end); - std::vector zipPath(std::vector& path, CFG*& g, int start, int end); - std::vector zipPath2(std::vector& path, CFG*& g); - void printCFGNode(int& cf, std::ofstream& o); - void printCFGNodeGeneric(int& cf, std::string prop, std::ofstream& o); - void printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o); - void printHotness(CFG*& g); - void printPathDot(CFG*& g); - void computeOrder(CFG*& g, const int& begin); - void computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential); - //int getTarget(int& n, CFG*& g); - //int getSource(int& n, CFG*& g); - std::vector sources; - std::vector sinks; - std::vector recursiveLoops; - std::vector recurses; - std::map ptsNum; - bool borrowed; - std::set badloop; - std::map > > totalLoops; -// int pathnum; - std::map nodeStrings; - int sourcenum; - unsigned long long evaledpaths; - int badpaths; - int workingthreadnum; - bool workingthread; - std::map > > loopStore; - std::vector > pathStore; - std::map > subpathglobal; - std::map, int> subpathglobalinv; - int nextsubpath; - std::vector orderOfNodes; -// std::map vertintmap; -// std::map edgeintmap; -// std::map intvertmap; -// std::map intedgemap; - std::vector > SubGraphGraphMap; - std::vector > GraphSubGraphMap; - std::vector subGraphVector; - void getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath ); - void storeCompact(std::vector path); - int nextNode; - int nextEdge; - std::vector markers; - std::vector closures; - std::map markerIndex; - std::map > pathsAtMarkers; - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::edge_iterator edge_iterator; - bool bound; -// SgGraphTraversal(); -// virtual ~SgGraphTraversal(); -// SgGraphTraversal( SgGraphTraversal &); -// SgGraphTraversal &operator=( SgGraphTraversal &); - - -}; - - -template -SgGraphTraversal:: -SgGraphTraversal() -{ -} - - - -template -SgGraphTraversal & -SgGraphTraversal:: -operator=( SgGraphTraversal &other) -{ - return *this; -} - -#ifndef SWIG - -template -SgGraphTraversal:: -~SgGraphTraversal() -{ -} - -#endif - -/** - Gets the source of an edge - SgGraphTraversal::getSource - Input: - @param[edge] int& integer representation of edge in question - @param[g] CFG*& the CFG used -*/ -template -inline int -SgGraphTraversal:: -getSource(int& edge, CFG*& g) -{ - Edge e = intedgemap[edge]; - Vertex v = boost::source(e, *g); - return(vertintmap[v]); -} - -/** - Gets the target of an edge - SgGraphTraversal::getTarget - Input: - @param[edge] int& integer representation of edge in quesution - @param[g] the CFG*& CFG used -*/ - - -template -inline int -SgGraphTraversal:: -getTarget(int& edge, CFG*& g) -{ - Edge e = intedgemap[edge]; - Vertex v = boost::target(e, *g); - return(vertintmap[v]); -} - -/** -Gets out edges with integer inputs, internal use only -SgGraphTraversal::getInEdges -Input: -@param[node] int, integer representation of the node to get the in edges from -@param[g] CFG* g, CFG -*/ - -template -std::vector -SgGraphTraversal:: -getInEdges(int& node, CFG*& g) -{ - Vertex getIns = intvertmap[node]; - std::vector inedges; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - in_edge_iterator i, j; -#else - // This does not compile. - in_edge_iterator i = inedges.begin(); - in_edge_iterator j = i; -#endif - for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i) - { - inedges.push_back(edgeintmap[*i]); - } - return inedges; -} - -/** -Gets out edges with integer inputs, internal use only -SgGraphTraversal::getOutEdges -Input: -@param[node] int, integer representation of the node to get the out edges from -@param[g] CFG* g, CFG -*/ - - - -template -std::vector -SgGraphTraversal:: -getOutEdges(int &node, CFG*& g) -{ - Vertex getOuts = intvertmap[node]; - std::vector outedges; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - out_edge_iterator i, j; -#else - // This does not compile. - out_edge_iterator i = outedges.begin(); - out_edge_iterator j = i; -#endif - for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i) - { - outedges.push_back(edgeintmap[*i]); - } - return outedges; -} - -/** -Condenses paths, currently deprecated... -Input: -@param[pth] std::vector the original path -@param[g] CFG*, the ambient graph -Output: -zipped path -*/ - -template -inline -std::vector -SgGraphTraversal:: -zipPath2(std::vector& pth, CFG*& g) { - std::vector npth; - npth.push_back(pth[0]); - for (int i = 1; i < pth.size()-1; i++) { - if (find(closures.begin(), closures.end(), pth[i]) != closures.end()) { - npth.push_back(pth[i]); - } - } - npth.push_back(pth.back()); - return npth; -} - -/** -Condenses paths to simply the first and last node and the ordered set of edges -taken at nodes with more than 1 outedge -Input: -@param[pth] std::vector, the original path -@param[g] CFG*, the ambient graph -@param[start] integer representation of the first node -@param[end] integer representation of the last node -*/ - - -template -std::vector -SgGraphTraversal:: -zipPath(std::vector& pth, CFG*& g, int start, int end) { - std::vector subpath; - std::vector movepath; - movepath.push_back(pth.front()); - movepath.push_back(pth.back()); - for (unsigned int qw = 0; qw < pth.size()-1; qw++) { - if (find(markers.begin(), markers.end(), pth[qw]) != markers.end()) { - std::vector oeds = getOutEdges(pth[qw], g); - for (unsigned int i = 0; i < oeds.size(); i++) { - if (getTarget(oeds[i], g) == pth[qw+1]) { - movepath.push_back(oeds[i]); - } - } - } - } - return movepath; - } - - - - - - -/** -unzips the paths zipped by zipPath -Input: -@param[pzipped] the zipped path -@param[CFG] the ambient graph -@param[start] the integer representation of the first node (used to check that zipPath is working correctly) -@param[end] the integer representation of the end node -*/ - - -template -std::vector -SgGraphTraversal:: -unzipPath(std::vector& pzipped, CFG*& g, int start, int end) { - ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1)); - std::vector zipped; - for (unsigned int i = 2; i < pzipped.size(); i++) { - zipped.push_back(pzipped[i]); - } - std::vector unzipped; - unzipped.push_back(start); - std::vector oeds = getOutEdges(start, g); - if (oeds.size() == 0) { - return unzipped; - } - for (unsigned int i = 0; i < zipped.size(); i++) { - oeds = getOutEdges(unzipped.back(), g); - while (oeds.size() == 1) { - if (getTarget(oeds[0], g) == end && unzipped.size() != 1) { - unzipped.push_back(end); - return unzipped; - } - unzipped.push_back(getTarget(oeds[0], g)); - oeds = getOutEdges(unzipped.back(), g); - } - if (oeds.size() == 0) { - return unzipped; - } - if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) { - ROSE_ASSERT(getSource(zipped[i], g) == unzipped.back()); - unzipped.push_back(getTarget(zipped[i], g)); - } - - } - std::vector oeds2 = getOutEdges(unzipped.back(), g); - if (unzipped.back() != end && oeds2.size() != 0) { - while (oeds2.size() == 1 && unzipped.back() != end) { - unzipped.push_back(getTarget(oeds2[0], g)); - oeds2 = getOutEdges(unzipped.back(), g); - } - } - return unzipped; -} - -/* -Example Time - - Example: - timeval tim; - gettimeofday(&tim, NULL); - double t1=tim.tv_sec+(tim.tv_usec/1000000.0); - do_something_long(); - gettimeofday(&tim, NULL); - double t2=tim.tv_sec+(tim.tv_usec/1000000.0); - printf("%.6lf seconds elapsed\n", t2-t1); - -*/ - -/** -The function responsible for collecting all paths without loops, and all paths within lops that do not include other loops -then sending those to uTraverse to assemble them into all paths with any combination of loops -Input: -@param[begin] integer representation of the first node -@param[end] integer representation of the last node (or -1 if its not bounded) -@param[g] CFG*, the ambient CFG -@param[loop] boolean expressing whether or not we are calculating paths contained within a loop -*/ - - -template -std::vector > -SgGraphTraversal:: -bfsTraversePath(int begin, int end, CFG*& g, bool loop) { -//perfdebug allows for examining the speed of traversal - #ifdef PERFDEBUG - //timeval tim; - //gettimeofday(&tim, NULL); - //double tim1 = tim.tv_sec+(tim.tv_usec/1000000.0); - #endif - bool recursedloop = loop; - std::map > > PtP; - std::set nodes; - std::vector > pathContainer; - //std::vector > oldPaths; - std::vector completedLoops; - std::vector > npc; - std::vector bgpath; - bgpath.push_back(begin); - pathContainer.push_back(bgpath); - std::vector > newPathContainer; - std::vector > paths; - std::vector localLoops; - std::map > > globalLoopPaths; - //std::cout << "at the while" << std::endl; -//To keep - while (pathContainer.size() != 0 /*|| oldPaths.size() != 0*/) { -/* - unsigned int mpc = 50000; - if (pathContainer.size() == 0) { - unsigned int mxl = 0; - if (oldPaths.size() > mpc) { - mxl = mpc/2; - } - else { - mxl = oldPaths.size(); - } - for (unsigned int k = 0; k < mxl; k++) { - pathContainer.push_back(oldPaths.back()); - oldPaths.pop_back(); - } - } - if (pathContainer.size() > mpc) { - unsigned int j = 0; - while (j < mpc) { - npc.push_back(pathContainer.back()); - pathContainer.pop_back(); - j++; - } - oldPaths.insert(oldPaths.end(), pathContainer.begin(), pathContainer.end()); - pathContainer = npc; - npc.clear(); - } -*/ - -//iterating through the currently discovered subpaths to build them up - for (unsigned int i = 0; i < pathContainer.size(); i++) { - std::vector npth = pathContainer[i]; - std::vector oeds = getOutEdges(npth.back(), g); - std::vector ieds = getInEdges(npth.back(), g); - - npth = pathContainer[i]; - oeds = getOutEdges(npth.back(), g); - - if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) { - std::vector newpth; - newpth = (pathContainer[i]); - std::vector movepath = newpth;//zipPath(newpth, g); - if (recursedloop && newpth.back() == end && newpth.size() != 1) { - paths.push_back(movepath); - } - else if (!recursedloop) { - if (bound && newpth.size() != 1 && newpth.back() == end) { - paths.push_back(movepath); - } - else if (!bound) { - paths.push_back(movepath); - } - } - - } - else { -std::vector oeds = getOutEdges(pathContainer[i].back(), g); - - for (unsigned int j = 0; j < oeds.size(); j++) { - - -int tg = getTarget(oeds[j], g); - - - std::vector newpath = (pathContainer[i]); - //we split up paths into pieces so that they don't take up a lot of memory, basically this is when we run into a path - //more than once, so we attach all paths that go to that path to that particular node via PtP - if (nodes.find(tg) != nodes.end() && find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) { - if (PtP.find(tg) == PtP.end()) { - std::vector nv; - nv.push_back(tg); - newPathContainer.push_back(nv); - PtP[tg].push_back(/*zipPath(*(*/newpath);//, g, newpath.front(), newpath.back())); - } - else { - PtP[tg].push_back(/*zipPath(*/newpath);//, g, newpath.front(), newpath.back())); - } - } - else if (find(newpath.begin(), newpath.end(), getTarget(oeds[j], g)) == newpath.end() || getTarget(oeds[j], g) == end) { - newpath.push_back(tg); - std::vector ieds = getInEdges(tg, g); - if (ieds.size() > 1) {//find(closures.begin(), closures.end(), tg) != closures.end()) { - nodes.insert(tg); - } - newPathContainer.push_back(newpath); - } - else if (tg == end && recursedloop) { - newpath.push_back(tg); - newPathContainer.push_back(newpath); - } - else {//if (find(newpath.begin(), newpath.end(), tg) != newpath.end() && tg != end) { - std::vector ieds = getInEdges(tg, g); - if (ieds.size() > 1/*find(closures.begin(), closures.end(), tg) != closures.end()*/ && find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() /*&& find(localLoops.begin(), localLoops.end(), tg) == localLoops.end()*/ && find(recurses.begin(), recurses.end(), tg) == recurses.end()) { - localLoops.push_back(tg); - nodes.insert(tg); - } - // else if (find(recurses.begin(), recurses.end(), tg) != recurses.end()) { - // } - } - //else { - // std::cout << "problem" << std::endl; - // ROSE_ASSERT(false); - // } - } - } - } - pathContainer = newPathContainer; - newPathContainer.clear(); - } - // std::cout << "done while" << std::endl; - pathContainer.clear(); - std::vector > finnpts; - std::vector > npts; - while (true) { - if (paths.size() > 1000000) { - std::cout << "too many paths, consider a subgraph" << std::endl; - ROSE_ABORT(); - } - //#pragma omp parallel for schedule(guided) - for (unsigned int qq = 0; qq < paths.size(); qq++) { - std::vector pq = paths[qq]; - std::vector qp; - int ppf = paths[qq].front(); - if (PtP.find(ppf) != PtP.end()) { - for (unsigned int kk = 0; kk < PtP[ppf].size(); kk++) { - std::vector newpath = /*unzipPath(*/PtP[ppf][kk];//, g, PtP[ppf][kk][0], PtP[ppf][kk][1]); - bool good = true; - if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) { - good = false; - } - else { - - // if (find(pq.begin(), pq.end(), newpath.front()) != pq.end() && newpath.front() != begin) { - // good = false; - // } - - - // else { - for (unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) { - - /* - if (newpath.front() == newpath.back()) { - good = false; - break; - } - else */if (find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) { - good = false; - break; - - } - } - //} - } - if (good) { - newpath.insert(newpath.end(), pq.begin(), pq.end()); - #pragma omp critical - { - npts.push_back(newpath); - } - } - } - } - else { - std::vector ppq = pq;// zipPath(pq, g, pq.front(), pq.back()); - #pragma omp critical - { - finnpts.push_back(ppq); - } - } - } - if (npts.size() == 0) { - break; - } - else { - paths = npts; - npts.clear(); - } - } - paths = finnpts; - finnpts.clear(); - for (unsigned int k = 0; k < localLoops.size(); k++) { - int lk = localLoops[k]; - std::vector > loopp; - if (loopStore.find(localLoops[k]) != loopStore.end()) { - loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end()); - } - else { - std::map > > localLoopPaths; - completedLoops.push_back(lk); - recurses.push_back(lk); - loopp = bfsTraversePath(lk, lk, g, true); - recurses.pop_back(); - } - for (unsigned int ik = 0; ik < loopp.size(); ik++) { - - if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) { - globalLoopPaths[localLoops[k]].push_back(loopp[ik]); - } - } - - - - } - borrowed = true; - std::vector > lps2; - //unsigned int maxpaths = 1000; - //unsigned int pathdivisor = 1;//paths.size()/maxpaths;///paths.size(); - - //if (pathdivisor < 1) { - //pathdivisor = 1; - //maxpaths = paths.size(); - // } -/* - for (unsigned int j = 0; j < pathdivisor+1; j++) { - std::vector > npaths; - std::vector dummyvec; - unsigned int mxpths; - if (j < pathdivisor) { - mxpths = maxpaths; - } - else { - mxpths = paths.size() % pathdivisor; - } - for (unsigned int k = 0; k < mxpths; k++) { - npaths.push_back(paths.back());//unzipPath(paths.back(), g, begin, end)); - paths.pop_back(); - } -*/ - pathStore = paths; - paths.clear(); - if (!recursedloop) { - uTraversePath(begin, end, g, false, globalLoopPaths); - } - else { - recursed++; - - std::set > lps = uTraversePath(begin, end, g, true, globalLoopPaths); - recursed--; - for (std::set >::iterator ij = lps.begin(); ij != lps.end(); ij++) { - std::vector ijk = (*ij); - - lps2.push_back(*ij); - } - } - //} - #ifdef PERFDEBUG - // timeval tim; - //std::cout << "begin: " << begin << " end: " << end << std::endl; - //gettimeofday(&tim, NULL); - //double tim2 = tim.tv_sec+(tim.tv_usec/1000000); - //double timeRet = tim2 - tim1; - //std::cout << "bfs time elapsed: " << timeRet << std::endl; - #endif - return lps2; - -} - - -/** -This function calculates all the permutations of loops on paths -it also throws away duplicate paths -Input: -@param[begin] integer representation of first node -@param[end] integer representation of the final node -@param[g] ambient CFG -@param[globalLoopPaths] connects an integer representation of a node to all possible loops starting at that node -*/ - - -template -std::set > -SgGraphTraversal:: -uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& globalLoopPaths) { - //std::cout << "uTraverse" << std::endl; - //int doubledpaths = 0; - int newmil = 1; - //#ifdef LP - //if (loop && loopStore.find(begin) != loopStore.end()) { - // return loopStore[begin]; - //} - //#endif - #ifdef PERFDEBUG - //timeval tim; - //gettimeofday(&tim, NULL); - //double t1 = tim.tv_sec+(tim.tv_usec/1000000); - #endif - std::set > newpaths; - std::set > npaths; - pathnum = 0; - std::vector path; - std::vector > paths; - int truepaths = 0; - std::vector > checkpaths; - std::vector > npathchecker; - std::map currents; - //int nnumpaths = 0; - std::set > loopPaths; - //bool threadsafe = true; - bool done = false; - std::set > fts; - //double ttfors = 0; - //double tperms = 0; - while (true) { - //std::cout << "paths.size() " << paths.size() << std::endl; - if (paths.size() > 1000000) { - std::cout << "nearly 1 million paths with no loops, stopping" << std::endl; - return loopPaths; - std::cout << "ended early" << std::endl; - } - if (done || borrowed) { - - if (borrowed) { - paths = pathStore; - pathStore.clear(); - } - //std::cout << "paths.size(): " << paths.size() << std::endl; - if (paths.size() != 0) { - } - else { - return loopPaths; - } - - // #pragma omp parallel - // { - #pragma omp parallel for schedule(guided) - for (unsigned int qqq = 0; qqq < paths.size(); qqq++) { - // std::cout << "pathcheck" << std::endl; - //int pathevals = 0; - //std::vector zpt = zipPath2(paths[qqq], g); - //std::set > boxpaths; - std::set > movepaths; - std::vector path;// = paths[qqq]; - path = paths[qqq];//unzipPath(paths[qqq], g, begin, end); - truepaths++; - int permnums = 1; - std::vector perms; - std::vector qs; - std::map > > localLoops; - std::vector takenLoops; - takenLoops.push_back(path[0]); - bool taken = false; - //timeval timfor; - int lost = 0; - //gettimeofday(&timfor, NULL); - //double t1for = timfor.tv_sec + (timfor.tv_usec/1000000); - for (unsigned int q = 1; q < path.size()-1; q++) { - //if (find(closures.begin(), closures.end(), path[q]) != closures.end()) { - if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() /*&& find(lloops.begin(), lloops.end(), path[q]) != lloops.end()*/ && globalLoopPaths[path[q]].size() != 0 /*&& path[q] != begin && path[q] != end*/) { - for (unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) { - - std::vector gp = globalLoopPaths[path[q]][qp1]; //unzipPath(globalLoopPaths[path[q]][qp1],g,path[q],path[q]); - // std::vector zgp = zipPath2(globalLoopPaths[zpt[q]][qp1], g); - for (unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) { - if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) { - taken = true; - } - } - - if (!taken) { - localLoops[path[q]].push_back(gp); - } - else { - lost++; - taken = false; - } - } - if (localLoops[path[q]].size() != 0) { - takenLoops.push_back(path[q]); - permnums *= (localLoops[path[q]].size()+1); - perms.push_back(permnums); - qs.push_back(path[q]); - } - } - } - - //} - //if (loop) { - //std::cout << "lostloop: " << lost << std::endl; - //} - //else { - //std::cout << "lostpath: " << lost << std::endl; - //} - //std::cout << "endpathcheck" << std::endl; - //std::cout << "rest" << std::endl; - //std::cout << "permnums: " << permnums << std::endl; - //gettimeofday(&timfor, NULL); - //double t2for = timfor.tv_sec + (timfor.tv_usec/1000000); - //double ttfor = t2for - t1for; - //#pragma omp atomic - //ttfors += ttfor; - - //std::set > movepaths2; - std::set > movepathscheck; - //timeval timperms; - //gettimeofday(&timperms, NULL); - // double t1perm = timperms.tv_sec + (timperms.tv_usec/1000000); - std::vector nvec; - std::vector > boxpaths(permnums, nvec); - //#pragma omp parallel for schedule(guided) - for (int i = 1; i <= permnums; i++) { - //bool goodthread = false; - std::vector loopsTaken; - //bool stop = false; - unsigned int j = 0; - std::vector npath; - while (true) { - if (j == perms.size() || perms[j] > i) { - break; - } - else { - j++; - } - } - int pn = i; - std::vector pL; - for (unsigned int j1 = 0; j1 <= j; j1++) { - pL.push_back(-1); - } - for (unsigned int k = j; k > 0; k--) { - int l = 1; - while (perms[k-1]*l < pn) { - l++; - } - pL[k] = l-2; - pn -= (perms[k-1]*(l-1)); - } - pL[0] = pn-2; - - unsigned int q2 = 0; - for (unsigned int q1 = 0; q1 < path.size(); q1++) { - if (q2 < qs.size()) { - if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (size_t)q2 != pL.size()) { - if (pL[q2] == -1) { - npath.push_back(path[q1]); - } - else { - // if (!stop) { - npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(), - localLoops[path[q1]][pL[q2]].end()); - // } - } - q2++; - } - else { - npath.push_back(path[q1]); - } - } - else { - npath.push_back(path[q1]); - } - } - #ifdef FULLDEBUG - std::cout << "path: " << std::endl; - for (int qe = 0; qe < npath.size(); qe++) { - std::cout << ", " << npath[qe]; - } - std::cout << std::endl; - std::cout << "permnum: " << i << std::endl; - #endif - // bool addit = false; - //if (!stop) { - // if (loop && npath.front() == npath.back()) { - // addit = true; - // } - // else if (!loop && bound && npath.front() == begin && npath.back() == end && npath.size() != 1) { - // addit = true; - // } - // else if (!loop && !bound) { - // addit = true; - // } - // if (!addit) { - // std::cout << "bad path" << std::endl; - // } - //bool extra = false; - //if (addit && !loop) { - //if (movepathscheck.find(npath) == movepathscheck.end()) { - //int mpc = movepathscheck.size(); - //std::set > movepathspre = movepathscheck; - // movepaths2.insert(npath); - //movepathscheck.insert(npath); - //ROSE_ASSERT(movepathscheck.size() == mpc || movepathspre.find(npath) == movepathspre.end()); - //if (movepathscheck.size() == mpc) { - // extra = true; - // } - - //} - //else { - //#pragma omp atomic - // doubledpaths++; - // } - //} - - //if (!workingthread || threadsafe) { - //if ((newpaths.size() > 1 || i == permnums || threadsafe)) { - // } - // } - - // } - //if (!extra) - // { - //if (movepaths2.size() > 0) //|| i == permnums || threadsafe) - // #pragma omp critical - // { - boxpaths[i-1] = npath; - // } - // } - //std::cout << "endrest" << std::endl; - } - - evaledpaths += boxpaths.size(); - if (evaledpaths > newmil*100000ull) { - //std::cout << "evaledpaths: " << evaledpaths << std::endl; - newmil++; - } - // #pragma omp critical - // { - if (!loop) { - for (std::vector >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) { - std::vector verts; - getVertexPath((*box), g, verts); - #pragma omp critical - { - analyzePath(verts); - } - } - } - else { - #pragma omp critical - { - loopPaths.insert(boxpaths.begin(), boxpaths.end());; - } - } - } - } - //} - -/* - #pragma omp atomic - evaledpaths++; - //pathevals++; - if (evaledpaths % 10000 == 0 && evaledpaths != 0) { - std::cout << "evaled paths: " << evaledpaths << std::endl; - } - if (!loop) { - std::vector verts; - getVertexPath(npath, g, verts); - #pragma omp critical - { - #ifdef FULLDEBUG - for (unsigned int aa = 0; aa < npath.size(); aa++) { - if (ptsNum.find(npath[aa]) != ptsNum.end()) { - ptsNum[npath[aa]] += 1; - } - else { - ptsNum[npath[aa]] = 1; - } - } - #endif - analyzePath(verts); - } - } - else if (loop) - { - //std::vector zpth = zipPath(npath, g, npath.front(), npath.back()); - #pragma omp critical - { - loopPaths.insert(npath);//zipPath(npath, g, npath.front(), npath.back())); - } - } - else { - } - - } -*/ - - // movepaths2.clear(); - - // std::cout << "permnums: " << permnums << std::endl; - // std::cout << "evaledpaths final: " << pathevals << std::endl; - //gettimeofday(&timperms, NULL); - //double t2perm = timperms.tv_sec+(timperms.tv_usec/1000000); - //#pragma omp atomic - //tperms += t2perm - t1perm; - // } - //} - //} - //} - - - - - - - #ifdef PERFDEBUG - //gettimeofday(&tim, NULL); - // double t2 = tim.tv_sec+(tim.tv_usec/1000000.0); - // double tperm = t2 - t1perm - //double tX = t2 - t1; - //std::cout << "begin: " << begin << " end: " << end << std::endl; - // std::cout << "uTraverse time: " << tX << std::endl; - // std::cout << "tperms: " << tperms << std::endl; - // std::cout << "ttfors: " << ttfors << std::endl; - // std::cout << "doubledpaths: " << doubledpaths << std::endl; - #endif - #ifdef LP - if (loop) { - #ifdef PERFDEBUG - // std::cout << "loopPaths: " << loopPaths.size() << std::endl; - #endif - loopStore[begin] = loopPaths; - } - #endif - return loopPaths; - - } - } - - - - - - - - -/** -This is the function that is used by the user directly to start the algorithm. It is immediately available to the user - -SgGraphTraversal::constructPathAnalyzer -Input: -@param[begin] Vertex, starting node -@param[end] Vertex, endnode -@param[g] CFG* g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -constructPathAnalyzer(CFG* g, bool unbounded, Vertex begin, Vertex end, bool ns) { - abnormals = 0; - normals = 0; - if (ns) { - needssafety = true; - } - else { - needssafety = false; - } - checkedfound = 0; - recursed = 0; - nextsubpath = 0; - borrowed = true; - stoppedpaths = 0; - evaledpaths = 0; - badpaths = 0; - sourcenum = 0; - prepareGraph(g); - workingthread = false; - workingthreadnum = -1; - //std::cout << "markers: " << markers.size() << std::endl; - //std::cout << "closures: " << closures.size() << std::endl; - //std::cout << "sources: " << sources.size() << std::endl; - //std::cout << "sinks" << sinks.size() << std::endl; -// printHotness(g); - bool subgraph = false; - if (!subgraph) { - if (!unbounded) { - bound = true; - recursiveLoops.clear(); - recurses.clear(); - std::vector > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g); - // std::cout << "spaths: " << spaths.size() << std::endl; - } - else { - std::set usedsources; - bound = false; - std::vector localLps; - for (unsigned int j = 0; j < sources.size(); j++) { - sourcenum = sources[j]; - recursiveLoops.clear(); - recurses.clear(); - std::vector > spaths = bfsTraversePath(sources[j], -1, g); - - - } - } - } - //std::cout << "checkedfound: " << checkedfound << std::endl; - printHotness(g); -} - -/** DEPRECATED -This is a function to construct subgraphs for parallelization -SgGraphTraversal::computeSubGraphs -Input: -@param[begin] const int, starting point -@param[end] const int ending point -@param[g] const CFG*, control flow graph to compute -@param[depthDifferential] int, used to specify how large the subgraph should be - */ - -template -void -SgGraphTraversal:: -computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential) { - int minDepth = 0; - int maxDepth = minDepth + depthDifferential; - int currSubGraph = 0; - CFG* subGraph; - std::set foundNodes; - while (true) { - Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]); - GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin]; - SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]]; - for (int i = minDepth; i <= maxDepth; i++) { - Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]]; - std::vector outEdges = getOutEdges(orderOfNodes[i], g); - for (unsigned int j = 0; j < outEdges.size(); j++) { - Vertex u; - if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) { - u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]]; - } - else { - u = boost::add_vertex(*subGraphVector[currSubGraph]); - foundNodes.insert(getTarget(outEdges[j], g)); - SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)]; - GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u; - - } - Edge edge; - bool ok; - boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]); - } - } - minDepth = maxDepth; - if ((unsigned int) minDepth == orderOfNodes.size()-1) { - break; - } - maxDepth += depthDifferential; - if ((unsigned int) maxDepth > orderOfNodes.size()-1) - { - maxDepth = orderOfNodes.size()-1; - } - CFG* newSubGraph; - subGraphVector.push_back(newSubGraph); - currSubGraph++; - } - return; -} - - -/* -These should NOT be used by the user. They are simply for writing interesting information on the DOT graphs of the CFG -*/ - - - - template - void - SgGraphTraversal:: - printCFGNodeGeneric(int &cf, std::string prop, std::ofstream& o) { - std::string nodeColor = "black"; - o << cf << " [label=\"" << " num:" << cf << " prop: " << prop << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - } - - template - void - SgGraphTraversal:: - printCFGNode(int& cf, std::ofstream& o) - { - #ifdef FULLDEBUG - int pts = ptsNum[cf]; - std::string nodeColor = "black"; - o << cf << " [label=\"" << " pts: " << pts << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - #endif - #ifndef FULLDEBUG - std::string nodeColor = "black"; - o << cf << " [label=\"" << " num:" << cf << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - #endif - - } - - template - void - SgGraphTraversal:: - printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o) - { - int src = getSource(cf, cfg); - int tar = getTarget(cf, cfg); - o << src << " -> " << tar << " [label=\"" << src << " " << tar << "\", style=\"" << "solid" << "\"];\n"; - } - - template - void - SgGraphTraversal:: - printHotness(CFG*& g) - { - const CFG* gc = g; - int currhot = 0; - std::ofstream mf; - std::stringstream filenam; - filenam << "hotness" << currhot << ".dot"; - currhot++; - std::string fn = filenam.str(); - mf.open(fn.c_str()); - - mf << "digraph defaultName { \n"; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v, vend; - edge_iterator e, eend; -#else - // This does not compile. - vertex_iterator v = vertices(*gc).begin(); - vertex_iterator vend = v; - edge_iterator e = edges(*gc).begin(); - edge_iterator eend = e; -#endif - for (boost::tie(v, vend) = vertices(*gc); v != vend; ++v) - { - printCFGNode(vertintmap[*v], mf); - } - for (tie(e, eend) = edges(*gc); e != eend; ++e) - { - printCFGEdge(edgeintmap[*e], g, mf); - } - mf.close(); - } - template - void - SgGraphTraversal:: - printPathDot(CFG*& g) - { - const CFG* gc = g; - std::ofstream mf; - std::stringstream filenam; - filenam << "pathnums.dot"; - std::string fn = filenam.str(); - mf.open(fn.c_str()); - - mf << "digraph defaultName { \n"; - vertex_iterator v, vend; - edge_iterator e, eend; - for (tie(v, vend) = vertices(*gc); v != vend; ++v) - { - if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) { - int nn = vertintmap[*v]; - printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf); - } - else { - printCFGNodeGeneric(vertintmap[*v], "noprop", mf); - } - } - for (tie(e, eend) = edges(*gc); e != eend; ++e) - { - printCFGEdge(edgeintmap[*e], g, mf); - } - - mf.close(); - } - - - -/** -This is the function that preps the graph for traversal - -SgGraphTraversal::prepareGraph -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -prepareGraph(CFG*& g) { - nextNode = 1; - nextEdge = 1; - findClosuresAndMarkersAndEnumerate(g); -} - - -/** -DEPRECATED -This is the function that preps the graph for traversal, currently this one isn't used but for many traversals on one visitor -may necessitate - -SgGraphTraversal::firstPrepGraph -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -firstPrepGraph(CFG*& g) { - nextNode = 1; - nextEdge = 1; - findClosuresAndMarkersAndEnumerate(g); -} - -/** -This calculates nodes with more than one in edge or more than one out edge - -SgGraphTraversal::findClosuresAndMarkers -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - - - -template -void -SgGraphTraversal:: -findClosuresAndMarkersAndEnumerate(CFG*& g) -{ - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - edge_iterator e, eend; -#else - edge_iterator e = edges(*g).begin(); - edge_iterator eend = e; -#endif - for (tie(e, eend) = edges(*g); e != eend; ++e) { - intedgemap[nextEdge] = *e; - edgeintmap[*e] = nextEdge; - nextEdge++; - } - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v1, vend1; -#else - vertex_iterator v1 = vertices(*g).begin(); - vertex_iterator vend1 = v1; -#endif - for (boost::tie(v1, vend1) = vertices(*g); v1 != vend1; ++v1) - { - vertintmap[*v1] = nextNode; - intvertmap[nextNode] = *v1; - nextNode++; - } - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v, vend; -#else - vertex_iterator v = vertices(*g).begin(); - vertex_iterator vend = v; -#endif - for (boost::tie(v, vend) = vertices(*g); v != vend; ++v) { - std::vector outs = getOutEdges(vertintmap[*v], g); - std::vector ins = getInEdges(vertintmap[*v], g); - if (outs.size() > 1) - { - markers.push_back(vertintmap[*v]); - - markerIndex[vertintmap[*v]] = markers.size()-1; - for (unsigned int i = 0; i < outs.size(); i++) { - pathsAtMarkers[vertintmap[*v]].push_back(getTarget(outs[i], g)); - } - } - if (ins.size() > 1) - { - closures.push_back(vertintmap[*v]); - } - if (outs.size() == 0) { - sinks.push_back(vertintmap[*v]); - } - if (ins.size() == 0) { - sources.push_back(vertintmap[*v]); - } - } - return; -} - - - -/** DEPRECATED -Currently unused but will be necessary for parallelization in progress -SgGraphTraversal::computeOrder -@param[g] CFG* cfg in question -@parm[begin] const int, integer representation of source node -*/ -template -void -SgGraphTraversal:: -computeOrder(CFG*& g, const int& begin) { - std::vector currentNodes; - std::vector newCurrentNodes; - currentNodes.push_back(begin); - std::map reverseCurrents; - orderOfNodes.push_back(begin); - std::set heldBackNodes; - while (currentNodes.size() != 0) { - for (unsigned int j = 0; j < currentNodes.size(); j++) { - - std::vector inEdges = getInEdges(currentNodes[j], g); - if (inEdges.size() > 1) { - if (reverseCurrents.find(currentNodes[j]) == reverseCurrents.end()) { - reverseCurrents[currentNodes[j]] = 0; - } - if ((unsigned int) reverseCurrents[currentNodes[j]] == inEdges.size() - 1) { - heldBackNodes.erase(currentNodes[j]); - reverseCurrents[currentNodes[j]]++; - std::vector outEdges = getOutEdges(currentNodes[j], g); - for (unsigned int k = 0; k < outEdges.size(); k++) { - newCurrentNodes.push_back(getTarget(outEdges[k], g)); - orderOfNodes.push_back(getTarget(outEdges[k], g)); - } - } - else if (reverseCurrents[currentNodes[j]] < reverseCurrents.size()) { - reverseCurrents[currentNodes[j]]++; - if (heldBackNodes.find(currentNodes[j]) == heldBackNodes.end()) { - heldBackNodes.insert(currentNodes[j]); - } - } - } - else { - std::vector outEdges = getOutEdges(currentNodes[j], g); - for (unsigned int k = 0; k < outEdges.size(); k++) { - newCurrentNodes.push_back(getTarget(outEdges[k], g)); - orderOfNodes.push_back(getTarget(outEdges[k], g)); - - } - } - } - if (newCurrentNodes.size() == 0 && heldBackNodes.size() != 0) { - for (std::set::iterator q = heldBackNodes.begin(); q != heldBackNodes.end(); q++) { - int qint = *q; - std::vector heldBackOutEdges = getOutEdges(qint, g); - for (unsigned int p = 0; p < heldBackOutEdges.size(); p++) { - newCurrentNodes.push_back(getTarget(heldBackOutEdges[p], g)); - } - } - heldBackNodes.clear(); - } - currentNodes = newCurrentNodes; - newCurrentNodes.clear(); - } - return; -} - -/** -Converts the path calculated by this algorithm to Vertices so users can -access data -SgGraphTraversal::getVertexPath -@param[path] integer representation of path -@param[g] CFG*, cfg in question -@param[vertexPath] for some reason this can't be a return value so it is changed via pass by reference -*/ - -template -void -SgGraphTraversal:: -getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath) { - for (unsigned int i = 0; i < path.size(); i++) { - vertexPath.push_back(intvertmap[path[i]]); - } - - - -} - -/** -DEPRECATED -Currently unused, may eventually be modified for optimal storage purposes -SgGraphTraversal::storeCompact -@param[compactPath] path to be compactified -*/ -template -void -SgGraphTraversal:: -storeCompact(std::vector compactPath) { -return; -} - - - - - diff --git a/src/midend/astProcessing/graphProcessingSgIncGraph.h b/src/midend/astProcessing/graphProcessingSgIncGraph.h deleted file mode 100644 index 382dc09079d..00000000000 --- a/src/midend/astProcessing/graphProcessingSgIncGraph.h +++ /dev/null @@ -1,1865 +0,0 @@ -/* - -FINISH TEMPFLATPATH CODE - -*/ - - - - -// Original Author (SgGraphTraversal mechanisms): Michael Hoffman -//$id$ -#include -#include -#include -#include -#include - -/** -*@file graphProcessing.h - -*Brief Overview of Algorithm: - -*********************** -*Current Implementation -*********************** - -*The idea behind the algorithm here is to decompose the given Control Flow Graph into a Tree structure (still stored as a Control Flow Graph, though it may be possible to change this). This tree splits on children of a graph node, but does not connect in the case of multiple parents of a single node. In this we refer to out nodes as "children" and in nodes as "parents". However, we do this from the end node to the start node. This is best because then you get one value on the end node, and that value is the only one we want (however, the function takes a pointer to an empty SgIncidenceDirectedGraph as an argument, this can then be analyzed post traversal if that is wanted. - -*Also, following the algorithm explained above, one must realize that the tree has one leaf for EACH path. Thus small programs can lead from a small-ish graph to a VERY large tree. For example, a program with 20 if else statements would end with 2^20 paths, which means the number of nodes in the tree is greater than this. Thus with 32 or 64 you can overflow a 32 or 64 bit integer. - -*However, this can be partially resolved by setting the deleteTree boolean to true. This is set to false as the default, however if you don't need the tree then deleteTree will allow you to deal with much larger trees and thus much larger original graphs. - -*Realize that because of the potentially massive growth rate of path number, that in large cases path enumeration and counting is extremely prohibitive, as it is not difficult to create a program which has more paths than 2^64, thus an unsigned (signed?) 64 bit integer could not store the number. - -*Further, this is still a relatively compact method. You could just as easily force enumeration of paths, which could in some cases drastically increase the number of nodes necessary to store all the information. - -*The advantage of the tree structure is two-fold. First it relieves the algorithm of having to keep even more in memory than it has to at the moment, and if you want to deal with GoTo statements, one case can develop that cannot be solved otherwise, e.g. - -*Consider the four node tree with nodes a, b, c, d, and edges atb, atc, btc, ctb, btd, ctd. There are FOUR legitimate paths here (a, b, d; a, b, c, d; a, c, d; a, c, b, d), and any other method would recognize this as a loop and, without a special algorithm for loop behavior, this would be ignored. - -*The tree structure also allows for very strong parallelization, currently implemented in openMP. This is because depth has meaning in terms of a tree (it doesn't in terms of a general graph) and that you know you can evaluate all nodes at a certain depth if you have solved all the nodes at depth + 1. - -************************** -*Further Improvements: TODO -************************** - -@todo *One improvement that should be implemented ASAP is changing the algorithm from a recursive algorithm to an iterative algorithm. Keeping the memory requirements down is much easier in this form and would probably increase the size of graph that the algorithm can handle. - -@todo *Another improvement that should be implemented when possible is to allow for loop analysis. This could be implemented by simply running the algorithm on the loop, but there would need to be a provision that kept the algorithm from stopping as soon as it starts. This could be done by separating the node into two nodes, one with all the inedges and one with all the outedges. OR one could collect the loops when they are deleted (the whole loop is calculated necessarily), though nested loops would have to be considered further in order to find a way to deal with them. - -@todo *It is possible that graph matching algorithms might prove useful to distinguish different types of graphs contained within the CFG and optimize traversal over them. Look up graph matching algorithms or pattern matching (potentially) for more information on such algorithms, though I do not believe there is an existant literature on matching subgraphs for this purpose. - -@todo *The parallelism in this program should be optimized by someone experienced in parallelization optimization - -*************** -*Contact Info -*************** - -*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed - -*archangel DOT associate AT gmail DOT com -*or, if I'm still at Lawrence -*hoffman34 AT llnl DOT gov -*@author Michael Hoffman -*/ - - - - - -#include "staticCFG.h" -#include -#include -#include -#include -#include -#include -//#include "graphBot.h" - -//This is necessary for technical reasons with regards to the graphnodeinheritedmap - - - -struct Bot { - std::vector > path; - std::vector > pthloops; - std::vector currpth; - std::vector > nodelst; - bool on; - bool remove; -}; - -double timeDifference(const struct timeval& end, const struct timeval& begin) -{ - return (end.tv_sec + end.tv_usec / 1.0e6) - (begin.tv_sec + begin.tv_usec / 1.0e6); -} - -static inline timeval getCPUTime() { - rusage ru; - getrusage(RUSAGE_SELF, &ru); - return ru.ru_utime; -} - - -struct compareSgGraphNode { - bool operator()(const SgGraphNode* a, const SgGraphNode* b) const - { - return a==b; - } -}; - - -/* The SgGraphTraversal class is utilized specifically for StaticCFG traversals, -though the input must be in terms of a SgIncidenceDirectedGraph*/ -template -class SgGraphTraversal -{ - public: - std::set > > subpathmap; - int loopNum; - int nullNum; - std::set nullEdgesOrdered; - std::map loopNumMap; - std::map pathValMap; - int nullloops; - std::vector > looppaths; - std::vector > iLoops; - std::vector ifstatements; - virtual ~SgGraphTraversal(); - SgGraphTraversal(); - // Copy operations - int nullEdgesPaths; - int turns; - SgGraphTraversal(const SgGraphTraversal &); - const SgGraphTraversal &operator=(const SgGraphTraversal &); - //This is not used, but will be important if SynthesizedAttributes become useful - typedef StackFrameVector SynthesizedAttributesList; - //one of the most important structures in the algorithm, this attaches SgGraphNode*s to InheritedAttributeTypes so that - //looking up the values is possible. - //int numnodes; - //std::map seen; - int numnodes; - //InheritedAttributeType pthgraphinherit; - //StaticCFG::CFG* SgCFG; - SgGraphNode* nullnode; - std::map primenode; - bool done; - //std::set startnodes; - std::set lstN; - std::map > > lstordmap; - std::set solvedLoops; - std::map > checkednodes; - std::map > downed; - - //std::map nodeinedgordmap; - //a value for nodes that have no value, set in the traverse function - InheritedAttributeType nullInherit; - //the user invoked function, runs the algorithm - InheritedAttributeType traverse(SgGraphNode* basenode, SgIncidenceDirectedGraph* g, - InheritedAttributeType inheritedValue, InheritedAttributeType nullInherit, - SgGraphNode* endnode, bool insep = false, bool pcHk = false); - std::set loopSet; - - protected: - //User defined functions to do whatever is needed in evaluation - //All the user gets access to is the node in question - //and the values of the parent nodes (this should be all that is necessary) - virtual InheritedAttributeType evaluateInheritedAttribute(SgGraphNode* n, - std::vector inheritedValues) = 0; - //Not used, but may be useful if SynthesizedAttributes become workable in this context - virtual SynthesizedAttributeType evaluateSynthesizedAttribute(SgGraphNode* n, - InheritedAttributeType in, - SynthesizedAttributesList l) = 0; - -#if !USE_ROSE - // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct, - // namely that the value of a reference must be an lvalue (not NULL). But since we are only trying - // to compile ROSE with ROSE (using the new EDG 4.3 front-end as a tests) we can just skip this case for now. - virtual void pathAnalyze(std::vector& pth, bool loop=false, std::set >& incloops=NULL) = 0; -#else - virtual void pathAnalyze(std::vector& pth, bool loop, std::set >& incloops) = 0; -#endif - - //also not used, but important for possible later use of SynthesizedAttributes - SynthesizedAttributeType defaultSynthesizedAttribute(InheritedAttributeType); - private: - double distime; - //std::set, std::pair > > flpset; - //std::set, std::pair > > goodset; - std::set ploops; - std::map > > lpbegins; - std::map frksLeft; - int currm; - int dpMax; - int repEval; - bool pathCheck; - int pathsSize; - //this constructs the graph tree for computation of inheritedValues - - - std::map known; - std::vector connectNodes; - std::map solved; - std::set solvedset; - //these two are not used, but will be important if SynthesizedAttributes are made reasonable in this context - SynthesizedAttributesList *synthesizedAttributes; - SynthesizedAttributeType traversalResult(); - //finally we have two functions necessary for parallel processing if that is chosen to be used by the user - - - - - std::map nodeInEdgesNum; - int currprime; - std::vector endnodefakes; - std::map > > pathsAtMk; - std::set mkloops; - std::map > > mkloopmap; - std::map > > subPathsAtMk; - std::vector mkglobal; - std::vector clglobal; - bool inseparable; - void solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); - std::vector > closuresVec; - void evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); - void evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); - bool disjoint(std::vector& path, std::vector& vec2) const; - std::set > flatpaths; -// void evalNode(SgIncidenceDirectedGraph* g, SgGraphNode* n); - bool canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::map inhVals; - std::set seenEdges; - std::set nullEdges; - std::set clsT; - void computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); - void computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::pair getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::pair getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n); - bool computable(SgIncidenceDirectedGraph* g, SgGraphNode* n); - void evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::map oVals; - bool canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n); - void setPathVal(SgIncidenceDirectedGraph*g, SgGraphNode* n); - void printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss); - void printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss); - void printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream& ss); - std::set completedNodesPath; - std::set > completedEdgesPath; - void printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream& ss); - void printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream& ss); - std::map iVals; - - std::set nullEdgesOrderedOut; - std::set completedEdgesOut; - std::set completedEdges; - std::set compPar; - std::set compChild; - std::set computedNodes; - SgGraphNode* st; - SgGraphNode* en; - double fllp; - int loopnum; - //std::set solved; - //InheritedAttributeType findAndReverse(SgGraphNode* n, SgIncidenceDirectedGraph* g); - //evaluateAllInheritedAttribute(std::vector endNodeInhVec, SgGraphNode* endnode, std::vector nodes, std::vector inh); -//std::vector getZeroInhs(std::vector > > qAnsSetSet, std::vector endnodeInhVec, SgGraphNode* node); - -}; - - - -/* -template -void -GraphBot:: -travelDown(SgIncidenceDirectedGraph* g) { - std::set oedgs = g->computeEdgeSetOut(iAmHere); - bool taken = false; - if (oedgs.size() > 1) { - std::set edgeTrav = clEdgeTrav[iAmHere]; - ROSE_ASSERT(clEdgeTrav.find(iAmHere) != clEdgeTrav.end()); - for (std::set::iterator i = oedgs.begin(); i != oedgs.end(); i++) { - if (edgTrav.find(*i) == edgTrav.end() || !taken) { - taken = true; - iAmHere = (*i)->get_to(); - lastEdge = *i; - } - } - } - else { - iAmHere = (*(oedgs.begin())->get_to(); - } -} -*/ - - - - - - -/* -*************************** -Various Admin Functions -*************************** -*/ -template -SgGraphTraversal:: -SgGraphTraversal() - : synthesizedAttributes(new SynthesizedAttributesList()) -{ -} - -#ifndef SWIG - -template -SgGraphTraversal:: -~SgGraphTraversal() -{ - ROSE_ASSERT(synthesizedAttributes != NULL); - delete synthesizedAttributes; - synthesizedAttributes = NULL; -} - -#endif - - -template -const SgGraphTraversal & -SgGraphTraversal:: -operator=(const SgGraphTraversal &other) -{ - - ROSE_ASSERT(synthesizedAttributes != NULL); - delete synthesizedAttributes; - synthesizedAttributes = other.synthesizedAttributes->deepCopy(); - - return *this; -} - -/** -This is the function that is used by the user directly to start the algorithm. It is immediately available to the user - -SgGraphTraversal::traverse -Input: -@param[n] n starting node -@param[g] SgIncidenceDirectedGraph* g, CFG calculated previously -@param[inheritedValue] InheritedAttributeType inheritedValue, value of the starting node -@param[nullI] InheritedAttributeType nullI, value of the null Attribute, i.e. what to attribute to a node with no value\ -@param[endnode] SgGraphNode* endnode, final node -@param[insep] boolean to decide inseparability of the analysis function, not yet in use, set automatically to false -@param[pCh] deprecated, set to false -@return InheritedAttributeType, the value of the attribute at the end node - -*/ - - -template -InheritedAttributeType -SgGraphTraversal:: -traverse(SgGraphNode* n, SgIncidenceDirectedGraph* g, InheritedAttributeType inheritedValue, InheritedAttributeType nullI, SgGraphNode* endnode, bool insep, bool pCh) { - //numnodes = 0; - //primes.clear(); - looppaths.clear(); - iLoops.clear(); - completedEdgesPath.clear(); - pathValMap.clear(); - loopNumMap.clear(); - nullloops = 0; - nullEdgesPaths = 0; - fllp = 0.0; - mkglobal.clear(); - clglobal.clear(); - - lpbegins.clear(); - //currents.clear(); - inhVals.clear(); - iVals.clear(); - oVals.clear(); - //reservedEdges.clear(); - completedEdges.clear(); - completedEdgesOut.clear(); - //completedNodes.clear(); - computedNodes.clear(); - nullEdgesOrdered.clear(); - nullEdgesOrderedOut.clear(); - loopSet.clear(); - pathsAtMk.clear(); - - st = n; - en = endnode; - distime = 0.0; - int currm = 1; - int turns = 0; - pathsSize = 0; - done = false; - numnodes = 1; - std::cout << "starting traversal" << std::endl; - pathCheck = pCh; - currprime = 1; - inseparable = insep; - synthesizedAttributes->resetStack(); - ROSE_ASSERT(synthesizedAttributes->debugSize() == 0); - //SgCFG = cfg; - inhVals[n] = inheritedValue; - //GraphBot::inhVals[n] = inheritedValue; - //primes = generatePrimesSieve(); - - -// graphnodeinheritedordmap[ncpy] = inheritedValue; -// nodenodeordmap[ncpy] = n; -// std::vector lst; -// lst.push_back(n); -// lstordmap[ncpy] = lst; - - nullInherit = nullI; -InheritedAttributeType inh; - struct timeval t1, t2, t3, t4, t5, t6, t7, t8; - //else { - loopnum = 0; - //InheritedAttributeType inh; - t1 = getCPUTime(); - - //this function essentially sets up for the evaluate later, it makes putting together the paths much easier - solvePaths(g, n, endnode); - - t2 = getCPUTime(); - -//making sure that endnode hasn't already been evaluated before the traversal starts, unlikely but just in case - ROSE_ASSERT(inhVals.find(endnode) == inhVals.end()); - - std::cout << "solvePaths done" << std::endl; - double diff = timeDifference(t2, t1); - t5 = getCPUTime(); - //InheritedAttributeType pthgraphinherit = botTraverse(g, n, endnode); - oVals[n] = 0; - iVals[0] = n; - pathValMap[n] = 1; -//inserting n as a computed node - computedNodes.insert(n); -//computes the order in which the nodes must be evaluated, makes computeInheritedOrdered much faster - computeOrder(g, n, endnode); - std::cout << "order computed" << std::endl; -//computes the nodal inheritance values - computeInheritedOrdered(g, n); - std::cout << "inheritance computed" << std::endl; - ROSE_ASSERT(oVals.find(endnode) != oVals.end()); - ROSE_ASSERT(inhVals.find(endnode) != inhVals.end()); -//value at the endnode - InheritedAttributeType pthgraphinherit = inhVals[endnode]; - //= evaluateGraph(g, n, endnode, inheritedValue); - t6 = getCPUTime(); - std::cout << "evaluateGraph done" << std::endl; - double diff3 = timeDifference(t6, t5); - t3 = getCPUTime(); -//actually evaluates every path with a user defined pathAnalyze function - //for (int i = 0; i < 10; i++) { - evaluatePaths(g, n, endnode); - //} - t4 = getCPUTime(); - - t7 = getCPUTime(); - //evaluatePathsPar(g, n, endnode); - t8 = getCPUTime(); - - std::cout << "evaluatePaths done " << std::endl; - double diff2 = timeDifference(t4, t3); - double diff2Par = timeDifference(t8, t7); - std::cout << "pathsolve took: " << diff << std::endl; - std::cout << "patheval took: " << diff2 << std::endl; - std::cout << "parpatheval took: " << diff2Par << std::endl; - std::cout << "grapheval took: " << diff3 << std::endl; - std::cout << "entire pathsolve took: " << diff+diff2+diff3+diff2Par << std::endl; - std::cout << "potential loops: " << nullEdgesOrdered.size() << std::endl; - std::cout << "nullNum: " << nullNum << std::endl; - //std::cout << "goodsets: " << goodset.size() << std::endl; - //std::cout << "flpsets: " << flpset.size() << std::endl; - std::cout << "mkloops: " << mkloops.size() << std::endl; - std::cout << "distime: " << distime << std::endl; - std::cout << "fllp: " << fllp << std::endl; - return pthgraphinherit; - //} - //std::cout << "number of endnodefakes: " << endnodefakes.size() << std::endl; - //std::cout << "should be number of nodes: " << currprime << std::endl; - //if (pathanalysis == true) { - // analyzepaths(endnode, g); - //} - //return inh; - //Currently this is not very useful, but it does nothing if traversalResult is not set. -} - -/* WARNING: - This is not a general is_disjoint. It skips the -first element of the second set because in the way I assemble -paths the last element of the path and the first element of addend -must be the same. Hence I simply skip the first node -*/ -bool is_disjoint(std::set set1, std::set set2) { - - if (set1.empty() || set2.empty()) { - return true; - } - std::set::iterator it1 = set1.begin(); - std::set::iterator it2 = set2.begin(); - std::set::iterator it1End = set1.end(); - std::set::iterator it2End = set2.end(); - - if (*it1 > *set2.rbegin() || *it2 > *set1.rbegin()) { - return true; - } - - while (it1 != it1End && it2 != it2End) { - if (*it1 == *it2) { - return false; - } - if (*it1 < *it2) { - it1++; - } - else { - it2++; - } - } - return true; -} - - - -//Checks for disjoint, necessary in computing the paths -template -bool -SgGraphTraversal:: -disjoint(std::vector& pthloops, std::vector& vec2) const { -/* - time_t t1, t2; - time(&t1); - int a = 0; - std::set s1; - std::set s2; - std::vector mkloopvec; - bool goodsetbool; - bool pbool = true; - //std::cout << "calculating disjoint" << std::endl; - ROSE_ASSERT((path.back()).back() == vec2.front()); - - //copy(vec2.begin(), vec2.end(), inserter(s2, s2.end())); -/* - for (int i = 0; i < vec2.size(); i++) { - if (ploops.find(vec2[i]) != ploops.end()) { - pbool = false; - } - } - if (pbool) { - return true; - } - if ( -*/ //for (int q = 0; q < pthloops->size(); q++) { - for (int i = 0; i < pthloops.size(); i++) { - if (find(vec2.begin(), vec2.end(), pthloops[i]) != vec2.end()) { - return false; - } - } - return true; -} -/* - if (pbool) { - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - return true; - } - for (unsigned int k = 0; k < path.size(); k++) { - s1.clear(); -*/ -/* - pbool = true; - for (int p = 0; p < path[k].size(); p++) { - if (ploops.find(path[k][p]) != ploops.end()) { - pbool = false; - } - } -// copy(path[k].begin(), path[k].end(), inserter(s1, s1.end())); - if (!pbool) { -*/ -/* - std::pair, std::pair > flp; - flp.second.first = vec2[0]; - flp.second.first = vec2[1]; - - flp.first.first = path[k][0]; - flp.first.second = path[k][1]; - if (vec2.front() == vec2.back()) { - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } - if (flpset.find(flp) != flpset.end()) { - //std::cout << "already seen" << std::endl; - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } -*/ -/* - else if (goodset.find(flp) != goodset.end()) { - goodsetbool = true; - } -*/ -/* - if (is_disjoint(s1,s2)) { - //goodset.insert(flp); - continue; - } - else { - return false; - } -*/ -/* - else { - std::vector vec1 = path[k]; - - //for (unsigned int i = 0; i < vec1.size(); i++) { - for (unsigned int j = 0; j < mkloopvec.size(); j++) { - std::vector::iterator q = find(vec1.begin(), vec1.end(), mkloopvec[j]); - if (q != vec1.end()) { - if (*q != vec1[vec1.size() - 1] || j != 0) { - - flpset.insert(flp); - // std::cout << "not disjoint" << std::endl; - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } - } - } - //} - //goodset.insert(flp); - } - } - //} -*/ - - -/* - for (unsigned int p = 0; p < vec2.size(); p++) { - for (unsigned int q = 0; q < vec2.size(); q++) { - if (p != q) { - if (vec2[p] == vec2[q]) { - return false; - } - } - } - } -*/ -/* - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return true; -} -*/ -//checks for solvability of a node in nodal analysis - -template -bool -SgGraphTraversal:: -canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool loop = false; - if (inhVals.find(n) != inhVals.end()) { - return true; - } - std::set oed = g->computeEdgeSetIn(n); - if (oed.size() == 0) { - return false; - } - for (std::set::iterator i = oed.begin(); i != oed.end(); i++) { - if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdges.find(*i) == nullEdges.end()) { - return false; - } - } - return true; -} - -//this function evaluates values of paths via the user-defined pathAnalyze function - -template -void -SgGraphTraversal:: -evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { -std::vector > path; -std::vector spath; -SgGraphNode* n = realstartnode; -int successes = 0; -int failures = 0; -int j = 0; -std::vector currpthorg; -int currint = 0; -std::map intPath; -intPath[n] = currint; -currint++; -std::map currents; -SgGraphNode* currnode; -bool step = false; -bool midstep = false; - -//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) - -std::vector > pth = pathsAtMk[realstartnode]; -std::vector > cpth = pathsAtMk[realstartnode]; - path.clear(); - int disjoints = 0; - int disjointtrues = 0; - currpthorg = pth[0]; - intPath[pth[0].front()] = currint; - std::set pthloopstmp; - SgGraphNode* fakenode; - pthloopstmp.insert(fakenode); - std::vector > pthloops; - pthloops.push_back(pthloopstmp); - pthloopstmp.clear(); - currint++; - - int stepnum = 0; - std::vector rs; - rs.push_back(realstartnode); - path.push_back(rs); - currents.clear(); - - step = false; - std::vector sub; - - - std::set > nullIncLoops; - std::vector todobotlst; - std::vector botlst; - struct Bot* rootBot = new Bot; - rootBot->remove = false; - - rootBot->path = path; - rootBot->currpth = currpthorg; - rootBot->pthloops = pthloops; - rootBot->on = true; - botlst.push_back(rootBot); - int tip = 1; - int ti = 1; - std::vector, std::vector > > > collectedPaths; - int maxlst = 0; - while (true) { - if (todobotlst.size()+botlst.size() > maxlst) { - maxlst = todobotlst.size()+botlst.size(); - std::cout << "maxlst: " << maxlst << std::endl; - std::cout << "todobotlst.size(): " << todobotlst.size() << std::endl; - std::cout << "botlst.size(): " << botlst.size() << std::endl; - } - int MAXBOTS = 10000; - int MINPATHS = 1000; - int LOCALMAXBOTS = 10; - int LOCALMAXNODES = 0; - std::vector lstnullbot; - std::vector > newbotlsts (MAXBOTS, lstnullbot); - //std::vector newbotlsts (MAXBOTS, lstnullbot); - //tip = ti; - //ti = 0; - ROSE_ASSERT(botlst.size() >= 0); - if (botlst.size() == 0) { - if (todobotlst.size() != 0) { - while (todobotlst.size() > 0 && botlst.size() < MAXBOTS) { - todobotlst.back()->on = true; - botlst.push_back(todobotlst.back()); - todobotlst.pop_back(); - } - } - else { - if (collectedPaths.size() > 0) { - for (int i = 0; i < collectedPaths.size(); i++) { - std::set > incloops; - std::vector > pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - collectedPaths.clear(); - } - break; - } - } - if (botlst.size() > 0) { - std::pair, std::vector > > nullpr; - std::vector, std::vector > > > newpathslst (MAXBOTS, nullpr); - #pragma omp parallel for - for (int i = 0; i < botlst.size(); i++) { - //std::map > > mkloopmaptmp = mkloopmap; - std::vector localbotlst; - std::pair, std::vector > > localnewpath; - struct Bot* currBot = botlst[i]; - if (currBot->on) { - std::vector currpth = currBot->currpth; - std::vector > path = currBot->path; - std::vector > pthloops = currBot->pthloops; - - if (currpth.back() == endnode) { - path.push_back(currpth); - std::vector flatpath; - std::set > incloops; - struct timeval q1, q2; - ROSE_ASSERT(path.size() == pthloops.size() + 1); - q1 = getCPUTime(); - for (unsigned int q = 0; q < pthloops.size(); q++) { - for (unsigned int r = 0; r < path[q].size(); r++) { - flatpath.push_back(path[q][r]); - } - -/* -#pragma omp critical -{ - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } -} -*/ - - } - - for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { - flatpath.push_back(path[path.size()-1][pt2]); - } - q2 = getCPUTime(); - fllp += timeDifference(q2,q1); - flatpath.push_back(endnode); -//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops -/* - #pragma omp critical (analyze) -{ - pathAnalyze(flatpath, false, incloops); -} -*/ - std::pair , std::vector > > newcol; - newcol.first = flatpath; - newcol.second = pthloops; - localnewpath = newcol; - incloops.clear(); - - int pts = pathsSize++; - pathsSize += 1; - - flatpath.clear(); - path.pop_back(); - int rounds = 0; - bool starter = false; - -// This gets a bit complicated so here is an overview: -// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. -/* - if (currBot->nodelst.size() != 0) { - while (path.back().back() != currBot->nodelst.back().first) { - ROSE_ASSERT(path.size() != 0); - path.pop_back(); - pthloops.pop_back(); - - } - currBot->path = path; - currBot->pthloops = pthloops; - currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; - currBot->nodelst.pop_back(); - localbotlst.push_back(currBot); - } - else { -*/ - currBot->remove = true; - localbotlst.push_back(currBot); - //} - } - else { - -//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node - bool disj = true; - struct timeval tdisb, tdise; - //tdisb = getCPUTime(); - for (int x = 0; x < pthloops.size(); x++) { - for (std::set::iterator j = pthloops[x].begin(); j != pthloops[x].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - } - } - } - //tdise = getCPUTime(); - //distime += timeDifference(tdise, tdisb); - if (disj) { - - disjointtrues++; - //std::cout << "disjoints: " << disjointtrues << std::endl; - midstep = false; -std::set pthloopstmp; - pthloopstmp.clear(); - for (int i = 0; i < currpth.size(); i++) { - //currflat.push_back(currpth[i]); - if (mkloops.find(currpth[i]) != mkloops.end()) { - pthloopstmp.insert(currpth[i]); - } - } - pthloops.push_back(pthloopstmp); - path.push_back(currpth); - pthloopstmp.clear(); - - //std::set > lpth; - std::vector oldcurrpth = currpth; - currpth.clear(); - SgGraphNode* frontnode = (path.back()).front(); - SgGraphNode* backnode = (path.back()).back(); - - ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); - ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); - std::vector > tmppths = pathsAtMk[backnode]; - currBot->currpth = tmppths[0]; - currBot->path = path; - currBot->pthloops = pthloops; - //newbotlst.push_back(currBot); - for (int tp = 1; tp < tmppths.size(); tp++) { - //if (localbotlst.size() < LOCALMAXBOTS) { -/* - if (currBot->nodelst.size() < LOCALMAXNODES) { - std::pair cur; - cur.second = tp; - cur.first = path.back().back(); - currBot->nodelst.push_back(cur); - } - else { -*/ - struct Bot* newBot = new Bot; - newBot->remove = false; - newBot->currpth = tmppths[tp]; - newBot->path = path; - newBot->pthloops = pthloops; - localbotlst.push_back(newBot); - //ti++; - // } - } - localbotlst.push_back(currBot); - //ti++; - } - else { -/* - if (currBot->nodelst.size() != 0) { - while (path.back().back() != currBot->nodelst.back().first) { - ROSE_ASSERT(path.size() != 0); - path.pop_back(); - pthloops.pop_back(); - - } - currBot->path = path; - currBot->pthloops = pthloops; - currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; - currBot->nodelst.pop_back(); - localbotlst.push_back(currBot); - //ti++; - } - - else { -*/ - currBot->remove = true; - localbotlst.push_back(currBot); - //delete currBot; - // } - - } - } - newpathslst[i] = localnewpath; - newbotlsts[i] = localbotlst; - } -} - botlst.clear(); - int num = 0; - - for (int i = 0; i < newbotlsts.size(); i++) { - if (newpathslst[i].first.size() > 0) { - collectedPaths.push_back(newpathslst[i]); - } - for (int j = 0; j < newbotlsts[i].size(); j++) { - if (newbotlsts[i][j]->remove == true) { - delete newbotlsts[i][j]; - } - else if (num < MAXBOTS) { - newbotlsts[i][j]->on = true; - botlst.push_back(newbotlsts[i][j]); - num++; - } - else { - newbotlsts[i][j]->on = false; - todobotlst.push_back(newbotlsts[i][j]); - } - } -} - -if (collectedPaths.size() > MINPATHS) { - - for (int i = 0; i < collectedPaths.size(); i++) { - std::vector > pthloops; - std::set > incloops; - pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - collectedPaths.clear(); -} -} - else { - if (collectedPaths.size() > 0) { - for (int i = 0; i < collectedPaths.size(); i++) { - std::set > incloops; - pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - } - collectedPaths.clear(); - break; - } -} - -std::cout << "successes: " << successes << std::endl; -std::cout << "failures: " << failures << std::endl; -std::cout << "maxlst: " << maxlst << std::endl; -return; -} - - - -template -void -SgGraphTraversal:: -evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { -//std::set seen; -//for (std::map > >::iterator i = pathsAtMk.begin(); i != pathsAtMk.end(); i++) { -/* - std::vector > tocheck = (*i).second; - for (int j = 0; j < tocheck.size(); j++) { - for (int k = 0; k < tocheck[j].size(); k++) { - if (seen.find(tocheck[j][k]) != seen.end()) { - ploops.insert(tocheck[j][k]); - } - else { - seen.insert(tocheck[j][k]); - } - } - } -} -*/ -std::vector > path; -std::vector spath; -SgGraphNode* n = realstartnode; -int successes = 0; -int failures = 0; -int j = 0; -std::vector currpth; -int currint = 0; -std::map intPath; -intPath[n] = currint; -currint++; -std::map currents; -SgGraphNode* currnode; -bool step = false; -bool midstep = false; - -//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) - -std::vector > pth = pathsAtMk[realstartnode]; -std::vector > cpth = pathsAtMk[realstartnode]; - path.clear(); - int disjoints = 0; - int disjointtrues = 0; - currpth = pth[0]; - intPath[pth[0].front()] = currint; - std::set pthloopstmp; - SgGraphNode* fakenode; - pthloopstmp.insert(fakenode); - std::vector > pthloops; - pthloops.push_back(pthloopstmp); - pthloopstmp.clear(); - currint++; - - int stepnum = 0; - std::vector rs; - rs.push_back(realstartnode); - path.push_back(rs); - //currflat.push_back(realstartnode); - currents.clear(); - - step = false; - //std::vector currflat; - std::vector sub; - -/* - std::ofstream mz; - mz.open("pathanalysis.dot"); - mz << "digraph defaultName { \n"; -*/ - std::set > nullIncLoops; - -/* - for (unsigned int p = 0; p < looppaths.size(); p++) { - std::vector lp = looppaths[p]; - - for (unsigned int i = 0; i < lp.size()-1; i++) { - for (unsigned int l = i+1; l < lp.size(); l++) { - if (lp[i] == lp[l] && lp[i] != realstartnode && lp[i] != endnode) { - std::vector interiorloop; - interiorloop.clear(); - for (unsigned int j = i; j < l+1; j++) { - interiorloop.push_back(lp[j]); - } - if (interiorloop.size() > 2) { - } - if (interiorloop.size() > 2 && interiorloop.back() != endnode) { - if (find(iLoops.begin(), iLoops.end(), interiorloop) == iLoops.end()) { - if (find(looppaths.begin(), looppaths.end(), interiorloop) == looppaths.end()) { - iLoops.push_back(interiorloop); - loopnum++; - for (unsigned int k = 0; k < interiorloop.size(); k++) { - loopNumMap[interiorloop[k]] = loopnum; - } - lpbegins[interiorloop.front()].insert(interiorloop); - pathAnalyze(interiorloop, true, nullIncLoops); - - } - } - } - } - } - } - if (lp.size() > 2) { - lpbegins[lp.front()].insert(lp); - pathAnalyze(lp, true, nullIncLoops); - //for (unsigned int i = 1; i < lp.size(); i++) { - // printNodePlusEdgesForAnalysisPath(g, lp, p, p, mz); - //} - } - } -*/ - while (step == false) { - stepnum++; - - if (currpth.back() == endnode) { - path.push_back(currpth); - //for (int i = 0; i < currpth.size(); i++) { - // currflat.push_back(currpth[i]); - //} - std::vector flatpath; - //std::vector sub; - std::set > incloops; - struct timeval q1, q2; - //std::cout << "path.size(): " << path.size() << std::endl; - //std::cout << "pthloops.size(): " << pthloops.size() << std::endl; - ROSE_ASSERT(path.size() == pthloops.size() + 1); - q1 = getCPUTime(); - for (unsigned int q = 0; q < pthloops.size(); q++) { - //sub = path[q]; - //sub.pop_back(); - for (unsigned int r = 0; r < path[q].size(); r++) { - flatpath.push_back(path[q][r]); - } - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { - flatpath.push_back(path[path.size()-1][pt2]); - } - - q2 = getCPUTime(); - fllp += timeDifference(q2,q1); - flatpath.push_back(endnode); -/* - for (unsigned int ps = 0; ps < flatpath.size(); ps++) { - if (lpbegins.find(flatpath[ps]) != lpbegins.end()) { - for (std::set >::iterator sv = lpbegins[flatpath[ps]].begin(); sv != lpbegins[flatpath[ps]].end(); sv++) { - incloops.insert(*sv); - } - } - } -*/ -//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops - pathAnalyze(flatpath, false, incloops); - incloops.clear(); - //printNodePlusEdgesForAnalysisPath(g, flatpath, -1, -1, mz); - - int pts = pathsSize++; - pathsSize += 1; - - flatpath.clear(); - path.pop_back(); - int rounds = 0; - bool starter = false; - -// This gets a bit complicated so here is an overview: -// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. - - - while (true) { - rounds++; - ROSE_ASSERT(pathsAtMk.find((path.back()).back()) != pathsAtMk.end()); - if ((path.back()).front() == realstartnode) { - starter = true; - } - if (currents[(path.back()).back()] < (pathsAtMk[(path.back()).back()].size()) /*|| (path.back()).front() == realstartnode*/) { - std::vector > cpths = pathsAtMk[(path.back()).back()]; - currpth = cpths[currents[(path.back()).back()]]; - currents[(path.back()).back()]++; - break; - } - else { - currents[(path.back()).back()] = 0; - path.pop_back(); - pthloops.pop_back(); - } - if (starter == true) { - step = true; - break; - } - - } - } - else { - -//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node - bool disj = true; - struct timeval tdisb, tdise; - tdisb = getCPUTime(); - for (int i = 0; i < pthloops.size(); i++) { - for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - } - } - } -/* - #pragma omp parallel for num_threads(4) private(i,j) - for (i = 0; i < pthloops.size(); i++) { - if (disj) { - for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - //j = pthloops[i].size(); - } - } - } - - } -*/ - tdise = getCPUTime(); - distime += timeDifference(tdise, tdisb); - if (disj) { - - disjointtrues++; - //std::cout << "disjoints: " << disjointtrues << std::endl; - midstep = false; - std::set pthloopstmp; - pthloopstmp.clear(); - for (int i = 0; i < currpth.size(); i++) { - //currflat.push_back(currpth[i]); - if (mkloops.find(currpth[i]) != mkloops.end()) { - pthloopstmp.insert(currpth[i]); - } - } - pthloops.push_back(pthloopstmp); - path.push_back(currpth); - pthloopstmp.clear(); - - //std::set > lpth; - std::vector oldcurrpth = currpth; - currpth.clear(); - if (currents.find((path.back()).back()) == currents.end()) { - currents[(path.back()).back()] = 0; - } - SgGraphNode* frontnode = (path.back()).front(); - SgGraphNode* backnode = (path.back()).back(); - - ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); - ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); - if (currents.find(backnode) == currents.end()) { - currents[backnode] = 0; - } - else { - ROSE_ASSERT(currents[backnode] == 0); - } - std::vector > tmppths = pathsAtMk[backnode]; - - currpth = tmppths[currents[backnode]]; - ROSE_ASSERT(currpth != oldcurrpth); - currents[backnode]++; - } - else { - disjoints++; - //std::cout << "disjoint false: " << s << std::endl; - - while (true) { - if (currents[(path.back()).back()] < pathsAtMk[(path.back()).back()].size() || path.back().back() == realstartnode) { - break; - } - currents[(path.back()).back()] = 0; - path.pop_back(); - pthloops.pop_back(); - } - if ((path.back()).back() != realstartnode) { - currpth = (pathsAtMk[(path.back()).back()])[currents[(path.back()).back()]]; - currents[(path.back()).back()]++; - } - else { - step = true; - } - } - } - } -std::cout << "successes: " << successes << std::endl; -std::cout << "failures: " << failures << std::endl; - -return; -} - - -//these are debugging functions, used to visually ascertain where the paths are going to check to make sure everything is evaluated - - -/* DEBUGGING */ - -template -void -SgGraphTraversal:: -printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss) { - printNodeForAnalysis(n, loopNum, pathVal, ss); - std::set outEdges = g->computeEdgeSetOut(n); - for (std::set::iterator i = outEdges.begin(); i != outEdges.end(); i++) { - if (nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - printEdgeForAnalysis(*i, false, ss); - } - else { - printEdgeForAnalysis(*i, true, ss); - } - } -} - -template -void -SgGraphTraversal:: -printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss) { - for (unsigned int i = 0; i < n.size()-1; i++) { - if (completedNodesPath.find(n[i]) == completedNodesPath.end()) { - printNodeForAnalysis(n[i], loopNum, pathVal, ss); - completedNodesPath.insert(n[i]); - } - std::pair prnod; - prnod.first = n[i+1]; - prnod.second = n[i]; - if (completedEdgesPath.find(prnod) == completedEdgesPath.end()) { - printEdgeForAnalysisPath(n[i+1], n[i], ss); - completedEdgesPath.insert(prnod); - } - } - if (completedNodesPath.find(n[n.size() - 1]) == completedNodesPath.end()) { - printNodeForAnalysis(n[n.size()-1], loopNum, pathVal, ss); - completedNodesPath.insert(n[n.size() - 1]); - } - -} - - -template -void -SgGraphTraversal:: -printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream &ss) { - int id = n->get_index(); - std::string nodeColor = "black"; - if (loopNum != 0) { - ss << id << " [label=\"" << "LoopNumS" << loopNum << "\", color=\"" << "green" << "\", style=\"" << "solid" << "\"];\n"; - } - else { - ss << id << " [label=\"" << "pathNumS" << pathNum << "\", color=\"" << "black" << "\", style=\"" << "dotted" << "\"];\n"; - } - -} -template -void -SgGraphTraversal:: -printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream &ss) { - if (isNullEdge) { - ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "NullEdge" << "\", style=\"" << "dotted" << "\"];\n"; - } - else { - ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "\", style=\"" << "solid" << "\"];\n"; - } -} -template -void -SgGraphTraversal:: -printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream &ss) { - ss << g2->get_index() << " -> " << g1->get_index() << " [label=\"" << "Edge" << "\", style=\"" << "solid" << "\"];\n"; -} - -/* END DEBUGGING */ - -//This function sets up the graph so that the evaluatePath function can easily traverse the paths - -template -void -SgGraphTraversal:: -solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { - bool done = false; - bool edges = true; - bool tookone = false; - std::vector mkpath; - std::vector marks; - marks.push_back(n); - mkglobal.push_back(n); - SgGraphNode* currn = n; - SgGraphNode* took; - std::set taken; - std::vector toTake; - std::vector path; - path.push_back(n); - mkpath.push_back(n); - int itr = 0; - int bifurcations = 0; - std::map completed; - while (done == false) { - ROSE_ASSERT(currn != NULL); -//check to see if we've hit the endnode or if we're done, if not continue, if so push the subpath into the "pathsAtMk" repository - if (currn == endnode || completed.find(currn) != completed.end()) { - if (pathsAtMk.find(marks.back()) == pathsAtMk.end()) { - std::vector > emptypath; - pathsAtMk[marks.back()] = emptypath; - } - edges = false; - pathsAtMk[marks.back()].push_back(mkpath); - //for (int mk = 0; mk < mkpath.size(); mk++) { - // std::set iedg = g->computeEdgeSetIn(mkpath[mk]); - //if (iedg.size() > 1) { - // ploops.insert(mkpath[mk]); - // } - //} - ROSE_ASSERT(mkpath.front() == marks.back()); - if (marks.size() == 0) { - return; - } - mkpath.clear(); - bool y = true; - bool haventtaken = false; - bool p = true; - int place; - bool found = false; - while (found == false) { - if (marks.size() == 0) { - return; - } - SgDirectedGraphEdge* tooked; - SgGraphNode* mark1 = marks.back(); - std::set oedg = g->computeEdgeSetOut(mark1); - ROSE_ASSERT(oedg.size() > 1 || mark1 == n); - for (std::set::iterator j = oedg.begin(); j != oedg.end(); j++) { - if (taken.find(*j) == taken.end() && haventtaken == false) { - tooked = *j; - haventtaken = true; - } - } - if (haventtaken == true) { - if (marks.back() == n) { - path.clear(); - } - path.push_back(marks.back()); - if ( mkpath.empty() || (mkpath.back() != marks.back()) ) { - ROSE_ASSERT(!marks.empty()); - mkpath.push_back(marks.back()); - } - taken.insert(tooked); - took = tooked->get_to(); - found = true; - } - else { - completed[marks.back()] = true; - bifurcations++; - marks.pop_back(); - } - } - if (marks.size() == 0) { - return; - } - haventtaken = false; - found = false; - - } -//if we haven't reached the endnode or completed, continue down the graph - else { - std::set oedg = g->computeEdgeSetOut(currn); - std::set iedg = g->computeEdgeSetIn(currn); - if (oedg.size() > 1) { - if (mkpath.back() != currn) { - mkpath.push_back(currn); - } - pathsAtMk[marks.back()].push_back(mkpath); - mkpath.clear(); - mkpath.push_back(currn); - marks.push_back(currn); - if (find(mkglobal.begin(), mkglobal.end(), currn) == mkglobal.end()) { - mkglobal.push_back(currn); - } - for (std::set::iterator i = oedg.begin(); i != oedg.end(); i++) { - if (taken.find(*i) == taken.end() && tookone == false) { - taken.insert(*i); - tookone = true; - took = (*i)->get_to(); - } - else if (taken.find(*i) == taken.end() && tookone == true) { - //toTake.push_back((*i)->get_to()); - } - } - tookone = false; - } - else { - took = (*(oedg.begin()))->get_to(); - } - } - itr++; - - if (find(path.begin(), path.end(), took) == path.end()) { - mkpath.push_back(took); - path.push_back(took); - currn = took; - } - else { - mkloops.insert(took); - std::vector lptemp; - lptemp.clear(); - lptemp.push_back(took); - while (path.back() != took) { - - path.pop_back(); - - lptemp.push_back(path.back()); - - } - (mkloopmap[took]).insert(lptemp); -/* - if (lptemp.size() > 1) { - if (find(looppaths.begin(), looppaths.end(), lptemp) == looppaths.end() && find(lptemp.begin(), lptemp.end(), st) == lptemp.end() && find(lptemp.begin(), lptemp.end(), endnode) == lptemp.end()) { - looppaths.push_back(lptemp); - loopnum++; - for (unsigned int i = 0; i < lptemp.size(); i++) { - loopNumMap[lptemp[i]] = loopnum; - } - } - } -*/ - path.push_back(took); - currn = path.back(); - mkpath.push_back(took); - } - - -} - return; -} - -//not currently useful -template -SynthesizedAttributeType -SgGraphTraversal:: -defaultSynthesizedAttribute(InheritedAttributeType inh) -{ - SynthesizedAttributeType s = SynthesizedAttributeType(); - return s; -} - - -//computes the order in which to evaluate the nodes in nodal analysis so that you don't evaluate a node before you evaluate its parents - -template -void -SgGraphTraversal:: -computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { - std::map incomputables; - std::set lpposs; - //std::set lps; - SgGraphNode* currn; - currn = n; - int orders = 0; - while (true) { - if (orders % 10000 == 0) { - std::cout << "orders: " << orders << std::endl; - } - orders++; - if (currn == endnode) { - } - if (computable(g, currn) || currn == n) { - int mp; - if (oVals.find(currn) == oVals.end()) { - oVals[currn] = currm++; - iVals[currm++] = currn; - currm += 1; - } - if (currn == endnode) { - - break; - } - std::pair pbs = getNextChild(g, currn); - computedNodes.insert(currn); - ROSE_ASSERT(pbs.first == true); - currn = pbs.second; - } - else { - std::pair pbp = getNextPar(g, currn); - ROSE_ASSERT(pbp.first == true); - currn = pbp.second; - - } - - } - std::cout << "required orders" << orders << std::endl; - std::cout << "incomputables.size() " << incomputables.size() << std::endl; -} - -//simple fucntion to check the computability under nodal analysis -template -bool -SgGraphTraversal:: -computable(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - if (computedNodes.find(n) != computedNodes.end()) { - return true; - } - std::set ed = g->computeEdgeSetIn(n); - bool comp = true; - for (std::set::iterator i = ed.begin(); i != ed.end(); i++) { - if (oVals.find((*i)->get_from()) == oVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - comp = false; - } - } - return comp; -} - - -//computes the inherited attribute values in nodal analysis - -template -void -SgGraphTraversal:: -computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - int runs = 0; -// std::ofstream mf; -// mf.open("analysis.dot"); -// mf << "digraph defaultName { \n"; - for (std::map::iterator i = iVals.begin(); i != iVals.end(); i++) { - runs++; - ROSE_ASSERT(canEval(g, (*i).second)); - setPathVal(g, n); - //printNodePlusEdgesForAnalysis(g, (*i).second, loopNumMap[(*i).second], pathValMap[(*i).second], mf); - evalNodeOrdered(g, (*i).second); - } -} - -//checks to see if evaluation is possible under nodal analysis -template -bool -SgGraphTraversal:: -canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool evaled = true; - if (inhVals.find(n) == inhVals.end()) { - std::set ins = g->computeEdgeSetIn(n); - for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { - if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - evaled = false; - } - } - } - return evaled; -} - - -//actually does the evaluation -template -void -SgGraphTraversal:: -evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - if (inhVals.find(n) != inhVals.end()) { - return; - } - std::set par = g->computeEdgeSetIn(n); - std::vector inh; - for (std::set::iterator i = par.begin(); i != par.end(); i++) { - if (inhVals.find((*i)->get_from()) != inhVals.end()) { - inh.push_back(inhVals[(*i)->get_from()]); - } - } - - if (n != st || inh.size() > 0) { - InheritedAttributeType inhX; - inhX = evaluateInheritedAttribute(n, inh); - inhVals[n] = inhX; - } - //std::cout << "num of inhVals: " << inh.size() << std::endl; - -} - - -//debugging function, currently not useful for the end user -template -void -SgGraphTraversal:: -setPathVal(SgIncidenceDirectedGraph* g, SgGraphNode* currn) { - if (pathValMap.find(currn) != pathValMap.end()) { - return; - } - std::set ined = g->computeEdgeSetIn(currn); - int tmppathcount = 0; - for (std::set::iterator i = ined.begin(); i != ined.end(); i++) { - ROSE_ASSERT(pathValMap.find((*i)->get_from()) != pathValMap.end() /*|| nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()*/); - //if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - // pathValMap[(*i)->get_from()] = 0; - // } - int pv = pathValMap[(*i)->get_from()]; - if (pv != 0) { - tmppathcount += pv; - } - } - pathValMap[currn] = tmppathcount; - return; - } - -//computes the next child to be analyzed in nodal analysis -template -std::pair -SgGraphTraversal:: -getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool nullPoss = false; - //std::cout << "nextChild" << std::endl; - std::set outs = g->computeEdgeSetOut(n); - //std::cout << "outs.size(): " << outs.size() << std::endl; - //std::cout << "outs: " << outs.size() << std::endl; - SgGraphNode* nextNode; - SgGraphNode* nullNode; - bool completed = false; - bool completeNull = false; - - for (std::set::iterator i = outs.begin(); i != outs.end(); i++) { - - if (outs.size() == 1) { - nextNode = (*i)->get_to(); - if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - nullNum++; - } - //completedEdges.insert(*i); - completed = true; - } - else if (completed == false && computedNodes.find((*i)->get_to()) == computedNodes.end()) { - completed = true; - nextNode = (*i)->get_to(); - if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - nullNum++; - } - completedEdgesOut.insert(*i); - } - - - } - std::pair pr; - ROSE_ASSERT (completed == true || completeNull == true); - if (completed == true) { - pr.first = completed; - pr.second = nextNode; - return pr; - } - else { - pr.first = true; - pr.second = nullNode; - return pr; - } - -} - -//computes the next parent to be analyzed in nodal analysis -template -std::pair -SgGraphTraversal:: -getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - std::set ins = g->computeEdgeSetIn(n); - SgGraphNode* nextPar; - SgDirectedGraphEdge* nullEdgeO; - bool completed = false; - bool completeNull = false; - for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { - - if (ins.size() == 1 /*&& completedEdges.find(*i) == completedEdges.end()*/) { - completed = true; - completedEdges.insert(*i); - nextPar = (*i)->get_from(); - } - - else if (completedEdges.find(*i) == completedEdges.end() && completed == false) { - completed = true; - nextPar = (*i)->get_from(); - completedEdges.insert(*i); - } - - else if (completedEdges.find(*i) != completedEdges.end() && computedNodes.find((*i)->get_from()) == computedNodes.end() && completed == false /*&& nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()*/) { - completeNull = true; - std::pair lpp; - nextPar = n; - nullEdgesOrdered.insert(*i); - nullEdgesPaths++; - - } - } - ROSE_ASSERT(completed == true || completeNull == true); - std::pair pr; - pr.first = completed; - pr.second = nextPar; - - if (completeNull == true && completed == false) { - pr.first = completeNull; - pr.second = nextPar; - } - - return pr; -} - - - - - - - - - - - - - - - diff --git a/src/midend/astProcessing/graphTemplate.h b/src/midend/astProcessing/graphTemplate.h deleted file mode 100644 index e3075618ffb..00000000000 --- a/src/midend/astProcessing/graphTemplate.h +++ /dev/null @@ -1,533 +0,0 @@ -#ifndef BACKSTROKE_CFG_H -#define BACKSTROKE_CFG_H - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace Backstroke -{ - -#define foreach BOOST_FOREACH - - -//! This function helps to write the DOT file for vertices. -template -void writeCFGNode(std::ostream& out, const CFGNodeType& cfgNode) -{ - SgNode* node = cfgNode.getNode(); - ROSE_ASSERT(node); - - std::string nodeColor = "black"; - if (isSgStatement(node)) - nodeColor = "blue"; - else if (isSgExpression(node)) - nodeColor = "green"; - else if (isSgInitializedName(node)) - nodeColor = "red"; - - std::string label; - - if (SgFunctionDefinition* funcDef = isSgFunctionDefinition(node)) - { - std::string funcName = funcDef->get_declaration()->get_name().str(); - if (cfgNode.getIndex() == 0) - label = "Entry\\n" + funcName; - else if (cfgNode.getIndex() == 3) - label = "Exit\\n" + funcName; - } - - if (!isSgScopeStatement(node) && !isSgCaseOptionStmt(node) && !isSgDefaultOptionStmt(node)) - { - std::string content = node->unparseToString(); - boost::replace_all(content, "\"", "\\\""); - boost::replace_all(content, "\\n", "\\\\n"); - label += content; - } - else - label += "<" + node->class_name() + ">"; - - if (label == "") - label += "<" + node->class_name() + ">"; - - out << "[label=\"" << label << "\", color=\"" << nodeColor << - "\", style=\"" << (cfgNode.isInteresting()? "solid" : "dotted") << "\"]"; -} - - -//! This function helps to write the DOT file for edges. -template -void writeCFGEdge(std::ostream& out, const CFGEdgeType& e) -{ - out << "[label=\"" << escapeString(e.toString()) << - "\", style=\"" << "solid" << "\"]"; -} - - -// Predeclaration of class CFG. -template class CFG; - -struct FullCFGNodeFilter -{ - bool operator()(const VirtualCFG::CFGNode& cfgNode) const - { return true; } -}; - -struct InterestingCFGNodeFilter -{ - bool operator()(const VirtualCFG::CFGNode& cfgNode) const - { return cfgNode.isInteresting(); } -}; - -//! A full CFG without any filtered nodes. -typedef CFG FullCFG; - - -//! A filtered CFG which only contains interesting nodes and edges. -typedef CFG FilteredCFG; - - - - - -/********************************************************************/ -// The concept required to be fulfilled by CFGNodeFilter is -// -// struct CFGNodeFilter -// { -// bool operator()(const VirtualCFG::CFGNode& cfgNode) const; -// }; -// -/********************************************************************/ - -//! A class holding a Control Flow Graph. - -template -class CFG : public boost::adjacency_list >, - boost::shared_ptr > > -{ - typedef typename boost::graph_traits > GraphTraits; - -public: - typedef VirtualCFG::FilteredCFGNode CFGNodeType; - typedef VirtualCFG::FilteredCFGEdge CFGEdgeType; - - typedef boost::shared_ptr CFGNodePtr; - typedef boost::shared_ptr CFGEdgePtr; - - typedef typename GraphTraits::vertex_descriptor Vertex; - typedef typename GraphTraits::edge_descriptor Edge; - - typedef std::map VertexVertexMap; - //! The entry node. - Vertex entry_; - - //! The exit node. - Vertex exit_; - - -protected: - - //! The function definition of this CFG. - SgFunctionDefinition* funcDef_; - - - //! A map from a CFG node to the corresponding vertex - std::map nodesToVertices_; - - //! The dominator tree of this CFG. - VertexVertexMap dominatorTree_; - - //! The postdominator tree of this CFG. - VertexVertexMap postdominatorTree_; - -public: - std::map getNodeVert() { - return nodesToVertices_; - } - - //! The default constructor. - CFG() - : funcDef_(NULL), - entry_(GraphTraits::null_vertex()), - exit_(GraphTraits::null_vertex()) - { - } - - //! The constructor building the CFG. - explicit CFG(SgFunctionDefinition* funcDef) - : funcDef_(funcDef), - entry_(GraphTraits::null_vertex()), - exit_(GraphTraits::null_vertex()) - { - build(funcDef); - } - - //! Build the actual CFG for the given function. - void build(SgFunctionDefinition* funcDef); - - //! Get the function definition of this CFG. - SgFunctionDefinition* getFunctionDefinition() const - { return funcDef_; } - - //! Get the entry node of the CFG - const Vertex& getEntry() const - { return entry_; } - - //! Get the exit node of the CFG - const Vertex& getExit() const - { return exit_; } - - //! Build the dominator tree of this CFG. - //! @returns A map from each node to its immediate dominator. - const VertexVertexMap& getDominatorTree(); - - //! Build the postdominator tree of this CFG. - const VertexVertexMap& getPostdominatorTree(); - - //! Build a reverse CFG. - CFG makeReverseCopy() const; - - //! Output the graph to a DOT file. - void toDot(const std::string& filename) const; - - //! Get all CFG nodes in this graph. - std::vector getAllNodes() const; - - //! Get all CFG edges in this graph. - std::vector getAllEdges() const; - - //! Given a CFG node, returns the corresponding vertex in the graph. - //! Returns Vertex::null_vertex() if the given node is not in the graph - Vertex getVertexForNode(const CFGNodeType &node) const; - - //! Return if this CFG is reducible (if all loops are natural loops, the - //! CFG is reducible). - bool isReducible() const { return true; } - - //! Get all back edges in the CFG. A back edge is one whose target dominates its source. - std::vector getAllBackEdges(); - - //! Get all loop headers in this CFG. A natural loop only has one header. - std::vector getAllLoopHeaders(); - -protected: - - //! A internal funtion which builds the actual CFG (boost::graph). - void buildCFG(const CFGNodeType& node, - std::map& nodesAdded, - std::set& nodesProcessed); - - //! Find the entry and exit of this CFG and set the corresponding members. - void setEntryAndExit(); - - //! This function helps to write the DOT file for vertices. - void writeGraphNode(std::ostream& out, const Vertex& node) const - { - writeCFGNode(out, *(*this)[node]); - //VirtualCFG::printNode(out, (*this)[node]); - } - - //! This function helps to write the DOT file for edges. - void writeGraphEdge(std::ostream& out, const Edge& edge) const - { - writeCFGEdge(out, *(*this)[edge]); - //VirtualCFG::printEdge(out, (*this)[edge], true); - } - - //! This class is used to copy vertices when calling copy_graph(). - struct VertexCopier - { - VertexCopier(const CFG& g1, CFG& g2) - : cfg1(g1), cfg2(g2) {} - - void operator()(const Vertex& v1, Vertex& v2) const - { cfg2[v2] = cfg1[v1]; } - - const CFG& cfg1; - CFG& cfg2; - }; - - //! This class is used to copy edges when calling copy_graph(). - struct EdgeCopier - { - EdgeCopier(const CFG& g1, CFG& g2) - : cfg1(g1), cfg2(g2) {} - - void operator()(const Edge& e1, Edge& e2) const - { cfg2[e2] = cfg1[e1]; } - - const CFG& cfg1; - CFG& cfg2; - }; -}; - - - -template -void CFG::toDot(const std::string& filename) const -{ - std::ofstream ofile(filename.c_str(), std::ios::out); - boost::write_graphviz(ofile, *this, - boost::bind(&CFG::writeGraphNode, this, ::_1, ::_2), - boost::bind(&CFG::writeGraphEdge, this, ::_1, ::_2)); -} - -template -void CFG::build(SgFunctionDefinition* funcDef) -{ - ROSE_ASSERT(funcDef); - funcDef_ = funcDef; - - // The following two variables are used to record the nodes traversed. - nodesToVertices_.clear(); - std::set nodesProcessed; - - // Remove all nodes and edges first. - this->clear(); - entry_ = GraphTraits::null_vertex(); - exit_ = GraphTraits::null_vertex(); - - buildCFG(CFGNodeType(funcDef->cfgForBeginning()), nodesToVertices_, nodesProcessed); - - // Find the entry and exit of this CFG. - setEntryAndExit(); - - ROSE_ASSERT(isSgFunctionDefinition((*this)[entry_]->getNode())); - ROSE_ASSERT(isSgFunctionDefinition((*this)[exit_]->getNode())); -} - -template -void CFG::setEntryAndExit() -{ - foreach (Vertex v, boost::vertices(*this)) - { - CFGNodePtr node = (*this)[v]; - if (isSgFunctionDefinition(node->getNode())) - { - if (node->getIndex() == 0) - entry_ = v; - else if (node->getIndex() == 3) - exit_ = v; - } - } - - //In graphs with an infinite loop, we might never get to the end vertex - //In those cases, we need to add it explicitly - if (exit_ == GraphTraits::null_vertex()) - { - std::cerr << "This function may contain an infinite loop " - "inside so that its CFG cannot be built" << std::endl; - exit_ = add_vertex(*this); - (*this)[exit_] = CFGNodePtr(new CFGNodeType(funcDef_->cfgForEnd())); - } - - ROSE_ASSERT(entry_ != GraphTraits::null_vertex()); - ROSE_ASSERT(exit_ != GraphTraits::null_vertex()); -} - -template -void CFG::buildCFG( - const CFGNodeType& node, - std::map& nodesAdded, - std::set& nodesProcessed) -{ - ROSE_ASSERT(node.getNode()); - - if (nodesProcessed.count(node) > 0) - return; - nodesProcessed.insert(node); - - typename std::map::iterator iter; - bool inserted; - Vertex from, to; - - // Add the source node. - const CFGNodeType& src = node; - ROSE_ASSERT(src.getNode()); - - boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src, Vertex())); - - if (inserted) - { - from = add_vertex(*this); - (*this)[from] = CFGNodePtr(new CFGNodeType(src)); - iter->second = from; - } - else - { - from = iter->second; - } - - std::vector outEdges = node.outEdges(); - - foreach(const CFGEdgeType& cfgEdge, outEdges) - { - // For each out edge, add the target node. - CFGNodeType tar = cfgEdge.target(); - ROSE_ASSERT(tar.getNode()); - - boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar, Vertex())); - - if (inserted) - { - to = add_vertex(*this); - (*this)[to] = CFGNodePtr(new CFGNodeType(tar)); - iter->second = to; - } - else - { - to = iter->second; - } - - // Add the edge. - Edge edge = add_edge(from, to, *this).first; - (*this)[edge] = CFGEdgePtr(new CFGEdgeType(cfgEdge)); - - // Build the CFG recursively. - buildCFG(tar, nodesAdded, nodesProcessed); - } -} - -template -const typename CFG::VertexVertexMap& CFG::getDominatorTree() -{ - if (!dominatorTree_.empty()) - return dominatorTree_; - - boost::associative_property_map domTreePredMap(dominatorTree_); - - // Here we use the algorithm in boost::graph to build a map from each node to its immediate dominator. - boost::lengauer_tarjan_dominator_tree(*this, entry_, domTreePredMap); - return dominatorTree_; -} - -template -const typename CFG::VertexVertexMap& CFG::getPostdominatorTree() -{ - if (!postdominatorTree_.empty()) - return postdominatorTree_; - - boost::associative_property_map postdomTreePredMap(postdominatorTree_); - - // Here we use the algorithm in boost::graph to build an map from each node to its immediate dominator. - boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*this), exit_, postdomTreePredMap); - return postdominatorTree_; -} - -template -CFG CFG::makeReverseCopy() const -{ - CFG reverseCFG; - // The following function makes a reverse CFG copy. - boost::transpose_graph(*this, reverseCFG, - boost::vertex_copy(VertexCopier(*this, reverseCFG)). - edge_copy(EdgeCopier(*this, reverseCFG))); - - // Swap entry and exit. - reverseCFG.entry_ = this->exit_; - reverseCFG.exit_ = this->entry_; - return reverseCFG; -} - - -template -std::vector::CFGNodePtr> -CFG::getAllNodes() const -{ - std::vector allNodes; - foreach (Vertex v, boost::vertices(*this)) - allNodes.push_back((*this)[v]); - return allNodes; -} - -/* -template -std::vector::CFGNodeType> -CFG::getAllNodesNoPtrs() const -{ - std::vector allNodes; - foreach (Vertex v, boost::vertices(*this)) - allNodes.push_back(&((*this)[v])); - return allNodes; -} -*/ - -template -std::vector::CFGEdgePtr> -CFG::getAllEdges() const -{ - std::vector allEdges; - foreach (const Edge& e, boost::edges(*this)) - allEdges.push_back((*this)[e]); - return allEdges; -} - -template -typename CFG::Vertex CFG::getVertexForNode(const CFGNodeType &node) const -{ - typename std::map::const_iterator vertexIter = nodesToVertices_.find(node); - if (vertexIter == nodesToVertices_.end()) - return GraphTraits::null_vertex(); - else - { - ROSE_ASSERT(*(*this)[vertexIter->second] == node); - return vertexIter->second; - } -} - -template -std::vector::Edge> CFG::getAllBackEdges() -{ - std::vector backEdges; - - // If the dominator tree is not built yet, build it now. - getDominatorTree(); - - foreach (const Edge& e, boost::edges(*this)) - { - Vertex src = boost::source(e, *this); - Vertex tar = boost::target(e, *this); - - //Vertex v = *(dominatorTree.find(src)); - typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src); - while (iter != dominatorTree_.end()) - { - if (iter->second == tar) - { - backEdges.push_back(e); - break; // break the while loop - } - iter = dominatorTree_.find(iter->second); - } - } - - return backEdges; -} - -template -std::vector::Vertex> CFG::getAllLoopHeaders() -{ - std::vector backEdges = getAllBackEdges(); - std::vector headers; - foreach (Edge e, backEdges) - headers.push_back(boost::target(e, *this)); - return headers; -} - -#undef foreach - -} // End of namespace Backstroke - - -#endif /* BACKSTROKE_CFG_H */ diff --git a/tests/nonsmoke/functional/roseTests/CMakeLists.txt b/tests/nonsmoke/functional/roseTests/CMakeLists.txt index 535c285e2f5..5c444e94781 100644 --- a/tests/nonsmoke/functional/roseTests/CMakeLists.txt +++ b/tests/nonsmoke/functional/roseTests/CMakeLists.txt @@ -4,7 +4,7 @@ if(enable-c) add_subdirectory (astMergeTests) add_subdirectory (astPerformanceTests) - add_subdirectory (astProcessingTests) + #add_subdirectory (astProcessingTests) add_subdirectory (astQueryTests) add_subdirectory (astSymbolTableTests) add_subdirectory (astTokenStreamTests) diff --git a/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt b/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt index 53fb6e8172f..2c9f27c3634 100644 --- a/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt +++ b/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt @@ -161,18 +161,18 @@ if (HAVE_SYS_TIME_H) endforeach() #----------------------------------------------------------------------------- - add_executable(processnew3Down4SgIncGraph3 processnew3Down4SgIncGraph3.C) - target_link_libraries(processnew3Down4SgIncGraph3 - ROSE_DLL EDG ${link_with_libraries}) - set(processnew3Down4SgIncGraph3_SPECIMENS test11.C test12.C test13.C test14.C) - - set(processnew3Down4SgIncGraph3_SPECIMENS eif.C eif2.C eif3.C eif4.C) - foreach(specimen ${processnew3Down4SgIncGraph3_SPECIMENS}) - add_test( - NAME pnew2_${specimen} - COMMAND processnew3Down4SgIncGraph3 ${CMAKE_CURRENT_SOURCE_DIR}/${specimen} - ) - endforeach() + #add_executable(processnew3Down4SgIncGraph3 processnew3Down4SgIncGraph3.C) + #target_link_libraries(processnew3Down4SgIncGraph3 + # ROSE_DLL EDG ${link_with_libraries}) + #set(processnew3Down4SgIncGraph3_SPECIMENS test11.C test12.C test13.C test14.C) + + #set(processnew3Down4SgIncGraph3_SPECIMENS eif.C eif2.C eif3.C eif4.C) + #foreach(specimen ${processnew3Down4SgIncGraph3_SPECIMENS}) + # add_test( + # NAME pnew2_${specimen} + # COMMAND processnew3Down4SgIncGraph3 ${CMAKE_CURRENT_SOURCE_DIR}/${specimen} + # ) + #endforeach() if (enable-binary-analysis) #--------------------------------------------------------------------------- From 2d3bf16db4df4afe44c50a95eff15e12e7b03e71 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 26 Sep 2023 10:15:15 -0400 Subject: [PATCH 13/42] Revert "Removed potentially dead midend code" This reverts commit f9e8ad7bd34ea0db3daee2a3cb315b7a3608ec8f. --- src/midend/astProcessing/CMakeLists.txt | 7 +- src/midend/astProcessing/SgGraphTemplate.h | 201 ++ src/midend/astProcessing/graphProcessing.h | 1560 ++++++++++++++ .../astProcessing/graphProcessingSgIncGraph.h | 1865 +++++++++++++++++ src/midend/astProcessing/graphTemplate.h | 533 +++++ .../functional/roseTests/CMakeLists.txt | 2 +- .../astProcessingTests/CMakeLists.txt | 24 +- 7 files changed, 4174 insertions(+), 18 deletions(-) create mode 100644 src/midend/astProcessing/SgGraphTemplate.h create mode 100644 src/midend/astProcessing/graphProcessing.h create mode 100644 src/midend/astProcessing/graphProcessingSgIncGraph.h create mode 100644 src/midend/astProcessing/graphTemplate.h diff --git a/src/midend/astProcessing/CMakeLists.txt b/src/midend/astProcessing/CMakeLists.txt index ec4582f4c22..075c79f514e 100644 --- a/src/midend/astProcessing/CMakeLists.txt +++ b/src/midend/astProcessing/CMakeLists.txt @@ -32,13 +32,10 @@ set(files_to_install AstReverseSimpleProcessing.h AstRestructure.h AstClearVisitFlags.h AstTraversal.h AstCombinedProcessing.h AstCombinedProcessingImpl.h AstCombinedSimpleProcessing.h StackFrameVector.h - #graphProcessing.h - #graphProcessingSgIncGraph.h - #graphTemplate.h + graphProcessing.h graphProcessingSgIncGraph.h graphTemplate.h AstSharedMemoryParallelProcessing.h AstSharedMemoryParallelProcessingImpl.h AstSharedMemoryParallelSimpleProcessing.h - #SgGraphTemplate.h - TreeTraversal.h) + SgGraphTemplate.h TreeTraversal.h) if(NOT WIN32) #tps commented out AstSharedMemoryParallelProcessing.h for Windows diff --git a/src/midend/astProcessing/SgGraphTemplate.h b/src/midend/astProcessing/SgGraphTemplate.h new file mode 100644 index 00000000000..9429026a6b4 --- /dev/null +++ b/src/midend/astProcessing/SgGraphTemplate.h @@ -0,0 +1,201 @@ +#include +#include +//#include +#include +#include +#include +struct Vertex{ + SgGraphNode* sg; + CFGNode cfgnd; +}; + +struct Edge { + SgDirectedGraphEdge* gedge; +}; + +typedef boost::adjacency_list< + boost::vecS, + boost::vecS, + boost::bidirectionalS, + Vertex, + Edge +> myGraph; + +typedef myGraph::vertex_descriptor VertexID; +typedef myGraph::edge_descriptor EdgeID; + +//myGraph* instantiateGraph(SgIncidencedDirectedGraph* g, StaticCFG::CFG cfg); +std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start); +std::map getGraphNode; +std::map VSlink; + +myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::InterproceduralCFG& cfg, SgNode* pstart) { + //SgNode* prestart = cfg.getEntry(); + //cfg.buildFullCFG(); + CFGNode startN = cfg.getEntry(); + SgGraphNode* start = cfg.toGraphNode(startN); + ROSE_ASSERT(startN != NULL); + ROSE_ASSERT(start != NULL); + myGraph* graph = new myGraph; + //std::map VSlink; + std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); + std::vector nods = alledsnds.first; + std::vector eds = alledsnds.second; + std::set > prs; + //for (std::vector i = nods.begin(); i != nods.end(); i++) { + // VertexID vID = boost::add_vertex(graph); + // graph[vID].cfgnd = cfg->toCFGNode(*i); + //} + for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { + SgDirectedGraphEdge* u = *j; + SgGraphNode* u1 = u->get_from(); + SgGraphNode* u2 = u->get_to(); + VertexID v1; + VertexID v2; + if (VSlink.find(u1) == VSlink.end()) { + v1 = boost::add_vertex(*graph); + getGraphNode[v1] = u1; + VSlink[u1] = v1; + (*graph)[v1].sg = u1; + (*graph)[v1].cfgnd = cfg.toCFGNode(u1); + } + else { + v1 = VSlink[u1]; + } + if (VSlink.find(u2) != VSlink.end()) { + v2 = VSlink[u2]; + } + else { + v2 = boost::add_vertex(*graph); + VSlink[u2] = v2; + (*graph)[v2].sg = u2; + getGraphNode[v2] = u2; + (*graph)[v2].cfgnd = cfg.toCFGNode(u2); + } + bool ok; + EdgeID uE; + std::pair pr; + pr.first = v1; + pr.second = v2; + if (prs.find(pr) == prs.end()) { + prs.insert(pr); + boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); + } + } + //std::cout << "prs.size: " << prs.size() << std::endl; + return graph; +} + + + +myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::CFG& cfg) { + SgGraphNode* start = cfg.getEntry(); + myGraph* graph = new myGraph; + //std::map VSlink; + std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); + std::vector nods = alledsnds.first; + std::vector eds = alledsnds.second; + std::set > prs; + //for (std::vector i = nods.begin(); i != nods.end(); i++) { + // VertexID vID = boost::add_vertex(graph); + // graph[vID].cfgnd = cfg->toCFGNode(*i); + //} + for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { + SgDirectedGraphEdge* u = *j; + SgGraphNode* u1 = u->get_from(); + SgGraphNode* u2 = u->get_to(); + VertexID v1; + VertexID v2; + if (VSlink.find(u1) == VSlink.end()) { + v1 = boost::add_vertex(*graph); + getGraphNode[v1] = u1; + VSlink[u1] = v1; + (*graph)[v1].sg = u1; + (*graph)[v1].cfgnd = cfg.toCFGNode(u1); + } + else { + v1 = VSlink[u1]; + } + if (VSlink.find(u2) != VSlink.end()) { + v2 = VSlink[u2]; + } + else { + v2 = boost::add_vertex(*graph); + VSlink[u2] = v2; + (*graph)[v2].sg = u2; + getGraphNode[v2] = u2; + (*graph)[v2].cfgnd = cfg.toCFGNode(u2); + } + bool ok; + EdgeID uE; + std::pair pr; + pr.first = v1; + pr.second = v2; + if (prs.find(pr) == prs.end()) { + prs.insert(pr); + boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); + } + } + //std::cout << "prs.size: " << prs.size() << std::endl; + return graph; +} + + + + +std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start) { + //for (int i = 0; i < starts.size(); i++) { + SgGraphNode* n = start; + std::vector nods; + std::vector newnods; + std::set edsnew; + std::vector eds; + std::vector feds; + std::vector fnods; + std::set > prs; + std::set oeds = g->computeEdgeSetOut(start); + fnods.push_back(start); + newnods.push_back(n); + + while (oeds.size() > 0) { + for (std::set::iterator j = oeds.begin(); j != oeds.end(); j++) { + //if (find(eds.begin(), eds.end(), *j) == eds.end()) { + if (find(feds.begin(), feds.end(), *j) == feds.end()) { + feds.push_back(*j); + edsnew.insert(*j); + } + if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { + fnods.push_back((*j)->get_to()); + } + newnods.push_back((*j)->get_to()); + //} + } + + for (unsigned int i = 0; i < newnods.size(); i++) { + std::set oedsp = g->computeEdgeSetOut(newnods[i]); + for (std::set::iterator j = oedsp.begin(); j != oedsp.end(); j++) { + if (find(feds.begin(), feds.end(), *j) == feds.end()) { + // feds.push_back(*j); + edsnew.insert(*j); + + } + //if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { + // fnods.push_back((*j)->get_to()); + // newnods.push_back((*j)->get_to()); + // } + // newnods.push_back((*j)->get_to()); + } + } + nods = newnods; + oeds = edsnew; + edsnew.clear(); + newnods.clear(); + } + std::pair, std::vector > retpr; + retpr.first = fnods; + retpr.second = feds; + //std::cout << "fnods.size()" << fnods.size() << std::endl; + //std::cout << "feds.size()" << feds.size() << std::endl; + return retpr; +} + diff --git a/src/midend/astProcessing/graphProcessing.h b/src/midend/astProcessing/graphProcessing.h new file mode 100644 index 00000000000..07cdbd35235 --- /dev/null +++ b/src/midend/astProcessing/graphProcessing.h @@ -0,0 +1,1560 @@ +/* + +FINISH TEMPFLATPATH CODE + +AS WRITTEN, THESE FUNCTIONS WILL ONLY WORK WITH GRAPHS THAT ARE IMPLEMENTED IN THE boost NAMESPACE. + +*/ + + + + +#define LP 1 +#define PERFDEBUG 0 +//#define FULLDEBUG 1 +#ifdef _OPENMP +#include +#endif +#include +#include +#include +#include +#include +#include + +/** +*@file graphProcessing.h + +*Brief Overview of Algorithm: + +*********************** +*Current Implementation +*********************** + +*This implementation uses BOOSTs graph structure to analyze the paths of the graph + +*The path analyzer sends the user paths to be evaluated by the "analyzePath" function that is user defined + +************************** +*Further Improvements: TODO +************************** + +@todo utilize BOOST visitors to take advantage of the BOOST graph structures abilities + +*************** +*Contact Info +*************** + +*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed + +*if I'm still at Lawrence +*hoffman34 AT llnl DOT gov +*@author Michael Hoffman +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include +#include +#include +#include +#include +#include +#include + + + + + + +template +class SgGraphTraversal +{ +public: + + typedef typename boost::graph_traits::vertex_descriptor Vertex; + typedef typename boost::graph_traits:: edge_descriptor Edge; + + void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); + virtual void analyzePath(std::vector& pth) = 0; + std::vector getInEdges(int& node, CFG*& g); + std::vector getOutEdges(int& node, CFG*& g); + int getTarget(int& n, CFG*& g); + int getSource(int& n, CFG*& g); + std::map vertintmap; + std::map edgeintmap; + std::map intvertmap; + std::map intedgemap; + SgGraphTraversal(); + virtual ~SgGraphTraversal(); + SgGraphTraversal( SgGraphTraversal &); + SgGraphTraversal &operator=( SgGraphTraversal &); + int pathnum; + + + void firstPrepGraph(CFG*& g); + +private: + + int normals; + int abnormals; + bool needssafety; + int recursed; + int checkedfound; + // typedef typename boost::graph_traits::vertex_descriptor Vertex; + // typedef typename boost::graph_traits:: edge_descriptor Edge; + // std::vector getInEdges(int& node, CFG*& g); + // std::vector getOutEdges(int& node, CFG*& g); + void prepareGraph(CFG*& g); + void findClosuresAndMarkersAndEnumerate(CFG*& g); + // void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); + // virtual void analyzePath(std::vector& pth) = 0; + // void firstPrepGraph(CFG*& g); + int stoppedpaths; + std::set > traversePath(int begin, int end, CFG*& g, bool loop=false); + std::set > uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& localLoops); + std::vector > bfsTraversePath(int begin, int end, CFG*& g, bool loop=false); + std::vector unzipPath(std::vector& path, CFG*& g, int start, int end); + std::vector zipPath(std::vector& path, CFG*& g, int start, int end); + std::vector zipPath2(std::vector& path, CFG*& g); + void printCFGNode(int& cf, std::ofstream& o); + void printCFGNodeGeneric(int& cf, std::string prop, std::ofstream& o); + void printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o); + void printHotness(CFG*& g); + void printPathDot(CFG*& g); + void computeOrder(CFG*& g, const int& begin); + void computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential); + //int getTarget(int& n, CFG*& g); + //int getSource(int& n, CFG*& g); + std::vector sources; + std::vector sinks; + std::vector recursiveLoops; + std::vector recurses; + std::map ptsNum; + bool borrowed; + std::set badloop; + std::map > > totalLoops; +// int pathnum; + std::map nodeStrings; + int sourcenum; + unsigned long long evaledpaths; + int badpaths; + int workingthreadnum; + bool workingthread; + std::map > > loopStore; + std::vector > pathStore; + std::map > subpathglobal; + std::map, int> subpathglobalinv; + int nextsubpath; + std::vector orderOfNodes; +// std::map vertintmap; +// std::map edgeintmap; +// std::map intvertmap; +// std::map intedgemap; + std::vector > SubGraphGraphMap; + std::vector > GraphSubGraphMap; + std::vector subGraphVector; + void getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath ); + void storeCompact(std::vector path); + int nextNode; + int nextEdge; + std::vector markers; + std::vector closures; + std::map markerIndex; + std::map > pathsAtMarkers; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits::edge_iterator edge_iterator; + bool bound; +// SgGraphTraversal(); +// virtual ~SgGraphTraversal(); +// SgGraphTraversal( SgGraphTraversal &); +// SgGraphTraversal &operator=( SgGraphTraversal &); + + +}; + + +template +SgGraphTraversal:: +SgGraphTraversal() +{ +} + + + +template +SgGraphTraversal & +SgGraphTraversal:: +operator=( SgGraphTraversal &other) +{ + return *this; +} + +#ifndef SWIG + +template +SgGraphTraversal:: +~SgGraphTraversal() +{ +} + +#endif + +/** + Gets the source of an edge + SgGraphTraversal::getSource + Input: + @param[edge] int& integer representation of edge in question + @param[g] CFG*& the CFG used +*/ +template +inline int +SgGraphTraversal:: +getSource(int& edge, CFG*& g) +{ + Edge e = intedgemap[edge]; + Vertex v = boost::source(e, *g); + return(vertintmap[v]); +} + +/** + Gets the target of an edge + SgGraphTraversal::getTarget + Input: + @param[edge] int& integer representation of edge in quesution + @param[g] the CFG*& CFG used +*/ + + +template +inline int +SgGraphTraversal:: +getTarget(int& edge, CFG*& g) +{ + Edge e = intedgemap[edge]; + Vertex v = boost::target(e, *g); + return(vertintmap[v]); +} + +/** +Gets out edges with integer inputs, internal use only +SgGraphTraversal::getInEdges +Input: +@param[node] int, integer representation of the node to get the in edges from +@param[g] CFG* g, CFG +*/ + +template +std::vector +SgGraphTraversal:: +getInEdges(int& node, CFG*& g) +{ + Vertex getIns = intvertmap[node]; + std::vector inedges; + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + in_edge_iterator i, j; +#else + // This does not compile. + in_edge_iterator i = inedges.begin(); + in_edge_iterator j = i; +#endif + for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i) + { + inedges.push_back(edgeintmap[*i]); + } + return inedges; +} + +/** +Gets out edges with integer inputs, internal use only +SgGraphTraversal::getOutEdges +Input: +@param[node] int, integer representation of the node to get the out edges from +@param[g] CFG* g, CFG +*/ + + + +template +std::vector +SgGraphTraversal:: +getOutEdges(int &node, CFG*& g) +{ + Vertex getOuts = intvertmap[node]; + std::vector outedges; + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + out_edge_iterator i, j; +#else + // This does not compile. + out_edge_iterator i = outedges.begin(); + out_edge_iterator j = i; +#endif + for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i) + { + outedges.push_back(edgeintmap[*i]); + } + return outedges; +} + +/** +Condenses paths, currently deprecated... +Input: +@param[pth] std::vector the original path +@param[g] CFG*, the ambient graph +Output: +zipped path +*/ + +template +inline +std::vector +SgGraphTraversal:: +zipPath2(std::vector& pth, CFG*& g) { + std::vector npth; + npth.push_back(pth[0]); + for (int i = 1; i < pth.size()-1; i++) { + if (find(closures.begin(), closures.end(), pth[i]) != closures.end()) { + npth.push_back(pth[i]); + } + } + npth.push_back(pth.back()); + return npth; +} + +/** +Condenses paths to simply the first and last node and the ordered set of edges +taken at nodes with more than 1 outedge +Input: +@param[pth] std::vector, the original path +@param[g] CFG*, the ambient graph +@param[start] integer representation of the first node +@param[end] integer representation of the last node +*/ + + +template +std::vector +SgGraphTraversal:: +zipPath(std::vector& pth, CFG*& g, int start, int end) { + std::vector subpath; + std::vector movepath; + movepath.push_back(pth.front()); + movepath.push_back(pth.back()); + for (unsigned int qw = 0; qw < pth.size()-1; qw++) { + if (find(markers.begin(), markers.end(), pth[qw]) != markers.end()) { + std::vector oeds = getOutEdges(pth[qw], g); + for (unsigned int i = 0; i < oeds.size(); i++) { + if (getTarget(oeds[i], g) == pth[qw+1]) { + movepath.push_back(oeds[i]); + } + } + } + } + return movepath; + } + + + + + + +/** +unzips the paths zipped by zipPath +Input: +@param[pzipped] the zipped path +@param[CFG] the ambient graph +@param[start] the integer representation of the first node (used to check that zipPath is working correctly) +@param[end] the integer representation of the end node +*/ + + +template +std::vector +SgGraphTraversal:: +unzipPath(std::vector& pzipped, CFG*& g, int start, int end) { + ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1)); + std::vector zipped; + for (unsigned int i = 2; i < pzipped.size(); i++) { + zipped.push_back(pzipped[i]); + } + std::vector unzipped; + unzipped.push_back(start); + std::vector oeds = getOutEdges(start, g); + if (oeds.size() == 0) { + return unzipped; + } + for (unsigned int i = 0; i < zipped.size(); i++) { + oeds = getOutEdges(unzipped.back(), g); + while (oeds.size() == 1) { + if (getTarget(oeds[0], g) == end && unzipped.size() != 1) { + unzipped.push_back(end); + return unzipped; + } + unzipped.push_back(getTarget(oeds[0], g)); + oeds = getOutEdges(unzipped.back(), g); + } + if (oeds.size() == 0) { + return unzipped; + } + if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) { + ROSE_ASSERT(getSource(zipped[i], g) == unzipped.back()); + unzipped.push_back(getTarget(zipped[i], g)); + } + + } + std::vector oeds2 = getOutEdges(unzipped.back(), g); + if (unzipped.back() != end && oeds2.size() != 0) { + while (oeds2.size() == 1 && unzipped.back() != end) { + unzipped.push_back(getTarget(oeds2[0], g)); + oeds2 = getOutEdges(unzipped.back(), g); + } + } + return unzipped; +} + +/* +Example Time + + Example: + timeval tim; + gettimeofday(&tim, NULL); + double t1=tim.tv_sec+(tim.tv_usec/1000000.0); + do_something_long(); + gettimeofday(&tim, NULL); + double t2=tim.tv_sec+(tim.tv_usec/1000000.0); + printf("%.6lf seconds elapsed\n", t2-t1); + +*/ + +/** +The function responsible for collecting all paths without loops, and all paths within lops that do not include other loops +then sending those to uTraverse to assemble them into all paths with any combination of loops +Input: +@param[begin] integer representation of the first node +@param[end] integer representation of the last node (or -1 if its not bounded) +@param[g] CFG*, the ambient CFG +@param[loop] boolean expressing whether or not we are calculating paths contained within a loop +*/ + + +template +std::vector > +SgGraphTraversal:: +bfsTraversePath(int begin, int end, CFG*& g, bool loop) { +//perfdebug allows for examining the speed of traversal + #ifdef PERFDEBUG + //timeval tim; + //gettimeofday(&tim, NULL); + //double tim1 = tim.tv_sec+(tim.tv_usec/1000000.0); + #endif + bool recursedloop = loop; + std::map > > PtP; + std::set nodes; + std::vector > pathContainer; + //std::vector > oldPaths; + std::vector completedLoops; + std::vector > npc; + std::vector bgpath; + bgpath.push_back(begin); + pathContainer.push_back(bgpath); + std::vector > newPathContainer; + std::vector > paths; + std::vector localLoops; + std::map > > globalLoopPaths; + //std::cout << "at the while" << std::endl; +//To keep + while (pathContainer.size() != 0 /*|| oldPaths.size() != 0*/) { +/* + unsigned int mpc = 50000; + if (pathContainer.size() == 0) { + unsigned int mxl = 0; + if (oldPaths.size() > mpc) { + mxl = mpc/2; + } + else { + mxl = oldPaths.size(); + } + for (unsigned int k = 0; k < mxl; k++) { + pathContainer.push_back(oldPaths.back()); + oldPaths.pop_back(); + } + } + if (pathContainer.size() > mpc) { + unsigned int j = 0; + while (j < mpc) { + npc.push_back(pathContainer.back()); + pathContainer.pop_back(); + j++; + } + oldPaths.insert(oldPaths.end(), pathContainer.begin(), pathContainer.end()); + pathContainer = npc; + npc.clear(); + } +*/ + +//iterating through the currently discovered subpaths to build them up + for (unsigned int i = 0; i < pathContainer.size(); i++) { + std::vector npth = pathContainer[i]; + std::vector oeds = getOutEdges(npth.back(), g); + std::vector ieds = getInEdges(npth.back(), g); + + npth = pathContainer[i]; + oeds = getOutEdges(npth.back(), g); + + if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) { + std::vector newpth; + newpth = (pathContainer[i]); + std::vector movepath = newpth;//zipPath(newpth, g); + if (recursedloop && newpth.back() == end && newpth.size() != 1) { + paths.push_back(movepath); + } + else if (!recursedloop) { + if (bound && newpth.size() != 1 && newpth.back() == end) { + paths.push_back(movepath); + } + else if (!bound) { + paths.push_back(movepath); + } + } + + } + else { +std::vector oeds = getOutEdges(pathContainer[i].back(), g); + + for (unsigned int j = 0; j < oeds.size(); j++) { + + +int tg = getTarget(oeds[j], g); + + + std::vector newpath = (pathContainer[i]); + //we split up paths into pieces so that they don't take up a lot of memory, basically this is when we run into a path + //more than once, so we attach all paths that go to that path to that particular node via PtP + if (nodes.find(tg) != nodes.end() && find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) { + if (PtP.find(tg) == PtP.end()) { + std::vector nv; + nv.push_back(tg); + newPathContainer.push_back(nv); + PtP[tg].push_back(/*zipPath(*(*/newpath);//, g, newpath.front(), newpath.back())); + } + else { + PtP[tg].push_back(/*zipPath(*/newpath);//, g, newpath.front(), newpath.back())); + } + } + else if (find(newpath.begin(), newpath.end(), getTarget(oeds[j], g)) == newpath.end() || getTarget(oeds[j], g) == end) { + newpath.push_back(tg); + std::vector ieds = getInEdges(tg, g); + if (ieds.size() > 1) {//find(closures.begin(), closures.end(), tg) != closures.end()) { + nodes.insert(tg); + } + newPathContainer.push_back(newpath); + } + else if (tg == end && recursedloop) { + newpath.push_back(tg); + newPathContainer.push_back(newpath); + } + else {//if (find(newpath.begin(), newpath.end(), tg) != newpath.end() && tg != end) { + std::vector ieds = getInEdges(tg, g); + if (ieds.size() > 1/*find(closures.begin(), closures.end(), tg) != closures.end()*/ && find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() /*&& find(localLoops.begin(), localLoops.end(), tg) == localLoops.end()*/ && find(recurses.begin(), recurses.end(), tg) == recurses.end()) { + localLoops.push_back(tg); + nodes.insert(tg); + } + // else if (find(recurses.begin(), recurses.end(), tg) != recurses.end()) { + // } + } + //else { + // std::cout << "problem" << std::endl; + // ROSE_ASSERT(false); + // } + } + } + } + pathContainer = newPathContainer; + newPathContainer.clear(); + } + // std::cout << "done while" << std::endl; + pathContainer.clear(); + std::vector > finnpts; + std::vector > npts; + while (true) { + if (paths.size() > 1000000) { + std::cout << "too many paths, consider a subgraph" << std::endl; + ROSE_ABORT(); + } + //#pragma omp parallel for schedule(guided) + for (unsigned int qq = 0; qq < paths.size(); qq++) { + std::vector pq = paths[qq]; + std::vector qp; + int ppf = paths[qq].front(); + if (PtP.find(ppf) != PtP.end()) { + for (unsigned int kk = 0; kk < PtP[ppf].size(); kk++) { + std::vector newpath = /*unzipPath(*/PtP[ppf][kk];//, g, PtP[ppf][kk][0], PtP[ppf][kk][1]); + bool good = true; + if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) { + good = false; + } + else { + + // if (find(pq.begin(), pq.end(), newpath.front()) != pq.end() && newpath.front() != begin) { + // good = false; + // } + + + // else { + for (unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) { + + /* + if (newpath.front() == newpath.back()) { + good = false; + break; + } + else */if (find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) { + good = false; + break; + + } + } + //} + } + if (good) { + newpath.insert(newpath.end(), pq.begin(), pq.end()); + #pragma omp critical + { + npts.push_back(newpath); + } + } + } + } + else { + std::vector ppq = pq;// zipPath(pq, g, pq.front(), pq.back()); + #pragma omp critical + { + finnpts.push_back(ppq); + } + } + } + if (npts.size() == 0) { + break; + } + else { + paths = npts; + npts.clear(); + } + } + paths = finnpts; + finnpts.clear(); + for (unsigned int k = 0; k < localLoops.size(); k++) { + int lk = localLoops[k]; + std::vector > loopp; + if (loopStore.find(localLoops[k]) != loopStore.end()) { + loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end()); + } + else { + std::map > > localLoopPaths; + completedLoops.push_back(lk); + recurses.push_back(lk); + loopp = bfsTraversePath(lk, lk, g, true); + recurses.pop_back(); + } + for (unsigned int ik = 0; ik < loopp.size(); ik++) { + + if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) { + globalLoopPaths[localLoops[k]].push_back(loopp[ik]); + } + } + + + + } + borrowed = true; + std::vector > lps2; + //unsigned int maxpaths = 1000; + //unsigned int pathdivisor = 1;//paths.size()/maxpaths;///paths.size(); + + //if (pathdivisor < 1) { + //pathdivisor = 1; + //maxpaths = paths.size(); + // } +/* + for (unsigned int j = 0; j < pathdivisor+1; j++) { + std::vector > npaths; + std::vector dummyvec; + unsigned int mxpths; + if (j < pathdivisor) { + mxpths = maxpaths; + } + else { + mxpths = paths.size() % pathdivisor; + } + for (unsigned int k = 0; k < mxpths; k++) { + npaths.push_back(paths.back());//unzipPath(paths.back(), g, begin, end)); + paths.pop_back(); + } +*/ + pathStore = paths; + paths.clear(); + if (!recursedloop) { + uTraversePath(begin, end, g, false, globalLoopPaths); + } + else { + recursed++; + + std::set > lps = uTraversePath(begin, end, g, true, globalLoopPaths); + recursed--; + for (std::set >::iterator ij = lps.begin(); ij != lps.end(); ij++) { + std::vector ijk = (*ij); + + lps2.push_back(*ij); + } + } + //} + #ifdef PERFDEBUG + // timeval tim; + //std::cout << "begin: " << begin << " end: " << end << std::endl; + //gettimeofday(&tim, NULL); + //double tim2 = tim.tv_sec+(tim.tv_usec/1000000); + //double timeRet = tim2 - tim1; + //std::cout << "bfs time elapsed: " << timeRet << std::endl; + #endif + return lps2; + +} + + +/** +This function calculates all the permutations of loops on paths +it also throws away duplicate paths +Input: +@param[begin] integer representation of first node +@param[end] integer representation of the final node +@param[g] ambient CFG +@param[globalLoopPaths] connects an integer representation of a node to all possible loops starting at that node +*/ + + +template +std::set > +SgGraphTraversal:: +uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& globalLoopPaths) { + //std::cout << "uTraverse" << std::endl; + //int doubledpaths = 0; + int newmil = 1; + //#ifdef LP + //if (loop && loopStore.find(begin) != loopStore.end()) { + // return loopStore[begin]; + //} + //#endif + #ifdef PERFDEBUG + //timeval tim; + //gettimeofday(&tim, NULL); + //double t1 = tim.tv_sec+(tim.tv_usec/1000000); + #endif + std::set > newpaths; + std::set > npaths; + pathnum = 0; + std::vector path; + std::vector > paths; + int truepaths = 0; + std::vector > checkpaths; + std::vector > npathchecker; + std::map currents; + //int nnumpaths = 0; + std::set > loopPaths; + //bool threadsafe = true; + bool done = false; + std::set > fts; + //double ttfors = 0; + //double tperms = 0; + while (true) { + //std::cout << "paths.size() " << paths.size() << std::endl; + if (paths.size() > 1000000) { + std::cout << "nearly 1 million paths with no loops, stopping" << std::endl; + return loopPaths; + std::cout << "ended early" << std::endl; + } + if (done || borrowed) { + + if (borrowed) { + paths = pathStore; + pathStore.clear(); + } + //std::cout << "paths.size(): " << paths.size() << std::endl; + if (paths.size() != 0) { + } + else { + return loopPaths; + } + + // #pragma omp parallel + // { + #pragma omp parallel for schedule(guided) + for (unsigned int qqq = 0; qqq < paths.size(); qqq++) { + // std::cout << "pathcheck" << std::endl; + //int pathevals = 0; + //std::vector zpt = zipPath2(paths[qqq], g); + //std::set > boxpaths; + std::set > movepaths; + std::vector path;// = paths[qqq]; + path = paths[qqq];//unzipPath(paths[qqq], g, begin, end); + truepaths++; + int permnums = 1; + std::vector perms; + std::vector qs; + std::map > > localLoops; + std::vector takenLoops; + takenLoops.push_back(path[0]); + bool taken = false; + //timeval timfor; + int lost = 0; + //gettimeofday(&timfor, NULL); + //double t1for = timfor.tv_sec + (timfor.tv_usec/1000000); + for (unsigned int q = 1; q < path.size()-1; q++) { + //if (find(closures.begin(), closures.end(), path[q]) != closures.end()) { + if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() /*&& find(lloops.begin(), lloops.end(), path[q]) != lloops.end()*/ && globalLoopPaths[path[q]].size() != 0 /*&& path[q] != begin && path[q] != end*/) { + for (unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) { + + std::vector gp = globalLoopPaths[path[q]][qp1]; //unzipPath(globalLoopPaths[path[q]][qp1],g,path[q],path[q]); + // std::vector zgp = zipPath2(globalLoopPaths[zpt[q]][qp1], g); + for (unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) { + if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) { + taken = true; + } + } + + if (!taken) { + localLoops[path[q]].push_back(gp); + } + else { + lost++; + taken = false; + } + } + if (localLoops[path[q]].size() != 0) { + takenLoops.push_back(path[q]); + permnums *= (localLoops[path[q]].size()+1); + perms.push_back(permnums); + qs.push_back(path[q]); + } + } + } + + //} + //if (loop) { + //std::cout << "lostloop: " << lost << std::endl; + //} + //else { + //std::cout << "lostpath: " << lost << std::endl; + //} + //std::cout << "endpathcheck" << std::endl; + //std::cout << "rest" << std::endl; + //std::cout << "permnums: " << permnums << std::endl; + //gettimeofday(&timfor, NULL); + //double t2for = timfor.tv_sec + (timfor.tv_usec/1000000); + //double ttfor = t2for - t1for; + //#pragma omp atomic + //ttfors += ttfor; + + //std::set > movepaths2; + std::set > movepathscheck; + //timeval timperms; + //gettimeofday(&timperms, NULL); + // double t1perm = timperms.tv_sec + (timperms.tv_usec/1000000); + std::vector nvec; + std::vector > boxpaths(permnums, nvec); + //#pragma omp parallel for schedule(guided) + for (int i = 1; i <= permnums; i++) { + //bool goodthread = false; + std::vector loopsTaken; + //bool stop = false; + unsigned int j = 0; + std::vector npath; + while (true) { + if (j == perms.size() || perms[j] > i) { + break; + } + else { + j++; + } + } + int pn = i; + std::vector pL; + for (unsigned int j1 = 0; j1 <= j; j1++) { + pL.push_back(-1); + } + for (unsigned int k = j; k > 0; k--) { + int l = 1; + while (perms[k-1]*l < pn) { + l++; + } + pL[k] = l-2; + pn -= (perms[k-1]*(l-1)); + } + pL[0] = pn-2; + + unsigned int q2 = 0; + for (unsigned int q1 = 0; q1 < path.size(); q1++) { + if (q2 < qs.size()) { + if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (size_t)q2 != pL.size()) { + if (pL[q2] == -1) { + npath.push_back(path[q1]); + } + else { + // if (!stop) { + npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(), + localLoops[path[q1]][pL[q2]].end()); + // } + } + q2++; + } + else { + npath.push_back(path[q1]); + } + } + else { + npath.push_back(path[q1]); + } + } + #ifdef FULLDEBUG + std::cout << "path: " << std::endl; + for (int qe = 0; qe < npath.size(); qe++) { + std::cout << ", " << npath[qe]; + } + std::cout << std::endl; + std::cout << "permnum: " << i << std::endl; + #endif + // bool addit = false; + //if (!stop) { + // if (loop && npath.front() == npath.back()) { + // addit = true; + // } + // else if (!loop && bound && npath.front() == begin && npath.back() == end && npath.size() != 1) { + // addit = true; + // } + // else if (!loop && !bound) { + // addit = true; + // } + // if (!addit) { + // std::cout << "bad path" << std::endl; + // } + //bool extra = false; + //if (addit && !loop) { + //if (movepathscheck.find(npath) == movepathscheck.end()) { + //int mpc = movepathscheck.size(); + //std::set > movepathspre = movepathscheck; + // movepaths2.insert(npath); + //movepathscheck.insert(npath); + //ROSE_ASSERT(movepathscheck.size() == mpc || movepathspre.find(npath) == movepathspre.end()); + //if (movepathscheck.size() == mpc) { + // extra = true; + // } + + //} + //else { + //#pragma omp atomic + // doubledpaths++; + // } + //} + + //if (!workingthread || threadsafe) { + //if ((newpaths.size() > 1 || i == permnums || threadsafe)) { + // } + // } + + // } + //if (!extra) + // { + //if (movepaths2.size() > 0) //|| i == permnums || threadsafe) + // #pragma omp critical + // { + boxpaths[i-1] = npath; + // } + // } + //std::cout << "endrest" << std::endl; + } + + evaledpaths += boxpaths.size(); + if (evaledpaths > newmil*100000ull) { + //std::cout << "evaledpaths: " << evaledpaths << std::endl; + newmil++; + } + // #pragma omp critical + // { + if (!loop) { + for (std::vector >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) { + std::vector verts; + getVertexPath((*box), g, verts); + #pragma omp critical + { + analyzePath(verts); + } + } + } + else { + #pragma omp critical + { + loopPaths.insert(boxpaths.begin(), boxpaths.end());; + } + } + } + } + //} + +/* + #pragma omp atomic + evaledpaths++; + //pathevals++; + if (evaledpaths % 10000 == 0 && evaledpaths != 0) { + std::cout << "evaled paths: " << evaledpaths << std::endl; + } + if (!loop) { + std::vector verts; + getVertexPath(npath, g, verts); + #pragma omp critical + { + #ifdef FULLDEBUG + for (unsigned int aa = 0; aa < npath.size(); aa++) { + if (ptsNum.find(npath[aa]) != ptsNum.end()) { + ptsNum[npath[aa]] += 1; + } + else { + ptsNum[npath[aa]] = 1; + } + } + #endif + analyzePath(verts); + } + } + else if (loop) + { + //std::vector zpth = zipPath(npath, g, npath.front(), npath.back()); + #pragma omp critical + { + loopPaths.insert(npath);//zipPath(npath, g, npath.front(), npath.back())); + } + } + else { + } + + } +*/ + + // movepaths2.clear(); + + // std::cout << "permnums: " << permnums << std::endl; + // std::cout << "evaledpaths final: " << pathevals << std::endl; + //gettimeofday(&timperms, NULL); + //double t2perm = timperms.tv_sec+(timperms.tv_usec/1000000); + //#pragma omp atomic + //tperms += t2perm - t1perm; + // } + //} + //} + //} + + + + + + + #ifdef PERFDEBUG + //gettimeofday(&tim, NULL); + // double t2 = tim.tv_sec+(tim.tv_usec/1000000.0); + // double tperm = t2 - t1perm + //double tX = t2 - t1; + //std::cout << "begin: " << begin << " end: " << end << std::endl; + // std::cout << "uTraverse time: " << tX << std::endl; + // std::cout << "tperms: " << tperms << std::endl; + // std::cout << "ttfors: " << ttfors << std::endl; + // std::cout << "doubledpaths: " << doubledpaths << std::endl; + #endif + #ifdef LP + if (loop) { + #ifdef PERFDEBUG + // std::cout << "loopPaths: " << loopPaths.size() << std::endl; + #endif + loopStore[begin] = loopPaths; + } + #endif + return loopPaths; + + } + } + + + + + + + + +/** +This is the function that is used by the user directly to start the algorithm. It is immediately available to the user + +SgGraphTraversal::constructPathAnalyzer +Input: +@param[begin] Vertex, starting node +@param[end] Vertex, endnode +@param[g] CFG* g, CFG calculated previously +*/ + + +template +void +SgGraphTraversal:: +constructPathAnalyzer(CFG* g, bool unbounded, Vertex begin, Vertex end, bool ns) { + abnormals = 0; + normals = 0; + if (ns) { + needssafety = true; + } + else { + needssafety = false; + } + checkedfound = 0; + recursed = 0; + nextsubpath = 0; + borrowed = true; + stoppedpaths = 0; + evaledpaths = 0; + badpaths = 0; + sourcenum = 0; + prepareGraph(g); + workingthread = false; + workingthreadnum = -1; + //std::cout << "markers: " << markers.size() << std::endl; + //std::cout << "closures: " << closures.size() << std::endl; + //std::cout << "sources: " << sources.size() << std::endl; + //std::cout << "sinks" << sinks.size() << std::endl; +// printHotness(g); + bool subgraph = false; + if (!subgraph) { + if (!unbounded) { + bound = true; + recursiveLoops.clear(); + recurses.clear(); + std::vector > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g); + // std::cout << "spaths: " << spaths.size() << std::endl; + } + else { + std::set usedsources; + bound = false; + std::vector localLps; + for (unsigned int j = 0; j < sources.size(); j++) { + sourcenum = sources[j]; + recursiveLoops.clear(); + recurses.clear(); + std::vector > spaths = bfsTraversePath(sources[j], -1, g); + + + } + } + } + //std::cout << "checkedfound: " << checkedfound << std::endl; + printHotness(g); +} + +/** DEPRECATED +This is a function to construct subgraphs for parallelization +SgGraphTraversal::computeSubGraphs +Input: +@param[begin] const int, starting point +@param[end] const int ending point +@param[g] const CFG*, control flow graph to compute +@param[depthDifferential] int, used to specify how large the subgraph should be + */ + +template +void +SgGraphTraversal:: +computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential) { + int minDepth = 0; + int maxDepth = minDepth + depthDifferential; + int currSubGraph = 0; + CFG* subGraph; + std::set foundNodes; + while (true) { + Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]); + GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin]; + SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]]; + for (int i = minDepth; i <= maxDepth; i++) { + Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]]; + std::vector outEdges = getOutEdges(orderOfNodes[i], g); + for (unsigned int j = 0; j < outEdges.size(); j++) { + Vertex u; + if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) { + u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]]; + } + else { + u = boost::add_vertex(*subGraphVector[currSubGraph]); + foundNodes.insert(getTarget(outEdges[j], g)); + SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)]; + GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u; + + } + Edge edge; + bool ok; + boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]); + } + } + minDepth = maxDepth; + if ((unsigned int) minDepth == orderOfNodes.size()-1) { + break; + } + maxDepth += depthDifferential; + if ((unsigned int) maxDepth > orderOfNodes.size()-1) + { + maxDepth = orderOfNodes.size()-1; + } + CFG* newSubGraph; + subGraphVector.push_back(newSubGraph); + currSubGraph++; + } + return; +} + + +/* +These should NOT be used by the user. They are simply for writing interesting information on the DOT graphs of the CFG +*/ + + + + template + void + SgGraphTraversal:: + printCFGNodeGeneric(int &cf, std::string prop, std::ofstream& o) { + std::string nodeColor = "black"; + o << cf << " [label=\"" << " num:" << cf << " prop: " << prop << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; + } + + template + void + SgGraphTraversal:: + printCFGNode(int& cf, std::ofstream& o) + { + #ifdef FULLDEBUG + int pts = ptsNum[cf]; + std::string nodeColor = "black"; + o << cf << " [label=\"" << " pts: " << pts << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; + #endif + #ifndef FULLDEBUG + std::string nodeColor = "black"; + o << cf << " [label=\"" << " num:" << cf << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; + #endif + + } + + template + void + SgGraphTraversal:: + printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o) + { + int src = getSource(cf, cfg); + int tar = getTarget(cf, cfg); + o << src << " -> " << tar << " [label=\"" << src << " " << tar << "\", style=\"" << "solid" << "\"];\n"; + } + + template + void + SgGraphTraversal:: + printHotness(CFG*& g) + { + const CFG* gc = g; + int currhot = 0; + std::ofstream mf; + std::stringstream filenam; + filenam << "hotness" << currhot << ".dot"; + currhot++; + std::string fn = filenam.str(); + mf.open(fn.c_str()); + + mf << "digraph defaultName { \n"; + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + vertex_iterator v, vend; + edge_iterator e, eend; +#else + // This does not compile. + vertex_iterator v = vertices(*gc).begin(); + vertex_iterator vend = v; + edge_iterator e = edges(*gc).begin(); + edge_iterator eend = e; +#endif + for (boost::tie(v, vend) = vertices(*gc); v != vend; ++v) + { + printCFGNode(vertintmap[*v], mf); + } + for (tie(e, eend) = edges(*gc); e != eend; ++e) + { + printCFGEdge(edgeintmap[*e], g, mf); + } + mf.close(); + } + template + void + SgGraphTraversal:: + printPathDot(CFG*& g) + { + const CFG* gc = g; + std::ofstream mf; + std::stringstream filenam; + filenam << "pathnums.dot"; + std::string fn = filenam.str(); + mf.open(fn.c_str()); + + mf << "digraph defaultName { \n"; + vertex_iterator v, vend; + edge_iterator e, eend; + for (tie(v, vend) = vertices(*gc); v != vend; ++v) + { + if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) { + int nn = vertintmap[*v]; + printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf); + } + else { + printCFGNodeGeneric(vertintmap[*v], "noprop", mf); + } + } + for (tie(e, eend) = edges(*gc); e != eend; ++e) + { + printCFGEdge(edgeintmap[*e], g, mf); + } + + mf.close(); + } + + + +/** +This is the function that preps the graph for traversal + +SgGraphTraversal::prepareGraph +Input: +@param[g] CFG*& g, CFG calculated previously +*/ + + +template +void +SgGraphTraversal:: +prepareGraph(CFG*& g) { + nextNode = 1; + nextEdge = 1; + findClosuresAndMarkersAndEnumerate(g); +} + + +/** +DEPRECATED +This is the function that preps the graph for traversal, currently this one isn't used but for many traversals on one visitor +may necessitate + +SgGraphTraversal::firstPrepGraph +Input: +@param[g] CFG*& g, CFG calculated previously +*/ + + +template +void +SgGraphTraversal:: +firstPrepGraph(CFG*& g) { + nextNode = 1; + nextEdge = 1; + findClosuresAndMarkersAndEnumerate(g); +} + +/** +This calculates nodes with more than one in edge or more than one out edge + +SgGraphTraversal::findClosuresAndMarkers +Input: +@param[g] CFG*& g, CFG calculated previously +*/ + + + + +template +void +SgGraphTraversal:: +findClosuresAndMarkersAndEnumerate(CFG*& g) +{ + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + edge_iterator e, eend; +#else + edge_iterator e = edges(*g).begin(); + edge_iterator eend = e; +#endif + for (tie(e, eend) = edges(*g); e != eend; ++e) { + intedgemap[nextEdge] = *e; + edgeintmap[*e] = nextEdge; + nextEdge++; + } + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + vertex_iterator v1, vend1; +#else + vertex_iterator v1 = vertices(*g).begin(); + vertex_iterator vend1 = v1; +#endif + for (boost::tie(v1, vend1) = vertices(*g); v1 != vend1; ++v1) + { + vertintmap[*v1] = nextNode; + intvertmap[nextNode] = *v1; + nextNode++; + } + // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. +#if 1 + vertex_iterator v, vend; +#else + vertex_iterator v = vertices(*g).begin(); + vertex_iterator vend = v; +#endif + for (boost::tie(v, vend) = vertices(*g); v != vend; ++v) { + std::vector outs = getOutEdges(vertintmap[*v], g); + std::vector ins = getInEdges(vertintmap[*v], g); + if (outs.size() > 1) + { + markers.push_back(vertintmap[*v]); + + markerIndex[vertintmap[*v]] = markers.size()-1; + for (unsigned int i = 0; i < outs.size(); i++) { + pathsAtMarkers[vertintmap[*v]].push_back(getTarget(outs[i], g)); + } + } + if (ins.size() > 1) + { + closures.push_back(vertintmap[*v]); + } + if (outs.size() == 0) { + sinks.push_back(vertintmap[*v]); + } + if (ins.size() == 0) { + sources.push_back(vertintmap[*v]); + } + } + return; +} + + + +/** DEPRECATED +Currently unused but will be necessary for parallelization in progress +SgGraphTraversal::computeOrder +@param[g] CFG* cfg in question +@parm[begin] const int, integer representation of source node +*/ +template +void +SgGraphTraversal:: +computeOrder(CFG*& g, const int& begin) { + std::vector currentNodes; + std::vector newCurrentNodes; + currentNodes.push_back(begin); + std::map reverseCurrents; + orderOfNodes.push_back(begin); + std::set heldBackNodes; + while (currentNodes.size() != 0) { + for (unsigned int j = 0; j < currentNodes.size(); j++) { + + std::vector inEdges = getInEdges(currentNodes[j], g); + if (inEdges.size() > 1) { + if (reverseCurrents.find(currentNodes[j]) == reverseCurrents.end()) { + reverseCurrents[currentNodes[j]] = 0; + } + if ((unsigned int) reverseCurrents[currentNodes[j]] == inEdges.size() - 1) { + heldBackNodes.erase(currentNodes[j]); + reverseCurrents[currentNodes[j]]++; + std::vector outEdges = getOutEdges(currentNodes[j], g); + for (unsigned int k = 0; k < outEdges.size(); k++) { + newCurrentNodes.push_back(getTarget(outEdges[k], g)); + orderOfNodes.push_back(getTarget(outEdges[k], g)); + } + } + else if (reverseCurrents[currentNodes[j]] < reverseCurrents.size()) { + reverseCurrents[currentNodes[j]]++; + if (heldBackNodes.find(currentNodes[j]) == heldBackNodes.end()) { + heldBackNodes.insert(currentNodes[j]); + } + } + } + else { + std::vector outEdges = getOutEdges(currentNodes[j], g); + for (unsigned int k = 0; k < outEdges.size(); k++) { + newCurrentNodes.push_back(getTarget(outEdges[k], g)); + orderOfNodes.push_back(getTarget(outEdges[k], g)); + + } + } + } + if (newCurrentNodes.size() == 0 && heldBackNodes.size() != 0) { + for (std::set::iterator q = heldBackNodes.begin(); q != heldBackNodes.end(); q++) { + int qint = *q; + std::vector heldBackOutEdges = getOutEdges(qint, g); + for (unsigned int p = 0; p < heldBackOutEdges.size(); p++) { + newCurrentNodes.push_back(getTarget(heldBackOutEdges[p], g)); + } + } + heldBackNodes.clear(); + } + currentNodes = newCurrentNodes; + newCurrentNodes.clear(); + } + return; +} + +/** +Converts the path calculated by this algorithm to Vertices so users can +access data +SgGraphTraversal::getVertexPath +@param[path] integer representation of path +@param[g] CFG*, cfg in question +@param[vertexPath] for some reason this can't be a return value so it is changed via pass by reference +*/ + +template +void +SgGraphTraversal:: +getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath) { + for (unsigned int i = 0; i < path.size(); i++) { + vertexPath.push_back(intvertmap[path[i]]); + } + + + +} + +/** +DEPRECATED +Currently unused, may eventually be modified for optimal storage purposes +SgGraphTraversal::storeCompact +@param[compactPath] path to be compactified +*/ +template +void +SgGraphTraversal:: +storeCompact(std::vector compactPath) { +return; +} + + + + + diff --git a/src/midend/astProcessing/graphProcessingSgIncGraph.h b/src/midend/astProcessing/graphProcessingSgIncGraph.h new file mode 100644 index 00000000000..382dc09079d --- /dev/null +++ b/src/midend/astProcessing/graphProcessingSgIncGraph.h @@ -0,0 +1,1865 @@ +/* + +FINISH TEMPFLATPATH CODE + +*/ + + + + +// Original Author (SgGraphTraversal mechanisms): Michael Hoffman +//$id$ +#include +#include +#include +#include +#include + +/** +*@file graphProcessing.h + +*Brief Overview of Algorithm: + +*********************** +*Current Implementation +*********************** + +*The idea behind the algorithm here is to decompose the given Control Flow Graph into a Tree structure (still stored as a Control Flow Graph, though it may be possible to change this). This tree splits on children of a graph node, but does not connect in the case of multiple parents of a single node. In this we refer to out nodes as "children" and in nodes as "parents". However, we do this from the end node to the start node. This is best because then you get one value on the end node, and that value is the only one we want (however, the function takes a pointer to an empty SgIncidenceDirectedGraph as an argument, this can then be analyzed post traversal if that is wanted. + +*Also, following the algorithm explained above, one must realize that the tree has one leaf for EACH path. Thus small programs can lead from a small-ish graph to a VERY large tree. For example, a program with 20 if else statements would end with 2^20 paths, which means the number of nodes in the tree is greater than this. Thus with 32 or 64 you can overflow a 32 or 64 bit integer. + +*However, this can be partially resolved by setting the deleteTree boolean to true. This is set to false as the default, however if you don't need the tree then deleteTree will allow you to deal with much larger trees and thus much larger original graphs. + +*Realize that because of the potentially massive growth rate of path number, that in large cases path enumeration and counting is extremely prohibitive, as it is not difficult to create a program which has more paths than 2^64, thus an unsigned (signed?) 64 bit integer could not store the number. + +*Further, this is still a relatively compact method. You could just as easily force enumeration of paths, which could in some cases drastically increase the number of nodes necessary to store all the information. + +*The advantage of the tree structure is two-fold. First it relieves the algorithm of having to keep even more in memory than it has to at the moment, and if you want to deal with GoTo statements, one case can develop that cannot be solved otherwise, e.g. + +*Consider the four node tree with nodes a, b, c, d, and edges atb, atc, btc, ctb, btd, ctd. There are FOUR legitimate paths here (a, b, d; a, b, c, d; a, c, d; a, c, b, d), and any other method would recognize this as a loop and, without a special algorithm for loop behavior, this would be ignored. + +*The tree structure also allows for very strong parallelization, currently implemented in openMP. This is because depth has meaning in terms of a tree (it doesn't in terms of a general graph) and that you know you can evaluate all nodes at a certain depth if you have solved all the nodes at depth + 1. + +************************** +*Further Improvements: TODO +************************** + +@todo *One improvement that should be implemented ASAP is changing the algorithm from a recursive algorithm to an iterative algorithm. Keeping the memory requirements down is much easier in this form and would probably increase the size of graph that the algorithm can handle. + +@todo *Another improvement that should be implemented when possible is to allow for loop analysis. This could be implemented by simply running the algorithm on the loop, but there would need to be a provision that kept the algorithm from stopping as soon as it starts. This could be done by separating the node into two nodes, one with all the inedges and one with all the outedges. OR one could collect the loops when they are deleted (the whole loop is calculated necessarily), though nested loops would have to be considered further in order to find a way to deal with them. + +@todo *It is possible that graph matching algorithms might prove useful to distinguish different types of graphs contained within the CFG and optimize traversal over them. Look up graph matching algorithms or pattern matching (potentially) for more information on such algorithms, though I do not believe there is an existant literature on matching subgraphs for this purpose. + +@todo *The parallelism in this program should be optimized by someone experienced in parallelization optimization + +*************** +*Contact Info +*************** + +*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed + +*archangel DOT associate AT gmail DOT com +*or, if I'm still at Lawrence +*hoffman34 AT llnl DOT gov +*@author Michael Hoffman +*/ + + + + + +#include "staticCFG.h" +#include +#include +#include +#include +#include +#include +//#include "graphBot.h" + +//This is necessary for technical reasons with regards to the graphnodeinheritedmap + + + +struct Bot { + std::vector > path; + std::vector > pthloops; + std::vector currpth; + std::vector > nodelst; + bool on; + bool remove; +}; + +double timeDifference(const struct timeval& end, const struct timeval& begin) +{ + return (end.tv_sec + end.tv_usec / 1.0e6) - (begin.tv_sec + begin.tv_usec / 1.0e6); +} + +static inline timeval getCPUTime() { + rusage ru; + getrusage(RUSAGE_SELF, &ru); + return ru.ru_utime; +} + + +struct compareSgGraphNode { + bool operator()(const SgGraphNode* a, const SgGraphNode* b) const + { + return a==b; + } +}; + + +/* The SgGraphTraversal class is utilized specifically for StaticCFG traversals, +though the input must be in terms of a SgIncidenceDirectedGraph*/ +template +class SgGraphTraversal +{ + public: + std::set > > subpathmap; + int loopNum; + int nullNum; + std::set nullEdgesOrdered; + std::map loopNumMap; + std::map pathValMap; + int nullloops; + std::vector > looppaths; + std::vector > iLoops; + std::vector ifstatements; + virtual ~SgGraphTraversal(); + SgGraphTraversal(); + // Copy operations + int nullEdgesPaths; + int turns; + SgGraphTraversal(const SgGraphTraversal &); + const SgGraphTraversal &operator=(const SgGraphTraversal &); + //This is not used, but will be important if SynthesizedAttributes become useful + typedef StackFrameVector SynthesizedAttributesList; + //one of the most important structures in the algorithm, this attaches SgGraphNode*s to InheritedAttributeTypes so that + //looking up the values is possible. + //int numnodes; + //std::map seen; + int numnodes; + //InheritedAttributeType pthgraphinherit; + //StaticCFG::CFG* SgCFG; + SgGraphNode* nullnode; + std::map primenode; + bool done; + //std::set startnodes; + std::set lstN; + std::map > > lstordmap; + std::set solvedLoops; + std::map > checkednodes; + std::map > downed; + + //std::map nodeinedgordmap; + //a value for nodes that have no value, set in the traverse function + InheritedAttributeType nullInherit; + //the user invoked function, runs the algorithm + InheritedAttributeType traverse(SgGraphNode* basenode, SgIncidenceDirectedGraph* g, + InheritedAttributeType inheritedValue, InheritedAttributeType nullInherit, + SgGraphNode* endnode, bool insep = false, bool pcHk = false); + std::set loopSet; + + protected: + //User defined functions to do whatever is needed in evaluation + //All the user gets access to is the node in question + //and the values of the parent nodes (this should be all that is necessary) + virtual InheritedAttributeType evaluateInheritedAttribute(SgGraphNode* n, + std::vector inheritedValues) = 0; + //Not used, but may be useful if SynthesizedAttributes become workable in this context + virtual SynthesizedAttributeType evaluateSynthesizedAttribute(SgGraphNode* n, + InheritedAttributeType in, + SynthesizedAttributesList l) = 0; + +#if !USE_ROSE + // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct, + // namely that the value of a reference must be an lvalue (not NULL). But since we are only trying + // to compile ROSE with ROSE (using the new EDG 4.3 front-end as a tests) we can just skip this case for now. + virtual void pathAnalyze(std::vector& pth, bool loop=false, std::set >& incloops=NULL) = 0; +#else + virtual void pathAnalyze(std::vector& pth, bool loop, std::set >& incloops) = 0; +#endif + + //also not used, but important for possible later use of SynthesizedAttributes + SynthesizedAttributeType defaultSynthesizedAttribute(InheritedAttributeType); + private: + double distime; + //std::set, std::pair > > flpset; + //std::set, std::pair > > goodset; + std::set ploops; + std::map > > lpbegins; + std::map frksLeft; + int currm; + int dpMax; + int repEval; + bool pathCheck; + int pathsSize; + //this constructs the graph tree for computation of inheritedValues + + + std::map known; + std::vector connectNodes; + std::map solved; + std::set solvedset; + //these two are not used, but will be important if SynthesizedAttributes are made reasonable in this context + SynthesizedAttributesList *synthesizedAttributes; + SynthesizedAttributeType traversalResult(); + //finally we have two functions necessary for parallel processing if that is chosen to be used by the user + + + + + std::map nodeInEdgesNum; + int currprime; + std::vector endnodefakes; + std::map > > pathsAtMk; + std::set mkloops; + std::map > > mkloopmap; + std::map > > subPathsAtMk; + std::vector mkglobal; + std::vector clglobal; + bool inseparable; + void solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); + std::vector > closuresVec; + void evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); + void evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); + bool disjoint(std::vector& path, std::vector& vec2) const; + std::set > flatpaths; +// void evalNode(SgIncidenceDirectedGraph* g, SgGraphNode* n); + bool canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n); + std::map inhVals; + std::set seenEdges; + std::set nullEdges; + std::set clsT; + void computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); + void computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); + std::pair getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n); + std::pair getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n); + bool computable(SgIncidenceDirectedGraph* g, SgGraphNode* n); + void evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); + std::map oVals; + bool canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n); + void setPathVal(SgIncidenceDirectedGraph*g, SgGraphNode* n); + void printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss); + void printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss); + void printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream& ss); + std::set completedNodesPath; + std::set > completedEdgesPath; + void printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream& ss); + void printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream& ss); + std::map iVals; + + std::set nullEdgesOrderedOut; + std::set completedEdgesOut; + std::set completedEdges; + std::set compPar; + std::set compChild; + std::set computedNodes; + SgGraphNode* st; + SgGraphNode* en; + double fllp; + int loopnum; + //std::set solved; + //InheritedAttributeType findAndReverse(SgGraphNode* n, SgIncidenceDirectedGraph* g); + //evaluateAllInheritedAttribute(std::vector endNodeInhVec, SgGraphNode* endnode, std::vector nodes, std::vector inh); +//std::vector getZeroInhs(std::vector > > qAnsSetSet, std::vector endnodeInhVec, SgGraphNode* node); + +}; + + + +/* +template +void +GraphBot:: +travelDown(SgIncidenceDirectedGraph* g) { + std::set oedgs = g->computeEdgeSetOut(iAmHere); + bool taken = false; + if (oedgs.size() > 1) { + std::set edgeTrav = clEdgeTrav[iAmHere]; + ROSE_ASSERT(clEdgeTrav.find(iAmHere) != clEdgeTrav.end()); + for (std::set::iterator i = oedgs.begin(); i != oedgs.end(); i++) { + if (edgTrav.find(*i) == edgTrav.end() || !taken) { + taken = true; + iAmHere = (*i)->get_to(); + lastEdge = *i; + } + } + } + else { + iAmHere = (*(oedgs.begin())->get_to(); + } +} +*/ + + + + + + +/* +*************************** +Various Admin Functions +*************************** +*/ +template +SgGraphTraversal:: +SgGraphTraversal() + : synthesizedAttributes(new SynthesizedAttributesList()) +{ +} + +#ifndef SWIG + +template +SgGraphTraversal:: +~SgGraphTraversal() +{ + ROSE_ASSERT(synthesizedAttributes != NULL); + delete synthesizedAttributes; + synthesizedAttributes = NULL; +} + +#endif + + +template +const SgGraphTraversal & +SgGraphTraversal:: +operator=(const SgGraphTraversal &other) +{ + + ROSE_ASSERT(synthesizedAttributes != NULL); + delete synthesizedAttributes; + synthesizedAttributes = other.synthesizedAttributes->deepCopy(); + + return *this; +} + +/** +This is the function that is used by the user directly to start the algorithm. It is immediately available to the user + +SgGraphTraversal::traverse +Input: +@param[n] n starting node +@param[g] SgIncidenceDirectedGraph* g, CFG calculated previously +@param[inheritedValue] InheritedAttributeType inheritedValue, value of the starting node +@param[nullI] InheritedAttributeType nullI, value of the null Attribute, i.e. what to attribute to a node with no value\ +@param[endnode] SgGraphNode* endnode, final node +@param[insep] boolean to decide inseparability of the analysis function, not yet in use, set automatically to false +@param[pCh] deprecated, set to false +@return InheritedAttributeType, the value of the attribute at the end node + +*/ + + +template +InheritedAttributeType +SgGraphTraversal:: +traverse(SgGraphNode* n, SgIncidenceDirectedGraph* g, InheritedAttributeType inheritedValue, InheritedAttributeType nullI, SgGraphNode* endnode, bool insep, bool pCh) { + //numnodes = 0; + //primes.clear(); + looppaths.clear(); + iLoops.clear(); + completedEdgesPath.clear(); + pathValMap.clear(); + loopNumMap.clear(); + nullloops = 0; + nullEdgesPaths = 0; + fllp = 0.0; + mkglobal.clear(); + clglobal.clear(); + + lpbegins.clear(); + //currents.clear(); + inhVals.clear(); + iVals.clear(); + oVals.clear(); + //reservedEdges.clear(); + completedEdges.clear(); + completedEdgesOut.clear(); + //completedNodes.clear(); + computedNodes.clear(); + nullEdgesOrdered.clear(); + nullEdgesOrderedOut.clear(); + loopSet.clear(); + pathsAtMk.clear(); + + st = n; + en = endnode; + distime = 0.0; + int currm = 1; + int turns = 0; + pathsSize = 0; + done = false; + numnodes = 1; + std::cout << "starting traversal" << std::endl; + pathCheck = pCh; + currprime = 1; + inseparable = insep; + synthesizedAttributes->resetStack(); + ROSE_ASSERT(synthesizedAttributes->debugSize() == 0); + //SgCFG = cfg; + inhVals[n] = inheritedValue; + //GraphBot::inhVals[n] = inheritedValue; + //primes = generatePrimesSieve(); + + +// graphnodeinheritedordmap[ncpy] = inheritedValue; +// nodenodeordmap[ncpy] = n; +// std::vector lst; +// lst.push_back(n); +// lstordmap[ncpy] = lst; + + nullInherit = nullI; +InheritedAttributeType inh; + struct timeval t1, t2, t3, t4, t5, t6, t7, t8; + //else { + loopnum = 0; + //InheritedAttributeType inh; + t1 = getCPUTime(); + + //this function essentially sets up for the evaluate later, it makes putting together the paths much easier + solvePaths(g, n, endnode); + + t2 = getCPUTime(); + +//making sure that endnode hasn't already been evaluated before the traversal starts, unlikely but just in case + ROSE_ASSERT(inhVals.find(endnode) == inhVals.end()); + + std::cout << "solvePaths done" << std::endl; + double diff = timeDifference(t2, t1); + t5 = getCPUTime(); + //InheritedAttributeType pthgraphinherit = botTraverse(g, n, endnode); + oVals[n] = 0; + iVals[0] = n; + pathValMap[n] = 1; +//inserting n as a computed node + computedNodes.insert(n); +//computes the order in which the nodes must be evaluated, makes computeInheritedOrdered much faster + computeOrder(g, n, endnode); + std::cout << "order computed" << std::endl; +//computes the nodal inheritance values + computeInheritedOrdered(g, n); + std::cout << "inheritance computed" << std::endl; + ROSE_ASSERT(oVals.find(endnode) != oVals.end()); + ROSE_ASSERT(inhVals.find(endnode) != inhVals.end()); +//value at the endnode + InheritedAttributeType pthgraphinherit = inhVals[endnode]; + //= evaluateGraph(g, n, endnode, inheritedValue); + t6 = getCPUTime(); + std::cout << "evaluateGraph done" << std::endl; + double diff3 = timeDifference(t6, t5); + t3 = getCPUTime(); +//actually evaluates every path with a user defined pathAnalyze function + //for (int i = 0; i < 10; i++) { + evaluatePaths(g, n, endnode); + //} + t4 = getCPUTime(); + + t7 = getCPUTime(); + //evaluatePathsPar(g, n, endnode); + t8 = getCPUTime(); + + std::cout << "evaluatePaths done " << std::endl; + double diff2 = timeDifference(t4, t3); + double diff2Par = timeDifference(t8, t7); + std::cout << "pathsolve took: " << diff << std::endl; + std::cout << "patheval took: " << diff2 << std::endl; + std::cout << "parpatheval took: " << diff2Par << std::endl; + std::cout << "grapheval took: " << diff3 << std::endl; + std::cout << "entire pathsolve took: " << diff+diff2+diff3+diff2Par << std::endl; + std::cout << "potential loops: " << nullEdgesOrdered.size() << std::endl; + std::cout << "nullNum: " << nullNum << std::endl; + //std::cout << "goodsets: " << goodset.size() << std::endl; + //std::cout << "flpsets: " << flpset.size() << std::endl; + std::cout << "mkloops: " << mkloops.size() << std::endl; + std::cout << "distime: " << distime << std::endl; + std::cout << "fllp: " << fllp << std::endl; + return pthgraphinherit; + //} + //std::cout << "number of endnodefakes: " << endnodefakes.size() << std::endl; + //std::cout << "should be number of nodes: " << currprime << std::endl; + //if (pathanalysis == true) { + // analyzepaths(endnode, g); + //} + //return inh; + //Currently this is not very useful, but it does nothing if traversalResult is not set. +} + +/* WARNING: + This is not a general is_disjoint. It skips the +first element of the second set because in the way I assemble +paths the last element of the path and the first element of addend +must be the same. Hence I simply skip the first node +*/ +bool is_disjoint(std::set set1, std::set set2) { + + if (set1.empty() || set2.empty()) { + return true; + } + std::set::iterator it1 = set1.begin(); + std::set::iterator it2 = set2.begin(); + std::set::iterator it1End = set1.end(); + std::set::iterator it2End = set2.end(); + + if (*it1 > *set2.rbegin() || *it2 > *set1.rbegin()) { + return true; + } + + while (it1 != it1End && it2 != it2End) { + if (*it1 == *it2) { + return false; + } + if (*it1 < *it2) { + it1++; + } + else { + it2++; + } + } + return true; +} + + + +//Checks for disjoint, necessary in computing the paths +template +bool +SgGraphTraversal:: +disjoint(std::vector& pthloops, std::vector& vec2) const { +/* + time_t t1, t2; + time(&t1); + int a = 0; + std::set s1; + std::set s2; + std::vector mkloopvec; + bool goodsetbool; + bool pbool = true; + //std::cout << "calculating disjoint" << std::endl; + ROSE_ASSERT((path.back()).back() == vec2.front()); + + //copy(vec2.begin(), vec2.end(), inserter(s2, s2.end())); +/* + for (int i = 0; i < vec2.size(); i++) { + if (ploops.find(vec2[i]) != ploops.end()) { + pbool = false; + } + } + if (pbool) { + return true; + } + if ( +*/ //for (int q = 0; q < pthloops->size(); q++) { + for (int i = 0; i < pthloops.size(); i++) { + if (find(vec2.begin(), vec2.end(), pthloops[i]) != vec2.end()) { + return false; + } + } + return true; +} +/* + if (pbool) { + time(&t2); + double diff = difftime(t2, t1); + distime += diff; + return true; + } + for (unsigned int k = 0; k < path.size(); k++) { + s1.clear(); +*/ +/* + pbool = true; + for (int p = 0; p < path[k].size(); p++) { + if (ploops.find(path[k][p]) != ploops.end()) { + pbool = false; + } + } +// copy(path[k].begin(), path[k].end(), inserter(s1, s1.end())); + if (!pbool) { +*/ +/* + std::pair, std::pair > flp; + flp.second.first = vec2[0]; + flp.second.first = vec2[1]; + + flp.first.first = path[k][0]; + flp.first.second = path[k][1]; + if (vec2.front() == vec2.back()) { + time(&t2); + double diff = difftime(t2, t1); + distime += diff; + + return false; + } + if (flpset.find(flp) != flpset.end()) { + //std::cout << "already seen" << std::endl; + time(&t2); + double diff = difftime(t2, t1); + distime += diff; + + return false; + } +*/ +/* + else if (goodset.find(flp) != goodset.end()) { + goodsetbool = true; + } +*/ +/* + if (is_disjoint(s1,s2)) { + //goodset.insert(flp); + continue; + } + else { + return false; + } +*/ +/* + else { + std::vector vec1 = path[k]; + + //for (unsigned int i = 0; i < vec1.size(); i++) { + for (unsigned int j = 0; j < mkloopvec.size(); j++) { + std::vector::iterator q = find(vec1.begin(), vec1.end(), mkloopvec[j]); + if (q != vec1.end()) { + if (*q != vec1[vec1.size() - 1] || j != 0) { + + flpset.insert(flp); + // std::cout << "not disjoint" << std::endl; + time(&t2); + double diff = difftime(t2, t1); + distime += diff; + + return false; + } + } + } + //} + //goodset.insert(flp); + } + } + //} +*/ + + +/* + for (unsigned int p = 0; p < vec2.size(); p++) { + for (unsigned int q = 0; q < vec2.size(); q++) { + if (p != q) { + if (vec2[p] == vec2[q]) { + return false; + } + } + } + } +*/ +/* + time(&t2); + double diff = difftime(t2, t1); + distime += diff; + + return true; +} +*/ +//checks for solvability of a node in nodal analysis + +template +bool +SgGraphTraversal:: +canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + bool loop = false; + if (inhVals.find(n) != inhVals.end()) { + return true; + } + std::set oed = g->computeEdgeSetIn(n); + if (oed.size() == 0) { + return false; + } + for (std::set::iterator i = oed.begin(); i != oed.end(); i++) { + if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdges.find(*i) == nullEdges.end()) { + return false; + } + } + return true; +} + +//this function evaluates values of paths via the user-defined pathAnalyze function + +template +void +SgGraphTraversal:: +evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { +std::vector > path; +std::vector spath; +SgGraphNode* n = realstartnode; +int successes = 0; +int failures = 0; +int j = 0; +std::vector currpthorg; +int currint = 0; +std::map intPath; +intPath[n] = currint; +currint++; +std::map currents; +SgGraphNode* currnode; +bool step = false; +bool midstep = false; + +//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) + +std::vector > pth = pathsAtMk[realstartnode]; +std::vector > cpth = pathsAtMk[realstartnode]; + path.clear(); + int disjoints = 0; + int disjointtrues = 0; + currpthorg = pth[0]; + intPath[pth[0].front()] = currint; + std::set pthloopstmp; + SgGraphNode* fakenode; + pthloopstmp.insert(fakenode); + std::vector > pthloops; + pthloops.push_back(pthloopstmp); + pthloopstmp.clear(); + currint++; + + int stepnum = 0; + std::vector rs; + rs.push_back(realstartnode); + path.push_back(rs); + currents.clear(); + + step = false; + std::vector sub; + + + std::set > nullIncLoops; + std::vector todobotlst; + std::vector botlst; + struct Bot* rootBot = new Bot; + rootBot->remove = false; + + rootBot->path = path; + rootBot->currpth = currpthorg; + rootBot->pthloops = pthloops; + rootBot->on = true; + botlst.push_back(rootBot); + int tip = 1; + int ti = 1; + std::vector, std::vector > > > collectedPaths; + int maxlst = 0; + while (true) { + if (todobotlst.size()+botlst.size() > maxlst) { + maxlst = todobotlst.size()+botlst.size(); + std::cout << "maxlst: " << maxlst << std::endl; + std::cout << "todobotlst.size(): " << todobotlst.size() << std::endl; + std::cout << "botlst.size(): " << botlst.size() << std::endl; + } + int MAXBOTS = 10000; + int MINPATHS = 1000; + int LOCALMAXBOTS = 10; + int LOCALMAXNODES = 0; + std::vector lstnullbot; + std::vector > newbotlsts (MAXBOTS, lstnullbot); + //std::vector newbotlsts (MAXBOTS, lstnullbot); + //tip = ti; + //ti = 0; + ROSE_ASSERT(botlst.size() >= 0); + if (botlst.size() == 0) { + if (todobotlst.size() != 0) { + while (todobotlst.size() > 0 && botlst.size() < MAXBOTS) { + todobotlst.back()->on = true; + botlst.push_back(todobotlst.back()); + todobotlst.pop_back(); + } + } + else { + if (collectedPaths.size() > 0) { + for (int i = 0; i < collectedPaths.size(); i++) { + std::set > incloops; + std::vector > pthloops = collectedPaths[i].second; + for (int q = 0; q < pthloops.size(); q++) { + for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { + for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { + incloops.insert(*o); + } + } + } + + + pathAnalyze(collectedPaths[i].first, false, incloops); + } + collectedPaths.clear(); + } + break; + } + } + if (botlst.size() > 0) { + std::pair, std::vector > > nullpr; + std::vector, std::vector > > > newpathslst (MAXBOTS, nullpr); + #pragma omp parallel for + for (int i = 0; i < botlst.size(); i++) { + //std::map > > mkloopmaptmp = mkloopmap; + std::vector localbotlst; + std::pair, std::vector > > localnewpath; + struct Bot* currBot = botlst[i]; + if (currBot->on) { + std::vector currpth = currBot->currpth; + std::vector > path = currBot->path; + std::vector > pthloops = currBot->pthloops; + + if (currpth.back() == endnode) { + path.push_back(currpth); + std::vector flatpath; + std::set > incloops; + struct timeval q1, q2; + ROSE_ASSERT(path.size() == pthloops.size() + 1); + q1 = getCPUTime(); + for (unsigned int q = 0; q < pthloops.size(); q++) { + for (unsigned int r = 0; r < path[q].size(); r++) { + flatpath.push_back(path[q][r]); + } + +/* +#pragma omp critical +{ + for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { + for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { + incloops.insert(*o); + } + } +} +*/ + + } + + for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { + flatpath.push_back(path[path.size()-1][pt2]); + } + q2 = getCPUTime(); + fllp += timeDifference(q2,q1); + flatpath.push_back(endnode); +//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops +/* + #pragma omp critical (analyze) +{ + pathAnalyze(flatpath, false, incloops); +} +*/ + std::pair , std::vector > > newcol; + newcol.first = flatpath; + newcol.second = pthloops; + localnewpath = newcol; + incloops.clear(); + + int pts = pathsSize++; + pathsSize += 1; + + flatpath.clear(); + path.pop_back(); + int rounds = 0; + bool starter = false; + +// This gets a bit complicated so here is an overview: +// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. +/* + if (currBot->nodelst.size() != 0) { + while (path.back().back() != currBot->nodelst.back().first) { + ROSE_ASSERT(path.size() != 0); + path.pop_back(); + pthloops.pop_back(); + + } + currBot->path = path; + currBot->pthloops = pthloops; + currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; + currBot->nodelst.pop_back(); + localbotlst.push_back(currBot); + } + else { +*/ + currBot->remove = true; + localbotlst.push_back(currBot); + //} + } + else { + +//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node + bool disj = true; + struct timeval tdisb, tdise; + //tdisb = getCPUTime(); + for (int x = 0; x < pthloops.size(); x++) { + for (std::set::iterator j = pthloops[x].begin(); j != pthloops[x].end(); j++) { + if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { + disj = false; + } + } + } + //tdise = getCPUTime(); + //distime += timeDifference(tdise, tdisb); + if (disj) { + + disjointtrues++; + //std::cout << "disjoints: " << disjointtrues << std::endl; + midstep = false; +std::set pthloopstmp; + pthloopstmp.clear(); + for (int i = 0; i < currpth.size(); i++) { + //currflat.push_back(currpth[i]); + if (mkloops.find(currpth[i]) != mkloops.end()) { + pthloopstmp.insert(currpth[i]); + } + } + pthloops.push_back(pthloopstmp); + path.push_back(currpth); + pthloopstmp.clear(); + + //std::set > lpth; + std::vector oldcurrpth = currpth; + currpth.clear(); + SgGraphNode* frontnode = (path.back()).front(); + SgGraphNode* backnode = (path.back()).back(); + + ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); + ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); + std::vector > tmppths = pathsAtMk[backnode]; + currBot->currpth = tmppths[0]; + currBot->path = path; + currBot->pthloops = pthloops; + //newbotlst.push_back(currBot); + for (int tp = 1; tp < tmppths.size(); tp++) { + //if (localbotlst.size() < LOCALMAXBOTS) { +/* + if (currBot->nodelst.size() < LOCALMAXNODES) { + std::pair cur; + cur.second = tp; + cur.first = path.back().back(); + currBot->nodelst.push_back(cur); + } + else { +*/ + struct Bot* newBot = new Bot; + newBot->remove = false; + newBot->currpth = tmppths[tp]; + newBot->path = path; + newBot->pthloops = pthloops; + localbotlst.push_back(newBot); + //ti++; + // } + } + localbotlst.push_back(currBot); + //ti++; + } + else { +/* + if (currBot->nodelst.size() != 0) { + while (path.back().back() != currBot->nodelst.back().first) { + ROSE_ASSERT(path.size() != 0); + path.pop_back(); + pthloops.pop_back(); + + } + currBot->path = path; + currBot->pthloops = pthloops; + currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; + currBot->nodelst.pop_back(); + localbotlst.push_back(currBot); + //ti++; + } + + else { +*/ + currBot->remove = true; + localbotlst.push_back(currBot); + //delete currBot; + // } + + } + } + newpathslst[i] = localnewpath; + newbotlsts[i] = localbotlst; + } +} + botlst.clear(); + int num = 0; + + for (int i = 0; i < newbotlsts.size(); i++) { + if (newpathslst[i].first.size() > 0) { + collectedPaths.push_back(newpathslst[i]); + } + for (int j = 0; j < newbotlsts[i].size(); j++) { + if (newbotlsts[i][j]->remove == true) { + delete newbotlsts[i][j]; + } + else if (num < MAXBOTS) { + newbotlsts[i][j]->on = true; + botlst.push_back(newbotlsts[i][j]); + num++; + } + else { + newbotlsts[i][j]->on = false; + todobotlst.push_back(newbotlsts[i][j]); + } + } +} + +if (collectedPaths.size() > MINPATHS) { + + for (int i = 0; i < collectedPaths.size(); i++) { + std::vector > pthloops; + std::set > incloops; + pthloops = collectedPaths[i].second; + for (int q = 0; q < pthloops.size(); q++) { + for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { + for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { + incloops.insert(*o); + } + } + } + + pathAnalyze(collectedPaths[i].first, false, incloops); + } + collectedPaths.clear(); +} +} + else { + if (collectedPaths.size() > 0) { + for (int i = 0; i < collectedPaths.size(); i++) { + std::set > incloops; + pthloops = collectedPaths[i].second; + for (int q = 0; q < pthloops.size(); q++) { + for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { + for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { + incloops.insert(*o); + } + } + } + + pathAnalyze(collectedPaths[i].first, false, incloops); + } + } + collectedPaths.clear(); + break; + } +} + +std::cout << "successes: " << successes << std::endl; +std::cout << "failures: " << failures << std::endl; +std::cout << "maxlst: " << maxlst << std::endl; +return; +} + + + +template +void +SgGraphTraversal:: +evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { +//std::set seen; +//for (std::map > >::iterator i = pathsAtMk.begin(); i != pathsAtMk.end(); i++) { +/* + std::vector > tocheck = (*i).second; + for (int j = 0; j < tocheck.size(); j++) { + for (int k = 0; k < tocheck[j].size(); k++) { + if (seen.find(tocheck[j][k]) != seen.end()) { + ploops.insert(tocheck[j][k]); + } + else { + seen.insert(tocheck[j][k]); + } + } + } +} +*/ +std::vector > path; +std::vector spath; +SgGraphNode* n = realstartnode; +int successes = 0; +int failures = 0; +int j = 0; +std::vector currpth; +int currint = 0; +std::map intPath; +intPath[n] = currint; +currint++; +std::map currents; +SgGraphNode* currnode; +bool step = false; +bool midstep = false; + +//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) + +std::vector > pth = pathsAtMk[realstartnode]; +std::vector > cpth = pathsAtMk[realstartnode]; + path.clear(); + int disjoints = 0; + int disjointtrues = 0; + currpth = pth[0]; + intPath[pth[0].front()] = currint; + std::set pthloopstmp; + SgGraphNode* fakenode; + pthloopstmp.insert(fakenode); + std::vector > pthloops; + pthloops.push_back(pthloopstmp); + pthloopstmp.clear(); + currint++; + + int stepnum = 0; + std::vector rs; + rs.push_back(realstartnode); + path.push_back(rs); + //currflat.push_back(realstartnode); + currents.clear(); + + step = false; + //std::vector currflat; + std::vector sub; + +/* + std::ofstream mz; + mz.open("pathanalysis.dot"); + mz << "digraph defaultName { \n"; +*/ + std::set > nullIncLoops; + +/* + for (unsigned int p = 0; p < looppaths.size(); p++) { + std::vector lp = looppaths[p]; + + for (unsigned int i = 0; i < lp.size()-1; i++) { + for (unsigned int l = i+1; l < lp.size(); l++) { + if (lp[i] == lp[l] && lp[i] != realstartnode && lp[i] != endnode) { + std::vector interiorloop; + interiorloop.clear(); + for (unsigned int j = i; j < l+1; j++) { + interiorloop.push_back(lp[j]); + } + if (interiorloop.size() > 2) { + } + if (interiorloop.size() > 2 && interiorloop.back() != endnode) { + if (find(iLoops.begin(), iLoops.end(), interiorloop) == iLoops.end()) { + if (find(looppaths.begin(), looppaths.end(), interiorloop) == looppaths.end()) { + iLoops.push_back(interiorloop); + loopnum++; + for (unsigned int k = 0; k < interiorloop.size(); k++) { + loopNumMap[interiorloop[k]] = loopnum; + } + lpbegins[interiorloop.front()].insert(interiorloop); + pathAnalyze(interiorloop, true, nullIncLoops); + + } + } + } + } + } + } + if (lp.size() > 2) { + lpbegins[lp.front()].insert(lp); + pathAnalyze(lp, true, nullIncLoops); + //for (unsigned int i = 1; i < lp.size(); i++) { + // printNodePlusEdgesForAnalysisPath(g, lp, p, p, mz); + //} + } + } +*/ + while (step == false) { + stepnum++; + + if (currpth.back() == endnode) { + path.push_back(currpth); + //for (int i = 0; i < currpth.size(); i++) { + // currflat.push_back(currpth[i]); + //} + std::vector flatpath; + //std::vector sub; + std::set > incloops; + struct timeval q1, q2; + //std::cout << "path.size(): " << path.size() << std::endl; + //std::cout << "pthloops.size(): " << pthloops.size() << std::endl; + ROSE_ASSERT(path.size() == pthloops.size() + 1); + q1 = getCPUTime(); + for (unsigned int q = 0; q < pthloops.size(); q++) { + //sub = path[q]; + //sub.pop_back(); + for (unsigned int r = 0; r < path[q].size(); r++) { + flatpath.push_back(path[q][r]); + } + for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { + for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { + incloops.insert(*o); + } + } + } + for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { + flatpath.push_back(path[path.size()-1][pt2]); + } + + q2 = getCPUTime(); + fllp += timeDifference(q2,q1); + flatpath.push_back(endnode); +/* + for (unsigned int ps = 0; ps < flatpath.size(); ps++) { + if (lpbegins.find(flatpath[ps]) != lpbegins.end()) { + for (std::set >::iterator sv = lpbegins[flatpath[ps]].begin(); sv != lpbegins[flatpath[ps]].end(); sv++) { + incloops.insert(*sv); + } + } + } +*/ +//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops + pathAnalyze(flatpath, false, incloops); + incloops.clear(); + //printNodePlusEdgesForAnalysisPath(g, flatpath, -1, -1, mz); + + int pts = pathsSize++; + pathsSize += 1; + + flatpath.clear(); + path.pop_back(); + int rounds = 0; + bool starter = false; + +// This gets a bit complicated so here is an overview: +// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. + + + while (true) { + rounds++; + ROSE_ASSERT(pathsAtMk.find((path.back()).back()) != pathsAtMk.end()); + if ((path.back()).front() == realstartnode) { + starter = true; + } + if (currents[(path.back()).back()] < (pathsAtMk[(path.back()).back()].size()) /*|| (path.back()).front() == realstartnode*/) { + std::vector > cpths = pathsAtMk[(path.back()).back()]; + currpth = cpths[currents[(path.back()).back()]]; + currents[(path.back()).back()]++; + break; + } + else { + currents[(path.back()).back()] = 0; + path.pop_back(); + pthloops.pop_back(); + } + if (starter == true) { + step = true; + break; + } + + } + } + else { + +//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node + bool disj = true; + struct timeval tdisb, tdise; + tdisb = getCPUTime(); + for (int i = 0; i < pthloops.size(); i++) { + for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { + if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { + disj = false; + } + } + } +/* + #pragma omp parallel for num_threads(4) private(i,j) + for (i = 0; i < pthloops.size(); i++) { + if (disj) { + for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { + if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { + disj = false; + //j = pthloops[i].size(); + } + } + } + + } +*/ + tdise = getCPUTime(); + distime += timeDifference(tdise, tdisb); + if (disj) { + + disjointtrues++; + //std::cout << "disjoints: " << disjointtrues << std::endl; + midstep = false; + std::set pthloopstmp; + pthloopstmp.clear(); + for (int i = 0; i < currpth.size(); i++) { + //currflat.push_back(currpth[i]); + if (mkloops.find(currpth[i]) != mkloops.end()) { + pthloopstmp.insert(currpth[i]); + } + } + pthloops.push_back(pthloopstmp); + path.push_back(currpth); + pthloopstmp.clear(); + + //std::set > lpth; + std::vector oldcurrpth = currpth; + currpth.clear(); + if (currents.find((path.back()).back()) == currents.end()) { + currents[(path.back()).back()] = 0; + } + SgGraphNode* frontnode = (path.back()).front(); + SgGraphNode* backnode = (path.back()).back(); + + ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); + ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); + if (currents.find(backnode) == currents.end()) { + currents[backnode] = 0; + } + else { + ROSE_ASSERT(currents[backnode] == 0); + } + std::vector > tmppths = pathsAtMk[backnode]; + + currpth = tmppths[currents[backnode]]; + ROSE_ASSERT(currpth != oldcurrpth); + currents[backnode]++; + } + else { + disjoints++; + //std::cout << "disjoint false: " << s << std::endl; + + while (true) { + if (currents[(path.back()).back()] < pathsAtMk[(path.back()).back()].size() || path.back().back() == realstartnode) { + break; + } + currents[(path.back()).back()] = 0; + path.pop_back(); + pthloops.pop_back(); + } + if ((path.back()).back() != realstartnode) { + currpth = (pathsAtMk[(path.back()).back()])[currents[(path.back()).back()]]; + currents[(path.back()).back()]++; + } + else { + step = true; + } + } + } + } +std::cout << "successes: " << successes << std::endl; +std::cout << "failures: " << failures << std::endl; + +return; +} + + +//these are debugging functions, used to visually ascertain where the paths are going to check to make sure everything is evaluated + + +/* DEBUGGING */ + +template +void +SgGraphTraversal:: +printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss) { + printNodeForAnalysis(n, loopNum, pathVal, ss); + std::set outEdges = g->computeEdgeSetOut(n); + for (std::set::iterator i = outEdges.begin(); i != outEdges.end(); i++) { + if (nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { + printEdgeForAnalysis(*i, false, ss); + } + else { + printEdgeForAnalysis(*i, true, ss); + } + } +} + +template +void +SgGraphTraversal:: +printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss) { + for (unsigned int i = 0; i < n.size()-1; i++) { + if (completedNodesPath.find(n[i]) == completedNodesPath.end()) { + printNodeForAnalysis(n[i], loopNum, pathVal, ss); + completedNodesPath.insert(n[i]); + } + std::pair prnod; + prnod.first = n[i+1]; + prnod.second = n[i]; + if (completedEdgesPath.find(prnod) == completedEdgesPath.end()) { + printEdgeForAnalysisPath(n[i+1], n[i], ss); + completedEdgesPath.insert(prnod); + } + } + if (completedNodesPath.find(n[n.size() - 1]) == completedNodesPath.end()) { + printNodeForAnalysis(n[n.size()-1], loopNum, pathVal, ss); + completedNodesPath.insert(n[n.size() - 1]); + } + +} + + +template +void +SgGraphTraversal:: +printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream &ss) { + int id = n->get_index(); + std::string nodeColor = "black"; + if (loopNum != 0) { + ss << id << " [label=\"" << "LoopNumS" << loopNum << "\", color=\"" << "green" << "\", style=\"" << "solid" << "\"];\n"; + } + else { + ss << id << " [label=\"" << "pathNumS" << pathNum << "\", color=\"" << "black" << "\", style=\"" << "dotted" << "\"];\n"; + } + +} +template +void +SgGraphTraversal:: +printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream &ss) { + if (isNullEdge) { + ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "NullEdge" << "\", style=\"" << "dotted" << "\"];\n"; + } + else { + ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "\", style=\"" << "solid" << "\"];\n"; + } +} +template +void +SgGraphTraversal:: +printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream &ss) { + ss << g2->get_index() << " -> " << g1->get_index() << " [label=\"" << "Edge" << "\", style=\"" << "solid" << "\"];\n"; +} + +/* END DEBUGGING */ + +//This function sets up the graph so that the evaluatePath function can easily traverse the paths + +template +void +SgGraphTraversal:: +solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { + bool done = false; + bool edges = true; + bool tookone = false; + std::vector mkpath; + std::vector marks; + marks.push_back(n); + mkglobal.push_back(n); + SgGraphNode* currn = n; + SgGraphNode* took; + std::set taken; + std::vector toTake; + std::vector path; + path.push_back(n); + mkpath.push_back(n); + int itr = 0; + int bifurcations = 0; + std::map completed; + while (done == false) { + ROSE_ASSERT(currn != NULL); +//check to see if we've hit the endnode or if we're done, if not continue, if so push the subpath into the "pathsAtMk" repository + if (currn == endnode || completed.find(currn) != completed.end()) { + if (pathsAtMk.find(marks.back()) == pathsAtMk.end()) { + std::vector > emptypath; + pathsAtMk[marks.back()] = emptypath; + } + edges = false; + pathsAtMk[marks.back()].push_back(mkpath); + //for (int mk = 0; mk < mkpath.size(); mk++) { + // std::set iedg = g->computeEdgeSetIn(mkpath[mk]); + //if (iedg.size() > 1) { + // ploops.insert(mkpath[mk]); + // } + //} + ROSE_ASSERT(mkpath.front() == marks.back()); + if (marks.size() == 0) { + return; + } + mkpath.clear(); + bool y = true; + bool haventtaken = false; + bool p = true; + int place; + bool found = false; + while (found == false) { + if (marks.size() == 0) { + return; + } + SgDirectedGraphEdge* tooked; + SgGraphNode* mark1 = marks.back(); + std::set oedg = g->computeEdgeSetOut(mark1); + ROSE_ASSERT(oedg.size() > 1 || mark1 == n); + for (std::set::iterator j = oedg.begin(); j != oedg.end(); j++) { + if (taken.find(*j) == taken.end() && haventtaken == false) { + tooked = *j; + haventtaken = true; + } + } + if (haventtaken == true) { + if (marks.back() == n) { + path.clear(); + } + path.push_back(marks.back()); + if ( mkpath.empty() || (mkpath.back() != marks.back()) ) { + ROSE_ASSERT(!marks.empty()); + mkpath.push_back(marks.back()); + } + taken.insert(tooked); + took = tooked->get_to(); + found = true; + } + else { + completed[marks.back()] = true; + bifurcations++; + marks.pop_back(); + } + } + if (marks.size() == 0) { + return; + } + haventtaken = false; + found = false; + + } +//if we haven't reached the endnode or completed, continue down the graph + else { + std::set oedg = g->computeEdgeSetOut(currn); + std::set iedg = g->computeEdgeSetIn(currn); + if (oedg.size() > 1) { + if (mkpath.back() != currn) { + mkpath.push_back(currn); + } + pathsAtMk[marks.back()].push_back(mkpath); + mkpath.clear(); + mkpath.push_back(currn); + marks.push_back(currn); + if (find(mkglobal.begin(), mkglobal.end(), currn) == mkglobal.end()) { + mkglobal.push_back(currn); + } + for (std::set::iterator i = oedg.begin(); i != oedg.end(); i++) { + if (taken.find(*i) == taken.end() && tookone == false) { + taken.insert(*i); + tookone = true; + took = (*i)->get_to(); + } + else if (taken.find(*i) == taken.end() && tookone == true) { + //toTake.push_back((*i)->get_to()); + } + } + tookone = false; + } + else { + took = (*(oedg.begin()))->get_to(); + } + } + itr++; + + if (find(path.begin(), path.end(), took) == path.end()) { + mkpath.push_back(took); + path.push_back(took); + currn = took; + } + else { + mkloops.insert(took); + std::vector lptemp; + lptemp.clear(); + lptemp.push_back(took); + while (path.back() != took) { + + path.pop_back(); + + lptemp.push_back(path.back()); + + } + (mkloopmap[took]).insert(lptemp); +/* + if (lptemp.size() > 1) { + if (find(looppaths.begin(), looppaths.end(), lptemp) == looppaths.end() && find(lptemp.begin(), lptemp.end(), st) == lptemp.end() && find(lptemp.begin(), lptemp.end(), endnode) == lptemp.end()) { + looppaths.push_back(lptemp); + loopnum++; + for (unsigned int i = 0; i < lptemp.size(); i++) { + loopNumMap[lptemp[i]] = loopnum; + } + } + } +*/ + path.push_back(took); + currn = path.back(); + mkpath.push_back(took); + } + + +} + return; +} + +//not currently useful +template +SynthesizedAttributeType +SgGraphTraversal:: +defaultSynthesizedAttribute(InheritedAttributeType inh) +{ + SynthesizedAttributeType s = SynthesizedAttributeType(); + return s; +} + + +//computes the order in which to evaluate the nodes in nodal analysis so that you don't evaluate a node before you evaluate its parents + +template +void +SgGraphTraversal:: +computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { + std::map incomputables; + std::set lpposs; + //std::set lps; + SgGraphNode* currn; + currn = n; + int orders = 0; + while (true) { + if (orders % 10000 == 0) { + std::cout << "orders: " << orders << std::endl; + } + orders++; + if (currn == endnode) { + } + if (computable(g, currn) || currn == n) { + int mp; + if (oVals.find(currn) == oVals.end()) { + oVals[currn] = currm++; + iVals[currm++] = currn; + currm += 1; + } + if (currn == endnode) { + + break; + } + std::pair pbs = getNextChild(g, currn); + computedNodes.insert(currn); + ROSE_ASSERT(pbs.first == true); + currn = pbs.second; + } + else { + std::pair pbp = getNextPar(g, currn); + ROSE_ASSERT(pbp.first == true); + currn = pbp.second; + + } + + } + std::cout << "required orders" << orders << std::endl; + std::cout << "incomputables.size() " << incomputables.size() << std::endl; +} + +//simple fucntion to check the computability under nodal analysis +template +bool +SgGraphTraversal:: +computable(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + if (computedNodes.find(n) != computedNodes.end()) { + return true; + } + std::set ed = g->computeEdgeSetIn(n); + bool comp = true; + for (std::set::iterator i = ed.begin(); i != ed.end(); i++) { + if (oVals.find((*i)->get_from()) == oVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { + comp = false; + } + } + return comp; +} + + +//computes the inherited attribute values in nodal analysis + +template +void +SgGraphTraversal:: +computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + int runs = 0; +// std::ofstream mf; +// mf.open("analysis.dot"); +// mf << "digraph defaultName { \n"; + for (std::map::iterator i = iVals.begin(); i != iVals.end(); i++) { + runs++; + ROSE_ASSERT(canEval(g, (*i).second)); + setPathVal(g, n); + //printNodePlusEdgesForAnalysis(g, (*i).second, loopNumMap[(*i).second], pathValMap[(*i).second], mf); + evalNodeOrdered(g, (*i).second); + } +} + +//checks to see if evaluation is possible under nodal analysis +template +bool +SgGraphTraversal:: +canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + bool evaled = true; + if (inhVals.find(n) == inhVals.end()) { + std::set ins = g->computeEdgeSetIn(n); + for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { + if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { + evaled = false; + } + } + } + return evaled; +} + + +//actually does the evaluation +template +void +SgGraphTraversal:: +evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + if (inhVals.find(n) != inhVals.end()) { + return; + } + std::set par = g->computeEdgeSetIn(n); + std::vector inh; + for (std::set::iterator i = par.begin(); i != par.end(); i++) { + if (inhVals.find((*i)->get_from()) != inhVals.end()) { + inh.push_back(inhVals[(*i)->get_from()]); + } + } + + if (n != st || inh.size() > 0) { + InheritedAttributeType inhX; + inhX = evaluateInheritedAttribute(n, inh); + inhVals[n] = inhX; + } + //std::cout << "num of inhVals: " << inh.size() << std::endl; + +} + + +//debugging function, currently not useful for the end user +template +void +SgGraphTraversal:: +setPathVal(SgIncidenceDirectedGraph* g, SgGraphNode* currn) { + if (pathValMap.find(currn) != pathValMap.end()) { + return; + } + std::set ined = g->computeEdgeSetIn(currn); + int tmppathcount = 0; + for (std::set::iterator i = ined.begin(); i != ined.end(); i++) { + ROSE_ASSERT(pathValMap.find((*i)->get_from()) != pathValMap.end() /*|| nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()*/); + //if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { + // pathValMap[(*i)->get_from()] = 0; + // } + int pv = pathValMap[(*i)->get_from()]; + if (pv != 0) { + tmppathcount += pv; + } + } + pathValMap[currn] = tmppathcount; + return; + } + +//computes the next child to be analyzed in nodal analysis +template +std::pair +SgGraphTraversal:: +getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + bool nullPoss = false; + //std::cout << "nextChild" << std::endl; + std::set outs = g->computeEdgeSetOut(n); + //std::cout << "outs.size(): " << outs.size() << std::endl; + //std::cout << "outs: " << outs.size() << std::endl; + SgGraphNode* nextNode; + SgGraphNode* nullNode; + bool completed = false; + bool completeNull = false; + + for (std::set::iterator i = outs.begin(); i != outs.end(); i++) { + + if (outs.size() == 1) { + nextNode = (*i)->get_to(); + if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { + nullNum++; + } + //completedEdges.insert(*i); + completed = true; + } + else if (completed == false && computedNodes.find((*i)->get_to()) == computedNodes.end()) { + completed = true; + nextNode = (*i)->get_to(); + if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { + nullNum++; + } + completedEdgesOut.insert(*i); + } + + + } + std::pair pr; + ROSE_ASSERT (completed == true || completeNull == true); + if (completed == true) { + pr.first = completed; + pr.second = nextNode; + return pr; + } + else { + pr.first = true; + pr.second = nullNode; + return pr; + } + +} + +//computes the next parent to be analyzed in nodal analysis +template +std::pair +SgGraphTraversal:: +getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n) { + std::set ins = g->computeEdgeSetIn(n); + SgGraphNode* nextPar; + SgDirectedGraphEdge* nullEdgeO; + bool completed = false; + bool completeNull = false; + for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { + + if (ins.size() == 1 /*&& completedEdges.find(*i) == completedEdges.end()*/) { + completed = true; + completedEdges.insert(*i); + nextPar = (*i)->get_from(); + } + + else if (completedEdges.find(*i) == completedEdges.end() && completed == false) { + completed = true; + nextPar = (*i)->get_from(); + completedEdges.insert(*i); + } + + else if (completedEdges.find(*i) != completedEdges.end() && computedNodes.find((*i)->get_from()) == computedNodes.end() && completed == false /*&& nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()*/) { + completeNull = true; + std::pair lpp; + nextPar = n; + nullEdgesOrdered.insert(*i); + nullEdgesPaths++; + + } + } + ROSE_ASSERT(completed == true || completeNull == true); + std::pair pr; + pr.first = completed; + pr.second = nextPar; + + if (completeNull == true && completed == false) { + pr.first = completeNull; + pr.second = nextPar; + } + + return pr; +} + + + + + + + + + + + + + + + diff --git a/src/midend/astProcessing/graphTemplate.h b/src/midend/astProcessing/graphTemplate.h new file mode 100644 index 00000000000..e3075618ffb --- /dev/null +++ b/src/midend/astProcessing/graphTemplate.h @@ -0,0 +1,533 @@ +#ifndef BACKSTROKE_CFG_H +#define BACKSTROKE_CFG_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Backstroke +{ + +#define foreach BOOST_FOREACH + + +//! This function helps to write the DOT file for vertices. +template +void writeCFGNode(std::ostream& out, const CFGNodeType& cfgNode) +{ + SgNode* node = cfgNode.getNode(); + ROSE_ASSERT(node); + + std::string nodeColor = "black"; + if (isSgStatement(node)) + nodeColor = "blue"; + else if (isSgExpression(node)) + nodeColor = "green"; + else if (isSgInitializedName(node)) + nodeColor = "red"; + + std::string label; + + if (SgFunctionDefinition* funcDef = isSgFunctionDefinition(node)) + { + std::string funcName = funcDef->get_declaration()->get_name().str(); + if (cfgNode.getIndex() == 0) + label = "Entry\\n" + funcName; + else if (cfgNode.getIndex() == 3) + label = "Exit\\n" + funcName; + } + + if (!isSgScopeStatement(node) && !isSgCaseOptionStmt(node) && !isSgDefaultOptionStmt(node)) + { + std::string content = node->unparseToString(); + boost::replace_all(content, "\"", "\\\""); + boost::replace_all(content, "\\n", "\\\\n"); + label += content; + } + else + label += "<" + node->class_name() + ">"; + + if (label == "") + label += "<" + node->class_name() + ">"; + + out << "[label=\"" << label << "\", color=\"" << nodeColor << + "\", style=\"" << (cfgNode.isInteresting()? "solid" : "dotted") << "\"]"; +} + + +//! This function helps to write the DOT file for edges. +template +void writeCFGEdge(std::ostream& out, const CFGEdgeType& e) +{ + out << "[label=\"" << escapeString(e.toString()) << + "\", style=\"" << "solid" << "\"]"; +} + + +// Predeclaration of class CFG. +template class CFG; + +struct FullCFGNodeFilter +{ + bool operator()(const VirtualCFG::CFGNode& cfgNode) const + { return true; } +}; + +struct InterestingCFGNodeFilter +{ + bool operator()(const VirtualCFG::CFGNode& cfgNode) const + { return cfgNode.isInteresting(); } +}; + +//! A full CFG without any filtered nodes. +typedef CFG FullCFG; + + +//! A filtered CFG which only contains interesting nodes and edges. +typedef CFG FilteredCFG; + + + + + +/********************************************************************/ +// The concept required to be fulfilled by CFGNodeFilter is +// +// struct CFGNodeFilter +// { +// bool operator()(const VirtualCFG::CFGNode& cfgNode) const; +// }; +// +/********************************************************************/ + +//! A class holding a Control Flow Graph. + +template +class CFG : public boost::adjacency_list >, + boost::shared_ptr > > +{ + typedef typename boost::graph_traits > GraphTraits; + +public: + typedef VirtualCFG::FilteredCFGNode CFGNodeType; + typedef VirtualCFG::FilteredCFGEdge CFGEdgeType; + + typedef boost::shared_ptr CFGNodePtr; + typedef boost::shared_ptr CFGEdgePtr; + + typedef typename GraphTraits::vertex_descriptor Vertex; + typedef typename GraphTraits::edge_descriptor Edge; + + typedef std::map VertexVertexMap; + //! The entry node. + Vertex entry_; + + //! The exit node. + Vertex exit_; + + +protected: + + //! The function definition of this CFG. + SgFunctionDefinition* funcDef_; + + + //! A map from a CFG node to the corresponding vertex + std::map nodesToVertices_; + + //! The dominator tree of this CFG. + VertexVertexMap dominatorTree_; + + //! The postdominator tree of this CFG. + VertexVertexMap postdominatorTree_; + +public: + std::map getNodeVert() { + return nodesToVertices_; + } + + //! The default constructor. + CFG() + : funcDef_(NULL), + entry_(GraphTraits::null_vertex()), + exit_(GraphTraits::null_vertex()) + { + } + + //! The constructor building the CFG. + explicit CFG(SgFunctionDefinition* funcDef) + : funcDef_(funcDef), + entry_(GraphTraits::null_vertex()), + exit_(GraphTraits::null_vertex()) + { + build(funcDef); + } + + //! Build the actual CFG for the given function. + void build(SgFunctionDefinition* funcDef); + + //! Get the function definition of this CFG. + SgFunctionDefinition* getFunctionDefinition() const + { return funcDef_; } + + //! Get the entry node of the CFG + const Vertex& getEntry() const + { return entry_; } + + //! Get the exit node of the CFG + const Vertex& getExit() const + { return exit_; } + + //! Build the dominator tree of this CFG. + //! @returns A map from each node to its immediate dominator. + const VertexVertexMap& getDominatorTree(); + + //! Build the postdominator tree of this CFG. + const VertexVertexMap& getPostdominatorTree(); + + //! Build a reverse CFG. + CFG makeReverseCopy() const; + + //! Output the graph to a DOT file. + void toDot(const std::string& filename) const; + + //! Get all CFG nodes in this graph. + std::vector getAllNodes() const; + + //! Get all CFG edges in this graph. + std::vector getAllEdges() const; + + //! Given a CFG node, returns the corresponding vertex in the graph. + //! Returns Vertex::null_vertex() if the given node is not in the graph + Vertex getVertexForNode(const CFGNodeType &node) const; + + //! Return if this CFG is reducible (if all loops are natural loops, the + //! CFG is reducible). + bool isReducible() const { return true; } + + //! Get all back edges in the CFG. A back edge is one whose target dominates its source. + std::vector getAllBackEdges(); + + //! Get all loop headers in this CFG. A natural loop only has one header. + std::vector getAllLoopHeaders(); + +protected: + + //! A internal funtion which builds the actual CFG (boost::graph). + void buildCFG(const CFGNodeType& node, + std::map& nodesAdded, + std::set& nodesProcessed); + + //! Find the entry and exit of this CFG and set the corresponding members. + void setEntryAndExit(); + + //! This function helps to write the DOT file for vertices. + void writeGraphNode(std::ostream& out, const Vertex& node) const + { + writeCFGNode(out, *(*this)[node]); + //VirtualCFG::printNode(out, (*this)[node]); + } + + //! This function helps to write the DOT file for edges. + void writeGraphEdge(std::ostream& out, const Edge& edge) const + { + writeCFGEdge(out, *(*this)[edge]); + //VirtualCFG::printEdge(out, (*this)[edge], true); + } + + //! This class is used to copy vertices when calling copy_graph(). + struct VertexCopier + { + VertexCopier(const CFG& g1, CFG& g2) + : cfg1(g1), cfg2(g2) {} + + void operator()(const Vertex& v1, Vertex& v2) const + { cfg2[v2] = cfg1[v1]; } + + const CFG& cfg1; + CFG& cfg2; + }; + + //! This class is used to copy edges when calling copy_graph(). + struct EdgeCopier + { + EdgeCopier(const CFG& g1, CFG& g2) + : cfg1(g1), cfg2(g2) {} + + void operator()(const Edge& e1, Edge& e2) const + { cfg2[e2] = cfg1[e1]; } + + const CFG& cfg1; + CFG& cfg2; + }; +}; + + + +template +void CFG::toDot(const std::string& filename) const +{ + std::ofstream ofile(filename.c_str(), std::ios::out); + boost::write_graphviz(ofile, *this, + boost::bind(&CFG::writeGraphNode, this, ::_1, ::_2), + boost::bind(&CFG::writeGraphEdge, this, ::_1, ::_2)); +} + +template +void CFG::build(SgFunctionDefinition* funcDef) +{ + ROSE_ASSERT(funcDef); + funcDef_ = funcDef; + + // The following two variables are used to record the nodes traversed. + nodesToVertices_.clear(); + std::set nodesProcessed; + + // Remove all nodes and edges first. + this->clear(); + entry_ = GraphTraits::null_vertex(); + exit_ = GraphTraits::null_vertex(); + + buildCFG(CFGNodeType(funcDef->cfgForBeginning()), nodesToVertices_, nodesProcessed); + + // Find the entry and exit of this CFG. + setEntryAndExit(); + + ROSE_ASSERT(isSgFunctionDefinition((*this)[entry_]->getNode())); + ROSE_ASSERT(isSgFunctionDefinition((*this)[exit_]->getNode())); +} + +template +void CFG::setEntryAndExit() +{ + foreach (Vertex v, boost::vertices(*this)) + { + CFGNodePtr node = (*this)[v]; + if (isSgFunctionDefinition(node->getNode())) + { + if (node->getIndex() == 0) + entry_ = v; + else if (node->getIndex() == 3) + exit_ = v; + } + } + + //In graphs with an infinite loop, we might never get to the end vertex + //In those cases, we need to add it explicitly + if (exit_ == GraphTraits::null_vertex()) + { + std::cerr << "This function may contain an infinite loop " + "inside so that its CFG cannot be built" << std::endl; + exit_ = add_vertex(*this); + (*this)[exit_] = CFGNodePtr(new CFGNodeType(funcDef_->cfgForEnd())); + } + + ROSE_ASSERT(entry_ != GraphTraits::null_vertex()); + ROSE_ASSERT(exit_ != GraphTraits::null_vertex()); +} + +template +void CFG::buildCFG( + const CFGNodeType& node, + std::map& nodesAdded, + std::set& nodesProcessed) +{ + ROSE_ASSERT(node.getNode()); + + if (nodesProcessed.count(node) > 0) + return; + nodesProcessed.insert(node); + + typename std::map::iterator iter; + bool inserted; + Vertex from, to; + + // Add the source node. + const CFGNodeType& src = node; + ROSE_ASSERT(src.getNode()); + + boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src, Vertex())); + + if (inserted) + { + from = add_vertex(*this); + (*this)[from] = CFGNodePtr(new CFGNodeType(src)); + iter->second = from; + } + else + { + from = iter->second; + } + + std::vector outEdges = node.outEdges(); + + foreach(const CFGEdgeType& cfgEdge, outEdges) + { + // For each out edge, add the target node. + CFGNodeType tar = cfgEdge.target(); + ROSE_ASSERT(tar.getNode()); + + boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar, Vertex())); + + if (inserted) + { + to = add_vertex(*this); + (*this)[to] = CFGNodePtr(new CFGNodeType(tar)); + iter->second = to; + } + else + { + to = iter->second; + } + + // Add the edge. + Edge edge = add_edge(from, to, *this).first; + (*this)[edge] = CFGEdgePtr(new CFGEdgeType(cfgEdge)); + + // Build the CFG recursively. + buildCFG(tar, nodesAdded, nodesProcessed); + } +} + +template +const typename CFG::VertexVertexMap& CFG::getDominatorTree() +{ + if (!dominatorTree_.empty()) + return dominatorTree_; + + boost::associative_property_map domTreePredMap(dominatorTree_); + + // Here we use the algorithm in boost::graph to build a map from each node to its immediate dominator. + boost::lengauer_tarjan_dominator_tree(*this, entry_, domTreePredMap); + return dominatorTree_; +} + +template +const typename CFG::VertexVertexMap& CFG::getPostdominatorTree() +{ + if (!postdominatorTree_.empty()) + return postdominatorTree_; + + boost::associative_property_map postdomTreePredMap(postdominatorTree_); + + // Here we use the algorithm in boost::graph to build an map from each node to its immediate dominator. + boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*this), exit_, postdomTreePredMap); + return postdominatorTree_; +} + +template +CFG CFG::makeReverseCopy() const +{ + CFG reverseCFG; + // The following function makes a reverse CFG copy. + boost::transpose_graph(*this, reverseCFG, + boost::vertex_copy(VertexCopier(*this, reverseCFG)). + edge_copy(EdgeCopier(*this, reverseCFG))); + + // Swap entry and exit. + reverseCFG.entry_ = this->exit_; + reverseCFG.exit_ = this->entry_; + return reverseCFG; +} + + +template +std::vector::CFGNodePtr> +CFG::getAllNodes() const +{ + std::vector allNodes; + foreach (Vertex v, boost::vertices(*this)) + allNodes.push_back((*this)[v]); + return allNodes; +} + +/* +template +std::vector::CFGNodeType> +CFG::getAllNodesNoPtrs() const +{ + std::vector allNodes; + foreach (Vertex v, boost::vertices(*this)) + allNodes.push_back(&((*this)[v])); + return allNodes; +} +*/ + +template +std::vector::CFGEdgePtr> +CFG::getAllEdges() const +{ + std::vector allEdges; + foreach (const Edge& e, boost::edges(*this)) + allEdges.push_back((*this)[e]); + return allEdges; +} + +template +typename CFG::Vertex CFG::getVertexForNode(const CFGNodeType &node) const +{ + typename std::map::const_iterator vertexIter = nodesToVertices_.find(node); + if (vertexIter == nodesToVertices_.end()) + return GraphTraits::null_vertex(); + else + { + ROSE_ASSERT(*(*this)[vertexIter->second] == node); + return vertexIter->second; + } +} + +template +std::vector::Edge> CFG::getAllBackEdges() +{ + std::vector backEdges; + + // If the dominator tree is not built yet, build it now. + getDominatorTree(); + + foreach (const Edge& e, boost::edges(*this)) + { + Vertex src = boost::source(e, *this); + Vertex tar = boost::target(e, *this); + + //Vertex v = *(dominatorTree.find(src)); + typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src); + while (iter != dominatorTree_.end()) + { + if (iter->second == tar) + { + backEdges.push_back(e); + break; // break the while loop + } + iter = dominatorTree_.find(iter->second); + } + } + + return backEdges; +} + +template +std::vector::Vertex> CFG::getAllLoopHeaders() +{ + std::vector backEdges = getAllBackEdges(); + std::vector headers; + foreach (Edge e, backEdges) + headers.push_back(boost::target(e, *this)); + return headers; +} + +#undef foreach + +} // End of namespace Backstroke + + +#endif /* BACKSTROKE_CFG_H */ diff --git a/tests/nonsmoke/functional/roseTests/CMakeLists.txt b/tests/nonsmoke/functional/roseTests/CMakeLists.txt index 5c444e94781..535c285e2f5 100644 --- a/tests/nonsmoke/functional/roseTests/CMakeLists.txt +++ b/tests/nonsmoke/functional/roseTests/CMakeLists.txt @@ -4,7 +4,7 @@ if(enable-c) add_subdirectory (astMergeTests) add_subdirectory (astPerformanceTests) - #add_subdirectory (astProcessingTests) + add_subdirectory (astProcessingTests) add_subdirectory (astQueryTests) add_subdirectory (astSymbolTableTests) add_subdirectory (astTokenStreamTests) diff --git a/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt b/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt index 2c9f27c3634..53fb6e8172f 100644 --- a/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt +++ b/tests/nonsmoke/functional/roseTests/astProcessingTests/CMakeLists.txt @@ -161,18 +161,18 @@ if (HAVE_SYS_TIME_H) endforeach() #----------------------------------------------------------------------------- - #add_executable(processnew3Down4SgIncGraph3 processnew3Down4SgIncGraph3.C) - #target_link_libraries(processnew3Down4SgIncGraph3 - # ROSE_DLL EDG ${link_with_libraries}) - #set(processnew3Down4SgIncGraph3_SPECIMENS test11.C test12.C test13.C test14.C) - - #set(processnew3Down4SgIncGraph3_SPECIMENS eif.C eif2.C eif3.C eif4.C) - #foreach(specimen ${processnew3Down4SgIncGraph3_SPECIMENS}) - # add_test( - # NAME pnew2_${specimen} - # COMMAND processnew3Down4SgIncGraph3 ${CMAKE_CURRENT_SOURCE_DIR}/${specimen} - # ) - #endforeach() + add_executable(processnew3Down4SgIncGraph3 processnew3Down4SgIncGraph3.C) + target_link_libraries(processnew3Down4SgIncGraph3 + ROSE_DLL EDG ${link_with_libraries}) + set(processnew3Down4SgIncGraph3_SPECIMENS test11.C test12.C test13.C test14.C) + + set(processnew3Down4SgIncGraph3_SPECIMENS eif.C eif2.C eif3.C eif4.C) + foreach(specimen ${processnew3Down4SgIncGraph3_SPECIMENS}) + add_test( + NAME pnew2_${specimen} + COMMAND processnew3Down4SgIncGraph3 ${CMAKE_CURRENT_SOURCE_DIR}/${specimen} + ) + endforeach() if (enable-binary-analysis) #--------------------------------------------------------------------------- From 737a8d9afb2e19bb9a23d84594a9ce727b9f0790 Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 26 Sep 2023 10:15:32 -0400 Subject: [PATCH 14/42] Revert "Removed more boost code; removed dead extractFunctionArgumentsNormalization" This reverts commit 7ee15636dc04e5670090fa5312bfaef27b470ea8. --- .../programTransformation/CMakeLists.txt | 1 + .../astOutlining/GenerateFunc.cc | 5 +- .../astOutlining/PragmaInterface.cc | 4 +- .../CMakeLists.txt | 3 + .../ExtractFunctionArguments.C | 379 ++++++++++++++++++ .../ExtractFunctionArguments.h | 83 ++++ .../Makefile.am | 22 + .../functionEvaluationOrderTraversal.C | 166 ++++++++ .../functionEvaluationOrderTraversal.h | 89 ++++ 9 files changed, 747 insertions(+), 5 deletions(-) create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C create mode 100644 src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h diff --git a/src/midend/programTransformation/CMakeLists.txt b/src/midend/programTransformation/CMakeLists.txt index 6a28cf5c3c1..cba1b50a9ae 100644 --- a/src/midend/programTransformation/CMakeLists.txt +++ b/src/midend/programTransformation/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(astInlining) add_subdirectory(astOutlining) add_subdirectory(ompLowering) add_subdirectory(transformationTracking) +add_subdirectory(extractFunctionArgumentsNormalization) add_subdirectory(singleStatementToBlockNormalization) if(NOT enable-internalFrontendDevelopment) add_subdirectory(loopProcessing) diff --git a/src/midend/programTransformation/astOutlining/GenerateFunc.cc b/src/midend/programTransformation/astOutlining/GenerateFunc.cc index 57853a80c01..226b88b2f9f 100644 --- a/src/midend/programTransformation/astOutlining/GenerateFunc.cc +++ b/src/midend/programTransformation/astOutlining/GenerateFunc.cc @@ -22,7 +22,6 @@ #include #include #include -#include #include "Outliner.hh" #include "ASTtools.hh" @@ -1398,8 +1397,8 @@ class SymbolMapOfTwoFiles dict[i1->second]=i2->second; #endif rose_hash_multimap::iterator i1, i2; - std::unordered_map varSymDict; - std::unordered_map funcSymDict; + boost::unordered_map varSymDict; + boost::unordered_map funcSymDict; // cache mapping of new symbols,indexed by qualified name : qualified name to symbol for (i2=set2->begin(); i2!=set2->end(); i2++) diff --git a/src/midend/programTransformation/astOutlining/PragmaInterface.cc b/src/midend/programTransformation/astOutlining/PragmaInterface.cc index 4c9035e53d0..af02e2f3021 100644 --- a/src/midend/programTransformation/astOutlining/PragmaInterface.cc +++ b/src/midend/programTransformation/astOutlining/PragmaInterface.cc @@ -19,7 +19,7 @@ #include "Outliner.hh" #include "ASTtools.hh" #include "PreprocessingInfo.hh" -#include +#include //! Simplest outlining directives, applied to a single statement. static const std::string PRAGMA_OUTLINE ("rose_outline"); @@ -89,7 +89,7 @@ processFortranComment(SgLocatedNode* node) if ((*i)->getTypeOfDirective() == PreprocessingInfo::FortranStyleComment) { string commentString = (*i)->getString(); - trim(commentString); + boost::algorithm::trim(commentString); if ( (commentString == "!$"+PRAGMA_OUTLINE) || (commentString == "c$"+PRAGMA_OUTLINE) || (commentString == "*$"+PRAGMA_OUTLINE)) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt b/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt new file mode 100644 index 00000000000..859357b7396 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/CMakeLists.txt @@ -0,0 +1,3 @@ +install(FILES + ExtractFunctionArguments.h functionEvaluationOrderTraversal.h + DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C new file mode 100644 index 00000000000..ff84237e9f8 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C @@ -0,0 +1,379 @@ +#include "ExtractFunctionArguments.h" +#include +#include +#include +#include "SingleStatementToBlockNormalization.h" + +#define foreach BOOST_FOREACH + +using namespace std; +using namespace boost; + + +/** Performs the function argument extraction on all function calls in the given subtree of the AST. */ +/** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all callsites ignoring the safety (Suggested by Markus Schordan) */ + +void ExtractFunctionArguments::NormalizeTree(SgNode* tree, bool doUnsafeNormalization) { + // First Normalize each single statememnt body into a block body + // This transformation is necessary to provide scope to newly created temporaries + // Note: if this transofrmation is already done, it is benign to rerun it + // and this would act as a NOP transformation. + + SingleStatementToBlockNormalizer singleStatementToBlockNormalizer; + singleStatementToBlockNormalizer.Normalize(tree); + + + + // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) + // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} + this->functionCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); + + // Normalize each function from safe place + foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.first) { + RewriteFunctionCallArguments(functionCallInfo); + } + + // if doUnsafeNormalization is true, we will normalize calls which are not safe + if(doUnsafeNormalization){ + foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.second) { + RewriteFunctionCallArguments(functionCallInfo); + } + } + +} + + +/* + return a vector of temporaries introduced during the translation process + */ +std::vector ExtractFunctionArguments::GetTemporariesIntroduced() { + return this->temporariesIntroduced; +} + +/** Returns true if the given expression refers to a variable. This could include using the + * dot and arrow operator to access member variables. A comma op counts as a variable references + * if all its members are variable references (not just the last expression in the list). */ +bool isVariableReference(SgExpression* expression) +{ + if (isSgVarRefExp(expression)) + { + return true; + } + else if (isSgThisExp(expression)) + { + return true; + } + else if (isSgDotExp(expression)) + { + SgDotExp* dotExpression = isSgDotExp(expression); + return isVariableReference(dotExpression->get_lhs_operand()) && + isVariableReference(dotExpression->get_rhs_operand()); + } + else if (isSgArrowExp(expression)) + { + SgArrowExp* arrowExpression = isSgArrowExp(expression); + return isVariableReference(arrowExpression->get_lhs_operand()) && + isVariableReference(arrowExpression->get_rhs_operand()); + } + else if (isSgCommaOpExp(expression)) + { + //Comma op where both the lhs and th rhs are variable references. + //The lhs would be semantically meaningless since it doesn't have any side effects + SgCommaOpExp* commaOp = isSgCommaOpExp(expression); + return isVariableReference(commaOp->get_lhs_operand()) && + isVariableReference(commaOp->get_rhs_operand()); + } + else if (isSgPointerDerefExp(expression) || isSgCastExp(expression) || isSgAddressOfOp(expression)) + { + return isVariableReference(isSgUnaryOp(expression)->get_operand()); + } + else + { + return false; + } +} + +/* Given the expression which is the argument to a function call, returns true if that + expression is trivial. Trivial expressions are those which are simple variable references or constants. + */ + +bool ExtractFunctionArguments::IsFunctionArgumentTrivial(SgExpression* argument) { + while ((isSgPointerDerefExp(argument) || isSgCastExp(argument) || isSgAddressOfOp(argument))) { + argument = isSgUnaryOp(argument)->get_operand(); + } + + SgArrowExp* arrowExp = isSgArrowExp(argument); + if (arrowExp && isSgThisExp(arrowExp->get_lhs_operand())) + return true; + + // We don't lift these simple types + if (isVariableReference(argument) || isSgValueExp(argument)) + return true; + + return false; +} + + +/* Given a vector of function call sites returns true if every argument of every function call is a trivial expression + (IsFunctionArgumentTrivial). Such functions don't need to be normalized. + */ +bool ExtractFunctionArguments::AreAllFunctionCallsTrivial(std::vector functions){ + foreach(FunctionCallInfo functionCallInfo, functions){ + foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ + if (!IsFunctionArgumentTrivial(arg)) { + return false; + } + } + } + return true; +} + +/* Given a vector of function call sites, returns true if every argument + at every function call site is either trivial (IsFunctionArgumentTrivial) or can be normalized (FunctionArgumentCanBeNormalized). + */ +bool ExtractFunctionArguments::AreAllFunctionCallsNormalizable(std::vector functions){ + foreach(FunctionCallInfo functionCallInfo, functions){ + foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ + if (!IsFunctionArgumentTrivial(arg) && !FunctionArgumentCanBeNormalized(arg)) { + return false; + } + } + } + return true; +} + + +/* + IsNormalized: Given a subtree, returns true if every argument of every function call is a trivial arguemnt. +*/ + +bool ExtractFunctionArguments::IsNormalized(SgNode* tree){ + // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) + // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} + pair< std::vector, std::vector > fCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); + + //Make sure all arguemnts of all SAFE place functions calls are trivial + if(!AreAllFunctionCallsTrivial(fCalls.first)) + return false; + + //Make sure all arguemnts of all NON-SAFE place functions calls are also trivial + if(!AreAllFunctionCallsTrivial(fCalls.second)) + return false; + + // All are trivial + return true; +} + + +/* + IsNormalizable: Given a subtree, returns true if every argument of every function call is a either trivial arguemnt or + present in a SAFE place from where lifting is possible. +*/ + +bool ExtractFunctionArguments::IsNormalizable(SgNode* tree){ + // Obtain functions that are candidates for normalizing (first) and those which are not condidates (second) + // non candidates are those which are present in places from where it is unsafe to lift: e.g., : while(Foo(Bar())){} + pair< std::vector, std::vector > fCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); + + //Make sure all arguemnts of all SAFE place functions calls are either trivial or normalizable + if(!AreAllFunctionCallsNormalizable(fCalls.first)) + return false; + + // Must be trivail in NON SAFE places + if(!AreAllFunctionCallsTrivial(fCalls.second)) + return false; + + // We can normalize + return true; +} + + +/** Given the information about a function call (obtained through a traversal), extract its arguments + * into temporary variables where it is necessary. + * Returns true on success, false on failure (unsupported code). */ +void ExtractFunctionArguments::RewriteFunctionCallArguments(const FunctionCallInfo& functionCallInfo) +{ + SgFunctionCallExp* functionCall = functionCallInfo.functionCall; + + // Force the function call to NOT use operator syntax + functionCall->set_uses_operator_syntax(false); + + SgExprListExp* functionArgs = functionCall->get_args(); + ROSE_ASSERT(functionArgs != NULL); + + SgExpressionPtrList argumentList = functionArgs->get_expressions(); + + // We also normalize the caller if the function called is a member function. + if (SgBinaryOp * binExp = isSgBinaryOp(functionCall->get_function())) { + argumentList.push_back(binExp->get_lhs_operand()); + } + + //Go over all the function arguments, pull them out + + foreach(SgExpression* arg, argumentList) + { + //No need to pull out parameters that are not complex expressions and + //thus don't have side effects + if (!FunctionArgumentNeedsNormalization(arg)) + continue; + + //Build a declaration for the temporary variable + SgScopeStatement* scope = functionCallInfo.tempVarDeclarationLocation->get_scope(); + ROSE_ASSERT(scope != NULL ); + + // DQ (3/1/2015): Added initialization to these local variables. + // SgVariableDeclaration* tempVarDeclaration; + // SgExpression* tempVarReference; + SgVariableDeclaration* tempVarDeclaration = NULL; + SgExpression* tempVarReference = NULL; + + // DQ (3/1/2015): Avoid normalization of function arguments of type SgFunctionType (see inputBug317.C). + // This might be an issue more narrowly defined for compiler-generated functions, this is less clear. + SgFunctionType* functionType = isSgFunctionType(arg->get_type()); + if (functionType == NULL) + { + tie(tempVarDeclaration, tempVarReference) = SageInterface::createTempVariableAndReferenceForExpression(arg, scope); + + // createTempVariableOrReferenceForExpression does not set the parent if the scope stack is empty. Hence set it manually to the currect scope. + tempVarDeclaration->set_parent(scope); +#if 0 + { + std::cout<<"\n"<get_file_info()->get_filenameString () << ":" << functionCall->get_file_info()->get_line() << ":" << functionCall->get_file_info()->get_col(); + std::cout<<"\n Name = "<< tempVarDeclaration->get_mangled_name().getString()<< " : type : " << arg->get_type()->class_name() << " Expr class : " << arg->class_name(); + } +#endif + ROSE_ASSERT(tempVarDeclaration != NULL ); + + // DQ (3/1/2015): This is not always true (see inputBug317.C). + ROSE_ASSERT(tempVarDeclaration->get_definition(0) != NULL); + ROSE_ASSERT(isSgVariableDefinition(tempVarDeclaration->get_definition()) != NULL); + + //Insert the temporary variable declaration + InsertStatement(tempVarDeclaration, functionCallInfo.tempVarDeclarationLocation, functionCallInfo); + + // remember the introduced temp so that it can be queried + temporariesIntroduced.push_back(tempVarDeclaration); + + //Replace the argument with the new temporary variable + SageInterface::replaceExpression(arg, tempVarReference); + } + else + { + printf ("In ExtractFunctionArguments::RewriteFunctionCallArguments(): Skipping normalization of function arguments of type SgFunctionType \n"); + } + } +} + + +// If we have a limitation in normalizing the function return false +bool ExtractFunctionArguments::FunctionArgumentCanBeNormalized(SgExpression* argument) +{ + while ((isSgPointerDerefExp(argument) || isSgCastExp(argument) || isSgAddressOfOp(argument))) + { + argument = isSgUnaryOp(argument)->get_operand(); + } + // Don't include SgConstructorInitializer since it will be called even on the temporary, so avoid double copy. + if (isSgFunctionRefExp(argument) || isSgMemberFunctionRefExp(argument) || isSgConstructorInitializer(argument)) + return false; + + // Unknow Template type expressions can't be normalized. + if (isSgTypeUnknown(argument->get_type()) || isSgMemberFunctionType(argument->get_type())) { + //printf("\n Skipping over SgTypeUnknown/SgMemberFunctionType expr"); + return false; + } + + return true; +} + + + +/** Given the expression which is the argument to a function call, returns true if that + * expression should be pulled out into a temporary variable on a separate line. + * E.g. if the expression contains a function call, it needs to be normalized, while if it + * is a constant, there is no need to change it. */ + +bool ExtractFunctionArguments::FunctionArgumentNeedsNormalization(SgExpression* argument) +{ + // Trivial argument don't need to be listed + + if (IsFunctionArgumentTrivial(argument)) + return false; + + // true/false based on our ability to normalize the argument + return FunctionArgumentCanBeNormalized(argument); +} + + +/** Returns true if any of the arguments of the given function call will need to + * be extracted. */ +bool ExtractFunctionArguments::FunctionArgsNeedNormalization(SgExprListExp* functionArgs) +{ + ROSE_ASSERT(functionArgs != NULL); + SgExpressionPtrList& argumentList = functionArgs->get_expressions(); + + foreach(SgExpression* functionArgument, argumentList) + { + if (FunctionArgumentNeedsNormalization(functionArgument)) + return true; + } + return false; +} + +/** Returns true if any function calls in the given subtree will need to be + * instrumented. (to extract function arguments). */ +bool ExtractFunctionArguments::SubtreeNeedsNormalization(SgNode* top) +{ + ROSE_ASSERT(top != NULL); + Rose_STL_Container functionCalls = NodeQuery::querySubTree(top, V_SgFunctionCallExp); + for (Rose_STL_Container::const_iterator iter = functionCalls.begin(); iter != functionCalls.end(); iter++) + { + SgExpression* functionCall = isSgFunctionCallExp(*iter); + ROSE_ASSERT(functionCall != NULL); + if (FunctionArgumentNeedsNormalization(functionCall)) + return true; + } + + return false; +} + +/** Insert a new statement in the specified location. The actual insertion can occur either before or after the location + * depending on the insertion mode. */ +void ExtractFunctionArguments::InsertStatement(SgStatement* newStatement, SgStatement* location, const FunctionCallInfo& insertionMode) +{ + switch (insertionMode.tempVarDeclarationInsertionMode) + { + case FunctionCallInfo::INSERT_BEFORE: + SageInterface::insertStatementBefore(location, newStatement); + break; + case FunctionCallInfo::APPEND_SCOPE: + { + SgScopeStatement* scopeStatement = isSgScopeStatement(location); + if (scopeStatement == NULL) + { + //scopeStatement = isSgScopeStatement(SageInterface::ensureBasicBlockAsParent(location)); + if (SageInterface::isBodyStatement(location)) // if the location is a single body statement (not a basic block) at this point + scopeStatement = SageInterface::makeSingleStatementBodyToBlock (location); + else + scopeStatement = isSgScopeStatement(location->get_parent()); + } + ROSE_ASSERT(scopeStatement != NULL); + + SageInterface::appendStatement(newStatement, scopeStatement); + break; + } + case FunctionCallInfo::INVALID: + default: + ROSE_ABORT(); + } +} + +/** Traverses the subtree of the given AST node and finds all function calls in + * function-evaluation order. */ +/*static*/pair< std::vector, std::vector > FunctionEvaluationOrderTraversal::GetFunctionCalls(SgNode* root) +{ + FunctionEvaluationOrderTraversal t; + FunctionCallInheritedAttribute rootAttribute; + t.traverse(root, rootAttribute); + + return pair< std::vector, std::vector > (t.normalizableFunctionCalls, t.nonNormalizableFunctionCalls); +} diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h new file mode 100644 index 00000000000..7bd0d37c3f3 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.h @@ -0,0 +1,83 @@ +#pragma once + +// DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h. +// #include "rose.h" +#include "sage3basic.h" + +#include "functionEvaluationOrderTraversal.h" + +//class FunctionCallInfo; + +//! This normalization makes sure each function call argument is a side-effect free expression of only one variable. +//! To accomplish this, temporary variables are declared and the arguments of a function are evaluated before the function itself. +//! Note: Normalization is not performed if it is unsafe. E,g.: while(Foo(Bar()) {} is not equal to t = Bar(); while(Foo(t) {} +//! Note that only SgFunctionCall arguments are normalized. For example the arguments of the constructor initializer +//! MyObject o(foo(), bar()) will not be extracted. +class ExtractFunctionArguments +{ +public: + + /** Performs the function argument extraction on all function calls in the given subtree of the AST. */ + /** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all call sites ignoring the safety (Suggested by Markus Schordan) */ + void NormalizeTree(SgNode* tree, bool doUnsafeNormalization = false); + + // returns a vector of newly introduced temporaries + std::vector GetTemporariesIntroduced(); + + /* + IsNormalized: Given a subtree, returns true if every argument of every function call is a trivial arguemnt. + */ + bool IsNormalized(SgNode* tree); + + /* + IsNormalizable: Given a subtree, returns true if every argument of every function call is a either trivial arguemnt or + is present in a SAFE place from where lifting is possible. + */ + bool IsNormalizable(SgNode* tree); + + +private: + + std::vector temporariesIntroduced; + std::pair< std::vector, std::vector > functionCalls; + + /** Given the expression which is the argument to a function call, returns true if that + * expression should be pulled out into a temporary variable on a separate line. + * E.g. if the expression contains a function call, it needs to be normalized, while if it + * is a constant, there is no need to change it. */ + bool FunctionArgumentNeedsNormalization(SgExpression* argument); + + /** Returns true if any of the arguments of the given function call will need to + * be extracted. */ + bool FunctionArgsNeedNormalization(SgExprListExp* functionArgs); + + /** Returns true if any function calls in the given subtree will need to be + * instrumented. (to extract function arguments). */ + bool SubtreeNeedsNormalization(SgNode* top); + + /** Given the information about a function call (obtained through a traversal), extract its arguments + * into temporary variables where it is necessary. */ + void RewriteFunctionCallArguments(const FunctionCallInfo& functionCallInfo); + + /** Insert a new statement in the specified location. The actual insertion can occur either before or after the location + * depending on the insertion mode. */ + void InsertStatement(SgStatement* newStatement, SgStatement* location, const FunctionCallInfo& insertionMode); + + bool FunctionArgumentCanBeNormalized(SgExpression* argument); + + + /* Given the expression which is the argument to a function call, returns true if that + expression is trivial. Trivial expressions are those which are simple variable references or constants. + */ + bool IsFunctionArgumentTrivial(SgExpression* argument); + + /* Given a vector of function call sites returns true if every argument of every function call is a trivial expression + (IsFunctionArgumentTrivial). Such functions don't need to be normalized. + */ + bool AreAllFunctionCallsTrivial(std::vector functions); + + /* Given a vector of function call sites, returns true if every argument + at every function call site is either trivial (IsFunctionArgumentTrivial) or can be normalized (FunctionArgumentCanBeNormalized). + */ + bool AreAllFunctionCallsNormalizable(std::vector functions); +}; diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am b/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am new file mode 100644 index 00000000000..4d9b1a853a7 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/Makefile.am @@ -0,0 +1,22 @@ +include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs + +AM_CPPFLAGS = $(ROSE_INCLUDES) +#LINK = $(CXXLINK) + +# noinst_LTLIBRARIES lists all the libraries that should be built, but not installed +noinst_LTLIBRARIES = libExtractFunctionArgumentsNormalization.la + +libExtractFunctionArgumentsNormalization_la_DEPENDENCIES = $(srcdir)/../singleStatementToBlockNormalization/SingleStatementToBlockNormalization.h +libExtractFunctionArgumentsNormalization_la_CXXFLAGS = -I$(srcdir)/../singleStatementToBlockNormalization +libExtractFunctionArgumentsNormalization_la_SOURCES = ExtractFunctionArguments.C functionEvaluationOrderTraversal.C +pkginclude_HEADERS = ExtractFunctionArguments.h functionEvaluationOrderTraversal.h + + +# EXTRA_DIST are files that are not compiled or installed. These include readme's, internal header files, etc. +EXTRA_DIST = + +CLEANFILES = + + +check-local: + diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C new file mode 100644 index 00000000000..175939503f8 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.C @@ -0,0 +1,166 @@ +#include "sage3basic.h" // every librose .C file must start with this +#include + + +bool IsStatusSafe(int status){ + if (status == FunctionCallInheritedAttribute::IN_SAFE_PLACE) + return true; + if (status == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) + return true; + return false; +} + +/** Visits AST nodes in pre-order */ +FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute) +{ + FunctionCallInheritedAttribute result = parentAttribute; + SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope); + SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope); + SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope); + + SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL; + SgAndOp* parentAndOp = astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL; + SgOrOp* parentOrOp = astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL; + + if (isSgForStatement(astNode)) + result.currentScope = isSgForStatement(astNode); + else if (isSgWhileStmt(astNode)) + result.currentScope = isSgWhileStmt(astNode); + else if (isSgDoWhileStmt(astNode)) + result.currentScope = isSgDoWhileStmt(astNode); + //else if (isSgConditionalExp(astNode)) + // result.currentScope = isSgConditionalExp(astNode); + //else if (isSgAndOp(astNode)) + // result.currentScope = isSgAndOp(astNode); + //else if (isSgOrOp(astNode)) + // result.currentScope = isSgOrOp(astNode); + else if (isSgForInitStatement(astNode)) { + ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT; + ROSE_ASSERT(isSgForStatement(result.currentScope)); + } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) { + ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST; + } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) { + ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT; + } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) { + ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION; + } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) { + ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION; + } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) { + // if the scope status was safe, turn it into unsafe + if (IsStatusSafe(result.scopeStatus)) + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM; + } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) { + // if the scope status was safe, turn it into unsafe + if (IsStatusSafe(result.scopeStatus)) + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM; + } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) { + // if the scope status was safe, turn it into unsafe + if (IsStatusSafe(result.scopeStatus)) + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; + } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode) { + // if the scope status was safe, turn it into unsafe + if (IsStatusSafe(result.scopeStatus)) + result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; + } + + //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc. + if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) { + //We can't insert a variable declaration at these locations. Use the parent statement + } else if (isSgStatement(astNode)) { + result.lastStatement = isSgStatement(astNode); + } + + return result; +} + +// Returns false in the absence of any analysis information +bool FunctionEvaluationOrderTraversal::IsFunctionCallSideEffectFree(SgFunctionCallExp* functionCall) { + return false; +} + + +/** Visits AST nodes in post-order. This is function-evaluation order. */ +bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList) +{ + SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode); + if (functionCall == NULL) + return false; //dummy return value + + FunctionCallInfo functionCallInfo(functionCall); + + // Can't lift function call arguments from the following: + // 1. For loop test and increment + // 2. While loop test + // 3. Do-While loop test + // 4. Either arms of ternary op + // 5. RHS of any short circuit expression + // An alternative is to use comma operators and use assignemnt op as done by the original author. + // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);) + // But using assignement op is not always safe and it requires us to always have a default constructor + // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer + // but if & op is overloaded we may not get the pointer. + // Taking all these in view, I am simpling not lifting such expressions. + + if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST || + parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT || + parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION || + parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) { + + // ***** FOR UNSAFE TRANSFORMATION ******* + //Temporary variables should be declared before the stmt + ROSE_ASSERT(isSgStatement(parentAttribute.currentScope)); + functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope); + functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; + + nonNormalizableFunctionCalls.push_back(functionCallInfo); + return false; + } + + // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions + if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM || + parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM || + parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){ + + if(!IsFunctionCallSideEffectFree(functionCall)) { + + // ***** FOR UNSAFE TRANSFORMATION ******* + //Temporary variables should be declared before the stmt + ROSE_ASSERT(parentAttribute.lastStatement); + functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; + functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; + + nonNormalizableFunctionCalls.push_back(functionCallInfo); + return false; + } + } + + //Handle for loops (being inside the body of a for loop doesn't need special handling) + if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) + { + SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope); + ROSE_ASSERT(forLoop != NULL); + //Temporary variables should be declared before the loop + functionCallInfo.tempVarDeclarationLocation = forLoop; + functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; + } + else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE) + { + //Assume we're in a basic block. Then just insert right before the current statement + ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE); + functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; + functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; + } + else + { + //Unhandled condition?! + ROSE_ABORT(); + } + + normalizableFunctionCalls.push_back(functionCallInfo); + return false; //dummy return value +} diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h new file mode 100644 index 00000000000..e00d7203382 --- /dev/null +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/functionEvaluationOrderTraversal.h @@ -0,0 +1,89 @@ +#pragma once + +// DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h. +// #include "rose.h" +// rose.h and sage3basic.h should not be included in librose header files. [Robb P. Matzke 2014-10-15] +// #include "sage3basic.h" + +struct FunctionCallInheritedAttribute +{ + /** The innermost scope inside of which this AST node resides. It is either a for-loop, + a do-loop, a while-loop or a conditioanl expression. */ + SgNode* currentScope; + + /** The last statement encountered before the current node in the AST. */ + SgStatement* lastStatement; + + /** Is the current node inside a for loop or conditional expresion structure (not the body). */ + enum + { + INSIDE_FOR_INIT, INSIDE_FOR_TEST, INSIDE_FOR_INCREMENT, INSIDE_WHILE_CONDITION, + INSIDE_DO_WHILE_CONDITION, IN_SAFE_PLACE, INSIDE_CONDITIONAL_EXP_TRUE_ARM, INSIDE_CONDITIONAL_EXP_FALSE_ARM, INSIDE_SHORT_CIRCUIT_EXP_RHS + } + scopeStatus; + + /** Default constructor. Initializes everything to NULL. */ + FunctionCallInheritedAttribute() : currentScope(NULL), lastStatement(NULL), scopeStatus(IN_SAFE_PLACE) { } +}; + +/** Stores a function call expression, along with associated information about its context. */ +struct FunctionCallInfo +{ + /** The function call expression. */ + SgFunctionCallExp* functionCall; + + /** When a variable is created to replace one of the arguments of this function, where should it be inserted? + * The declaration of the variable will occur right before this statement. */ + SgStatement* tempVarDeclarationLocation; + + /** How a statement should be inserted. */ + enum InsertionMode + { + /** Insert right before the given statement. */ + INSERT_BEFORE, + /** Insert at the bottom of the scope defined by the given statement. */ + APPEND_SCOPE, + INVALID + }; + + /** How to insert the temporary variable declaration. */ + InsertionMode tempVarDeclarationInsertionMode; + + FunctionCallInfo(SgFunctionCallExp * function) : + functionCall(function), + tempVarDeclarationLocation(NULL), + tempVarDeclarationInsertionMode(INVALID) { } +}; + + +//! Traverses a given AST and finds all function calls in the order in which they're evaluated +//! Also, for each function we find where to put declarations of temporary variables so that they're accessible at the function call + +class FunctionEvaluationOrderTraversal : public AstTopDownBottomUpProcessing +{ +public: + /** Traverses the subtree of the given AST node and finds all function calls in + * function-evaluation order. */ + static std::pair< std::vector, std::vector > GetFunctionCalls(SgNode* root); + + /** Visits AST nodes in pre-order */ + FunctionCallInheritedAttribute evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute); + + /** Visits AST nodes in post-order. This is function-evaluation order. */ + bool evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList); + + /// Returns true if the function call has no side effects. + virtual bool IsFunctionCallSideEffectFree(SgFunctionCallExp* functionCall); + +private: + + //! Private constructor. Use the static method to access the functionality of this class. + + FunctionEvaluationOrderTraversal() { } + + /** All the function calls seen so far that can be normalized. */ + std::vector normalizableFunctionCalls; + /** All the function calls seen so far that can't be normalized. */ + std::vector nonNormalizableFunctionCalls; +}; + From 2dbc1bd6cf2389b46534b628c476bd4156f605bf Mon Sep 17 00:00:00 2001 From: Patrick Flynn Date: Tue, 26 Sep 2023 11:26:27 -0400 Subject: [PATCH 15/42] Removed boost serialization --- src/ROSETTA/Grammar/Node.code | 4 ---- src/ROSETTA/Grammar/Support.code | 20 -------------------- 2 files changed, 24 deletions(-) diff --git a/src/ROSETTA/Grammar/Node.code b/src/ROSETTA/Grammar/Node.code index d787ca122ea..9f690bdcc2c 100644 --- a/src/ROSETTA/Grammar/Node.code +++ b/src/ROSETTA/Grammar/Node.code @@ -7,10 +7,6 @@ HEADER_NODE_PREDECLARATION_START #include #include -#include -#include -#include - // tps (01/27/10): Added essential files.. //#include "sage3basic.h" #include diff --git a/src/ROSETTA/Grammar/Support.code b/src/ROSETTA/Grammar/Support.code index 71ded074a02..b81d5430e40 100644 --- a/src/ROSETTA/Grammar/Support.code +++ b/src/ROSETTA/Grammar/Support.code @@ -8,16 +8,6 @@ HEADER_START private: $CLASSNAME(const $CLASSNAME &); /* private so it can't be used. */ $CLASSNAME & operator= ( const $CLASSNAME & X ); - - private: - friend class boost::serialization::access; - template - void serialize(S &s, const unsigned /*version*/) { - s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(SgNode); - // No data members are serialized at this time, but this serialization function needs to be - // defined because SgSupport is an indirect base class of SgBinaryComposite, which is - // serializable. - } HEADER_END @@ -6118,16 +6108,6 @@ HEADER_APPLICATION_FILE_PREDECLARATION_END HEADER_APPLICATION_FILE_START -private: - friend class boost::serialization::access; - - template - void serialize(S &s, const unsigned /*version*/) { - s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(SgSupport); - // Most data members are not serialized yet, but this is here because SgFile is a base class of - // SgBinaryComposite whose fields are serialized. - } - public: /*! \brief Enum type used to specify output of Fortran as fixed for free format. From 0c95ac35a5869a779a8c6cba27b2d121f9243084 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Fri, 29 Sep 2023 07:31:42 -0400 Subject: [PATCH 16/42] [REX]: deBoost: replace the usage of BOOST_FOREACH with C++17 foreach. This is performed using a python script generated from ChatGPT and then manually checked each change one by one. The script replace BOOST_FOREACH/foreach with for, and the , with : in the same line. --- .../SageIII/sageInterface/sageBuilder.C | 3 - .../SageIII/sageInterface/sageInterface.C | 17 +- .../sageInterface/sageInterface_type.C | 62 +++--- src/frontend/SageIII/sage_support/cmdline.cpp | 7 +- .../SageIII/sage_support/keep_going.cpp | 15 +- .../SageIII/sage_support/sage_support.cpp | 7 +- .../SageIII/virtualCFG/customFilteredCFG.C | 10 +- .../SageIII/virtualCFG/interproceduralCFG.C | 10 +- .../SageIII/virtualCFG/memberFunctions.C | 8 +- src/frontend/SageIII/virtualCFG/staticCFG.C | 28 ++- src/midend/astDump/AstDOTGeneration.C | 11 +- src/midend/astProcessing/graphProcessing.h | 1 - src/midend/astProcessing/graphTemplate.h | 16 +- .../CallGraphAnalysis/CallGraph.C | 20 +- .../CallGraphAnalysis/CallGraph.h | 7 +- .../CallGraphAnalysis/ClassHierarchyGraph.C | 7 +- .../InterProcDataFlowAnalysis.C | 5 +- .../IntraProcAliasAnalysis.C | 16 +- .../IntraProcAliasAnalysis.h | 6 - .../PtrAliasAnalysis.C | 15 +- .../VirtualFunctionAnalysis.C | 8 +- .../variableRenaming/VariableRenaming.C | 201 +++++++++--------- .../variableRenaming/VariableRenaming.h | 3 +- .../ExtractFunctionArguments.C | 21 +- src/rose-config.C | 7 +- src/util/StringUtility/FileNameClassifier.C | 1 - src/util/StringUtility/FileUtility.C | 1 - .../CompileTests/Cxx17_tests/test2018_25.C | 2 +- .../CompileTests/Cxx_tests/test2011_10.C | 2 +- .../CompileTests/Cxx_tests/test2011_13.C | 3 +- .../CompileTests/Cxx_tests/test2014_103.C | 4 +- .../CompileTests/Cxx_tests/test2014_104.C | 4 +- .../CompileTests/Cxx_tests/test2014_105.C | 4 +- .../CompileTests/Cxx_tests/test2014_106.C | 4 +- .../CompileTests/Cxx_tests/test2014_108.C | 2 +- .../CompileTests/Cxx_tests/test2015_55.C | 4 +- .../CompileTests/Cxx_tests/test2015_56.h | 38 ++-- .../CompileTests/Cxx_tests/test2016_58.C | 13 +- ...eDeclarationToInnermostScope_test2015_71.C | 4 +- .../astInliningTests/inlineEverything.C | 2 +- .../roseTests/astLValueTests/runTest.C | 7 +- .../VirtualFunctionAnalysisTest.C | 6 - .../pointerAliasAnalysis.h | 1 - .../typeTraitExerciseWithRetCode.C | 4 - .../typeTraitExerciseWithoutRetCode.C | 2 - .../NormalizationTranslator.C | 4 +- .../translatorTests/testConstDeclarations.C | 3 +- .../translatorTests/testDataMemberOfConst.C | 3 +- .../translatorTests/testFortranParameter.C | 3 +- .../translatorTests/testFortranProtected.C | 6 +- .../translatorTests/testTranslator2010_03.C | 3 +- tools/moveDeclarationToInnermostScope.C | 3 +- tutorial/ASTGraphGeneratorCustomized.C | 1 - tutorial/classHierarchyGraph.C | 6 +- 54 files changed, 278 insertions(+), 373 deletions(-) diff --git a/src/frontend/SageIII/sageInterface/sageBuilder.C b/src/frontend/SageIII/sageInterface/sageBuilder.C index 411f96b1b7f..34359b54958 100644 --- a/src/frontend/SageIII/sageInterface/sageBuilder.C +++ b/src/frontend/SageIII/sageInterface/sageBuilder.C @@ -12,13 +12,11 @@ // #include "sageBuilder.h" #include #include - #include #include "Outliner.hh" #else // #include "sageBuilder.h" #include #include - #include #endif // DQ (4/3/2012): Added so that I can enforce some rules as the AST is constructed. @@ -28,7 +26,6 @@ #include "RoseAst.h" // DQ (3/31/2012): Is this going to be an issue for C++11 use with ROSE? -#define foreach BOOST_FOREACH diff --git a/src/frontend/SageIII/sageInterface/sageInterface.C b/src/frontend/SageIII/sageInterface/sageInterface.C index 4719aee44a3..ed61908f756 100644 --- a/src/frontend/SageIII/sageInterface/sageInterface.C +++ b/src/frontend/SageIII/sageInterface/sageInterface.C @@ -49,7 +49,6 @@ #endif #include -#include #include #include #include // for set operations @@ -10610,7 +10609,7 @@ string SageInterface::generateUniqueVariableName(SgScopeStatement* scope, std::s //Look up the name in the children scopes Rose_STL_Container childScopes = NodeQuery::querySubTree(scope, V_SgScopeStatement); - BOOST_FOREACH(SgNode* childScope, childScopes) + for(SgNode* childScope: childScopes) { SgScopeStatement* childScopeStatement = isSgScopeStatement(childScope); @@ -14416,7 +14415,7 @@ void SageInterface::insertStatementBeforeFirstNonDeclaration(SgStatement *newStm { ROSE_ASSERT(newStmt!=NULL); ROSE_ASSERT(scope!=NULL); - BOOST_FOREACH (SgStatement *targetStmt, scope->generateStatementList()) { + for (SgStatement *targetStmt: scope->generateStatementList()) { if (!isSgDeclarationStatement(targetStmt)) { insertStatementBefore(targetStmt, newStmt, movePreprocessingInfo); return; @@ -14428,7 +14427,7 @@ void SageInterface::insertStatementBeforeFirstNonDeclaration(SgStatement *newStm void SageInterface::insertStatementListBeforeFirstNonDeclaration(const std::vector &newStmts,SgScopeStatement *scope) { ROSE_ASSERT(scope!=NULL); - BOOST_FOREACH (SgStatement *targetStmt, scope->generateStatementList()) { + for (SgStatement *targetStmt: scope->generateStatementList()) { if (!isSgDeclarationStatement(targetStmt)) { insertStatementListBefore(targetStmt, newStmts); return; @@ -18096,7 +18095,7 @@ void SageInterface::replaceSubexpressionWithStatement(SgExpression* from, Statem std::vector SageInterface::getInParameters(const SgInitializedNamePtrList ¶ms) { std::vector in_params; - BOOST_FOREACH (SgInitializedName* name, params) + for (SgInitializedName* name: params) { if (!isMutable(name)) in_params.push_back(name); } @@ -18108,7 +18107,7 @@ void SageInterface::replaceSubexpressionWithStatement(SgExpression* from, Statem std::vector SageInterface::getOutParameters(const SgInitializedNamePtrList ¶ms) { std::vector out_params; - BOOST_FOREACH (SgInitializedName* name, params) + for (SgInitializedName* name: params) { if (isMutable(name)) out_params.push_back(name); } @@ -20359,7 +20358,7 @@ SageInterface::deleteAST ( SgNode* n ) SgDeclarationStatement * template_decl1 = ((SgDeclarationStatement*)node)->get_definingDeclaration(); if((template_decl==templateInstantiate_defining||template_decl1==templateInstantiate_defining) && node!=templateInstantiate_defining){ /*vector tempargs= ((SgTemplateInstantiationDecl*)node)->get_templateArguments(); - foreach (SgTemplateArgument* element, tempargs){ + for (SgTemplateArgument* element: tempargs){ SgTemplateArgument* temparg = isSgTemplateArgument(element); if(temparg){ delete temparg; @@ -20996,7 +20995,7 @@ SageInterface::deleteAST ( SgNode* n ) } vector tempargs= ((SgTemplateInstantiationDecl*)node)->get_templateArguments(); - foreach (SgTemplateArgument* element, tempargs){ + for (SgTemplateArgument* element: tempargs){ SgTemplateArgument* temparg = isSgTemplateArgument(element); if(temparg){ delete temparg; @@ -21277,7 +21276,7 @@ static void moveOneStatement(SgScopeStatement* sourceBlock, SgScopeStatement* ta if (enum_decl) // Rasmussen (12/23/2020) { // Set the scope of the enumerators - BOOST_FOREACH (SgInitializedName* name, enum_decl->get_enumerators()) + for (SgInitializedName* name: enum_decl->get_enumerators()) { name->set_scope(targetBlock); } diff --git a/src/frontend/SageIII/sageInterface/sageInterface_type.C b/src/frontend/SageIII/sageInterface/sageInterface_type.C index f21ca2aecc5..23d1e761a9e 100644 --- a/src/frontend/SageIII/sageInterface/sageInterface_type.C +++ b/src/frontend/SageIII/sageInterface/sageInterface_type.C @@ -3,10 +3,8 @@ #include #include "sageInterface.h" #include -#include using namespace std; -#define foreach BOOST_FOREACH #define DEBUG_QUADRATIC_BEHAVIOR 0 @@ -822,7 +820,7 @@ bool isCopyConstructible(SgType* type) } //Check that all the bases classes are copy constructible - foreach (SgBaseClass* baseClass, defn->get_inheritances()) + for (SgBaseClass* baseClass: defn->get_inheritances()) { SgClassDeclaration* baseClassDecl = baseClass->get_base_class(); if (!isCopyConstructible(baseClassDecl->get_type())) @@ -1570,9 +1568,9 @@ bool isPureVirtualClass(SgType* type, const ClassHierarchyWrapper& classHierarch //Find all virtual and concrete functions set concreteFunctions, pureVirtualFunctions; - foreach(SgClassDefinition* c, inclusiveAncestors) + for(SgClassDefinition* c: inclusiveAncestors) { - foreach(SgDeclarationStatement* memberDeclaration, c->get_members()) + for(SgDeclarationStatement* memberDeclaration: c->get_members()) { if (SgMemberFunctionDeclaration* memberFunction = isSgMemberFunctionDeclaration(memberDeclaration)) { @@ -1589,11 +1587,11 @@ bool isPureVirtualClass(SgType* type, const ClassHierarchyWrapper& classHierarch } //Check if each virtual function is implemented somewhere - foreach (SgMemberFunctionDeclaration* virtualFunction, pureVirtualFunctions) + for (SgMemberFunctionDeclaration* virtualFunction: pureVirtualFunctions) { bool foundConcrete = false; - foreach (SgMemberFunctionDeclaration* concreteFunction, concreteFunctions) + for (SgMemberFunctionDeclaration* concreteFunction: concreteFunctions) { if (concreteFunction->get_name() != virtualFunction->get_name()) continue; @@ -1680,8 +1678,8 @@ if (!sgClassType) { \ inclusiveAncestors.insert(classDef); //Find all member functions - foreach(SgClassDefinition* c, inclusiveAncestors) { - foreach(SgDeclarationStatement* memberDeclaration, c->get_members()) { + for(SgClassDefinition* c: inclusiveAncestors) { + for(SgDeclarationStatement* memberDeclaration: c->get_members()) { if (SgMemberFunctionDeclaration* memberFunction = isSgMemberFunctionDeclaration(memberDeclaration)) { allMemberFunctions.push_back(memberFunction); } @@ -1713,8 +1711,8 @@ if (!sgClassType) { \ set exclusiveAncestors(ancestors.begin(), ancestors.end()); //Find all data members - foreach(SgClassDefinition* c, exclusiveAncestors) { - foreach(SgDeclarationStatement* memberDeclaration, c->get_members()) { + for(SgClassDefinition* c: exclusiveAncestors) { + for(SgDeclarationStatement* memberDeclaration: c->get_members()) { if (SgVariableDeclaration * sgVariableDeclaration = isSgVariableDeclaration(memberDeclaration)) { allVariableDeclarations.push_back(sgVariableDeclaration); } @@ -1783,7 +1781,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasNoThrowAssign(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isOperator() && memberFunction->get_name().getString()=="operator="){ // check if the function has nothrow attribute //TODO: C++11 accepts noexcept expression which we need to check when we support it. @@ -1812,7 +1810,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasNoThrowCopy(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isConstructor()){ // function must have exactly one argument and the argument type must match class type after stripping typedef, const, and ref if(CheckIfFunctionAcceptsArgumentIgnoreConstRefAndTypedef(memberFunction)) { @@ -1842,7 +1840,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasNoThrowConstructor(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isConstructor()){ // function must have no args if(memberFunction->get_args().size() == 0) { @@ -1879,7 +1877,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasTrivialAssign(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isOperator() && memberFunction->get_name().getString()=="operator="){ // function must have exactly one argument and the argument type after stripping typedef, const, and ref must match class type if(CheckIfFunctionAcceptsArgumentIgnoreConstRefAndTypedef(memberFunction)) @@ -1915,7 +1913,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasTrivialCopy(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isConstructor()){ // function must have exactly one argument and the argument type after stripping typedef, const, and ref must match passed-in type if(CheckIfFunctionAcceptsArgumentIgnoreConstRefAndTypedef(memberFunction)) @@ -1947,7 +1945,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasTrivialConstructor(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isConstructor()){ return false; } @@ -1979,7 +1977,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasTrivialDestructor(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_specialFunctionModifier().isDestructor()){ return false; } @@ -2011,7 +2009,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In HasVirtualDestructor(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_functionModifier().isVirtual() && memberFunction->get_specialFunctionModifier().isDestructor()) return true; } @@ -2079,7 +2077,7 @@ if (!sgClassType) { \ #endif // Match types - foreach(SgClassDefinition* c, inclusiveAncestors) { + for(SgClassDefinition* c: inclusiveAncestors) { if(c->get_declaration()->get_type()->stripType(SgType::STRIP_TYPEDEF_TYPE | SgType::STRIP_ARRAY_TYPE | SgType::STRIP_MODIFIER_TYPE ) == baseClassType) return true; } @@ -2262,7 +2260,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In IsPolymorphic(): allMemberFunctions.size() = %zu \n",allMemberFunctions.size()); #endif - foreach(SgMemberFunctionDeclaration* memberFunction,allMemberFunctions) { + for(SgMemberFunctionDeclaration* memberFunction:allMemberFunctions) { if (memberFunction->get_functionModifier().isVirtual()) return true; } @@ -2304,7 +2302,7 @@ if (!sgClassType) { \ //If we have a virtual function, then it not OK - foreach(SgDeclarationStatement* memberDeclaration, classDef->get_members()) { + for(SgDeclarationStatement* memberDeclaration: classDef->get_members()) { if (SgMemberFunctionDeclaration* memberFunction = isSgMemberFunctionDeclaration(memberDeclaration)) { if (memberFunction->get_functionModifier().isVirtual()) return false; @@ -2329,7 +2327,7 @@ if (!sgClassType) { \ //same access control (private, protected, public) for all its non-static data members bool first = true; SgAccessModifier::access_modifier_enum prevModifier=SgAccessModifier::e_unknown; - foreach(SgDeclarationStatement* memberDeclaration, classDef->get_members()) { + for(SgDeclarationStatement* memberDeclaration: classDef->get_members()) { //has no non-static data members with brace- or equal- initializers. if (SgVariableDeclaration* memberVariable = isSgVariableDeclaration(memberDeclaration)) { if (memberVariable->get_declarationModifier().get_storageModifier().isStatic()) @@ -2343,7 +2341,7 @@ if (!sgClassType) { \ if (first) { first = false; firstNonStaticDataMember = NULL; - foreach(SgInitializedName* name, memberVariable->get_variables ()) { + for(SgInitializedName* name: memberVariable->get_variables ()) { firstNonStaticDataMember = name->get_type(); break; } @@ -2360,7 +2358,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In IsStandardLayout(): allVariableDeclarations.size() = %zu \n",allVariableDeclarations.size()); #endif - foreach(SgVariableDeclaration* memberVariable, allVariableDeclarations) { + for(SgVariableDeclaration* memberVariable: allVariableDeclarations) { if (memberVariable->get_declarationModifier().get_storageModifier().isStatic()) continue; // ok, we have atleast one non-static data member in the ancestry @@ -2380,8 +2378,8 @@ if (!sgClassType) { \ // There can be atmost 1 base class with non-static data members int baseClassesWithNonStaticData = 0; - foreach(SgClassDefinition* c, exclusiveAncestors) { - foreach(SgDeclarationStatement* baseMemberDeclaration, c->get_members()) { + for(SgClassDefinition* c: exclusiveAncestors) { + for(SgDeclarationStatement* baseMemberDeclaration: c->get_members()) { if (SgVariableDeclaration* baseMemberVariable = isSgVariableDeclaration(baseMemberDeclaration)) { if (!baseMemberVariable->get_declarationModifier().get_storageModifier().isStatic()) { baseClassesWithNonStaticData ++; @@ -2395,7 +2393,7 @@ if (!sgClassType) { \ } // All base classes have to be standard layout - foreach(SgBaseClass* baseClass, classDef->get_inheritances()) { + for(SgBaseClass* baseClass: classDef->get_inheritances()) { if(!IsStandardLayout(baseClass->get_base_class()->get_type())) return false; } @@ -2410,7 +2408,7 @@ if (!sgClassType) { \ #if DEBUG_QUADRATIC_BEHAVIOR printf ("In IsStandardLayout(): exclusiveAncestors.size() = %zu \n",exclusiveAncestors.size()); #endif - foreach(SgClassDefinition* c, exclusiveAncestors) { + for(SgClassDefinition* c: exclusiveAncestors) { if(c->get_declaration()->get_type()->stripType(SgType::STRIP_TYPEDEF_TYPE) == firstNonStaticDataMember->stripType(SgType::STRIP_TYPEDEF_TYPE)) return false; } @@ -2465,7 +2463,7 @@ if (!sgClassType) { \ return false; - foreach(SgDeclarationStatement* memberDeclaration, classDef->get_members()) { + for(SgDeclarationStatement* memberDeclaration: classDef->get_members()) { // No virtual functions if (SgMemberFunctionDeclaration* memberFunction = isSgMemberFunctionDeclaration(memberDeclaration)) { if (memberFunction->get_functionModifier().isVirtual()) @@ -2478,7 +2476,7 @@ if (!sgClassType) { \ continue; // each variable must be Trivial and must not have initializers - foreach(SgInitializedName* name, memberVariable->get_variables ()) { + for(SgInitializedName* name: memberVariable->get_variables ()) { if(name->get_initializer()) return false; if(!IsTrivial(name->get_type())) @@ -2489,7 +2487,7 @@ if (!sgClassType) { \ } // Base classes must be trivial too - foreach(SgBaseClass* baseClass, classDef->get_inheritances()) { + for(SgBaseClass* baseClass: classDef->get_inheritances()) { if(!IsTrivial(baseClass->get_base_class()->get_type())) return false; } diff --git a/src/frontend/SageIII/sage_support/cmdline.cpp b/src/frontend/SageIII/sage_support/cmdline.cpp index a65366f484d..b806b856779 100644 --- a/src/frontend/SageIII/sage_support/cmdline.cpp +++ b/src/frontend/SageIII/sage_support/cmdline.cpp @@ -18,7 +18,6 @@ #include "Outliner.hh" -#include using namespace Rose; // temporary, until this file lives in namespace Rose @@ -1567,7 +1566,7 @@ NormalizeIncludePathOptions (std::vector& argv) std::vector r_argv; bool looking_for_include_path_arg = false; - BOOST_FOREACH(std::string arg, argv) + for(std::string arg: argv) { // Must be first since there could be, for example, "-I -I", // in which case, the else if branch checking for -I would @@ -1801,7 +1800,7 @@ StripRoseOptions (std::vector& argv) Cmdline::Fortran::option_prefix, // Current prefix, e.g. "-rose:fortran:" "-"); // New prefix, e.g. "-" - BOOST_FOREACH(std::string fortran_option, fortran_options) + for(std::string fortran_option: fortran_options) { // TOO1 (2/13/2014): There are no ROSE-specific Fortran options yet. // Skip ROSE-specific Fortran options @@ -1879,7 +1878,7 @@ StripRoseOptions (std::vector& argv) // TOO1 (2/13/2014): Skip ALL ROSE-specific OFP options; // at this stage, we only have "-rose:fortran:ofp:jvm_options", // and this is only inteded for the OFP frontend's JVM. - BOOST_FOREACH(std::string ofp_option, ofp_options) + for(std::string ofp_option: ofp_options) { if (SgProject::get_verbose() > 1) { diff --git a/src/frontend/SageIII/sage_support/keep_going.cpp b/src/frontend/SageIII/sage_support/keep_going.cpp index 9b7ff843008..cbd7eb6e28d 100644 --- a/src/frontend/SageIII/sage_support/keep_going.cpp +++ b/src/frontend/SageIII/sage_support/keep_going.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -316,7 +315,7 @@ void Rose::KeepGoing::commandLineProcessing std::vector filenames = GetSourceFilenamesFromCommandline( std::vector(argv, argv + argc)); - BOOST_FOREACH(std::string filename, filenames) + for(std::string filename: filenames) { std::cout << filename << std::endl; } @@ -477,7 +476,7 @@ void Rose::KeepGoing::setMidendErrorCode (SgProject* project, int errorCode) project->set_midendErrorCode(errorCode); SgFilePtrList files = project->get_files(); - BOOST_FOREACH(SgFile* file, files) + for(SgFile* file: files) { file->set_midendErrorCode(errorCode); } @@ -511,7 +510,7 @@ void Rose::KeepGoing::generate_reports(SgProject* project, AppendToFile (report_filename__fail, orig_command_str); - BOOST_FOREACH(SgFile* file, files_with_errors) + for(SgFile* file: files_with_errors) { std::string filename = file->getFileName(); filename = StripPrefix(path_prefix, filename); @@ -569,7 +568,7 @@ void Rose::KeepGoing::generate_reports(SgProject* project, ostamp << GetTimestamp() << " " << getpid() << std::endl; AppendToFile (report_filename__pass, ostamp.str()); - BOOST_FOREACH(SgFile* file, files_without_errors) + for(SgFile* file: files_without_errors) { std::string full_filename = file->getFileName(); std::string filename = StripPrefix(path_prefix, full_filename); @@ -607,7 +606,7 @@ void Rose::KeepGoing::generate_reports(SgProject* project, std::ostringstream ostamp; ostamp << GetTimestamp() << " " << getpid() << std::endl; - BOOST_FOREACH(SgFile* file, files_with_errors) + for(SgFile* file: files_with_errors) { std::string filename = file->getFileName(); @@ -647,7 +646,7 @@ void Rose::KeepGoing::generate_reports(SgProject* project, // exit(1); //} - BOOST_FOREACH(SgFile* file, files_with_errors) + for(SgFile* file: files_with_errors) { std::string filename = file->getFileName(); filename = StripPrefix(path_prefix, filename); @@ -694,7 +693,7 @@ void Rose::KeepGoing::generate_reports(SgProject* project, // exit(1); //} - BOOST_FOREACH(SgFile* file, files_without_errors) + for(SgFile* file: files_without_errors) { std::string filename = file->getFileName(); filename = StripPrefix(path_prefix, filename); diff --git a/src/frontend/SageIII/sage_support/sage_support.cpp b/src/frontend/SageIII/sage_support/sage_support.cpp index fb4642250a5..2a5ccbd6c4c 100644 --- a/src/frontend/SageIII/sage_support/sage_support.cpp +++ b/src/frontend/SageIII/sage_support/sage_support.cpp @@ -24,7 +24,6 @@ #include #include -#include // DQ (12/22/2019): I don't need this now, and it is an issue for some compilers (e.g. GNU 4.9.4). // DQ (12/21/2019): Require hash table support for determining the shared nodes in the ASTs. @@ -1801,7 +1800,7 @@ SgProject::parse() #if 0 // DQ (4/24/2021): Debugging the handling of header_file_unparsing_optimization for non-optimized case. - BOOST_FOREACH(SgFile* file, files) + for(SgFile* file: files) { printf ("file = %s \n",file->getFileName().c_str()); printf (" --- file->get_header_file_unparsing_optimization() = %s \n",file->get_header_file_unparsing_optimization() ? "true" : "false"); @@ -1812,7 +1811,7 @@ SgProject::parse() bool unparse_using_tokens = false; - BOOST_FOREACH(SgFile* file, files) + for(SgFile* file: files) { ASSERT_not_null(file); @@ -4456,7 +4455,7 @@ Rose::Frontend::RunSerial(SgProject* project) } #endif } - }//BOOST_FOREACH + } }//all_files->callFrontEnd ASSERT_not_null(project); diff --git a/src/frontend/SageIII/virtualCFG/customFilteredCFG.C b/src/frontend/SageIII/virtualCFG/customFilteredCFG.C index 7430cdd9303..63e38724346 100644 --- a/src/frontend/SageIII/virtualCFG/customFilteredCFG.C +++ b/src/frontend/SageIII/virtualCFG/customFilteredCFG.C @@ -1,6 +1,4 @@ #include "customFilteredCFG.h" -#include -#define foreach BOOST_FOREACH namespace StaticCFG { @@ -32,7 +30,7 @@ namespace StaticCFG (start_->cfgForBeginning(), all_nodes, explored); typedef std::pair, SgGraphNode*> pair_t; - foreach (const pair_t& p, all_nodes) + for (const pair_t& p: all_nodes) all_nodes_[VirtualCFG::CFGNode(p.first.getNode(), 0)] = p.second; } @@ -71,7 +69,7 @@ void CustomFilteredCFG<_filter>::buildTemplatedCFG(NodeT n, std::map outEdges = n.outEdges(); - foreach (const EdgeT& edge, outEdges) + for (const EdgeT& edge: outEdges) { NodeT tar = edge.target(); @@ -102,14 +100,14 @@ void CustomFilteredCFG<_filter>::buildTemplatedCFG(NodeT n, std::mapaddDirectedEdge(new_edge); } - foreach (const EdgeT& edge, outEdges) + for (const EdgeT& edge: outEdges) { ROSE_ASSERT(edge.source() == n); buildTemplatedCFG(edge.target(), all_nodes, explored); } std::vector inEdges = n.inEdges(); - foreach (const EdgeT& edge, inEdges) + for (const EdgeT& edge: inEdges) { ROSE_ASSERT(edge.target() == n); buildTemplatedCFG(edge.source(), all_nodes, explored); diff --git a/src/frontend/SageIII/virtualCFG/interproceduralCFG.C b/src/frontend/SageIII/virtualCFG/interproceduralCFG.C index 46442468a79..c2d72cc541f 100644 --- a/src/frontend/SageIII/virtualCFG/interproceduralCFG.C +++ b/src/frontend/SageIII/virtualCFG/interproceduralCFG.C @@ -1,12 +1,8 @@ #include "sage3basic.h" #include "CallGraph.h" #include "interproceduralCFG.h" -#include #include -#define foreach BOOST_FOREACH - - namespace StaticCFG { @@ -113,7 +109,7 @@ void InterproceduralCFG::buildCFG(CFGNode n, << std::endl; outEdges = n.outEdges(); } else { - foreach (SgFunctionDefinition* def, defs) { + for (SgFunctionDefinition* def: defs) { addEdge(n, def->cfgForBeginning(), outEdges); addEdge(def->cfgForEnd(), CFGNode(sgnode, idx+1), outEdges); } @@ -124,7 +120,7 @@ void InterproceduralCFG::buildCFG(CFGNode n, } std::set targets; - foreach (const CFGEdge& edge, outEdges) + for (const CFGEdge& edge: outEdges) { CFGNode tar = edge.target(); targets.insert(tar); @@ -146,7 +142,7 @@ void InterproceduralCFG::buildCFG(CFGNode n, graph_->addDirectedEdge(new_edge); } - foreach (const CFGNode& target, targets) + for (const CFGNode& target: targets) { buildCFG(target, all_nodes, explored, classHierarchy); } diff --git a/src/frontend/SageIII/virtualCFG/memberFunctions.C b/src/frontend/SageIII/virtualCFG/memberFunctions.C index 949435893d1..2b794162307 100644 --- a/src/frontend/SageIII/virtualCFG/memberFunctions.C +++ b/src/frontend/SageIII/virtualCFG/memberFunctions.C @@ -7,8 +7,6 @@ #endif #include -#include -#define foreach BOOST_FOREACH using namespace std; #ifndef ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT @@ -1170,7 +1168,7 @@ SgFunctionDefinition::cfgInEdges(unsigned int idx) { ClassHierarchyWrapper classHierarchy( SageInterface::getProject() ); Rose_STL_Container exps; CallTargetSet::getExpressionsForDefinition(this, &classHierarchy, exps); - foreach (SgExpression* exp, exps) + for (SgExpression* exp: exps) makeEdge(exp->cfgForEnd(), CFGNode(this, idx), result); } break; @@ -4139,7 +4137,7 @@ SgPseudoDestructorRefExp::cfgInEdges(unsigned int idx) ClassHierarchyWrapper classHierarchy( SageInterface::getProject() ); Rose_STL_Container defs; CallTargetSet::getDefinitionsForExpression(this, &classHierarchy, defs); - foreach (SgFunctionDefinition* def, defs) + for (SgFunctionDefinition* def: defs) makeEdge(CFGNode(this, idx), def->cfgForBeginning(), result); } else { @@ -4165,7 +4163,7 @@ SgPseudoDestructorRefExp::cfgInEdges(unsigned int idx) ClassHierarchyWrapper classHierarchy( SageInterface::getProject() ); Rose_STL_Container defs; CallTargetSet::getDefinitionsForExpression(this, &classHierarchy, defs); - foreach (SgFunctionDefinition* def, defs) + for (SgFunctionDefinition* def: defs) makeEdge(def->cfgForEnd(), CFGNode(this, idx), result); } else diff --git a/src/frontend/SageIII/virtualCFG/staticCFG.C b/src/frontend/SageIII/virtualCFG/staticCFG.C index 7256b2d258b..720e781cc32 100644 --- a/src/frontend/SageIII/virtualCFG/staticCFG.C +++ b/src/frontend/SageIII/virtualCFG/staticCFG.C @@ -1,7 +1,5 @@ #include "staticCFG.h" -#include -#define foreach BOOST_FOREACH namespace StaticCFG @@ -27,9 +25,9 @@ void CFG::clearNodesAndEdges() { if (graph_ != NULL) { - foreach (SgGraphNode* node, graph_->computeNodeSet()) + for (SgGraphNode* node: graph_->computeNodeSet()) { - foreach (SgDirectedGraphEdge* edge, graph_->computeEdgeSetOut(node)) + for (SgDirectedGraphEdge* edge: graph_->computeEdgeSetOut(node)) { // This would be so much simpler if the attribute used container-owns-attribute paradigm. In any case, we // cannot delete the attribute without first removing it from the container because the container needs to be @@ -121,7 +119,7 @@ void CFG::buildFilteredCFG() (VirtualCFG::makeInterestingCfg(start_), all_nodes, explored); typedef std::pair pair_t; - foreach (const pair_t& p, all_nodes) + for (const pair_t& p: all_nodes) all_nodes_[VirtualCFG::CFGNode(p.first.getNode(), 0)] = p.second; } @@ -149,7 +147,7 @@ void CFG::buildCFG(CFGNode n) } std::vector outEdges = n.outEdges(); - foreach (const VirtualCFG::CFGEdge& edge, outEdges) + for (const VirtualCFG::CFGEdge& edge: outEdges) { CFGNode tar = edge.target(); @@ -168,7 +166,7 @@ void CFG::buildCFG(CFGNode n) graph_->addDirectedEdge(new SgDirectedGraphEdge(from, to)); } - foreach (const VirtualCFG::CFGEdge& edge, outEdges) + for (const VirtualCFG::CFGEdge& edge: outEdges) { ROSE_ASSERT(edge.source() == n); buildCFG(edge.target()); @@ -176,7 +174,7 @@ void CFG::buildCFG(CFGNode n) #if 1 std::vector inEdges = n.inEdges(); - foreach (const VirtualCFG::CFGEdge& edge, inEdges) + for (const VirtualCFG::CFGEdge& edge: inEdges) { ROSE_ASSERT(edge.target() == n); buildCFG(edge.source()); @@ -241,7 +239,7 @@ void CFG::buildCFG(NodeT n, std::map& all_nodes, std::set& all_nodes, std::set(edge.target(), all_nodes, explored); @@ -304,7 +302,7 @@ void CFG::buildCFG(NodeT n, std::map& all_nodes, std::set inEdges = n.inEdges(); - foreach (const EdgeT& edge, inEdges) + for (const EdgeT& edge: inEdges) { ROSE_ASSERT(edge.target() == n); buildCFG(edge.source(), all_nodes, explored); @@ -368,11 +366,11 @@ void CFG::processNodes(std::ostream & o, SgGraphNode* n, std::set& printNodePlusEdges(o, n); std::set out_edges = graph_->computeEdgeSetOut(n); - foreach (SgDirectedGraphEdge* e, out_edges) + for (SgDirectedGraphEdge* e: out_edges) processNodes(o, e->get_to(), explored); std::set in_edges = graph_->computeEdgeSetIn(n); - foreach (SgDirectedGraphEdge* e, in_edges) + for (SgDirectedGraphEdge* e: in_edges) processNodes(o, e->get_from(), explored); } @@ -381,12 +379,12 @@ void CFG::printNodePlusEdges(std::ostream & o, SgGraphNode* node) printNode(o, node); std::set out_edges = graph_->computeEdgeSetOut(node); - foreach (SgDirectedGraphEdge* e, out_edges) + for (SgDirectedGraphEdge* e: out_edges) printEdge(o, e, false); #ifdef DEBUG std::set in_edges = graph_->computeEdgeSetIn(node); - foreach (SgDirectedGraphEdge* e, in_edges) + for (SgDirectedGraphEdge* e: in_edges) printEdge(o, e, true); #endif } diff --git a/src/midend/astDump/AstDOTGeneration.C b/src/midend/astDump/AstDOTGeneration.C index 4515f73c4cf..c3fc5d122c4 100644 --- a/src/midend/astDump/AstDOTGeneration.C +++ b/src/midend/astDump/AstDOTGeneration.C @@ -9,7 +9,6 @@ #include "sage3basic.h" #include "AstDOTGeneration.h" #include "transformationTracking.h" -#include // DQ (10/21/2010): This should only be included by source files that require it. // This fixed a reported bug which caused conflicts with autoconf macros (e.g. PACKAGE_BUGREPORT). @@ -251,7 +250,7 @@ void AstDOTGeneration::addAdditionalNodesAndEdges(SgNode* node) if (astAttributeContainer != NULL) { // Loop over all the attributes at this IR node - BOOST_FOREACH (const std::string &name, astAttributeContainer->getAttributeIdentifiers()) + for (const std::string &name: astAttributeContainer->getAttributeIdentifiers()) { AstAttribute* attribute = astAttributeContainer->operator[](name); ROSE_ASSERT(attribute != NULL); @@ -759,7 +758,7 @@ AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribu if (astAttributeContainer != NULL) { // Loop over all the attributes at this IR node - BOOST_FOREACH (const std::string &name, astAttributeContainer->getAttributeIdentifiers()) + for (const std::string &name: astAttributeContainer->getAttributeIdentifiers()) { AstAttribute* attribute = astAttributeContainer->operator[](name); ROSE_ASSERT(attribute != NULL); @@ -1159,7 +1158,7 @@ AstDOTGeneration::additionalNodeInfo(SgNode* node) if (astAttributeContainer != NULL) { ss << "Attribute list (size=" << astAttributeContainer->size() << "):" << "\\n"; - BOOST_FOREACH (const std::string &name, astAttributeContainer->getAttributeIdentifiers()) + for (const std::string &name: astAttributeContainer->getAttributeIdentifiers()) { // pair AstAttribute* attribute = astAttributeContainer->operator[](name); @@ -1219,7 +1218,7 @@ AstDOTGeneration::additionalNodeOptions(SgNode* node) #if 0 printf ("In AstDOTGeneration::additionalNodeOptions(): astAttributeContainer = %p for node = %p = %s \n",astAttributeContainer,node,node->class_name().c_str()); #endif - BOOST_FOREACH (const std::string &name, astAttributeContainer->getAttributeIdentifiers()) + for (const std::string &name: astAttributeContainer->getAttributeIdentifiers()) { // std::string name = i->first; AstAttribute* attribute = astAttributeContainer->operator[](name); @@ -1257,7 +1256,7 @@ AstDOTGeneration::commentOutNodeInGraph(SgNode* node) AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism(); if (astAttributeContainer != NULL) { - BOOST_FOREACH (const std::string &name, astAttributeContainer->getAttributeIdentifiers()) + for (const std::string &name: astAttributeContainer->getAttributeIdentifiers()) { // std::string name = i->first; AstAttribute* attribute = astAttributeContainer->operator[](name); diff --git a/src/midend/astProcessing/graphProcessing.h b/src/midend/astProcessing/graphProcessing.h index 07cdbd35235..0d8baadcf09 100644 --- a/src/midend/astProcessing/graphProcessing.h +++ b/src/midend/astProcessing/graphProcessing.h @@ -55,7 +55,6 @@ AS WRITTEN, THESE FUNCTIONS WILL ONLY WORK WITH GRAPHS THAT ARE IMPLEMENTED IN T #include #include -#include #include #include #include diff --git a/src/midend/astProcessing/graphTemplate.h b/src/midend/astProcessing/graphTemplate.h index e3075618ffb..a0935ffdb1b 100644 --- a/src/midend/astProcessing/graphTemplate.h +++ b/src/midend/astProcessing/graphTemplate.h @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -17,7 +16,6 @@ namespace Backstroke { -#define foreach BOOST_FOREACH //! This function helps to write the DOT file for vertices. @@ -310,7 +308,7 @@ void CFG::build(SgFunctionDefinition* funcDef) template void CFG::setEntryAndExit() { - foreach (Vertex v, boost::vertices(*this)) + for (Vertex v: boost::vertices(*this)) { CFGNodePtr node = (*this)[v]; if (isSgFunctionDefinition(node->getNode())) @@ -371,7 +369,7 @@ void CFG::buildCFG( std::vector outEdges = node.outEdges(); - foreach(const CFGEdgeType& cfgEdge, outEdges) + for(const CFGEdgeType& cfgEdge: outEdges) { // For each out edge, add the target node. CFGNodeType tar = cfgEdge.target(); @@ -446,7 +444,7 @@ std::vector::CFGNodePtr> CFG::getAllNodes() const { std::vector allNodes; - foreach (Vertex v, boost::vertices(*this)) + for (Vertex v: boost::vertices(*this)) allNodes.push_back((*this)[v]); return allNodes; } @@ -457,7 +455,7 @@ std::vector::CFGNodeType> CFG::getAllNodesNoPtrs() const { std::vector allNodes; - foreach (Vertex v, boost::vertices(*this)) + for (Vertex v: boost::vertices(*this)) allNodes.push_back(&((*this)[v])); return allNodes; } @@ -468,7 +466,7 @@ std::vector::CFGEdgePtr> CFG::getAllEdges() const { std::vector allEdges; - foreach (const Edge& e, boost::edges(*this)) + for (const Edge& e: boost::edges(*this)) allEdges.push_back((*this)[e]); return allEdges; } @@ -494,7 +492,7 @@ std::vector::Edge> CFG::getAllBackEdg // If the dominator tree is not built yet, build it now. getDominatorTree(); - foreach (const Edge& e, boost::edges(*this)) + for (const Edge& e: boost::edges(*this)) { Vertex src = boost::source(e, *this); Vertex tar = boost::target(e, *this); @@ -520,7 +518,7 @@ std::vector::Vertex> CFG::getAllLoopH { std::vector backEdges = getAllBackEdges(); std::vector headers; - foreach (Edge e, backEdges) + for (Edge e: backEdges) headers.push_back(boost::target(e, *this)); return headers; } diff --git a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.C b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.C index a703a86a141..5c9ae52a19f 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.C +++ b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.C @@ -11,8 +11,6 @@ #ifndef _MSC_VER #include #endif -#include -#define foreach BOOST_FOREACH using namespace std; using namespace Rose; @@ -1075,7 +1073,7 @@ CallTargetSet::solveConstructorInitializer(SgConstructorInitializer* sgCtorInit) continue; } - foreach(SgBaseClass* baseClass, currClass->get_inheritances()) + for(SgBaseClass* baseClass: currClass->get_inheritances()) { ROSE_ASSERT(baseClass->get_base_class() != NULL); SgMemberFunctionDeclaration* constructorCalled = SageInterface::getDefaultConstructor(baseClass->get_base_class()); @@ -1376,7 +1374,7 @@ void CallTargetSet::getDeclarationsForExpression(SgExpression* exp, Rose_STL_Container props; CallTargetSet::getPropertiesForExpression(exp, classHierarchy, props, includePureVirtualFunc); - foreach(SgFunctionDeclaration* candidateDecl, props) + for(SgFunctionDeclaration* candidateDecl: props) { ROSE_ASSERT(candidateDecl); assert(!isSgTemplateFunctionDeclaration(candidateDecl)); @@ -1392,7 +1390,7 @@ CallTargetSet::getDefinitionsForExpression(SgExpression* sgexp, Rose_STL_Container props; CallTargetSet::getPropertiesForExpression(sgexp, classHierarchy, props); - foreach(SgFunctionDeclaration* candidateDecl, props) + for(SgFunctionDeclaration* candidateDecl: props) { ROSE_ASSERT(candidateDecl); assert(!isSgTemplateFunctionDeclaration(candidateDecl)); @@ -1414,11 +1412,11 @@ CallTargetSet::getExpressionsForDefinition(SgFunctionDefinition* targetDef, Rose_STL_Container& exps) { VariantVector vv(V_SgFunctionCallExp); Rose_STL_Container callCandidates = NodeQuery::queryMemoryPool(vv); - foreach (SgNode* callCandidate, callCandidates) { + for (SgNode* callCandidate: callCandidates) { SgFunctionCallExp* callexp = isSgFunctionCallExp(callCandidate); Rose_STL_Container candidateDefs; CallTargetSet::getDefinitionsForExpression(callexp, classHierarchy, candidateDefs); - foreach (SgFunctionDefinition* candidateDef, candidateDefs) { + for (SgFunctionDefinition* candidateDef: candidateDefs) { if (candidateDef == targetDef) { exps.push_back(callexp); break; @@ -1427,11 +1425,11 @@ CallTargetSet::getExpressionsForDefinition(SgFunctionDefinition* targetDef, } VariantVector vv2(V_SgConstructorInitializer); Rose_STL_Container ctorCandidates = NodeQuery::queryMemoryPool(vv2); - foreach (SgNode* ctorCandidate, ctorCandidates) { + for (SgNode* ctorCandidate: ctorCandidates) { SgConstructorInitializer* ctorInit = isSgConstructorInitializer(ctorCandidate); Rose_STL_Container candidateDefs; CallTargetSet::getDefinitionsForExpression(ctorInit, classHierarchy, candidateDefs); - foreach (SgFunctionDefinition* candidateDef, candidateDefs) { + for (SgFunctionDefinition* candidateDef: candidateDefs) { if (candidateDef == targetDef) { exps.push_back(ctorInit); break; @@ -1470,13 +1468,13 @@ FunctionData::FunctionData ( SgFunctionDeclaration* inputFunctionDeclaration, hasDefinition = true; Rose_STL_Container functionCallExpList = NodeQuery::querySubTree(defDecl, V_SgFunctionCallExp); - foreach(SgNode* functionCallExp, functionCallExpList) + for(SgNode* functionCallExp: functionCallExpList) { CallTargetSet::getPropertiesForExpression(isSgExpression(functionCallExp), classHierarchy, functionList); } Rose_STL_Container ctorInitList = NodeQuery::querySubTree(defDecl, V_SgConstructorInitializer); - foreach(SgNode* ctorInit, ctorInitList) + for(SgNode* ctorInit: ctorInitList) { CallTargetSet::getPropertiesForExpression(isSgExpression(ctorInit), classHierarchy, functionList); } diff --git a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h index 69f472ee63a..28684ea4e01 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h +++ b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h @@ -13,7 +13,6 @@ #include #include #include -#include #include class FunctionData; @@ -211,7 +210,7 @@ CallGraphBuilder::buildCallGraph(Predicate pred) VariantVector vv(V_SgFunctionDeclaration); GetOneFuncDeclarationPerFunction defFunc; std::vector fdecl_nodes = NodeQuery::queryMemoryPool(defFunc, &vv); - BOOST_FOREACH(SgNode *node, fdecl_nodes) { + for(SgNode *node: fdecl_nodes) { SgFunctionDeclaration *fdecl = isSgFunctionDeclaration(node); SgFunctionDeclaration *unique = isSgFunctionDeclaration(fdecl->get_firstNondefiningDeclaration()); #if 0 //debug @@ -243,13 +242,13 @@ CallGraphBuilder::buildCallGraph(Predicate pred) } // Add edges to the graph - BOOST_FOREACH(FunctionData ¤tFunction, callGraphData) { + for(FunctionData ¤tFunction: callGraphData) { SgFunctionDeclaration* curFuncDecl = currentFunction.functionDeclaration; std::string curFuncName = curFuncDecl->get_qualified_name().getString(); SgGraphNode * srcNode = hasGraphNodeFor(currentFunction.functionDeclaration); ROSE_ASSERT(srcNode != NULL); std::vector & callees = currentFunction.functionList; - BOOST_FOREACH(SgFunctionDeclaration * callee, callees) { + for(SgFunctionDeclaration * callee: callees) { if (isSelected(pred)(callee)) { SgGraphNode * dstNode = getGraphNodeFor(callee); //getGraphNode here, see function comment ROSE_ASSERT(dstNode != NULL); diff --git a/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.C b/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.C index 27f410e64af..22d1333d9e0 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.C +++ b/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.C @@ -1,13 +1,8 @@ // tps : Switching from rose.h to sage3 changed size from 17,7 MB to 7,3MB #include "sage3basic.h" - #include "CallGraph.h" -#include -#include -#define foreach BOOST_FOREACH using namespace std; -using namespace boost; ClassHierarchyWrapper::ClassHierarchyWrapper(SgNode *node) { @@ -150,7 +145,7 @@ void findParents(const string& classMangledName, ClassHierarchyWrapper::ClassDefSet& currentTransitiveParents = transitiveParents[classMangledName]; //Our transitive parents are simply the union of our parents' transitive parents - foreach(SgClassDefinition* parent, currentParents->second) + for(SgClassDefinition* parent: currentParents->second) { std::string parentName = parent->get_declaration()->get_mangled_name(); diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/InterProcDataFlowAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/InterProcDataFlowAnalysis.C index d3b5f9cf273..e068acd5890 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/InterProcDataFlowAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/InterProcDataFlowAnalysis.C @@ -1,8 +1,5 @@ #include "sage3basic.h" #include "InterProcDataFlowAnalysis.h" -#include -#define foreach BOOST_FOREACH - void InterProcDataFlowAnalysis::run () { @@ -15,7 +12,7 @@ void InterProcDataFlowAnalysis::run () { getFunctionDeclarations(processingOrder); - foreach (SgFunctionDeclaration* funcDecl, processingOrder) { + for (SgFunctionDeclaration* funcDecl: processingOrder) { change |= runAndCheckIntraProcAnalysis(funcDecl); diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C index a85513ca759..db645b21a82 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C @@ -11,7 +11,7 @@ void CompactRepresentation::computeAliases (SgGraphNode *node, int derefLevel, v } else { std::set edges = graph->computeEdgeSetOut(node); - foreach(SgDirectedGraphEdge *ed, edges) { + for(SgDirectedGraphEdge *ed: edges) { computeAliases(ed->get_to(), derefLevel-1, sol); } @@ -38,10 +38,10 @@ void CompactRepresentation::merge(SgIncidenceDirectedGraph *thatGraph) { set nodes = thatGraph->computeNodeSet(); SgGraphNode *g_from; - BOOST_FOREACH(SgGraphNode *node, nodes) { + for(SgGraphNode *node: nodes) { std::set edges = thatGraph->computeEdgeSetOut(node); g_from = getGraphNode(node->get_SgNode()); - BOOST_FOREACH(SgDirectedGraphEdge *ed, edges) { + for(SgDirectedGraphEdge *ed: edges) { addEdge(g_from, getGraphNode(ed->get_to()->get_SgNode())); } } @@ -196,7 +196,7 @@ void CompactRepresentation::toDot(const std::string& file_name) { ofile << "digraph defaultName {\n"; std::set explored; - foreach(SgGraphNode *node, nodes) + for(SgGraphNode *node: nodes) processNodes(ofile, node, explored); ofile << "}\n"; @@ -210,11 +210,11 @@ void CompactRepresentation::processNodes(std::ostream & o, SgGraphNode* n, std:: printNodePlusEdges(o, n); std::set out_edges = graph->computeEdgeSetOut(n); - foreach (SgDirectedGraphEdge* e, out_edges) + for (SgDirectedGraphEdge* e: out_edges) processNodes(o, e->get_to(), explored); std::set in_edges = graph->computeEdgeSetIn(n); - foreach (SgDirectedGraphEdge* e, in_edges) + for (SgDirectedGraphEdge* e: in_edges) processNodes(o, e->get_from(), explored); } @@ -225,7 +225,7 @@ void CompactRepresentation::printNodePlusEdges(std::ostream & o, SgGraphNode* no printNode(o, node); std::set out_edges = graph->computeEdgeSetOut(node); - foreach (SgDirectedGraphEdge* e, out_edges) + for (SgDirectedGraphEdge* e: out_edges) printEdge(o, e, false); } @@ -1195,7 +1195,7 @@ void CollectAliasRelations::run() { boost::unordered_map colors; - foreach(SgGraphNode *node, allNodes) { + for(SgGraphNode *node: allNodes) { colors[node] = WHITE; } diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h index 5e7b75905a0..5c340b17700 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h @@ -4,16 +4,10 @@ #include "customFilteredCFG.h" #include "ClassHierarchyGraph.h" #include "CallGraph.h" -#include #include #include #include -// warning: poor practice and possible name conflicts according to Boost documentation -#define foreach BOOST_FOREACH -#define reverse_foreach BOOST_REVERSE_FOREACH - - using namespace boost; using namespace std; diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C index 8ed5c9ad259..80727f8bbb7 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C @@ -2,11 +2,6 @@ #include #include "PtrAliasAnalysis.h" -// warning: poor practice and possible name conflicts according to Boost documentation -#define foreach BOOST_FOREACH -#define reverse_foreach BOOST_REVERSE_FOREACH - - struct FunctionFilter { bool operator()(SgFunctionDeclaration* funcDecl) @@ -69,7 +64,7 @@ struct OnlyNonCompilerGenerated : public std::unary_functiongetGraph(), "init_call_graph.dot"); #if 0 typedef boost::unordered_map res_map; - foreach (res_map::value_type it, cg2.getGraphNodesMapping()) { + for (res_map::value_type it: cg2.getGraphNodesMapping()) { std::cout << it.first <<" - "<< isSgFunctionDeclaration(it.first->get_definingDeclaration()) << " - " << it.first->get_name().getString() << std::endl; } #endif @@ -77,7 +72,7 @@ struct OnlyNonCompilerGenerated : public std::unary_function map; - foreach (map::value_type it, intraAliases) { + for (map::value_type it: intraAliases) { delete ((IntraProcAliasAnalysis *)it.second); } } @@ -145,7 +140,7 @@ void PtrAliasAnalysis:: SortCallGraphRecursive(SgFunctionDeclaration* targetFunc callGraph->getSuccessors(graphNode, callees); //Recursively process all the callees before adding this function to the list - foreach(SgGraphNode* calleeNode, callees) + for(SgGraphNode* calleeNode: callees) { if(colors.at(calleeNode) == WHITE) { SgFunctionDeclaration* calleeDecl = isSgFunctionDeclaration(calleeNode->get_SgNode()); @@ -181,7 +176,7 @@ void PtrAliasAnalysis::SortCallGraphNodes(SgFunctionDeclaration* targetFunction, boost::unordered_map colors; typedef boost::unordered_map my_map; - foreach(my_map::value_type item, graphNodeToFunction) { + for(my_map::value_type item: graphNodeToFunction) { colors[item.second] = WHITE; } @@ -209,7 +204,7 @@ void PtrAliasAnalysis::run() { std::setallNodes = fullCallGraph.getGraph()->computeNodeSet(); int counter = 0; - foreach(SgGraphNode *node, allNodes) { + for(SgGraphNode *node: allNodes) { #if 0 printf ("In PtrAliasAnalysis::run(): in loop body: counter = %d \n",counter); #endif diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C index fabe123fb3b..2c9b845a4c5 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C @@ -94,7 +94,7 @@ void VirtualFunctionAnalysis::pruneCallGraph(CallGraphBuilder& builder) { boost::unordered_mapnode_mapping = builder.getGraphNodesMapping(); typedef boost::unordered_map map; - foreach (map::value_type it, node_mapping) { + for (map::value_type it: node_mapping) { SgFunctionDeclaration *defDecl = ( it.first->get_definition() != NULL ? @@ -105,20 +105,20 @@ void VirtualFunctionAnalysis::pruneCallGraph(CallGraphBuilder& builder) { Rose_STL_Container functionCallExpList = NodeQuery::querySubTree(defDecl, V_SgFunctionCallExp); std::vector functions; - foreach(SgNode* functionCallExp, functionCallExpList) { + for(SgNode* functionCallExp: functionCallExpList) { functions.insert(functions.end(), resolver.at(isSgExpression(functionCallExp)).begin(), resolver.at(isSgExpression(functionCallExp)).end()); } Rose_STL_Container ctorInitList = NodeQuery::querySubTree(defDecl, V_SgConstructorInitializer); - foreach(SgNode* ctorInit, ctorInitList) { + for(SgNode* ctorInit: ctorInitList) { functions.insert(functions.end(), resolver.at(isSgExpression(ctorInit)).begin(), resolver.at(isSgExpression(ctorInit)).end()); } std::setedges = graph->computeEdgeSetOut(it.second); - foreach(SgDirectedGraphEdge *edge, edges) { + for(SgDirectedGraphEdge *edge: edges) { SgGraphNode *toNode = edge->get_to(); SgFunctionDeclaration *toDecl = isSgFunctionDeclaration(toNode->get_SgNode()); ROSE_ASSERT(toDecl != NULL); diff --git a/src/midend/programAnalysis/variableRenaming/VariableRenaming.C b/src/midend/programAnalysis/variableRenaming/VariableRenaming.C index 7b3377581ce..6db4fa56eb7 100644 --- a/src/midend/programAnalysis/variableRenaming/VariableRenaming.C +++ b/src/midend/programAnalysis/variableRenaming/VariableRenaming.C @@ -11,13 +11,8 @@ #include #include #include -#include #include -// warning: poor practice and possible name conflicts according to Boost documentation -#define foreach BOOST_FOREACH -#define reverse_foreach BOOST_REVERSE_FOREACH - using namespace std; using namespace Rose; @@ -34,7 +29,7 @@ std::string VariableRenaming::keyToString(const VarName& vec) { std::string name = ""; - foreach(const VarName::value_type& iter, vec) + for(const VarName::value_type& iter: vec) { if (iter != vec.front()) { @@ -50,11 +45,11 @@ void VariableRenaming::printDefs(SgNode* node) { std::cout << "Def Table for [" << node->class_name() << ":" << node << "]:" << std::endl; - foreach(TableEntry::value_type& entry, defTable[node]) + for(TableEntry::value_type& entry: defTable[node]) { std::cout << " Defs for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(NodeVec::value_type& iter, entry.second) + for(NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -65,11 +60,11 @@ void VariableRenaming::printDefs(const std::map< std::vector { std::cout << "Def Table:" << std::endl; - foreach(const TableEntry::value_type& entry, table) + for(const TableEntry::value_type& entry: table) { std::cout << " Defs for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(const NodeVec::value_type& iter, entry.second) + for(const NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -80,11 +75,11 @@ void VariableRenaming::printOriginalDefs(SgNode* node) { std::cout << "Original Def Table for [" << node->class_name() << ":" << node << "]:" << std::endl; - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { std::cout << " Defs for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(NodeVec::value_type& iter, entry.second) + for(NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -95,15 +90,15 @@ void VariableRenaming::printOriginalDefTable() { std::cout << "Original Def Table:" << endl; - foreach(DefUseTable::value_type& node, originalDefTable) + for(DefUseTable::value_type& node: originalDefTable) { std::cout << " Original Def Table for [" << node.first->class_name() << ":" << node.first << "]:" << std::endl; - foreach(TableEntry::value_type& entry, originalDefTable[node.first]) + for(TableEntry::value_type& entry: originalDefTable[node.first]) { std::cout << " Defs for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(NodeVec::value_type& iter, entry.second) + for(NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -115,11 +110,11 @@ void VariableRenaming::printUses(SgNode* node) { std::cout << "Use Table for [" << node->class_name() << ":" << node << "]:" << std::endl; - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { std::cout << " Uses for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(NodeVec::value_type& iter, entry.second) + for(NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -130,11 +125,11 @@ void VariableRenaming::printUses(const std::map< std::vector { std::cout << "Use Table:" << std::endl; - foreach(const TableEntry::value_type& entry, table) + for(const TableEntry::value_type& entry: table) { std::cout << " Uses for [" << keyToString(entry.first) << "]:" << std::endl; - foreach(const NodeVec::value_type& iter, entry.second) + for(const NodeVec::value_type& iter: entry.second) { std::cout << " -[" << iter->class_name() << ":" << iter << "]" << std::endl; } @@ -159,7 +154,7 @@ void VariableRenaming::printRenameTable(const NodeNumRenameTable& table) //Iterate the table - foreach(const NodeNumRenameTable::value_type& entry, table) + for(const NodeNumRenameTable::value_type& entry: table) { cout << " Names for [" << keyToString(entry.first) << "]:" << endl; @@ -174,7 +169,7 @@ void VariableRenaming::printRenameTable(const NumNodeRenameTable& table) //Iterate the table - foreach(const NumNodeRenameTable::value_type& entry, table) + for(const NumNodeRenameTable::value_type& entry: table) { std::cout << " Names for [" << keyToString(entry.first) << "]:" << std::endl; @@ -190,7 +185,7 @@ void VariableRenaming::printRenameEntry(const NodeNumRenameEntry& entry) //Iterate the entry - foreach(const NodeNumRenameEntry::value_type& iter, entry) + for(const NodeNumRenameEntry::value_type& iter: entry) { if (start == 0 && end == 0) { @@ -215,7 +210,7 @@ void VariableRenaming::printRenameEntry(const NodeNumRenameEntry& entry) SgNode* current = NULL; //Find the entry for start if it exists - foreach(const NodeNumRenameEntry::value_type& iter, entry) + for(const NodeNumRenameEntry::value_type& iter: entry) { if (iter.second == start) { @@ -237,7 +232,7 @@ void VariableRenaming::printRenameEntry(const NumNodeRenameEntry& entry) { //Iterate the entry - foreach(const NumNodeRenameEntry::value_type& iter, entry) + for(const NumNodeRenameEntry::value_type& iter: entry) { cout << " " << iter.first << ": " << iter.second << endl; } @@ -402,7 +397,7 @@ void VariableRenaming::insertDefsForExternalVariables(SgFunctionDeclaration* fun //Iterate over each used variable and check it it is declared outside of the function scope - foreach(const VarName& usedVar, usedNames) + for(const VarName& usedVar: usedNames) { VarName rootName; rootName.assign(1, usedVar[0]); @@ -476,7 +471,7 @@ set VariableRenaming::getVarsUsedInSubtree(SgNode* ro if (defEntry != ssa->useTable.end()) { - foreach(TableEntry::value_type& varDefsPair, ssa->useTable[node]) + for(TableEntry::value_type& varDefsPair: ssa->useTable[node]) { usedNames.insert(varDefsPair.first); } @@ -486,7 +481,7 @@ set VariableRenaming::getVarsUsedInSubtree(SgNode* ro if (defEntry != ssa->originalDefTable.end()) { - foreach(TableEntry::value_type& varDefsPair, ssa->originalDefTable[node]) + for(TableEntry::value_type& varDefsPair: ssa->originalDefTable[node]) { usedNames.insert(varDefsPair.first); } @@ -509,7 +504,7 @@ void VariableRenaming::toDOT(const std::string fileName) //print all the functions in each file - foreach(fileVec::value_type& file, files) + for(fileVec::value_type& file: files) { ofstream outFile((StringUtility::stripPathFromFileName(file->getFileName()) + "_" + fileName).c_str()); @@ -536,7 +531,7 @@ void VariableRenaming::toFilteredDOT(const std::string fileName) //print all the functions in each file - foreach(fileVec::value_type& file, files) + for(fileVec::value_type& file: files) { ofstream outFile((StringUtility::stripPathFromFileName(file->getFileName()) + "_filtered_" + fileName).c_str()); @@ -574,7 +569,7 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) //Iterate all the functions and print them in the same file. - foreach(funcDefVec::value_type& func, funcs) + for(funcDefVec::value_type& func: funcs) { vector visited; stack traverse; @@ -616,11 +611,11 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) //Print the defs to a string std::stringstream defUse; - foreach(TableEntry::value_type& entry, defTable[current.getNode()]) + for(TableEntry::value_type& entry: defTable[current.getNode()]) { defUse << "Def [" << keyToString(entry.first) << "]: "; - foreach(NodeVec::value_type& val, entry.second) + for(NodeVec::value_type& val: entry.second) { defUse << getRenameNumberForNode(entry.first, val) << ": " << val << ", "; } @@ -628,11 +623,11 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) } //Print the uses to a string - foreach(TableEntry::value_type& entry, useTable[current.getNode()]) + for(TableEntry::value_type& entry: useTable[current.getNode()]) { defUse << "Use [" << keyToString(entry.first) << "]: "; - foreach(NodeVec::value_type& val, entry.second) + for(NodeVec::value_type& val: entry.second) { defUse << getRenameNumberForNode(entry.first, val) << ": " << val << ", "; } @@ -654,7 +649,7 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) //Now print the out edges std::vector outEdges = current.outEdges(); - foreach(std::vector::value_type& edge, outEdges) + for(std::vector::value_type& edge: outEdges) { outFile << edge.source().id() << " -> " << edge.target().id() << " [label=\"" << escapeString(edge.toString()) @@ -666,7 +661,7 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) std::vector outEdges = current.outEdges(); - foreach(std::vector::value_type& edge, outEdges) + for(std::vector::value_type& edge: outEdges) { //If we haven't seen the target of this node yet, process the node if (std::count(visited.begin(), visited.end(), edge.target()) == 0) @@ -681,7 +676,7 @@ void VariableRenaming::printToDOT(SgSourceFile* source, std::ofstream &outFile) { std::vector inEdges = current.inEdges(); - foreach(std::vector::value_type& edge, inEdges) + for(std::vector::value_type& edge: inEdges) { //If we haven't seen the target of this node yet, process the node if (std::count(visited.begin(), visited.end(), edge.target()) == 0) @@ -724,7 +719,7 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o //Iterate all the functions and print them in the same file. - foreach(funcDefVec::value_type& func, funcs) + for(funcDefVec::value_type& func: funcs) { vector visited; stack traverse; @@ -766,11 +761,11 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o //Print the defs to a string std::stringstream defUse; - foreach(TableEntry::value_type& entry, defTable[current.getNode()]) + for(TableEntry::value_type& entry: defTable[current.getNode()]) { defUse << "Def [" << keyToString(entry.first) << "]: "; - foreach(NodeVec::value_type& val, entry.second) + for(NodeVec::value_type& val: entry.second) { defUse << getRenameNumberForNode(entry.first, val) << ": " << val << ", "; } @@ -778,11 +773,11 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o } //Print the uses to a string - foreach(TableEntry::value_type& entry, useTable[current.getNode()]) + for(TableEntry::value_type& entry: useTable[current.getNode()]) { defUse << "Use [" << keyToString(entry.first) << "]: "; - foreach(NodeVec::value_type& val, entry.second) + for(NodeVec::value_type& val: entry.second) { defUse << getRenameNumberForNode(entry.first, val) << ": " << val << ", "; } @@ -804,7 +799,7 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o //Now print the out edges std::vector outEdges = current.outEdges(); - foreach(std::vector::value_type& edge, outEdges) + for(std::vector::value_type& edge: outEdges) { outFile << edge.source().id() << " -> " << edge.target().id() << " [label=\"" << escapeString(edge.toString()) @@ -816,7 +811,7 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o std::vector outEdges = current.outEdges(); - foreach(std::vector::value_type& edge, outEdges) + for(std::vector::value_type& edge: outEdges) { //If we haven't seen the target of this node yet, process the node if (std::count(visited.begin(), visited.end(), edge.target()) == 0) @@ -831,7 +826,7 @@ void VariableRenaming::printToFilteredDOT(SgSourceFile* source, std::ofstream& o { std::vector inEdges = current.inEdges(); - foreach(std::vector::value_type& edge, inEdges) + for(std::vector::value_type& edge: inEdges) { //If we haven't seen the target of this node yet, process the node if (std::count(visited.begin(), visited.end(), edge.target()) == 0) @@ -860,7 +855,7 @@ SgInitializedName* VariableRenaming::UniqueNameTraversal::resolveTemporaryInitNa if (isSgVarRefExp(name->get_parent())) { - foreach(SgInitializedName* otherName, allInitNames) + for(SgInitializedName* otherName: allInitNames) { if (otherName->get_prev_decl_item() == name) return otherName; @@ -1196,7 +1191,7 @@ void VariableRenaming::runDefUse(SgFunctionDefinition* func) //Insert each changed node into the list - foreach(SgNode* chNode, changedNodes) + for(SgNode* chNode: changedNodes) { //Get the cfg node for this AST node cfgNode nextNode; @@ -1226,8 +1221,10 @@ void VariableRenaming::runDefUse(SgFunctionDefinition* func) //For every edge, add it to the worklist if it is not seen or something has changed - reverse_foreach(cfgEdgeVec::value_type& edge, outEdges) + //reverse_foreach(cfgEdgeVec::value_type& edge, outEdges) + for (auto it = outEdges.rbegin(); it != outEdges.rend(); ++it) { + cfgEdgeVec::value_type& edge = *it; cfgNode nextNode = edge.target(); //Only insert the node in the worklist if it isn't there already. @@ -1338,7 +1335,7 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV if (!isSgFunctionDefinition(node) && (!isSgInitializedName(node) || isSgCtorInitializerList(node->get_parent()))) { - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { if (propDefs.find(entry.first) == propDefs.end()) { @@ -1352,7 +1349,7 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV //Replace every entry in staging table that has definition in original defs //Also assign renaming numbers to any new definitions - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { //Replace the entry for this variable with the definitions at this node. propDefs[entry.first] = entry.second; @@ -1360,7 +1357,7 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV //Now, iterate the definition vector for this node ROSE_ASSERT(entry.second.size() == 1); - foreach(NodeVec::value_type& defNode, entry.second) + for(NodeVec::value_type& defNode: entry.second) { //Assign a number to each new definition. The function will prevent duplicates addRenameNumberForNode(entry.first, defNode); @@ -1371,10 +1368,10 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV //that have an originalDef as a prefix VarName expVar; - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { - foreach(TableEntry::value_type& propEntry, propDefs) + for(TableEntry::value_type& propEntry: propDefs) { //Don't insert a def if it is already originally defined. if (originalDefTable[node].count(propEntry.first) != 0) @@ -1399,13 +1396,13 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV //Replace every entry in staging table that has definition in expandedDefs //Also assign renaming numbers to any new definitions - foreach(TableEntry::value_type& entry, expandedDefTable[node]) + for(TableEntry::value_type& entry: expandedDefTable[node]) { propDefs[entry.first] = entry.second; //Now, iterate the definition vector for this node - foreach(NodeVec::value_type& defNode, entry.second) + for(NodeVec::value_type& defNode: entry.second) { //Assign a number to each new definition. The function will prevent duplicates addRenameNumberForNode(entry.first, defNode); @@ -1414,7 +1411,7 @@ bool VariableRenaming::mergeDefs(cfgNode curNode, bool *memberRefInserted, NodeV //If there is an initial definition of a name at this node, we should insert it in the table - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { //If the given variable name is not present in the first def table if (firstDefList.count(entry.first) == 0) @@ -1492,7 +1489,7 @@ void VariableRenaming::aggregatePreviousDefs(cfgNode curNode, TableEntry& result //Perform the union of all the infoming definitions. - foreach(TableEntry::value_type& entry, defTable[prev]) + for(TableEntry::value_type& entry: defTable[prev]) { //Insert the definitions for this node at the end of the list results[entry.first].insert(results[entry.first].end(), entry.second.begin(), entry.second.end()); @@ -1502,7 +1499,7 @@ void VariableRenaming::aggregatePreviousDefs(cfgNode curNode, TableEntry& result //Sort every vector in propDefs and remove duplicates - foreach(TableEntry::value_type& entry, results) + for(TableEntry::value_type& entry: results) { std::sort(entry.second.begin(), entry.second.end()); //Create new sequence of unique elements and remove duplicate ones @@ -1534,7 +1531,7 @@ bool VariableRenaming::expandMemberDefinitions(cfgNode curNode) //We want to iterate the vars defined on this node, and expand them - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { if (DEBUG_MODE_EXTRA) { @@ -1602,7 +1599,7 @@ bool VariableRenaming::resolveUses(FilteredCFGNode curNode, bool //Iterate every use at the current node - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { //Check the defs that are active at the current node to find the reaching definition //We want to check if there is a definition entry for this use at the current node @@ -1636,7 +1633,7 @@ bool VariableRenaming::resolveUses(FilteredCFGNode curNode, bool //Iterate every use at the current node - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { //If any of these uses are for a variable defined at this node, we will //set the flag and correct it later. @@ -1667,7 +1664,7 @@ bool VariableRenaming::expandMemberUses(cfgNode curNode) //We want to iterate the vars used on this node, and expand them - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { if (DEBUG_MODE_EXTRA) { @@ -1955,7 +1952,7 @@ VariableRenaming::NodeVec VariableRenaming::getAllUsesForDef(const VarName& var, //Traverse the use Table looking for locations where the def is used - foreach(DefUseTable::value_type& entry, useTable) + for(DefUseTable::value_type& entry: useTable) { //If this entry contains the variable that we want if (entry.second.count(var) != 0) @@ -1980,11 +1977,11 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtNode(SgN //Iterate every variable definition reaching this node - foreach(TableEntry::value_type& entry, defTable[node]) + for(TableEntry::value_type& entry: defTable[node]) { //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2023,7 +2020,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getReachingDefsAtNodeForN //Iterate every variable definition reaching this node - foreach(TableEntry::value_type& entry, defTable[node]) + for(TableEntry::value_type& entry: defTable[node]) { //Check that the current var is the one we want. if (entry.first != var) @@ -2033,7 +2030,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getReachingDefsAtNodeForN //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2072,11 +2069,11 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getUsesAtNode(SgNode* nod //Iterate every variable definition used at this node - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2128,7 +2125,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getUsesAtNodeForName(SgNo //Iterate every variable use at this node - foreach(TableEntry::value_type& entry, useTable[node]) + for(TableEntry::value_type& entry: useTable[node]) { //Check that the current var is the one we want. if (entry.first != var) @@ -2138,7 +2135,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getUsesAtNodeForName(SgNo //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2217,7 +2214,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getOriginalUsesAtNode(SgN VariableRenaming::NumNodeRenameTable result; - foreach(VariableRenaming::VarName varName, originalVariableUsesTraversal.originalVariablesUsed) + for(VariableRenaming::VarName varName: originalVariableUsesTraversal.originalVariablesUsed) { ROSE_ASSERT(result.count(varName) == 0); VariableRenaming::NumNodeRenameEntry varDefs = getUsesAtNodeForName(node, varName); @@ -2234,7 +2231,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getDefsAtNode(SgNode* nod //Loop the expanded table and insert it into the original table - foreach(NumNodeRenameTable::value_type& entry, expanded) + for(NumNodeRenameTable::value_type& entry: expanded) { //Insert the entry wholesale if (original.count(entry.first) == 0) @@ -2245,7 +2242,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getDefsAtNode(SgNode* nod else { - foreach(NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(NumNodeRenameEntry::value_type& tableEntry: entry.second) { //Insert the entry wholesale if (original[entry.first].count(tableEntry.first) == 0) @@ -2276,7 +2273,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getDefsAtNodeForName(SgNo //Loop the expanded table and insert it into the original table - foreach(NumNodeRenameEntry::value_type& tableEntry, expanded) + for(NumNodeRenameEntry::value_type& tableEntry: expanded) { //Insert the entry wholesale if (original.count(tableEntry.first) == 0) @@ -2301,11 +2298,11 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getOriginalDefsAtNode(SgN //Iterate every variable definition reaching this node - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2357,7 +2354,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getOriginalDefsAtNodeForN //Iterate every variable use at this node - foreach(TableEntry::value_type& entry, originalDefTable[node]) + for(TableEntry::value_type& entry: originalDefTable[node]) { //Check that the current var is the one we want. if (entry.first != var) @@ -2367,7 +2364,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getOriginalDefsAtNodeForN //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2419,11 +2416,11 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getExpandedDefsAtNode(SgN //Iterate every variable definition expanded on this node - foreach(TableEntry::value_type& entry, expandedDefTable[node]) + for(TableEntry::value_type& entry: expandedDefTable[node]) { //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2462,7 +2459,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getExpandedDefsAtNodeForN //Iterate every variable use at this node - foreach(TableEntry::value_type& entry, expandedDefTable[node]) + for(TableEntry::value_type& entry: expandedDefTable[node]) { //Check that the current var is the one we want. if (entry.first != var) @@ -2472,7 +2469,7 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getExpandedDefsAtNodeForN //Iterate every definition site for this variable - foreach(NodeVec::value_type& defEntry, entry.second) + for(NodeVec::value_type& defEntry: entry.second) { //Get the rename number for the current variable at the current def site int renameNum = getRenameNumberForNode(entry.first, defEntry); @@ -2519,7 +2516,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getDefsForSubtree(SgNode* //Traverse the defs - foreach(VariableRenaming::NumNodeRenameTable::value_type& entry, defsAtNode) + for(VariableRenaming::NumNodeRenameTable::value_type& entry: defsAtNode) { //If this is the first time the var has been seen, add it wholesale if (result.count(entry.first) == 0) @@ -2529,7 +2526,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getDefsForSubtree(SgNode* } //Traverse each definition of the variable - foreach(VariableRenaming::NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(VariableRenaming::NumNodeRenameEntry::value_type& tableEntry: entry.second) { if (result[entry.first].count(tableEntry.first) == 0) { @@ -2568,7 +2565,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getOriginalDefsForSubtree //Traverse the defs - foreach(VariableRenaming::NumNodeRenameTable::value_type& entry, defsAtNode) + for(VariableRenaming::NumNodeRenameTable::value_type& entry: defsAtNode) { //If this is the first time the var has been seen, add it wholesale if (result.count(entry.first) == 0) @@ -2578,7 +2575,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getOriginalDefsForSubtree } //Traverse each definition of the variable - foreach(VariableRenaming::NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(VariableRenaming::NumNodeRenameEntry::value_type& tableEntry: entry.second) { if (result[entry.first].count(tableEntry.first) == 0) { @@ -2631,7 +2628,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtScopeEnd //Find if any of the children exit the basic block. cfgEdgeVec outEdges = current.outEdges(); - foreach(cfgEdge edge, outEdges) + for(cfgEdge edge: outEdges) { SgNode* targetNode = edge.target().getNode(); @@ -2648,7 +2645,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtScopeEnd //Merge the tables - foreach(NumNodeRenameTable::value_type& entry, temp) + for(NumNodeRenameTable::value_type& entry: temp) { //Insert the entry wholesale if (result.count(entry.first) == 0) @@ -2659,7 +2656,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtScopeEnd else { - foreach(NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(NumNodeRenameEntry::value_type& tableEntry: entry.second) { //Insert the entry wholesale if (result[entry.first].count(tableEntry.first) == 0) @@ -2710,13 +2707,13 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtFunction { //Iterate and merge each edge - foreach(cfgEdgeVec::value_type& edge, lastEdges) + for(cfgEdgeVec::value_type& edge: lastEdges) { NumNodeRenameTable temp = getReachingDefsAtNode(edge.source().getNode()); //Merge the tables - foreach(NumNodeRenameTable::value_type& entry, temp) + for(NumNodeRenameTable::value_type& entry: temp) { //Insert the entry wholesale if (result.count(entry.first) == 0) @@ -2727,7 +2724,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtFunction else { - foreach(NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(NumNodeRenameEntry::value_type& tableEntry: entry.second) { //Insert the entry wholesale if (result[entry.first].count(tableEntry.first) == 0) @@ -2779,11 +2776,11 @@ VariableRenaming::NumNodeRenameEntry VariableRenaming::getReachingDefsAtFunction { //Iterate and merge each edge - foreach(cfgEdgeVec::value_type& edge, lastEdges) + for(cfgEdgeVec::value_type& edge: lastEdges) { NumNodeRenameEntry temp = getReachingDefsAtNodeForName(edge.source().getNode(), var); - foreach(NumNodeRenameEntry::value_type& tableEntry, temp) + for(NumNodeRenameEntry::value_type& tableEntry: temp) { //Insert the entry wholesale if (result.count(tableEntry.first) == 0) @@ -2828,7 +2825,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtStatemen //Add all the unfiltered inEdges to the initial worklist - foreach(CFGEdge inEdge, inEdges) + for(CFGEdge inEdge: inEdges) { unfilteredNodes.push(inEdge.source()); } @@ -2849,7 +2846,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtStatemen else { - foreach(CFGEdge inEdge, node.inEdges()) + for(CFGEdge inEdge: node.inEdges()) { CFGNode parentNode = inEdge.source(); if (visited.count(parentNode) == 0) @@ -2862,7 +2859,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtStatemen //Merge in the defs from the reaching CFG nodes that are not children of the current statement - foreach(CFGNode cfgNode, filteredNodes) + for(CFGNode cfgNode: filteredNodes) { SgNode* sourceNode = cfgNode.getNode(); if (statement == sourceNode || SageInterface::isAncestor(statement, sourceNode)) @@ -2875,7 +2872,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtStatemen //Merge the tables //TODO: Factor this out into a function - foreach(NumNodeRenameTable::value_type& entry, temp) + for(NumNodeRenameTable::value_type& entry: temp) { //Insert the entry wholesale if (result.count(entry.first) == 0) @@ -2886,7 +2883,7 @@ VariableRenaming::NumNodeRenameTable VariableRenaming::getReachingDefsAtStatemen else { - foreach(NumNodeRenameEntry::value_type& tableEntry, entry.second) + for(NumNodeRenameEntry::value_type& tableEntry: entry.second) { //Insert the entry wholesale if (result[entry.first].count(tableEntry.first) == 0) @@ -3112,7 +3109,7 @@ VariableRenaming::ChildUses VariableRenaming::DefsAndUsesTraversal::evaluateSynt //In this case, there are no uses in the operand. We also want to delete any uses for the children vector successors = SageInterface::querySubTree (unaryOp); - foreach(SgNode* successor, successors) + for(SgNode* successor: successors) { ssa->getUseTable()[successor].clear(); } @@ -3203,7 +3200,7 @@ VariableRenaming::ChildUses VariableRenaming::DefsAndUsesTraversal::evaluateSynt void VariableRenaming::DefsAndUsesTraversal::addUsesToNode(SgNode* node, std::vector uses) { - foreach(SgNode* useNode, uses) + for(SgNode* useNode: uses) { //Get the unique name of the def. VarUniqueName * uName = VariableRenaming::getUniqueName(useNode); diff --git a/src/midend/programAnalysis/variableRenaming/VariableRenaming.h b/src/midend/programAnalysis/variableRenaming/VariableRenaming.h index f7ddfcdcdef..c9bc2222a9d 100644 --- a/src/midend/programAnalysis/variableRenaming/VariableRenaming.h +++ b/src/midend/programAnalysis/variableRenaming/VariableRenaming.h @@ -11,7 +11,6 @@ #include #include #include -#include #include "filteredCFG.h" #include @@ -603,7 +602,7 @@ class VariableRenaming std::vector res; T* temp = NULL; - BOOST_FOREACH(NodeVec::value_type& val, vec) + for(NodeVec::value_type& val: vec) { temp = dynamic_cast(val); if(temp != NULL) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C index ff84237e9f8..9832c9e0cc3 100644 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C @@ -1,15 +1,10 @@ #include "ExtractFunctionArguments.h" -#include -#include #include #include "SingleStatementToBlockNormalization.h" -#define foreach BOOST_FOREACH - using namespace std; using namespace boost; - /** Performs the function argument extraction on all function calls in the given subtree of the AST. */ /** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all callsites ignoring the safety (Suggested by Markus Schordan) */ @@ -29,13 +24,13 @@ void ExtractFunctionArguments::NormalizeTree(SgNode* tree, bool doUnsafeNormaliz this->functionCalls = FunctionEvaluationOrderTraversal::GetFunctionCalls(tree); // Normalize each function from safe place - foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.first) { + for(const FunctionCallInfo& functionCallInfo: this->functionCalls.first) { RewriteFunctionCallArguments(functionCallInfo); } // if doUnsafeNormalization is true, we will normalize calls which are not safe if(doUnsafeNormalization){ - foreach(const FunctionCallInfo& functionCallInfo, this->functionCalls.second) { + for(const FunctionCallInfo& functionCallInfo: this->functionCalls.second) { RewriteFunctionCallArguments(functionCallInfo); } } @@ -118,8 +113,8 @@ bool ExtractFunctionArguments::IsFunctionArgumentTrivial(SgExpression* argument) (IsFunctionArgumentTrivial). Such functions don't need to be normalized. */ bool ExtractFunctionArguments::AreAllFunctionCallsTrivial(std::vector functions){ - foreach(FunctionCallInfo functionCallInfo, functions){ - foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ + for(FunctionCallInfo functionCallInfo: functions){ + for(SgExpression* arg: functionCallInfo.functionCall->get_args()->get_expressions()){ if (!IsFunctionArgumentTrivial(arg)) { return false; } @@ -132,8 +127,8 @@ bool ExtractFunctionArguments::AreAllFunctionCallsTrivial(std::vector functions){ - foreach(FunctionCallInfo functionCallInfo, functions){ - foreach(SgExpression* arg, functionCallInfo.functionCall->get_args()->get_expressions()){ + for(FunctionCallInfo functionCallInfo: functions){ + for(SgExpression* arg: functionCallInfo.functionCall->get_args()->get_expressions()){ if (!IsFunctionArgumentTrivial(arg) && !FunctionArgumentCanBeNormalized(arg)) { return false; } @@ -210,7 +205,7 @@ void ExtractFunctionArguments::RewriteFunctionCallArguments(const FunctionCallIn //Go over all the function arguments, pull them out - foreach(SgExpression* arg, argumentList) + for(SgExpression* arg: argumentList) { //No need to pull out parameters that are not complex expressions and //thus don't have side effects @@ -311,7 +306,7 @@ bool ExtractFunctionArguments::FunctionArgsNeedNormalization(SgExprListExp* func ROSE_ASSERT(functionArgs != NULL); SgExpressionPtrList& argumentList = functionArgs->get_expressions(); - foreach(SgExpression* functionArgument, argumentList) + for(SgExpression* functionArgument: argumentList) { if (FunctionArgumentNeedsNormalization(functionArgument)) return true; diff --git a/src/rose-config.C b/src/rose-config.C index 69333919dab..098ede2ba58 100644 --- a/src/rose-config.C +++ b/src/rose-config.C @@ -35,7 +35,6 @@ static const char *description = #include // POLICY_OK -- this is not a ROSE library source file #include -#include #include #include #include @@ -165,7 +164,7 @@ readConfigFile(const std::filesystem::path &configName) { } bool hadError = false; - BOOST_FOREACH (const std::string &key, requiredKeys()) { + for (const std::string &key: requiredKeys()) { if (retval.find(key) == retval.end()) { MLOG_FATAL_CXX("rose-config") < dirs; //boost::split(dirs, settings.searchDirs, boost::is_any_of(":;")); dirs = Rose::StringUtility::split(settings.searchDirs, ":;"); - BOOST_FOREACH (const std::string &dir, dirs) { + for (const std::string &dir: dirs) { std::filesystem::path configFile = std::filesystem::path(dir) / CONFIG_NAME; if (std::filesystem::exists(configFile)) return readConfigFile(configFile); @@ -194,7 +193,7 @@ readConfigFile(const Settings &settings) { MLOG_FATAL_CXX("rose-config") <<"cannot find file \"" < #endif -#include #include #if BOOST_VERSION >= 103600 diff --git a/src/util/StringUtility/FileUtility.C b/src/util/StringUtility/FileUtility.C index 3accc18727a..6d194618308 100644 --- a/src/util/StringUtility/FileUtility.C +++ b/src/util/StringUtility/FileUtility.C @@ -10,7 +10,6 @@ #include "mlog.h" // Other includes -#include #include #include #include // DQ (9/29/2006): This is required for 64-bit g++ 3.4.4 compiler. diff --git a/tests/nonsmoke/functional/CompileTests/Cxx17_tests/test2018_25.C b/tests/nonsmoke/functional/CompileTests/Cxx17_tests/test2018_25.C index 899299ebffd..00a502556d8 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx17_tests/test2018_25.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx17_tests/test2018_25.C @@ -6,7 +6,7 @@ class Work void do_something() const { // for ( int i = 0 ; i < N ; ++i ) - foreach( Parallel , 0 , N , [=,tmp=*this]( int i ) + for( Parallel : 0 , N , [=,tmp=*this]( int i ) { // A modestly long loop body where // every reference to a member must be modified diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_10.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_10.C index 8e6885b754b..d68f0d565bb 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_10.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_10.C @@ -24,7 +24,7 @@ int main(int argc, char** argv) vector funcs = SageInterface::querySubTree(project, V_SgFunctionDeclaration); - BOOST_FOREACH (SgFunctionDeclaration* func, funcs) + for (SgFunctionDeclaration* func: funcs) { if (func->get_name() != "foo") continue; diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_13.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_13.C index 8024cba040a..3962ccd2e3b 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_13.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2011_13.C @@ -25,14 +25,13 @@ To verify this is the case, you can use the following translator ---------------------------------------------- #include "rose.h" -#include int main(int argc, char** argv) { SgProject* project = frontend(argc, argv); vector functions = SageInterface::querySubTree(project, V_SgFunctionDeclaration); - BOOST_FOREACH(SgFunctionDeclaration* function, functions) + for(SgFunctionDeclaration* function: functions) { //Process each function only once if (function != function->get_firstNondefiningDeclaration()) diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_103.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_103.C index d2646598255..c59ca5c83c1 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_103.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_103.C @@ -1,7 +1,5 @@ - #include -#include "boost/foreach.hpp" #include "boost/cstdint.hpp" using std::vector; @@ -20,7 +18,7 @@ uint64_t getNumberOfZones(const vector& blocks) { uint64_t numZones = 0; - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_104.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_104.C index d3e7069abe1..95d30a3d5f9 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_104.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_104.C @@ -1,7 +1,5 @@ - #include -#include "boost/foreach.hpp" #include "boost/cstdint.hpp" using std::vector; @@ -18,7 +16,7 @@ uint64_t getNumberOfZones(const vector& blocks) { uint64_t numZones = 0; - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_105.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_105.C index 4a92711434a..ddfd6a3ce80 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_105.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_105.C @@ -1,5 +1,3 @@ - - #include #include "boost/foreach.hpp" @@ -19,7 +17,7 @@ uint64_t getNumberOfZones(const vector& blocks) { uint64_t numZones = 0; - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_106.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_106.C index 2a114c18c69..e2bd4691241 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_106.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_106.C @@ -1,5 +1,3 @@ - - #include #include "boost/foreach.hpp" @@ -19,7 +17,7 @@ uint64_t getNumberOfZones(const vector& blocks) { uint64_t numZones = 0; - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_108.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_108.C index 20f38fbb865..cafe7d61b76 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_108.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2014_108.C @@ -26,7 +26,7 @@ uint64_t getNumberOfZones(const vector& blocks) { uint64_t numZones = 0; - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_55.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_55.C index 7c51b700d4a..16f4d7c0445 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_55.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_55.C @@ -2,8 +2,6 @@ #include "boost/shared_ptr.hpp" -#include "boost/foreach.hpp" - class X; void foobar() @@ -11,7 +9,7 @@ void foobar() int num = 0; std::vector > *X_ptr = 0L; - BOOST_FOREACH(boost::shared_ptr procInfo, *X_ptr) + for(boost::shared_ptr procInfo: *X_ptr) { num++; } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_56.h b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_56.h index 9c269c42496..9c871309dd0 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_56.h +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2015_56.h @@ -71402,23 +71402,23 @@ namespace foreach template inline boost::foreach::is_lightweight_proxy * -boost_foreach_is_lightweight_proxy(T *&, boost::foreach::tag) { return 0; } +boost_for_is_lightweight_proxy(T *&: boost::foreach::tag) { return 0; } template inline boost::mpl::true_ * -boost_foreach_is_lightweight_proxy(std::pair *&, boost::foreach::tag) { return 0; } +boost_for_is_lightweight_proxy(std::pair *&, boost::foreach::tag) { return 0; } template inline boost::mpl::true_ * -boost_foreach_is_lightweight_proxy(boost::iterator_range *&, boost::foreach::tag) { return 0; } +boost_for_is_lightweight_proxy(boost::iterator_range *&: boost::foreach::tag) { return 0; } template inline boost::mpl::true_ * -boost_foreach_is_lightweight_proxy(boost::sub_range *&, boost::foreach::tag) { return 0; } +boost_for_is_lightweight_proxy(boost::sub_range *&: boost::foreach::tag) { return 0; } template inline boost::mpl::true_ * -boost_foreach_is_lightweight_proxy(T **&, boost::foreach::tag) { return 0; } +boost_for_is_lightweight_proxy(T **&: boost::foreach::tag) { return 0; } @@ -71427,7 +71427,7 @@ boost_foreach_is_lightweight_proxy(T **&, boost::foreach::tag) { return 0; } template inline boost::foreach::is_noncopyable * -boost_foreach_is_noncopyable(T *&, boost::foreach::tag) { return 0; } +boost_for_is_noncopyable(T *&: boost::foreach::tag) { return 0; } namespace boost { @@ -71799,7 +71799,7 @@ template inline auto_any::type> begin(auto_any_t col, type2type *, boost::mpl::true_ *) { - return auto_any::type>( + return auto_any::type>( boost::begin(auto_any_cast(col))); } @@ -71809,7 +71809,7 @@ begin(auto_any_t col, type2type *, boost::mpl::false_ *) { typedef typename type2type::type type; typedef typename foreach_iterator::type iterator; - return auto_any::type>( + return auto_any::type>( iterator(boost::begin((*(auto_any_cast(col)))))); } @@ -71817,7 +71817,7 @@ template inline auto_any::type> begin(auto_any_t col, type2type *, bool *) { - return auto_any::type>( + return auto_any::type>( boost::begin(*auto_any_cast, boost::mpl::false_>(col).get())); } @@ -71835,7 +71835,7 @@ template inline auto_any::type> end(auto_any_t col, type2type *, boost::mpl::true_ *) { - return auto_any::type>( + return auto_any::type>( boost::end(auto_any_cast(col))); } @@ -71845,7 +71845,7 @@ end(auto_any_t col, type2type *, boost::mpl::false_ *) { typedef typename type2type::type type; typedef typename foreach_iterator::type iterator; - return auto_any::type>( + return auto_any::type>( iterator(boost::end((*(auto_any_cast(col)))))); } @@ -71853,7 +71853,7 @@ template inline auto_any::type> end(auto_any_t col, type2type *, bool *) { - return auto_any::type>( + return auto_any::type>( boost::end(*auto_any_cast, boost::mpl::false_>(col).get())); } @@ -71908,7 +71908,7 @@ template inline auto_any::type> rbegin(auto_any_t col, type2type *, boost::mpl::true_ *) { - return auto_any::type>( + return auto_any::type>( boost::rbegin(auto_any_cast(col))); } @@ -71918,7 +71918,7 @@ rbegin(auto_any_t col, type2type *, boost::mpl::false_ *) { typedef typename type2type::type type; typedef typename foreach_reverse_iterator::type iterator; - return auto_any::type>( + return auto_any::type>( iterator(boost::rbegin((*(auto_any_cast(col)))))); } @@ -71926,7 +71926,7 @@ template inline auto_any::type> rbegin(auto_any_t col, type2type *, bool *) { - return auto_any::type>( + return auto_any::type>( boost::rbegin(*auto_any_cast, boost::mpl::false_>(col).get())); } @@ -71947,7 +71947,7 @@ template inline auto_any::type> rend(auto_any_t col, type2type *, boost::mpl::true_ *) { - return auto_any::type>( + return auto_any::type>( boost::rend(auto_any_cast(col))); } @@ -71957,7 +71957,7 @@ rend(auto_any_t col, type2type *, boost::mpl::false_ *) { typedef typename type2type::type type; typedef typename foreach_reverse_iterator::type iterator; - return auto_any::type>( + return auto_any::type>( iterator(boost::rend((*(auto_any_cast(col)))))); } @@ -71965,7 +71965,7 @@ template inline auto_any::type> rend(auto_any_t col, type2type *, bool *) { - return auto_any::type>( + return auto_any::type>( boost::rend(*auto_any_cast, boost::mpl::false_>(col).get())); } @@ -72090,7 +72090,7 @@ void foobar() int num = 0; std::vector > *X_ptr = 0L; - if (bool _foreach_is_rvalue14 = false) {} else if (boost::foreach_detail_::auto_any_t _foreach_col14 = boost::foreach_detail_::contain( (true ? boost::foreach_detail_::make_probe((*X_ptr), _foreach_is_rvalue14) : (*X_ptr)) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur14 = boost::foreach_detail_::begin( _foreach_col14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end14 = boost::foreach_detail_::end( _foreach_col14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else for (bool _foreach_continue14 = true; _foreach_continue14 && !boost::foreach_detail_::done( _foreach_cur14 , _foreach_end14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))); _foreach_continue14 ? boost::foreach_detail_::next( _foreach_cur14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue14)) {} else for (boost::shared_ptr procInfo = boost::foreach_detail_::deref( _foreach_cur14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))); !_foreach_continue14; _foreach_continue14 = true) + if (bool _for_is_rvalue14 = false) {} else if (boost::foreach_detail_::auto_any_t _foreach_col14 = boost::foreach_detail_::contain( (true ? boost::foreach_detail_::make_probe((*X_ptr): _foreach_is_rvalue14) : (*X_ptr)) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur14 = boost::foreach_detail_::begin( _foreach_col14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end14 = boost::foreach_detail_::end( _foreach_col14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(*X_ptr) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(*X_ptr))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(*X_ptr) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue14)))) {} else for (bool _foreach_continue14 = true; _foreach_continue14 && !boost::foreach_detail_::done( _foreach_cur14 , _foreach_end14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))); _foreach_continue14 ? boost::foreach_detail_::next( _foreach_cur14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue14)) {} else for (boost::shared_ptr procInfo = boost::foreach_detail_::deref( _foreach_cur14 , (true ? 0 : boost::foreach_detail_::encode_type(*X_ptr, boost::foreach_detail_::is_const_(*X_ptr)))); !_foreach_continue14; _foreach_continue14 = true) { num++; } diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2016_58.C b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2016_58.C index 207e0806cc1..dcc78b32502 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2016_58.C +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/test2016_58.C @@ -1793,6 +1793,7 @@ class SharedObject { }; enum boost_foreach_argument_dependent_lookup_hack +#include "boost/foreach.hpp" { boost_foreach_argument_dependent_lookup_hack_value }; @@ -2044,25 +2045,25 @@ contain(T const &t, bool *rvalue); template inline auto_any::type> begin(auto_any_t col, type2type *, bool *); -// { return auto_any::type>(boost::begin(*auto_any_cast, boost::mpl::false_>(col).get())); } +// { return auto_any::type>(boost::begin(*auto_any_cast, boost::mpl::false_>(col).get())); } template inline auto_any::type> end(auto_any_t col, type2type *, bool *); - // { return auto_any::type>(boost::end(*auto_any_cast, boost::mpl::false_>(col).get())); } + // { return auto_any::type>(boost::end(*auto_any_cast, boost::mpl::false_>(col).get())); } template inline bool done(auto_any_t cur, auto_any_t end, type2type *); - // { typedef typename foreach_iterator::type iter_t; return auto_any_cast(cur) == auto_any_cast(end); } + // { typedef typename for_iterator::type iter_t; return auto_any_cast(cur) == auto_any_cast(end); } template inline void next(auto_any_t cur, type2type *); -// { typedef typename foreach_iterator::type iter_t; ++auto_any_cast(cur); } +// { typedef typename for_iterator::type iter_t; ++auto_any_cast(cur); } template inline typename foreach_reference::type deref(auto_any_t cur, type2type *); -// { typedef typename foreach_iterator::type iter_t; return *auto_any_cast(cur); } +// { typedef typename for_iterator::type iter_t; return *auto_any_cast(cur); } } } @@ -2150,7 +2151,7 @@ void fromDecimal(Word *vec, const std::string &input) boost::uint64_t v = 0; #if 1 - if (bool _foreach_is_rvalue1401 = false) {} else if (boost::foreach_detail_::auto_any_t _foreach_col1401 = boost::foreach_detail_::contain( (true ? boost::foreach_detail_::make_probe((input), _foreach_is_rvalue1401) : (input)) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur1401 = boost::foreach_detail_::begin( _foreach_col1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end1401 = boost::foreach_detail_::end( _foreach_col1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else for (bool _foreach_continue1401 = true; _foreach_continue1401 && !boost::foreach_detail_::done( _foreach_cur1401 , _foreach_end1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))); _foreach_continue1401 ? boost::foreach_detail_::next( _foreach_cur1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue1401)) {} else for (char ch = boost::foreach_detail_::deref( _foreach_cur1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))); !_foreach_continue1401; _foreach_continue1401 = true) { + if (bool _for_is_rvalue1401 = false) {} else if (boost::foreach_detail_::auto_any_t _foreach_col1401 = boost::foreach_detail_::contain( (true ? boost::foreach_detail_::make_probe((input): _foreach_is_rvalue1401) : (input)) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur1401 = boost::foreach_detail_::begin( _foreach_col1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end1401 = boost::foreach_detail_::end( _foreach_col1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input))) , (boost::foreach_detail_::should_copy_impl( true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::is_array_(input) , boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value) , boost::foreach_detail_::not_(boost::foreach_detail_::is_const_(input))) , true ? 0 : boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(input) , boost_foreach_argument_dependent_lookup_hack_value)) , &_foreach_is_rvalue1401)))) {} else for (bool _foreach_continue1401 = true; _foreach_continue1401 && !boost::foreach_detail_::done( _foreach_cur1401 , _foreach_end1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))); _foreach_continue1401 ? boost::foreach_detail_::next( _foreach_cur1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue1401)) {} else for (char ch = boost::foreach_detail_::deref( _foreach_cur1401 , (true ? 0 : boost::foreach_detail_::encode_type(input, boost::foreach_detail_::is_const_(input)))); !_foreach_continue1401; _foreach_continue1401 = true) { } #endif diff --git a/tests/nonsmoke/functional/moveDeclarationTool/inputmoveDeclarationToInnermostScope_test2015_71.C b/tests/nonsmoke/functional/moveDeclarationTool/inputmoveDeclarationToInnermostScope_test2015_71.C index 384e735ecb2..246c056ae0d 100644 --- a/tests/nonsmoke/functional/moveDeclarationTool/inputmoveDeclarationToInnermostScope_test2015_71.C +++ b/tests/nonsmoke/functional/moveDeclarationTool/inputmoveDeclarationToInnermostScope_test2015_71.C @@ -1,7 +1,5 @@ - #include -#include "boost/foreach.hpp" #include "boost/cstdint.hpp" using std::vector; @@ -37,7 +35,7 @@ getNumberOfZones(const vector& blocks) uint64_t numZones = 0; #endif - BOOST_FOREACH(const Block& block, blocks) + for(const Block& block: blocks) { numZones += block.getSize(); } diff --git a/tests/nonsmoke/functional/roseTests/astInliningTests/inlineEverything.C b/tests/nonsmoke/functional/roseTests/astInliningTests/inlineEverything.C index f9532b188ca..d456434a36e 100644 --- a/tests/nonsmoke/functional/roseTests/astInliningTests/inlineEverything.C +++ b/tests/nonsmoke/functional/roseTests/astInliningTests/inlineEverything.C @@ -153,7 +153,7 @@ main (int argc, char* argv[]) { for (int count=0; count<10; ++count) { bool changed = false; - // BOOST_FOREACH (SgFunctionCallExp *call, SageInterface::querySubTree(sageProject)) + // for (SgFunctionCallExp *call: SageInterface::querySubTree(sageProject)) // interesting user loops are often located in the end of the source file //BOOST_REVERSE_FOREACH (SgFunctionCallExp *call, SageInterface::querySubTree(sageProject)) MLOG_WARN_C("astInliningTests", "reverse_foreach, e.g., BOOST_REVERSE_FOREACH should be used.\n"); diff --git a/tests/nonsmoke/functional/roseTests/astLValueTests/runTest.C b/tests/nonsmoke/functional/roseTests/astLValueTests/runTest.C index f65622b925c..938837f4442 100644 --- a/tests/nonsmoke/functional/roseTests/astLValueTests/runTest.C +++ b/tests/nonsmoke/functional/roseTests/astLValueTests/runTest.C @@ -1,6 +1,5 @@ #include #include -#include int main(int argc, char ** argv) { @@ -15,14 +14,14 @@ int main(int argc, char ** argv) bool success = true; std::vector funs = SageInterface::querySubTree(project, V_SgFunctionDeclaration); - BOOST_FOREACH(SgFunctionDeclaration* fun, funs) + for(SgFunctionDeclaration* fun: funs) { std::string funName = fun->get_qualified_name().getString(); // every expr statement should be an lvalue if (funName == "HasLValues") { Rose_STL_Container bodystmts = fun->get_definition()->get_body()->get_statements(); - BOOST_FOREACH(SgStatement* stmt, bodystmts) + for(SgStatement* stmt: bodystmts) { if (SgExprStatement* exprstmt = isSgExprStatement(stmt)) { @@ -39,7 +38,7 @@ int main(int argc, char ** argv) else if (funName == "NoLValues") { Rose_STL_Container bodystmts = fun->get_definition()->get_body()->get_statements(); - BOOST_FOREACH(SgStatement* stmt, bodystmts) + for(SgStatement* stmt: bodystmts) { if (SgExprStatement* exprstmt = isSgExprStatement(stmt)) { diff --git a/tests/nonsmoke/functional/roseTests/programAnalysisTests/VirtualFunctionAnalysisTest.C b/tests/nonsmoke/functional/roseTests/programAnalysisTests/VirtualFunctionAnalysisTest.C index d20251899ac..5fb5d4aefec 100644 --- a/tests/nonsmoke/functional/roseTests/programAnalysisTests/VirtualFunctionAnalysisTest.C +++ b/tests/nonsmoke/functional/roseTests/programAnalysisTests/VirtualFunctionAnalysisTest.C @@ -4,13 +4,7 @@ #include #include #include - #include "VirtualFunctionAnalysis.h" -using namespace boost; - -// warning: poor practice and possible name conflicts according to Boost documentation -#define foreach BOOST_FOREACH -#define reverse_foreach BOOST_REVERSE_FOREACH using namespace std; using namespace boost; diff --git a/tests/nonsmoke/functional/roseTests/programAnalysisTests/generalDataFlowAnalysisTests/pointerAliasAnalysis.h b/tests/nonsmoke/functional/roseTests/programAnalysisTests/generalDataFlowAnalysisTests/pointerAliasAnalysis.h index a3122b27268..228748f8a41 100644 --- a/tests/nonsmoke/functional/roseTests/programAnalysisTests/generalDataFlowAnalysisTests/pointerAliasAnalysis.h +++ b/tests/nonsmoke/functional/roseTests/programAnalysisTests/generalDataFlowAnalysisTests/pointerAliasAnalysis.h @@ -1,7 +1,6 @@ #ifndef POINTERALIAS_ANALYSIS_H #define POINTERALIAS_ANALYSIS_H -#include #include #include #include diff --git a/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithRetCode.C b/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithRetCode.C index c3003fe67af..b4358c483db 100644 --- a/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithRetCode.C +++ b/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithRetCode.C @@ -7,14 +7,10 @@ #include #include #include -#include using namespace std; using namespace boost::algorithm; using namespace SageInterface; - -#define foreach BOOST_FOREACH - class TypeTraitChecker : public AstSimpleProcessing { private: bool expectedValue; diff --git a/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithoutRetCode.C b/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithoutRetCode.C index f86081585a1..8db6b88b028 100644 --- a/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithoutRetCode.C +++ b/tests/nonsmoke/functional/roseTests/programAnalysisTests/typeTraitTests/typeTraitExerciseWithoutRetCode.C @@ -8,13 +8,11 @@ // #include // #include // #include -// #include using namespace std; // using namespace boost::algorithm; // using namespace SageInterface; -// #define foreach BOOST_FOREACH #define DEBUG_QUADRATIC_BEHAVIOR 0 diff --git a/tests/nonsmoke/functional/roseTests/programTransformationTests/extractFunctionArgumentsTest/NormalizationTranslator.C b/tests/nonsmoke/functional/roseTests/programTransformationTests/extractFunctionArgumentsTest/NormalizationTranslator.C index 3b3d23c6d75..daeca8b742d 100644 --- a/tests/nonsmoke/functional/roseTests/programTransformationTests/extractFunctionArgumentsTest/NormalizationTranslator.C +++ b/tests/nonsmoke/functional/roseTests/programTransformationTests/extractFunctionArgumentsTest/NormalizationTranslator.C @@ -1,9 +1,7 @@ #include "rose.h" #include -#include #include -#define foreach BOOST_FOREACH int main(int argc, char** argv) { @@ -12,7 +10,7 @@ int main(int argc, char** argv) AstTests::runAllTests(project); std::vector functions = SageInterface::querySubTree(project, V_SgFunctionDefinition); - foreach(SgFunctionDefinition* function, functions) + for(SgFunctionDefinition* function: functions) { ExtractFunctionArguments e; #if 0 diff --git a/tests/nonsmoke/functional/translatorTests/testConstDeclarations.C b/tests/nonsmoke/functional/translatorTests/testConstDeclarations.C index cc67e36d1ed..c5069b1bb52 100644 --- a/tests/nonsmoke/functional/translatorTests/testConstDeclarations.C +++ b/tests/nonsmoke/functional/translatorTests/testConstDeclarations.C @@ -4,7 +4,6 @@ // directory which demonstrates input codes that demonstrate bugs in ROSE. #include "rose.h" -#include // using namespace SageBuilder; // using namespace SageInterface; @@ -17,7 +16,7 @@ main(int argc, char* argv[]) SgProject* project = frontend(argc, argv); std::vector ifs = SageInterface::querySubTree(project, V_SgIfStmt); - BOOST_FOREACH(SgIfStmt* if_stmt, ifs) + for(SgIfStmt* if_stmt: ifs) { if (SgExpression *se = isSgExprStatement(if_stmt->get_conditional())->get_expression()) { diff --git a/tests/nonsmoke/functional/translatorTests/testDataMemberOfConst.C b/tests/nonsmoke/functional/translatorTests/testDataMemberOfConst.C index 3ca119d522f..987a9da11b7 100644 --- a/tests/nonsmoke/functional/translatorTests/testDataMemberOfConst.C +++ b/tests/nonsmoke/functional/translatorTests/testDataMemberOfConst.C @@ -1,6 +1,5 @@ // ROSE Translator to make sure that members of const data structures are const #include "rose.h" -#include using namespace SageBuilder; using namespace SageInterface; @@ -12,7 +11,7 @@ int main(int argc, char* argv[]) SgBasicBlock* body= mainFunc->get_definition()->get_body(); std::vector dots = SageInterface::querySubTree(body, V_SgDotExp); - BOOST_FOREACH(SgDotExp* dot, dots) + for(SgDotExp* dot: dots) { std::string memberName = isSgVarRefExp(dot->get_rhs_operand())->get_symbol()->get_name().getString(); if (memberName == "i") diff --git a/tests/nonsmoke/functional/translatorTests/testFortranParameter.C b/tests/nonsmoke/functional/translatorTests/testFortranParameter.C index 4b7217839ee..175c349b425 100644 --- a/tests/nonsmoke/functional/translatorTests/testFortranParameter.C +++ b/tests/nonsmoke/functional/translatorTests/testFortranParameter.C @@ -1,6 +1,5 @@ // ROSE Translator to make sure that Fortran parameters come through as const #include "rose.h" -#include using namespace SageBuilder; using namespace SageInterface; @@ -9,7 +8,7 @@ int main(int argc, char* argv[]) SgProject* project = frontend(argc, argv); std::vector names = SageInterface::querySubTree(project, V_SgInitializedName); - BOOST_FOREACH(SgInitializedName* name, names) + for(SgInitializedName* name: names) { if (name->get_qualified_name().getString() == "pi") { diff --git a/tests/nonsmoke/functional/translatorTests/testFortranProtected.C b/tests/nonsmoke/functional/translatorTests/testFortranProtected.C index c9c3262a49b..8f6ea90dc3c 100644 --- a/tests/nonsmoke/functional/translatorTests/testFortranProtected.C +++ b/tests/nonsmoke/functional/translatorTests/testFortranProtected.C @@ -1,10 +1,8 @@ // ROSE Translator to make sure that Fortran parameters come through as const #include "rose.h" -#include using namespace SageBuilder; using namespace SageInterface; -#define foreach BOOST_FOREACH int main(int argc, char* argv[]) { @@ -13,7 +11,7 @@ int main(int argc, char* argv[]) std::vector names = SageInterface::querySubTree(project, V_SgInitializedName); std::vector pnames; - foreach(SgInitializedName* name, names) + for(SgInitializedName* name: names) { std::cout << name->get_qualified_name().getString(); if (name->get_protected_declaration()) @@ -45,7 +43,7 @@ int main(int argc, char* argv[]) } std::vector assigns = SageInterface::querySubTree(project); - foreach(SgAssignOp* op, assigns) + for(SgAssignOp* op: assigns) { SgVarRefExp* var = isSgVarRefExp(op->get_lhs_operand()); SgInitializedName* decl = var->get_symbol()->get_declaration(); diff --git a/tests/nonsmoke/functional/translatorTests/testTranslator2010_03.C b/tests/nonsmoke/functional/translatorTests/testTranslator2010_03.C index 5dd776021c5..7eb649943af 100644 --- a/tests/nonsmoke/functional/translatorTests/testTranslator2010_03.C +++ b/tests/nonsmoke/functional/translatorTests/testTranslator2010_03.C @@ -1,5 +1,4 @@ #include "rose.h" -#include int main(int argc, char** argv) { @@ -15,7 +14,7 @@ int main(int argc, char** argv) backend(project); std::vector functions = SageInterface::querySubTree(project,V_SgFunctionDeclaration); - BOOST_FOREACH(SgFunctionDeclaration* function, functions) + for(SgFunctionDeclaration* function: functions) { // Process each function only once if (function != function->get_firstNondefiningDeclaration()) diff --git a/tools/moveDeclarationToInnermostScope.C b/tools/moveDeclarationToInnermostScope.C index fe764080738..ea91412e3f6 100644 --- a/tools/moveDeclarationToInnermostScope.C +++ b/tools/moveDeclarationToInnermostScope.C @@ -94,7 +94,6 @@ #include #include // used for a worklist of declarations to be moved #include // used for a worklist of declarations to be moved , first found, last processing -#include #include // used to store special var reference's scope // another level of control over transformation tracking code @@ -639,7 +638,7 @@ int main(int argc, char * argv[]) std::vector filenames = GetSourceFilenamesFromCommandline( std::vector(argv, argv + argc)); - BOOST_FOREACH(std::string filename, filenames) + for(std::string filename: filenames) { std::cout << filename << std::endl; } diff --git a/tutorial/ASTGraphGeneratorCustomized.C b/tutorial/ASTGraphGeneratorCustomized.C index 66bc42451a6..00190fdc097 100644 --- a/tutorial/ASTGraphGeneratorCustomized.C +++ b/tutorial/ASTGraphGeneratorCustomized.C @@ -3,7 +3,6 @@ #include "rose.h" #include "AstDOTGeneration.h" #include "utility_functions.h" -#include struct ExtraNodeInfo { diff --git a/tutorial/classHierarchyGraph.C b/tutorial/classHierarchyGraph.C index 840e60a510f..3ae559c44ec 100644 --- a/tutorial/classHierarchyGraph.C +++ b/tutorial/classHierarchyGraph.C @@ -1,8 +1,6 @@ #include "rose.h" #include "CallGraph.h" -#include -#define foreach BOOST_FOREACH using namespace std; @@ -15,10 +13,10 @@ int main(int argc, char * argv[]) //Display the ancestors of each class vector allClasses = SageInterface::querySubTree(project, V_SgClassDefinition); - foreach(SgClassDefinition* classDef, allClasses) + for(SgClassDefinition* classDef: allClasses) { printf("\n%s subclasses: ", classDef->get_declaration()->get_name().str()); - foreach(SgClassDefinition* subclass, hier.getSubclasses(classDef)) + for(SgClassDefinition* subclass: hier.getSubclasses(classDef)) { printf("%s, ", subclass->get_declaration()->get_name().str()); } From d200a8d8c7c793ac88924e0606efde84da3fc4a0 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Fri, 29 Sep 2023 15:15:36 -0400 Subject: [PATCH 17/42] [REX]: deBoost: removing boost from autotools building, work-in-progress. --- CMakeLists.txt | 3 +- Makefile.am | 7 +- config/Makefile.for.ROSE.includes.and.libs | 31 +- config/automake_conditional_display_makefile | 60 ---- config/ax_boost_asio.m4 | 103 ------- config/ax_boost_atomic.m4 | 106 ------- config/ax_boost_base.m4 | 290 ------------------ config/ax_boost_chrono.m4 | 123 -------- config/ax_boost_date_time.m4 | 105 ------- config/ax_boost_filesystem.m4 | 112 ------- config/ax_boost_iostreams.m4 | 122 -------- config/ax_boost_program_options.m4 | 101 ------ config/ax_boost_python.m4 | 127 -------- config/ax_boost_random.m4 | 97 ------ config/ax_boost_regex.m4 | 106 ------- config/ax_boost_signals.m4 | 106 ------- config/ax_boost_system.m4 | 114 ------- config/ax_boost_test_exec_monitor.m4 | 132 -------- config/ax_boost_thread.m4 | 148 --------- config/ax_boost_unit_test_framework.m4 | 130 -------- config/ax_boost_wave.m4 | 119 ------- config/ax_boost_wserialization.m4 | 109 ------- config/ax_rose_lib.m4 | 100 ------ config/support-blacklist.m4 | 123 -------- config/support-boost.m4 | 198 ------------ config/support-rose.m4 | 4 - config/support-summary.m4 | 23 -- configure.ac | 1 - rose_config.h.in.cmake | 31 -- src/Makefile.am | 26 +- src/ROSETTA/src/Makefile.am | 7 - src/frontend/SageIII/Makefile.am | 8 +- .../SageIII/astTokenStream/Makefile.am | 4 +- src/frontend/SageIII/rose_attributes_list.C | 18 -- src/frontend/SageIII/rose_attributes_list.h | 68 ---- src/rose.h | 1 - .../CompileTests/Cxx_tests/Makefile.am | 8 +- .../CompilerOptionsTests/testWave/Makefile.am | 4 +- .../RunTests/FortranTests/LANL_POP/.gitignore | 2 - .../programAnalysisTests/Makefile.am | 4 +- 40 files changed, 18 insertions(+), 2963 deletions(-) delete mode 100644 config/ax_boost_asio.m4 delete mode 100644 config/ax_boost_atomic.m4 delete mode 100644 config/ax_boost_base.m4 delete mode 100644 config/ax_boost_chrono.m4 delete mode 100644 config/ax_boost_date_time.m4 delete mode 100644 config/ax_boost_filesystem.m4 delete mode 100644 config/ax_boost_iostreams.m4 delete mode 100644 config/ax_boost_program_options.m4 delete mode 100644 config/ax_boost_python.m4 delete mode 100644 config/ax_boost_random.m4 delete mode 100644 config/ax_boost_regex.m4 delete mode 100644 config/ax_boost_signals.m4 delete mode 100644 config/ax_boost_system.m4 delete mode 100644 config/ax_boost_test_exec_monitor.m4 delete mode 100644 config/ax_boost_thread.m4 delete mode 100644 config/ax_boost_unit_test_framework.m4 delete mode 100644 config/ax_boost_wave.m4 delete mode 100644 config/ax_boost_wserialization.m4 delete mode 100644 config/ax_rose_lib.m4 delete mode 100644 config/support-blacklist.m4 delete mode 100644 config/support-boost.m4 delete mode 100644 tests/nonsmoke/functional/RunTests/FortranTests/LANL_POP/.gitignore diff --git a/CMakeLists.txt b/CMakeLists.txt index 78f99030c86..e7292b5e3fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ # 8. If a CMakefile file needs to be conditionally enabled, do it in that CMake file rather than around the # add_subdirectory in the level above. This keeps all the logic for a directory in a single file rather than # split across two files. It is a bit unfortunate that CMake can't find the lower-level CMakeList files + # on its own, so some of the logic is still necessarily in the level above. There are exceptions to this rule, # and they're pretty obvious when they occur--as when a single if() protects a whole bunch of add_subdirectory. @@ -112,8 +113,6 @@ if(WIN32) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() -#add_definitions(-DBOOST_ALL_NO_LIB=1) - # FIXME: Why do we have to have a copy of some standard built-in modules inside rose? set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH}) diff --git a/Makefile.am b/Makefile.am index 66d280193f5..d8cfad4cc85 100644 --- a/Makefile.am +++ b/Makefile.am @@ -253,12 +253,7 @@ endif @echo '***** make install-data rule complete (terminated normally) *****' @echo '*****************************************************************' -# DQ (4/22/2005): Set this so that make distcheck will use the same -# --with-edg_source_code=true/false option as were used at configure. -# JJW (5/14/2008): Add the Boost flag the same way, using an internal -# variable from AX_BOOST_* to find the argument to --with-boost when -# this copy of ROSE was originally configured. -DISTCHECK_CONFIGURE_FLAGS = --with-boost=$(ac_boost_path) +DISTCHECK_CONFIGURE_FLAGS = # DQ (7/25/2008): If ROSE was originallly configured with Fortran (by tuning # on the java support) then make sure it is tested as part of the distcheck rule. diff --git a/config/Makefile.for.ROSE.includes.and.libs b/config/Makefile.for.ROSE.includes.and.libs index fdb844c4ba6..f7ba097ab55 100644 --- a/config/Makefile.for.ROSE.includes.and.libs +++ b/config/Makefile.for.ROSE.includes.and.libs @@ -32,13 +32,6 @@ if USE_ROSE_IN_BUILD_TREE_VAR export ROSE_IN_BUILD_TREE=$(top_builddir) endif -# DQ (12/22/2008): Specification of Boost path for use with "-isystem" option (may be GNU -# specific). We use this option only if the configuration of ROSE has detected a -# previously installed version of Boost (which we do not want to use). -# Note that only one of these will be non-empty makefile variables. -ROSE_BOOST_PREINCLUDE_PATH = @ROSE_BOOST_PREINCLUDE_PATH@ -ROSE_BOOST_NORMAL_INCLUDE_PATH = @ROSE_BOOST_NORMAL_INCLUDE_PATH@ - # This is properly handled by automake even when specified in an include file EDG_LIBS = @EDG_LIBS@ @@ -129,8 +122,7 @@ ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH_ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT -I$(top_srcdir)/src/midend/programAnalysis \ -I$(top_srcdir)/src/3rdPartyLibraries/json \ -I$(top_srcdir)/src/util/graphs \ - $(ROSE_FLANG_INCLUDES) \ - $(ROSE_BOOST_NORMAL_INCLUDE_PATH) + $(ROSE_FLANG_INCLUDES) # else # ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT # ROSE_INCLUDES = # $(ROSE_BOOST_PREINCLUDE_PATH) @@ -209,9 +201,7 @@ ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH = \ -I$(top_srcdir)/src/midend/astUtil/astInterface \ -I$(top_srcdir)/libltdl \ $(VALGRIND_CFLAGS) \ - $(ROSE_BOOST_NORMAL_INCLUDE_PATH) \ - $(ROSE_PCH_INCLUDE) \ - $(BOOST_CPPFLAGS) + $(ROSE_PCH_INCLUDE) # endif # ROSE_USE_INTERNAL_FRONTEND_DEVELOPMENT # DQ (10/23/2015): These paths have been replaces with the following variables. @@ -223,12 +213,7 @@ ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH = \ # $(ROSE_CLANG_INCLUDE) SWIG_ROSE_INCLUDES = $(ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH) -ROSE_INCLUDES = -I$(top_builddir) -I$(top_builddir)/src $(ROSE_BOOST_PREINCLUDE_PATH) $(ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH) - -# DQ (12/22/2008): Move Boost directory to front and used "-isystem" option so -# that a system with a previous (older) installation of boost does not interfer -# with the use of ROSE (and the version of boost specified using "--with-boost"). -# $(BOOST_CPPFLAGS) +ROSE_INCLUDES = -I$(top_builddir) -I$(top_builddir)/src $(ROSE_INCLUDES_WITHOUT_BOOST_ISYSTEM_PATH) # DQ (10/28/2008): I think these should be included, I don't know why they # were removed (used with Microsoft Windows tests, and Yices tests). @@ -244,17 +229,7 @@ ROSE_INCLUDES = -I$(top_builddir) -I$(top_builddir)/src $(ROSE_BOOST_PREINCLUDE_ # JJW 7/25/2008: This should probably just be the same as ROSE_LIBS ROSE_LIBS_WITH_PATH = $(ROSE_LIBS) -# ROSE_LIBS = $(top_builddir)/src/librose.la -lm $(LEXLIB) $(WAVE_LDFLAGS) $(WAVE_LIBRARIES) $(WAVE_LIBS) $(JAVA_JVM_LIB) $(RT_LIBS) - -# MS 10/19/2015: added ROSE_BOOST_LIBS variable to share exact same -# boost libs list in ROSE an in the ROSTTA Makefiles. -ROSE_BOOST_LIBS=$(BOOST_LDFLAGS) $(BOOST_DATE_TIME_LIB) $(BOOST_CHRONO_LIB) \ - $(BOOST_THREAD_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_PROGRAM_OPTIONS_LIB) \ - $(BOOST_RANDOM_LIB) $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_SERIALIZATION_LIB) \ - $(BOOST_WAVE_LIB) $(BOOST_IOSTREAMS_LIB) $(BOOST_ATOMIC_LIB) - ROSE_LIBS = $(abspath $(top_builddir)/src/librose.la) -lm $(JAVA_JVM_LINK) \ - $(ROSE_BOOST_LIBS) \ $(RT_LIBS) \ $(ROSE_INTEL_COMPILER_MATH_LIBS) \ $(ROSE_QUAD_FLOAT_MATH) diff --git a/config/automake_conditional_display_makefile b/config/automake_conditional_display_makefile index 6c444c033f9..2b53c52ead1 100644 --- a/config/automake_conditional_display_makefile +++ b/config/automake_conditional_display_makefile @@ -159,11 +159,6 @@ if ROSE_PCH else @echo "Automake conditional ROSE_PCH: NOT defined" endif -if ROSE_USE_BOOST_WAVE - @echo "Automake conditional ROSE_USE_BOOST_WAVE: DEFINED" -else - @echo "Automake conditional ROSE_USE_BOOST_WAVE: NOT defined" -endif if ROSE_USE_GCC_OMP @echo "Automake conditional ROSE_USE_GCC_OMP: DEFINED" else @@ -219,61 +214,6 @@ if ROSE_USE_WGET else @echo "Automake conditional ROSE_USE_WGET: NOT defined" endif -if ROSE_USING_BOOST_VERSION_1_35 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_35: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_35: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_36 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_36: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_36: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_37 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_37: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_37: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_38 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_38: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_38: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_39 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_39: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_39: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_40 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_40: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_40: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_41 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_41: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_41: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_42 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_42: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_42: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_43 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_43: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_43: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_44 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_44: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_44: NOT defined" -endif -if ROSE_USING_BOOST_VERSION_1_45 - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_45: DEFINED" -else - @echo "Automake conditional ROSE_USING_BOOST_VERSION_1_45: NOT defined" -endif if ROSE_USING_GFORTRAN_VERSION_4_0 @echo "Automake conditional ROSE_USING_GFORTRAN_VERSION_4_0: DEFINED" else diff --git a/config/ax_boost_asio.m4 b/config/ax_boost_asio.m4 deleted file mode 100644 index 443fec35ca5..00000000000 --- a/config/ax_boost_asio.m4 +++ /dev/null @@ -1,103 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_asio.html -# -# SYNOPSIS -# -# AX_BOOST_ASIO -# -# DESCRIPTION -# -# Test for Asio library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_ASIO_LIB) -# -# And sets: -# -# HAVE_BOOST_ASIO -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Pete Greenwell -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_ASIO], -[ - AC_ARG_WITH([boost-asio], - AS_HELP_STRING([--with-boost-asio@<:@=special-lib@:>@], - [use the ASIO library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-asio=boost_system-gcc41-mt-1_34 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_asio_lib="" - else - want_boost="yes" - ax_boost_user_asio_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::ASIO library is available, - ax_cv_boost_asio, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[ @%:@include - ]], - [[ - - boost::asio::io_service io; - boost::system::error_code timer_result; - boost::asio::deadline_timer t(io); - t.cancel(); - io.run_one(); - return 0; - ]]), - ax_cv_boost_asio=yes, ax_cv_boost_asio=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_asio" = "xyes"; then - AC_DEFINE(HAVE_BOOST_ASIO,,[define if the Boost::ASIO library is available]) - BN=boost_system - if test "x$ax_boost_user_asio_lib" = "x"; then - for ax_lib in $BN $BN-$CC $BN-$CC-mt $BN-$CC-mt-s $BN-$CC-s \ - lib$BN lib$BN-$CC lib$BN-$CC-mt lib$BN-$CC-mt-s lib$BN-$CC-s \ - $BN-mgw $BN-mgw $BN-mgw-mt $BN-mgw-mt-s $BN-mgw-s ; do - AC_CHECK_LIB($ax_lib, main, [BOOST_ASIO_LIB="-l$ax_lib" AC_SUBST(BOOST_ASIO_LIB) link_thread="yes" break], - [link_thread="no"]) - done - else - for ax_lib in $ax_boost_user_asio_lib $BN-$ax_boost_user_asio_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_ASIO_LIB="-l$ax_lib" AC_SUBST(BOOST_ASIO_LIB) link_asio="yes" break], - [link_asio="no"]) - done - - fi - if test "x$link_asio" = "xno"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_atomic.m4 b/config/ax_boost_atomic.m4 deleted file mode 100644 index a71d0c3f4b7..00000000000 --- a/config/ax_boost_atomic.m4 +++ /dev/null @@ -1,106 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_atomic.html -# -# SYNOPSIS -# -# AX_BOOST_ATOMIC -# -# DESCRIPTION -# -# Test for Atomic library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_ATOMIC_LIB) -# -# And sets: -# -# HAVE_BOOST_ATOMIC -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_ATOMIC], -[ - AC_ARG_WITH([boost-atomic], - AS_HELP_STRING([--with-boost-atomic@<:@=special-lib@:>@], - [use the Atomic library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-atomic=boost_atomic-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_atomic_lib="" - else - want_boost="yes" - ax_boost_user_atomic_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Atomic library is available, - ax_cv_boost_atomic, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::atomic r; return 0;]])], - ax_cv_boost_atomic=yes, ax_cv_boost_atomic=no) - AC_LANG_POP([C++]) - ]) - - if test "x$ax_cv_boost_atomic" = "xyes"; then - AC_DEFINE(HAVE_BOOST_ATOMIC,,[define if the Boost::Atomic library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - if test "x$ax_boost_user_atomic_lib" = "x"; then - - for libextension in `ls $BOOSTLIBDIR/libboost_atomic*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_atomic.*\)\.so.*$;\1;' -e 's;^lib\(boost_atomic.*\)\.a*$;\1;' -e 's;^lib\(boost_atomic.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_ATOMIC_LIB="-l$ax_lib"; AC_SUBST(BOOST_ATOMIC_LIB) link_atomic="yes"; break], - [link_atomic="no"]) - done - - if test "x$link_atomic" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_atomic*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_atomic.*\)\.dll.*$;\1;' -e 's;^\(boost_atomic.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_ATOMIC_LIB="-l$ax_lib"; AC_SUBST(BOOST_ATOMIC_LIB) link_atomic="yes"; break], - [link_atomic="no"]) - done - fi - else - for ax_lib in $ax_boost_user_atomic_lib boost_atomic-$ax_boost_user_atomic_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_ATOMIC_LIB="-l$ax_lib"; AC_SUBST(BOOST_ATOMIC_LIB) link_atomic="yes"; break], - [link_atomic="no"]) - done - fi - - if test "x$link_atomic" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_base.m4 b/config/ax_boost_base.m4 deleted file mode 100644 index f4a2e086e89..00000000000 --- a/config/ax_boost_base.m4 +++ /dev/null @@ -1,290 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_base.html -# -# SYNOPSIS -# -# AX_BOOST_BASE([MINIMUM-VERSION]) -# -# DESCRIPTION -# -# Test for the Boost C++ libraries of a particular version (or newer) -# -# If no path to the installed boost library is given the macro -# searchs under /usr, /usr/local, /opt and /opt/local and evaluates -# the $BOOST_ROOT environment variable. Further documentation is -# available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) -# -# And sets: -# -# HAVE_BOOST -# -# COPYLEFT -# -# Copyright (c) 2008 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_BASE], -[ -AC_ARG_WITH([boost], - AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ac_boost_path="" - else - want_boost="yes" - ac_boost_path="$withval" - fi - ], - [want_boost="yes"]) - - -AC_ARG_WITH([boost-libdir], - AS_HELP_STRING([--with-boost-libdir=LIB_DIR], - [Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]), - [ - if test -d $withval - then - ac_boost_lib_path="$withval" - else - AC_MSG_ERROR([--with-boost-libdir expected directory name]) - fi - ], - [ac_boost_lib_path=""] -) - -if test "x$want_boost" = "xyes"; then - boost_lib_version_req=ifelse([$1], ,1.20.0,$1) - boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` - boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` - boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` - boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` - if test "x$boost_lib_version_req_sub_minor" = "x" ; then - boost_lib_version_req_sub_minor="0" - fi - WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` - AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req) - succeeded=no - - # DQ (2/4/2010): Added to support setting Automake conditionals for boost versions. - # export boost_lib_version_req_major - # export boost_lib_version_req_minor - # export boost_lib_version_req_sub_minor - - # echo "In ax boost base macro: boost_lib_version_req_major = $boost_lib_version_req_major" - # echo "In ax boost base macro: boost_lib_version_req_minor = $boost_lib_version_req_minor" - # echo "In ax boost base macro: boost_lib_version_req_sub_minor = $boost_lib_version_req_sub_minor" - - dnl first we check the system location for boost libraries - dnl this location ist chosen if boost libraries are installed with the --layout=system option - dnl or if you install boost with RPM - if test "$ac_boost_path" != ""; then - BOOST_LDFLAGS=" -L$ac_boost_path/lib" - BOOST_CPPFLAGS="-I$ac_boost_path/include" - ROSE_BOOST_INCLUDE_PATH="$ac_boost_path/include" - else - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib" - BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" - ROSE_BOOST_INCLUDE_PATH="$ac_boost_path_tmp/include" - break; - fi - done - fi - -# echo "WANT_BOOST_VERSION = $WANT_BOOST_VERSION" -# echo "boost_lib_version_req = $boost_lib_version_req" -# echo "BOOST_LDFLAGS = $BOOST_LDFLAGS" -# echo "BOOST_CPPFLAGS = $BOOST_CPPFLAGS" - -# DQ (1/1/2009): Set the default value based on BOOST_CPPFLAGS -# Liao (1/12/2009): ac_boost_path_tmp is one of the if's branches. -# Moved the assignment into the two branches above -# ROSE_BOOST_INCLUDE_PATH="$ac_boost_path_tmp/include" - - # DQ (1/1/2009): Added testing for previously installed Boost (always older version) - # so that we can trigger the use of "-isystem" option (to g++) only when required - # (it appears to be a problem for SWIG). - # Use this set of paths, and the set including "/home/dquinlan" for testing this macro. - # for ac_boost_path_tmp in /usr /usr/local /opt /opt/local /home/dquinlan; do - for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do - if test "x${ac_boost_path_tmp}/include" != "x${ROSE_BOOST_INCLUDE_PATH}" && test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then - PREVIOUSLY_INSTALLED_BOOST="$ac_boost_path_tmp/include/boost" - AC_MSG_WARN([detected a previously installed version of boost library: "$PREVIOUSLY_INSTALLED_BOOST"]) - break; - fi - done - - dnl overwrite ld flags if we have required special directory with - dnl --with-boost-libdir parameter - if test "$ac_boost_lib_path" != ""; then - BOOST_LDFLAGS="-L$ac_boost_lib_path" - fi - - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - succeeded=yes - found_system=yes - ],[ - ]) - AC_LANG_POP([C++]) - - dnl if we found no boost with system layout we search for boost libraries - dnl built and installed without the --layout=system option or for a staged(not installed) version - if test "x$succeeded" != "xyes"; then - _version=0 - if test "$ac_boost_path" != ""; then - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` - V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then - _version=$_version_tmp - fi - VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" - # DQ (12/22/2008): Modified macro to save the boost path so that it could be used with "-isystem" option (gcc). - ROSE_BOOST_INCLUDE_PATH="$ac_boost_path/include/boost-$VERSION_UNDERSCORE" - done - fi - else - for ac_boost_path in /usr /usr/local /opt /opt/local ; do - if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then - for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do - _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'` - V_CHECK=`expr $_version_tmp \> $_version` - if test "$V_CHECK" = "1" ; then - _version=$_version_tmp - best_path=$ac_boost_path - fi - done - fi - done - - VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` - BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" - if test "$ac_boost_lib_path" = "" - then - BOOST_LDFLAGS="-L$best_path/lib" - fi - - if test "x$BOOST_ROOT" != "x"; then - if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then - version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'` - stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'` - stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'` - V_CHECK=`expr $stage_version_shorten \>\= $_version` - if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then - AC_MSG_NOTICE([will use a staged boost library from $BOOST_ROOT]) - BOOST_CPPFLAGS="-I$BOOST_ROOT" - BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib" - fi - fi - fi - fi - - # DQ (12/22/2008): Fixup Boost to not use the system (OS) installation of Boost - # BOOST_CPPFLAGS="$BOOST_CPPFLAGS/boost" - - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= $WANT_BOOST_VERSION - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - succeeded=yes - found_system=yes - ],[ - ]) - AC_LANG_POP([C++]) - fi - - # DQ (2/4/2010): Added to get version information for what we are using. - AC_MSG_NOTICE([in boost base macro -- Boost version being used is: "$_version"]) - # rose_boost_version_number=$_version - # export rose_boost_version_number - - if test "$succeeded" != "yes" ; then - if test "$_version" = "0" ; then - # This was always a confusing error message so make it more explicit for users. - # AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in . See http://randspringer.de/boost for more documentation.]]) - AC_MSG_ERROR([Boost libraries (version $boost_lib_version_req_shorten or higher) must be specified on the configure line (using the --with-boost switch) and the boost libraries must be in your LD_LIBRARY_PATH]) - else - AC_MSG_FAILURE([your boost libraries seems to old (version $_version)]) - fi - else - AC_SUBST(BOOST_CPPFLAGS) - AC_SUBST(BOOST_LDFLAGS) - AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available]) - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" -fi - -# DQ (12/22/2008): Modified macro to save the boost path so that it could be used with "-isystem" -# option to include the boost path specified on the configure command ahead of "/usr/local/include" -# so that we can get the required version of Boost on systems that have it installed by default. -# echo "Final Test: ROSE_BOOST_INCLUDE_PATH = $ROSE_BOOST_INCLUDE_PATH" -# AC_SUBST(ROSE_BOOST_INCLUDE_PATH) - -# DQ (1/1/2009): This use of "-isystem" is not triggered only when there is -# a previously installed version of ROSE detected (e.g. in /usr/liclude/boost). -# Note that use of "-isystem" option with g++ will cause SWIG to fail. -if test "$PREVIOUSLY_INSTALLED_BOOST" != ""; then - # echo "Using the -isystem option of g++ to force the use of the specified version of Boost ahead of a previously installed version of boost on your system at: $PREVIOUSLY_INSTALLED_BOOST" - AC_MSG_NOTICE(using the -isystem option of g++ to force the use of the specified version of Boost ahead of a previously installed version of boost on your system at: $PREVIOUSLY_INSTALLED_BOOST) - AC_MSG_WARN([--with-javaport cannot be used with the -isystem option]) - ROSE_BOOST_PREINCLUDE_PATH="-isystem $ROSE_BOOST_INCLUDE_PATH" - ROSE_BOOST_NORMAL_INCLUDE_PATH="" - AC_MSG_WARN([detected previously installed version of boost (please remove older version of Boost before installing ROSE); continuing but expect Boost to be a problem]) - # AC_MSG_ERROR([[Detected previously installed version of boost (please remove older version of Boost before installing ROSE) (continuing but expect Boost to be a problem...)]]) - # Remove this exit (as a test) after detecting what I expect is a problem... - # exit 1 -else - AC_MSG_NOTICE(no previously installed version of boost detected: using boost include directories with normal -I option) - ROSE_BOOST_PREINCLUDE_PATH="" - ROSE_BOOST_NORMAL_INCLUDE_PATH="-I$ROSE_BOOST_INCLUDE_PATH" -fi - -AC_SUBST(ROSE_BOOST_PREINCLUDE_PATH) -AC_SUBST(ROSE_BOOST_NORMAL_INCLUDE_PATH) - - -]) diff --git a/config/ax_boost_chrono.m4 b/config/ax_boost_chrono.m4 deleted file mode 100644 index 619b4e8b29e..00000000000 --- a/config/ax_boost_chrono.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_CHRONO -# -# DESCRIPTION -# -# Test for Chrono library from the Boost C++ libraries. The macro requires -# a preceding call to AX_BOOST_BASE. Further documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_CHRONO_LIB) -# -# And sets: -# -# HAVE_BOOST_CHRONO -# -# LICENSE -# -# Copyright (c) 2012 Xiyue Deng -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 3 - -AC_DEFUN([AX_BOOST_CHRONO], -[ - AC_ARG_WITH([boost-chrono], - AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@], - [use the Chrono library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-chrono=boost_chrono-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_chrono_lib="" - else - want_boost="yes" - ax_boost_user_chrono_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - LIBS_SAVED="$LIBS" - LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_THREAD_LIB" - export LIBS - - AC_CACHE_CHECK(whether the Boost::Chrono library is available, - ax_cv_boost_chrono, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::chrono::system_clock::time_point time;]])], - ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_chrono" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_chrono_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - if test "x$link_chrono" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break], - [link_chrono="no"]) - done - - fi - if test "x$ax_lib" = "x"; then - AC_MSG_ERROR([could not find a version of the library]) - fi - if test "x$link_chrono" = "xno"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - LIBS="$LIBS_SAVED" - fi -]) diff --git a/config/ax_boost_date_time.m4 b/config/ax_boost_date_time.m4 deleted file mode 100644 index d93840f73ee..00000000000 --- a/config/ax_boost_date_time.m4 +++ /dev/null @@ -1,105 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_date_time.html -# -# SYNOPSIS -# -# AX_BOOST_DATE_TIME -# -# DESCRIPTION -# -# Test for Date_Time library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_DATE_TIME_LIB) -# -# And sets: -# -# HAVE_BOOST_DATE_TIME -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_DATE_TIME], -[ - AC_ARG_WITH([boost-date-time], - AS_HELP_STRING([--with-boost-date-time@<:@=special-lib@:>@], - [use the Date_Time library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-date-time=boost_date_time-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_date_time_lib="" - else - want_boost="yes" - ax_boost_user_date_time_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Date_Time library is available, - ax_cv_boost_date_time, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[using namespace boost::gregorian; date d(2002,Jan,10); - return 0; - ]])], - ax_cv_boost_date_time=yes, ax_cv_boost_date_time=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_date_time" = "xyes"; then - AC_DEFINE(HAVE_BOOST_DATE_TIME,,[define if the Boost::Date_Time library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_date_time_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_date_time*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_date_time.*\)\.so.*$;\1;' -e 's;^lib\(boost_date_time.*\)\.a*$;\1;' -e 's;^lib\(boost_date_time.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break], - [link_date_time="no"]) - done - if test "x$link_date_time" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_date_time*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_date_time.*\)\.dll.*$;\1;' -e 's;^\(boost_date_time.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break], - [link_date_time="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_date_time_lib boost_date_time-$ax_boost_user_date_time_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_DATE_TIME_LIB="-l$ax_lib"; AC_SUBST(BOOST_DATE_TIME_LIB) link_date_time="yes"; break], - [link_date_time="no"]) - done - - fi - if test "x$link_date_time" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_filesystem.m4 b/config/ax_boost_filesystem.m4 deleted file mode 100644 index 876db4b75e4..00000000000 --- a/config/ax_boost_filesystem.m4 +++ /dev/null @@ -1,112 +0,0 @@ -# =========================================================================== -# http://autoconf-archive.cryp.to/ax_boost_filesystem.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_BOOST_FILESYSTEM -# -# DESCRIPTION -# -# Test for Filesystem library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation is -# available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_FILESYSTEM_LIB) -# -# And sets: -# -# HAVE_BOOST_FILESYSTEM -# -# COPYLEFT -# -# Copyright (c) 2008 Thomas Porschberg -# Copyright (c) 2008 Michael Tindal -# Copyright (c) 2008 Roman Rybalko (using BOOST_SYSTEM_LIB) -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. - -AC_DEFUN([AX_BOOST_FILESYSTEM], -[ - AC_ARG_WITH([boost-filesystem], - AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@], - [use the Filesystem library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_filesystem_lib="" - else - want_boost="yes" - ax_boost_user_filesystem_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - LIBS_SAVED=$LIBS - LIBS="$LIBS $BOOST_SYSTEM_LIB" - export LIBS - - AC_CACHE_CHECK(whether the Boost::Filesystem library is available, - ax_cv_boost_filesystem, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[using namespace boost::filesystem; - path my_path( "foo/bar/data.txt" ); - return 0;]])], - ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_filesystem" = "xyes"; then - AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_filesystem_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_filesystem*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_filesystem.*\)\.so.*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.a*$;\1;' -e 's;^lib\(boost_filesystem.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], - [link_filesystem="no"]) - done - if test "x$link_program_options" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_filesystem*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_filesystem.*\)\.dll.*$;\1;' -e 's;^\(boost_filesystem.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], - [link_filesystem="no"]) - done - fi - else - for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break], - [link_filesystem="no"]) - done - - fi - if test "x$link_filesystem" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - LIBS="$LIBS_SAVED" - fi -]) diff --git a/config/ax_boost_iostreams.m4 b/config/ax_boost_iostreams.m4 deleted file mode 100644 index 9cfe0904694..00000000000 --- a/config/ax_boost_iostreams.m4 +++ /dev/null @@ -1,122 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_iostreams.html -# -# SYNOPSIS -# -# AX_BOOST_IOSTREAMS -# -# DESCRIPTION -# -# Test for IOStreams library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_IOSTREAMS_LIB) -# -# And sets: -# -# HAVE_BOOST_IOSTREAMS -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. -# -# MODIFIED -# Robb Matzke, 2015-01: fixed indentation -# Robb Matzke, 2015-01: fixed message about "library not found" when it's the headers that aren't found -# Robb Matzke, 2015-01: it is not an error for the iostreams library to be missing when headers are present -# Robb Matzke, 2015-01: replaced test .C file with mapped_file_params since that's what ROSE needs from iostreams - -AC_DEFUN([AX_BOOST_IOSTREAMS], -[ - AC_ARG_WITH([boost-iostreams], - AS_HELP_STRING([--with-boost-iostreams@<:@=special-lib@:>@], - [use the IOStreams library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-iostreams=boost_iostreams-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_iostreams_lib="" - else - want_boost="yes" - ax_boost_user_iostreams_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK([whether the boost::iostreams headers are available], - ax_cv_boost_iostreams, - [ - AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - @%:@include - ]], - [[ - boost::iostreams::mapped_file_params params; - boost::iostreams::mapped_file f(params); - f.const_data(); - return 0; - ]])], - ax_cv_boost_iostreams=yes, - ax_cv_boost_iostreams=no) - AC_LANG_POP([C++]) - ]) - - - if test "x$ax_cv_boost_iostreams" = "xyes"; then - AC_DEFINE(HAVE_BOOST_IOSTREAMS,,[define if the Boost::IOStreams library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_iostreams_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_iostreams*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_iostreams.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.a*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], - [link_iostreams="no"]) - done - - if test "x$link_iostreams" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_iostreams*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_iostreams.*\)\.dll.*$;\1;' -e 's;^\(boost_iostreams.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], - [link_iostreams="no"]) - done - fi - else - for ax_lib in $ax_boost_user_iostreams_lib boost_iostreams-$ax_boost_user_iostreams_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break], - [link_iostreams="no"]) - done - fi - - dnl Failing to link against libiostreams should not be an error here; perhaps at a higher level it is. - if test "x$link_iostreams" != "xyes"; then - AC_MSG_NOTICE([boost::iostreams headers are available, but not the library]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_program_options.m4 b/config/ax_boost_program_options.m4 deleted file mode 100644 index 8143e57ece7..00000000000 --- a/config/ax_boost_program_options.m4 +++ /dev/null @@ -1,101 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_program_options.html -# -# SYNOPSIS -# -# AX_BOOST_PROGRAM_OPTIONS -# -# DESCRIPTION -# -# Test for program options library from the Boost C++ libraries. The -# macro requires a preceding call to AX_BOOST_BASE. Further -# documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) -# -# And sets: -# -# HAVE_BOOST_PROGRAM_OPTIONS -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], -[ - AC_ARG_WITH([boost-program-options], - AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@], - [use the program options library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_program_options_lib="" - else - want_boost="yes" - ax_boost_user_program_options_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - export want_boost - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - AC_CACHE_CHECK([whether the Boost::Program_Options library is available], - ax_cv_boost_program_options, - [AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include - ]], - [[boost::program_options::options_description generic("Generic options"); - return 0;]])], - ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no) - AC_LANG_POP([C++]) - ]) - if test "$ax_cv_boost_program_options" = yes; then - AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_program_options_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;' -e 's;^lib\(boost_program_options.*\)\.a*$;\1;' -e 's;^lib\(boost_program_options.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], - [link_program_options="no"]) - done - if test "x$link_program_options" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_program_options*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.dll.*$;\1;' -e 's;^\(boost_program_options.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], - [link_program_options="no"]) - done - fi - else - for ax_lib in $ax_boost_user_program_options_lib boost_program_options-$ax_boost_user_program_options_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break], - [link_program_options="no"]) - done - fi - if test "x$link_program_options" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_python.m4 b/config/ax_boost_python.m4 deleted file mode 100644 index c2d56e65b1d..00000000000 --- a/config/ax_boost_python.m4 +++ /dev/null @@ -1,127 +0,0 @@ -# Copied and modified from ax_boost_chrono with ROSE-specific changes. -# -# SYNOPSIS -# -# AX_BOOST_PYTHON -# -# DESCRIPTION -# -# Test for Python library from the Boost C++ libraries. The macro requires -# a preceding call to AX_BOOST_BASE. Further documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_PYTHON_LIB) -# -# And sets: -# -# HAVE_BOOST_PYTHON -# -# LICENSE -# -# Copyright (c) 2012 Xiyue Deng -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 3 - -AC_DEFUN([AX_BOOST_PYTHON], -[ - AC_ARG_WITH([boost-python], - AS_HELP_STRING([--with-boost-python@<:@=special-lib@:>@], - [use the Python library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-python=boost_python-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_python_lib="" - else - want_boost="yes" - ax_boost_user_python_lib="$withval" - fi - ], - [want_boost="yes"]) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - LIBS_SAVED="$LIBS" - LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_THREAD_LIB" - export LIBS - - AC_CACHE_CHECK([whether the Boost::Python library is available], ax_cv_boost_python, - [ - AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[@%:@include ]], [[int dummy;]])], - ax_cv_boost_python=yes, - ax_cv_boost_python=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - - if test "x$ax_cv_boost_python" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_PYTHON,,[define if the Boost::Python library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_python_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_python*.so* $BOOSTLIBDIR/libboost_python*.dylib* $BOOSTLIBDIR/libboost_python*.a* 2>/dev/null |\ - sed 's,.*/,,' |\ - sed -e 's;^lib\(boost_python.*\)\.so.*$;\1;' -e 's;^lib\(boost_python.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_python.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_PYTHON_LIB="-l$ax_lib"; AC_SUBST(BOOST_PYTHON_LIB) link_python="yes"; break], - [link_python="no"]) - done - - if test "x$link_python" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_python*.dll* $BOOSTLIBDIR/boost_python*.a* 2>/dev/null |\ - sed 's,.*/,,' |\ - sed -e 's;^\(boost_python.*\)\.dll.*$;\1;' -e 's;^\(boost_python.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_PYTHON_LIB="-l$ax_lib"; AC_SUBST(BOOST_PYTHON_LIB) link_python="yes"; break], - [link_python="no"]) - done - fi - else - for ax_lib in $ax_boost_user_python_lib boost_python-$ax_boost_user_python_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_PYTHON_LIB="-l$ax_lib"; AC_SUBST(BOOST_PYTHON_LIB) link_python="yes"; break], - [link_python="no"]) - done - fi - - if test "x$ax_lib" = "x"; then - AC_MSG_ERROR([could not find a version of the library]) - fi - - if test "x$link_python" = "xno"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - LIBS="$LIBS_SAVED" - fi -]) diff --git a/config/ax_boost_random.m4 b/config/ax_boost_random.m4 deleted file mode 100644 index a8e1a33ee32..00000000000 --- a/config/ax_boost_random.m4 +++ /dev/null @@ -1,97 +0,0 @@ -# Cut-n-pasted from boost_chrono.m4 instead of downloading from the original -# location, in order to preserve any local bug fixes already applied by the -# ROSE team to the boost_chrono detection. All instances of "chrono" were -# then replaced by "random" (preserving capitalizations) and a single occurrence -# of "boost::chrono::system_clock::time_point time" was replaced by a suitable -# type from boost::random. - -AC_DEFUN([AX_BOOST_RANDOM], -[ - AC_ARG_WITH([boost-random], - AS_HELP_STRING([--with-boost-random@<:@=special-lib@:>@], - [use the Random library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-random=boost_random-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_random_lib="" - else - want_boost="yes" - ax_boost_user_random_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - LIBS_SAVED="$LIBS" - LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_THREAD_LIB" - export LIBS - - AC_CACHE_CHECK(whether the Boost::Random library is available, - ax_cv_boost_random, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::random::mt19937 rng;]])], - ax_cv_boost_random=yes, ax_cv_boost_random=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_random" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_RANDOM,,[define if the Boost::Random library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_random_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_random*.so* $BOOSTLIBDIR/libboost_random*.dylib* $BOOSTLIBDIR/libboost_random*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_random.*\)\.so.*$;\1;' -e 's;^lib\(boost_random.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_random.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], - [link_random="no"]) - done - if test "x$link_random" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_random*.dll* $BOOSTLIBDIR/boost_random*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_random.*\)\.dll.*$;\1;' -e 's;^\(boost_random.*\)\.a.*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], - [link_random="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_random_lib boost_random-$ax_boost_user_random_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_RANDOM_LIB="-l$ax_lib"; AC_SUBST(BOOST_RANDOM_LIB) link_random="yes"; break], - [link_random="no"]) - done - - fi - if test "x$ax_lib" = "x"; then - AC_MSG_ERROR([could not find a version of the library]) - fi - if test "x$link_random" = "xno"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - LIBS="$LIBS_SAVED" - fi -]) diff --git a/config/ax_boost_regex.m4 b/config/ax_boost_regex.m4 deleted file mode 100644 index 9a44203cfeb..00000000000 --- a/config/ax_boost_regex.m4 +++ /dev/null @@ -1,106 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_regex.html -# -# SYNOPSIS -# -# AX_BOOST_REGEX -# -# DESCRIPTION -# -# Test for Regex library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_REGEX_LIB) -# -# And sets: -# -# HAVE_BOOST_REGEX -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_REGEX], -[ - AC_ARG_WITH([boost-regex], - AS_HELP_STRING([--with-boost-regex@<:@=special-lib@:>@], - [use the Regex library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-regex=boost_regex-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_regex_lib="" - else - want_boost="yes" - ax_boost_user_regex_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Regex library is available, - ax_cv_boost_regex, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::regex r(); return 0;]])], - ax_cv_boost_regex=yes, ax_cv_boost_regex=no) - AC_LANG_POP([C++]) - ]) - - if test "x$ax_cv_boost_regex" = "xyes"; then - AC_DEFINE(HAVE_BOOST_REGEX,,[define if the Boost::Regex library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - if test "x$ax_boost_user_regex_lib" = "x"; then - - for libextension in `ls $BOOSTLIBDIR/libboost_regex*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_regex.*\)\.so.*$;\1;' -e 's;^lib\(boost_regex.*\)\.a*$;\1;' -e 's;^lib\(boost_regex.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_REGEX_LIB="-l$ax_lib"; AC_SUBST(BOOST_REGEX_LIB) link_regex="yes"; break], - [link_regex="no"]) - done - - if test "x$link_regex" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_regex*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_regex.*\)\.dll.*$;\1;' -e 's;^\(boost_regex.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_REGEX_LIB="-l$ax_lib"; AC_SUBST(BOOST_REGEX_LIB) link_regex="yes"; break], - [link_regex="no"]) - done - fi - else - for ax_lib in $ax_boost_user_regex_lib boost_regex-$ax_boost_user_regex_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_REGEX_LIB="-l$ax_lib"; AC_SUBST(BOOST_REGEX_LIB) link_regex="yes"; break], - [link_regex="no"]) - done - fi - - if test "x$link_regex" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_signals.m4 b/config/ax_boost_signals.m4 deleted file mode 100644 index ef1dd4a24bd..00000000000 --- a/config/ax_boost_signals.m4 +++ /dev/null @@ -1,106 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_signals.html -# -# SYNOPSIS -# -# AX_BOOST_SIGNALS -# -# DESCRIPTION -# -# Test for Signals library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_SIGNALS_LIB) -# -# And sets: -# -# HAVE_BOOST_SIGNALS -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_SIGNALS], -[ - AC_ARG_WITH([boost-signals], - AS_HELP_STRING([--with-boost-signals@<:@=special-lib@:>@], - [use the Signals library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-signals=boost_signals-gcc-mt-d ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_signals_lib="" - else - want_boost="yes" - ax_boost_user_signals_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Signals library is available, - ax_cv_boost_signals, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include - ]], - [[boost::signal sig; - return 0; - ]]), - ax_cv_boost_signals=yes, ax_cv_boost_signals=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_signals" = "xyes"; then - AC_DEFINE(HAVE_BOOST_SIGNALS,,[define if the Boost::Signals library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_signals_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_signals*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_signals.*\)\.so.*$;\1;' -e 's;^lib\(boost_signals.*\)\.a*$;\1;' -e 's;^lib\(boost_signals.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break], - [link_signals="no"]) - done - if test "x$link_signals" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_signals*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_signals.*\)\.dll.*$;\1;' -e 's;^\(boost_signals.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break], - [link_signals="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_signals_lib boost_signals-$ax_boost_user_signals_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_SIGNALS_LIB="-l$ax_lib"; AC_SUBST(BOOST_SIGNALS_LIB) link_signals="yes"; break], - [link_signals="no"]) - done - - fi - if test "x$link_signals" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_system.m4 b/config/ax_boost_system.m4 deleted file mode 100644 index b5f2f41061d..00000000000 --- a/config/ax_boost_system.m4 +++ /dev/null @@ -1,114 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_system.html -# -# SYNOPSIS -# -# AX_BOOST_SYSTEM -# -# DESCRIPTION -# -# Test for System library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_SYSTEM_LIB) -# -# And sets: -# -# HAVE_BOOST_SYSTEM -# -# COPYLEFT -# -# Copyright (c) 2008 Thomas Porschberg -# Copyright (c) 2008 Michael Tindal -# Copyright (c) 2008 Daniel Casimiro -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_SYSTEM], -[ - AC_BEFORE([$0], [AX_BOOST_THREAD]) - - AC_ARG_WITH([boost-system], - AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@], - [use the System library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-system=boost_system-gcc-mt ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_system_lib="" - else - want_boost="yes" - ax_boost_user_system_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::System library is available, - ax_cv_boost_system, - [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::system::system_category]])], - ax_cv_boost_system=yes, ax_cv_boost_system=no) - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_system" = "xyes"; then - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - if test "x$ax_boost_user_system_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_system*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_system.*\)\.so.*$;\1;' -e 's;^lib\(boost_system.*\)\.a*$;\1;' -e 's;^lib\(boost_system.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], - [link_system="no"]) - done - if test "x$link_system" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_system*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_system.*\)\.dll.*$;\1;' -e 's;^\(boost_system.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], - [link_system="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break], - [link_system="no"]) - done - - fi - if test "x$link_system" = "xno"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - AC_DEFINE([USE_ROSE_BOOST_WAVE_SUPPORT],1,[Controls use of BOOST WAVE support in ROSE.]) - fi - fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_test_exec_monitor.m4 b/config/ax_boost_test_exec_monitor.m4 deleted file mode 100644 index cd4293ea5dd..00000000000 --- a/config/ax_boost_test_exec_monitor.m4 +++ /dev/null @@ -1,132 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_test_exec_monitor.html -# -# SYNOPSIS -# -# AX_BOOST_TEST_EXEC_MONITOR -# -# DESCRIPTION -# -# Test for Test_Exec_Monitor library from the Boost C++ libraries. -# The macro requires a preceding call to AX_BOOST_BASE. Further -# documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB) -# -# And sets: -# -# HAVE_BOOST_TEST_EXEC_MONITOR -# -# COPYLEFT -# -# Copyright (c) 2007 Dodji Seketeli -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_TEST_EXEC_MONITOR], -[ - AC_ARG_WITH([boost-test-exec-monitor], - AS_HELP_STRING([--with-boost-test-exec-monitor@<:@=special-lib@:>@], - [use the Test_Exec_Monitor library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-test-exec-monitor=boost_test_exec_monitor-gcc ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_test_exec_monitor_lib="" - else - want_boost="yes" - ax_boost_user_test_exec_monitor_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Test_Exec_Monitor library is available, - ax_cv_boost_test_exec_monitor, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include ]], - [[int i=1 ; BOOST_REQUIRE(i==1); ; return 0;]]), - ax_cv_boost_test_exec_monitor=yes, ax_cv_boost_test_exec_monitor=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_test_exec_monitor" = "xyes"; then - AC_DEFINE(HAVE_BOOST_TEST_EXEC_MONITOR,,[define if the Boost::Test_Exec_Monitor library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - if test "x$ax_boost_user_test_exec_monitor_lib" = "x"; then - saved_ldflags="${LDFLAGS}" - - for monitor_library in `ls $BOOSTLIBDIR/libboost_test_exec_monitor*.{so,dylib,a}* 2>/dev/null` ; do - if test -r $monitor_library ; then - libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_test_exec_monitor.*\)\.so.*$;\1;' -e 's;^lib\(boost_test_exec_monitor.*\)\.a*$;\1;' -e 's;^lib\(boost_test_exec_monitor.*\)\.dylib$;\1;'` - ax_lib=${libextension} - link_test_exec_monitor="yes" - else - link_test_exec_monitor="no" - fi - - if test "x$link_test_exec_monitor" = "xyes"; then - BOOST_TEST_EXEC_MONITOR_LIB="-l$ax_lib" - AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB) - break - fi - done - if test "x$link_test_exec_monitor" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_test_exec_monitor*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_test_exec_monitor.*\)\.dll.*$;\1;' -e 's;^\(boost_test_exec_monitor.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_TEST_EXEC_MONITOR_LIB="-l$ax_lib"; AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB) link_test_exec_monitor="yes"; break], - [link_test_exec_monitor="no"]) - done - fi - - else - link_test_exec_monitor="no" - saved_ldflags="${LDFLAGS}" - for ax_lib in boost_test_exec_monitor-$ax_boost_user_test_exec_monitor_lib $ax_boost_user_test_exec_monitor_lib ; do - if test "x$link_test_exec_monitor" = "xyes"; then - break; - fi - for monitor_library in `ls $BOOSTLIBDIR/lib${ax_lib}.{so,dylib,a}* 2>/dev/null` ; do - if test -r $monitor_library ; then - libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_test_exec_monitor.*\)\.so.*$;\1;' -e 's;^lib\(boost_test_exec_monitor.*\)\.a*$;\1;' -e 's;^lib\(boost_test_exec_monitor.*\)\.dylib$;\1;'` - ax_lib=${libextension} - link_test_exec_monitor="yes" - else - link_test_exec_monitor="no" - fi - - if test "x$link_test_exec_monitor" = "xyes"; then - BOOST_TEST_EXEC_MONITOR_LIB="-l$ax_lib" - AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB) - break - fi - done - done - fi - if test "x$link_test_exec_monitor" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_thread.m4 b/config/ax_boost_thread.m4 deleted file mode 100644 index 230af2cbb46..00000000000 --- a/config/ax_boost_thread.m4 +++ /dev/null @@ -1,148 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_thread.html -# -# SYNOPSIS -# -# AX_BOOST_THREAD -# -# DESCRIPTION -# -# Test for Thread library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_THREAD_LIB) -# -# And sets: -# -# HAVE_BOOST_THREAD -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_THREAD], -[ - AC_ARG_WITH([boost-thread], - AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], - [Use the Thread library from Boost. If the value is 'yes' or a certain library then ROSE will - incorporate multi-thread support into some of its algorithms. The default is to incorporate - multi-thread support into ROSE algorithms since Boost is compiled with thread support by default. - If thread support is enabled then user code should also be compiled and linked with switches - appropriate for multi-threading e.g., -pthread for GCC. If the user compiles Boost without - thread support, then --without-boost-thread can be given on the ROSE configure commandline. ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_thread_lib="" - else - want_boost="yes" - ax_boost_user_thread_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the boost/thread/thread.hpp header is available, - ax_cv_boost_thread, - [ - AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS - - case "$build_os" in - solaris ) CXXFLAGS="-pthreads $CXXFLAGS" ;; - ming32 ) CXXFLAGS="-mthreads $CXXFLAGS" ;; - # DQ (12/6/2016): Added pthread option since it appears that the default installation of Boost used pthread library. - # Note that their is no "s" on the -pthread option for Clang or GNU g++. - # Note that since boost appears to not be compiled on OSX with threading enabled, we don't want to specify -pthread option to the compiler. - # darwin* ) CXXFLAGS="$CXXFLAGS" ;; - # darwin* ) CXXFLAGS="-pthread $CXXFLAGS" ;; - darwin* ) CXXFLAGS="$CXXFLAGS" ;; - * ) CXXFLAGS="-pthread $CXXFLAGS" ;; - esac - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[@%:@include ]], - [[boost::thread_group thrds; - return 0;]])], - ax_cv_boost_thread=yes, - ax_cv_boost_thread=no) - - CXXFLAGS=$CXXFLAGS_SAVE - AC_LANG_POP([C++]) - ]) - - if test "x$ax_cv_boost_thread" = "xyes"; then - AC_MSG_NOTICE([boost thread header found; checking for library...]) - case "$build_os" in - solaris ) BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" ;; - ming32 ) BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" ;; - darwin* ) BOOST_CPPFLAGS="$BOOST_CPPFLAGS" ;; - * ) BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" ;; - esac - - AC_SUBST(BOOST_CPPFLAGS) - - AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - LDFLAGS_SAVE=$LDFLAGS - case "x$build_os" in - *bsd* ) LDFLAGS="-pthread $LDFLAGS" ;; - esac - if test "x$ax_boost_user_thread_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_thread*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_thread.*\)\.so.*$;\1;' -e 's;^lib\(boost_thread.*\)\.a*$;\1;' -e 's;^lib\(boost_thread.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"], [${BOOST_SYSTEM_LIB}]) - done - if test "x$link_thread" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_thread*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_thread.*\)\.dll.*$;\1;' -e 's;^\(boost_thread.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"], [${BOOST_SYSTEM_LIB}]) - done - fi - else - for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], - [link_thread="no"], [${BOOST_SYSTEM_LIB}]) - done - fi - - if test "x$link_thread" != "xyes"; then - AC_MSG_ERROR([could not link against -lboost_thread; ROSE requires this library in "$BOOSTLIBDIR"]) - else - case "x$build_os" in - *bsd* ) BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" ;; - *linux-gnu*) BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" ;; - esac - AC_MSG_RESULT([boost thread library found: $BOOST_LDFLAGS]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_unit_test_framework.m4 b/config/ax_boost_unit_test_framework.m4 deleted file mode 100644 index a1add1657e9..00000000000 --- a/config/ax_boost_unit_test_framework.m4 +++ /dev/null @@ -1,130 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_unit_test_framework.html -# -# SYNOPSIS -# -# AX_BOOST_UNIT_TEST_FRAMEWORK -# -# DESCRIPTION -# -# Test for Unit_Test_Framework library from the Boost C++ libraries. -# The macro requires a preceding call to AX_BOOST_BASE. Further -# documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) -# -# And sets: -# -# HAVE_BOOST_UNIT_TEST_FRAMEWORK -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], -[ - AC_ARG_WITH([boost-unit-test-framework], - AS_HELP_STRING([--with-boost-unit-test-framework@<:@=special-lib@:>@], - [use the Unit_Test_Framework library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-unit-test-framework=boost_unit_test_framework-gcc ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_unit_test_framework_lib="" - else - want_boost="yes" - ax_boost_user_unit_test_framework_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::Unit_Test_Framework library is available, - ax_cv_boost_unit_test_framework, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include ]], - [[using boost::unit_test::test_suite; - test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); return 0;]]), - ax_cv_boost_unit_test_framework=yes, ax_cv_boost_unit_test_framework=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_unit_test_framework" = "xyes"; then - AC_DEFINE(HAVE_BOOST_UNIT_TEST_FRAMEWORK,,[define if the Boost::Unit_Test_Framework library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - - if test "x$ax_boost_user_unit_test_framework_lib" = "x"; then - saved_ldflags="${LDFLAGS}" - for monitor_library in `ls $BOOSTLIBDIR/libboost_unit_test_framework*.{so,dylib,a}* 2>/dev/null` ; do - if test -r $monitor_library ; then - libextension=`echo $monitor_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib$;\1;'` - ax_lib=${libextension} - link_unit_test_framework="yes" - else - link_unit_test_framework="no" - fi - - if test "x$link_unit_test_framework" = "xyes"; then - BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" - AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) - break - fi - done - if test "x$link_unit_test_framework" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_unit_test_framework*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_unit_test_framework.*\)\.dll.*$;\1;' -e 's;^\(boost_unit_test_framework.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"; AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) link_unit_test_framework="yes"; break], - [link_unit_test_framework="no"]) - done - fi - else - link_unit_test_framework="no" - saved_ldflags="${LDFLAGS}" - for ax_lib in boost_unit_test_framework-$ax_boost_user_unit_test_framework_lib $ax_boost_user_unit_test_framework_lib ; do - if test "x$link_unit_test_framework" = "xyes"; then - break; - fi - for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.{so,dylib,a}* 2>/dev/null` ; do - if test -r $unittest_library ; then - libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.dylib$;\1;'` - ax_lib=${libextension} - link_unit_test_framework="yes" - else - link_unit_test_framework="no" - fi - - if test "x$link_unit_test_framework" = "xyes"; then - BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" - AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) - break - fi - done - done - fi - if test "x$link_unit_test_framework" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_boost_wave.m4 b/config/ax_boost_wave.m4 deleted file mode 100644 index 4473ea8bee8..00000000000 --- a/config/ax_boost_wave.m4 +++ /dev/null @@ -1,119 +0,0 @@ - http://autoconf-archive.cryp.to/ax_boost_regex.html -# -# SYNOPSIS -# -# AX_BOOST_WAVE -# -# DESCRIPTION -# -# Test for Wave library from the Boost C++ libraries. The macro -# requires a preceding call to AX_BOOST_BASE. Further documentation -# is available at . -# -# This macro calls: -# -# AC_SUBST(BOOST_WAVE_LIB) -# -# And sets: -# -# HAVE_BOOST_WAVE -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# Copyright (c) 2007 Michael Tindal -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_WAVE], -[ - AC_ARG_WITH([boost-wave], - AS_HELP_STRING([--with-boost-wave@<:@=special-lib@:>@], - [use the Wave library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-wave=boost_wave-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_wave_lib="" - else - want_boost="yes" - ax_boost_user_wave_lib="$withval" - fi - ], - [want_boost="yes"] - ) - AM_CONDITIONAL(ROSE_USE_BOOST_WAVE, test "x$want_boost" = "xyes" ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - LIBS_SAVED=$LIBS - LIBS="$LIBS $BOOST_SYSTEM_LIB $BOOST_THREAD_LIB" - export LIBS - - AC_CACHE_CHECK(whether the Boost::Wave library is available, - ax_cv_boost_wave, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include - ]], - [[boost::wave::token_category r; return 0;]])], - ax_cv_boost_wave=yes, ax_cv_boost_wave=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_wave" = "xyes"; then - - AC_DEFINE(HAVE_BOOST_WAVE,,[define if the Boost::Wave library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_wave_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_wave*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_wave.*\)\.so.*$;\1;' -e 's;^lib\(boost_wave.*\)\.a*$;\1;' -e 's;^lib\(boost_wave.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_WAVE_LIB="-l$ax_lib"; AC_SUBST(BOOST_WAVE_LIB) link_wave="yes"; break], - [link_wave="no"]) - done - if test "x$link_wave" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_wave*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_wave.*\)\.dll.*$;\1;' -e 's;^\(boost_wave.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_WAVE_LIB="-l$ax_lib"; AC_SUBST(BOOST_WAVE_LIB) link_wave="yes"; break], - [link_wave="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_wave_lib boost_wave-$ax_boost_user_wave_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_WAVE_LIB="-l$ax_lib"; AC_SUBST(BOOST_WAVE_LIB) link_wave="yes"; break], - [link_wave="no"]) - done - fi - if test "x$link_wave" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - # DQ (4/7/2006): build a macro to use in source code to know when WAVE is to be used. - AC_DEFINE([USE_ROSE_BOOST_WAVE_SUPPORT],1,[Controls use of BOOST WAVE support in ROSE.]) - - else - AC_DEFINE([USE_ROSE_BOOST_WAVE_SUPPORT],0,[Controls use of BOOST WAVE support in ROSE.]) - - fi - - - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - LIBS="$LIBS_SAVED" - - fi -]) diff --git a/config/ax_boost_wserialization.m4 b/config/ax_boost_wserialization.m4 deleted file mode 100644 index 48f232d409f..00000000000 --- a/config/ax_boost_wserialization.m4 +++ /dev/null @@ -1,109 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_boost_wserialization.html -# -# SYNOPSIS -# -# AX_BOOST_WSERIALIZATION -# -# DESCRIPTION -# -# Test for Serialization library from the Boost C++ libraries. The -# macro requires a preceding call to AX_BOOST_BASE. Further -# documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(BOOST_WSERIALIZATION_LIB) -# -# And sets: -# -# HAVE_BOOST_WSERIALIZATION -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_BOOST_WSERIALIZATION], -[ - AC_ARG_WITH([boost-wserialization], - AS_HELP_STRING([--with-boost-wserialization@<:@=special-lib@:>@], - [use the WSerialization library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-wserialization=boost_wserialization-gcc-mt-d-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then - want_boost="yes" - ax_boost_user_wserialization_lib="" - else - want_boost="yes" - ax_boost_user_wserialization_lib="$withval" - fi - ], - [want_boost="yes"] - ) - - if test "x$want_boost" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS - - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS - - AC_CACHE_CHECK(whether the Boost::WSerialization library is available, - ax_cv_boost_wserialization, - [AC_LANG_PUSH([C++]) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include - @%:@include - @%:@include - ]], - [[std::ofstream ofs("filename"); - boost::archive::text_oarchive oa(ofs); - return 0; - ]]), - ax_cv_boost_wserialization=yes, ax_cv_boost_wserialization=no) - AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_wserialization" = "xyes"; then - AC_DEFINE(HAVE_BOOST_WSERIALIZATION,,[define if the Boost::WSerialization library is available]) - BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_boost_user_wserialization_lib" = "x"; then - for libextension in `ls $BOOSTLIBDIR/libboost_wserialization*.{so,dylib,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_wserialization.*\)\.so.*$;\1;' -e 's;^lib\(boost_wserialization.*\)\.a*$;\1;' -e 's;^lib\(boost_wserialization.*\)\.dylib$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_WSERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_WSERIALIZATION_LIB) link_wserialization="yes"; break], - [link_wserialization="no"]) - done - if test "x$link_wserialization" != "xyes"; then - for libextension in `ls $BOOSTLIBDIR/boost_wserialization*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_wserialization.*\)\.dll.*$;\1;' -e 's;^\(boost_wserialization.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, toupper, - [BOOST_WSERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_WSERIALIZATION_LIB) link_wserialization="yes"; break], - [link_wserialization="no"]) - done - fi - - else - for ax_lib in $ax_boost_user_wserialization_lib boost_wserialization-$ax_boost_user_wserialization_lib; do - AC_CHECK_LIB($ax_lib, main, - [BOOST_WSERIALIZATION_LIB="-l$ax_lib"; AC_SUBST(BOOST_WSERIALIZATION_LIB) link_wserialization="yes"; break], - [link_wserialization="no"]) - done - - fi - if test "x$link_wserialization" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/ax_rose_lib.m4 b/config/ax_rose_lib.m4 deleted file mode 100644 index 21924602e03..00000000000 --- a/config/ax_rose_lib.m4 +++ /dev/null @@ -1,100 +0,0 @@ -##### http://autoconf-archive.cryp.to/ax_rose.html -# -# SYNOPSIS -# -# AX_ROSE_LIB -# -# DESCRIPTION -# -# Test for program options library from the Boost C++ libraries. The -# macro requires a preceding call to AX_ROSE_LIB_BASE. Further -# documentation is available at -# . -# -# This macro calls: -# -# AC_SUBST(ROSE_LIB) -# -# And sets: -# -# HAVE_ROSE -# -# COPYLEFT -# -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([AX_ROSE_LIB], -[ - AC_ARG_WITH([rose-lib], - AS_HELP_STRING([--with-rose-lib@<:@=special-lib@:>@], - [use the program options library from rose - it is possible to specify a certain library for the linker - e.g. --with-rose-lib=rose-gcc-mt-1_33_1 ]), - [ - if test "$withval" = "no"; then - want_rose="no" - elif test "$withval" = "yes"; then - want_rose="yes" - ax_rose_user_lib="" - else - want_rose="yes" - ax_rose_user_lib="$withval" - fi - ], - [want_rose="yes"] - ) - - if test "x$want_rose" = "xyes"; then - AC_REQUIRE([AC_PROG_CC]) - export want_rose - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $ROSE_CPPFLAGS $BOOST_CPPFLAGS " - export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $ROSE_LDFLAGS $BOOST_LDFLAGS " - export LDFLAGS - AC_CACHE_CHECK([whether the Boost::Program_Options library is available], - ax_cv_rose, - [AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include - ]], - [[ return 0;]]), - ax_cv_rose=yes, ax_cv_rose=no) - AC_LANG_POP([C++]) - ]) - if test "$ax_cv_rose" = yes; then - AC_DEFINE(HAVE_ROSE,,[define if the Boost::PROGRAM_OPTIONS library is available]) - ROSELIBDIR=`echo $ROSE_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - if test "x$ax_rose_user_lib" = "x"; then - for libextension in `ls $ROSELIBDIR/librose*.{so,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(rose.*\)\.so.*$;\1;' -e 's;^lib\(rose.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [ROSE_LIB="-l$ax_lib"; AC_SUBST(ROSE_LIB) link="yes"; break], - [link="no"]) - done - if test "x$link" != "xyes"; then - for libextension in `ls $ROSELIBDIR/rose*.{dll,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(rose.*\)\.dll.*$;\1;' -e 's;^\(rose.*\)\.a*$;\1;'` ; do - ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [ROSE_LIB="-l$ax_lib"; AC_SUBST(ROSE_LIB) link="yes"; break], - [link="no"]) - done - fi - else - for ax_lib in $ax_rose_user_lib rose-$ax_rose_user_lib; do - AC_CHECK_LIB($ax_lib, main, - [ROSE_LIB="-l$ax_lib"; AC_SUBST(ROSE_LIB) link="yes"; break], - [link="no"]) - done - fi - if test "x$link" != "xyes"; then - AC_MSG_ERROR([could not link against "$ax_lib"]) - fi - fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi -]) diff --git a/config/support-blacklist.m4 b/config/support-blacklist.m4 deleted file mode 100644 index a1ff8faf1de..00000000000 --- a/config/support-blacklist.m4 +++ /dev/null @@ -1,123 +0,0 @@ -# Support for gracefully bailing out of configure for certain combinations of dependency versions -# or other situations. - -AC_DEFUN([ROSE_SUPPORT_BLACKLIST],[ - prohibited= - - # ----------------------- - # Versions we HAVE - # ----------------------- - - # Debugging blacklists... Spit out the values that will be needed by users when they're - # trying to figure out why their configuration is blacklisted. These are the versions they - # HAVE. The versions that are PROHIBITED will be emitted later in this function. The version - # number variables should be set wherever we're detecting the dependency, not here. - - # ----------------------- - # Versions we PROHIBIT - # ----------------------- - - ROSE_CONFIGURE_SECTION([Checking blacklisted configurations]) - while true; do - # Boost 1.54 has numerous bugs related to threads. These manifest themselves as compile errors in - # the first ROSE source that happens to include boost thread support, usually something in the - # src/util/Sawyer directory. - if test "$rose_boost_version" = 105400 -a \ - "$FRONTEND_CXX_COMPILER_VENDOR" = "gnu" -a \ - "$FRONTEND_CXX_VERSION_MAJOR" = 4 -a \ - "$FRONTEND_CXX_VERSION_MINOR" -ge 8; then - prohibited="boost 1.54 with gcc >= 4.8 and gcc < 5" - break - fi - - # Boost-1.60.0 serialization cannot be compiled with GCC-6.1.0 because of ambiguous destructors. Also, when - # optimizations are disabled and assertions are enabled, the assembler ("as") takes about an hour to compile - # src/Rose/BinaryAnalysis/SerialIo.C on a fast machine (this is true of boost-1.61 with GCC-6.1.0 as well). - if test "$support_binaries_frontend" = yes -a \ - "$rose_boost_version" = 106000 -a \ - "$FRONTEND_CXX_COMPILER_VENDOR" = gnu -a \ - "$FRONTEND_CXX_VERSION_MAJOR" = 6 -a \ - "$FRONTEND_CXX_VERSION_MINOR" = 1; then - prohibited="binary analysis enabled with boost 1.60.x and GCC 6.1.x" - break - fi - - # Boost-1.61 through 1.63 serialization cause link errors when compiled by Intel compilers. Binary analysis - # is the only thing that uses serialization at this time. - if test "$rose_boost_version" -ge 106100 -a "$rose_boost_version" -le 106300 -a \ - "$FRONTEND_CXX_COMPILER_VENDOR" = "intel" -a \ - "$support_binaries_frontend" = "yes"; then - prohibited="binary analysis enabled with boost 1.61 through 1.63 with Intel compiler" - break - fi - - # Boost-1.65.x have segmentation faults in the destructors of some serialization static objects within the Boost - # library. I thought this was just for GCC 4 and 5, but after enabling wider testing, we're also getting the - # segmentation faults with GCC 7 and 8. Therefore, this version of boost is blacklisted if binary analysis - # support is enabled. - if test "$rose_boost_version" = 106500 -o "$rose_boost_version" = 106501; then - if test "$support_binaries_frontend" = yes -a "$FRONTEND_CXX_COMPILER_VENDOR" = gnu ; then - prohibited="binary analysis enabled with boost 1.65 with GCC compiler" - break - fi - fi - - # Boost-1.68.0 has serialization bugs reported by numerous other projects. Within ROSE, 1.68.0 fails the - # basic boost serialization tests that we've written. These tests don't depend on ROSE, rather link only - # with boost. - if test "$rose_boost_version" = 106800; then - prohibited="boost-1.68.0" - break - fi - - # Boost versions prior to 1.68.0 do not work with C++17 and GNU++17 compilers. They experience compiler - # errors when a program tries to use the two-argument version of boost::lock, which is needed by ROSE for - # thread synchronization. - if test "$rose_boost_version" -le 106800; then - if test "$HOST_CXX_LANGUAGE" = "c++17" -o "$HOST_CXX_LANGUAGE" = "gnu++17"; then - prohibited="boost-$rose_boost_version with $HOST_CXX_LANGUAGE (problems with boost::lock)" - break - fi - fi - - # Z3 4.7.1 is blacklisted because it introduced an API change without any easy way to detect the change - # at compile time. - if test "$Z3_VERSION" = "4.7.1.0"; then - prohibited="z3-4.7.1" - break - fi - - # Add more blacklist items right above this line with comments like the others. If you detect - # a combination that's blacklisted, then set the "prohibited" string to say what is blacklisted - # and then break out of the loop to avoid testing other combinations. - : whatever tests you like - - # If we made it this far then this combination is not blacklisted - prohibited= - break - done - - # ----------------------- - # Output results - # ----------------------- - AC_ARG_ENABLE([blacklist], - AS_HELP_STRING([--disable-blacklist], - [Disabling the blacklist check causes blacklist related messages to become non-fatal. - The default --enable-blacklist, means trying to use a blacklisted configuration is fatal.]), - [should_die="$enableval"], [should_die=yes]) - - if test "$prohibited" != ""; then - if test "$should_die" != no; then - AC_MSG_FAILURE([blacklisted: $prohibited - The above combination of ROSE software dependencies is blacklisted. The ROSE - team occassionally blacklists combinations that are known to cause failures in - perhaps subtle ways. If you would like to continue with this configuration at your - own risk, then reconfigure with --disable-blacklist. (This message comes from - config/support-blacklist.m4, which also contains more information about the reason - for blacklisting.)]) - else - AC_MSG_WARN([blacklisted: $prohibited]) - AC_MSG_WARN([ continuing with unsafe configuration at user's request (--disable-blacklist)]) - fi - fi -]) diff --git a/config/support-boost.m4 b/config/support-boost.m4 deleted file mode 100644 index 39e89097d6f..00000000000 --- a/config/support-boost.m4 +++ /dev/null @@ -1,198 +0,0 @@ -##### http://www.rosecompiler.org -# -# SYNOPSIS -# -# ROSE_SUPPORT_BOOST([]) -# -# DESCRIPTION -# -# Handle Boost C++ Library settings. -# -# This macro calls: -# -# AC_SUBST(ac_boost_path) -# -# And sets: -# -# Automake conditionals: -# AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_X_XX) -# -# CPP #defines: -# AC_DEFINE_UNQUOTED(ROSE_BOOST_PATH) -# AC_DEFINE_UNQUOTED(ROSE_WAVE_PATH) -# -# COPYLEFT -# -# Copyright (c) 2013 Justin Too -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN([ROSE_SUPPORT_BOOST], -[ - ROSE_CONFIGURE_SECTION([Checking Boost]) - - - #============================================================================ - # --enable-boost-version-check - #============================================================================ - ROSE_ARG_ENABLE( - [boost-version-check], - [if we should validate your Boost version], - [validate version of Boost C++ libraries (default: yes)], - [yes] - ) - -AX_BOOST_BASE([1.51.0], [], [echo "Boost 1.51.0 - 1.61.0 except 1.54 is required for ROSE" 1>&2; exit 1]) - -dnl Hack using an internal variable from AX_BOOST_BASE -- this path should only -dnl be used to set --with-boost in distcheck. -AC_SUBST(ac_boost_path) - -BOOST_VERSION_HEADER="${ac_boost_path}/include/boost/version.hpp" - -# Liao, 2019/3/12. Check file existence before calling grep -if test -f "$BOOST_VERSION_HEADER" ; then - rose_boost_version=`grep "#define BOOST_VERSION " ${ac_boost_path}/include/boost/version.hpp | cut -d" " -f 3 | tr -d '\r'` -else - ROSE_MSG_ERROR([Unable to find $ac_boost_path/include/boost/version.hpp . Please specify the right boost installation path with --with-boost=/path/to/boost]) -fi - -AC_MSG_NOTICE([rose_boost_version = '$rose_boost_version']) - -if test "x$rose_boost_version" = "x"; then - ROSE_MSG_ERROR([Unable to compute the version of your Boost C++ libraries from '$ac_boost_path'/include/boost/version.hpp . Please make sure the file exists or specify the right path with --with-boost]) -fi - -# DQ (10/22/2015): Added more tests (1.55 through 1.62) -# Define macros for conditional compilation of parts of ROSE based on version of boost -# (this ONLY happens for the tests in tests/nonsmoke/functional/CompilerOptionsTests/testWave) -# -# !! We don't want conditional compilation or code in ROSE based on version numbers of Boost. !! -# -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_35, test "$rose_boost_version" = "103500" -o "$_version" = "1.35") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_36, test "$rose_boost_version" = "103600" -o "$_version" = "1.36") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_37, test "$rose_boost_version" = "103700" -o "$_version" = "1.37") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_38, test "$rose_boost_version" = "103800" -o "$_version" = "1.38") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_39, test "$rose_boost_version" = "103900" -o "$_version" = "1.39") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_40, test "$rose_boost_version" = "104000" -o "$_version" = "1.40") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_41, test "$rose_boost_version" = "104100" -o "$_version" = "1.41") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_42, test "$rose_boost_version" = "104200" -o "$_version" = "1.42") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_43, test "$rose_boost_version" = "104300" -o "$_version" = "1.43") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_44, test "$rose_boost_version" = "104400" -o "$_version" = "1.44") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_45, test "$rose_boost_version" = "104500" -o "$_version" = "1.45") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_46, test "$rose_boost_version" = "104600" -o "$_version" = "1.46") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_46, test "$rose_boost_version" = "104601" -o "$_version" = "1.46") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_47, test "$rose_boost_version" = "104700" -o "$_version" = "1.47") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_48, test "$rose_boost_version" = "104800" -o "$_version" = "1.48") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_49, test "$rose_boost_version" = "104900" -o "$_version" = "1.49") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_50, test "$rose_boost_version" = "105000" -o "$_version" = "1.50") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_51, test "$rose_boost_version" = "105100" -o "$_version" = "1.51") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_52, test "$rose_boost_version" = "105200" -o "$_version" = "1.52") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_53, test "$rose_boost_version" = "105300" -o "$_version" = "1.53") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_54, test "$rose_boost_version" = "105400" -o "$_version" = "1.54") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_55, test "$rose_boost_version" = "105500" -o "$_version" = "1.55") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_56, test "$rose_boost_version" = "105600" -o "$_version" = "1.56") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_57, test "$rose_boost_version" = "105700" -o "$_version" = "1.57") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_58, test "$rose_boost_version" = "105800" -o "$_version" = "1.58") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_59, test "$rose_boost_version" = "105900" -o "$_version" = "1.59") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_60, test "$rose_boost_version" = "106000" -o "$_version" = "1.60") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_61, test "$rose_boost_version" = "106100" -o "$_version" = "1.61") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_62, test "$rose_boost_version" = "106200" -o "$_version" = "1.62") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_63, test "$rose_boost_version" = "106300" -o "$_version" = "1.63") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_64, test "$rose_boost_version" = "106400" -o "$_version" = "1.64") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_65, test "$rose_boost_version" = "106500" -o "$_version" = "1.65") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_66, test "$rose_boost_version" = "106600" -o "$_version" = "1.66") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_67, test "$rose_boost_version" = "106700" -o "$_version" = "1.67") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_68, test "$rose_boost_version" = "106800" -o "$_version" = "1.68") -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_1_69, test "$rose_boost_version" = "106900" -o "$_version" = "1.69") - -# DQ (10/22/2015): Added more tests (1.55 through 1.62) -# TOO1 (3/16/2015): -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_35, test $rose_boost_version -ge 103500) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_36, test $rose_boost_version -ge 103600) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_37, test $rose_boost_version -ge 103700) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_38, test $rose_boost_version -ge 103800) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_39, test $rose_boost_version -ge 103900) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_40, test $rose_boost_version -ge 104000) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_41, test $rose_boost_version -ge 104100) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_42, test $rose_boost_version -ge 104200) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_43, test $rose_boost_version -ge 104300) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_44, test $rose_boost_version -ge 104400) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_45, test $rose_boost_version -ge 104500) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_46, test $rose_boost_version -ge 104600) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_46, test $rose_boost_version -ge 104601) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_47, test $rose_boost_version -ge 104700) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_48, test $rose_boost_version -ge 104800) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_49, test $rose_boost_version -ge 104900) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_50, test $rose_boost_version -ge 105000) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_51, test $rose_boost_version -ge 105100) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_52, test $rose_boost_version -ge 105200) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_53, test $rose_boost_version -ge 105300) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_54, test $rose_boost_version -ge 105400) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_55, test $rose_boost_version -ge 105500) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_56, test $rose_boost_version -ge 105600) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_57, test $rose_boost_version -ge 105700) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_58, test $rose_boost_version -ge 105800) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_59, test $rose_boost_version -ge 105900) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_60, test $rose_boost_version -ge 106000) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_61, test $rose_boost_version -ge 106100) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_62, test $rose_boost_version -ge 106200) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_63, test $rose_boost_version -ge 106300) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_64, test $rose_boost_version -ge 106400) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_65, test $rose_boost_version -ge 106500) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_66, test $rose_boost_version -ge 106600) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_67, test $rose_boost_version -ge 106700) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_68, test $rose_boost_version -ge 106800) -AM_CONDITIONAL(ROSE_USING_BOOST_VERSION_GE_1_69, test $rose_boost_version -ge 106900) - -# DQ (10/22/2015): Added acceptable case 1.54. -# DQ (8/2/2016): Added acceptable case 1.55 through 1.61. -# [Matzke, 2016-09-19] Acceptable cases now 1.49-1.53, 1.55-1.60 decided at Jun 17 meeting, but leaving in 1.61 -# [Matzke, 2019-01-31] Acceptable versions no 1.57-1.69. We decided to support only latest 10 versions from now on. -boost_minimum_version=105700 - -if test "$rose_boost_version" -lt "$boost_minimum_version"; then - if test "$ROSE_ENABLE_BOOST_VERSION_CHECK" = "yes"; then - AC_MSG_FAILURE([boost version $rose_boost_version is unsupported (need $boost_minimum_version or later)]) - else - AC_MSG_WARN([boost version $rose_boost_version is unsupported (need $boost_minimum_version or later)]) - fi -else - AC_MSG_NOTICE([reasonable version of Boost found: $rose_boost_version]) -fi - -# DQ (12/22/2008): Fix boost configure to handle OS with older version of Boost that will -# not work with ROSE, and use the newer version specified by the user on the configure line. -AC_MSG_NOTICE([in ROSE/configure: ac_boost_path = "$ac_boost_path"]) -#AC_DEFINE([ROSE_BOOST_PATH],"$ac_boost_path",[Location of Boost specified on configure line.]) -AC_DEFINE_UNQUOTED([ROSE_BOOST_PATH],"$ac_boost_path",[Location (unquoted) of Boost specified on configure line.]) -#AC_DEFINE([ROSE_WAVE_PATH],"$ac_boost_path/wave",[Location of Wave specified on configure line.]) -AC_DEFINE_UNQUOTED([ROSE_WAVE_PATH],"$ac_boost_path/wave",[Location (unquoted) of Wave specified on configure line.]) - -AC_DEFINE_UNQUOTED([ROSE_BOOST_VERSION], $rose_boost_version, [Version of Boost specified on configure line.]) - -AX_BOOST_ATOMIC -AX_BOOST_SYSTEM -AX_BOOST_THREAD -AX_BOOST_DATE_TIME -AX_BOOST_CHRONO -AX_BOOST_RANDOM dnl needed by Wt and other libraries that use boost -AX_BOOST_REGEX -AX_BOOST_PROGRAM_OPTIONS -#AX_BOOST_SERIALIZATION -#AX_BOOST_ASIO -#AX_BOOST_SIGNALS -#AX_BOOST_TEST_EXEC_MONITOR -AX_BOOST_FILESYSTEM -AX_BOOST_WAVE -#AX_BOOST_PYTHON -AX_BOOST_IOSTREAMS - -# AM_CONDITIONAL(ROSE_USE_BOOST_WAVE,test "$with_wave" = true) -AM_COND_IF([OS_MACOSX],[LDFLAGS="-Xlinker -rpath $ac_boost_path/lib $LDFLAGS"],[]) - -# End macro ROSE_SUPPORT_BOOST. -]) - diff --git a/config/support-rose.m4 b/config/support-rose.m4 index 9692860956e..2eb08b38a7b 100644 --- a/config/support-rose.m4 +++ b/config/support-rose.m4 @@ -392,8 +392,6 @@ AC_SUBST(ROSE_HOME) AC_LANG(C++) -ROSE_SUPPORT_BOOST - # Rasmussen (12/16/2017): Added test for Bison version (Mac OSX Bison version may be too old) ROSE_SUPPORT_BISON @@ -693,8 +691,6 @@ AC_PROG_MAKE_SET AC_MSG_NOTICE([testing the value of CC: (CC = "$CC")]) AC_MSG_NOTICE([testing the value of CPPFLAGS: (CPPFLAGS = "$CPPFLAGS")]) -AX_BOOST_IOSTREAMS - ROSE_SUPPORT_VECTORIZATION ROSE_SUPPORT_LIBHARU diff --git a/config/support-summary.m4 b/config/support-summary.m4 index e844a4a1306..f2efd2486cd 100644 --- a/config/support-summary.m4 +++ b/config/support-summary.m4 @@ -58,29 +58,6 @@ ROSE_COMPILER_FEATURES([fortran], [$FC $FCLAGS], [HOST_FC_]) echo " Fortran ${support_fortran_frontend:-no}" echo " OpenCL ${support_opencl_frontend:-no}" - #-------------------------------------------------------------------------------- - ROSE_SUMMARY_HEADING([Boost library]) - echo " location ${ac_boost_path:-unknown}" - echo " version constant ${rose_boost_version:-unknown}" - echo " asio library ${BOOST_ASIO_LIB:-none}" - echo " atomic library ${BOOST_ATOMIC_LIB:-none}" - echo " chrono library ${BOOST_CHRONO_LIB:-none}" - echo " date/time library ${BOOST_DATE_TIME_LIB:-none}" - echo " filesystem library ${BOOST_FILESYSTEM_LIB:-none}" - echo " iostreams library ${BOOST_IOSTREAMS_LIB:-none}" - echo " program options library ${BOOST_PROGRAM_OPTIONS_LIB:-none}" - echo " python library ${BOOST_PYTHON_LIB:-none}" - echo " random library ${BOOST_RANDOM_LIB:-none}" - echo " regex library ${BOOST_REGEX_LIB:-none}" - echo " serialization library ${BOOST_SERIALIZATION_LIB:-none}" - echo " signals library ${BOOST_SIGNALS_LIB:-none}" - echo " system library ${BOOST_SYSTEM_LIB:-none}" - echo " test exec monitor library ${BOOST_TEST_EXEC_MONITOR_LIB:-none}" - echo " thread library ${BOOST_THREAD_LIB:-none}" - echo " unit test framework library ${BOOST_UNIT_TEST_FRAMEWORK_LIB:-none}" - echo " wave library ${BOOST_WAVE_LIB:-none}" - echo " wserialization library ${BOOST_WSERIALIZATION_LIB:-none}" - #-------------------------------------------------------------------------------- if test -n "$support_cxx_frontend" -o -n "$verbose"; then ROSE_SUMMARY_HEADING([C/C++ analysis support]) diff --git a/configure.ac b/configure.ac index 765bbe83ea0..39dd67585fc 100644 --- a/configure.ac +++ b/configure.ac @@ -143,7 +143,6 @@ ROSE_SUPPORT_ROSE_PART_6 ROSE_SUPPORT_ROSE_PART_7 dnl Fail gracefully for blacklisted dependencies and other situations -ROSE_SUPPORT_BLACKLIST ROSE_SUPPORT_SUMMARY dnl Now generate all the output files (specified above) diff --git a/rose_config.h.in.cmake b/rose_config.h.in.cmake index c89cc8cf504..2cc322f3828 100644 --- a/rose_config.h.in.cmake +++ b/rose_config.h.in.cmake @@ -36,34 +36,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ARGZ_H 1 -/* define if the Boost library is available , convert the cmake output Boost_FOUND to our custom HAVE_BOOST */ -#cmakedefine HAVE_BOOST - -/* define if the Boost::Date_Time library is available */ -#cmakedefine HAVE_BOOST_DATE_TIME - -/* define if the Boost::Filesystem library is available */ -#cmakedefine HAVE_BOOST_FILESYSTEM - -/* define if the Boost::PROGRAM_OPTIONS library is available */ -#cmakedefine HAVE_BOOST_PROGRAM_OPTIONS - -/* define if the Boost::Regex library is available */ -#cmakedefine HAVE_BOOST_REGEX - -/* define if the Boost::System library is available */ -#cmakedefine HAVE_BOOST_SYSTEM - -/* define if the Boost::Thread library is available */ -#cmakedefine HAVE_BOOST_THREAD - -/* define if the Boost::Wave library is available */ -#cmakedefine HAVE_BOOST_WAVE -#cmakedefine USE_ROSE_BOOST_WAVE_SUPPORT - -/* Define if the boost::serialization library is available */ -#cmakedefine HAVE_BOOST_SERIALIZATION_LIB 1 - /* Define if Z3 library is available */ #cmakedefine ROSE_HAVE_Z3 @@ -510,9 +482,6 @@ //AS Don't know what to do with this #undef RETSIGTYPE -/* Location (unquoted) of Boost specified on configure line. */ -#define ROSE_BOOST_PATH "${BOOST_ROOT}" - /* Location of ROSE Compile Tree. */ #define ROSE_COMPILE_TREE_PATH ${ROSE_TOP_BINARY_DIR} diff --git a/src/Makefile.am b/src/Makefile.am index 7012b41b2e8..ef9ef7ee547 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,12 +90,7 @@ endif librose_la_SOURCES = dummyCppFileForLibrose.C -librose_la_LIBADD = $(BOOST_LDFLAGS) $(libroseLibraries) $(JAVA_JVM_FLAGS) -lm $(RT_LIBS) \ - $(BOOST_DATE_TIME_LIB) \ - $(BOOST_THREAD_LIB) $(BOOST_FILESYSTEM_LIB) \ - $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_REGEX_LIB) \ - $(BOOST_SYSTEM_LIB) $(BOOST_SERIALIZATION_LIB) \ - $(BOOST_WAVE_LIB) $(BOOST_IOSTREAMS_LIB) +librose_la_LIBADD = $(libroseLibraries) $(JAVA_JVM_FLAGS) -lm $(RT_LIBS) if ROSE_USE_GCC_OMP librose_la_LIBADD += lgomp @@ -143,22 +138,10 @@ rose_config_LDFLAGS += -fno-rtti rose_config_installed_cppflags = \ -I@includedir@/rose \ - $(ROSE_PCH_INCLUDE) \ - $(BOOST_CPPFLAGS) + $(ROSE_PCH_INCLUDE) rose_config_installed_ldflags = \ -L@libdir@ -lrose \ - $(BOOST_LDFLAGS) \ - $(BOOST_DATE_TIME_LIB) \ - $(BOOST_THREAD_LIB) \ - $(BOOST_FILESYSTEM_LIB) \ - $(BOOST_PROGRAM_OPTIONS_LIB) \ - $(BOOST_REGEX_LIB) \ - $(BOOST_SYSTEM_LIB) \ - $(BOOST_SERIALIZATION_LIB) \ - $(BOOST_WAVE_LIB) \ - $(BOOST_IOSTREAMS_LIB) \ - $(BOOST_CHRONO_LIB) \ $(JAVA_JVM_LINK) \ $(RT_LIBS) \ $(ROSE_INTEL_COMPILER_MATH_LIBS) \ @@ -237,10 +220,6 @@ rose_fortran_LDADD = $(LDADD_ROSEBIN) ######################################################################################################################## # Test that a simple ROSE program can run, and as a side effect, print some version numbers. -check-boost: - @echo " TEST boost shared linkage [rose-compiler]" - ${AM_V_at}$(top_srcdir)/scripts/check_boost_linkage.sh .libs/rose-compiler >&2 - check-dynload: @echo " TEST whether a trivial ROSE program runs [rose-compiler]" ${AM_V_at}if ! ./rose-compiler --version; then \ @@ -295,7 +274,6 @@ check-hello-fortran: endif check-local: $(bin_PROGRAMS) - ${AM_V_at}$(MAKE) check-boost ${AM_V_at}$(MAKE) check-dynload ${AM_V_at}$(MAKE) check-config if ROSE_BUILD_C_LANGUAGE_SUPPORT diff --git a/src/ROSETTA/src/Makefile.am b/src/ROSETTA/src/Makefile.am index 150b858fe80..d45eee5e697 100644 --- a/src/ROSETTA/src/Makefile.am +++ b/src/ROSETTA/src/Makefile.am @@ -116,14 +116,7 @@ CxxGrammarMetaProgram_SOURCES = \ # buildConstructorsWithoutSourcePositionInformation.o: buildConstructorsWithoutSourcePositionInformation.C -BoostLibraries = \ - $(BOOST_LDFLAGS) $(BOOST_DATE_TIME_LIB) \ - $(BOOST_THREAD_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_PROGRAM_OPTIONS_LIB) \ - $(BOOST_REGEX_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_SERIALIZATION_LIB) \ - $(BOOST_WAVE_LIB) $(BOOST_IOSTREAMS_LIB) - CxxGrammarMetaProgram_LDADD = \ - $(ROSE_BOOST_LIBS) \ $(top_builddir)/src/util/libroseutil.la \ $(RT_LIBS) diff --git a/src/frontend/SageIII/Makefile.am b/src/frontend/SageIII/Makefile.am index 1d94a9aa561..9c76172d0ab 100644 --- a/src/frontend/SageIII/Makefile.am +++ b/src/frontend/SageIII/Makefile.am @@ -135,8 +135,8 @@ libsage3_la_SOURCES = $(libsage3Sources) preproc-c.ll omp_exprparser_lexer.ll om # nodist_libsage3_la_SOURCES = $(ROSETTA_GENERATED_SOURCE) $(top_builddir)/rose_config.h nodist_libsage3_la_SOURCES = $(ROSETTA_GENERATED_SOURCE) license_string.h -if ROSE_USE_BOOST_WAVE -libsage3_la_LIBADD= \ +#if ROSE_USE_BOOST_WAVE +libsage3_la_LIBADD_not_used= \ astFixup/libastFixup.la \ accparser/libaccparser.la \ ompparser/libompparser.la \ @@ -146,7 +146,7 @@ libsage3_la_LIBADD= \ astHiddenTypeAndDeclarationLists/libastHiddenTypeAndDeclarationLists.la \ includeDirectivesProcessing/libincludeDirectivesProcessing.la \ astTokenStream/libastTokenStream.la -else +#else libsage3_la_LIBADD= \ astFixup/libastFixup.la \ accparser/libaccparser.la \ @@ -156,7 +156,7 @@ libsage3_la_LIBADD= \ virtualCFG/libvirtualCFG.la \ astHiddenTypeAndDeclarationLists/libastHiddenTypeAndDeclarationLists.la \ includeDirectivesProcessing/libincludeDirectivesProcessing.la -endif +#endif # DQ (6/25/2011): Readded this directory so that we can support the older behavior as a default # although this will likely fail at least some of the nearly one hundred new name qualification tests. diff --git a/src/frontend/SageIII/astTokenStream/Makefile.am b/src/frontend/SageIII/astTokenStream/Makefile.am index eb8b3690451..ae7f5044221 100644 --- a/src/frontend/SageIII/astTokenStream/Makefile.am +++ b/src/frontend/SageIII/astTokenStream/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs AM_CPPFLAGS = $(ROSE_INCLUDES) -if ROSE_USE_BOOST_WAVE +#if ROSE_USE_BOOST_WAVE # DQ (10/27/2013): Commented out for now from this Makefile.am (experimenting with replacing with new implementation independent of WAVE). # libastTokenStream_la_SOURCES = createMap.C doCompleteMapping.C linearizeAST.C unparseMacro.C @@ -10,7 +10,7 @@ if ROSE_USE_BOOST_WAVE # libastTokenStream_la_DEPENDENCIES = # include_HEADERS = createMap.h doCompleteMapping.h linearizeAST.h unparseMacro.h -endif +#endif # DQ (10/27/2013): This is a new definition of libastTokenStream diff --git a/src/frontend/SageIII/rose_attributes_list.C b/src/frontend/SageIII/rose_attributes_list.C index 318ba9fa833..0d9e80461a2 100644 --- a/src/frontend/SageIII/rose_attributes_list.C +++ b/src/frontend/SageIII/rose_attributes_list.C @@ -14,22 +14,6 @@ // #if (CAN_NOT_COMPILE_WITH_ROSE == 0) // #ifndef USE_ROSE -/////////////////////////////////////////////////////////////////////////////// -// Include the token class from Wave -/////////////////////////////////////////////////////////////////////////////// - -#ifndef ROSE_SKIP_COMPILATION_OF_WAVE -// Include Wave itself -#include - -token_container wave_tokenStream; -#endif - -// #include //as_string - -// #endif - - // DQ (9/30/2013): This global variable is used in only the initial accumulation of // the CPP directives, comments and tokens by file name in the src/frontend/SageIII/preproc-c.ll // file. Later after processin it is an empty map (e.g. in the unparsing phase). @@ -39,8 +23,6 @@ token_container wave_tokenStream; // to get this by a traversal of the AST std::map mapFilenameToAttributes; - - // DQ (12/31/2005): This is OK if not declared in a header file using namespace std; using namespace Rose; diff --git a/src/frontend/SageIII/rose_attributes_list.h b/src/frontend/SageIII/rose_attributes_list.h index aae9c45fca6..8567fd3043b 100644 --- a/src/frontend/SageIII/rose_attributes_list.h +++ b/src/frontend/SageIII/rose_attributes_list.h @@ -30,74 +30,6 @@ // #if !CAN_NOT_COMPILE_WITH_ROSE // #ifndef USE_ROSE -// DQ (5/21/2010): I have built a separate macro for tuning off the compilation of WAVE -// since it is done only for the purpose of allowing ROSE based projects: -// 1) projects/DocumentationGenerator -// 2) projects/haskellport -// to process the ROSE files cleanly. ROSE can however process and compile ROSE -// (including a slightly modified version of WAVE that EDG will accept) and we -// separately test this in noightly tests. The previous 5/18/2010 fix to permit -// the Haskell support to skip processign WAVE turned this off and broke the nightly -// tests of ROSE compiling ROSE. This use of the macro ROSE_SKIP_COMPILATION_OF_WAVE -// it menat to be turned on by ROSE based tools that need to process the ROSE code -// and which currently fail (because of Wave) and so turn of the processing of Wave -// for those tools. -// #ifdef USE_ROSE -// #define ROSE_SKIP_COMPILATION_OF_WAVE -// #endif - -// DQ (2/27/2016): Check for DEBIAN and Boost 1.54 and disable WAVE (not found in -// Boost 1.54, for Debian OS installations, as I understand it). This is a fix -// for a bug identified to be specific to Boost 1.54 on Debian systems, so that -// is why it is so specific in deactivating boost::wave. To support this the -// boost::wave support had to be revisited to permit it to NOT be a dependence. -// We shuld put in place tests that make sure it does not accedently become a -// dependence in the future. -#ifdef ROSE_DEBIAN_OS_VENDOR - #if (ROSE_BOOST_VERSION == 105400) - #define ROSE_SKIP_COMPILATION_OF_WAVE - #endif -#endif - -#if __sun - // PP 05/16/19 - // Continue skipping WAVE until it is needed - // (after boost 1.65 is working on Solaris, WAVE should also work) - #define ROSE_SKIP_COMPILATION_OF_WAVE -#endif - -// DQ (2/27/2016): Test compilation of ROSE without boost::wave support. -// #define ROSE_SKIP_COMPILATION_OF_WAVE - -#ifndef ROSE_SKIP_COMPILATION_OF_WAVE -// #if _MSC_VER < 1600 // 1600 == VC++ 10.0 - #if (!defined(_MSC_VER) || (_MSC_VER > 1600)) - #include // Liao, 7/10/2009, required by GCC 4.4.0 for a #define line of BOOST_PP_ITERATION_DEPTH - #ifdef _MSC_VER - #include // CH (4/7/2010): Put this header here to avoid compiling error about mismatch between defination and declaration - #endif - #include // token class - #include // lexer type - #else -// #warning "Setting CAN_NOT_COMPILE_WITH_ROSE to value = 1" -// #define CAN_NOT_COMPILE_WITH_ROSE 1 -// tps (12/4/2009) : This is not found in VC++ 10.0 and Boost 1.4 - #pragma message ("Boost preprocessor and wave not included yet for VC++ 10.0") - - #endif -#endif - -//template boost::wave::cpplexer::impl::token_data::delete(std::size_t) ; -// DQ (10/16/2002): Required for compiling with SUN 5.2 C++ compiler -#ifndef NAMESPACE_IS_BROKEN -// DQ (12/30/2005): This is a Bad Bad thing to do (I can explain) -// it hides names in the global namespace and causes errors in -// otherwise valid and useful code. Where it is needed it should -// appear only in *.C files (and only ones not included for template -// instantiation reasons) else they effect user who use ROSE unexpectedly. -// using namespace std; -#endif - class ROSE_DLL_API PreprocessingInfo; class ROSEAttributesList; //AS(01/04/07) Global map of filenames to PreprocessingInfo*'s as it is inefficient diff --git a/src/rose.h b/src/rose.h index 1cd1fb21e57..e26a4451fec 100644 --- a/src/rose.h +++ b/src/rose.h @@ -9,7 +9,6 @@ #include "sage3basic.hhh" // DQ (4/21/2009): Andreas needs to add a comment about what this is for... -#define BOOST_WAVE_PREPROCESS_PRAGMA_BODY 1 #include "rosedefs.h" diff --git a/tests/nonsmoke/functional/CompileTests/Cxx_tests/Makefile.am b/tests/nonsmoke/functional/CompileTests/Cxx_tests/Makefile.am index 814ab403dea..47a806f90b5 100644 --- a/tests/nonsmoke/functional/CompileTests/Cxx_tests/Makefile.am +++ b/tests/nonsmoke/functional/CompileTests/Cxx_tests/Makefile.am @@ -2488,15 +2488,9 @@ else rose-1701-1.C endif -if ROSE_USING_BOOST_VERSION_1_57 - TESTCODE_CURRENTLY_FAILING += \ - test2014_77.C \ - test2014_78.C -else - EXAMPLE_TESTCODES_REQUIRED_TO_PASS += \ +EXAMPLE_TESTCODES_REQUIRED_TO_PASS += \ test2014_77.C \ test2014_78.C -endif if USING_CLANG_COMPILER TESTCODE_CURRENTLY_FAILING += \ diff --git a/tests/nonsmoke/functional/CompilerOptionsTests/testWave/Makefile.am b/tests/nonsmoke/functional/CompilerOptionsTests/testWave/Makefile.am index dea4d05ab9b..e147e1a742b 100644 --- a/tests/nonsmoke/functional/CompilerOptionsTests/testWave/Makefile.am +++ b/tests/nonsmoke/functional/CompilerOptionsTests/testWave/Makefile.am @@ -96,10 +96,10 @@ check-local: @echo "************************************************************************************************" @echo "*** ROSE/tests/nonsmoke/functional/CompilerOptionsTests/testWave: make check rule start ***" @echo "************************************************************************************************" -if ROSE_USING_BOOST_VERSION_1_35 +#if ROSE_USING_BOOST_VERSION_1_35 # It is not helpful to have Boost version dependent tests in ROSE. @$(MAKE) $(PASSING_TEST_Objects) -endif +#endif @echo "************************************************************************************************" @echo "*** ROSE/tests/nonsmoke/functional/CompilerOptionsTests/testWave: make check rule complete (terminated normally) ***" @echo "************************************************************************************************" diff --git a/tests/nonsmoke/functional/RunTests/FortranTests/LANL_POP/.gitignore b/tests/nonsmoke/functional/RunTests/FortranTests/LANL_POP/.gitignore deleted file mode 100644 index 70823417cae..00000000000 --- a/tests/nonsmoke/functional/RunTests/FortranTests/LANL_POP/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -!Makefile.in -/Makefile.in diff --git a/tests/nonsmoke/functional/roseTests/programAnalysisTests/Makefile.am b/tests/nonsmoke/functional/roseTests/programAnalysisTests/Makefile.am index ed626e970d2..2ed697d950d 100644 --- a/tests/nonsmoke/functional/roseTests/programAnalysisTests/Makefile.am +++ b/tests/nonsmoke/functional/roseTests/programAnalysisTests/Makefile.am @@ -13,9 +13,9 @@ SUBDIRS = \ # DQ (4/4/2017): Note that Boost 1.62 version is problematic and Boost suggests using an older version. # There is nothing that ROSE can do about this except skip some tests that require problem features of Boost 1.62. -if !ROSE_USING_BOOST_VERSION_1_62 +#if !ROSE_USING_BOOST_VERSION_1_62 SUBDIRS += staticInterproceduralSlicingTests -endif +#endif # ROSE Test Harness scripts #CHECK_ANSWER = $(top_srcdir)/scripts/test_against_answer From 583e95501dbcdd0d5b5dab760184af481ec8f64e Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Tue, 12 Nov 2024 23:16:55 -0500 Subject: [PATCH 18/42] deBoost: removing boost usage in src/util/StringUtility --- src/util/StringUtility/Escape.C | 5 +-- src/util/StringUtility/FileNameClassifier.C | 11 ++----- src/util/StringUtility/FileUtility.C | 1 - src/util/StringUtility/NumberToString.C | 34 ++++++++++----------- src/util/StringUtility/NumberToString.h | 4 ++- src/util/StringUtility/Replace.C | 24 +++++++++++++-- src/util/StringUtility/Replace.h | 4 --- src/util/StringUtility/StringUtility.h | 5 +-- src/util/StringUtility/Trim.h | 1 - src/util/Unique.C | 27 ++++++++++++++++ src/util/Unique.h | 13 ++++++++ 11 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 src/util/Unique.C create mode 100644 src/util/Unique.h diff --git a/src/util/StringUtility/Escape.C b/src/util/StringUtility/Escape.C index 965ae282c4c..e36db6b1a20 100644 --- a/src/util/StringUtility/Escape.C +++ b/src/util/StringUtility/Escape.C @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace Rose { namespace StringUtility { @@ -202,7 +202,8 @@ yamlEscape(const std::string &s) { } else if (s.find(':') != std::string::npos) { return "\"" + s + "\""; } else { - const std::string lc = boost::to_lower_copy(s); + std::string lc = s; + for (char&c: lc) c = std::tolower(c); //convert to lower case if ("yes" == lc || "true" == lc || "no" == lc || "false" == lc) { return"\"" + s + "\""; } else { diff --git a/src/util/StringUtility/FileNameClassifier.C b/src/util/StringUtility/FileNameClassifier.C index dec0a01d810..20028571ad8 100644 --- a/src/util/StringUtility/FileNameClassifier.C +++ b/src/util/StringUtility/FileNameClassifier.C @@ -23,6 +23,7 @@ #include #include #include +#include #include "FileUtility.h" #include #include "mlog.h" @@ -33,14 +34,6 @@ #include #endif - -#include -#if BOOST_VERSION >= 103600 -# define BOOST_HAS_BRANCH_PATH has_parent_path -#else -# define BOOST_HAS_BRANCH_PATH has_branch_path -#endif - using namespace std; using namespace Rose; @@ -116,7 +109,7 @@ using namespace Rose; "execinfo.h", "fcntl.h", "features.h", - "fenv.h", + "fenv.h", "fmtmsg.h", "fnmatch.h", "fpu_control.h", diff --git a/src/util/StringUtility/FileUtility.C b/src/util/StringUtility/FileUtility.C index 6d194618308..9ad36d1a9d1 100644 --- a/src/util/StringUtility/FileUtility.C +++ b/src/util/StringUtility/FileUtility.C @@ -10,7 +10,6 @@ #include "mlog.h" // Other includes -#include #include #include // DQ (9/29/2006): This is required for 64-bit g++ 3.4.4 compiler. #include diff --git a/src/util/StringUtility/NumberToString.C b/src/util/StringUtility/NumberToString.C index 7445d8b6ace..f0c7b1752f1 100644 --- a/src/util/StringUtility/NumberToString.C +++ b/src/util/StringUtility/NumberToString.C @@ -1,8 +1,5 @@ #include -#include -#include - namespace Rose { namespace StringUtility { @@ -12,32 +9,32 @@ namespace StringUtility { std::string numberToString(long long x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string numberToString(unsigned long long x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string numberToString(long x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string numberToString(unsigned long x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string numberToString(int x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string numberToString(unsigned int x) { - return boost::lexical_cast(x); + return std::to_string(x); } std::string @@ -61,16 +58,14 @@ numberToString(double x) { __WORDSIZE == 64 std::string numberToString( __int128 x) { - // DQ (2/22/2014): I don't think that the boost::lexical_cast can support __int128 yet. long long temp_x = (long long) x; - return boost::lexical_cast(temp_x); + return std::to_string(temp_x); } std::string numberToString(unsigned __int128 x) { - // DQ (2/22/2014): I don't think that the boost::lexical_cast can support __int128 yet. unsigned long long temp_x = (unsigned long long) x; - return boost::lexical_cast(temp_x); + return std::to_string(temp_x); } #endif @@ -98,10 +93,15 @@ toHex2(uint64_t value, size_t nbits, bool show_unsigned_decimal, bool show_signe uint64_t sign_bit = ((uint64_t)1 << (nbits-1)); // Hexadecimal value - std::string retval; - int nnibbles = (nbits+3)/4; - std::string fmt = "0x%0" + boost::lexical_cast(nnibbles) + "x"; - retval = (boost::format(fmt) % value).str(); + + //std::string retval; + //int nnibbles = (nbits+3)/4; + //std::string fmt = "0x%0" + std::to_string(nnibbles) + "x"; + //retval = (boost::format(fmt) % value).str(); + + std::stringstream ss; + ss << "0x" << std::setw((nbits + 3) / 4) << std::setfill('0') << std::hex << value; + std::string retval = ss.str(); // unsigned decimal bool showed_unsigned = false; diff --git a/src/util/StringUtility/NumberToString.h b/src/util/StringUtility/NumberToString.h index c4a74da8849..d6a9fab62b4 100644 --- a/src/util/StringUtility/NumberToString.h +++ b/src/util/StringUtility/NumberToString.h @@ -5,6 +5,9 @@ #include #include +#include +#include +#include namespace Rose { namespace StringUtility { @@ -15,7 +18,6 @@ namespace StringUtility { /** Convert an integer to a string. * - * These functions are wrappers around boost::lexical_cast. * * @{ */ ROSE_UTIL_API std::string numberToString(long long); diff --git a/src/util/StringUtility/Replace.C b/src/util/StringUtility/Replace.C index 89ca31997bf..3d2ffb5c6c5 100644 --- a/src/util/StringUtility/Replace.C +++ b/src/util/StringUtility/Replace.C @@ -7,8 +7,28 @@ namespace StringUtility { // Replace //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// std::string replaceAllCopy(const std::string& input, const std::string& search, const std::string & replacedWith) { - return boost::replace_all_copy(input, search, replacedWith); - //TODO: for deBoost, this can be replaced with std::replace_copy when the compiler bumps to support c++17 by default + if (search.empty()) return input; // Avoid infinite loop if 'search' is empty + + std::string result; + result.reserve(input.size()); // Reserve space to avoid multiple allocations + + std::size_t start_pos = 0; + std::size_t found_pos; + + // Iterate through the input string + while ((found_pos = input.find(search, start_pos)) != std::string::npos) { + // Append the part before the found substring + result.append(input, start_pos, found_pos - start_pos); + // Append the replacement substring + result.append(replacedWith); + // Update start position to continue after the found substring + start_pos = found_pos + search.size(); + } + + // Append the rest of the string after the last found position + result.append(input, start_pos, input.size() - start_pos); + + return result; } } // namespace diff --git a/src/util/StringUtility/Replace.h b/src/util/StringUtility/Replace.h index 8411d3852ce..430a934cde8 100644 --- a/src/util/StringUtility/Replace.h +++ b/src/util/StringUtility/Replace.h @@ -3,8 +3,6 @@ #include #include -#include "boost/algorithm/string/replace.hpp" - namespace Rose { namespace StringUtility { @@ -14,8 +12,6 @@ namespace StringUtility { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** Replace a pattern with another one in a string - * - * These functions are wrappers around boost::replace_all_copy. * * @{ */ ROSE_UTIL_API std::string replaceAllCopy(const std::string& input, const std::string& search, const std::string & replacedWith); diff --git a/src/util/StringUtility/StringUtility.h b/src/util/StringUtility/StringUtility.h index e5f99e24bde..6c9c64f1e9c 100644 --- a/src/util/StringUtility/StringUtility.h +++ b/src/util/StringUtility/StringUtility.h @@ -12,8 +12,9 @@ namespace Rose { /** Functions for operating on strings. * - * This name space provides functions for operating on strings. See also, Boost String Algo - * [http://http://www.boost.org/doc/libs/1_78_0/doc/html/string_algo.html]. */ + * This name space provides functions for operating on strings. + * + */ namespace StringUtility {} // DQ (1/21/2010): Use this to turn off the use of #line in ROSETTA generated code. diff --git a/src/util/StringUtility/Trim.h b/src/util/StringUtility/Trim.h index 8eaca6a8e77..7ae773d8dbe 100644 --- a/src/util/StringUtility/Trim.h +++ b/src/util/StringUtility/Trim.h @@ -3,7 +3,6 @@ #include #include -// To replace boost::trim std::string trim(const std::string& str) { size_t start = str.find_first_not_of(" \t\n\r"); if (start == std::string::npos) diff --git a/src/util/Unique.C b/src/util/Unique.C new file mode 100644 index 00000000000..63f71dc0023 --- /dev/null +++ b/src/util/Unique.C @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +namespace Rose { +namespace Unique { + +std::string +genUniqueID() { + // Get the current timestamp + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + auto timestamp = std::chrono::duration_cast(duration).count(); + + // Use a counter to ensure uniqueness if generated within the same millisecond + static int counter = 0; + + // Construct a unique id using a hex representation of the timestamp and counter + std::ostringstream oss; + oss << std::hex << timestamp << std::setw(4) << std::setfill('0') << counter++; + return oss.str(); +} + +} // namespace +} // namespace diff --git a/src/util/Unique.h b/src/util/Unique.h new file mode 100644 index 00000000000..9f97825340e --- /dev/null +++ b/src/util/Unique.h @@ -0,0 +1,13 @@ +#ifndef ROSE_UNIQUE_H +#define ROSE_UNIQUE_H + +namespace Rose { + +namespace Unique { + +ROSE_UTIL_API std::string genUniqueID(); + +} // namespace +} // namespace + +#endif From 86e5bd0f0fd7a43dddc0e3664b97b59de50525ea Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Tue, 12 Nov 2024 23:40:36 -0500 Subject: [PATCH 19/42] deBoost: now boost usage are all removed from src/util --- src/util/CMakeLists.txt | 3 ++- src/util/Makefile.am | 4 ++-- src/util/commandlineProcessing/commandline_processing.C | 2 -- src/util/commandlineProcessing/sla++.C | 1 - src/util/mlog.C | 7 ------- src/util/rose_isnan.h | 6 +++--- src/util/support/FileHelper.h | 5 ++--- 7 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 37ec0ed2375..bbc56b798b9 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -55,6 +55,7 @@ add_subdirectory(support) set(rose_util_src ${CMAKE_BINARY_DIR}/src/util/rose_paths.C FileSystem.C + Unique.C mlog.C rose_getline.C processSupport.C @@ -74,6 +75,6 @@ target_sources(roseUtil INTERFACE ########### install files ############### install(FILES - processSupport.h rose_paths.h mlog.h FileSystem.h + processSupport.h rose_paths.h mlog.h FileSystem.h Unique.h timing.h rose_getline.h rose_strtoull.h rose_isnan.h DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 490e2febc0c..1238a31ce64 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -30,7 +30,7 @@ noinst_LTLIBRARIES = libroseutil.la libroseutil_la_SOURCES = \ processSupport.C \ rose_getline.C \ - rose_strtoull.C mlog.C FileSystem.C + rose_strtoull.C mlog.C FileSystem.C Unique.C nodist_libroseutil_la_SOURCES = rose_paths.C libroseutil_la_LIBADD = \ @@ -54,7 +54,7 @@ pkginclude_HEADERS = \ rose_isnan.h \ rose_paths.h \ rose_strtoull.h \ - mlog.h FileSystem.h + mlog.h FileSystem.h Unique.h EXTRA_DIST = CMakeLists.txt utilDocumentation.docs diff --git a/src/util/commandlineProcessing/commandline_processing.C b/src/util/commandlineProcessing/commandline_processing.C index 01ecd59390e..1fa080f4221 100644 --- a/src/util/commandlineProcessing/commandline_processing.C +++ b/src/util/commandlineProcessing/commandline_processing.C @@ -7,14 +7,12 @@ #include "mlog.h" #include #include -#include #include // Use Brian Gunney's String List Assignent (SLA) library #include "sla.h" #ifdef _MSC_VER -# include #else # include #endif diff --git a/src/util/commandlineProcessing/sla++.C b/src/util/commandlineProcessing/sla++.C index 18bbe59d733..5028d1e6ba4 100644 --- a/src/util/commandlineProcessing/sla++.C +++ b/src/util/commandlineProcessing/sla++.C @@ -106,7 +106,6 @@ Return: The number of value found. If pname is not a list, the number of #endif #if (_WIN32) - #include // #include #else #include diff --git a/src/util/mlog.C b/src/util/mlog.C index 26e41c5d985..cfaf638ac2a 100644 --- a/src/util/mlog.C +++ b/src/util/mlog.C @@ -8,10 +8,6 @@ #include #include "mlog.h" -#if defined(REX_STACKTRACE_ABORT_BOOST) -#include -#endif - int mlogLevel = DEFAULT_MLOG_LEVEL; /** @@ -80,9 +76,6 @@ void mlogAssertFail_C(const char * subject, const char * expr, const char * file va_end(l); fflush(mlogFile); } -#if defined(REX_STACKTRACE_ABORT_BOOST) - std::cerr << boost::stacktrace::stacktrace(); -#endif abort(); } diff --git a/src/util/rose_isnan.h b/src/util/rose_isnan.h index 867853f60e7..76ecadc89cc 100644 --- a/src/util/rose_isnan.h +++ b/src/util/rose_isnan.h @@ -1,14 +1,14 @@ #ifndef ROSE_isnan_H #define ROSE_isnan_H +#include + // In case anyone included a C header file, since isnan is a macro in C #undef isnan -#include - template bool rose_isnan(T x) { - return boost::math::isnan(x); + return std::isnan(x); } #endif diff --git a/src/util/support/FileHelper.h b/src/util/support/FileHelper.h index 81c505d3527..29f2de0705e 100644 --- a/src/util/support/FileHelper.h +++ b/src/util/support/FileHelper.h @@ -16,7 +16,6 @@ #include -#include #include #include @@ -152,7 +151,7 @@ class FileHelper { } static bool endsWith(const std::string& str1, const std::string& str2) { //checks that str1 ends with str2 - return boost::ends_with(str1, str2); + if (str2.size() > str1.size()) return false; + return str1.compare(str1.size() - str2.size(), str2.size(), str2) == 0; } - }; From b40daa8d6a408dea874082280de061cdf2447838 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 00:01:52 -0500 Subject: [PATCH 20/42] deBoost: remove boost usage in src/3rdPartyLibraries, mainly remove sarif support --- src/3rdPartyLibraries/json/Makefile.am | 5 +- src/3rdPartyLibraries/json/README | 28 +- src/3rdPartyLibraries/json/roseSarif.hpp | 311 -- src/3rdPartyLibraries/json/sarif.hpp | 6027 ---------------------- 4 files changed, 2 insertions(+), 6369 deletions(-) delete mode 100644 src/3rdPartyLibraries/json/roseSarif.hpp delete mode 100644 src/3rdPartyLibraries/json/sarif.hpp diff --git a/src/3rdPartyLibraries/json/Makefile.am b/src/3rdPartyLibraries/json/Makefile.am index bee50062fa2..55fce0ca8f8 100644 --- a/src/3rdPartyLibraries/json/Makefile.am +++ b/src/3rdPartyLibraries/json/Makefile.am @@ -1,4 +1 @@ -SUBDIRS=nlohmann - -SARIF_includedir=$(prefix)/include/rose -SARIF_include_HEADERS=sarif.hpp roseSarif.hpp +SUBDIRS=nlohmann \ No newline at end of file diff --git a/src/3rdPartyLibraries/json/README b/src/3rdPartyLibraries/json/README index ed06a3d0944..0ccabf8b89b 100644 --- a/src/3rdPartyLibraries/json/README +++ b/src/3rdPartyLibraries/json/README @@ -6,30 +6,4 @@ nlohmann: This is the common nlohmann json library that is widely used in the C++ community. The license allows it to be freely distributed with the constraint that the include file be in $(prefix)/nlohmann/json.hpp --- the "nlohmann" part shall be preserved. - -sarif: - -This is an implementation of the Static Analysis Results Interchange -Format (SARIF) v2.1.0 as defined here: - - https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html - -The sarif.hpp header was automatically generated using QuickType: - - https://quicktype.io/ - -Based on the JSON schema: - - https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json - -This automatically generated code has no license restrictions and -only depends on the NLohmann JSON library. The sarif.hpp header -serves as a bridge between a C++-facing object model and the backing -JSON representation. An additional layer will be provided within -ROSE that maps ROSE objects to the corresponding SARIF objects as well -as sanitization of the emitted JSON to remove unnecessary null objects -from appearing in the generated JSON. - -Note that the VERSION and SCHEMA constants were manually added after the code -was generated by quicktype. +-- the "nlohmann" part shall be preserved. \ No newline at end of file diff --git a/src/3rdPartyLibraries/json/roseSarif.hpp b/src/3rdPartyLibraries/json/roseSarif.hpp deleted file mode 100644 index 5d545a203ac..00000000000 --- a/src/3rdPartyLibraries/json/roseSarif.hpp +++ /dev/null @@ -1,311 +0,0 @@ -// -// ROSE/SARIF wrapper. This provides an abstraction layer between -// ROSE tools and the SARIF library that generates SARIF-formatted -// JSON files. This is intended to achieve two goals: -// -// 1. Insulate ROSE tools from the detail of SARIF. Many -// seemingly simple things require layers of nested -// SARIF objects where the nesting structure requires -// some knowledge of the SARIF format. Encapsulating -// that detail in the wrapper reduces the exposure of -// ROSE developers to the SARIF details. -// -// 2. Provide a stable ROSE-facing API if/when the SARIF -// specification changes. As the SARIF specification -// evolves the nesting structure of SARIF objects may -// change and new SARIF objects may be introduced. -// In many simple use cases, this change will not affect -// how ROSE tools report their results - just the -// manner by which the results are represented in the -// SARIF file. Hiding those details in this wrapper -// should minimize ROSE-tool breakage when the SARIF -// format changes as most necessary changes will be -// concentrated in this file. -// -// This API is intended to be relatively general, so there -// will likely exist special cases in which a tool has objects -// representing analysis results to serialize that are not -// included in this API. The recommendation is to either add -// appropriate methods to the SARIFOutput class here, or use -// methods here as a model for writing specialized serializers -// to include in specific analyzers. -// -// SARIF schema -> C++ generated via https://github.com/quicktype/quicktype -// -#ifndef __ROSESARIF_HPP__ -#define __ROSESARIF_HPP__ - -#include "sarif.hpp" -#include "rose.h" - -using json = nlohmann::json; - -/** - * This class manages SARIF output information. A SARIF file contains - * a description of the tool being run, the rules that correspond to - * the analyses, and the results of rule application. A result associates - * a rule with a physical location within a file. - * - * This wrapper class does not attempt to provide a full mapping of the - * SARIF schema - instead, the goal is to hide much of the detail in setting - * up various objects within a SARIF file to insulate ROSE tool developers - * from the complexity. - */ -class SARIFOutput { -private: - SARIF::Run run; - - // this pass to remove null-valued keys is due to the - // way the automatically generated SARIF C++ objects - // implement to_json. instead of skipping keys that - // have no value, it emits them with null values. - // there is no clean way according to the author of the - // JSON library to remove them other than traversing - // the JSON structure and removing them by hand... - void strip_nulls(nlohmann::json &j) { - std::vector removals; - - // accumulate up things to delete after iteration - for (auto iter = j.begin(); - iter != j.end(); - ++iter) { - if (iter.value().is_null()) { - removals.push_back(iter.key()); - } else { - if (iter.value().is_structured()) { - strip_nulls(iter.value()); - } - } - } - - for (std::string s: removals) { - j.erase(s); - } - } - - // typedef std::pair mapkey_t; - // std::map> results; - std::vector> results; - std::map rules; - std::map rule_indices; - SARIF::Tool *t; - SARIF::ToolComponent *tc; - int cur_index; - -public: - // create a SARIF output object for a given tool component name. - // this creates a fresh SARIF file that represents results - // from a single tool component. If we have a tool with more than - // one component we will need to generalize this interface (or split - // out a secondary object) that allows one tool to have multiple - // components. - SARIFOutput(const std::string &toolname) { - tc = new SARIF::ToolComponent(); - tc->set_name(toolname); - t = new SARIF::Tool(); - - std::vector invocations; - run.set_invocations(std::make_shared>(invocations)); - - cur_index = 0; - } - - // register a tool invocation with a command line specified as a single string - void register_invocation(const std::string &cmdline) { - SARIF::Invocation invoke; - - invoke.set_command_line(std::make_shared(cmdline)); - auto invocations = this->run.get_invocations(); - invocations->push_back(invoke); - } - - // register a tool invocation with a vector of arguments - void register_invocation(const std::vector &args) { - SARIF::Invocation invoke; - - invoke.set_arguments(std::make_shared>(args)); - auto invocations = this->run.get_invocations(); - invocations->push_back(invoke); - } - - // register a tool invocation with argc and argv - void register_invocation(int argc, char **argv) { - std::vector args; - for (int i = 0; i < argc; i++) - args.push_back(std::string(argv[i])); - register_invocation(args); - } - - // this registers a named rule with the object with a rule description string. - // the rule name is later used to register results generated by the tool component. - void register_rule(const std::string &rule, const std::string &desc) { - if (rules.find(rule) == rules.end()) { - SARIF::ReportingDescriptor r; - r.set_id(rule); - auto msg = std::make_shared(SARIF::MultiformatMessageString()); - msg->set_text(desc); - r.set_short_description(msg); - rules[rule] = r; - rule_indices[rule] = cur_index; - cur_index += 1; - } - } - - SARIF::Location define_source_region(SgNode *n, - std::shared_ptr artifact) - { - // extract the file info object from the SgNode to determine the extent of the - // program that the node represents. - Sg_File_Info *fi_start = n->get_startOfConstruct(); - Sg_File_Info *fi_end = n->get_endOfConstruct(); - - auto r = std::make_shared(SARIF::Region()); - r->set_start_line(std::make_shared(fi_start->get_line())); - r->set_start_column(std::make_shared(fi_start->get_col())); - r->set_end_line(std::make_shared(fi_end->get_line())); - r->set_end_column(std::make_shared(fi_end->get_col())); - - auto pl = std::make_shared(SARIF::PhysicalLocation()); - pl->set_region(r); - pl->set_artifact_location(artifact); - - SARIF::Location loc; - loc.set_physical_location(pl); - - return loc; - } - - // note: see SARIF spec 3.32.12 for expected valid values for address kind. while any - // value is legal, a set of strings are specified that producers and consumers of - // SARIF can agree upon - SARIF::Location define_binary_location(const rose_addr_t &a, - std::shared_ptr artifact, - int64_t length = 0, - std::string addrkind = "", - std::string name = "") - { - SARIF::Location loc; - - auto pl = std::make_shared(SARIF::PhysicalLocation()); - loc.set_physical_location(pl); - - auto addr = std::make_shared(SARIF::Address()); - addr->set_absolute_address(std::make_shared(a)); - if (length != 0) { - addr->set_length(std::make_shared(length)); - } - if (addrkind != "") { - addr->set_kind(std::make_shared(addrkind)); - } - if (name != "") { - addr->set_name(std::make_shared(name)); - } - pl->set_address(addr); - pl->set_artifact_location(artifact); - - return loc; - } - - // define a located artifact given some filename - std::shared_ptr create_artifact_location(std::shared_ptr filename) { - std::shared_ptr artifact = - std::make_shared(SARIF::ArtifactLocation()); - artifact->set_uri(filename); - return artifact; - } - - // register a result for a given named rule. the rule must have - // previously been registered with the register_rule method. - // - // the location passed in represents either a source or binary - // location created with the functions above. - // - // the artifact location represents the target of the analysis and - // is created with create_artifact_location. - // - // The result kind and level are optional : by default a result is - // given Kind=PASS and Level=WARNING. The caller registering the - // result should pick those appropriately. - void result(const std::string &rule, - const std::string &mesg, - const SARIF::Location &loc, - const std::shared_ptr &artifact, - const SARIF::ResultKind &kind = SARIF::ResultKind::PASS, - const SARIF::Level &lvl = SARIF::Level::WARNING) - { - // create the result object with a pointer to the given artifact location, - // and add it to the result collection. - std::shared_ptr res; - res = std::make_shared(SARIF::Result()); - res->set_locations(std::make_shared>(std::vector())); - res->set_analysis_target(artifact); - results.push_back(res); - - // wrap the message in a Message object - auto msg = SARIF::Message(); - msg.set_text(std::make_shared(mesg)); - res->set_message(msg); - - // update the kind and level of the result - res->set_kind(std::make_shared(kind)); - res->set_level(std::make_shared(lvl)); - - // create the mapping between the result and the rule that - // it corresponds to - auto rdr = std::make_shared(SARIF::ReportingDescriptorReference()); - rdr->set_id(std::make_shared(rule)); - rdr->set_index(std::make_shared(rule_indices[rule])); - res->set_rule(rdr); - res->set_rule_index(std::make_shared(rule_indices[rule])); - res->set_rule_id(std::make_shared(rule)); - - // add the location of the result to the result location vector - auto locs = res->get_locations(); - locs->push_back(loc); - } - - // emit the SARIF to the given ofstream - void emit(std::ofstream &ostr) { - json j; - - std::vector rvec; - for (auto it = rules.begin(); it != rules.end(); ++it) { - rvec.push_back(it->second); - } - tc->set_rules(std::make_shared>(rvec)); - t->set_driver(*tc); - run.set_tool(*t); - - // SARIF version and schema. - j["version"] = SARIF::VERSION; - j["$schema"] = SARIF::SCHEMA; - std::vector runs; - - std::vector res; - for (auto it = results.begin(); it != results.end(); ++it) { - res.push_back(*(*it)); - } - this->run.set_results(std::make_shared>(res)); - - json jrun; - to_json(jrun, this->run); - strip_nulls(jrun); - - runs.push_back(jrun); - j["runs"] = runs; - - // Note: setw() necessary to get the pretty printer to emit well formatted - // JSON. Without it a giant flat string is produced that is syntactically - // correct but not exactly human readable. - ostr << std::setw(4) << j << std::endl; - } - - // dump the JSON corresponding to the SARIF object to the named file. - void emit(const std::string &fname) { - std::ofstream o(fname); - emit(o); - } - -}; - -#endif // __ROSESARIF_HPP__ diff --git a/src/3rdPartyLibraries/json/sarif.hpp b/src/3rdPartyLibraries/json/sarif.hpp deleted file mode 100644 index 5bd2804e919..00000000000 --- a/src/3rdPartyLibraries/json/sarif.hpp +++ /dev/null @@ -1,6027 +0,0 @@ -// Automatically generated code for the schema defined by: -// -// https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json -// -// QuickType.io was used for the code generation -// -// To parse this JSON data, first install -// -// Boost http://www.boost.org -// json.hpp https://github.com/nlohmann/json -// -// Then include this file, and then do -// -// Coordinate data = nlohmann::json::parse(jsonString); - -#pragma once - -#include "nlohmann/json.hpp" - -#include -#include -#include -#include - -#ifndef NLOHMANN_OPT_HELPER -#define NLOHMANN_OPT_HELPER -namespace nlohmann { - template - struct adl_serializer> { - static void to_json(json & j, const std::shared_ptr & opt) { - if (!opt) j = nullptr; else j = *opt; - } - - static std::shared_ptr from_json(const json & j) { - if (j.is_null()) return std::unique_ptr(); else return std::unique_ptr(new T(j.get())); - } - }; -} -#endif - -namespace SARIF { - using nlohmann::json; - - const std::string VERSION = "2.1.0"; - const std::string SCHEMA = "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json"; - - class ClassMemberConstraints { - private: - boost::optional min_value; - boost::optional max_value; - boost::optional min_length; - boost::optional max_length; - boost::optional pattern; - - public: - ClassMemberConstraints( - boost::optional min_value, - boost::optional max_value, - boost::optional min_length, - boost::optional max_length, - boost::optional pattern - ) : min_value(min_value), max_value(max_value), min_length(min_length), max_length(max_length), pattern(pattern) {} - ClassMemberConstraints() = default; - virtual ~ClassMemberConstraints() = default; - - void set_min_value(int min_value) { this->min_value = min_value; } - auto get_min_value() const { return min_value; } - - void set_max_value(int max_value) { this->max_value = max_value; } - auto get_max_value() const { return max_value; } - - void set_min_length(size_t min_length) { this->min_length = min_length; } - auto get_min_length() const { return min_length; } - - void set_max_length(size_t max_length) { this->max_length = max_length; } - auto get_max_length() const { return max_length; } - - void set_pattern(const std::string & pattern) { this->pattern = pattern; } - auto get_pattern() const { return pattern; } - }; - - class ClassMemberConstraintException : public std::runtime_error { - public: - ClassMemberConstraintException(const std::string & msg) : std::runtime_error(msg) {} - }; - - class ValueTooLowException : public ClassMemberConstraintException { - public: - ValueTooLowException(const std::string & msg) : ClassMemberConstraintException(msg) {} - }; - - class ValueTooHighException : public ClassMemberConstraintException { - public: - ValueTooHighException(const std::string & msg) : ClassMemberConstraintException(msg) {} - }; - - class ValueTooShortException : public ClassMemberConstraintException { - public: - ValueTooShortException(const std::string & msg) : ClassMemberConstraintException(msg) {} - }; - - class ValueTooLongException : public ClassMemberConstraintException { - public: - ValueTooLongException(const std::string & msg) : ClassMemberConstraintException(msg) {} - }; - - class InvalidPatternException : public ClassMemberConstraintException { - public: - InvalidPatternException(const std::string & msg) : ClassMemberConstraintException(msg) {} - }; - - void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, int64_t value) { - if (c.get_min_value() != boost::none && value < *c.get_min_value()) { - throw ValueTooLowException ("Value too low for " + name + " (" + std::to_string(value) + "<" + std::to_string(*c.get_min_value()) + ")"); - } - - if (c.get_max_value() != boost::none && value > *c.get_max_value()) { - throw ValueTooHighException ("Value too high for " + name + " (" + std::to_string(value) + ">" + std::to_string(*c.get_max_value()) + ")"); - } - } - - void CheckConstraint(const std::string & name, const ClassMemberConstraints & c, const std::string & value) { - if (c.get_min_length() != boost::none && value.length() < *c.get_min_length()) { - throw ValueTooShortException ("Value too short for " + name + " (" + std::to_string(value.length()) + "<" + std::to_string(*c.get_min_length()) + ")"); - } - - if (c.get_max_length() != boost::none && value.length() > *c.get_max_length()) { - throw ValueTooLongException ("Value too long for " + name + " (" + std::to_string(value.length()) + ">" + std::to_string(*c.get_max_length()) + ")"); - } - - if (c.get_pattern() != boost::none) { - std::smatch result; - std::regex_search(value, result, std::regex( *c.get_pattern() )); - if (result.empty()) { - throw InvalidPatternException ("Value doesn't match pattern for " + name + " (" + value +" != " + *c.get_pattern() + ")"); - } - } - } - - inline json get_untyped(const json & j, const char * property) { - if (j.find(property) != j.end()) { - return j.at(property).get(); - } - return json(); - } - - inline json get_untyped(const json & j, std::string property) { - return get_untyped(j, property.data()); - } - - template - inline std::shared_ptr get_optional(const json & j, const char * property) { - if (j.find(property) != j.end()) { - return j.at(property).get>(); - } - return std::shared_ptr(); - } - - template - inline std::shared_ptr get_optional(const json & j, std::string property) { - return get_optional(j, property.data()); - } - - /** - * Key/value pairs that provide additional information about the address. - * - * Key/value pairs that provide additional information about the object. - * - * Key/value pairs that provide additional information about the artifact content. - * - * Key/value pairs that provide additional information about the message. - * - * Key/value pairs that provide additional information about the artifact location. - * - * Key/value pairs that provide additional information about the artifact. - * - * Contains configuration information specific to a report. - * - * Key/value pairs that provide additional information about the reporting configuration. - * - * Key/value pairs that provide additional information about the reporting descriptor - * reference. - * - * Key/value pairs that provide additional information about the toolComponentReference. - * - * Key/value pairs that provide additional information about the configuration override. - * - * Key/value pairs that provide additional information about the invocation. - * - * Key/value pairs that provide additional information about the exception. - * - * Key/value pairs that provide additional information about the region. - * - * Key/value pairs that provide additional information about the logical location. - * - * Key/value pairs that provide additional information about the physical location. - * - * Key/value pairs that provide additional information about the location. - * - * Key/value pairs that provide additional information about the location relationship. - * - * Key/value pairs that provide additional information about the stack frame. - * - * Key/value pairs that provide additional information about the stack. - * - * Key/value pairs that provide additional information about the notification. - * - * Key/value pairs that provide additional information about the conversion. - * - * Key/value pairs that provide additional information about the report. - * - * Key/value pairs that provide additional information about the tool component. - * - * Key/value pairs that provide additional information about the translation metadata. - * - * Key/value pairs that provide additional information about the tool. - * - * Key/value pairs that provide additional information that will be merged with a separate - * run. - * - * Key/value pairs that provide additional information about the edge. - * - * Key/value pairs that provide additional information about the node. - * - * Key/value pairs that provide additional information about the graph. - * - * Key/value pairs that provide additional information about the external properties. - * - * Key/value pairs that provide additional information about the attachment. - * - * Key/value pairs that provide additional information about the rectangle. - * - * Key/value pairs that provide additional information about the code flow. - * - * Key/value pairs that provide additional information about the threadflow location. - * - * Key/value pairs that provide additional information about the request. - * - * Key/value pairs that provide additional information about the response. - * - * Key/value pairs that provide additional information about the thread flow. - * - * Key/value pairs that provide additional information about the change. - * - * Key/value pairs that provide additional information about the replacement. - * - * Key/value pairs that provide additional information about the fix. - * - * Key/value pairs that provide additional information about the edge traversal. - * - * Key/value pairs that provide additional information about the graph traversal. - * - * Key/value pairs that provide additional information about the result. - * - * Key/value pairs that provide additional information about the suppression. - * - * Key/value pairs that provide additional information about the log file. - * - * Key/value pairs that provide additional information about the run automation details. - * - * Key/value pairs that provide additional information about the external property file. - * - * Key/value pairs that provide additional information about the external property files. - * - * Key/value pairs that provide additional information about the run. - * - * Key/value pairs that provide additional information about the special locations. - * - * Key/value pairs that provide additional information about the version control details. - */ - class PropertyBag { - public: - PropertyBag() = default; - virtual ~PropertyBag() = default; - - private: - std::shared_ptr> tags; - - public: - /** - * A set of distinct strings that provide additional information. - */ - std::shared_ptr> get_tags() const { return tags; } - void set_tags(std::shared_ptr> value) { this->tags = value; } - }; - - /** - * A physical or virtual address, or a range of addresses, in an 'addressable region' - * (memory or a binary file). - * - * The address of the location. - */ - class Address { - public: - Address() : - absolute_address_constraint(-1, boost::none, boost::none, boost::none, boost::none), - index_constraint(-1, boost::none, boost::none, boost::none, boost::none), - parent_index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~Address() = default; - - private: - std::shared_ptr absolute_address; - ClassMemberConstraints absolute_address_constraint; - std::shared_ptr fully_qualified_name; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr kind; - std::shared_ptr length; - std::shared_ptr name; - std::shared_ptr offset_from_parent; - std::shared_ptr parent_index; - ClassMemberConstraints parent_index_constraint; - std::shared_ptr properties; - std::shared_ptr relative_address; - - public: - /** - * The address expressed as a byte offset from the start of the addressable region. - */ - std::shared_ptr get_absolute_address() const { return absolute_address; } - void set_absolute_address(std::shared_ptr value) { if (value) CheckConstraint("absolute_address", absolute_address_constraint, *value); this->absolute_address = value; } - - /** - * A human-readable fully qualified name that is associated with the address. - */ - std::shared_ptr get_fully_qualified_name() const { return fully_qualified_name; } - void set_fully_qualified_name(std::shared_ptr value) { this->fully_qualified_name = value; } - - /** - * The index within run.addresses of the cached object for this address. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * An open-ended string that identifies the address kind. 'data', 'function', - * 'header','instruction', 'module', 'page', 'section', 'segment', 'stack', 'stackFrame', - * 'table' are well-known values. - */ - std::shared_ptr get_kind() const { return kind; } - void set_kind(std::shared_ptr value) { this->kind = value; } - - /** - * The number of bytes in this range of addresses. - */ - std::shared_ptr get_length() const { return length; } - void set_length(std::shared_ptr value) { this->length = value; } - - /** - * A name that is associated with the address, e.g., '.text'. - */ - std::shared_ptr get_name() const { return name; } - void set_name(std::shared_ptr value) { this->name = value; } - - /** - * The byte offset of this address from the absolute or relative address of the parent - * object. - */ - std::shared_ptr get_offset_from_parent() const { return offset_from_parent; } - void set_offset_from_parent(std::shared_ptr value) { this->offset_from_parent = value; } - - /** - * The index within run.addresses of the parent object. - */ - std::shared_ptr get_parent_index() const { return parent_index; } - void set_parent_index(std::shared_ptr value) { if (value) CheckConstraint("parent_index", parent_index_constraint, *value); this->parent_index = value; } - - /** - * Key/value pairs that provide additional information about the address. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The address expressed as a byte offset from the absolute address of the top-most parent - * object. - */ - std::shared_ptr get_relative_address() const { return relative_address; } - void set_relative_address(std::shared_ptr value) { this->relative_address = value; } - }; - - /** - * An alternate rendered representation of the artifact (e.g., a decompiled representation - * of a binary region). - * - * A message string or message format string rendered in multiple formats. - * - * A comprehensive description of the tool component. - * - * A description of the report. Should, as far as possible, provide details sufficient to - * enable resolution of any problem indicated by the result. - * - * Provides the primary documentation for the report, useful when there is no online - * documentation. - * - * A concise description of the report. Should be a single sentence that is understandable - * when visible space is limited to a single line of text. - * - * A brief description of the tool component. - * - * A comprehensive description of the translation metadata. - * - * A brief description of the translation metadata. - */ - class MultiformatMessageString { - public: - MultiformatMessageString() = default; - virtual ~MultiformatMessageString() = default; - - private: - std::shared_ptr markdown; - std::shared_ptr properties; - std::string text; - - public: - /** - * A Markdown message string or format string. - */ - std::shared_ptr get_markdown() const { return markdown; } - void set_markdown(std::shared_ptr value) { this->markdown = value; } - - /** - * Key/value pairs that provide additional information about the message. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A plain text message string or format string. - */ - const std::string & get_text() const { return text; } - std::string & get_mutable_text() { return text; } - void set_text(const std::string & value) { this->text = value; } - }; - - /** - * The contents of the artifact. - * - * Represents the contents of an artifact. - * - * The portion of the artifact contents within the specified region. - * - * The body of the request. - * - * The body of the response. - * - * The content to insert at the location specified by the 'deletedRegion' property. - */ - class ArtifactContent { - public: - ArtifactContent() = default; - virtual ~ArtifactContent() = default; - - private: - std::shared_ptr binary; - std::shared_ptr properties; - std::shared_ptr rendered; - std::shared_ptr text; - - public: - /** - * MIME Base64-encoded content from a binary artifact, or from a text artifact in its - * original encoding. - */ - std::shared_ptr get_binary() const { return binary; } - void set_binary(std::shared_ptr value) { this->binary = value; } - - /** - * Key/value pairs that provide additional information about the artifact content. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An alternate rendered representation of the artifact (e.g., a decompiled representation - * of a binary region). - */ - std::shared_ptr get_rendered() const { return rendered; } - void set_rendered(std::shared_ptr value) { this->rendered = value; } - - /** - * UTF-8-encoded content from a text artifact. - */ - std::shared_ptr get_text() const { return text; } - void set_text(std::shared_ptr value) { this->text = value; } - }; - - /** - * A short description of the artifact. - * - * A short description of the artifact location. - * - * A message relevant to the region. - * - * A message relevant to the location. - * - * A description of the location relationship. - * - * A message relevant to this call stack. - * - * A message that describes the condition that was encountered. - * - * A description of the reporting descriptor relationship. - * - * A description of the graph. - * - * A short description of the edge. - * - * A short description of the node. - * - * A message describing the role played by the attachment. - * - * A message relevant to the rectangle. - * - * A message relevant to the code flow. - * - * A message relevant to the thread flow. - * - * A message that describes the proposed fix, enabling viewers to present the proposed - * change to an end user. - * - * A description of this graph traversal. - * - * A message to display to the user as the edge is traversed. - * - * A message that describes the result. The first sentence of the message only will be - * displayed when visible space is limited. - * - * A description of the identity and role played within the engineering system by this - * object's containing run object. - * - * Encapsulates a message intended to be read by the end user. - */ - class Message { - public: - Message() = default; - virtual ~Message() = default; - - private: - std::shared_ptr> arguments; - std::shared_ptr id; - std::shared_ptr markdown; - std::shared_ptr properties; - std::shared_ptr text; - - public: - /** - * An array of strings to substitute into the message string. - */ - std::shared_ptr> get_arguments() const { return arguments; } - void set_arguments(std::shared_ptr> value) { this->arguments = value; } - - /** - * The identifier for this message. - */ - std::shared_ptr get_id() const { return id; } - void set_id(std::shared_ptr value) { this->id = value; } - - /** - * A Markdown message string. - */ - std::shared_ptr get_markdown() const { return markdown; } - void set_markdown(std::shared_ptr value) { this->markdown = value; } - - /** - * Key/value pairs that provide additional information about the message. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A plain text message string. - */ - std::shared_ptr get_text() const { return text; } - void set_text(std::shared_ptr value) { this->text = value; } - }; - - /** - * The location of the artifact. - * - * Specifies the location of an artifact. - * - * An absolute URI specifying the location of the executable that was invoked. - * - * A file containing the standard error stream from the process that was invoked. - * - * A file containing the standard input stream to the process that was invoked. - * - * A file containing the standard output stream from the process that was invoked. - * - * A file containing the interleaved standard output and standard error stream from the - * process that was invoked. - * - * The working directory for the invocation. - * - * Identifies the artifact that the analysis tool was instructed to scan. This need not be - * the same as the artifact where the result actually occurred. - * - * The location of the attachment. - * - * The location of the artifact to change. - * - * The location of the external property file. - * - * Provides a suggestion to SARIF consumers to display file paths relative to the specified - * location. - * - * The location in the local file system to which the root of the repository was mapped at - * the time of the analysis. - */ - class ArtifactLocation { - public: - ArtifactLocation() : - index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~ArtifactLocation() = default; - - private: - std::shared_ptr description; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr properties; - std::shared_ptr uri; - std::shared_ptr uri_base_id; - - public: - /** - * A short description of the artifact location. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * The index within the run artifacts array of the artifact object associated with the - * artifact location. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * Key/value pairs that provide additional information about the artifact location. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A string containing a valid relative or absolute URI. - */ - std::shared_ptr get_uri() const { return uri; } - void set_uri(std::shared_ptr value) { this->uri = value; } - - /** - * A string which indirectly specifies the absolute URI with respect to which a relative URI - * in the "uri" property is interpreted. - */ - std::shared_ptr get_uri_base_id() const { return uri_base_id; } - void set_uri_base_id(std::shared_ptr value) { this->uri_base_id = value; } - }; - - enum class Role : int { ADDED, ANALYSIS_TARGET, ATTACHMENT, DEBUG_OUTPUT_FILE, DELETED, DIRECTORY, DRIVER, EXTENSION, MEMORY_CONTENTS, MODIFIED, POLICY, REFERENCED_ON_COMMAND_LINE, RENAMED, RESPONSE_FILE, RESULT_FILE, STANDARD_STREAM, TAXONOMY, TOOL_SPECIFIED_CONFIGURATION, TRACED_FILE, TRANSLATION, UNCONTROLLED, UNMODIFIED, USER_SPECIFIED_CONFIGURATION }; - - /** - * A single artifact. In some cases, this artifact might be nested within another artifact. - */ - class Artifact { - public: - Artifact() : - length_constraint(-1, boost::none, boost::none, boost::none, boost::none), - mime_type_constraint(boost::none, boost::none, boost::none, boost::none, std::string("[^/]+/.+")), - offset_constraint(0, boost::none, boost::none, boost::none, boost::none), - parent_index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~Artifact() = default; - - private: - std::shared_ptr contents; - std::shared_ptr description; - std::shared_ptr encoding; - std::shared_ptr> hashes; - std::shared_ptr last_modified_time_utc; - std::shared_ptr length; - ClassMemberConstraints length_constraint; - std::shared_ptr location; - std::shared_ptr mime_type; - ClassMemberConstraints mime_type_constraint; - std::shared_ptr offset; - ClassMemberConstraints offset_constraint; - std::shared_ptr parent_index; - ClassMemberConstraints parent_index_constraint; - std::shared_ptr properties; - std::shared_ptr> roles; - std::shared_ptr source_language; - - public: - /** - * The contents of the artifact. - */ - std::shared_ptr get_contents() const { return contents; } - void set_contents(std::shared_ptr value) { this->contents = value; } - - /** - * A short description of the artifact. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * Specifies the encoding for an artifact object that refers to a text file. - */ - std::shared_ptr get_encoding() const { return encoding; } - void set_encoding(std::shared_ptr value) { this->encoding = value; } - - /** - * A dictionary, each of whose keys is the name of a hash function and each of whose values - * is the hashed value of the artifact produced by the specified hash function. - */ - std::shared_ptr> get_hashes() const { return hashes; } - void set_hashes(std::shared_ptr> value) { this->hashes = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the artifact was most - * recently modified. See "Date/time properties" in the SARIF spec for the required format. - */ - std::shared_ptr get_last_modified_time_utc() const { return last_modified_time_utc; } - void set_last_modified_time_utc(std::shared_ptr value) { this->last_modified_time_utc = value; } - - /** - * The length of the artifact in bytes. - */ - std::shared_ptr get_length() const { return length; } - void set_length(std::shared_ptr value) { if (value) CheckConstraint("length", length_constraint, *value); this->length = value; } - - /** - * The location of the artifact. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * The MIME type (RFC 2045) of the artifact. - */ - std::shared_ptr get_mime_type() const { return mime_type; } - void set_mime_type(std::shared_ptr value) { if (value) CheckConstraint("mime_type", mime_type_constraint, *value); this->mime_type = value; } - - /** - * The offset in bytes of the artifact within its containing artifact. - */ - std::shared_ptr get_offset() const { return offset; } - void set_offset(std::shared_ptr value) { if (value) CheckConstraint("offset", offset_constraint, *value); this->offset = value; } - - /** - * Identifies the index of the immediate parent of the artifact, if this artifact is nested. - */ - std::shared_ptr get_parent_index() const { return parent_index; } - void set_parent_index(std::shared_ptr value) { if (value) CheckConstraint("parent_index", parent_index_constraint, *value); this->parent_index = value; } - - /** - * Key/value pairs that provide additional information about the artifact. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The role or roles played by the artifact in the analysis. - */ - std::shared_ptr> get_roles() const { return roles; } - void set_roles(std::shared_ptr> value) { this->roles = value; } - - /** - * Specifies the source language for any artifact object that refers to a text file that - * contains source code. - */ - std::shared_ptr get_source_language() const { return source_language; } - void set_source_language(std::shared_ptr value) { this->source_language = value; } - }; - - /** - * Specifies the failure level for the report. - * - * A value specifying the severity level of the notification. - * - * A value specifying the severity level of the result. - */ - enum class Level : int { ERROR, NONE, NOTE, WARNING }; - - /** - * Specifies how the rule or notification was configured during the scan. - * - * Information about a rule or notification that can be configured at runtime. - * - * Default reporting configuration information. - */ - class ReportingConfiguration { - public: - ReportingConfiguration() : - rank_constraint(-1, 100, boost::none, boost::none, boost::none) - {} - virtual ~ReportingConfiguration() = default; - - private: - std::shared_ptr enabled; - std::shared_ptr level; - std::shared_ptr parameters; - std::shared_ptr properties; - std::shared_ptr rank; - ClassMemberConstraints rank_constraint; - - public: - /** - * Specifies whether the report may be produced during the scan. - */ - std::shared_ptr get_enabled() const { return enabled; } - void set_enabled(std::shared_ptr value) { this->enabled = value; } - - /** - * Specifies the failure level for the report. - */ - std::shared_ptr get_level() const { return level; } - void set_level(std::shared_ptr value) { this->level = value; } - - /** - * Contains configuration information specific to a report. - */ - std::shared_ptr get_parameters() const { return parameters; } - void set_parameters(std::shared_ptr value) { this->parameters = value; } - - /** - * Key/value pairs that provide additional information about the reporting configuration. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * Specifies the relative priority of the report. Used for analysis output only. - */ - std::shared_ptr get_rank() const { return rank; } - void set_rank(std::shared_ptr value) { if (value) CheckConstraint("rank", rank_constraint, *value); this->rank = value; } - }; - - /** - * A reference used to locate the toolComponent associated with the descriptor. - * - * Identifies a particular toolComponent object, either the driver or an extension. - * - * The component which is strongly associated with this component. For a translation, this - * refers to the component which has been translated. For an extension, this is the driver - * that provides the extension's plugin model. - */ - class ToolComponentReference { - public: - ToolComponentReference() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~ToolComponentReference() = default; - - private: - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr name; - std::shared_ptr properties; - - public: - /** - * The 'guid' property of the referenced toolComponent. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * An index into the referenced toolComponent in tool.extensions. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * The 'name' property of the referenced toolComponent. - */ - std::shared_ptr get_name() const { return name; } - void set_name(std::shared_ptr value) { this->name = value; } - - /** - * Key/value pairs that provide additional information about the toolComponentReference. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A reference used to locate the descriptor whose configuration was overridden. - * - * A reference used to locate the rule descriptor associated with this notification. - * - * A reference used to locate the descriptor relevant to this notification. - * - * A reference to the related reporting descriptor. - * - * A reference used to locate the rule descriptor relevant to this result. - * - * Information about how to locate a relevant reporting descriptor. - */ - class ReportingDescriptorReference { - public: - ReportingDescriptorReference() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~ReportingDescriptorReference() = default; - - private: - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr id; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr properties; - std::shared_ptr tool_component; - - public: - /** - * A guid that uniquely identifies the descriptor. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * The id of the descriptor. - */ - std::shared_ptr get_id() const { return id; } - void set_id(std::shared_ptr value) { this->id = value; } - - /** - * The index into an array of descriptors in toolComponent.ruleDescriptors, - * toolComponent.notificationDescriptors, or toolComponent.taxonomyDescriptors, depending on - * context. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * Key/value pairs that provide additional information about the reporting descriptor - * reference. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A reference used to locate the toolComponent associated with the descriptor. - */ - std::shared_ptr get_tool_component() const { return tool_component; } - void set_tool_component(std::shared_ptr value) { this->tool_component = value; } - }; - - /** - * Information about how a specific rule or notification was reconfigured at runtime. - */ - class ConfigurationOverride { - public: - ConfigurationOverride() = default; - virtual ~ConfigurationOverride() = default; - - private: - ReportingConfiguration configuration; - ReportingDescriptorReference descriptor; - std::shared_ptr properties; - - public: - /** - * Specifies how the rule or notification was configured during the scan. - */ - const ReportingConfiguration & get_configuration() const { return configuration; } - ReportingConfiguration & get_mutable_configuration() { return configuration; } - void set_configuration(const ReportingConfiguration & value) { this->configuration = value; } - - /** - * A reference used to locate the descriptor whose configuration was overridden. - */ - const ReportingDescriptorReference & get_descriptor() const { return descriptor; } - ReportingDescriptorReference & get_mutable_descriptor() { return descriptor; } - void set_descriptor(const ReportingDescriptorReference & value) { this->descriptor = value; } - - /** - * Key/value pairs that provide additional information about the configuration override. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A region within an artifact where a result was detected. - * - * Specifies a portion of the artifact that encloses the region. Allows a viewer to display - * additional context around the region. - * - * Specifies a portion of the artifact. - * - * The region of the artifact to delete. - */ - class Region { - public: - Region() : - byte_length_constraint(0, boost::none, boost::none, boost::none, boost::none), - byte_offset_constraint(-1, boost::none, boost::none, boost::none, boost::none), - char_length_constraint(0, boost::none, boost::none, boost::none, boost::none), - char_offset_constraint(-1, boost::none, boost::none, boost::none, boost::none), - end_column_constraint(1, boost::none, boost::none, boost::none, boost::none), - end_line_constraint(1, boost::none, boost::none, boost::none, boost::none), - start_column_constraint(1, boost::none, boost::none, boost::none, boost::none), - start_line_constraint(1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~Region() = default; - - private: - std::shared_ptr byte_length; - ClassMemberConstraints byte_length_constraint; - std::shared_ptr byte_offset; - ClassMemberConstraints byte_offset_constraint; - std::shared_ptr char_length; - ClassMemberConstraints char_length_constraint; - std::shared_ptr char_offset; - ClassMemberConstraints char_offset_constraint; - std::shared_ptr end_column; - ClassMemberConstraints end_column_constraint; - std::shared_ptr end_line; - ClassMemberConstraints end_line_constraint; - std::shared_ptr message; - std::shared_ptr properties; - std::shared_ptr snippet; - std::shared_ptr source_language; - std::shared_ptr start_column; - ClassMemberConstraints start_column_constraint; - std::shared_ptr start_line; - ClassMemberConstraints start_line_constraint; - - public: - /** - * The length of the region in bytes. - */ - std::shared_ptr get_byte_length() const { return byte_length; } - void set_byte_length(std::shared_ptr value) { if (value) CheckConstraint("byte_length", byte_length_constraint, *value); this->byte_length = value; } - - /** - * The zero-based offset from the beginning of the artifact of the first byte in the region. - */ - std::shared_ptr get_byte_offset() const { return byte_offset; } - void set_byte_offset(std::shared_ptr value) { if (value) CheckConstraint("byte_offset", byte_offset_constraint, *value); this->byte_offset = value; } - - /** - * The length of the region in characters. - */ - std::shared_ptr get_char_length() const { return char_length; } - void set_char_length(std::shared_ptr value) { if (value) CheckConstraint("char_length", char_length_constraint, *value); this->char_length = value; } - - /** - * The zero-based offset from the beginning of the artifact of the first character in the - * region. - */ - std::shared_ptr get_char_offset() const { return char_offset; } - void set_char_offset(std::shared_ptr value) { if (value) CheckConstraint("char_offset", char_offset_constraint, *value); this->char_offset = value; } - - /** - * The column number of the character following the end of the region. - */ - std::shared_ptr get_end_column() const { return end_column; } - void set_end_column(std::shared_ptr value) { if (value) CheckConstraint("end_column", end_column_constraint, *value); this->end_column = value; } - - /** - * The line number of the last character in the region. - */ - std::shared_ptr get_end_line() const { return end_line; } - void set_end_line(std::shared_ptr value) { if (value) CheckConstraint("end_line", end_line_constraint, *value); this->end_line = value; } - - /** - * A message relevant to the region. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the region. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The portion of the artifact contents within the specified region. - */ - std::shared_ptr get_snippet() const { return snippet; } - void set_snippet(std::shared_ptr value) { this->snippet = value; } - - /** - * Specifies the source language, if any, of the portion of the artifact specified by the - * region object. - */ - std::shared_ptr get_source_language() const { return source_language; } - void set_source_language(std::shared_ptr value) { this->source_language = value; } - - /** - * The column number of the first character in the region. - */ - std::shared_ptr get_start_column() const { return start_column; } - void set_start_column(std::shared_ptr value) { if (value) CheckConstraint("start_column", start_column_constraint, *value); this->start_column = value; } - - /** - * The line number of the first character in the region. - */ - std::shared_ptr get_start_line() const { return start_line; } - void set_start_line(std::shared_ptr value) { if (value) CheckConstraint("start_line", start_line_constraint, *value); this->start_line = value; } - }; - - /** - * A logical location of a construct that produced a result. - */ - class LogicalLocation { - public: - LogicalLocation() : - index_constraint(-1, boost::none, boost::none, boost::none, boost::none), - parent_index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~LogicalLocation() = default; - - private: - std::shared_ptr decorated_name; - std::shared_ptr fully_qualified_name; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr kind; - std::shared_ptr name; - std::shared_ptr parent_index; - ClassMemberConstraints parent_index_constraint; - std::shared_ptr properties; - - public: - /** - * The machine-readable name for the logical location, such as a mangled function name - * provided by a C++ compiler that encodes calling convention, return type and other details - * along with the function name. - */ - std::shared_ptr get_decorated_name() const { return decorated_name; } - void set_decorated_name(std::shared_ptr value) { this->decorated_name = value; } - - /** - * The human-readable fully qualified name of the logical location. - */ - std::shared_ptr get_fully_qualified_name() const { return fully_qualified_name; } - void set_fully_qualified_name(std::shared_ptr value) { this->fully_qualified_name = value; } - - /** - * The index within the logical locations array. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * The type of construct this logical location component refers to. Should be one of - * 'function', 'member', 'module', 'namespace', 'parameter', 'resource', 'returnType', - * 'type', 'variable', 'object', 'array', 'property', 'value', 'element', 'text', - * 'attribute', 'comment', 'declaration', 'dtd' or 'processingInstruction', if any of those - * accurately describe the construct. - */ - std::shared_ptr get_kind() const { return kind; } - void set_kind(std::shared_ptr value) { this->kind = value; } - - /** - * Identifies the construct in which the result occurred. For example, this property might - * contain the name of a class or a method. - */ - std::shared_ptr get_name() const { return name; } - void set_name(std::shared_ptr value) { this->name = value; } - - /** - * Identifies the index of the immediate parent of the construct in which the result was - * detected. For example, this property might point to a logical location that represents - * the namespace that holds a type. - */ - std::shared_ptr get_parent_index() const { return parent_index; } - void set_parent_index(std::shared_ptr value) { if (value) CheckConstraint("parent_index", parent_index_constraint, *value); this->parent_index = value; } - - /** - * Key/value pairs that provide additional information about the logical location. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * Identifies the artifact and region. - * - * A physical location relevant to a result. Specifies a reference to a programming artifact - * together with a range of bytes or characters within that artifact. - */ - class PhysicalLocation { - public: - PhysicalLocation() = default; - virtual ~PhysicalLocation() = default; - - private: - std::shared_ptr
address; - std::shared_ptr artifact_location; - std::shared_ptr context_region; - std::shared_ptr properties; - std::shared_ptr region; - - public: - /** - * The address of the location. - */ - std::shared_ptr
get_address() const { return address; } - void set_address(std::shared_ptr
value) { this->address = value; } - - /** - * The location of the artifact. - */ - std::shared_ptr get_artifact_location() const { return artifact_location; } - void set_artifact_location(std::shared_ptr value) { this->artifact_location = value; } - - /** - * Specifies a portion of the artifact that encloses the region. Allows a viewer to display - * additional context around the region. - */ - std::shared_ptr get_context_region() const { return context_region; } - void set_context_region(std::shared_ptr value) { this->context_region = value; } - - /** - * Key/value pairs that provide additional information about the physical location. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * Specifies a portion of the artifact. - */ - std::shared_ptr get_region() const { return region; } - void set_region(std::shared_ptr value) { this->region = value; } - }; - - /** - * Information about the relation of one location to another. - */ - class LocationRelationship { - public: - LocationRelationship() : - target_constraint(0, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~LocationRelationship() = default; - - private: - std::shared_ptr description; - std::shared_ptr> kinds; - std::shared_ptr properties; - int64_t target; - ClassMemberConstraints target_constraint; - - public: - /** - * A description of the location relationship. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * A set of distinct strings that categorize the relationship. Well-known kinds include - * 'includes', 'isIncludedBy' and 'relevant'. - */ - std::shared_ptr> get_kinds() const { return kinds; } - void set_kinds(std::shared_ptr> value) { this->kinds = value; } - - /** - * Key/value pairs that provide additional information about the location relationship. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A reference to the related location. - */ - const int64_t & get_target() const { return target; } - int64_t & get_mutable_target() { return target; } - void set_target(const int64_t & value) { CheckConstraint("target", target_constraint, value); this->target = value; } - }; - - /** - * The location to which this stack frame refers. - * - * A location within a programming artifact. - * - * A code location associated with the node. - * - * The code location. - * - * Identifies the location associated with the suppression. - */ - class Location { - public: - Location() : - id_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~Location() = default; - - private: - std::shared_ptr> annotations; - std::shared_ptr id; - ClassMemberConstraints id_constraint; - std::shared_ptr> logical_locations; - std::shared_ptr message; - std::shared_ptr physical_location; - std::shared_ptr properties; - std::shared_ptr> relationships; - - public: - /** - * A set of regions relevant to the location. - */ - std::shared_ptr> get_annotations() const { return annotations; } - void set_annotations(std::shared_ptr> value) { this->annotations = value; } - - /** - * Value that distinguishes this location from all other locations within a single result - * object. - */ - std::shared_ptr get_id() const { return id; } - void set_id(std::shared_ptr value) { if (value) CheckConstraint("id", id_constraint, *value); this->id = value; } - - /** - * The logical locations associated with the result. - */ - std::shared_ptr> get_logical_locations() const { return logical_locations; } - void set_logical_locations(std::shared_ptr> value) { this->logical_locations = value; } - - /** - * A message relevant to the location. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Identifies the artifact and region. - */ - std::shared_ptr get_physical_location() const { return physical_location; } - void set_physical_location(std::shared_ptr value) { this->physical_location = value; } - - /** - * Key/value pairs that provide additional information about the location. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of objects that describe relationships between this location and others. - */ - std::shared_ptr> get_relationships() const { return relationships; } - void set_relationships(std::shared_ptr> value) { this->relationships = value; } - }; - - /** - * A function call within a stack trace. - */ - class StackFrame { - public: - StackFrame() = default; - virtual ~StackFrame() = default; - - private: - std::shared_ptr location; - std::shared_ptr stack_frame_module; - std::shared_ptr> parameters; - std::shared_ptr properties; - std::shared_ptr thread_id; - - public: - /** - * The location to which this stack frame refers. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * The name of the module that contains the code of this stack frame. - */ - std::shared_ptr get_stack_frame_module() const { return stack_frame_module; } - void set_stack_frame_module(std::shared_ptr value) { this->stack_frame_module = value; } - - /** - * The parameters of the call that is executing. - */ - std::shared_ptr> get_parameters() const { return parameters; } - void set_parameters(std::shared_ptr> value) { this->parameters = value; } - - /** - * Key/value pairs that provide additional information about the stack frame. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The thread identifier of the stack frame. - */ - std::shared_ptr get_thread_id() const { return thread_id; } - void set_thread_id(std::shared_ptr value) { this->thread_id = value; } - }; - - /** - * The sequence of function calls leading to the exception. - * - * A call stack that is relevant to a result. - * - * The call stack leading to this location. - */ - class Stack { - public: - Stack() = default; - virtual ~Stack() = default; - - private: - std::vector frames; - std::shared_ptr message; - std::shared_ptr properties; - - public: - /** - * An array of stack frames that represents a sequence of calls, rendered in reverse - * chronological order, that comprise the call stack. - */ - const std::vector & get_frames() const { return frames; } - std::vector & get_mutable_frames() { return frames; } - void set_frames(const std::vector & value) { this->frames = value; } - - /** - * A message relevant to this call stack. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the stack. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * The runtime exception, if any, relevant to this notification. - * - * Describes a runtime exception encountered during the execution of an analysis tool. - */ - class Exception { - public: - Exception() = default; - virtual ~Exception() = default; - - private: - std::shared_ptr> inner_exceptions; - std::shared_ptr kind; - std::shared_ptr message; - std::shared_ptr properties; - std::shared_ptr stack; - - public: - /** - * An array of exception objects each of which is considered a cause of this exception. - */ - std::shared_ptr> get_inner_exceptions() const { return inner_exceptions; } - void set_inner_exceptions(std::shared_ptr> value) { this->inner_exceptions = value; } - - /** - * A string that identifies the kind of exception, for example, the fully qualified type - * name of an object that was thrown, or the symbolic name of a signal. - */ - std::shared_ptr get_kind() const { return kind; } - void set_kind(std::shared_ptr value) { this->kind = value; } - - /** - * A message that describes the exception. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the exception. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The sequence of function calls leading to the exception. - */ - std::shared_ptr get_stack() const { return stack; } - void set_stack(std::shared_ptr value) { this->stack = value; } - }; - - /** - * Describes a condition relevant to the tool itself, as opposed to being relevant to a - * target being analyzed by the tool. - */ - class Notification { - public: - Notification() = default; - virtual ~Notification() = default; - - private: - std::shared_ptr associated_rule; - std::shared_ptr descriptor; - std::shared_ptr exception; - std::shared_ptr level; - std::shared_ptr> locations; - Message message; - std::shared_ptr properties; - std::shared_ptr thread_id; - std::shared_ptr time_utc; - - public: - /** - * A reference used to locate the rule descriptor associated with this notification. - */ - std::shared_ptr get_associated_rule() const { return associated_rule; } - void set_associated_rule(std::shared_ptr value) { this->associated_rule = value; } - - /** - * A reference used to locate the descriptor relevant to this notification. - */ - std::shared_ptr get_descriptor() const { return descriptor; } - void set_descriptor(std::shared_ptr value) { this->descriptor = value; } - - /** - * The runtime exception, if any, relevant to this notification. - */ - std::shared_ptr get_exception() const { return exception; } - void set_exception(std::shared_ptr value) { this->exception = value; } - - /** - * A value specifying the severity level of the notification. - */ - std::shared_ptr get_level() const { return level; } - void set_level(std::shared_ptr value) { this->level = value; } - - /** - * The locations relevant to this notification. - */ - std::shared_ptr> get_locations() const { return locations; } - void set_locations(std::shared_ptr> value) { this->locations = value; } - - /** - * A message that describes the condition that was encountered. - */ - const Message & get_message() const { return message; } - Message & get_mutable_message() { return message; } - void set_message(const Message & value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the notification. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The thread identifier of the code that generated the notification. - */ - std::shared_ptr get_thread_id() const { return thread_id; } - void set_thread_id(std::shared_ptr value) { this->thread_id = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the analysis tool generated - * the notification. - */ - std::shared_ptr get_time_utc() const { return time_utc; } - void set_time_utc(std::shared_ptr value) { this->time_utc = value; } - }; - - /** - * An invocation object that describes the invocation of the converter. - * - * The runtime environment of the analysis tool run. - */ - class Invocation { - public: - Invocation() = default; - virtual ~Invocation() = default; - - private: - std::shared_ptr account; - std::shared_ptr> arguments; - std::shared_ptr command_line; - std::shared_ptr end_time_utc; - std::shared_ptr> environment_variables; - std::shared_ptr executable_location; - bool execution_successful; - std::shared_ptr exit_code; - std::shared_ptr exit_code_description; - std::shared_ptr exit_signal_name; - std::shared_ptr exit_signal_number; - std::shared_ptr machine; - std::shared_ptr> notification_configuration_overrides; - std::shared_ptr process_id; - std::shared_ptr process_start_failure_message; - std::shared_ptr properties; - std::shared_ptr> response_files; - std::shared_ptr> rule_configuration_overrides; - std::shared_ptr start_time_utc; - std::shared_ptr stderr; - std::shared_ptr stdin; - std::shared_ptr stdout; - std::shared_ptr stdout_stderr; - std::shared_ptr> tool_configuration_notifications; - std::shared_ptr> tool_execution_notifications; - std::shared_ptr working_directory; - - public: - /** - * The account under which the invocation occurred. - */ - std::shared_ptr get_account() const { return account; } - void set_account(std::shared_ptr value) { this->account = value; } - - /** - * An array of strings, containing in order the command line arguments passed to the tool - * from the operating system. - */ - std::shared_ptr> get_arguments() const { return arguments; } - void set_arguments(std::shared_ptr> value) { this->arguments = value; } - - /** - * The command line used to invoke the tool. - */ - std::shared_ptr get_command_line() const { return command_line; } - void set_command_line(std::shared_ptr value) { this->command_line = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the invocation ended. See - * "Date/time properties" in the SARIF spec for the required format. - */ - std::shared_ptr get_end_time_utc() const { return end_time_utc; } - void set_end_time_utc(std::shared_ptr value) { this->end_time_utc = value; } - - /** - * The environment variables associated with the analysis tool process, expressed as - * key/value pairs. - */ - std::shared_ptr> get_environment_variables() const { return environment_variables; } - void set_environment_variables(std::shared_ptr> value) { this->environment_variables = value; } - - /** - * An absolute URI specifying the location of the executable that was invoked. - */ - std::shared_ptr get_executable_location() const { return executable_location; } - void set_executable_location(std::shared_ptr value) { this->executable_location = value; } - - /** - * Specifies whether the tool's execution completed successfully. - */ - const bool & get_execution_successful() const { return execution_successful; } - bool & get_mutable_execution_successful() { return execution_successful; } - void set_execution_successful(const bool & value) { this->execution_successful = value; } - - /** - * The process exit code. - */ - std::shared_ptr get_exit_code() const { return exit_code; } - void set_exit_code(std::shared_ptr value) { this->exit_code = value; } - - /** - * The reason for the process exit. - */ - std::shared_ptr get_exit_code_description() const { return exit_code_description; } - void set_exit_code_description(std::shared_ptr value) { this->exit_code_description = value; } - - /** - * The name of the signal that caused the process to exit. - */ - std::shared_ptr get_exit_signal_name() const { return exit_signal_name; } - void set_exit_signal_name(std::shared_ptr value) { this->exit_signal_name = value; } - - /** - * The numeric value of the signal that caused the process to exit. - */ - std::shared_ptr get_exit_signal_number() const { return exit_signal_number; } - void set_exit_signal_number(std::shared_ptr value) { this->exit_signal_number = value; } - - /** - * The machine on which the invocation occurred. - */ - std::shared_ptr get_machine() const { return machine; } - void set_machine(std::shared_ptr value) { this->machine = value; } - - /** - * An array of configurationOverride objects that describe notifications related runtime - * overrides. - */ - std::shared_ptr> get_notification_configuration_overrides() const { return notification_configuration_overrides; } - void set_notification_configuration_overrides(std::shared_ptr> value) { this->notification_configuration_overrides = value; } - - /** - * The id of the process in which the invocation occurred. - */ - std::shared_ptr get_process_id() const { return process_id; } - void set_process_id(std::shared_ptr value) { this->process_id = value; } - - /** - * The reason given by the operating system that the process failed to start. - */ - std::shared_ptr get_process_start_failure_message() const { return process_start_failure_message; } - void set_process_start_failure_message(std::shared_ptr value) { this->process_start_failure_message = value; } - - /** - * Key/value pairs that provide additional information about the invocation. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The locations of any response files specified on the tool's command line. - */ - std::shared_ptr> get_response_files() const { return response_files; } - void set_response_files(std::shared_ptr> value) { this->response_files = value; } - - /** - * An array of configurationOverride objects that describe rules related runtime overrides. - */ - std::shared_ptr> get_rule_configuration_overrides() const { return rule_configuration_overrides; } - void set_rule_configuration_overrides(std::shared_ptr> value) { this->rule_configuration_overrides = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the invocation started. See - * "Date/time properties" in the SARIF spec for the required format. - */ - std::shared_ptr get_start_time_utc() const { return start_time_utc; } - void set_start_time_utc(std::shared_ptr value) { this->start_time_utc = value; } - - /** - * A file containing the standard error stream from the process that was invoked. - */ - std::shared_ptr get_stderr() const { return stderr; } - void set_stderr(std::shared_ptr value) { this->stderr = value; } - - /** - * A file containing the standard input stream to the process that was invoked. - */ - std::shared_ptr get_stdin() const { return stdin; } - void set_stdin(std::shared_ptr value) { this->stdin = value; } - - /** - * A file containing the standard output stream from the process that was invoked. - */ - std::shared_ptr get_stdout() const { return stdout; } - void set_stdout(std::shared_ptr value) { this->stdout = value; } - - /** - * A file containing the interleaved standard output and standard error stream from the - * process that was invoked. - */ - std::shared_ptr get_stdout_stderr() const { return stdout_stderr; } - void set_stdout_stderr(std::shared_ptr value) { this->stdout_stderr = value; } - - /** - * A list of conditions detected by the tool that are relevant to the tool's configuration. - */ - std::shared_ptr> get_tool_configuration_notifications() const { return tool_configuration_notifications; } - void set_tool_configuration_notifications(std::shared_ptr> value) { this->tool_configuration_notifications = value; } - - /** - * A list of runtime conditions detected by the tool during the analysis. - */ - std::shared_ptr> get_tool_execution_notifications() const { return tool_execution_notifications; } - void set_tool_execution_notifications(std::shared_ptr> value) { this->tool_execution_notifications = value; } - - /** - * The working directory for the invocation. - */ - std::shared_ptr get_working_directory() const { return working_directory; } - void set_working_directory(std::shared_ptr value) { this->working_directory = value; } - }; - - enum class Content : int { LOCALIZED_DATA, NON_LOCALIZED_DATA }; - - /** - * Information about the relation of one reporting descriptor to another. - */ - class ReportingDescriptorRelationship { - public: - ReportingDescriptorRelationship() = default; - virtual ~ReportingDescriptorRelationship() = default; - - private: - std::shared_ptr description; - std::shared_ptr> kinds; - std::shared_ptr properties; - ReportingDescriptorReference target; - - public: - /** - * A description of the reporting descriptor relationship. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * A set of distinct strings that categorize the relationship. Well-known kinds include - * 'canPrecede', 'canFollow', 'willPrecede', 'willFollow', 'superset', 'subset', 'equal', - * 'disjoint', 'relevant', and 'incomparable'. - */ - std::shared_ptr> get_kinds() const { return kinds; } - void set_kinds(std::shared_ptr> value) { this->kinds = value; } - - /** - * Key/value pairs that provide additional information about the reporting descriptor - * reference. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A reference to the related reporting descriptor. - */ - const ReportingDescriptorReference & get_target() const { return target; } - ReportingDescriptorReference & get_mutable_target() { return target; } - void set_target(const ReportingDescriptorReference & value) { this->target = value; } - }; - - /** - * Metadata that describes a specific report produced by the tool, as part of the analysis - * it provides or its runtime reporting. - */ - class ReportingDescriptor { - public: - ReportingDescriptor() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")) - {} - virtual ~ReportingDescriptor() = default; - - private: - std::shared_ptr default_configuration; - std::shared_ptr> deprecated_guids; - std::shared_ptr> deprecated_ids; - std::shared_ptr> deprecated_names; - std::shared_ptr full_description; - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr help; - std::shared_ptr help_uri; - std::string id; - std::shared_ptr> message_strings; - std::shared_ptr name; - std::shared_ptr properties; - std::shared_ptr> relationships; - std::shared_ptr short_description; - - public: - /** - * Default reporting configuration information. - */ - std::shared_ptr get_default_configuration() const { return default_configuration; } - void set_default_configuration(std::shared_ptr value) { this->default_configuration = value; } - - /** - * An array of unique identifies in the form of a GUID by which this report was known in - * some previous version of the analysis tool. - */ - std::shared_ptr> get_deprecated_guids() const { return deprecated_guids; } - void set_deprecated_guids(std::shared_ptr> value) { this->deprecated_guids = value; } - - /** - * An array of stable, opaque identifiers by which this report was known in some previous - * version of the analysis tool. - */ - std::shared_ptr> get_deprecated_ids() const { return deprecated_ids; } - void set_deprecated_ids(std::shared_ptr> value) { this->deprecated_ids = value; } - - /** - * An array of readable identifiers by which this report was known in some previous version - * of the analysis tool. - */ - std::shared_ptr> get_deprecated_names() const { return deprecated_names; } - void set_deprecated_names(std::shared_ptr> value) { this->deprecated_names = value; } - - /** - * A description of the report. Should, as far as possible, provide details sufficient to - * enable resolution of any problem indicated by the result. - */ - std::shared_ptr get_full_description() const { return full_description; } - void set_full_description(std::shared_ptr value) { this->full_description = value; } - - /** - * A unique identifer for the reporting descriptor in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * Provides the primary documentation for the report, useful when there is no online - * documentation. - */ - std::shared_ptr get_help() const { return help; } - void set_help(std::shared_ptr value) { this->help = value; } - - /** - * A URI where the primary documentation for the report can be found. - */ - std::shared_ptr get_help_uri() const { return help_uri; } - void set_help_uri(std::shared_ptr value) { this->help_uri = value; } - - /** - * A stable, opaque identifier for the report. - */ - const std::string & get_id() const { return id; } - std::string & get_mutable_id() { return id; } - void set_id(const std::string & value) { this->id = value; } - - /** - * A set of name/value pairs with arbitrary names. Each value is a multiformatMessageString - * object, which holds message strings in plain text and (optionally) Markdown format. The - * strings can include placeholders, which can be used to construct a message in combination - * with an arbitrary number of additional string arguments. - */ - std::shared_ptr> get_message_strings() const { return message_strings; } - void set_message_strings(std::shared_ptr> value) { this->message_strings = value; } - - /** - * A report identifier that is understandable to an end user. - */ - std::shared_ptr get_name() const { return name; } - void set_name(std::shared_ptr value) { this->name = value; } - - /** - * Key/value pairs that provide additional information about the report. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of objects that describe relationships between this reporting descriptor and - * others. - */ - std::shared_ptr> get_relationships() const { return relationships; } - void set_relationships(std::shared_ptr> value) { this->relationships = value; } - - /** - * A concise description of the report. Should be a single sentence that is understandable - * when visible space is limited to a single line of text. - */ - std::shared_ptr get_short_description() const { return short_description; } - void set_short_description(std::shared_ptr value) { this->short_description = value; } - }; - - /** - * Translation metadata, required for a translation, not populated by other component - * types. - * - * Provides additional metadata related to translation. - */ - class TranslationMetadata { - public: - TranslationMetadata() = default; - virtual ~TranslationMetadata() = default; - - private: - std::shared_ptr download_uri; - std::shared_ptr full_description; - std::shared_ptr full_name; - std::shared_ptr information_uri; - std::string name; - std::shared_ptr properties; - std::shared_ptr short_description; - - public: - /** - * The absolute URI from which the translation metadata can be downloaded. - */ - std::shared_ptr get_download_uri() const { return download_uri; } - void set_download_uri(std::shared_ptr value) { this->download_uri = value; } - - /** - * A comprehensive description of the translation metadata. - */ - std::shared_ptr get_full_description() const { return full_description; } - void set_full_description(std::shared_ptr value) { this->full_description = value; } - - /** - * The full name associated with the translation metadata. - */ - std::shared_ptr get_full_name() const { return full_name; } - void set_full_name(std::shared_ptr value) { this->full_name = value; } - - /** - * The absolute URI from which information related to the translation metadata can be - * downloaded. - */ - std::shared_ptr get_information_uri() const { return information_uri; } - void set_information_uri(std::shared_ptr value) { this->information_uri = value; } - - /** - * The name associated with the translation metadata. - */ - const std::string & get_name() const { return name; } - std::string & get_mutable_name() { return name; } - void set_name(const std::string & value) { this->name = value; } - - /** - * Key/value pairs that provide additional information about the translation metadata. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A brief description of the translation metadata. - */ - std::shared_ptr get_short_description() const { return short_description; } - void set_short_description(std::shared_ptr value) { this->short_description = value; } - }; - - /** - * The analysis tool that was run. - * - * A component, such as a plug-in or the driver, of the analysis tool that was run. - * - * The analysis tool object that will be merged with a separate run. - */ - class ToolComponent { - public: - ToolComponent() : - dotted_quad_file_version_constraint(boost::none, boost::none, boost::none, boost::none, std::string("[0-9]+(\\.[0-9]+){3}")), - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - language_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[a-zA-Z]{2}|^[a-zA-Z]{2}-[a-zA-Z]{2}]?$")) - {} - virtual ~ToolComponent() = default; - - private: - std::shared_ptr associated_component; - std::shared_ptr> contents; - std::shared_ptr dotted_quad_file_version; - ClassMemberConstraints dotted_quad_file_version_constraint; - std::shared_ptr download_uri; - std::shared_ptr full_description; - std::shared_ptr full_name; - std::shared_ptr> global_message_strings; - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr information_uri; - std::shared_ptr is_comprehensive; - std::shared_ptr language; - ClassMemberConstraints language_constraint; - std::shared_ptr localized_data_semantic_version; - std::shared_ptr> locations; - std::shared_ptr minimum_required_localized_data_semantic_version; - std::string name; - std::shared_ptr> notifications; - std::shared_ptr organization; - std::shared_ptr product; - std::shared_ptr product_suite; - std::shared_ptr properties; - std::shared_ptr release_date_utc; - std::shared_ptr> rules; - std::shared_ptr semantic_version; - std::shared_ptr short_description; - std::shared_ptr> supported_taxonomies; - std::shared_ptr> taxa; - std::shared_ptr translation_metadata; - std::shared_ptr version; - - public: - /** - * The component which is strongly associated with this component. For a translation, this - * refers to the component which has been translated. For an extension, this is the driver - * that provides the extension's plugin model. - */ - std::shared_ptr get_associated_component() const { return associated_component; } - void set_associated_component(std::shared_ptr value) { this->associated_component = value; } - - /** - * The kinds of data contained in this object. - */ - std::shared_ptr> get_contents() const { return contents; } - void set_contents(std::shared_ptr> value) { this->contents = value; } - - /** - * The binary version of the tool component's primary executable file expressed as four - * non-negative integers separated by a period (for operating systems that express file - * versions in this way). - */ - std::shared_ptr get_dotted_quad_file_version() const { return dotted_quad_file_version; } - void set_dotted_quad_file_version(std::shared_ptr value) { if (value) CheckConstraint("dotted_quad_file_version", dotted_quad_file_version_constraint, *value); this->dotted_quad_file_version = value; } - - /** - * The absolute URI from which the tool component can be downloaded. - */ - std::shared_ptr get_download_uri() const { return download_uri; } - void set_download_uri(std::shared_ptr value) { this->download_uri = value; } - - /** - * A comprehensive description of the tool component. - */ - std::shared_ptr get_full_description() const { return full_description; } - void set_full_description(std::shared_ptr value) { this->full_description = value; } - - /** - * The name of the tool component along with its version and any other useful identifying - * information, such as its locale. - */ - std::shared_ptr get_full_name() const { return full_name; } - void set_full_name(std::shared_ptr value) { this->full_name = value; } - - /** - * A dictionary, each of whose keys is a resource identifier and each of whose values is a - * multiformatMessageString object, which holds message strings in plain text and - * (optionally) Markdown format. The strings can include placeholders, which can be used to - * construct a message in combination with an arbitrary number of additional string - * arguments. - */ - std::shared_ptr> get_global_message_strings() const { return global_message_strings; } - void set_global_message_strings(std::shared_ptr> value) { this->global_message_strings = value; } - - /** - * A unique identifer for the tool component in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * The absolute URI at which information about this version of the tool component can be - * found. - */ - std::shared_ptr get_information_uri() const { return information_uri; } - void set_information_uri(std::shared_ptr value) { this->information_uri = value; } - - /** - * Specifies whether this object contains a complete definition of the localizable and/or - * non-localizable data for this component, as opposed to including only data that is - * relevant to the results persisted to this log file. - */ - std::shared_ptr get_is_comprehensive() const { return is_comprehensive; } - void set_is_comprehensive(std::shared_ptr value) { this->is_comprehensive = value; } - - /** - * The language of the messages emitted into the log file during this run (expressed as an - * ISO 639-1 two-letter lowercase language code) and an optional region (expressed as an ISO - * 3166-1 two-letter uppercase subculture code associated with a country or region). The - * casing is recommended but not required (in order for this data to conform to RFC5646). - */ - std::shared_ptr get_language() const { return language; } - void set_language(std::shared_ptr value) { if (value) CheckConstraint("language", language_constraint, *value); this->language = value; } - - /** - * The semantic version of the localized strings defined in this component; maintained by - * components that provide translations. - */ - std::shared_ptr get_localized_data_semantic_version() const { return localized_data_semantic_version; } - void set_localized_data_semantic_version(std::shared_ptr value) { this->localized_data_semantic_version = value; } - - /** - * An array of the artifactLocation objects associated with the tool component. - */ - std::shared_ptr> get_locations() const { return locations; } - void set_locations(std::shared_ptr> value) { this->locations = value; } - - /** - * The minimum value of localizedDataSemanticVersion required in translations consumed by - * this component; used by components that consume translations. - */ - std::shared_ptr get_minimum_required_localized_data_semantic_version() const { return minimum_required_localized_data_semantic_version; } - void set_minimum_required_localized_data_semantic_version(std::shared_ptr value) { this->minimum_required_localized_data_semantic_version = value; } - - /** - * The name of the tool component. - */ - const std::string & get_name() const { return name; } - std::string & get_mutable_name() { return name; } - void set_name(const std::string & value) { this->name = value; } - - /** - * An array of reportingDescriptor objects relevant to the notifications related to the - * configuration and runtime execution of the tool component. - */ - std::shared_ptr> get_notifications() const { return notifications; } - void set_notifications(std::shared_ptr> value) { this->notifications = value; } - - /** - * The organization or company that produced the tool component. - */ - std::shared_ptr get_organization() const { return organization; } - void set_organization(std::shared_ptr value) { this->organization = value; } - - /** - * A product suite to which the tool component belongs. - */ - std::shared_ptr get_product() const { return product; } - void set_product(std::shared_ptr value) { this->product = value; } - - /** - * A localizable string containing the name of the suite of products to which the tool - * component belongs. - */ - std::shared_ptr get_product_suite() const { return product_suite; } - void set_product_suite(std::shared_ptr value) { this->product_suite = value; } - - /** - * Key/value pairs that provide additional information about the tool component. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A string specifying the UTC date (and optionally, the time) of the component's release. - */ - std::shared_ptr get_release_date_utc() const { return release_date_utc; } - void set_release_date_utc(std::shared_ptr value) { this->release_date_utc = value; } - - /** - * An array of reportingDescriptor objects relevant to the analysis performed by the tool - * component. - */ - std::shared_ptr> get_rules() const { return rules; } - void set_rules(std::shared_ptr> value) { this->rules = value; } - - /** - * The tool component version in the format specified by Semantic Versioning 2.0. - */ - std::shared_ptr get_semantic_version() const { return semantic_version; } - void set_semantic_version(std::shared_ptr value) { this->semantic_version = value; } - - /** - * A brief description of the tool component. - */ - std::shared_ptr get_short_description() const { return short_description; } - void set_short_description(std::shared_ptr value) { this->short_description = value; } - - /** - * An array of toolComponentReference objects to declare the taxonomies supported by the - * tool component. - */ - std::shared_ptr> get_supported_taxonomies() const { return supported_taxonomies; } - void set_supported_taxonomies(std::shared_ptr> value) { this->supported_taxonomies = value; } - - /** - * An array of reportingDescriptor objects relevant to the definitions of both standalone - * and tool-defined taxonomies. - */ - std::shared_ptr> get_taxa() const { return taxa; } - void set_taxa(std::shared_ptr> value) { this->taxa = value; } - - /** - * Translation metadata, required for a translation, not populated by other component types. - */ - std::shared_ptr get_translation_metadata() const { return translation_metadata; } - void set_translation_metadata(std::shared_ptr value) { this->translation_metadata = value; } - - /** - * The tool component version, in whatever format the component natively provides. - */ - std::shared_ptr get_version() const { return version; } - void set_version(std::shared_ptr value) { this->version = value; } - }; - - /** - * A tool object that describes the converter. - * - * The analysis tool that was run. - * - * Information about the tool or tool pipeline that generated the results in this run. A run - * can only contain results produced by a single tool or tool pipeline. A run can aggregate - * results from multiple log files, as long as context around the tool run (tool - * command-line arguments and the like) is identical for all aggregated files. - */ - class Tool { - public: - Tool() = default; - virtual ~Tool() = default; - - private: - ToolComponent driver; - std::shared_ptr> extensions; - std::shared_ptr properties; - - public: - /** - * The analysis tool that was run. - */ - const ToolComponent & get_driver() const { return driver; } - ToolComponent & get_mutable_driver() { return driver; } - void set_driver(const ToolComponent & value) { this->driver = value; } - - /** - * Tool extensions that contributed to or reconfigured the analysis tool that was run. - */ - std::shared_ptr> get_extensions() const { return extensions; } - void set_extensions(std::shared_ptr> value) { this->extensions = value; } - - /** - * Key/value pairs that provide additional information about the tool. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A conversion object that will be merged with a separate run. - * - * Describes how a converter transformed the output of a static analysis tool from the - * analysis tool's native output format into the SARIF format. - * - * A conversion object that describes how a converter transformed an analysis tool's native - * reporting format into the SARIF format. - */ - class Conversion { - public: - Conversion() = default; - virtual ~Conversion() = default; - - private: - std::shared_ptr> analysis_tool_log_files; - std::shared_ptr invocation; - std::shared_ptr properties; - Tool tool; - - public: - /** - * The locations of the analysis tool's per-run log files. - */ - std::shared_ptr> get_analysis_tool_log_files() const { return analysis_tool_log_files; } - void set_analysis_tool_log_files(std::shared_ptr> value) { this->analysis_tool_log_files = value; } - - /** - * An invocation object that describes the invocation of the converter. - */ - std::shared_ptr get_invocation() const { return invocation; } - void set_invocation(std::shared_ptr value) { this->invocation = value; } - - /** - * Key/value pairs that provide additional information about the conversion. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A tool object that describes the converter. - */ - const Tool & get_tool() const { return tool; } - Tool & get_mutable_tool() { return tool; } - void set_tool(const Tool & value) { this->tool = value; } - }; - - /** - * Represents a directed edge in a graph. - */ - class Edge { - public: - Edge() = default; - virtual ~Edge() = default; - - private: - std::string id; - std::shared_ptr label; - std::shared_ptr properties; - std::string source_node_id; - std::string target_node_id; - - public: - /** - * A string that uniquely identifies the edge within its graph. - */ - const std::string & get_id() const { return id; } - std::string & get_mutable_id() { return id; } - void set_id(const std::string & value) { this->id = value; } - - /** - * A short description of the edge. - */ - std::shared_ptr get_label() const { return label; } - void set_label(std::shared_ptr value) { this->label = value; } - - /** - * Key/value pairs that provide additional information about the edge. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * Identifies the source node (the node at which the edge starts). - */ - const std::string & get_source_node_id() const { return source_node_id; } - std::string & get_mutable_source_node_id() { return source_node_id; } - void set_source_node_id(const std::string & value) { this->source_node_id = value; } - - /** - * Identifies the target node (the node at which the edge ends). - */ - const std::string & get_target_node_id() const { return target_node_id; } - std::string & get_mutable_target_node_id() { return target_node_id; } - void set_target_node_id(const std::string & value) { this->target_node_id = value; } - }; - - /** - * Represents a node in a graph. - */ - class Node { - public: - Node() = default; - virtual ~Node() = default; - - private: - std::shared_ptr> children; - std::string id; - std::shared_ptr label; - std::shared_ptr location; - std::shared_ptr properties; - - public: - /** - * Array of child nodes. - */ - std::shared_ptr> get_children() const { return children; } - void set_children(std::shared_ptr> value) { this->children = value; } - - /** - * A string that uniquely identifies the node within its graph. - */ - const std::string & get_id() const { return id; } - std::string & get_mutable_id() { return id; } - void set_id(const std::string & value) { this->id = value; } - - /** - * A short description of the node. - */ - std::shared_ptr get_label() const { return label; } - void set_label(std::shared_ptr value) { this->label = value; } - - /** - * A code location associated with the node. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * Key/value pairs that provide additional information about the node. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A network of nodes and directed edges that describes some aspect of the structure of the - * code (for example, a call graph). - */ - class Graph { - public: - Graph() = default; - virtual ~Graph() = default; - - private: - std::shared_ptr description; - std::shared_ptr> edges; - std::shared_ptr> nodes; - std::shared_ptr properties; - - public: - /** - * A description of the graph. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * An array of edge objects representing the edges of the graph. - */ - std::shared_ptr> get_edges() const { return edges; } - void set_edges(std::shared_ptr> value) { this->edges = value; } - - /** - * An array of node objects representing the nodes of the graph. - */ - std::shared_ptr> get_nodes() const { return nodes; } - void set_nodes(std::shared_ptr> value) { this->nodes = value; } - - /** - * Key/value pairs that provide additional information about the graph. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * An area within an image. - */ - class Rectangle { - public: - Rectangle() = default; - virtual ~Rectangle() = default; - - private: - std::shared_ptr bottom; - std::shared_ptr left; - std::shared_ptr message; - std::shared_ptr properties; - std::shared_ptr right; - std::shared_ptr top; - - public: - /** - * The Y coordinate of the bottom edge of the rectangle, measured in the image's natural - * units. - */ - std::shared_ptr get_bottom() const { return bottom; } - void set_bottom(std::shared_ptr value) { this->bottom = value; } - - /** - * The X coordinate of the left edge of the rectangle, measured in the image's natural units. - */ - std::shared_ptr get_left() const { return left; } - void set_left(std::shared_ptr value) { this->left = value; } - - /** - * A message relevant to the rectangle. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the rectangle. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The X coordinate of the right edge of the rectangle, measured in the image's natural - * units. - */ - std::shared_ptr get_right() const { return right; } - void set_right(std::shared_ptr value) { this->right = value; } - - /** - * The Y coordinate of the top edge of the rectangle, measured in the image's natural units. - */ - std::shared_ptr get_top() const { return top; } - void set_top(std::shared_ptr value) { this->top = value; } - }; - - /** - * An artifact relevant to a result. - */ - class Attachment { - public: - Attachment() = default; - virtual ~Attachment() = default; - - private: - ArtifactLocation artifact_location; - std::shared_ptr description; - std::shared_ptr properties; - std::shared_ptr> rectangles; - std::shared_ptr> regions; - - public: - /** - * The location of the attachment. - */ - const ArtifactLocation & get_artifact_location() const { return artifact_location; } - ArtifactLocation & get_mutable_artifact_location() { return artifact_location; } - void set_artifact_location(const ArtifactLocation & value) { this->artifact_location = value; } - - /** - * A message describing the role played by the attachment. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * Key/value pairs that provide additional information about the attachment. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of rectangles specifying areas of interest within the image. - */ - std::shared_ptr> get_rectangles() const { return rectangles; } - void set_rectangles(std::shared_ptr> value) { this->rectangles = value; } - - /** - * An array of regions of interest within the attachment. - */ - std::shared_ptr> get_regions() const { return regions; } - void set_regions(std::shared_ptr> value) { this->regions = value; } - }; - - /** - * The state of a result relative to a baseline of a previous run. - */ - enum class BaselineState : int { ABSENT, NEW, UNCHANGED, UPDATED }; - - /** - * Specifies the importance of this location in understanding the code flow in which it - * occurs. The order from most to least important is "essential", "important", - * "unimportant". Default: "important". - */ - enum class Importance : int { ESSENTIAL, IMPORTANT, UNIMPORTANT }; - - /** - * A web request associated with this thread flow location. - * - * Describes an HTTP request. - * - * A web request associated with this result. - */ - class WebRequest { - public: - WebRequest() : - index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~WebRequest() = default; - - private: - std::shared_ptr body; - std::shared_ptr> headers; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr method; - std::shared_ptr> parameters; - std::shared_ptr properties; - std::shared_ptr protocol; - std::shared_ptr target; - std::shared_ptr version; - - public: - /** - * The body of the request. - */ - std::shared_ptr get_body() const { return body; } - void set_body(std::shared_ptr value) { this->body = value; } - - /** - * The request headers. - */ - std::shared_ptr> get_headers() const { return headers; } - void set_headers(std::shared_ptr> value) { this->headers = value; } - - /** - * The index within the run.webRequests array of the request object associated with this - * result. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * The HTTP method. Well-known values are 'GET', 'PUT', 'POST', 'DELETE', 'PATCH', 'HEAD', - * 'OPTIONS', 'TRACE', 'CONNECT'. - */ - std::shared_ptr get_method() const { return method; } - void set_method(std::shared_ptr value) { this->method = value; } - - /** - * The request parameters. - */ - std::shared_ptr> get_parameters() const { return parameters; } - void set_parameters(std::shared_ptr> value) { this->parameters = value; } - - /** - * Key/value pairs that provide additional information about the request. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The request protocol. Example: 'http'. - */ - std::shared_ptr get_protocol() const { return protocol; } - void set_protocol(std::shared_ptr value) { this->protocol = value; } - - /** - * The target of the request. - */ - std::shared_ptr get_target() const { return target; } - void set_target(std::shared_ptr value) { this->target = value; } - - /** - * The request version. Example: '1.1'. - */ - std::shared_ptr get_version() const { return version; } - void set_version(std::shared_ptr value) { this->version = value; } - }; - - /** - * A web response associated with this thread flow location. - * - * Describes the response to an HTTP request. - * - * A web response associated with this result. - */ - class WebResponse { - public: - WebResponse() : - index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~WebResponse() = default; - - private: - std::shared_ptr body; - std::shared_ptr> headers; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr no_response_received; - std::shared_ptr properties; - std::shared_ptr protocol; - std::shared_ptr reason_phrase; - std::shared_ptr status_code; - std::shared_ptr version; - - public: - /** - * The body of the response. - */ - std::shared_ptr get_body() const { return body; } - void set_body(std::shared_ptr value) { this->body = value; } - - /** - * The response headers. - */ - std::shared_ptr> get_headers() const { return headers; } - void set_headers(std::shared_ptr> value) { this->headers = value; } - - /** - * The index within the run.webResponses array of the response object associated with this - * result. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * Specifies whether a response was received from the server. - */ - std::shared_ptr get_no_response_received() const { return no_response_received; } - void set_no_response_received(std::shared_ptr value) { this->no_response_received = value; } - - /** - * Key/value pairs that provide additional information about the response. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The response protocol. Example: 'http'. - */ - std::shared_ptr get_protocol() const { return protocol; } - void set_protocol(std::shared_ptr value) { this->protocol = value; } - - /** - * The response reason. Example: 'Not found'. - */ - std::shared_ptr get_reason_phrase() const { return reason_phrase; } - void set_reason_phrase(std::shared_ptr value) { this->reason_phrase = value; } - - /** - * The response status code. Example: 451. - */ - std::shared_ptr get_status_code() const { return status_code; } - void set_status_code(std::shared_ptr value) { this->status_code = value; } - - /** - * The response version. Example: '1.1'. - */ - std::shared_ptr get_version() const { return version; } - void set_version(std::shared_ptr value) { this->version = value; } - }; - - /** - * A location visited by an analysis tool while simulating or monitoring the execution of a - * program. - */ - class ThreadFlowLocation { - public: - ThreadFlowLocation() : - execution_order_constraint(-1, boost::none, boost::none, boost::none, boost::none), - index_constraint(-1, boost::none, boost::none, boost::none, boost::none), - nesting_level_constraint(0, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~ThreadFlowLocation() = default; - - private: - std::shared_ptr execution_order; - ClassMemberConstraints execution_order_constraint; - std::shared_ptr execution_time_utc; - std::shared_ptr importance; - std::shared_ptr index; - ClassMemberConstraints index_constraint; - std::shared_ptr> kinds; - std::shared_ptr location; - std::shared_ptr thread_flow_location_module; - std::shared_ptr nesting_level; - ClassMemberConstraints nesting_level_constraint; - std::shared_ptr properties; - std::shared_ptr stack; - std::shared_ptr> state; - std::shared_ptr> taxa; - std::shared_ptr web_request; - std::shared_ptr web_response; - - public: - /** - * An integer representing the temporal order in which execution reached this location. - */ - std::shared_ptr get_execution_order() const { return execution_order; } - void set_execution_order(std::shared_ptr value) { if (value) CheckConstraint("execution_order", execution_order_constraint, *value); this->execution_order = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which this location was executed. - */ - std::shared_ptr get_execution_time_utc() const { return execution_time_utc; } - void set_execution_time_utc(std::shared_ptr value) { this->execution_time_utc = value; } - - /** - * Specifies the importance of this location in understanding the code flow in which it - * occurs. The order from most to least important is "essential", "important", - * "unimportant". Default: "important". - */ - std::shared_ptr get_importance() const { return importance; } - void set_importance(std::shared_ptr value) { this->importance = value; } - - /** - * The index within the run threadFlowLocations array. - */ - std::shared_ptr get_index() const { return index; } - void set_index(std::shared_ptr value) { if (value) CheckConstraint("index", index_constraint, *value); this->index = value; } - - /** - * A set of distinct strings that categorize the thread flow location. Well-known kinds - * include 'acquire', 'release', 'enter', 'exit', 'call', 'return', 'branch', 'implicit', - * 'false', 'true', 'caution', 'danger', 'unknown', 'unreachable', 'taint', 'function', - * 'handler', 'lock', 'memory', 'resource', 'scope' and 'value'. - */ - std::shared_ptr> get_kinds() const { return kinds; } - void set_kinds(std::shared_ptr> value) { this->kinds = value; } - - /** - * The code location. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * The name of the module that contains the code that is executing. - */ - std::shared_ptr get_thread_flow_location_module() const { return thread_flow_location_module; } - void set_thread_flow_location_module(std::shared_ptr value) { this->thread_flow_location_module = value; } - - /** - * An integer representing a containment hierarchy within the thread flow. - */ - std::shared_ptr get_nesting_level() const { return nesting_level; } - void set_nesting_level(std::shared_ptr value) { if (value) CheckConstraint("nesting_level", nesting_level_constraint, *value); this->nesting_level = value; } - - /** - * Key/value pairs that provide additional information about the threadflow location. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The call stack leading to this location. - */ - std::shared_ptr get_stack() const { return stack; } - void set_stack(std::shared_ptr value) { this->stack = value; } - - /** - * A dictionary, each of whose keys specifies a variable or expression, the associated value - * of which represents the variable or expression value. For an annotation of kind - * 'continuation', for example, this dictionary might hold the current assumed values of a - * set of global variables. - */ - std::shared_ptr> get_state() const { return state; } - void set_state(std::shared_ptr> value) { this->state = value; } - - /** - * An array of references to rule or taxonomy reporting descriptors that are applicable to - * the thread flow location. - */ - std::shared_ptr> get_taxa() const { return taxa; } - void set_taxa(std::shared_ptr> value) { this->taxa = value; } - - /** - * A web request associated with this thread flow location. - */ - std::shared_ptr get_web_request() const { return web_request; } - void set_web_request(std::shared_ptr value) { this->web_request = value; } - - /** - * A web response associated with this thread flow location. - */ - std::shared_ptr get_web_response() const { return web_response; } - void set_web_response(std::shared_ptr value) { this->web_response = value; } - }; - - /** - * Describes a sequence of code locations that specify a path through a single thread of - * execution such as an operating system or fiber. - */ - class ThreadFlow { - public: - ThreadFlow() = default; - virtual ~ThreadFlow() = default; - - private: - std::shared_ptr id; - std::shared_ptr> immutable_state; - std::shared_ptr> initial_state; - std::vector locations; - std::shared_ptr message; - std::shared_ptr properties; - - public: - /** - * An string that uniquely identifies the threadFlow within the codeFlow in which it occurs. - */ - std::shared_ptr get_id() const { return id; } - void set_id(std::shared_ptr value) { this->id = value; } - - /** - * Values of relevant expressions at the start of the thread flow that remain constant. - */ - std::shared_ptr> get_immutable_state() const { return immutable_state; } - void set_immutable_state(std::shared_ptr> value) { this->immutable_state = value; } - - /** - * Values of relevant expressions at the start of the thread flow that may change during - * thread flow execution. - */ - std::shared_ptr> get_initial_state() const { return initial_state; } - void set_initial_state(std::shared_ptr> value) { this->initial_state = value; } - - /** - * A temporally ordered array of 'threadFlowLocation' objects, each of which describes a - * location visited by the tool while producing the result. - */ - const std::vector & get_locations() const { return locations; } - std::vector & get_mutable_locations() { return locations; } - void set_locations(const std::vector & value) { this->locations = value; } - - /** - * A message relevant to the thread flow. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the thread flow. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A set of threadFlows which together describe a pattern of code execution relevant to - * detecting a result. - */ - class CodeFlow { - public: - CodeFlow() = default; - virtual ~CodeFlow() = default; - - private: - std::shared_ptr message; - std::shared_ptr properties; - std::vector thread_flows; - - public: - /** - * A message relevant to the code flow. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the code flow. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of one or more unique threadFlow objects, each of which describes the progress - * of a program through a thread of execution. - */ - const std::vector & get_thread_flows() const { return thread_flows; } - std::vector & get_mutable_thread_flows() { return thread_flows; } - void set_thread_flows(const std::vector & value) { this->thread_flows = value; } - }; - - /** - * The replacement of a single region of an artifact. - */ - class Replacement { - public: - Replacement() = default; - virtual ~Replacement() = default; - - private: - Region deleted_region; - std::shared_ptr inserted_content; - std::shared_ptr properties; - - public: - /** - * The region of the artifact to delete. - */ - const Region & get_deleted_region() const { return deleted_region; } - Region & get_mutable_deleted_region() { return deleted_region; } - void set_deleted_region(const Region & value) { this->deleted_region = value; } - - /** - * The content to insert at the location specified by the 'deletedRegion' property. - */ - std::shared_ptr get_inserted_content() const { return inserted_content; } - void set_inserted_content(std::shared_ptr value) { this->inserted_content = value; } - - /** - * Key/value pairs that provide additional information about the replacement. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A change to a single artifact. - */ - class ArtifactChange { - public: - ArtifactChange() = default; - virtual ~ArtifactChange() = default; - - private: - ArtifactLocation artifact_location; - std::shared_ptr properties; - std::vector replacements; - - public: - /** - * The location of the artifact to change. - */ - const ArtifactLocation & get_artifact_location() const { return artifact_location; } - ArtifactLocation & get_mutable_artifact_location() { return artifact_location; } - void set_artifact_location(const ArtifactLocation & value) { this->artifact_location = value; } - - /** - * Key/value pairs that provide additional information about the change. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of replacement objects, each of which represents the replacement of a single - * region in a single artifact specified by 'artifactLocation'. - */ - const std::vector & get_replacements() const { return replacements; } - std::vector & get_mutable_replacements() { return replacements; } - void set_replacements(const std::vector & value) { this->replacements = value; } - }; - - /** - * A proposed fix for the problem represented by a result object. A fix specifies a set of - * artifacts to modify. For each artifact, it specifies a set of bytes to remove, and - * provides a set of new bytes to replace them. - */ - class Fix { - public: - Fix() = default; - virtual ~Fix() = default; - - private: - std::vector artifact_changes; - std::shared_ptr description; - std::shared_ptr properties; - - public: - /** - * One or more artifact changes that comprise a fix for a result. - */ - const std::vector & get_artifact_changes() const { return artifact_changes; } - std::vector & get_mutable_artifact_changes() { return artifact_changes; } - void set_artifact_changes(const std::vector & value) { this->artifact_changes = value; } - - /** - * A message that describes the proposed fix, enabling viewers to present the proposed - * change to an end user. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * Key/value pairs that provide additional information about the fix. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * Represents the traversal of a single edge during a graph traversal. - */ - class EdgeTraversal { - public: - EdgeTraversal() : - step_over_edge_count_constraint(0, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~EdgeTraversal() = default; - - private: - std::string edge_id; - std::shared_ptr> final_state; - std::shared_ptr message; - std::shared_ptr properties; - std::shared_ptr step_over_edge_count; - ClassMemberConstraints step_over_edge_count_constraint; - - public: - /** - * Identifies the edge being traversed. - */ - const std::string & get_edge_id() const { return edge_id; } - std::string & get_mutable_edge_id() { return edge_id; } - void set_edge_id(const std::string & value) { this->edge_id = value; } - - /** - * The values of relevant expressions after the edge has been traversed. - */ - std::shared_ptr> get_final_state() const { return final_state; } - void set_final_state(std::shared_ptr> value) { this->final_state = value; } - - /** - * A message to display to the user as the edge is traversed. - */ - std::shared_ptr get_message() const { return message; } - void set_message(std::shared_ptr value) { this->message = value; } - - /** - * Key/value pairs that provide additional information about the edge traversal. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The number of edge traversals necessary to return from a nested graph. - */ - std::shared_ptr get_step_over_edge_count() const { return step_over_edge_count; } - void set_step_over_edge_count(std::shared_ptr value) { if (value) CheckConstraint("step_over_edge_count", step_over_edge_count_constraint, *value); this->step_over_edge_count = value; } - }; - - /** - * Represents a path through a graph. - */ - class GraphTraversal { - public: - GraphTraversal() : - result_graph_index_constraint(-1, boost::none, boost::none, boost::none, boost::none), - run_graph_index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~GraphTraversal() = default; - - private: - std::shared_ptr description; - std::shared_ptr> edge_traversals; - std::shared_ptr> immutable_state; - std::shared_ptr> initial_state; - std::shared_ptr properties; - std::shared_ptr result_graph_index; - ClassMemberConstraints result_graph_index_constraint; - std::shared_ptr run_graph_index; - ClassMemberConstraints run_graph_index_constraint; - - public: - /** - * A description of this graph traversal. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * The sequences of edges traversed by this graph traversal. - */ - std::shared_ptr> get_edge_traversals() const { return edge_traversals; } - void set_edge_traversals(std::shared_ptr> value) { this->edge_traversals = value; } - - /** - * Values of relevant expressions at the start of the graph traversal that remain constant - * for the graph traversal. - */ - std::shared_ptr> get_immutable_state() const { return immutable_state; } - void set_immutable_state(std::shared_ptr> value) { this->immutable_state = value; } - - /** - * Values of relevant expressions at the start of the graph traversal that may change during - * graph traversal. - */ - std::shared_ptr> get_initial_state() const { return initial_state; } - void set_initial_state(std::shared_ptr> value) { this->initial_state = value; } - - /** - * Key/value pairs that provide additional information about the graph traversal. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The index within the result.graphs to be associated with the result. - */ - std::shared_ptr get_result_graph_index() const { return result_graph_index; } - void set_result_graph_index(std::shared_ptr value) { if (value) CheckConstraint("result_graph_index", result_graph_index_constraint, *value); this->result_graph_index = value; } - - /** - * The index within the run.graphs to be associated with the result. - */ - std::shared_ptr get_run_graph_index() const { return run_graph_index; } - void set_run_graph_index(std::shared_ptr value) { if (value) CheckConstraint("run_graph_index", run_graph_index_constraint, *value); this->run_graph_index = value; } - }; - - /** - * A value that categorizes results by evaluation state. - */ - enum class ResultKind : int { FAIL, INFORMATIONAL, NOT_APPLICABLE, OPEN, PASS, REVIEW }; - - /** - * Information about how and when the result was detected. - * - * Contains information about how and when a result was detected. - */ - class ResultProvenance { - public: - ResultProvenance() : - first_detection_run_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - invocation_index_constraint(-1, boost::none, boost::none, boost::none, boost::none), - last_detection_run_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")) - {} - virtual ~ResultProvenance() = default; - - private: - std::shared_ptr> conversion_sources; - std::shared_ptr first_detection_run_guid; - ClassMemberConstraints first_detection_run_guid_constraint; - std::shared_ptr first_detection_time_utc; - std::shared_ptr invocation_index; - ClassMemberConstraints invocation_index_constraint; - std::shared_ptr last_detection_run_guid; - ClassMemberConstraints last_detection_run_guid_constraint; - std::shared_ptr last_detection_time_utc; - std::shared_ptr properties; - - public: - /** - * An array of physicalLocation objects which specify the portions of an analysis tool's - * output that a converter transformed into the result. - */ - std::shared_ptr> get_conversion_sources() const { return conversion_sources; } - void set_conversion_sources(std::shared_ptr> value) { this->conversion_sources = value; } - - /** - * A GUID-valued string equal to the automationDetails.guid property of the run in which the - * result was first detected. - */ - std::shared_ptr get_first_detection_run_guid() const { return first_detection_run_guid; } - void set_first_detection_run_guid(std::shared_ptr value) { if (value) CheckConstraint("first_detection_run_guid", first_detection_run_guid_constraint, *value); this->first_detection_run_guid = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the result was first - * detected. See "Date/time properties" in the SARIF spec for the required format. - */ - std::shared_ptr get_first_detection_time_utc() const { return first_detection_time_utc; } - void set_first_detection_time_utc(std::shared_ptr value) { this->first_detection_time_utc = value; } - - /** - * The index within the run.invocations array of the invocation object which describes the - * tool invocation that detected the result. - */ - std::shared_ptr get_invocation_index() const { return invocation_index; } - void set_invocation_index(std::shared_ptr value) { if (value) CheckConstraint("invocation_index", invocation_index_constraint, *value); this->invocation_index = value; } - - /** - * A GUID-valued string equal to the automationDetails.guid property of the run in which the - * result was most recently detected. - */ - std::shared_ptr get_last_detection_run_guid() const { return last_detection_run_guid; } - void set_last_detection_run_guid(std::shared_ptr value) { if (value) CheckConstraint("last_detection_run_guid", last_detection_run_guid_constraint, *value); this->last_detection_run_guid = value; } - - /** - * The Coordinated Universal Time (UTC) date and time at which the result was most recently - * detected. See "Date/time properties" in the SARIF spec for the required format. - */ - std::shared_ptr get_last_detection_time_utc() const { return last_detection_time_utc; } - void set_last_detection_time_utc(std::shared_ptr value) { this->last_detection_time_utc = value; } - - /** - * Key/value pairs that provide additional information about the result. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * A string that indicates where the suppression is persisted. - */ - enum class SuppressionKind : int { EXTERNAL, IN_SOURCE }; - - /** - * A string that indicates the review status of the suppression. - */ - enum class Status : int { ACCEPTED, REJECTED, UNDER_REVIEW }; - - /** - * A suppression that is relevant to a result. - */ - class Suppression { - public: - Suppression() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")) - {} - virtual ~Suppression() = default; - - private: - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr justification; - SuppressionKind kind; - std::shared_ptr location; - std::shared_ptr properties; - std::shared_ptr status; - - public: - /** - * A stable, unique identifer for the suprression in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * A string representing the justification for the suppression. - */ - std::shared_ptr get_justification() const { return justification; } - void set_justification(std::shared_ptr value) { this->justification = value; } - - /** - * A string that indicates where the suppression is persisted. - */ - const SuppressionKind & get_kind() const { return kind; } - SuppressionKind & get_mutable_kind() { return kind; } - void set_kind(const SuppressionKind & value) { this->kind = value; } - - /** - * Identifies the location associated with the suppression. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * Key/value pairs that provide additional information about the suppression. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * A string that indicates the review status of the suppression. - */ - std::shared_ptr get_status() const { return status; } - void set_status(std::shared_ptr value) { this->status = value; } - }; - - /** - * A result produced by an analysis tool. - */ - class Result { - public: - Result() : - correlation_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - occurrence_count_constraint(1, boost::none, boost::none, boost::none, boost::none), - rank_constraint(-1, 100, boost::none, boost::none, boost::none), - rule_index_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~Result() = default; - - private: - std::shared_ptr analysis_target; - std::shared_ptr> attachments; - std::shared_ptr baseline_state; - std::shared_ptr> code_flows; - std::shared_ptr correlation_guid; - ClassMemberConstraints correlation_guid_constraint; - std::shared_ptr> fingerprints; - std::shared_ptr> fixes; - std::shared_ptr> graphs; - std::shared_ptr> graph_traversals; - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr hosted_viewer_uri; - std::shared_ptr kind; - std::shared_ptr level; - std::shared_ptr> locations; - Message message; - std::shared_ptr occurrence_count; - ClassMemberConstraints occurrence_count_constraint; - std::shared_ptr> partial_fingerprints; - std::shared_ptr properties; - std::shared_ptr provenance; - std::shared_ptr rank; - ClassMemberConstraints rank_constraint; - std::shared_ptr> related_locations; - std::shared_ptr rule; - std::shared_ptr rule_id; - std::shared_ptr rule_index; - ClassMemberConstraints rule_index_constraint; - std::shared_ptr> stacks; - std::shared_ptr> suppressions; - std::shared_ptr> taxa; - std::shared_ptr web_request; - std::shared_ptr web_response; - std::shared_ptr> work_item_uris; - - public: - /** - * Identifies the artifact that the analysis tool was instructed to scan. This need not be - * the same as the artifact where the result actually occurred. - */ - std::shared_ptr get_analysis_target() const { return analysis_target; } - void set_analysis_target(std::shared_ptr value) { this->analysis_target = value; } - - /** - * A set of artifacts relevant to the result. - */ - std::shared_ptr> get_attachments() const { return attachments; } - void set_attachments(std::shared_ptr> value) { this->attachments = value; } - - /** - * The state of a result relative to a baseline of a previous run. - */ - std::shared_ptr get_baseline_state() const { return baseline_state; } - void set_baseline_state(std::shared_ptr value) { this->baseline_state = value; } - - /** - * An array of 'codeFlow' objects relevant to the result. - */ - std::shared_ptr> get_code_flows() const { return code_flows; } - void set_code_flows(std::shared_ptr> value) { this->code_flows = value; } - - /** - * A stable, unique identifier for the equivalence class of logically identical results to - * which this result belongs, in the form of a GUID. - */ - std::shared_ptr get_correlation_guid() const { return correlation_guid; } - void set_correlation_guid(std::shared_ptr value) { if (value) CheckConstraint("correlation_guid", correlation_guid_constraint, *value); this->correlation_guid = value; } - - /** - * A set of strings each of which individually defines a stable, unique identity for the - * result. - */ - std::shared_ptr> get_fingerprints() const { return fingerprints; } - void set_fingerprints(std::shared_ptr> value) { this->fingerprints = value; } - - /** - * An array of 'fix' objects, each of which represents a proposed fix to the problem - * indicated by the result. - */ - std::shared_ptr> get_fixes() const { return fixes; } - void set_fixes(std::shared_ptr> value) { this->fixes = value; } - - /** - * An array of zero or more unique graph objects associated with the result. - */ - std::shared_ptr> get_graphs() const { return graphs; } - void set_graphs(std::shared_ptr> value) { this->graphs = value; } - - /** - * An array of one or more unique 'graphTraversal' objects. - */ - std::shared_ptr> get_graph_traversals() const { return graph_traversals; } - void set_graph_traversals(std::shared_ptr> value) { this->graph_traversals = value; } - - /** - * A stable, unique identifer for the result in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * An absolute URI at which the result can be viewed. - */ - std::shared_ptr get_hosted_viewer_uri() const { return hosted_viewer_uri; } - void set_hosted_viewer_uri(std::shared_ptr value) { this->hosted_viewer_uri = value; } - - /** - * A value that categorizes results by evaluation state. - */ - std::shared_ptr get_kind() const { return kind; } - void set_kind(std::shared_ptr value) { this->kind = value; } - - /** - * A value specifying the severity level of the result. - */ - std::shared_ptr get_level() const { return level; } - void set_level(std::shared_ptr value) { this->level = value; } - - /** - * The set of locations where the result was detected. Specify only one location unless the - * problem indicated by the result can only be corrected by making a change at every - * specified location. - */ - std::shared_ptr> get_locations() const { return locations; } - void set_locations(std::shared_ptr> value) { this->locations = value; } - - /** - * A message that describes the result. The first sentence of the message only will be - * displayed when visible space is limited. - */ - const Message & get_message() const { return message; } - Message & get_mutable_message() { return message; } - void set_message(const Message & value) { this->message = value; } - - /** - * A positive integer specifying the number of times this logically unique result was - * observed in this run. - */ - std::shared_ptr get_occurrence_count() const { return occurrence_count; } - void set_occurrence_count(std::shared_ptr value) { if (value) CheckConstraint("occurrence_count", occurrence_count_constraint, *value); this->occurrence_count = value; } - - /** - * A set of strings that contribute to the stable, unique identity of the result. - */ - std::shared_ptr> get_partial_fingerprints() const { return partial_fingerprints; } - void set_partial_fingerprints(std::shared_ptr> value) { this->partial_fingerprints = value; } - - /** - * Key/value pairs that provide additional information about the result. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * Information about how and when the result was detected. - */ - std::shared_ptr get_provenance() const { return provenance; } - void set_provenance(std::shared_ptr value) { this->provenance = value; } - - /** - * A number representing the priority or importance of the result. - */ - std::shared_ptr get_rank() const { return rank; } - void set_rank(std::shared_ptr value) { if (value) CheckConstraint("rank", rank_constraint, *value); this->rank = value; } - - /** - * A set of locations relevant to this result. - */ - std::shared_ptr> get_related_locations() const { return related_locations; } - void set_related_locations(std::shared_ptr> value) { this->related_locations = value; } - - /** - * A reference used to locate the rule descriptor relevant to this result. - */ - std::shared_ptr get_rule() const { return rule; } - void set_rule(std::shared_ptr value) { this->rule = value; } - - /** - * The stable, unique identifier of the rule, if any, to which this result is relevant. - */ - std::shared_ptr get_rule_id() const { return rule_id; } - void set_rule_id(std::shared_ptr value) { this->rule_id = value; } - - /** - * The index within the tool component rules array of the rule object associated with this - * result. - */ - std::shared_ptr get_rule_index() const { return rule_index; } - void set_rule_index(std::shared_ptr value) { if (value) CheckConstraint("rule_index", rule_index_constraint, *value); this->rule_index = value; } - - /** - * An array of 'stack' objects relevant to the result. - */ - std::shared_ptr> get_stacks() const { return stacks; } - void set_stacks(std::shared_ptr> value) { this->stacks = value; } - - /** - * A set of suppressions relevant to this result. - */ - std::shared_ptr> get_suppressions() const { return suppressions; } - void set_suppressions(std::shared_ptr> value) { this->suppressions = value; } - - /** - * An array of references to taxonomy reporting descriptors that are applicable to the - * result. - */ - std::shared_ptr> get_taxa() const { return taxa; } - void set_taxa(std::shared_ptr> value) { this->taxa = value; } - - /** - * A web request associated with this result. - */ - std::shared_ptr get_web_request() const { return web_request; } - void set_web_request(std::shared_ptr value) { this->web_request = value; } - - /** - * A web response associated with this result. - */ - std::shared_ptr get_web_response() const { return web_response; } - void set_web_response(std::shared_ptr value) { this->web_response = value; } - - /** - * The URIs of the work items associated with this result. - */ - std::shared_ptr> get_work_item_uris() const { return work_item_uris; } - void set_work_item_uris(std::shared_ptr> value) { this->work_item_uris = value; } - }; - - /** - * The SARIF format version of this external properties object. - * - * The SARIF format version of this log file. - */ - enum class Version : int { THE_210 }; - - /** - * The top-level element of an external property file. - */ - class ExternalProperties { - public: - ExternalProperties() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - run_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")) - {} - virtual ~ExternalProperties() = default; - - private: - std::shared_ptr> addresses; - std::shared_ptr> artifacts; - std::shared_ptr conversion; - std::shared_ptr driver; - std::shared_ptr> extensions; - std::shared_ptr externalized_properties; - std::shared_ptr> graphs; - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr> invocations; - std::shared_ptr> logical_locations; - std::shared_ptr> policies; - std::shared_ptr properties; - std::shared_ptr> results; - std::shared_ptr run_guid; - ClassMemberConstraints run_guid_constraint; - std::shared_ptr schema; - std::shared_ptr> taxonomies; - std::shared_ptr> thread_flow_locations; - std::shared_ptr> translations; - std::shared_ptr version; - std::shared_ptr> web_requests; - std::shared_ptr> web_responses; - - public: - /** - * Addresses that will be merged with a separate run. - */ - std::shared_ptr> get_addresses() const { return addresses; } - void set_addresses(std::shared_ptr> value) { this->addresses = value; } - - /** - * An array of artifact objects that will be merged with a separate run. - */ - std::shared_ptr> get_artifacts() const { return artifacts; } - void set_artifacts(std::shared_ptr> value) { this->artifacts = value; } - - /** - * A conversion object that will be merged with a separate run. - */ - std::shared_ptr get_conversion() const { return conversion; } - void set_conversion(std::shared_ptr value) { this->conversion = value; } - - /** - * The analysis tool object that will be merged with a separate run. - */ - std::shared_ptr get_driver() const { return driver; } - void set_driver(std::shared_ptr value) { this->driver = value; } - - /** - * Tool extensions that will be merged with a separate run. - */ - std::shared_ptr> get_extensions() const { return extensions; } - void set_extensions(std::shared_ptr> value) { this->extensions = value; } - - /** - * Key/value pairs that provide additional information that will be merged with a separate - * run. - */ - std::shared_ptr get_externalized_properties() const { return externalized_properties; } - void set_externalized_properties(std::shared_ptr value) { this->externalized_properties = value; } - - /** - * An array of graph objects that will be merged with a separate run. - */ - std::shared_ptr> get_graphs() const { return graphs; } - void set_graphs(std::shared_ptr> value) { this->graphs = value; } - - /** - * A stable, unique identifer for this external properties object, in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * Describes the invocation of the analysis tool that will be merged with a separate run. - */ - std::shared_ptr> get_invocations() const { return invocations; } - void set_invocations(std::shared_ptr> value) { this->invocations = value; } - - /** - * An array of logical locations such as namespaces, types or functions that will be merged - * with a separate run. - */ - std::shared_ptr> get_logical_locations() const { return logical_locations; } - void set_logical_locations(std::shared_ptr> value) { this->logical_locations = value; } - - /** - * Tool policies that will be merged with a separate run. - */ - std::shared_ptr> get_policies() const { return policies; } - void set_policies(std::shared_ptr> value) { this->policies = value; } - - /** - * Key/value pairs that provide additional information about the external properties. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of result objects that will be merged with a separate run. - */ - std::shared_ptr> get_results() const { return results; } - void set_results(std::shared_ptr> value) { this->results = value; } - - /** - * A stable, unique identifer for the run associated with this external properties object, - * in the form of a GUID. - */ - std::shared_ptr get_run_guid() const { return run_guid; } - void set_run_guid(std::shared_ptr value) { if (value) CheckConstraint("run_guid", run_guid_constraint, *value); this->run_guid = value; } - - /** - * The URI of the JSON schema corresponding to the version of the external property file - * format. - */ - std::shared_ptr get_schema() const { return schema; } - void set_schema(std::shared_ptr value) { this->schema = value; } - - /** - * Tool taxonomies that will be merged with a separate run. - */ - std::shared_ptr> get_taxonomies() const { return taxonomies; } - void set_taxonomies(std::shared_ptr> value) { this->taxonomies = value; } - - /** - * An array of threadFlowLocation objects that will be merged with a separate run. - */ - std::shared_ptr> get_thread_flow_locations() const { return thread_flow_locations; } - void set_thread_flow_locations(std::shared_ptr> value) { this->thread_flow_locations = value; } - - /** - * Tool translations that will be merged with a separate run. - */ - std::shared_ptr> get_translations() const { return translations; } - void set_translations(std::shared_ptr> value) { this->translations = value; } - - /** - * The SARIF format version of this external properties object. - */ - std::shared_ptr get_version() const { return version; } - void set_version(std::shared_ptr value) { this->version = value; } - - /** - * Requests that will be merged with a separate run. - */ - std::shared_ptr> get_web_requests() const { return web_requests; } - void set_web_requests(std::shared_ptr> value) { this->web_requests = value; } - - /** - * Responses that will be merged with a separate run. - */ - std::shared_ptr> get_web_responses() const { return web_responses; } - void set_web_responses(std::shared_ptr> value) { this->web_responses = value; } - }; - - /** - * Automation details that describe this run. - * - * Information that describes a run's identity and role within an engineering system process. - */ - class RunAutomationDetails { - public: - RunAutomationDetails() : - correlation_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")) - {} - virtual ~RunAutomationDetails() = default; - - private: - std::shared_ptr correlation_guid; - ClassMemberConstraints correlation_guid_constraint; - std::shared_ptr description; - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr id; - std::shared_ptr properties; - - public: - /** - * A stable, unique identifier for the equivalence class of runs to which this object's - * containing run object belongs in the form of a GUID. - */ - std::shared_ptr get_correlation_guid() const { return correlation_guid; } - void set_correlation_guid(std::shared_ptr value) { if (value) CheckConstraint("correlation_guid", correlation_guid_constraint, *value); this->correlation_guid = value; } - - /** - * A description of the identity and role played within the engineering system by this - * object's containing run object. - */ - std::shared_ptr get_description() const { return description; } - void set_description(std::shared_ptr value) { this->description = value; } - - /** - * A stable, unique identifer for this object's containing run object in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * A hierarchical string that uniquely identifies this object's containing run object. - */ - std::shared_ptr get_id() const { return id; } - void set_id(std::shared_ptr value) { this->id = value; } - - /** - * Key/value pairs that provide additional information about the run automation details. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * Specifies the unit in which the tool measures columns. - */ - enum class ColumnKind : int { UNICODE_CODE_POINTS, UTF16_CODE_UNITS }; - - /** - * An external property file containing a run.conversion object to be merged with the root - * log file. - * - * An external property file containing a run.driver object to be merged with the root log - * file. - * - * An external property file containing a run.properties object to be merged with the root - * log file. - * - * Contains information that enables a SARIF consumer to locate the external property file - * that contains the value of an externalized property associated with the run. - */ - class ExternalPropertyFileReference { - public: - ExternalPropertyFileReference() : - guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - item_count_constraint(-1, boost::none, boost::none, boost::none, boost::none) - {} - virtual ~ExternalPropertyFileReference() = default; - - private: - std::shared_ptr guid; - ClassMemberConstraints guid_constraint; - std::shared_ptr item_count; - ClassMemberConstraints item_count_constraint; - std::shared_ptr location; - std::shared_ptr properties; - - public: - /** - * A stable, unique identifer for the external property file in the form of a GUID. - */ - std::shared_ptr get_guid() const { return guid; } - void set_guid(std::shared_ptr value) { if (value) CheckConstraint("guid", guid_constraint, *value); this->guid = value; } - - /** - * A non-negative integer specifying the number of items contained in the external property - * file. - */ - std::shared_ptr get_item_count() const { return item_count; } - void set_item_count(std::shared_ptr value) { if (value) CheckConstraint("item_count", item_count_constraint, *value); this->item_count = value; } - - /** - * The location of the external property file. - */ - std::shared_ptr get_location() const { return location; } - void set_location(std::shared_ptr value) { this->location = value; } - - /** - * Key/value pairs that provide additional information about the external property file. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * References to external property files that should be inlined with the content of a root - * log file. - */ - class ExternalPropertyFileReferences { - public: - ExternalPropertyFileReferences() = default; - virtual ~ExternalPropertyFileReferences() = default; - - private: - std::shared_ptr> addresses; - std::shared_ptr> artifacts; - std::shared_ptr conversion; - std::shared_ptr driver; - std::shared_ptr> extensions; - std::shared_ptr externalized_properties; - std::shared_ptr> graphs; - std::shared_ptr> invocations; - std::shared_ptr> logical_locations; - std::shared_ptr> policies; - std::shared_ptr properties; - std::shared_ptr> results; - std::shared_ptr> taxonomies; - std::shared_ptr> thread_flow_locations; - std::shared_ptr> translations; - std::shared_ptr> web_requests; - std::shared_ptr> web_responses; - - public: - /** - * An array of external property files containing run.addresses arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_addresses() const { return addresses; } - void set_addresses(std::shared_ptr> value) { this->addresses = value; } - - /** - * An array of external property files containing run.artifacts arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_artifacts() const { return artifacts; } - void set_artifacts(std::shared_ptr> value) { this->artifacts = value; } - - /** - * An external property file containing a run.conversion object to be merged with the root - * log file. - */ - std::shared_ptr get_conversion() const { return conversion; } - void set_conversion(std::shared_ptr value) { this->conversion = value; } - - /** - * An external property file containing a run.driver object to be merged with the root log - * file. - */ - std::shared_ptr get_driver() const { return driver; } - void set_driver(std::shared_ptr value) { this->driver = value; } - - /** - * An array of external property files containing run.extensions arrays to be merged with - * the root log file. - */ - std::shared_ptr> get_extensions() const { return extensions; } - void set_extensions(std::shared_ptr> value) { this->extensions = value; } - - /** - * An external property file containing a run.properties object to be merged with the root - * log file. - */ - std::shared_ptr get_externalized_properties() const { return externalized_properties; } - void set_externalized_properties(std::shared_ptr value) { this->externalized_properties = value; } - - /** - * An array of external property files containing a run.graphs object to be merged with the - * root log file. - */ - std::shared_ptr> get_graphs() const { return graphs; } - void set_graphs(std::shared_ptr> value) { this->graphs = value; } - - /** - * An array of external property files containing run.invocations arrays to be merged with - * the root log file. - */ - std::shared_ptr> get_invocations() const { return invocations; } - void set_invocations(std::shared_ptr> value) { this->invocations = value; } - - /** - * An array of external property files containing run.logicalLocations arrays to be merged - * with the root log file. - */ - std::shared_ptr> get_logical_locations() const { return logical_locations; } - void set_logical_locations(std::shared_ptr> value) { this->logical_locations = value; } - - /** - * An array of external property files containing run.policies arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_policies() const { return policies; } - void set_policies(std::shared_ptr> value) { this->policies = value; } - - /** - * Key/value pairs that provide additional information about the external property files. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of external property files containing run.results arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_results() const { return results; } - void set_results(std::shared_ptr> value) { this->results = value; } - - /** - * An array of external property files containing run.taxonomies arrays to be merged with - * the root log file. - */ - std::shared_ptr> get_taxonomies() const { return taxonomies; } - void set_taxonomies(std::shared_ptr> value) { this->taxonomies = value; } - - /** - * An array of external property files containing run.threadFlowLocations arrays to be - * merged with the root log file. - */ - std::shared_ptr> get_thread_flow_locations() const { return thread_flow_locations; } - void set_thread_flow_locations(std::shared_ptr> value) { this->thread_flow_locations = value; } - - /** - * An array of external property files containing run.translations arrays to be merged with - * the root log file. - */ - std::shared_ptr> get_translations() const { return translations; } - void set_translations(std::shared_ptr> value) { this->translations = value; } - - /** - * An array of external property files containing run.requests arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_web_requests() const { return web_requests; } - void set_web_requests(std::shared_ptr> value) { this->web_requests = value; } - - /** - * An array of external property files containing run.responses arrays to be merged with the - * root log file. - */ - std::shared_ptr> get_web_responses() const { return web_responses; } - void set_web_responses(std::shared_ptr> value) { this->web_responses = value; } - }; - - /** - * A specialLocations object that defines locations of special significance to SARIF - * consumers. - * - * Defines locations of special significance to SARIF consumers. - */ - class SpecialLocations { - public: - SpecialLocations() = default; - virtual ~SpecialLocations() = default; - - private: - std::shared_ptr display_base; - std::shared_ptr properties; - - public: - /** - * Provides a suggestion to SARIF consumers to display file paths relative to the specified - * location. - */ - std::shared_ptr get_display_base() const { return display_base; } - void set_display_base(std::shared_ptr value) { this->display_base = value; } - - /** - * Key/value pairs that provide additional information about the special locations. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - }; - - /** - * Specifies the information necessary to retrieve a desired revision from a version control - * system. - */ - class VersionControlDetails { - public: - VersionControlDetails() = default; - virtual ~VersionControlDetails() = default; - - private: - std::shared_ptr as_of_time_utc; - std::shared_ptr branch; - std::shared_ptr mapped_to; - std::shared_ptr properties; - std::string repository_uri; - std::shared_ptr revision_id; - std::shared_ptr revision_tag; - - public: - /** - * A Coordinated Universal Time (UTC) date and time that can be used to synchronize an - * enlistment to the state of the repository at that time. - */ - std::shared_ptr get_as_of_time_utc() const { return as_of_time_utc; } - void set_as_of_time_utc(std::shared_ptr value) { this->as_of_time_utc = value; } - - /** - * The name of a branch containing the revision. - */ - std::shared_ptr get_branch() const { return branch; } - void set_branch(std::shared_ptr value) { this->branch = value; } - - /** - * The location in the local file system to which the root of the repository was mapped at - * the time of the analysis. - */ - std::shared_ptr get_mapped_to() const { return mapped_to; } - void set_mapped_to(std::shared_ptr value) { this->mapped_to = value; } - - /** - * Key/value pairs that provide additional information about the version control details. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The absolute URI of the repository. - */ - const std::string & get_repository_uri() const { return repository_uri; } - std::string & get_mutable_repository_uri() { return repository_uri; } - void set_repository_uri(const std::string & value) { this->repository_uri = value; } - - /** - * A string that uniquely and permanently identifies the revision within the repository. - */ - std::shared_ptr get_revision_id() const { return revision_id; } - void set_revision_id(std::shared_ptr value) { this->revision_id = value; } - - /** - * A tag that has been applied to the revision. - */ - std::shared_ptr get_revision_tag() const { return revision_tag; } - void set_revision_tag(std::shared_ptr value) { this->revision_tag = value; } - }; - - /** - * Describes a single run of an analysis tool, and contains the reported output of that run. - */ - class Run { - public: - Run() : - baseline_guid_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$")), - language_constraint(boost::none, boost::none, boost::none, boost::none, std::string("^[a-zA-Z]{2}|^[a-zA-Z]{2}-[a-zA-Z]{2}]?$")) - {} - virtual ~Run() = default; - - private: - std::shared_ptr> addresses; - std::shared_ptr> artifacts; - std::shared_ptr automation_details; - std::shared_ptr baseline_guid; - ClassMemberConstraints baseline_guid_constraint; - std::shared_ptr column_kind; - std::shared_ptr conversion; - std::shared_ptr default_encoding; - std::shared_ptr default_source_language; - std::shared_ptr external_property_file_references; - std::shared_ptr> graphs; - std::shared_ptr> invocations; - std::shared_ptr language; - ClassMemberConstraints language_constraint; - std::shared_ptr> logical_locations; - std::shared_ptr> newline_sequences; - std::shared_ptr> original_uri_base_ids; - std::shared_ptr> policies; - std::shared_ptr properties; - std::shared_ptr> redaction_tokens; - std::shared_ptr> results; - std::shared_ptr> run_aggregates; - std::shared_ptr special_locations; - std::shared_ptr> taxonomies; - std::shared_ptr> thread_flow_locations; - Tool tool; - std::shared_ptr> translations; - std::shared_ptr> version_control_provenance; - std::shared_ptr> web_requests; - std::shared_ptr> web_responses; - - public: - /** - * Addresses associated with this run instance, if any. - */ - std::shared_ptr> get_addresses() const { return addresses; } - void set_addresses(std::shared_ptr> value) { this->addresses = value; } - - /** - * An array of artifact objects relevant to the run. - */ - std::shared_ptr> get_artifacts() const { return artifacts; } - void set_artifacts(std::shared_ptr> value) { this->artifacts = value; } - - /** - * Automation details that describe this run. - */ - std::shared_ptr get_automation_details() const { return automation_details; } - void set_automation_details(std::shared_ptr value) { this->automation_details = value; } - - /** - * The 'guid' property of a previous SARIF 'run' that comprises the baseline that was used - * to compute result 'baselineState' properties for the run. - */ - std::shared_ptr get_baseline_guid() const { return baseline_guid; } - void set_baseline_guid(std::shared_ptr value) { if (value) CheckConstraint("baseline_guid", baseline_guid_constraint, *value); this->baseline_guid = value; } - - /** - * Specifies the unit in which the tool measures columns. - */ - std::shared_ptr get_column_kind() const { return column_kind; } - void set_column_kind(std::shared_ptr value) { this->column_kind = value; } - - /** - * A conversion object that describes how a converter transformed an analysis tool's native - * reporting format into the SARIF format. - */ - std::shared_ptr get_conversion() const { return conversion; } - void set_conversion(std::shared_ptr value) { this->conversion = value; } - - /** - * Specifies the default encoding for any artifact object that refers to a text file. - */ - std::shared_ptr get_default_encoding() const { return default_encoding; } - void set_default_encoding(std::shared_ptr value) { this->default_encoding = value; } - - /** - * Specifies the default source language for any artifact object that refers to a text file - * that contains source code. - */ - std::shared_ptr get_default_source_language() const { return default_source_language; } - void set_default_source_language(std::shared_ptr value) { this->default_source_language = value; } - - /** - * References to external property files that should be inlined with the content of a root - * log file. - */ - std::shared_ptr get_external_property_file_references() const { return external_property_file_references; } - void set_external_property_file_references(std::shared_ptr value) { this->external_property_file_references = value; } - - /** - * An array of zero or more unique graph objects associated with the run. - */ - std::shared_ptr> get_graphs() const { return graphs; } - void set_graphs(std::shared_ptr> value) { this->graphs = value; } - - /** - * Describes the invocation of the analysis tool. - */ - std::shared_ptr> get_invocations() const { return invocations; } - void set_invocations(std::shared_ptr> value) { this->invocations = value; } - - /** - * The language of the messages emitted into the log file during this run (expressed as an - * ISO 639-1 two-letter lowercase culture code) and an optional region (expressed as an ISO - * 3166-1 two-letter uppercase subculture code associated with a country or region). The - * casing is recommended but not required (in order for this data to conform to RFC5646). - */ - std::shared_ptr get_language() const { return language; } - void set_language(std::shared_ptr value) { if (value) CheckConstraint("language", language_constraint, *value); this->language = value; } - - /** - * An array of logical locations such as namespaces, types or functions. - */ - std::shared_ptr> get_logical_locations() const { return logical_locations; } - void set_logical_locations(std::shared_ptr> value) { this->logical_locations = value; } - - /** - * An ordered list of character sequences that were treated as line breaks when computing - * region information for the run. - */ - std::shared_ptr> get_newline_sequences() const { return newline_sequences; } - void set_newline_sequences(std::shared_ptr> value) { this->newline_sequences = value; } - - /** - * The artifact location specified by each uriBaseId symbol on the machine where the tool - * originally ran. - */ - std::shared_ptr> get_original_uri_base_ids() const { return original_uri_base_ids; } - void set_original_uri_base_ids(std::shared_ptr> value) { this->original_uri_base_ids = value; } - - /** - * Contains configurations that may potentially override both - * reportingDescriptor.defaultConfiguration (the tool's default severities) and - * invocation.configurationOverrides (severities established at run-time from the command - * line). - */ - std::shared_ptr> get_policies() const { return policies; } - void set_policies(std::shared_ptr> value) { this->policies = value; } - - /** - * Key/value pairs that provide additional information about the run. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * An array of strings used to replace sensitive information in a redaction-aware property. - */ - std::shared_ptr> get_redaction_tokens() const { return redaction_tokens; } - void set_redaction_tokens(std::shared_ptr> value) { this->redaction_tokens = value; } - - /** - * The set of results contained in an SARIF log. The results array can be omitted when a run - * is solely exporting rules metadata. It must be present (but may be empty) if a log file - * represents an actual scan. - */ - std::shared_ptr> get_results() const { return results; } - void set_results(std::shared_ptr> value) { this->results = value; } - - /** - * Automation details that describe the aggregate of runs to which this run belongs. - */ - std::shared_ptr> get_run_aggregates() const { return run_aggregates; } - void set_run_aggregates(std::shared_ptr> value) { this->run_aggregates = value; } - - /** - * A specialLocations object that defines locations of special significance to SARIF - * consumers. - */ - std::shared_ptr get_special_locations() const { return special_locations; } - void set_special_locations(std::shared_ptr value) { this->special_locations = value; } - - /** - * An array of toolComponent objects relevant to a taxonomy in which results are categorized. - */ - std::shared_ptr> get_taxonomies() const { return taxonomies; } - void set_taxonomies(std::shared_ptr> value) { this->taxonomies = value; } - - /** - * An array of threadFlowLocation objects cached at run level. - */ - std::shared_ptr> get_thread_flow_locations() const { return thread_flow_locations; } - void set_thread_flow_locations(std::shared_ptr> value) { this->thread_flow_locations = value; } - - /** - * Information about the tool or tool pipeline that generated the results in this run. A run - * can only contain results produced by a single tool or tool pipeline. A run can aggregate - * results from multiple log files, as long as context around the tool run (tool - * command-line arguments and the like) is identical for all aggregated files. - */ - const Tool & get_tool() const { return tool; } - Tool & get_mutable_tool() { return tool; } - void set_tool(const Tool & value) { this->tool = value; } - - /** - * The set of available translations of the localized data provided by the tool. - */ - std::shared_ptr> get_translations() const { return translations; } - void set_translations(std::shared_ptr> value) { this->translations = value; } - - /** - * Specifies the revision in version control of the artifacts that were scanned. - */ - std::shared_ptr> get_version_control_provenance() const { return version_control_provenance; } - void set_version_control_provenance(std::shared_ptr> value) { this->version_control_provenance = value; } - - /** - * An array of request objects cached at run level. - */ - std::shared_ptr> get_web_requests() const { return web_requests; } - void set_web_requests(std::shared_ptr> value) { this->web_requests = value; } - - /** - * An array of response objects cached at run level. - */ - std::shared_ptr> get_web_responses() const { return web_responses; } - void set_web_responses(std::shared_ptr> value) { this->web_responses = value; } - }; - - /** - * Static Analysis Results Format (SARIF) Version 2.1.0 JSON Schema: a standard format for - * the output of static analysis tools. - */ - class Coordinate { - public: - Coordinate() = default; - virtual ~Coordinate() = default; - - private: - std::shared_ptr schema; - std::shared_ptr> inline_external_properties; - std::shared_ptr properties; - std::vector runs; - Version version; - - public: - /** - * The URI of the JSON schema corresponding to the version. - */ - std::shared_ptr get_schema() const { return schema; } - void set_schema(std::shared_ptr value) { this->schema = value; } - - /** - * References to external property files that share data between runs. - */ - std::shared_ptr> get_inline_external_properties() const { return inline_external_properties; } - void set_inline_external_properties(std::shared_ptr> value) { this->inline_external_properties = value; } - - /** - * Key/value pairs that provide additional information about the log file. - */ - std::shared_ptr get_properties() const { return properties; } - void set_properties(std::shared_ptr value) { this->properties = value; } - - /** - * The set of runs contained in this log file. - */ - const std::vector & get_runs() const { return runs; } - std::vector & get_mutable_runs() { return runs; } - void set_runs(const std::vector & value) { this->runs = value; } - - /** - * The SARIF format version of this log file. - */ - const Version & get_version() const { return version; } - Version & get_mutable_version() { return version; } - void set_version(const Version & value) { this->version = value; } - }; -} - -namespace nlohmann { - void from_json(const json & j, SARIF::PropertyBag & x); - void to_json(json & j, const SARIF::PropertyBag & x); - - void from_json(const json & j, SARIF::Address & x); - void to_json(json & j, const SARIF::Address & x); - - void from_json(const json & j, SARIF::MultiformatMessageString & x); - void to_json(json & j, const SARIF::MultiformatMessageString & x); - - void from_json(const json & j, SARIF::ArtifactContent & x); - void to_json(json & j, const SARIF::ArtifactContent & x); - - void from_json(const json & j, SARIF::Message & x); - void to_json(json & j, const SARIF::Message & x); - - void from_json(const json & j, SARIF::ArtifactLocation & x); - void to_json(json & j, const SARIF::ArtifactLocation & x); - - void from_json(const json & j, SARIF::Artifact & x); - void to_json(json & j, const SARIF::Artifact & x); - - void from_json(const json & j, SARIF::ReportingConfiguration & x); - void to_json(json & j, const SARIF::ReportingConfiguration & x); - - void from_json(const json & j, SARIF::ToolComponentReference & x); - void to_json(json & j, const SARIF::ToolComponentReference & x); - - void from_json(const json & j, SARIF::ReportingDescriptorReference & x); - void to_json(json & j, const SARIF::ReportingDescriptorReference & x); - - void from_json(const json & j, SARIF::ConfigurationOverride & x); - void to_json(json & j, const SARIF::ConfigurationOverride & x); - - void from_json(const json & j, SARIF::Region & x); - void to_json(json & j, const SARIF::Region & x); - - void from_json(const json & j, SARIF::LogicalLocation & x); - void to_json(json & j, const SARIF::LogicalLocation & x); - - void from_json(const json & j, SARIF::PhysicalLocation & x); - void to_json(json & j, const SARIF::PhysicalLocation & x); - - void from_json(const json & j, SARIF::LocationRelationship & x); - void to_json(json & j, const SARIF::LocationRelationship & x); - - void from_json(const json & j, SARIF::Location & x); - void to_json(json & j, const SARIF::Location & x); - - void from_json(const json & j, SARIF::StackFrame & x); - void to_json(json & j, const SARIF::StackFrame & x); - - void from_json(const json & j, SARIF::Stack & x); - void to_json(json & j, const SARIF::Stack & x); - - void from_json(const json & j, SARIF::Exception & x); - void to_json(json & j, const SARIF::Exception & x); - - void from_json(const json & j, SARIF::Notification & x); - void to_json(json & j, const SARIF::Notification & x); - - void from_json(const json & j, SARIF::Invocation & x); - void to_json(json & j, const SARIF::Invocation & x); - - void from_json(const json & j, SARIF::ReportingDescriptorRelationship & x); - void to_json(json & j, const SARIF::ReportingDescriptorRelationship & x); - - void from_json(const json & j, SARIF::ReportingDescriptor & x); - void to_json(json & j, const SARIF::ReportingDescriptor & x); - - void from_json(const json & j, SARIF::TranslationMetadata & x); - void to_json(json & j, const SARIF::TranslationMetadata & x); - - void from_json(const json & j, SARIF::ToolComponent & x); - void to_json(json & j, const SARIF::ToolComponent & x); - - void from_json(const json & j, SARIF::Tool & x); - void to_json(json & j, const SARIF::Tool & x); - - void from_json(const json & j, SARIF::Conversion & x); - void to_json(json & j, const SARIF::Conversion & x); - - void from_json(const json & j, SARIF::Edge & x); - void to_json(json & j, const SARIF::Edge & x); - - void from_json(const json & j, SARIF::Node & x); - void to_json(json & j, const SARIF::Node & x); - - void from_json(const json & j, SARIF::Graph & x); - void to_json(json & j, const SARIF::Graph & x); - - void from_json(const json & j, SARIF::Rectangle & x); - void to_json(json & j, const SARIF::Rectangle & x); - - void from_json(const json & j, SARIF::Attachment & x); - void to_json(json & j, const SARIF::Attachment & x); - - void from_json(const json & j, SARIF::WebRequest & x); - void to_json(json & j, const SARIF::WebRequest & x); - - void from_json(const json & j, SARIF::WebResponse & x); - void to_json(json & j, const SARIF::WebResponse & x); - - void from_json(const json & j, SARIF::ThreadFlowLocation & x); - void to_json(json & j, const SARIF::ThreadFlowLocation & x); - - void from_json(const json & j, SARIF::ThreadFlow & x); - void to_json(json & j, const SARIF::ThreadFlow & x); - - void from_json(const json & j, SARIF::CodeFlow & x); - void to_json(json & j, const SARIF::CodeFlow & x); - - void from_json(const json & j, SARIF::Replacement & x); - void to_json(json & j, const SARIF::Replacement & x); - - void from_json(const json & j, SARIF::ArtifactChange & x); - void to_json(json & j, const SARIF::ArtifactChange & x); - - void from_json(const json & j, SARIF::Fix & x); - void to_json(json & j, const SARIF::Fix & x); - - void from_json(const json & j, SARIF::EdgeTraversal & x); - void to_json(json & j, const SARIF::EdgeTraversal & x); - - void from_json(const json & j, SARIF::GraphTraversal & x); - void to_json(json & j, const SARIF::GraphTraversal & x); - - void from_json(const json & j, SARIF::ResultProvenance & x); - void to_json(json & j, const SARIF::ResultProvenance & x); - - void from_json(const json & j, SARIF::Suppression & x); - void to_json(json & j, const SARIF::Suppression & x); - - void from_json(const json & j, SARIF::Result & x); - void to_json(json & j, const SARIF::Result & x); - - void from_json(const json & j, SARIF::ExternalProperties & x); - void to_json(json & j, const SARIF::ExternalProperties & x); - - void from_json(const json & j, SARIF::RunAutomationDetails & x); - void to_json(json & j, const SARIF::RunAutomationDetails & x); - - void from_json(const json & j, SARIF::ExternalPropertyFileReference & x); - void to_json(json & j, const SARIF::ExternalPropertyFileReference & x); - - void from_json(const json & j, SARIF::ExternalPropertyFileReferences & x); - void to_json(json & j, const SARIF::ExternalPropertyFileReferences & x); - - void from_json(const json & j, SARIF::SpecialLocations & x); - void to_json(json & j, const SARIF::SpecialLocations & x); - - void from_json(const json & j, SARIF::VersionControlDetails & x); - void to_json(json & j, const SARIF::VersionControlDetails & x); - - void from_json(const json & j, SARIF::Run & x); - void to_json(json & j, const SARIF::Run & x); - - void from_json(const json & j, SARIF::Coordinate & x); - void to_json(json & j, const SARIF::Coordinate & x); - - void from_json(const json & j, SARIF::Role & x); - void to_json(json & j, const SARIF::Role & x); - - void from_json(const json & j, SARIF::Level & x); - void to_json(json & j, const SARIF::Level & x); - - void from_json(const json & j, SARIF::Content & x); - void to_json(json & j, const SARIF::Content & x); - - void from_json(const json & j, SARIF::BaselineState & x); - void to_json(json & j, const SARIF::BaselineState & x); - - void from_json(const json & j, SARIF::Importance & x); - void to_json(json & j, const SARIF::Importance & x); - - void from_json(const json & j, SARIF::ResultKind & x); - void to_json(json & j, const SARIF::ResultKind & x); - - void from_json(const json & j, SARIF::SuppressionKind & x); - void to_json(json & j, const SARIF::SuppressionKind & x); - - void from_json(const json & j, SARIF::Status & x); - void to_json(json & j, const SARIF::Status & x); - - void from_json(const json & j, SARIF::Version & x); - void to_json(json & j, const SARIF::Version & x); - - void from_json(const json & j, SARIF::ColumnKind & x); - void to_json(json & j, const SARIF::ColumnKind & x); - - inline void from_json(const json & j, SARIF::PropertyBag& x) { - x.set_tags(SARIF::get_optional>(j, "tags")); - } - - inline void to_json(json & j, const SARIF::PropertyBag & x) { - j = json::object(); - j["tags"] = x.get_tags(); - } - - inline void from_json(const json & j, SARIF::Address& x) { - x.set_absolute_address(SARIF::get_optional(j, "absoluteAddress")); - x.set_fully_qualified_name(SARIF::get_optional(j, "fullyQualifiedName")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_kind(SARIF::get_optional(j, "kind")); - x.set_length(SARIF::get_optional(j, "length")); - x.set_name(SARIF::get_optional(j, "name")); - x.set_offset_from_parent(SARIF::get_optional(j, "offsetFromParent")); - x.set_parent_index(SARIF::get_optional(j, "parentIndex")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_relative_address(SARIF::get_optional(j, "relativeAddress")); - } - - inline void to_json(json & j, const SARIF::Address & x) { - j = json::object(); - j["absoluteAddress"] = x.get_absolute_address(); - j["fullyQualifiedName"] = x.get_fully_qualified_name(); - j["index"] = x.get_index(); - j["kind"] = x.get_kind(); - j["length"] = x.get_length(); - j["name"] = x.get_name(); - j["offsetFromParent"] = x.get_offset_from_parent(); - j["parentIndex"] = x.get_parent_index(); - j["properties"] = x.get_properties(); - j["relativeAddress"] = x.get_relative_address(); - } - - inline void from_json(const json & j, SARIF::MultiformatMessageString& x) { - x.set_markdown(SARIF::get_optional(j, "markdown")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_text(j.at("text").get()); - } - - inline void to_json(json & j, const SARIF::MultiformatMessageString & x) { - j = json::object(); - j["markdown"] = x.get_markdown(); - j["properties"] = x.get_properties(); - j["text"] = x.get_text(); - } - - inline void from_json(const json & j, SARIF::ArtifactContent& x) { - x.set_binary(SARIF::get_optional(j, "binary")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_rendered(SARIF::get_optional(j, "rendered")); - x.set_text(SARIF::get_optional(j, "text")); - } - - inline void to_json(json & j, const SARIF::ArtifactContent & x) { - j = json::object(); - j["binary"] = x.get_binary(); - j["properties"] = x.get_properties(); - j["rendered"] = x.get_rendered(); - j["text"] = x.get_text(); - } - - inline void from_json(const json & j, SARIF::Message& x) { - x.set_arguments(SARIF::get_optional>(j, "arguments")); - x.set_id(SARIF::get_optional(j, "id")); - x.set_markdown(SARIF::get_optional(j, "markdown")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_text(SARIF::get_optional(j, "text")); - } - - inline void to_json(json & j, const SARIF::Message & x) { - j = json::object(); - j["arguments"] = x.get_arguments(); - j["id"] = x.get_id(); - j["markdown"] = x.get_markdown(); - j["properties"] = x.get_properties(); - j["text"] = x.get_text(); - } - - inline void from_json(const json & j, SARIF::ArtifactLocation& x) { - x.set_description(SARIF::get_optional(j, "description")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_uri(SARIF::get_optional(j, "uri")); - x.set_uri_base_id(SARIF::get_optional(j, "uriBaseId")); - } - - inline void to_json(json & j, const SARIF::ArtifactLocation & x) { - j = json::object(); - j["description"] = x.get_description(); - j["index"] = x.get_index(); - j["properties"] = x.get_properties(); - j["uri"] = x.get_uri(); - j["uriBaseId"] = x.get_uri_base_id(); - } - - inline void from_json(const json & j, SARIF::Artifact& x) { - x.set_contents(SARIF::get_optional(j, "contents")); - x.set_description(SARIF::get_optional(j, "description")); - x.set_encoding(SARIF::get_optional(j, "encoding")); - x.set_hashes(SARIF::get_optional>(j, "hashes")); - x.set_last_modified_time_utc(SARIF::get_optional(j, "lastModifiedTimeUtc")); - x.set_length(SARIF::get_optional(j, "length")); - x.set_location(SARIF::get_optional(j, "location")); - x.set_mime_type(SARIF::get_optional(j, "mimeType")); - x.set_offset(SARIF::get_optional(j, "offset")); - x.set_parent_index(SARIF::get_optional(j, "parentIndex")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_roles(SARIF::get_optional>(j, "roles")); - x.set_source_language(SARIF::get_optional(j, "sourceLanguage")); - } - - inline void to_json(json & j, const SARIF::Artifact & x) { - j = json::object(); - j["contents"] = x.get_contents(); - j["description"] = x.get_description(); - j["encoding"] = x.get_encoding(); - j["hashes"] = x.get_hashes(); - j["lastModifiedTimeUtc"] = x.get_last_modified_time_utc(); - j["length"] = x.get_length(); - j["location"] = x.get_location(); - j["mimeType"] = x.get_mime_type(); - j["offset"] = x.get_offset(); - j["parentIndex"] = x.get_parent_index(); - j["properties"] = x.get_properties(); - j["roles"] = x.get_roles(); - j["sourceLanguage"] = x.get_source_language(); - } - - inline void from_json(const json & j, SARIF::ReportingConfiguration& x) { - x.set_enabled(SARIF::get_optional(j, "enabled")); - x.set_level(SARIF::get_optional(j, "level")); - x.set_parameters(SARIF::get_optional(j, "parameters")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_rank(SARIF::get_optional(j, "rank")); - } - - inline void to_json(json & j, const SARIF::ReportingConfiguration & x) { - j = json::object(); - j["enabled"] = x.get_enabled(); - j["level"] = x.get_level(); - j["parameters"] = x.get_parameters(); - j["properties"] = x.get_properties(); - j["rank"] = x.get_rank(); - } - - inline void from_json(const json & j, SARIF::ToolComponentReference& x) { - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_name(SARIF::get_optional(j, "name")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::ToolComponentReference & x) { - j = json::object(); - j["guid"] = x.get_guid(); - j["index"] = x.get_index(); - j["name"] = x.get_name(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::ReportingDescriptorReference& x) { - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_id(SARIF::get_optional(j, "id")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_tool_component(SARIF::get_optional(j, "toolComponent")); - } - - inline void to_json(json & j, const SARIF::ReportingDescriptorReference & x) { - j = json::object(); - j["guid"] = x.get_guid(); - j["id"] = x.get_id(); - j["index"] = x.get_index(); - j["properties"] = x.get_properties(); - j["toolComponent"] = x.get_tool_component(); - } - - inline void from_json(const json & j, SARIF::ConfigurationOverride& x) { - x.set_configuration(j.at("configuration").get()); - x.set_descriptor(j.at("descriptor").get()); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::ConfigurationOverride & x) { - j = json::object(); - j["configuration"] = x.get_configuration(); - j["descriptor"] = x.get_descriptor(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Region& x) { - x.set_byte_length(SARIF::get_optional(j, "byteLength")); - x.set_byte_offset(SARIF::get_optional(j, "byteOffset")); - x.set_char_length(SARIF::get_optional(j, "charLength")); - x.set_char_offset(SARIF::get_optional(j, "charOffset")); - x.set_end_column(SARIF::get_optional(j, "endColumn")); - x.set_end_line(SARIF::get_optional(j, "endLine")); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_snippet(SARIF::get_optional(j, "snippet")); - x.set_source_language(SARIF::get_optional(j, "sourceLanguage")); - x.set_start_column(SARIF::get_optional(j, "startColumn")); - x.set_start_line(SARIF::get_optional(j, "startLine")); - } - - inline void to_json(json & j, const SARIF::Region & x) { - j = json::object(); - j["byteLength"] = x.get_byte_length(); - j["byteOffset"] = x.get_byte_offset(); - j["charLength"] = x.get_char_length(); - j["charOffset"] = x.get_char_offset(); - j["endColumn"] = x.get_end_column(); - j["endLine"] = x.get_end_line(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["snippet"] = x.get_snippet(); - j["sourceLanguage"] = x.get_source_language(); - j["startColumn"] = x.get_start_column(); - j["startLine"] = x.get_start_line(); - } - - inline void from_json(const json & j, SARIF::LogicalLocation& x) { - x.set_decorated_name(SARIF::get_optional(j, "decoratedName")); - x.set_fully_qualified_name(SARIF::get_optional(j, "fullyQualifiedName")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_kind(SARIF::get_optional(j, "kind")); - x.set_name(SARIF::get_optional(j, "name")); - x.set_parent_index(SARIF::get_optional(j, "parentIndex")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::LogicalLocation & x) { - j = json::object(); - j["decoratedName"] = x.get_decorated_name(); - j["fullyQualifiedName"] = x.get_fully_qualified_name(); - j["index"] = x.get_index(); - j["kind"] = x.get_kind(); - j["name"] = x.get_name(); - j["parentIndex"] = x.get_parent_index(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::PhysicalLocation& x) { - x.set_address(SARIF::get_optional(j, "address")); - x.set_artifact_location(SARIF::get_optional(j, "artifactLocation")); - x.set_context_region(SARIF::get_optional(j, "contextRegion")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_region(SARIF::get_optional(j, "region")); - } - - inline void to_json(json & j, const SARIF::PhysicalLocation & x) { - j = json::object(); - j["address"] = x.get_address(); - j["artifactLocation"] = x.get_artifact_location(); - j["contextRegion"] = x.get_context_region(); - j["properties"] = x.get_properties(); - j["region"] = x.get_region(); - } - - inline void from_json(const json & j, SARIF::LocationRelationship& x) { - x.set_description(SARIF::get_optional(j, "description")); - x.set_kinds(SARIF::get_optional>(j, "kinds")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_target(j.at("target").get()); - } - - inline void to_json(json & j, const SARIF::LocationRelationship & x) { - j = json::object(); - j["description"] = x.get_description(); - j["kinds"] = x.get_kinds(); - j["properties"] = x.get_properties(); - j["target"] = x.get_target(); - } - - inline void from_json(const json & j, SARIF::Location& x) { - x.set_annotations(SARIF::get_optional>(j, "annotations")); - x.set_id(SARIF::get_optional(j, "id")); - x.set_logical_locations(SARIF::get_optional>(j, "logicalLocations")); - x.set_message(SARIF::get_optional(j, "message")); - x.set_physical_location(SARIF::get_optional(j, "physicalLocation")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_relationships(SARIF::get_optional>(j, "relationships")); - } - - inline void to_json(json & j, const SARIF::Location & x) { - j = json::object(); - j["annotations"] = x.get_annotations(); - j["id"] = x.get_id(); - j["logicalLocations"] = x.get_logical_locations(); - j["message"] = x.get_message(); - j["physicalLocation"] = x.get_physical_location(); - j["properties"] = x.get_properties(); - j["relationships"] = x.get_relationships(); - } - - inline void from_json(const json & j, SARIF::StackFrame& x) { - x.set_location(SARIF::get_optional(j, "location")); - x.set_stack_frame_module(SARIF::get_optional(j, "module")); - x.set_parameters(SARIF::get_optional>(j, "parameters")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_thread_id(SARIF::get_optional(j, "threadId")); - } - - inline void to_json(json & j, const SARIF::StackFrame & x) { - j = json::object(); - j["location"] = x.get_location(); - j["module"] = x.get_stack_frame_module(); - j["parameters"] = x.get_parameters(); - j["properties"] = x.get_properties(); - j["threadId"] = x.get_thread_id(); - } - - inline void from_json(const json & j, SARIF::Stack& x) { - x.set_frames(j.at("frames").get>()); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Stack & x) { - j = json::object(); - j["frames"] = x.get_frames(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Exception& x) { - x.set_inner_exceptions(SARIF::get_optional>(j, "innerExceptions")); - x.set_kind(SARIF::get_optional(j, "kind")); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_stack(SARIF::get_optional(j, "stack")); - } - - inline void to_json(json & j, const SARIF::Exception & x) { - j = json::object(); - j["innerExceptions"] = x.get_inner_exceptions(); - j["kind"] = x.get_kind(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["stack"] = x.get_stack(); - } - - inline void from_json(const json & j, SARIF::Notification& x) { - x.set_associated_rule(SARIF::get_optional(j, "associatedRule")); - x.set_descriptor(SARIF::get_optional(j, "descriptor")); - x.set_exception(SARIF::get_optional(j, "exception")); - x.set_level(SARIF::get_optional(j, "level")); - x.set_locations(SARIF::get_optional>(j, "locations")); - x.set_message(j.at("message").get()); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_thread_id(SARIF::get_optional(j, "threadId")); - x.set_time_utc(SARIF::get_optional(j, "timeUtc")); - } - - inline void to_json(json & j, const SARIF::Notification & x) { - j = json::object(); - j["associatedRule"] = x.get_associated_rule(); - j["descriptor"] = x.get_descriptor(); - j["exception"] = x.get_exception(); - j["level"] = x.get_level(); - j["locations"] = x.get_locations(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["threadId"] = x.get_thread_id(); - j["timeUtc"] = x.get_time_utc(); - } - - inline void from_json(const json & j, SARIF::Invocation& x) { - x.set_account(SARIF::get_optional(j, "account")); - x.set_arguments(SARIF::get_optional>(j, "arguments")); - x.set_command_line(SARIF::get_optional(j, "commandLine")); - x.set_end_time_utc(SARIF::get_optional(j, "endTimeUtc")); - x.set_environment_variables(SARIF::get_optional>(j, "environmentVariables")); - x.set_executable_location(SARIF::get_optional(j, "executableLocation")); - x.set_execution_successful(j.at("executionSuccessful").get()); - x.set_exit_code(SARIF::get_optional(j, "exitCode")); - x.set_exit_code_description(SARIF::get_optional(j, "exitCodeDescription")); - x.set_exit_signal_name(SARIF::get_optional(j, "exitSignalName")); - x.set_exit_signal_number(SARIF::get_optional(j, "exitSignalNumber")); - x.set_machine(SARIF::get_optional(j, "machine")); - x.set_notification_configuration_overrides(SARIF::get_optional>(j, "notificationConfigurationOverrides")); - x.set_process_id(SARIF::get_optional(j, "processId")); - x.set_process_start_failure_message(SARIF::get_optional(j, "processStartFailureMessage")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_response_files(SARIF::get_optional>(j, "responseFiles")); - x.set_rule_configuration_overrides(SARIF::get_optional>(j, "ruleConfigurationOverrides")); - x.set_start_time_utc(SARIF::get_optional(j, "startTimeUtc")); - x.set_stderr(SARIF::get_optional(j, "stderr")); - x.set_stdin(SARIF::get_optional(j, "stdin")); - x.set_stdout(SARIF::get_optional(j, "stdout")); - x.set_stdout_stderr(SARIF::get_optional(j, "stdoutStderr")); - x.set_tool_configuration_notifications(SARIF::get_optional>(j, "toolConfigurationNotifications")); - x.set_tool_execution_notifications(SARIF::get_optional>(j, "toolExecutionNotifications")); - x.set_working_directory(SARIF::get_optional(j, "workingDirectory")); - } - - inline void to_json(json & j, const SARIF::Invocation & x) { - j = json::object(); - j["account"] = x.get_account(); - j["arguments"] = x.get_arguments(); - j["commandLine"] = x.get_command_line(); - j["endTimeUtc"] = x.get_end_time_utc(); - j["environmentVariables"] = x.get_environment_variables(); - j["executableLocation"] = x.get_executable_location(); - j["executionSuccessful"] = x.get_execution_successful(); - j["exitCode"] = x.get_exit_code(); - j["exitCodeDescription"] = x.get_exit_code_description(); - j["exitSignalName"] = x.get_exit_signal_name(); - j["exitSignalNumber"] = x.get_exit_signal_number(); - j["machine"] = x.get_machine(); - j["notificationConfigurationOverrides"] = x.get_notification_configuration_overrides(); - j["processId"] = x.get_process_id(); - j["processStartFailureMessage"] = x.get_process_start_failure_message(); - j["properties"] = x.get_properties(); - j["responseFiles"] = x.get_response_files(); - j["ruleConfigurationOverrides"] = x.get_rule_configuration_overrides(); - j["startTimeUtc"] = x.get_start_time_utc(); - j["stderr"] = x.get_stderr(); - j["stdin"] = x.get_stdin(); - j["stdout"] = x.get_stdout(); - j["stdoutStderr"] = x.get_stdout_stderr(); - j["toolConfigurationNotifications"] = x.get_tool_configuration_notifications(); - j["toolExecutionNotifications"] = x.get_tool_execution_notifications(); - j["workingDirectory"] = x.get_working_directory(); - } - - inline void from_json(const json & j, SARIF::ReportingDescriptorRelationship& x) { - x.set_description(SARIF::get_optional(j, "description")); - x.set_kinds(SARIF::get_optional>(j, "kinds")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_target(j.at("target").get()); - } - - inline void to_json(json & j, const SARIF::ReportingDescriptorRelationship & x) { - j = json::object(); - j["description"] = x.get_description(); - j["kinds"] = x.get_kinds(); - j["properties"] = x.get_properties(); - j["target"] = x.get_target(); - } - - inline void from_json(const json & j, SARIF::ReportingDescriptor& x) { - x.set_default_configuration(SARIF::get_optional(j, "defaultConfiguration")); - x.set_deprecated_guids(SARIF::get_optional>(j, "deprecatedGuids")); - x.set_deprecated_ids(SARIF::get_optional>(j, "deprecatedIds")); - x.set_deprecated_names(SARIF::get_optional>(j, "deprecatedNames")); - x.set_full_description(SARIF::get_optional(j, "fullDescription")); - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_help(SARIF::get_optional(j, "help")); - x.set_help_uri(SARIF::get_optional(j, "helpUri")); - x.set_id(j.at("id").get()); - x.set_message_strings(SARIF::get_optional>(j, "messageStrings")); - x.set_name(SARIF::get_optional(j, "name")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_relationships(SARIF::get_optional>(j, "relationships")); - x.set_short_description(SARIF::get_optional(j, "shortDescription")); - } - - inline void to_json(json & j, const SARIF::ReportingDescriptor & x) { - j = json::object(); - j["defaultConfiguration"] = x.get_default_configuration(); - j["deprecatedGuids"] = x.get_deprecated_guids(); - j["deprecatedIds"] = x.get_deprecated_ids(); - j["deprecatedNames"] = x.get_deprecated_names(); - j["fullDescription"] = x.get_full_description(); - j["guid"] = x.get_guid(); - j["help"] = x.get_help(); - j["helpUri"] = x.get_help_uri(); - j["id"] = x.get_id(); - j["messageStrings"] = x.get_message_strings(); - j["name"] = x.get_name(); - j["properties"] = x.get_properties(); - j["relationships"] = x.get_relationships(); - j["shortDescription"] = x.get_short_description(); - } - - inline void from_json(const json & j, SARIF::TranslationMetadata& x) { - x.set_download_uri(SARIF::get_optional(j, "downloadUri")); - x.set_full_description(SARIF::get_optional(j, "fullDescription")); - x.set_full_name(SARIF::get_optional(j, "fullName")); - x.set_information_uri(SARIF::get_optional(j, "informationUri")); - x.set_name(j.at("name").get()); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_short_description(SARIF::get_optional(j, "shortDescription")); - } - - inline void to_json(json & j, const SARIF::TranslationMetadata & x) { - j = json::object(); - j["downloadUri"] = x.get_download_uri(); - j["fullDescription"] = x.get_full_description(); - j["fullName"] = x.get_full_name(); - j["informationUri"] = x.get_information_uri(); - j["name"] = x.get_name(); - j["properties"] = x.get_properties(); - j["shortDescription"] = x.get_short_description(); - } - - inline void from_json(const json & j, SARIF::ToolComponent& x) { - x.set_associated_component(SARIF::get_optional(j, "associatedComponent")); - x.set_contents(SARIF::get_optional>(j, "contents")); - x.set_dotted_quad_file_version(SARIF::get_optional(j, "dottedQuadFileVersion")); - x.set_download_uri(SARIF::get_optional(j, "downloadUri")); - x.set_full_description(SARIF::get_optional(j, "fullDescription")); - x.set_full_name(SARIF::get_optional(j, "fullName")); - x.set_global_message_strings(SARIF::get_optional>(j, "globalMessageStrings")); - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_information_uri(SARIF::get_optional(j, "informationUri")); - x.set_is_comprehensive(SARIF::get_optional(j, "isComprehensive")); - x.set_language(SARIF::get_optional(j, "language")); - x.set_localized_data_semantic_version(SARIF::get_optional(j, "localizedDataSemanticVersion")); - x.set_locations(SARIF::get_optional>(j, "locations")); - x.set_minimum_required_localized_data_semantic_version(SARIF::get_optional(j, "minimumRequiredLocalizedDataSemanticVersion")); - x.set_name(j.at("name").get()); - x.set_notifications(SARIF::get_optional>(j, "notifications")); - x.set_organization(SARIF::get_optional(j, "organization")); - x.set_product(SARIF::get_optional(j, "product")); - x.set_product_suite(SARIF::get_optional(j, "productSuite")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_release_date_utc(SARIF::get_optional(j, "releaseDateUtc")); - x.set_rules(SARIF::get_optional>(j, "rules")); - x.set_semantic_version(SARIF::get_optional(j, "semanticVersion")); - x.set_short_description(SARIF::get_optional(j, "shortDescription")); - x.set_supported_taxonomies(SARIF::get_optional>(j, "supportedTaxonomies")); - x.set_taxa(SARIF::get_optional>(j, "taxa")); - x.set_translation_metadata(SARIF::get_optional(j, "translationMetadata")); - x.set_version(SARIF::get_optional(j, "version")); - } - - inline void to_json(json & j, const SARIF::ToolComponent & x) { - j = json::object(); - j["associatedComponent"] = x.get_associated_component(); - j["contents"] = x.get_contents(); - j["dottedQuadFileVersion"] = x.get_dotted_quad_file_version(); - j["downloadUri"] = x.get_download_uri(); - j["fullDescription"] = x.get_full_description(); - j["fullName"] = x.get_full_name(); - j["globalMessageStrings"] = x.get_global_message_strings(); - j["guid"] = x.get_guid(); - j["informationUri"] = x.get_information_uri(); - j["isComprehensive"] = x.get_is_comprehensive(); - j["language"] = x.get_language(); - j["localizedDataSemanticVersion"] = x.get_localized_data_semantic_version(); - j["locations"] = x.get_locations(); - j["minimumRequiredLocalizedDataSemanticVersion"] = x.get_minimum_required_localized_data_semantic_version(); - j["name"] = x.get_name(); - j["notifications"] = x.get_notifications(); - j["organization"] = x.get_organization(); - j["product"] = x.get_product(); - j["productSuite"] = x.get_product_suite(); - j["properties"] = x.get_properties(); - j["releaseDateUtc"] = x.get_release_date_utc(); - j["rules"] = x.get_rules(); - j["semanticVersion"] = x.get_semantic_version(); - j["shortDescription"] = x.get_short_description(); - j["supportedTaxonomies"] = x.get_supported_taxonomies(); - j["taxa"] = x.get_taxa(); - j["translationMetadata"] = x.get_translation_metadata(); - j["version"] = x.get_version(); - } - - inline void from_json(const json & j, SARIF::Tool& x) { - x.set_driver(j.at("driver").get()); - x.set_extensions(SARIF::get_optional>(j, "extensions")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Tool & x) { - j = json::object(); - j["driver"] = x.get_driver(); - j["extensions"] = x.get_extensions(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Conversion& x) { - x.set_analysis_tool_log_files(SARIF::get_optional>(j, "analysisToolLogFiles")); - x.set_invocation(SARIF::get_optional(j, "invocation")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_tool(j.at("tool").get()); - } - - inline void to_json(json & j, const SARIF::Conversion & x) { - j = json::object(); - j["analysisToolLogFiles"] = x.get_analysis_tool_log_files(); - j["invocation"] = x.get_invocation(); - j["properties"] = x.get_properties(); - j["tool"] = x.get_tool(); - } - - inline void from_json(const json & j, SARIF::Edge& x) { - x.set_id(j.at("id").get()); - x.set_label(SARIF::get_optional(j, "label")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_source_node_id(j.at("sourceNodeId").get()); - x.set_target_node_id(j.at("targetNodeId").get()); - } - - inline void to_json(json & j, const SARIF::Edge & x) { - j = json::object(); - j["id"] = x.get_id(); - j["label"] = x.get_label(); - j["properties"] = x.get_properties(); - j["sourceNodeId"] = x.get_source_node_id(); - j["targetNodeId"] = x.get_target_node_id(); - } - - inline void from_json(const json & j, SARIF::Node& x) { - x.set_children(SARIF::get_optional>(j, "children")); - x.set_id(j.at("id").get()); - x.set_label(SARIF::get_optional(j, "label")); - x.set_location(SARIF::get_optional(j, "location")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Node & x) { - j = json::object(); - j["children"] = x.get_children(); - j["id"] = x.get_id(); - j["label"] = x.get_label(); - j["location"] = x.get_location(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Graph& x) { - x.set_description(SARIF::get_optional(j, "description")); - x.set_edges(SARIF::get_optional>(j, "edges")); - x.set_nodes(SARIF::get_optional>(j, "nodes")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Graph & x) { - j = json::object(); - j["description"] = x.get_description(); - j["edges"] = x.get_edges(); - j["nodes"] = x.get_nodes(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Rectangle& x) { - x.set_bottom(SARIF::get_optional(j, "bottom")); - x.set_left(SARIF::get_optional(j, "left")); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_right(SARIF::get_optional(j, "right")); - x.set_top(SARIF::get_optional(j, "top")); - } - - inline void to_json(json & j, const SARIF::Rectangle & x) { - j = json::object(); - j["bottom"] = x.get_bottom(); - j["left"] = x.get_left(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["right"] = x.get_right(); - j["top"] = x.get_top(); - } - - inline void from_json(const json & j, SARIF::Attachment& x) { - x.set_artifact_location(j.at("artifactLocation").get()); - x.set_description(SARIF::get_optional(j, "description")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_rectangles(SARIF::get_optional>(j, "rectangles")); - x.set_regions(SARIF::get_optional>(j, "regions")); - } - - inline void to_json(json & j, const SARIF::Attachment & x) { - j = json::object(); - j["artifactLocation"] = x.get_artifact_location(); - j["description"] = x.get_description(); - j["properties"] = x.get_properties(); - j["rectangles"] = x.get_rectangles(); - j["regions"] = x.get_regions(); - } - - inline void from_json(const json & j, SARIF::WebRequest& x) { - x.set_body(SARIF::get_optional(j, "body")); - x.set_headers(SARIF::get_optional>(j, "headers")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_method(SARIF::get_optional(j, "method")); - x.set_parameters(SARIF::get_optional>(j, "parameters")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_protocol(SARIF::get_optional(j, "protocol")); - x.set_target(SARIF::get_optional(j, "target")); - x.set_version(SARIF::get_optional(j, "version")); - } - - inline void to_json(json & j, const SARIF::WebRequest & x) { - j = json::object(); - j["body"] = x.get_body(); - j["headers"] = x.get_headers(); - j["index"] = x.get_index(); - j["method"] = x.get_method(); - j["parameters"] = x.get_parameters(); - j["properties"] = x.get_properties(); - j["protocol"] = x.get_protocol(); - j["target"] = x.get_target(); - j["version"] = x.get_version(); - } - - inline void from_json(const json & j, SARIF::WebResponse& x) { - x.set_body(SARIF::get_optional(j, "body")); - x.set_headers(SARIF::get_optional>(j, "headers")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_no_response_received(SARIF::get_optional(j, "noResponseReceived")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_protocol(SARIF::get_optional(j, "protocol")); - x.set_reason_phrase(SARIF::get_optional(j, "reasonPhrase")); - x.set_status_code(SARIF::get_optional(j, "statusCode")); - x.set_version(SARIF::get_optional(j, "version")); - } - - inline void to_json(json & j, const SARIF::WebResponse & x) { - j = json::object(); - j["body"] = x.get_body(); - j["headers"] = x.get_headers(); - j["index"] = x.get_index(); - j["noResponseReceived"] = x.get_no_response_received(); - j["properties"] = x.get_properties(); - j["protocol"] = x.get_protocol(); - j["reasonPhrase"] = x.get_reason_phrase(); - j["statusCode"] = x.get_status_code(); - j["version"] = x.get_version(); - } - - inline void from_json(const json & j, SARIF::ThreadFlowLocation& x) { - x.set_execution_order(SARIF::get_optional(j, "executionOrder")); - x.set_execution_time_utc(SARIF::get_optional(j, "executionTimeUtc")); - x.set_importance(SARIF::get_optional(j, "importance")); - x.set_index(SARIF::get_optional(j, "index")); - x.set_kinds(SARIF::get_optional>(j, "kinds")); - x.set_location(SARIF::get_optional(j, "location")); - x.set_thread_flow_location_module(SARIF::get_optional(j, "module")); - x.set_nesting_level(SARIF::get_optional(j, "nestingLevel")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_stack(SARIF::get_optional(j, "stack")); - x.set_state(SARIF::get_optional>(j, "state")); - x.set_taxa(SARIF::get_optional>(j, "taxa")); - x.set_web_request(SARIF::get_optional(j, "webRequest")); - x.set_web_response(SARIF::get_optional(j, "webResponse")); - } - - inline void to_json(json & j, const SARIF::ThreadFlowLocation & x) { - j = json::object(); - j["executionOrder"] = x.get_execution_order(); - j["executionTimeUtc"] = x.get_execution_time_utc(); - j["importance"] = x.get_importance(); - j["index"] = x.get_index(); - j["kinds"] = x.get_kinds(); - j["location"] = x.get_location(); - j["module"] = x.get_thread_flow_location_module(); - j["nestingLevel"] = x.get_nesting_level(); - j["properties"] = x.get_properties(); - j["stack"] = x.get_stack(); - j["state"] = x.get_state(); - j["taxa"] = x.get_taxa(); - j["webRequest"] = x.get_web_request(); - j["webResponse"] = x.get_web_response(); - } - - inline void from_json(const json & j, SARIF::ThreadFlow& x) { - x.set_id(SARIF::get_optional(j, "id")); - x.set_immutable_state(SARIF::get_optional>(j, "immutableState")); - x.set_initial_state(SARIF::get_optional>(j, "initialState")); - x.set_locations(j.at("locations").get>()); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::ThreadFlow & x) { - j = json::object(); - j["id"] = x.get_id(); - j["immutableState"] = x.get_immutable_state(); - j["initialState"] = x.get_initial_state(); - j["locations"] = x.get_locations(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::CodeFlow& x) { - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_thread_flows(j.at("threadFlows").get>()); - } - - inline void to_json(json & j, const SARIF::CodeFlow & x) { - j = json::object(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["threadFlows"] = x.get_thread_flows(); - } - - inline void from_json(const json & j, SARIF::Replacement& x) { - x.set_deleted_region(j.at("deletedRegion").get()); - x.set_inserted_content(SARIF::get_optional(j, "insertedContent")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Replacement & x) { - j = json::object(); - j["deletedRegion"] = x.get_deleted_region(); - j["insertedContent"] = x.get_inserted_content(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::ArtifactChange& x) { - x.set_artifact_location(j.at("artifactLocation").get()); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_replacements(j.at("replacements").get>()); - } - - inline void to_json(json & j, const SARIF::ArtifactChange & x) { - j = json::object(); - j["artifactLocation"] = x.get_artifact_location(); - j["properties"] = x.get_properties(); - j["replacements"] = x.get_replacements(); - } - - inline void from_json(const json & j, SARIF::Fix& x) { - x.set_artifact_changes(j.at("artifactChanges").get>()); - x.set_description(SARIF::get_optional(j, "description")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::Fix & x) { - j = json::object(); - j["artifactChanges"] = x.get_artifact_changes(); - j["description"] = x.get_description(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::EdgeTraversal& x) { - x.set_edge_id(j.at("edgeId").get()); - x.set_final_state(SARIF::get_optional>(j, "finalState")); - x.set_message(SARIF::get_optional(j, "message")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_step_over_edge_count(SARIF::get_optional(j, "stepOverEdgeCount")); - } - - inline void to_json(json & j, const SARIF::EdgeTraversal & x) { - j = json::object(); - j["edgeId"] = x.get_edge_id(); - j["finalState"] = x.get_final_state(); - j["message"] = x.get_message(); - j["properties"] = x.get_properties(); - j["stepOverEdgeCount"] = x.get_step_over_edge_count(); - } - - inline void from_json(const json & j, SARIF::GraphTraversal& x) { - x.set_description(SARIF::get_optional(j, "description")); - x.set_edge_traversals(SARIF::get_optional>(j, "edgeTraversals")); - x.set_immutable_state(SARIF::get_optional>(j, "immutableState")); - x.set_initial_state(SARIF::get_optional>(j, "initialState")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_result_graph_index(SARIF::get_optional(j, "resultGraphIndex")); - x.set_run_graph_index(SARIF::get_optional(j, "runGraphIndex")); - } - - inline void to_json(json & j, const SARIF::GraphTraversal & x) { - j = json::object(); - j["description"] = x.get_description(); - j["edgeTraversals"] = x.get_edge_traversals(); - j["immutableState"] = x.get_immutable_state(); - j["initialState"] = x.get_initial_state(); - j["properties"] = x.get_properties(); - j["resultGraphIndex"] = x.get_result_graph_index(); - j["runGraphIndex"] = x.get_run_graph_index(); - } - - inline void from_json(const json & j, SARIF::ResultProvenance& x) { - x.set_conversion_sources(SARIF::get_optional>(j, "conversionSources")); - x.set_first_detection_run_guid(SARIF::get_optional(j, "firstDetectionRunGuid")); - x.set_first_detection_time_utc(SARIF::get_optional(j, "firstDetectionTimeUtc")); - x.set_invocation_index(SARIF::get_optional(j, "invocationIndex")); - x.set_last_detection_run_guid(SARIF::get_optional(j, "lastDetectionRunGuid")); - x.set_last_detection_time_utc(SARIF::get_optional(j, "lastDetectionTimeUtc")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::ResultProvenance & x) { - j = json::object(); - j["conversionSources"] = x.get_conversion_sources(); - j["firstDetectionRunGuid"] = x.get_first_detection_run_guid(); - j["firstDetectionTimeUtc"] = x.get_first_detection_time_utc(); - j["invocationIndex"] = x.get_invocation_index(); - j["lastDetectionRunGuid"] = x.get_last_detection_run_guid(); - j["lastDetectionTimeUtc"] = x.get_last_detection_time_utc(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::Suppression& x) { - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_justification(SARIF::get_optional(j, "justification")); - x.set_kind(j.at("kind").get()); - x.set_location(SARIF::get_optional(j, "location")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_status(SARIF::get_optional(j, "status")); - } - - inline void to_json(json & j, const SARIF::Suppression & x) { - j = json::object(); - j["guid"] = x.get_guid(); - j["justification"] = x.get_justification(); - j["kind"] = x.get_kind(); - j["location"] = x.get_location(); - j["properties"] = x.get_properties(); - j["status"] = x.get_status(); - } - - inline void from_json(const json & j, SARIF::Result& x) { - x.set_analysis_target(SARIF::get_optional(j, "analysisTarget")); - x.set_attachments(SARIF::get_optional>(j, "attachments")); - x.set_baseline_state(SARIF::get_optional(j, "baselineState")); - x.set_code_flows(SARIF::get_optional>(j, "codeFlows")); - x.set_correlation_guid(SARIF::get_optional(j, "correlationGuid")); - x.set_fingerprints(SARIF::get_optional>(j, "fingerprints")); - x.set_fixes(SARIF::get_optional>(j, "fixes")); - x.set_graphs(SARIF::get_optional>(j, "graphs")); - x.set_graph_traversals(SARIF::get_optional>(j, "graphTraversals")); - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_hosted_viewer_uri(SARIF::get_optional(j, "hostedViewerUri")); - x.set_kind(SARIF::get_optional(j, "kind")); - x.set_level(SARIF::get_optional(j, "level")); - x.set_locations(SARIF::get_optional>(j, "locations")); - x.set_message(j.at("message").get()); - x.set_occurrence_count(SARIF::get_optional(j, "occurrenceCount")); - x.set_partial_fingerprints(SARIF::get_optional>(j, "partialFingerprints")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_provenance(SARIF::get_optional(j, "provenance")); - x.set_rank(SARIF::get_optional(j, "rank")); - x.set_related_locations(SARIF::get_optional>(j, "relatedLocations")); - x.set_rule(SARIF::get_optional(j, "rule")); - x.set_rule_id(SARIF::get_optional(j, "ruleId")); - x.set_rule_index(SARIF::get_optional(j, "ruleIndex")); - x.set_stacks(SARIF::get_optional>(j, "stacks")); - x.set_suppressions(SARIF::get_optional>(j, "suppressions")); - x.set_taxa(SARIF::get_optional>(j, "taxa")); - x.set_web_request(SARIF::get_optional(j, "webRequest")); - x.set_web_response(SARIF::get_optional(j, "webResponse")); - x.set_work_item_uris(SARIF::get_optional>(j, "workItemUris")); - } - - inline void to_json(json & j, const SARIF::Result & x) { - j = json::object(); - j["analysisTarget"] = x.get_analysis_target(); - j["attachments"] = x.get_attachments(); - j["baselineState"] = x.get_baseline_state(); - j["codeFlows"] = x.get_code_flows(); - j["correlationGuid"] = x.get_correlation_guid(); - j["fingerprints"] = x.get_fingerprints(); - j["fixes"] = x.get_fixes(); - j["graphs"] = x.get_graphs(); - j["graphTraversals"] = x.get_graph_traversals(); - j["guid"] = x.get_guid(); - j["hostedViewerUri"] = x.get_hosted_viewer_uri(); - j["kind"] = x.get_kind(); - j["level"] = x.get_level(); - j["locations"] = x.get_locations(); - j["message"] = x.get_message(); - j["occurrenceCount"] = x.get_occurrence_count(); - j["partialFingerprints"] = x.get_partial_fingerprints(); - j["properties"] = x.get_properties(); - j["provenance"] = x.get_provenance(); - j["rank"] = x.get_rank(); - j["relatedLocations"] = x.get_related_locations(); - j["rule"] = x.get_rule(); - j["ruleId"] = x.get_rule_id(); - j["ruleIndex"] = x.get_rule_index(); - j["stacks"] = x.get_stacks(); - j["suppressions"] = x.get_suppressions(); - j["taxa"] = x.get_taxa(); - j["webRequest"] = x.get_web_request(); - j["webResponse"] = x.get_web_response(); - j["workItemUris"] = x.get_work_item_uris(); - } - - inline void from_json(const json & j, SARIF::ExternalProperties& x) { - x.set_addresses(SARIF::get_optional>(j, "addresses")); - x.set_artifacts(SARIF::get_optional>(j, "artifacts")); - x.set_conversion(SARIF::get_optional(j, "conversion")); - x.set_driver(SARIF::get_optional(j, "driver")); - x.set_extensions(SARIF::get_optional>(j, "extensions")); - x.set_externalized_properties(SARIF::get_optional(j, "externalizedProperties")); - x.set_graphs(SARIF::get_optional>(j, "graphs")); - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_invocations(SARIF::get_optional>(j, "invocations")); - x.set_logical_locations(SARIF::get_optional>(j, "logicalLocations")); - x.set_policies(SARIF::get_optional>(j, "policies")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_results(SARIF::get_optional>(j, "results")); - x.set_run_guid(SARIF::get_optional(j, "runGuid")); - x.set_schema(SARIF::get_optional(j, "schema")); - x.set_taxonomies(SARIF::get_optional>(j, "taxonomies")); - x.set_thread_flow_locations(SARIF::get_optional>(j, "threadFlowLocations")); - x.set_translations(SARIF::get_optional>(j, "translations")); - x.set_version(SARIF::get_optional(j, "version")); - x.set_web_requests(SARIF::get_optional>(j, "webRequests")); - x.set_web_responses(SARIF::get_optional>(j, "webResponses")); - } - - inline void to_json(json & j, const SARIF::ExternalProperties & x) { - j = json::object(); - j["addresses"] = x.get_addresses(); - j["artifacts"] = x.get_artifacts(); - j["conversion"] = x.get_conversion(); - j["driver"] = x.get_driver(); - j["extensions"] = x.get_extensions(); - j["externalizedProperties"] = x.get_externalized_properties(); - j["graphs"] = x.get_graphs(); - j["guid"] = x.get_guid(); - j["invocations"] = x.get_invocations(); - j["logicalLocations"] = x.get_logical_locations(); - j["policies"] = x.get_policies(); - j["properties"] = x.get_properties(); - j["results"] = x.get_results(); - j["runGuid"] = x.get_run_guid(); - j["schema"] = x.get_schema(); - j["taxonomies"] = x.get_taxonomies(); - j["threadFlowLocations"] = x.get_thread_flow_locations(); - j["translations"] = x.get_translations(); - j["version"] = x.get_version(); - j["webRequests"] = x.get_web_requests(); - j["webResponses"] = x.get_web_responses(); - } - - inline void from_json(const json & j, SARIF::RunAutomationDetails& x) { - x.set_correlation_guid(SARIF::get_optional(j, "correlationGuid")); - x.set_description(SARIF::get_optional(j, "description")); - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_id(SARIF::get_optional(j, "id")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::RunAutomationDetails & x) { - j = json::object(); - j["correlationGuid"] = x.get_correlation_guid(); - j["description"] = x.get_description(); - j["guid"] = x.get_guid(); - j["id"] = x.get_id(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::ExternalPropertyFileReference& x) { - x.set_guid(SARIF::get_optional(j, "guid")); - x.set_item_count(SARIF::get_optional(j, "itemCount")); - x.set_location(SARIF::get_optional(j, "location")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::ExternalPropertyFileReference & x) { - j = json::object(); - j["guid"] = x.get_guid(); - j["itemCount"] = x.get_item_count(); - j["location"] = x.get_location(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::ExternalPropertyFileReferences& x) { - x.set_addresses(SARIF::get_optional>(j, "addresses")); - x.set_artifacts(SARIF::get_optional>(j, "artifacts")); - x.set_conversion(SARIF::get_optional(j, "conversion")); - x.set_driver(SARIF::get_optional(j, "driver")); - x.set_extensions(SARIF::get_optional>(j, "extensions")); - x.set_externalized_properties(SARIF::get_optional(j, "externalizedProperties")); - x.set_graphs(SARIF::get_optional>(j, "graphs")); - x.set_invocations(SARIF::get_optional>(j, "invocations")); - x.set_logical_locations(SARIF::get_optional>(j, "logicalLocations")); - x.set_policies(SARIF::get_optional>(j, "policies")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_results(SARIF::get_optional>(j, "results")); - x.set_taxonomies(SARIF::get_optional>(j, "taxonomies")); - x.set_thread_flow_locations(SARIF::get_optional>(j, "threadFlowLocations")); - x.set_translations(SARIF::get_optional>(j, "translations")); - x.set_web_requests(SARIF::get_optional>(j, "webRequests")); - x.set_web_responses(SARIF::get_optional>(j, "webResponses")); - } - - inline void to_json(json & j, const SARIF::ExternalPropertyFileReferences & x) { - j = json::object(); - j["addresses"] = x.get_addresses(); - j["artifacts"] = x.get_artifacts(); - j["conversion"] = x.get_conversion(); - j["driver"] = x.get_driver(); - j["extensions"] = x.get_extensions(); - j["externalizedProperties"] = x.get_externalized_properties(); - j["graphs"] = x.get_graphs(); - j["invocations"] = x.get_invocations(); - j["logicalLocations"] = x.get_logical_locations(); - j["policies"] = x.get_policies(); - j["properties"] = x.get_properties(); - j["results"] = x.get_results(); - j["taxonomies"] = x.get_taxonomies(); - j["threadFlowLocations"] = x.get_thread_flow_locations(); - j["translations"] = x.get_translations(); - j["webRequests"] = x.get_web_requests(); - j["webResponses"] = x.get_web_responses(); - } - - inline void from_json(const json & j, SARIF::SpecialLocations& x) { - x.set_display_base(SARIF::get_optional(j, "displayBase")); - x.set_properties(SARIF::get_optional(j, "properties")); - } - - inline void to_json(json & j, const SARIF::SpecialLocations & x) { - j = json::object(); - j["displayBase"] = x.get_display_base(); - j["properties"] = x.get_properties(); - } - - inline void from_json(const json & j, SARIF::VersionControlDetails& x) { - x.set_as_of_time_utc(SARIF::get_optional(j, "asOfTimeUtc")); - x.set_branch(SARIF::get_optional(j, "branch")); - x.set_mapped_to(SARIF::get_optional(j, "mappedTo")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_repository_uri(j.at("repositoryUri").get()); - x.set_revision_id(SARIF::get_optional(j, "revisionId")); - x.set_revision_tag(SARIF::get_optional(j, "revisionTag")); - } - - inline void to_json(json & j, const SARIF::VersionControlDetails & x) { - j = json::object(); - j["asOfTimeUtc"] = x.get_as_of_time_utc(); - j["branch"] = x.get_branch(); - j["mappedTo"] = x.get_mapped_to(); - j["properties"] = x.get_properties(); - j["repositoryUri"] = x.get_repository_uri(); - j["revisionId"] = x.get_revision_id(); - j["revisionTag"] = x.get_revision_tag(); - } - - inline void from_json(const json & j, SARIF::Run& x) { - x.set_addresses(SARIF::get_optional>(j, "addresses")); - x.set_artifacts(SARIF::get_optional>(j, "artifacts")); - x.set_automation_details(SARIF::get_optional(j, "automationDetails")); - x.set_baseline_guid(SARIF::get_optional(j, "baselineGuid")); - x.set_column_kind(SARIF::get_optional(j, "columnKind")); - x.set_conversion(SARIF::get_optional(j, "conversion")); - x.set_default_encoding(SARIF::get_optional(j, "defaultEncoding")); - x.set_default_source_language(SARIF::get_optional(j, "defaultSourceLanguage")); - x.set_external_property_file_references(SARIF::get_optional(j, "externalPropertyFileReferences")); - x.set_graphs(SARIF::get_optional>(j, "graphs")); - x.set_invocations(SARIF::get_optional>(j, "invocations")); - x.set_language(SARIF::get_optional(j, "language")); - x.set_logical_locations(SARIF::get_optional>(j, "logicalLocations")); - x.set_newline_sequences(SARIF::get_optional>(j, "newlineSequences")); - x.set_original_uri_base_ids(SARIF::get_optional>(j, "originalUriBaseIds")); - x.set_policies(SARIF::get_optional>(j, "policies")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_redaction_tokens(SARIF::get_optional>(j, "redactionTokens")); - x.set_results(SARIF::get_optional>(j, "results")); - x.set_run_aggregates(SARIF::get_optional>(j, "runAggregates")); - x.set_special_locations(SARIF::get_optional(j, "specialLocations")); - x.set_taxonomies(SARIF::get_optional>(j, "taxonomies")); - x.set_thread_flow_locations(SARIF::get_optional>(j, "threadFlowLocations")); - x.set_tool(j.at("tool").get()); - x.set_translations(SARIF::get_optional>(j, "translations")); - x.set_version_control_provenance(SARIF::get_optional>(j, "versionControlProvenance")); - x.set_web_requests(SARIF::get_optional>(j, "webRequests")); - x.set_web_responses(SARIF::get_optional>(j, "webResponses")); - } - - inline void to_json(json & j, const SARIF::Run & x) { - j = json::object(); - j["addresses"] = x.get_addresses(); - j["artifacts"] = x.get_artifacts(); - j["automationDetails"] = x.get_automation_details(); - j["baselineGuid"] = x.get_baseline_guid(); - j["columnKind"] = x.get_column_kind(); - j["conversion"] = x.get_conversion(); - j["defaultEncoding"] = x.get_default_encoding(); - j["defaultSourceLanguage"] = x.get_default_source_language(); - j["externalPropertyFileReferences"] = x.get_external_property_file_references(); - j["graphs"] = x.get_graphs(); - j["invocations"] = x.get_invocations(); - j["language"] = x.get_language(); - j["logicalLocations"] = x.get_logical_locations(); - j["newlineSequences"] = x.get_newline_sequences(); - j["originalUriBaseIds"] = x.get_original_uri_base_ids(); - j["policies"] = x.get_policies(); - j["properties"] = x.get_properties(); - j["redactionTokens"] = x.get_redaction_tokens(); - j["results"] = x.get_results(); - j["runAggregates"] = x.get_run_aggregates(); - j["specialLocations"] = x.get_special_locations(); - j["taxonomies"] = x.get_taxonomies(); - j["threadFlowLocations"] = x.get_thread_flow_locations(); - j["tool"] = x.get_tool(); - j["translations"] = x.get_translations(); - j["versionControlProvenance"] = x.get_version_control_provenance(); - j["webRequests"] = x.get_web_requests(); - j["webResponses"] = x.get_web_responses(); - } - - inline void from_json(const json & j, SARIF::Coordinate& x) { - x.set_schema(SARIF::get_optional(j, "$schema")); - x.set_inline_external_properties(SARIF::get_optional>(j, "inlineExternalProperties")); - x.set_properties(SARIF::get_optional(j, "properties")); - x.set_runs(j.at("runs").get>()); - x.set_version(j.at("version").get()); - } - - inline void to_json(json & j, const SARIF::Coordinate & x) { - j = json::object(); - j["$schema"] = x.get_schema(); - j["inlineExternalProperties"] = x.get_inline_external_properties(); - j["properties"] = x.get_properties(); - j["runs"] = x.get_runs(); - j["version"] = x.get_version(); - } - - inline void from_json(const json & j, SARIF::Role & x) { - static std::unordered_map enumValues { - {"added", SARIF::Role::ADDED}, - {"analysisTarget", SARIF::Role::ANALYSIS_TARGET}, - {"attachment", SARIF::Role::ATTACHMENT}, - {"debugOutputFile", SARIF::Role::DEBUG_OUTPUT_FILE}, - {"deleted", SARIF::Role::DELETED}, - {"directory", SARIF::Role::DIRECTORY}, - {"driver", SARIF::Role::DRIVER}, - {"extension", SARIF::Role::EXTENSION}, - {"memoryContents", SARIF::Role::MEMORY_CONTENTS}, - {"modified", SARIF::Role::MODIFIED}, - {"policy", SARIF::Role::POLICY}, - {"referencedOnCommandLine", SARIF::Role::REFERENCED_ON_COMMAND_LINE}, - {"renamed", SARIF::Role::RENAMED}, - {"responseFile", SARIF::Role::RESPONSE_FILE}, - {"resultFile", SARIF::Role::RESULT_FILE}, - {"standardStream", SARIF::Role::STANDARD_STREAM}, - {"taxonomy", SARIF::Role::TAXONOMY}, - {"toolSpecifiedConfiguration", SARIF::Role::TOOL_SPECIFIED_CONFIGURATION}, - {"tracedFile", SARIF::Role::TRACED_FILE}, - {"translation", SARIF::Role::TRANSLATION}, - {"uncontrolled", SARIF::Role::UNCONTROLLED}, - {"unmodified", SARIF::Role::UNMODIFIED}, - {"userSpecifiedConfiguration", SARIF::Role::USER_SPECIFIED_CONFIGURATION}, - }; - auto iter = enumValues.find(j); - if (iter != enumValues.end()) { - x = iter->second; - } - } - - inline void to_json(json & j, const SARIF::Role & x) { - switch (x) { - case SARIF::Role::ADDED: j = "added"; break; - case SARIF::Role::ANALYSIS_TARGET: j = "analysisTarget"; break; - case SARIF::Role::ATTACHMENT: j = "attachment"; break; - case SARIF::Role::DEBUG_OUTPUT_FILE: j = "debugOutputFile"; break; - case SARIF::Role::DELETED: j = "deleted"; break; - case SARIF::Role::DIRECTORY: j = "directory"; break; - case SARIF::Role::DRIVER: j = "driver"; break; - case SARIF::Role::EXTENSION: j = "extension"; break; - case SARIF::Role::MEMORY_CONTENTS: j = "memoryContents"; break; - case SARIF::Role::MODIFIED: j = "modified"; break; - case SARIF::Role::POLICY: j = "policy"; break; - case SARIF::Role::REFERENCED_ON_COMMAND_LINE: j = "referencedOnCommandLine"; break; - case SARIF::Role::RENAMED: j = "renamed"; break; - case SARIF::Role::RESPONSE_FILE: j = "responseFile"; break; - case SARIF::Role::RESULT_FILE: j = "resultFile"; break; - case SARIF::Role::STANDARD_STREAM: j = "standardStream"; break; - case SARIF::Role::TAXONOMY: j = "taxonomy"; break; - case SARIF::Role::TOOL_SPECIFIED_CONFIGURATION: j = "toolSpecifiedConfiguration"; break; - case SARIF::Role::TRACED_FILE: j = "tracedFile"; break; - case SARIF::Role::TRANSLATION: j = "translation"; break; - case SARIF::Role::UNCONTROLLED: j = "uncontrolled"; break; - case SARIF::Role::UNMODIFIED: j = "unmodified"; break; - case SARIF::Role::USER_SPECIFIED_CONFIGURATION: j = "userSpecifiedConfiguration"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::Level & x) { - if (j == "error") x = SARIF::Level::ERROR; - else if (j == "none") x = SARIF::Level::NONE; - else if (j == "note") x = SARIF::Level::NOTE; - else if (j == "warning") x = SARIF::Level::WARNING; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::Level & x) { - switch (x) { - case SARIF::Level::ERROR: j = "error"; break; - case SARIF::Level::NONE: j = "none"; break; - case SARIF::Level::NOTE: j = "note"; break; - case SARIF::Level::WARNING: j = "warning"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::Content & x) { - if (j == "localizedData") x = SARIF::Content::LOCALIZED_DATA; - else if (j == "nonLocalizedData") x = SARIF::Content::NON_LOCALIZED_DATA; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::Content & x) { - switch (x) { - case SARIF::Content::LOCALIZED_DATA: j = "localizedData"; break; - case SARIF::Content::NON_LOCALIZED_DATA: j = "nonLocalizedData"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::BaselineState & x) { - if (j == "absent") x = SARIF::BaselineState::ABSENT; - else if (j == "new") x = SARIF::BaselineState::NEW; - else if (j == "unchanged") x = SARIF::BaselineState::UNCHANGED; - else if (j == "updated") x = SARIF::BaselineState::UPDATED; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::BaselineState & x) { - switch (x) { - case SARIF::BaselineState::ABSENT: j = "absent"; break; - case SARIF::BaselineState::NEW: j = "new"; break; - case SARIF::BaselineState::UNCHANGED: j = "unchanged"; break; - case SARIF::BaselineState::UPDATED: j = "updated"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::Importance & x) { - if (j == "essential") x = SARIF::Importance::ESSENTIAL; - else if (j == "important") x = SARIF::Importance::IMPORTANT; - else if (j == "unimportant") x = SARIF::Importance::UNIMPORTANT; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::Importance & x) { - switch (x) { - case SARIF::Importance::ESSENTIAL: j = "essential"; break; - case SARIF::Importance::IMPORTANT: j = "important"; break; - case SARIF::Importance::UNIMPORTANT: j = "unimportant"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::ResultKind & x) { - if (j == "fail") x = SARIF::ResultKind::FAIL; - else if (j == "informational") x = SARIF::ResultKind::INFORMATIONAL; - else if (j == "notApplicable") x = SARIF::ResultKind::NOT_APPLICABLE; - else if (j == "open") x = SARIF::ResultKind::OPEN; - else if (j == "pass") x = SARIF::ResultKind::PASS; - else if (j == "review") x = SARIF::ResultKind::REVIEW; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::ResultKind & x) { - switch (x) { - case SARIF::ResultKind::FAIL: j = "fail"; break; - case SARIF::ResultKind::INFORMATIONAL: j = "informational"; break; - case SARIF::ResultKind::NOT_APPLICABLE: j = "notApplicable"; break; - case SARIF::ResultKind::OPEN: j = "open"; break; - case SARIF::ResultKind::PASS: j = "pass"; break; - case SARIF::ResultKind::REVIEW: j = "review"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::SuppressionKind & x) { - if (j == "external") x = SARIF::SuppressionKind::EXTERNAL; - else if (j == "inSource") x = SARIF::SuppressionKind::IN_SOURCE; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::SuppressionKind & x) { - switch (x) { - case SARIF::SuppressionKind::EXTERNAL: j = "external"; break; - case SARIF::SuppressionKind::IN_SOURCE: j = "inSource"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::Status & x) { - if (j == "accepted") x = SARIF::Status::ACCEPTED; - else if (j == "rejected") x = SARIF::Status::REJECTED; - else if (j == "underReview") x = SARIF::Status::UNDER_REVIEW; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::Status & x) { - switch (x) { - case SARIF::Status::ACCEPTED: j = "accepted"; break; - case SARIF::Status::REJECTED: j = "rejected"; break; - case SARIF::Status::UNDER_REVIEW: j = "underReview"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::Version & x) { - if (j == "2.1.0") x = SARIF::Version::THE_210; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::Version & x) { - switch (x) { - case SARIF::Version::THE_210: j = "2.1.0"; break; - default: throw "This should not happen"; - } - } - - inline void from_json(const json & j, SARIF::ColumnKind & x) { - if (j == "unicodeCodePoints") x = SARIF::ColumnKind::UNICODE_CODE_POINTS; - else if (j == "utf16CodeUnits") x = SARIF::ColumnKind::UTF16_CODE_UNITS; - else throw "Input JSON does not conform to schema"; - } - - inline void to_json(json & j, const SARIF::ColumnKind & x) { - switch (x) { - case SARIF::ColumnKind::UNICODE_CODE_POINTS: j = "unicodeCodePoints"; break; - case SARIF::ColumnKind::UTF16_CODE_UNITS: j = "utf16CodeUnits"; break; - default: throw "This should not happen"; - } - } -} From 2b80afd5f89dc8993f6c0cff016ad9931bdabd0d Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 00:07:26 -0500 Subject: [PATCH 21/42] deBoost: remove several boost usage in non-src folder --- scripts/build_boost | 2 - scripts/check_boost_linkage.sh | 85 ---------------------------------- tools/makefile.external | 10 +--- tutorial/buildVFA.C | 3 -- 4 files changed, 2 insertions(+), 98 deletions(-) delete mode 100644 scripts/build_boost delete mode 100755 scripts/check_boost_linkage.sh diff --git a/scripts/build_boost b/scripts/build_boost deleted file mode 100644 index 66862d85cab..00000000000 --- a/scripts/build_boost +++ /dev/null @@ -1,2 +0,0 @@ -bjam --prefix=/home/dquinlan/local/boost_64bit_3.4.6 - --builddir=/home/dquinlan/local/boost_64bit_3.4.6 install -j8 diff --git a/scripts/check_boost_linkage.sh b/scripts/check_boost_linkage.sh deleted file mode 100755 index d088b83f5e3..00000000000 --- a/scripts/check_boost_linkage.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -#------------------------------------------------------------------------------- -# Default global variables -#------------------------------------------------------------------------------- -: ${OS_MACOSX:=false} -: ${LIBRARY:=} - -#------------------------------------------------------------------------------- -# Utilities -#------------------------------------------------------------------------------- -function usage() { - echo "Usage: $0 " -} - -function how_to_fix() { - echo " If this is an issue with only the Boost libraries (and not the Boost include files) and" - echo " you're using dynamic linking, then you should be able to fix this simply by adjusting" - echo " environment variables; otherwise you may need to reconfigure, \"make clean\" and re-make ROSE." -} - -#------------------------------------------------------------------------------- -# Main -#------------------------------------------------------------------------------- - -if test $# -lt 1 -o $# -gt 2; then - usage - exit 1 -else - LIBRARY="$1" - if [ -n "$(type ldd 2>/dev/null)" ]; then - OS_MACOSX=false - else - if [ -n "$(type otool 2>/dev/null)" ]; then - OS_MACOSX=true - else - echo "[ERROR] [${0}] ldd/otool does not exist. Can't determine Boost dependencies in '${LIBRARY}'." - exit 1 - fi - fi -fi - -#------------------------------------------------------------------------------- -# Check linkage of [Boost C++ library] -#------------------------------------------------------------------------------- -if $OS_MACOSX; then - cmd="otool -L \"$LIBRARY\" | grep libboost | sed -n 's/\(.*\)libboost_.*/\1/p' | sort | uniq" -else - cmd="ldd \"$LIBRARY\" | grep libboost | sed 's/.* => \(.*\)\/libboost_.* (.*)/\1/' | sort | uniq" -fi - -boostlibdirs="$(eval $cmd)" - -if test "$boostlibdirs" = ""; then - : no dynamic boost linkage at all -elif test -n "$boostlibdirs"; then - : echo "$0: info: Boost is being linked from '$(echo "$boostlibdirs" | xargs)' in '$LIBRARY'" -else - echo "$0: error: Boost link dependencies not found in '${LIBRARY}'." - echo " It looks like the directory you specified during ROSE's configure step for Boost libraries" - echo " is not being used in the ROSE test executable we just compiled. Perhaps some other Boost" - echo " is being picked up instead?" - how_to_fix - echo - echo " \$ $cmd" - echo - exit 1 -fi - -if test $(echo "$boostlibdirs" | wc -l) -gt 1; then - echo "$0: error: Boost libraries are being linked from multiple directories in '${LIBRARY}'." - echo " This is probably an error; it's not likely that you would have libraries from one version" - echo " of Boost spread into multiple directories. Perhaps one of the installed Boost versions is" - echo " not complete?" - how_to_fix - echo - echo " \$ $cmd" - if $OS_MACOSX; then - otool -L "$LIBRARY" | grep libboost - else - ldd "$LIBRARY" | sed -n --posix '/libboost/p' - fi - echo -fi - diff --git a/tools/makefile.external b/tools/makefile.external index 57a2413f064..9064f0819d3 100644 --- a/tools/makefile.external +++ b/tools/makefile.external @@ -11,9 +11,6 @@ ## * headers, e.g. "rose.h" ROSE_INSTALL=/home/liao6/workspace/raja/rose/install -## ROSE uses the BOOST C++ libraries -BOOST_INSTALL=/nfs/casc/overture/ROSE/opt/rhel7/x86_64/boost/1_55_0/gcc/4.9.3/ - ## Your translator TRANSLATOR=rajaChecker TRANSLATOR_SOURCE=$(TRANSLATOR).C @@ -21,10 +18,8 @@ TRANSLATOR_SOURCE=$(TRANSLATOR).C ## Input testcode for your translator TESTCODE=hello.cpp -#BOOST_LIBS # the Sawyer lib uses a long list of boost libs -BOOST_LIBS=-lboost_date_time -lboost_thread -lboost_filesystem -lboost_program_options -lboost_regex -lboost_system -lboost_serialization -lboost_wave -lboost_iostreams -LINK_FLAGS=-Wl,-rpath=$(ROSE_INSTALL)/lib -L$(ROSE_INSTALL)/lib -lrose -pthread -Wl,-rpath=$(BOOST_INSTALL)/lib -L$(BOOST_INSTALL)/lib $(BOOST_LIBS) -lm +LINK_FLAGS=-Wl,-rpath=$(ROSE_INSTALL)/lib -L$(ROSE_INSTALL)/lib -lrose -pthread -lm #------------------------------------------------------------- # Makefile Targets #------------------------------------------------------------- @@ -33,9 +28,8 @@ all: $(TRANSLATOR) # compile the translator and generate an executable # -g is recommended to be used by default to enable debugging your code -# Note: depending on the version of boost, you may have to use something like -I $(BOOST_ROOT)/include/boost-1_40 instead. $(TRANSLATOR): $(TRANSLATOR_SOURCE) - g++ -g $(TRANSLATOR_SOURCE) -I$(BOOST_INSTALL)/include -I$(ROSE_INSTALL)/include/rose $(LINK_FLAGS) -o $(TRANSLATOR) + g++ -g $(TRANSLATOR_SOURCE) -I$(ROSE_INSTALL)/include/rose $(LINK_FLAGS) -o $(TRANSLATOR) # test the translator check: $(TRANSLATOR) diff --git a/tutorial/buildVFA.C b/tutorial/buildVFA.C index 0ba32cb8265..bde2f4d45d4 100644 --- a/tutorial/buildVFA.C +++ b/tutorial/buildVFA.C @@ -4,11 +4,8 @@ #include #include "VirtualFunctionAnalysis.h" -using namespace boost; - using namespace std; -using namespace boost; // A Function object used as a predicate that determines which functions are // to be represented in the call graph. // Liao 1/23/2013. It turns out there is another FunctionFilter used in src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C From 6e526c5c5706af8723319465647e586f4e1fee2b Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 01:22:16 -0500 Subject: [PATCH 22/42] deBoost: remove boost usage in src/frontend/SageIII, WIP. done with subfolder files, but not the top folder --- src/ROSETTA/Grammar/Support.code | 26 ++-------- src/featureTests.h | 1 - .../astTokenStream/doCompleteMapping.h | 1 - .../SageIII/astTokenStream/linearizeAST.C | 7 ++- src/frontend/SageIII/rose_attributes_list.h | 1 + .../SageIII/sageInterface/CMakeLists.txt | 2 +- .../SageIII/sageInterface/Makefile.am | 1 - .../SageIII/sageInterface/sageBuilder.C | 5 +- .../sageInterface/sageBuilder_fortran.C | 1 - .../SageIII/sageInterface/sageInterface.C | 3 +- .../SageIII/sage_support/keep_going.cpp | 48 +++++++++---------- .../SageIII/sage_support/sage_support.cpp | 6 +-- .../SageIII/sage_support/utility_functions.C | 38 --------------- .../SageIII/sage_support/utility_functions.h | 7 --- src/util/StringUtility/CMakeLists.txt | 2 +- src/util/StringUtility/Convert.C | 2 +- src/util/StringUtility/FileUtility.C | 2 +- .../StringUtility/IntegerOps.h} | 13 +++-- src/util/StringUtility/Makefile.am | 1 + 19 files changed, 45 insertions(+), 122 deletions(-) rename src/{frontend/SageIII/sageInterface/integerOps.h => util/StringUtility/IntegerOps.h} (96%) diff --git a/src/ROSETTA/Grammar/Support.code b/src/ROSETTA/Grammar/Support.code index b81d5430e40..9663080669e 100644 --- a/src/ROSETTA/Grammar/Support.code +++ b/src/ROSETTA/Grammar/Support.code @@ -10,17 +10,13 @@ HEADER_START $CLASSNAME & operator= ( const $CLASSNAME & X ); HEADER_END +#define ROSE_SKIP_COMPILATION_OF_WAVE 1 // **************************************************** // ************ Support for Graph IR nodes ************ // **************************************************** HEADER_GRAPH_PREDECLARATION_START -#if 0 -// Required for Boost Spanning Tree support. -#include -#include -#endif /*! Doxygen documentation for graph class (should maybe be put with the rest of the doxygen documentation in docs/testDoxygen directory instead). @@ -517,23 +513,6 @@ HEADER_GRAPH_START e_last_property /*!< last value (unused, serves as upper bound on values) */ }; - - -#if 0 - - // DQ (4/29/2009): Boost graph Type - //! Boost Graph Type used to represent ROSE graphs within Boost Graph Algorithms. - typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, boost::property < boost::edge_weight_t, int > > BoostGraphType; - - //! Supporting graph types required by Boost Graph Library. - typedef boost::graph_traits < BoostGraphType >::edge_descriptor BoostEdgeDescriptor; - - // DQ (4/29/2009): We might need this in the future, but not now! - // typedef boost::graph_traits < BoostGraphType >::vertex_descriptor BoostVertexDescriptor; - -#endif - - //! Simple edge type used to input data to Boost algorithms typedef std::pair BoostEdgeType; @@ -4634,7 +4613,8 @@ class rose_hash_multimap : public rose_hash::unordered_multimap(), parent(NULL) - : rose_hash::unordered_multimap(boost::unordered_detail::default_bucket_count,hash_Name(),eqstr(case_insensitive_semantics)), parent(NULL) + // : rose_hash::unordered_multimap(boost::unordered_detail::default_bucket_count,hash_Name(),eqstr(case_insensitive_semantics)), parent(NULL) + : rose_hash::unordered_multimap(11,hash_Name(),eqstr(case_insensitive_semantics)), parent(NULL) {} rose_hash_multimap(int sz, bool case_insensitive_semantics = false) diff --git a/src/featureTests.h b/src/featureTests.h index 82c93f1cba8..0a7997c9064 100644 --- a/src/featureTests.h +++ b/src/featureTests.h @@ -15,7 +15,6 @@ // and fast as possible because its purpose is to be able to quickly compile (by skipping over) source code that's not // necessary in a particular ROSE configuration. #include -#include #if defined(_MSC_VER) // Microsoft Visual C++ Compiler erroneously advertises that it's a C++98 compiler. The "fix" for Visual Studio 2017 diff --git a/src/frontend/SageIII/astTokenStream/doCompleteMapping.h b/src/frontend/SageIII/astTokenStream/doCompleteMapping.h index 02c532272a6..8a1c92cdf16 100644 --- a/src/frontend/SageIII/astTokenStream/doCompleteMapping.h +++ b/src/frontend/SageIII/astTokenStream/doCompleteMapping.h @@ -4,7 +4,6 @@ #include #include "linearizeAST.h" #include -#include struct separator { diff --git a/src/frontend/SageIII/astTokenStream/linearizeAST.C b/src/frontend/SageIII/astTokenStream/linearizeAST.C index db156b2dd2c..a04e68f7f3e 100644 --- a/src/frontend/SageIII/astTokenStream/linearizeAST.C +++ b/src/frontend/SageIII/astTokenStream/linearizeAST.C @@ -9,7 +9,6 @@ #include "rose_config.h" #include "linearizeAST.h" -#include class PostSynthesizedAttribute { @@ -41,11 +40,11 @@ class PostAST : public SgBottomUpProcessing { std::string correspondingString =astNode->class_name()+ " "; correspondingString+=(astNode)->unparseToString()+" "; - correspondingString+=boost::lexical_cast((astNode)->get_file_info()->get_filenameString()); + correspondingString+=(astNode)->get_file_info()->get_filenameString(); correspondingString+= " "; - correspondingString+=boost::lexical_cast((astNode)->get_file_info()->get_line()); + correspondingString+=std::to_string((astNode)->get_file_info()->get_line()); correspondingString+= " "; - correspondingString+=boost::lexical_cast((astNode)->get_file_info()->get_col()); + correspondingString+=std::to_string((astNode)->get_file_info()->get_col()); if(isSgConditionalExp(astNode) != NULL) std::cout << "Found conditional exp" << std::endl; diff --git a/src/frontend/SageIII/rose_attributes_list.h b/src/frontend/SageIII/rose_attributes_list.h index 8567fd3043b..99bd034b113 100644 --- a/src/frontend/SageIII/rose_attributes_list.h +++ b/src/frontend/SageIII/rose_attributes_list.h @@ -9,6 +9,7 @@ // Include the ROSE lex specific definitions of tokens #include "general_token_defs.h" +#define ROSE_SKIP_COMPILATION_OF_WAVE 1 // #ifdef CAN_NOT_COMPILE_WITH_ROSE // #warning "CAN_NOT_COMPILE_WITH_ROSE IS defined" diff --git a/src/frontend/SageIII/sageInterface/CMakeLists.txt b/src/frontend/SageIII/sageInterface/CMakeLists.txt index 48ce79c5d2a..5fe4d741f1f 100644 --- a/src/frontend/SageIII/sageInterface/CMakeLists.txt +++ b/src/frontend/SageIII/sageInterface/CMakeLists.txt @@ -11,7 +11,7 @@ add_library(sageInterface OBJECT add_dependencies(sageInterface rosetta_generated) install( - FILES sageInterface.h sageBuilder.h integerOps.h abiStuff.h + FILES sageInterface.h sageBuilder.h abiStuff.h sageFunctors.h sageGeneric.h DESTINATION ${INCLUDE_INSTALL_DIR} ) diff --git a/src/frontend/SageIII/sageInterface/Makefile.am b/src/frontend/SageIII/sageInterface/Makefile.am index 0f805c5cffc..e9ec817faaf 100644 --- a/src/frontend/SageIII/sageInterface/Makefile.am +++ b/src/frontend/SageIII/sageInterface/Makefile.am @@ -21,7 +21,6 @@ pkginclude_HEADERS = \ sageBuilder.h \ sageGeneric.h \ sageFunctors.h \ - integerOps.h \ abiStuff.h EXTRA_DIST = CMakeLists.txt diff --git a/src/frontend/SageIII/sageInterface/sageBuilder.C b/src/frontend/SageIII/sageInterface/sageBuilder.C index 34359b54958..7954ae25cf6 100644 --- a/src/frontend/SageIII/sageInterface/sageBuilder.C +++ b/src/frontend/SageIII/sageInterface/sageBuilder.C @@ -11,13 +11,12 @@ #include "markLhsValues.h" // #include "sageBuilder.h" #include - #include #include "Outliner.hh" #else // #include "sageBuilder.h" #include - #include #endif +#include "Trim.h" // DQ (4/3/2012): Added so that I can enforce some rules as the AST is constructed. #include "AstConsistencyTests.h" @@ -16946,7 +16945,7 @@ PreprocessingInfo* SageBuilder::buildCpreprocessorDefineDeclaration(SgLocatedNod ROSE_ASSERT(target != NULL); //dangling #define xxx is not allowed in the ROSE AST // simple input verification std::string content2 = content; - boost::algorithm::trim(content2); + trim(content2); string prefix = "#define"; string::size_type pos = content2.find(prefix, 0); ROSE_ASSERT (pos == 0); diff --git a/src/frontend/SageIII/sageInterface/sageBuilder_fortran.C b/src/frontend/SageIII/sageInterface/sageBuilder_fortran.C index cdada507090..0b4ccc93471 100644 --- a/src/frontend/SageIII/sageInterface/sageBuilder_fortran.C +++ b/src/frontend/SageIII/sageInterface/sageBuilder_fortran.C @@ -6,7 +6,6 @@ #include "markLhsValues.h" #include "sageBuilder.h" #include -#include #include "Outliner.hh" #endif diff --git a/src/frontend/SageIII/sageInterface/sageInterface.C b/src/frontend/SageIII/sageInterface/sageInterface.C index ed61908f756..7d612076b00 100644 --- a/src/frontend/SageIII/sageInterface/sageInterface.C +++ b/src/frontend/SageIII/sageInterface/sageInterface.C @@ -48,7 +48,6 @@ #include "LoopUnroll.h" #endif -#include #include #include #include // for set operations @@ -10598,7 +10597,7 @@ string SageInterface::generateUniqueVariableName(SgScopeStatement* scope, std::s bool collision = false; do { - name = "__" + baseName + boost::lexical_cast (counter++) + "__"; + name = "__" + baseName + std::to_string (counter++) + "__"; // DQ (8/16/2013): Modified to reflect new API. // Look up the name in the parent scopes diff --git a/src/frontend/SageIII/sage_support/keep_going.cpp b/src/frontend/SageIII/sage_support/keep_going.cpp index cbd7eb6e28d..16c2bfb4cd0 100644 --- a/src/frontend/SageIII/sage_support/keep_going.cpp +++ b/src/frontend/SageIII/sage_support/keep_going.cpp @@ -7,6 +7,7 @@ #include #include +#include #include "keep_going.h" #include "processSupport.h" // ROSE_ASSERT in ROSE/src/util @@ -14,19 +15,17 @@ #include #include #include +#include +#include +#include +#include #include #include #ifdef __linux__ #include #endif -#include -#include -#include -#include -#include using namespace std; -using namespace boost::interprocess; namespace Rose { namespace KeepGoing { @@ -462,10 +461,13 @@ void Rose::KeepGoing::commandLineProcessing if (verbose) { - std::cout - << "[INFO] ROSE Commandline: " - << boost::algorithm::join(rose_cmdline, " ") - << std::endl; + std::ostringstream oss; + for (size_t i = 0; i < rose_cmdline.size(); ++i) { + if (i != 0) oss << " "; + oss << rose_cmdline[i]; + } + + std::cout << "[INFO] ROSE Commandline: " << oss.str() << std::endl; } }// CLI @@ -763,18 +765,14 @@ Rose::KeepGoing::StripPrefix(const std::string& prefix, const std::string& str) std::string Rose::KeepGoing::GetTimestamp(const std::string& format) { - using namespace boost::posix_time; - - //ptime now = second_clock::universal_time(); - // Using local time instead to be user-friendly. - ptime now = second_clock::local_time(); - - static std::locale loc(std::cout.getloc(), - new time_facet(format.c_str())); + // Get the current time + auto now = std::chrono::system_clock::now(); + std::time_t now_c = std::chrono::system_clock::to_time_t(now); + std::tm local_tm = *std::localtime(&now_c); // Use local time for user-friendliness - std::basic_stringstream ss; - ss.imbue(loc); - ss << now; + // Create a stringstream to format the output + std::ostringstream ss; + ss << std::put_time(&local_tm, format.c_str()); return ss.str(); } @@ -828,12 +826,10 @@ Rose::KeepGoing::AppendToFile(const std::string& filename, const std::string& ms // use a separated file for the file lock string lock_file_name = filename+".lock"; touch(filename); - touch(lock_file_name); //this lock file must exist. Or later flock() will fail. - boost::interprocess::file_lock flock (lock_file_name.c_str()); - // introduce a scope to use the scoped lock, which automatically unlock when existing the scope + while (std::filesystem::exists(lock_file_name)); //busy wait until it acquires lock + touch(lock_file_name); //acquire the lock file { - boost::interprocess::scoped_lock e_lock(flock); std::ofstream fout(filename.c_str(), std::ios::app); if(!fout.is_open()) { @@ -857,7 +853,7 @@ Rose::KeepGoing::AppendToFile(const std::string& filename, const std::string& ms fout.close(); } } // end scope for the scoped lock - std::filesystem::remove (lock_file_name); + std::filesystem::remove (lock_file_name); //release the lock by deleting the file } std::map diff --git a/src/frontend/SageIII/sage_support/sage_support.cpp b/src/frontend/SageIII/sage_support/sage_support.cpp index 2a5ccbd6c4c..8115d263f54 100644 --- a/src/frontend/SageIII/sage_support/sage_support.cpp +++ b/src/frontend/SageIII/sage_support/sage_support.cpp @@ -13,6 +13,7 @@ #include "cmdline.h" #include "processSupport.h" #include +#include "Unique.h" #ifdef ROSE_BUILD_FORTRAN_LANGUAGE_SUPPORT # include "FortranModuleInfo.h" @@ -23,8 +24,6 @@ #include #include -#include - // DQ (12/22/2019): I don't need this now, and it is an issue for some compilers (e.g. GNU 4.9.4). // DQ (12/21/2019): Require hash table support for determining the shared nodes in the ASTs. // #include @@ -3607,7 +3606,6 @@ SgSourceFile::build_Fortran_AST( vector argv, vector inputComman #elif BACKEND_FORTRAN_IS_PGI_COMPILER // Pei-Hung 12/09/2019 This is for PGI Fortran compiler, add others if necessary fortran_C_preprocessor_commandLine.push_back("-Mcpp"); - #endif // add source file name @@ -3618,7 +3616,7 @@ SgSourceFile::build_Fortran_AST( vector argv, vector inputComman FileSystem::Path abs_path = FileSystem::makeAbsolute(this->get_unparse_output_filename()); FileSystem::Path abs_dir = abs_path.parent_path(); FileSystem::Path base = abs_dir.filename().stem(); - string preprocessFilename = (abs_dir / std::filesystem::unique_path(base.string() + "-%%%%%%%%.F90")).string(); + string preprocessFilename = (abs_dir / (base.string() + "-" + Rose::Unique::genUniqueID() + ".F90")).string(); // The Sawyer::FileSystem::TemporaryFile d'tor will delete the file. We close the file after it's created because // Rose::FileSystem::copyFile will reopen it in binary mode anyway. diff --git a/src/frontend/SageIII/sage_support/utility_functions.C b/src/frontend/SageIII/sage_support/utility_functions.C index 267dc7ba90e..9815ae6cc84 100644 --- a/src/frontend/SageIII/sage_support/utility_functions.C +++ b/src/frontend/SageIII/sage_support/utility_functions.C @@ -20,9 +20,6 @@ #include -// Headers required only to obtain version numbers -#include - // DQ (10/11/2007): This is commented out to avoid use of this mechanism. // #include @@ -224,14 +221,6 @@ std::string ofpVersionString() return ofp_version; } -// similar to rose_boost_version_id but intended for human consumption (i.e., "1.50.0" rather than 105000). -static std::string -boostVersionString() { - return (StringUtility::numberToString(BOOST_VERSION / 100000) + "." + - StringUtility::numberToString(BOOST_VERSION / 100 % 1000) + "." + - StringUtility::numberToString(BOOST_VERSION % 100)); -} - // DQ (11/1/2009): replaced "version()" with separate "version_number()" and "version_message()" functions. std::string version_message() { std::ostringstream ss; @@ -262,8 +251,6 @@ std::string version_message() { ss <<" --- full optimization: disabled\n"; #endif - ss <<" --- boost library: " < #include -#include // rose +#include // rose #include #include diff --git a/src/util/StringUtility/FileUtility.C b/src/util/StringUtility/FileUtility.C index 9ad36d1a9d1..02592e226cb 100644 --- a/src/util/StringUtility/FileUtility.C +++ b/src/util/StringUtility/FileUtility.C @@ -5,7 +5,7 @@ #include #include -#include +#include #include "rose_msvc.h" // DQ (3/22/2009): Added MSVS support for ROSE. #include "mlog.h" diff --git a/src/frontend/SageIII/sageInterface/integerOps.h b/src/util/StringUtility/IntegerOps.h similarity index 96% rename from src/frontend/SageIII/sageInterface/integerOps.h rename to src/util/StringUtility/IntegerOps.h index b5b2082f748..3b64bdf58f7 100644 --- a/src/frontend/SageIII/sageInterface/integerOps.h +++ b/src/util/StringUtility/IntegerOps.h @@ -3,15 +3,14 @@ #include #include -#include -#include +#include namespace IntegerOpsPrivate { template struct NumBits { - BOOST_STATIC_ASSERT (std::numeric_limits::radix == 2); - BOOST_STATIC_ASSERT (std::numeric_limits::is_integer); + static_assert (std::numeric_limits::radix == 2); + static_assert (std::numeric_limits::is_integer); static const size_t value = std::numeric_limits::digits; }; @@ -300,15 +299,15 @@ inline size_t countClear(T val) /** Optionally returns the zero-origin position of the most significant set bit. Returns nothing if no bits are set. */ template -inline boost::optional msb_set(T val) +inline std::optional msb_set(T val) { if (val!=0) { for (size_t bitno = 8*sizeof(T); bitno>0; --bitno) { if (0 != (val & shl1(bitno-1))) - return boost::optional(bitno-1); + return std::optional(bitno-1); } } - return boost::optional(); + return std::optional(); } } // namespace diff --git a/src/util/StringUtility/Makefile.am b/src/util/StringUtility/Makefile.am index 8bb02f57c83..64d93330881 100644 --- a/src/util/StringUtility/Makefile.am +++ b/src/util/StringUtility/Makefile.am @@ -23,6 +23,7 @@ pkginclude_HEADERS = \ Convert.h \ Escape.h \ FileUtility.h \ + IntegerOps.h \ NumberToString.h \ Predicate.h \ Replace.h \ From bc19089a43021b0457e00fe7f99b69f770e2c768 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 01:24:39 -0500 Subject: [PATCH 23/42] deBoost: remove all usage in src/backend --- src/backend/unparser/unparser.C | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/backend/unparser/unparser.C b/src/backend/unparser/unparser.C index 66bb664816b..ec431662504 100644 --- a/src/backend/unparser/unparser.C +++ b/src/backend/unparser/unparser.C @@ -28,11 +28,6 @@ #include "IncludedFilesUnparser.h" #include "FileHelper.h" -#include - -// DQ (3/19/2014): Used for BOOST_CHECK_EQUAL_COLLECTIONS -// #include - // DQ (9/26/2018): Added so that we can call the display function for TokenStreamSequenceToNodeMapping (for debugging). #include "tokenStreamMapping.h" From 9a5e78bce9124909e5d71530b8d74b7d893fc348 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 14:09:53 -0500 Subject: [PATCH 24/42] deBoost: remove boost usage in src/midend/astDiagnostics and astQuery --- src/midend/astDiagnostics/AstPerformance.C | 4 +-- src/midend/astQuery/nodeQuery.C | 6 ++--- src/midend/astQuery/nodeQuery.h | 2 -- src/midend/astQuery/queryVariant.C | 31 ---------------------- 4 files changed, 4 insertions(+), 39 deletions(-) diff --git a/src/midend/astDiagnostics/AstPerformance.C b/src/midend/astDiagnostics/AstPerformance.C index 97269df8f9d..32dc0318502 100644 --- a/src/midend/astDiagnostics/AstPerformance.C +++ b/src/midend/astDiagnostics/AstPerformance.C @@ -12,15 +12,13 @@ #include #ifndef _MSC_VER #include +#include #else #include // getpagesize() #include "timing.h" // gettimeofday() #endif #endif - -#include // sleep() - #include "AstStatistics.h" // DQ (12/8/2006): Linux memory usage mechanism (no longer used, implemented internally (below)). diff --git a/src/midend/astQuery/nodeQuery.C b/src/midend/astQuery/nodeQuery.C index 063008394d0..51d2d64aa8e 100644 --- a/src/midend/astQuery/nodeQuery.C +++ b/src/midend/astQuery/nodeQuery.C @@ -10,7 +10,7 @@ // string class used if compiler does not contain a C++ string class // include -#include +#include #include "nodeQuery.h" #define DEBUG_NODEQUERY 0 @@ -1001,7 +1001,7 @@ NodeQuerySynthesizedAttributeType NodeQuery::querySubTree ( SgNode * subTree, Va printf ("Inside of NodeQuery::querySubTree #5 \n"); #endif - AstQueryNamespace::querySubTree(subTree, boost::bind(querySolverGrammarElementFromVariantVector, _1, targetVariantVector, &returnList), defineQueryType); + AstQueryNamespace::querySubTree(subTree, std::bind(querySolverGrammarElementFromVariantVector, std::placeholders::_1, targetVariantVector, &returnList), defineQueryType); return returnList; } @@ -1010,7 +1010,7 @@ NodeQuerySynthesizedAttributeType NodeQuery::queryNodeList ( NodeQuerySynthesize { NodeQuerySynthesizedAttributeType returnList; - AstQueryNamespace::queryRange(nodeList.begin(), nodeList.end(), boost::bind(querySolverGrammarElementFromVariantVector, _1, targetVariantVector, &returnList)); + AstQueryNamespace::queryRange(nodeList.begin(), nodeList.end(), std::bind(querySolverGrammarElementFromVariantVector, std::placeholders::_1, targetVariantVector, &returnList)); return returnList; } diff --git a/src/midend/astQuery/nodeQuery.h b/src/midend/astQuery/nodeQuery.h index c867a5c2726..37adf2f3fcb 100644 --- a/src/midend/astQuery/nodeQuery.h +++ b/src/midend/astQuery/nodeQuery.h @@ -186,8 +186,6 @@ namespace NodeQuery // Functions supporting the query of variants void pushNewNode ( NodeQuerySynthesizedAttributeType* nodeList, const VariantVector & targetVariantVector, SgNode * astNode); void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector, NodeQuerySynthesizedAttributeType* returnNodeList ); - NodeQuerySynthesizedAttributeType querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector ); - /******************************************************************************************** * diff --git a/src/midend/astQuery/queryVariant.C b/src/midend/astQuery/queryVariant.C index 27a36beb726..474d5db80d5 100644 --- a/src/midend/astQuery/queryVariant.C +++ b/src/midend/astQuery/queryVariant.C @@ -226,36 +226,5 @@ void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVect return NULL; } /* End function querySolverUnionFields() */ -NodeQuerySynthesizedAttributeType -querySolverGrammarElementFromVariantVector ( - SgNode * astNode, - VariantVector targetVariantVector ) - { - // This function extracts type nodes that would not be traversed so that they can - // accumulated to a list. The specific nodes collected into the list is controlled - // by targetVariantVector. - - ROSE_ASSERT (astNode != NULL); - NodeQuerySynthesizedAttributeType returnNodeList; - - Rose_STL_Container nodesToVisitTraverseOnlyOnce; - - pushNewNode (&returnNodeList,targetVariantVector,astNode); - - vector succContainer = astNode->get_traversalSuccessorContainer(); - vector > allNodesInSubtree = astNode->returnDataMemberPointers(); - - if( succContainer.size() != allNodesInSubtree.size() ) - for(vector >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end(); - ++iItr ) - if( isSgType(iItr->first) != NULL ) - if(std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() ) - pushNewNode (&returnNodeList,targetVariantVector,iItr->first); - - - return returnNodeList; - } /* End function querySolverUnionFields() */ - - }//END NAMESPACE NODEQUERY From 871834ca7bfb9f6c572b6470eba78c62187b1354 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 14:27:19 -0500 Subject: [PATCH 25/42] deBoost: remove boost usage in src/midend/programTransformation --- .../programTransformation/astOutlining/GenerateFunc.cc | 5 +++-- .../programTransformation/astOutlining/PragmaInterface.cc | 4 ++-- .../ExtractFunctionArguments.C | 1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/midend/programTransformation/astOutlining/GenerateFunc.cc b/src/midend/programTransformation/astOutlining/GenerateFunc.cc index 226b88b2f9f..57853a80c01 100644 --- a/src/midend/programTransformation/astOutlining/GenerateFunc.cc +++ b/src/midend/programTransformation/astOutlining/GenerateFunc.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include "Outliner.hh" #include "ASTtools.hh" @@ -1397,8 +1398,8 @@ class SymbolMapOfTwoFiles dict[i1->second]=i2->second; #endif rose_hash_multimap::iterator i1, i2; - boost::unordered_map varSymDict; - boost::unordered_map funcSymDict; + std::unordered_map varSymDict; + std::unordered_map funcSymDict; // cache mapping of new symbols,indexed by qualified name : qualified name to symbol for (i2=set2->begin(); i2!=set2->end(); i2++) diff --git a/src/midend/programTransformation/astOutlining/PragmaInterface.cc b/src/midend/programTransformation/astOutlining/PragmaInterface.cc index af02e2f3021..6dcec90eb2c 100644 --- a/src/midend/programTransformation/astOutlining/PragmaInterface.cc +++ b/src/midend/programTransformation/astOutlining/PragmaInterface.cc @@ -19,7 +19,7 @@ #include "Outliner.hh" #include "ASTtools.hh" #include "PreprocessingInfo.hh" -#include +#include "Trim.h" //! Simplest outlining directives, applied to a single statement. static const std::string PRAGMA_OUTLINE ("rose_outline"); @@ -89,7 +89,7 @@ processFortranComment(SgLocatedNode* node) if ((*i)->getTypeOfDirective() == PreprocessingInfo::FortranStyleComment) { string commentString = (*i)->getString(); - boost::algorithm::trim(commentString); + trim(commentString); if ( (commentString == "!$"+PRAGMA_OUTLINE) || (commentString == "c$"+PRAGMA_OUTLINE) || (commentString == "*$"+PRAGMA_OUTLINE)) diff --git a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C index 9832c9e0cc3..aa0bcea39dd 100644 --- a/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C +++ b/src/midend/programTransformation/extractFunctionArgumentsNormalization/ExtractFunctionArguments.C @@ -3,7 +3,6 @@ #include "SingleStatementToBlockNormalization.h" using namespace std; -using namespace boost; /** Performs the function argument extraction on all function calls in the given subtree of the AST. */ /** It does not do transofrmations in places where it is not safe. If you pass doUnsafeNormalization= true, we will normalize all callsites ignoring the safety (Suggested by Markus Schordan) */ From a880ef197a6c44389396b66a95fb8643e9ffa578 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Wed, 13 Nov 2024 17:38:42 -0500 Subject: [PATCH 26/42] deBoost: remove boost usage in midend/programAnalysis --- src/backend/unparser/unparser.C | 30 ------------------ .../astTokenStream/doCompleteMapping.C | 3 -- .../CompilerOutputParser.C | 2 ++ src/frontend/SageIII/memory-pool-snapshot.C | 1 + src/frontend/SageIII/sage3basic.h | 2 ++ .../SageIII/sageInterface/sageBuilder.C | 3 +- .../SageIII/sageInterface/sageInterface.C | 1 + .../SageIII/sage_support/keep_going.cpp | 3 +- src/midend/abstractLayer/SgNodeHelper.C | 3 +- src/midend/astDump/AstPDFGeneration.C | 4 +-- .../astProcessing/AstAttributeMechanism.C | 1 + .../astUtil/astInterface/CPPAstInterface.C | 1 + .../CallGraphAnalysis/CMakeLists.txt | 2 +- .../CallGraphAnalysis/CallGraph.h | 6 ++-- .../CallGraphAnalysis/ClassHierarchyGraph.h | 8 ++--- .../CallGraphAnalysis/Makefile.am | 2 +- .../CallGraphAnalysis/Makefile_variables | 3 +- .../CallGraphAnalysis/newCallGraph.C | 3 +- src/midend/programAnalysis/OAWrap/OAWrap.h | 1 + .../IntraProcAliasAnalysis.C | 14 ++++----- .../IntraProcAliasAnalysis.h | 31 +++++++++---------- .../PtrAliasAnalysis.C | 16 +++++----- .../PtrAliasAnalysis.h | 10 +++--- .../VirtualFunctionAnalysis.C | 4 +-- .../defUseAnalysis/DefUseAnalysis.cpp | 13 +++++--- .../defUseAnalysis/DefUseAnalysis.h | 5 --- .../defUseAnalysis/LivenessAnalysis.cpp | 2 -- .../genericDataflow/analysis/dataflow.C | 7 ++--- .../genericDataflow/analysis/dataflow.h | 8 ++--- .../rwAccessLabeler/rwAccessLabeler.C | 1 + .../simpleAnalyses/divAnalysis.C | 13 ++++---- .../simpleAnalyses/divAnalysis.h | 7 +++-- .../simpleAnalyses/liveDeadVarAnalysis.h | 7 +++-- .../programAnalysis/pointerAnal/PtrAnal.h | 6 ++-- .../variableRenaming/VariableRenaming.C | 5 +-- .../variableRenaming/VariableRenaming.h | 22 ++++++++++--- .../astOutlining/PragmaInterface.cc | 3 +- .../constantFolding/constantFolding.h | 2 ++ src/rose-config.C | 8 ++--- src/util/StringUtility/Trim.h | 16 ---------- 40 files changed, 121 insertions(+), 158 deletions(-) delete mode 100644 src/util/StringUtility/Trim.h diff --git a/src/backend/unparser/unparser.C b/src/backend/unparser/unparser.C index ec431662504..f6ceb3bf61f 100644 --- a/src/backend/unparser/unparser.C +++ b/src/backend/unparser/unparser.C @@ -2987,36 +2987,6 @@ unparseFile ( SgFile* file, UnparseFormatHelp *unparseHelp, UnparseDelegate* unp outputFilename = StringUtility::stripFileSuffixFromFileName (outputFilename); outputFilename += ".cu"; } - else if (file->get_X10_only()) - { - // X10 is Java source code; see Java file/class naming conventions. - // Filenames are based on the Java Class name contained in the file. - SgSourceFile *sourcefile = isSgSourceFile(file); - ROSE_ASSERT(sourcefile && "Try to unparse an SgFile not being an SgSourceFile using the x10 unparser"); - - SgProject *project = sourcefile -> get_project(); - ASSERT_not_null(project); - - SgJavaPackageStatement *package_statement = sourcefile -> get_package(); - string package_name = (package_statement ? package_statement -> get_name().getString() : ""); - //NOTE: Default package equals the empty string "" - //ROSE_ASSERT((packageDecl != NULL) && "Couldn't find the package definition of the java source file"); - string outFolder = ""; - string ds = project -> get_Java_source_destdir(); - if (ds != "") { - outFolder = ds; - outFolder += "/"; - } - outFolder += "rose-output/"; - boost::replace_all(package_name, ".", "/"); - outFolder += package_name; - outFolder += (package_name.size() > 0 ? "/" : ""); - // Create package folder structure - string mkdirCommand = string("mkdir -p ") + outFolder; - int status = system (mkdirCommand.c_str()); - ROSE_ASSERT(status == 0); - outputFilename = outFolder + file -> get_sourceFileNameWithoutPath(); - } else { //ROSE_ASSERT (! "Not implemented, or unknown file type"); diff --git a/src/frontend/SageIII/astTokenStream/doCompleteMapping.C b/src/frontend/SageIII/astTokenStream/doCompleteMapping.C index c4a3098266e..329bffb95fc 100644 --- a/src/frontend/SageIII/astTokenStream/doCompleteMapping.C +++ b/src/frontend/SageIII/astTokenStream/doCompleteMapping.C @@ -3,10 +3,7 @@ #include "sage3basic.h" #include "doCompleteMapping.h" - - using namespace std; -using namespace boost; separator::separator(int bp, int ep){ begin_pos = bp; diff --git a/src/frontend/SageIII/includeDirectivesProcessing/CompilerOutputParser.C b/src/frontend/SageIII/includeDirectivesProcessing/CompilerOutputParser.C index f0050fea3c7..6d3389c8fdf 100644 --- a/src/frontend/SageIII/includeDirectivesProcessing/CompilerOutputParser.C +++ b/src/frontend/SageIII/includeDirectivesProcessing/CompilerOutputParser.C @@ -1,6 +1,8 @@ // DQ (10/5/2014): This is more strict now that we include rose_config.h in the sage3basic.h. // #include #include "sage3basic.h" +#include // For fork and execv +#include // For pid_t #include diff --git a/src/frontend/SageIII/memory-pool-snapshot.C b/src/frontend/SageIII/memory-pool-snapshot.C index fe41044a7cb..16466ac51b5 100644 --- a/src/frontend/SageIII/memory-pool-snapshot.C +++ b/src/frontend/SageIII/memory-pool-snapshot.C @@ -1,6 +1,7 @@ #include "sage3basic.h" #include "memory-pool-snapshot.h" +#include namespace Rose { diff --git a/src/frontend/SageIII/sage3basic.h b/src/frontend/SageIII/sage3basic.h index d26fd3ec4b8..9e87b3ec079 100644 --- a/src/frontend/SageIII/sage3basic.h +++ b/src/frontend/SageIII/sage3basic.h @@ -127,6 +127,8 @@ //#include // For abort() #include #include +#include +#include // DQ (8/25/2014): Added logic to isTemplateDeclaration(a_routine_ptr) to force isTemplateDeclaration // in ROSE/EDG connection to be false where the topScopeStack() is a template class instantaition scope. diff --git a/src/frontend/SageIII/sageInterface/sageBuilder.C b/src/frontend/SageIII/sageInterface/sageBuilder.C index 7954ae25cf6..6acbe05d16a 100644 --- a/src/frontend/SageIII/sageInterface/sageBuilder.C +++ b/src/frontend/SageIII/sageInterface/sageBuilder.C @@ -16,7 +16,6 @@ // #include "sageBuilder.h" #include #endif -#include "Trim.h" // DQ (4/3/2012): Added so that I can enforce some rules as the AST is constructed. #include "AstConsistencyTests.h" @@ -16945,7 +16944,7 @@ PreprocessingInfo* SageBuilder::buildCpreprocessorDefineDeclaration(SgLocatedNod ROSE_ASSERT(target != NULL); //dangling #define xxx is not allowed in the ROSE AST // simple input verification std::string content2 = content; - trim(content2); + Rose::StringUtility::trim(content2); string prefix = "#define"; string::size_type pos = content2.find(prefix, 0); ROSE_ASSERT (pos == 0); diff --git a/src/frontend/SageIII/sageInterface/sageInterface.C b/src/frontend/SageIII/sageInterface/sageInterface.C index 7d612076b00..cb6c1c0bcf3 100644 --- a/src/frontend/SageIII/sageInterface/sageInterface.C +++ b/src/frontend/SageIII/sageInterface/sageInterface.C @@ -53,6 +53,7 @@ #include // for set operations #include // for std::accumulate #include +#include // DQ (11/5/2019): Added to support SageInterface::statementCanBeTransformed(). namespace EDG_ROSE_Translation diff --git a/src/frontend/SageIII/sage_support/keep_going.cpp b/src/frontend/SageIII/sage_support/keep_going.cpp index 16c2bfb4cd0..e0c02b157db 100644 --- a/src/frontend/SageIII/sage_support/keep_going.cpp +++ b/src/frontend/SageIII/sage_support/keep_going.cpp @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include // For signal constants like SIGSEGV, SIGINT, etc. #include #ifdef __linux__ #include diff --git a/src/midend/abstractLayer/SgNodeHelper.C b/src/midend/abstractLayer/SgNodeHelper.C index 10e57a52061..12b5e920db1 100644 --- a/src/midend/abstractLayer/SgNodeHelper.C +++ b/src/midend/abstractLayer/SgNodeHelper.C @@ -4,7 +4,8 @@ #include #include #include "SgNodeHelper.h" -#include "limits.h" +#include +#include #include "RoseAst.h" using namespace std; diff --git a/src/midend/astDump/AstPDFGeneration.C b/src/midend/astDump/AstPDFGeneration.C index 4aa46c09bef..4e72903e3c2 100644 --- a/src/midend/astDump/AstPDFGeneration.C +++ b/src/midend/astDump/AstPDFGeneration.C @@ -12,8 +12,8 @@ #include #include -// #include -// #include +#include +#include #include "PDFGeneration.h" #include "AstPDFGeneration.h" diff --git a/src/midend/astProcessing/AstAttributeMechanism.C b/src/midend/astProcessing/AstAttributeMechanism.C index 785c8c60ce6..efe32fcc848 100644 --- a/src/midend/astProcessing/AstAttributeMechanism.C +++ b/src/midend/astProcessing/AstAttributeMechanism.C @@ -4,6 +4,7 @@ #include "roseInternal.h" #include #include +#include using namespace Rose; diff --git a/src/midend/astUtil/astInterface/CPPAstInterface.C b/src/midend/astUtil/astInterface/CPPAstInterface.C index 92caccc0e0c..41efd2463f4 100644 --- a/src/midend/astUtil/astInterface/CPPAstInterface.C +++ b/src/midend/astUtil/astInterface/CPPAstInterface.C @@ -8,6 +8,7 @@ #include "CPPAstInterface.h" #include "AstInterface_ROSE.h" +#include using namespace std; //! Check if a node is a data member access function for an object, // such as dot (object.a) or arrow (objectptr->a)expression diff --git a/src/midend/programAnalysis/CallGraphAnalysis/CMakeLists.txt b/src/midend/programAnalysis/CallGraphAnalysis/CMakeLists.txt index 5f180c51193..173c8317c3a 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/CMakeLists.txt +++ b/src/midend/programAnalysis/CallGraphAnalysis/CMakeLists.txt @@ -17,7 +17,7 @@ install(FILES CallGraph.h ClassHierarchyGraph.h DESTINATION ${INCLUDE_INSTALL_D # # # -#INCLUDES = $(ROSE_INCLUDES) $(BOOST_CPPFLAGS) +#INCLUDES = $(ROSE_INCLUDES) #libCallGraphSources = CallGraph.C ClassHierarchyGraph.C # #noinst_LTLIBRARIES = libCallGraph.la diff --git a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h index 28684ea4e01..2f480e8bfbf 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h +++ b/src/midend/programAnalysis/CallGraphAnalysis/CallGraph.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include class FunctionData; @@ -153,7 +153,7 @@ class ROSE_DLL_API CallGraphBuilder //void classifyCallGraph(); //We map each function to the corresponding graph node - boost::unordered_map& getGraphNodesMapping(){ return graphNodes; } + std::unordered_map& getGraphNodesMapping(){ return graphNodes; } //! Retrieve the node matching a function declaration using firstNondefiningDeclaration (does not work across translation units) SgGraphNode * hasGraphNodeFor(SgFunctionDeclaration * fdecl) const; @@ -164,7 +164,7 @@ class ROSE_DLL_API CallGraphBuilder SgProject *project; SgIncidenceDirectedGraph *graph; //We map each function to the corresponding graph node - typedef boost::unordered_map GraphNodes; + typedef std::unordered_map GraphNodes; GraphNodes graphNodes; }; diff --git a/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.h b/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.h index 6c6be563ded..963a5467777 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.h +++ b/src/midend/programAnalysis/CallGraphAnalysis/ClassHierarchyGraph.h @@ -3,18 +3,18 @@ #include #include -#include +#include +#include class ROSE_DLL_API ClassHierarchyWrapper { public: - typedef boost::unordered_set ClassDefSet; + typedef std::unordered_set ClassDefSet; - typedef boost::unordered_map MangledNameToClassDefsMap; + typedef std::unordered_map MangledNameToClassDefsMap; private: - /** Map from each class to all its immediate superclasses. */ MangledNameToClassDefsMap directParents; diff --git a/src/midend/programAnalysis/CallGraphAnalysis/Makefile.am b/src/midend/programAnalysis/CallGraphAnalysis/Makefile.am index 3f87164978a..5731f0524f0 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/Makefile.am +++ b/src/midend/programAnalysis/CallGraphAnalysis/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs -AM_CPPFLAGS = $(ROSE_INCLUDES) $(BOOST_CPPFLAGS) +AM_CPPFLAGS = $(ROSE_INCLUDES) libCallGraphSources = newCallGraph.C CallGraph.C ClassHierarchyGraph.C noinst_LTLIBRARIES = libCallGraph.la diff --git a/src/midend/programAnalysis/CallGraphAnalysis/Makefile_variables b/src/midend/programAnalysis/CallGraphAnalysis/Makefile_variables index 22b93421780..f3153ae53c9 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/Makefile_variables +++ b/src/midend/programAnalysis/CallGraphAnalysis/Makefile_variables @@ -1,7 +1,6 @@ # Non-recursive Makefile -mpaCallGraphAnalysis_includes=\ - $(BOOST_CPPFLAGS) +mpaCallGraphAnalysis_includes= mpaCallGraphAnalysis_la_sources=\ diff --git a/src/midend/programAnalysis/CallGraphAnalysis/newCallGraph.C b/src/midend/programAnalysis/CallGraphAnalysis/newCallGraph.C index 827a66a8c7e..094af1c95d5 100644 --- a/src/midend/programAnalysis/CallGraphAnalysis/newCallGraph.C +++ b/src/midend/programAnalysis/CallGraphAnalysis/newCallGraph.C @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifndef _MSC_VER #include @@ -25,8 +26,6 @@ #endif #endif -#include // sleep() - #define DEBUG_CALLGRAPH 0 using namespace std; diff --git a/src/midend/programAnalysis/OAWrap/OAWrap.h b/src/midend/programAnalysis/OAWrap/OAWrap.h index f446a91dfb3..c0fc9ee53c1 100644 --- a/src/midend/programAnalysis/OAWrap/OAWrap.h +++ b/src/midend/programAnalysis/OAWrap/OAWrap.h @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace OpenAnalysis { diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C index db645b21a82..279bda4e788 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.C @@ -1,6 +1,6 @@ #include "sage3basic.h" #include "IntraProcAliasAnalysis.h" - +#include void CompactRepresentation::computeAliases (SgGraphNode *node, int derefLevel, vector & sol) { @@ -333,7 +333,7 @@ void IntraProcAliasAnalysis::buildCFG() { // run a bfs and list the nodes cfgNodes.clear(); std::queue workQ; - //boost::unordered_map visited; + //std::unordered_map visited; vectorvisited; workQ.push(cfg->getEntry()); visited.push_back(cfg->getEntry()); @@ -364,8 +364,8 @@ void IntraProcAliasAnalysis::buildCFG() { IntraProcAliasAnalysis::IntraProcAliasAnalysis(SgNode *head, ClassHierarchyWrapper *_classHierarchy, CallGraphBuilder *_cgBuilder, - boost::unordered_map &_mapping, - boost::unordered_map > &_resolver) : + std::unordered_map &_mapping, + std::unordered_map > &_resolver) : IntraProcDataFlowAnalysis(head), classHierarchy(_classHierarchy), cfg(0), cgBuilder(_cgBuilder), mapping(_mapping), resolver(_resolver) { ROSE_ASSERT(isSgFunctionDeclaration(head)); @@ -952,7 +952,7 @@ void ProcessExpression::processRHS(SgNode *node, struct AliasRelationNode &arNod SgVarRefExp *var_exp; int derefLevel = 0; static int new_index; - static boost::unordered_map new_variables; + static std::unordered_map new_variables; switch (node->variantT()) { @@ -1162,7 +1162,7 @@ void CollectAliasRelations::processNode(SgGraphNode* g_node){ } -void CollectAliasRelations::recursiveCollect(SgGraphNode *node, boost::unordered_map &colors){ +void CollectAliasRelations::recursiveCollect(SgGraphNode *node, std::unordered_map &colors){ if(node == NULL) return; @@ -1193,7 +1193,7 @@ void CollectAliasRelations::run() { set allNodes = graph->computeNodeSet(); - boost::unordered_map colors; + std::unordered_map colors; for(SgGraphNode *node: allNodes) { colors[node] = WHITE; diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h index 5c340b17700..06532ba26e7 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/IntraProcAliasAnalysis.h @@ -4,11 +4,10 @@ #include "customFilteredCFG.h" #include "ClassHierarchyGraph.h" #include "CallGraph.h" -#include -#include +#include +#include #include -using namespace boost; using namespace std; //! A struct to hold the information about an alias node @@ -110,7 +109,7 @@ class CompReprBase{ class CompactRepresentation : public CompReprBase{ //! A Map to hold the SgNode to SgGraphNode mapping - boost::unordered_map all_nodes; + std::unordered_map all_nodes; //! Get Graph Node from SgNode SgGraphNode * getGraphNode(SgNode *node); @@ -142,7 +141,7 @@ class CompactRepresentation : public CompReprBase{ public: //! Get the Mapping from SgNode to SgGraphNode - boost::unordered_map getNodesMapping(){ return all_nodes;} + std::unordered_map getNodesMapping(){ return all_nodes;} CompactRepresentation() { init(); } //! Get the Graph @@ -185,13 +184,13 @@ class CompactRepresentation : public CompReprBase{ //! A Shared Pointer Wrapper for CompactRepresentation class CompReprPtr { //! The shared pointer holding th CompactRepresentation - boost::shared_ptr ptr; + std::shared_ptr ptr; public: //! Constructor - CompReprPtr() { ptr = boost::shared_ptr(); } + CompReprPtr() { ptr = std::shared_ptr(); } //! Constructor - CompReprPtr(CompactRepresentation *repr) { ptr = boost::shared_ptr(repr); } + CompReprPtr(CompactRepresentation *repr) { ptr = std::shared_ptr(repr); } //! get the actual pointer to compact representation CompReprBase * get() const{ return ptr.get(); } @@ -209,16 +208,16 @@ class CompReprPtr { //! Helper class to hold Alias Information class AliasInfoGenerator { //! IN of every CFG Node - boost::unordered_map ins; + std::unordered_map ins; //! OUT of every CFG Node - boost::unordered_map outs; + std::unordered_map outs; //! All the Return Stmts std::vector returnStmts; //! All the AliasRelations for every CFG Node - boost::unordered_map > >aliasRelations; + std::unordered_map > >aliasRelations; public : AliasInfoGenerator(); @@ -278,7 +277,7 @@ class CollectAliasRelations { void run(); private: //! recursively Collect Alias Information from the CFG Nodes - void recursiveCollect(SgGraphNode *, boost::unordered_map &); + void recursiveCollect(SgGraphNode *, std::unordered_map &); }; //! IntraProcedurial DataFlow Analysis to compute exit and entry from all the function which @@ -316,10 +315,10 @@ class IntraProcAliasAnalysis : virtual void buildCFG() ; //! A mapping to hold SgFunctionDeclaration to IntraProcAliasAnalysis - boost::unordered_map &mapping; + std::unordered_map &mapping; //! A mapping to hold function resolve data - boost::unordered_map > &resolver; + std::unordered_map > &resolver; //! Retrieve Alias Relations from Function Parameters. Map data between actual and formal parameters. //! Handles return values as well. @@ -343,8 +342,8 @@ class IntraProcAliasAnalysis : public: //ReachingDefinitionAnalysis(SgNode *head) : DataFlowAnalysis(head), g(0) { IntraProcAliasAnalysis(SgNode *head, ClassHierarchyWrapper *_classHierarchy, CallGraphBuilder *_cgB, - boost::unordered_map &mapping, - boost::unordered_map > &resolver); + std::unordered_map &mapping, + std::unordered_map > &resolver); //! Get the Entry CompactRepresentation Graph for the function CompReprPtr getFunctionEntry() {return entry;} diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C index 80727f8bbb7..9b0316d3116 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.C @@ -63,7 +63,7 @@ struct OnlyNonCompilerGenerated : public std::unary_functiongetGraph(), "init_call_graph.dot"); #if 0 - typedef boost::unordered_map res_map; + typedef std::unordered_map res_map; for (res_map::value_type it: cg2.getGraphNodesMapping()) { std::cout << it.first <<" - "<< isSgFunctionDeclaration(it.first->get_definingDeclaration()) << " - " << it.first->get_name().getString() << std::endl; } @@ -71,7 +71,7 @@ struct OnlyNonCompilerGenerated : public std::unary_function map; + typedef std::unordered_map map; for (map::value_type it: intraAliases) { delete ((IntraProcAliasAnalysis *)it.second); } @@ -105,7 +105,7 @@ struct OnlyNonCompilerGenerated : public std::unary_function &graphNodeToFunction, boost::unordered_map &colors, + std::unordered_map &graphNodeToFunction, std::unordered_map &colors, vector &processingOrder, TRAVERSAL_TYPE order) { //If the function is already in the list of functions to be processed, don't add it again. @@ -116,7 +116,7 @@ void PtrAliasAnalysis:: SortCallGraphRecursive(SgFunctionDeclaration* targetFunc { printf("The function %s has no vertex in the call graph!\n", targetFunction->get_name().str()); printf("graphNodeToFunction contains:\n"); - boost::unordered_map::const_iterator iter; + std::unordered_map::const_iterator iter; for (iter= graphNodeToFunction.begin(); iter != graphNodeToFunction.end(); iter ++) { SgFunctionDeclaration* func = (*iter).first; @@ -170,11 +170,11 @@ void PtrAliasAnalysis:: SortCallGraphRecursive(SgFunctionDeclaration* targetFunc * @param order: 0-topological, 1- reverse */ void PtrAliasAnalysis::SortCallGraphNodes(SgFunctionDeclaration* targetFunction, SgIncidenceDirectedGraph* callGraph, - boost::unordered_map &graphNodeToFunction, + std::unordered_map &graphNodeToFunction, vector &processingOrder, TRAVERSAL_TYPE order) { - boost::unordered_map colors; - typedef boost::unordered_map my_map; + std::unordered_map colors; + typedef std::unordered_map my_map; for(my_map::value_type item: graphNodeToFunction) { colors[item.second] = WHITE; @@ -188,7 +188,7 @@ void PtrAliasAnalysis::SortCallGraphNodes(SgFunctionDeclaration* targetFunction, void PtrAliasAnalysis::computeCallGraphNodes(SgFunctionDeclaration* targetFunction, SgIncidenceDirectedGraph* callGraph, vector &processingOrder, TRAVERSAL_TYPE order) { - boost::unordered_map graphNodeToFunction ; + std::unordered_map graphNodeToFunction ; SortCallGraphNodes(targetFunction, callGraph, cgBuilder->getGraphNodesMapping(), processingOrder, order); diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.h b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.h index 9e1a08d1db2..ac9ed333782 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.h +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/PtrAliasAnalysis.h @@ -4,9 +4,7 @@ #include "InterProcDataFlowAnalysis.h" #include "IntraProcAliasAnalysis.h" - using namespace std; -using namespace boost; //! PtrAliasAnalysis computes Alias Information, which is used for //! Virtual Function Resolving. @@ -17,10 +15,10 @@ class ROSE_DLL_API PtrAliasAnalysis : public InterProcDataFlowAnalysis{ SgIncidenceDirectedGraph *callGraph; //! A map from SgFunctionDeclaration to IntraProcAliasAnalysis - boost::unordered_map intraAliases; + std::unordered_map intraAliases; //! A map which stores the function call resolve information - boost::unordered_map > resolver; + std::unordered_map > resolver; //! ClassHierarchy of the project ClassHierarchyWrapper *classHierarchy; @@ -42,12 +40,12 @@ class ROSE_DLL_API PtrAliasAnalysis : public InterProcDataFlowAnalysis{ private: void SortCallGraphRecursive(SgFunctionDeclaration* targetFunction, SgIncidenceDirectedGraph* callGraph, - boost::unordered_map &graphNodeToFunction, boost::unordered_map &graphNodeToFunction, std::unordered_map &colors, std::vector &processingOrder, PtrAliasAnalysis::TRAVERSAL_TYPE order) ; void SortCallGraphNodes(SgFunctionDeclaration* targetFunction, SgIncidenceDirectedGraph* callGraph, - boost::unordered_map &graphNodeToFunction, + std::unordered_map &graphNodeToFunction, std::vector &processingOrder, PtrAliasAnalysis::TRAVERSAL_TYPE order); void computeCallGraphNodes(SgFunctionDeclaration* targetFunction, SgIncidenceDirectedGraph* callGraph, diff --git a/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C b/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C index 2c9b845a4c5..8eaced7bf78 100644 --- a/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C +++ b/src/midend/programAnalysis/VirtualFunctionAnalysis/VirtualFunctionAnalysis.C @@ -91,9 +91,9 @@ void VirtualFunctionAnalysis::pruneCallGraph(CallGraphBuilder& builder) { SgIncidenceDirectedGraph *graph = builder.getGraph(); ROSE_ASSERT(graph != NULL); - boost::unordered_mapnode_mapping = builder.getGraphNodesMapping(); + std::unordered_mapnode_mapping = builder.getGraphNodesMapping(); - typedef boost::unordered_map map; + typedef std::unordered_map map; for (map::value_type it: node_mapping) { SgFunctionDeclaration *defDecl = ( diff --git a/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.cpp b/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.cpp index eba5260dd92..5358ee4edb4 100644 --- a/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.cpp +++ b/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.cpp @@ -9,9 +9,7 @@ #include "DefUseAnalysis.h" #include "DefUseAnalysis_perFunction.h" #include "GlobalVarAnalysis.h" -#include -#include - +#include using namespace std; // static counter for the node numbering (for visualization) @@ -123,7 +121,10 @@ void DefUseAnalysis::replaceElement(SgNode* sgNode, // table[sgNode].insert(make_pair(initName,sgNode)); multitype& map = table[sgNode]; - map.erase(std::remove_if(map.begin(), map.end(), boost::bind(boost::type(), DefUseAnalysismycond, _1, initName)), map.end()); + //map.erase(std::remove_if(map.begin(), map.end(), std::bind(boost::type(), DefUseAnalysismycond, std::placeholders::_1, initName)), map.end()); + map.erase(std::remove_if(map.begin(), map.end(), [initName](const auto& pair) { + return DefUseAnalysismycond(pair, initName); + }), map.end()); // table[sgNode].erase(it); table[sgNode].push_back(make_pair(initName,sgNode)); @@ -142,7 +143,9 @@ void DefUseAnalysis::clearUseOfElement(SgNode* sgNode, // usetable[sgNode].erase(initName); multitype& map = usetable[sgNode]; - map.erase(std::remove_if(map.begin(), map.end(), boost::bind(boost::type(), DefUseAnalysismycond, _1, initName)), map.end()); + map.erase(std::remove_if(map.begin(), map.end(), [initName](const auto& pair) { + return DefUseAnalysismycond(pair, initName); + }), map.end()); } } diff --git a/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.h b/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.h index 6539d20bded..47202030cce 100644 --- a/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.h +++ b/src/midend/programAnalysis/defUseAnalysis/DefUseAnalysis.h @@ -15,10 +15,6 @@ #include -// CH (4/9/2010): Use boost::unordered instead -#include -#include - #if 0 #ifdef _MSC_VER #include @@ -73,7 +69,6 @@ class ROSE_DLL_API DefUseAnalysis : public DFAnalysis, Support { typedef std::map< SgNode* , multitype > tabletype; // typedef std::map< SgNode* , int > convtype; -// CH (4/9/2010): Use boost::unordered instead //#ifdef _MSC_VER #if 0 typedef hash_map< SgNode* , int > convtype; diff --git a/src/midend/programAnalysis/defUseAnalysis/LivenessAnalysis.cpp b/src/midend/programAnalysis/defUseAnalysis/LivenessAnalysis.cpp index d6564a68301..ef139d2637d 100644 --- a/src/midend/programAnalysis/defUseAnalysis/LivenessAnalysis.cpp +++ b/src/midend/programAnalysis/defUseAnalysis/LivenessAnalysis.cpp @@ -21,8 +21,6 @@ #include "LivenessAnalysis.h" #include "DefUseAnalysis_perFunction.h" #include "GlobalVarAnalysis.h" -#include -#include #include "BottomUpTraversalLiveness.h" using namespace std; diff --git a/src/midend/programAnalysis/genericDataflow/analysis/dataflow.C b/src/midend/programAnalysis/genericDataflow/analysis/dataflow.C index fda69a433fc..8f9982b9616 100644 --- a/src/midend/programAnalysis/genericDataflow/analysis/dataflow.C +++ b/src/midend/programAnalysis/genericDataflow/analysis/dataflow.C @@ -12,9 +12,6 @@ using std::auto_ptr; using std::pair; using std::make_pair; -#include -using boost::mem_fn; - NodeState* IntraBWDataflow::initializeFunctionNodeState(const Function &func, NodeState *fState) { // DQ (12/10/2016): Eliminating a warning that we want to be an error: -Werror=unused-but-set-variable. @@ -161,7 +158,7 @@ vector IntraUniDirectionalDataflow::gatherDescendants(vector::const_iterator ei = edges.begin(); ei!=edges.end(); ei++) { - descendants.push_back(mem_fn(edgeFn)(*ei)); + descendants.push_back(std::mem_fn(edgeFn)(*ei)); } return descendants; @@ -308,7 +305,7 @@ bool IntraUniDirectionalDataflow::runAnalysis(const Function& func, NodeState* f if (isSgFunctionCallExp(sgn)) transferFunctionCall(func, n, state); - boost::shared_ptr transferVisitor = getTransferVisitor(func, n, *state, dfInfoPost); + std::shared_ptr transferVisitor = getTransferVisitor(func, n, *state, dfInfoPost); sgn->accept(*transferVisitor); modified = transferVisitor->finish() || modified; diff --git a/src/midend/programAnalysis/genericDataflow/analysis/dataflow.h b/src/midend/programAnalysis/genericDataflow/analysis/dataflow.h index 2fc520f0411..39c835120be 100644 --- a/src/midend/programAnalysis/genericDataflow/analysis/dataflow.h +++ b/src/midend/programAnalysis/genericDataflow/analysis/dataflow.h @@ -10,7 +10,7 @@ #include "analysis.h" #include "lattice.h" -#include +#include #include #include #include @@ -135,7 +135,7 @@ class IntraUnitDataflow : virtual public IntraProceduralDataflow // \todo \pp IMO. the function getTransferVisitor is not necessary and can be removed. // Users wanting to write the analysis based on visitors can do so // in the transfer function. (This safes one memory allocation, deallocation, - // and boost::shared_pointer management overhead per transfer). + // and std::shared_pointer management overhead per transfer). // A transfer function using the visitor would look like (if desired this can be // simplified by providing a convenience function taking a visitor as argument): // \code @@ -146,9 +146,9 @@ class IntraUnitDataflow : virtual public IntraProceduralDataflow // return visitor.finish(); // } // \endcode - virtual boost::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, + virtual std::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, NodeState& state, const std::vector& dfInfo) - { return boost::shared_ptr(new DefaultTransfer(func, n, state, dfInfo, this)); } + { return std::shared_ptr(new DefaultTransfer(func, n, state, dfInfo, this)); } }; class InterProceduralDataflow : virtual public InterProceduralAnalysis diff --git a/src/midend/programAnalysis/genericDataflow/rwAccessLabeler/rwAccessLabeler.C b/src/midend/programAnalysis/genericDataflow/rwAccessLabeler/rwAccessLabeler.C index 01b05dea98d..866c77246f2 100644 --- a/src/midend/programAnalysis/genericDataflow/rwAccessLabeler/rwAccessLabeler.C +++ b/src/midend/programAnalysis/genericDataflow/rwAccessLabeler/rwAccessLabeler.C @@ -3,6 +3,7 @@ #include "sage3basic.h" #include "rwAccessLabeler.h" +#include using namespace std; diff --git a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.C b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.C index ca165fd13f1..c21f9431814 100644 --- a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.C +++ b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.C @@ -3,8 +3,7 @@ #include "divAnalysis.h" -#include -#include +#include int divAnalysisDebugLevel=0; @@ -598,10 +597,10 @@ void DivAnalysisTransfer::transferAdditive(DivLattice *arg1Lat, DivLattice *arg2 else // Else => Top updateModified(resLat->setTop()); } -void DivAnalysisTransfer::visit(SgPlusAssignOp *sgn) { transferArith(sgn, boost::bind(&DivAnalysisTransfer::transferAdditive, _1, _2, _3, _4, true )); } -void DivAnalysisTransfer::visit(SgMinusAssignOp *sgn) { transferArith(sgn, boost::bind(&DivAnalysisTransfer::transferAdditive, _1, _2, _3, _4, false)); } -void DivAnalysisTransfer::visit(SgAddOp *sgn) { transferArith(sgn, boost::bind(&DivAnalysisTransfer::transferAdditive, _1, _2, _3, _4, true )); } -void DivAnalysisTransfer::visit(SgSubtractOp *sgn) { transferArith(sgn, boost::bind(&DivAnalysisTransfer::transferAdditive, _1, _2, _3, _4, false)); } +void DivAnalysisTransfer::visit(SgPlusAssignOp *sgn) { transferArith(sgn, std::bind(&DivAnalysisTransfer::transferAdditive, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, true )); } +void DivAnalysisTransfer::visit(SgMinusAssignOp *sgn) { transferArith(sgn, std::bind(&DivAnalysisTransfer::transferAdditive, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, false)); } +void DivAnalysisTransfer::visit(SgAddOp *sgn) { transferArith(sgn, std::bind(&DivAnalysisTransfer::transferAdditive, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, true )); } +void DivAnalysisTransfer::visit(SgSubtractOp *sgn) { transferArith(sgn, std::bind(&DivAnalysisTransfer::transferAdditive, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, false)); } void DivAnalysisTransfer::transferIncrement(SgUnaryOp *sgn) { DivLattice *arg1Lat, *arg2Lat, *resLat; @@ -736,7 +735,7 @@ void DivAnalysisTransfer::transferArith(SgBinaryOp *sgn, T transferOp) { arg1Lat->copy(resLat); } } -void DivAnalysisTransfer::transferArith(SgBinaryOp *sgn, TransferOp transferOp) { transferArith(sgn, boost::mem_fn(transferOp)); } +void DivAnalysisTransfer::transferArith(SgBinaryOp *sgn, TransferOp transferOp) { transferArith(sgn, std::mem_fn(transferOp)); } void DivAnalysisTransfer::transferMod(DivLattice *arg1Lat, DivLattice *arg2Lat, DivLattice *resLat) { if(divAnalysisDebugLevel>=1) Dbg::dbg << " case i = j %% k\n"; diff --git a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.h b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.h index f79fac2fd9a..8116d7800f9 100644 --- a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.h +++ b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/divAnalysis.h @@ -19,6 +19,7 @@ #include #include #include +#include extern int divAnalysisDebugLevel; @@ -233,9 +234,9 @@ class DivAnalysis : public IntraFWDataflow bool transfer(const Function& func, const DataflowNode& n, NodeState& state, const std::vector& dfInfo) { ROSE_ABORT(); } - boost::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, - NodeState& state, const std::vector& dfInfo) - { return boost::shared_ptr(new DivAnalysisTransfer(func, n, state, dfInfo)); } +std::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, + NodeState& state, const std::vector& dfInfo) +{ return std::shared_ptr(new DivAnalysisTransfer(func, n, state, dfInfo)); } }; // prints the Lattices set by the given DivAnalysis diff --git a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/liveDeadVarAnalysis.h b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/liveDeadVarAnalysis.h index 2d4defab944..9b2fee43863 100644 --- a/src/midend/programAnalysis/genericDataflow/simpleAnalyses/liveDeadVarAnalysis.h +++ b/src/midend/programAnalysis/genericDataflow/simpleAnalyses/liveDeadVarAnalysis.h @@ -19,6 +19,7 @@ #include #include #include +#include extern int liveDeadAnalysisDebugLevel; @@ -171,9 +172,9 @@ class LiveDeadVarsAnalysis : public IntraBWDataflow void genInitState(const Function& func, const DataflowNode& n, const NodeState& state, std::vector& initLattices, std::vector& initFacts); - boost::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, - NodeState& state, const std::vector& dfInfo) - { return boost::shared_ptr(new LiveDeadVarsTransfer(func, n, state, dfInfo, fseu)); } + std::shared_ptr getTransferVisitor(const Function& func, const DataflowNode& n, + NodeState& state, const std::vector& dfInfo) + { return std::shared_ptr(new LiveDeadVarsTransfer(func, n, state, dfInfo, fseu)); } bool transfer(const Function& func, const DataflowNode& n, NodeState& state, const std::vector& dfInfo) { ROSE_ABORT(); } }; diff --git a/src/midend/programAnalysis/pointerAnal/PtrAnal.h b/src/midend/programAnalysis/pointerAnal/PtrAnal.h index 26cff3a5ef9..80a0cb4a717 100644 --- a/src/midend/programAnalysis/pointerAnal/PtrAnal.h +++ b/src/midend/programAnalysis/pointerAnal/PtrAnal.h @@ -1,6 +1,6 @@ #ifndef PTR_ANAL_H #define PTR_ANAL_H -#include +#include #include #include #include @@ -53,8 +53,8 @@ class PtrAnal public: size_t operator()(void * p) const { return (size_t) p; } }; - typedef boost::unordered_map NameMap; - typedef boost::unordered_map, PtrAnal::hash> StmtMap; + typedef std::unordered_map NameMap; + typedef std::unordered_map, PtrAnal::hash> StmtMap; std::list fdefined; NameMap namemap; diff --git a/src/midend/programAnalysis/variableRenaming/VariableRenaming.C b/src/midend/programAnalysis/variableRenaming/VariableRenaming.C index 6db4fa56eb7..71a187b5404 100644 --- a/src/midend/programAnalysis/variableRenaming/VariableRenaming.C +++ b/src/midend/programAnalysis/variableRenaming/VariableRenaming.C @@ -11,7 +11,8 @@ #include #include #include -#include +#include +#include using namespace std; using namespace Rose; @@ -1149,7 +1150,7 @@ VariableRenaming::VarRefSynthAttr VariableRenaming::UniqueNameTraversal::evaluat void VariableRenaming::runDefUse(SgFunctionDefinition* func) { //Keep track of visited nodes - boost::unordered_set visited; + std::unordered_set visited; //Reset the first def list to prevent errors with global vars. firstDefList.clear(); diff --git a/src/midend/programAnalysis/variableRenaming/VariableRenaming.h b/src/midend/programAnalysis/variableRenaming/VariableRenaming.h index c9bc2222a9d..af5a8366231 100644 --- a/src/midend/programAnalysis/variableRenaming/VariableRenaming.h +++ b/src/midend/programAnalysis/variableRenaming/VariableRenaming.h @@ -12,7 +12,7 @@ #include #include #include "filteredCFG.h" -#include +#include /** Class holding a unique name for a variable. Is attached to varRefs as a persistent attribute. * This is used to assign absolute names to VarRefExp nodes during VariableRenaming. @@ -181,6 +181,18 @@ struct IsDefUseFilter } }; +template +struct VectorHash { + std::size_t operator()(const std::vector& vec) const { + std::hash hasher; + std::size_t seed = 0; + for (const T& elem : vec) { + seed ^= hasher(elem) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; + } +}; + /** Class that defines an VariableRenaming of a program * * Contains all the functionality to implement variable renaming on a given program. @@ -210,10 +222,10 @@ class VariableRenaming typedef std::map TableEntry; /** A table storing the name->node mappings for every node in the program. */ - typedef boost::unordered_map DefUseTable; + typedef std::unordered_map DefUseTable; /** A table mapping a name to a single node. */ - typedef boost::unordered_map FirstDefTable; + typedef std::unordered_map> FirstDefTable; /** A vector of SgInitializedName* */ @@ -235,13 +247,13 @@ class VariableRenaming typedef std::map NodeNumRenameEntry; /** A table that maps a name to it's node->number renamings. */ - typedef boost::unordered_map NodeNumRenameTable; + typedef std::unordered_map> NodeNumRenameTable; /** An entry in the rename table that maps a number to a node. */ typedef std::map NumNodeRenameEntry; /** A table that maps a name to it's number->node renamings. */ - typedef boost::unordered_map NumNodeRenameTable; + typedef std::unordered_map> NumNodeRenameTable; private: diff --git a/src/midend/programTransformation/astOutlining/PragmaInterface.cc b/src/midend/programTransformation/astOutlining/PragmaInterface.cc index 6dcec90eb2c..504342349ca 100644 --- a/src/midend/programTransformation/astOutlining/PragmaInterface.cc +++ b/src/midend/programTransformation/astOutlining/PragmaInterface.cc @@ -19,7 +19,6 @@ #include "Outliner.hh" #include "ASTtools.hh" #include "PreprocessingInfo.hh" -#include "Trim.h" //! Simplest outlining directives, applied to a single statement. static const std::string PRAGMA_OUTLINE ("rose_outline"); @@ -89,7 +88,7 @@ processFortranComment(SgLocatedNode* node) if ((*i)->getTypeOfDirective() == PreprocessingInfo::FortranStyleComment) { string commentString = (*i)->getString(); - trim(commentString); + Rose::StringUtility::trim(commentString); if ( (commentString == "!$"+PRAGMA_OUTLINE) || (commentString == "c$"+PRAGMA_OUTLINE) || (commentString == "*$"+PRAGMA_OUTLINE)) diff --git a/src/midend/programTransformation/constantFolding/constantFolding.h b/src/midend/programTransformation/constantFolding/constantFolding.h index ec501e8f1d8..2aa32a983fb 100644 --- a/src/midend/programTransformation/constantFolding/constantFolding.h +++ b/src/midend/programTransformation/constantFolding/constantFolding.h @@ -9,6 +9,8 @@ #ifndef ROSE_CONSTANT_FOLDING_H #define ROSE_CONSTANT_FOLDING_H +#include + namespace ConstantFolding { // Build an inherited attribute for the tree traversal to skip constant folded expressions diff --git a/src/rose-config.C b/src/rose-config.C index 098ede2ba58..27c9596f710 100644 --- a/src/rose-config.C +++ b/src/rose-config.C @@ -40,8 +40,6 @@ static const char *description = #include #include -#include - using namespace Rose; typedef std::map Configuration; @@ -133,16 +131,16 @@ readConfigFile(const std::filesystem::path &configName) { } std::string s = r.line; - s = trim(s); + s = Rose::StringUtility::trim(s); if (s.empty() || '#' == s[0]) continue; // Parse the "key=value" line size_t equal = s.find('='); std::string key = s.substr(0, equal); - key = trim(key); + key = Rose::StringUtility::trim(key); std::string value = equal == std::string::npos ? std::string() : s.substr(equal+1); - value = trim(value); + value = Rose::StringUtility::trim(value); if (equal == std::string::npos || !std::regex_match(key, keyRe)) { MLOG_FATAL_CXX("rose-config") < -#include - -std::string trim(const std::string& str) { - size_t start = str.find_first_not_of(" \t\n\r"); - if (start == std::string::npos) - return ""; - - size_t end = str.find_last_not_of(" \t\n\r"); - size_t length = end - start + 1; - - return str.substr(start, length); -} - From 62a7c4b579117820b44e6ef317bcd91087d75d03 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Thu, 14 Nov 2024 21:57:57 -0500 Subject: [PATCH 27/42] deBoost: remove the use of ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY and related graph support that rely on boost --- config/automake_conditional_display_makefile | 5 - config/support-rose.m4 | 9 - rose_config.h.in.cmake | 4 - src/ROSETTA/Grammar/Support.code | 12 -- src/ROSETTA/src/support.C | 22 --- src/frontend/SageIII/rose_graph_support.C | 178 ------------------- src/frontend/SageIII/rtiHelpers.h | 25 --- src/util/rose_paths.h | 11 -- 8 files changed, 266 deletions(-) diff --git a/config/automake_conditional_display_makefile b/config/automake_conditional_display_makefile index 2b53c52ead1..d2bf6b48d8a 100644 --- a/config/automake_conditional_display_makefile +++ b/config/automake_conditional_display_makefile @@ -224,11 +224,6 @@ if ROSE_USING_GFORTRAN_VERSION_4_1 else @echo "Automake conditional ROSE_USING_GFORTRAN_VERSION_4_1: NOT defined" endif -if ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY - @echo "Automake conditional ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY: DEFINED" -else - @echo "Automake conditional ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY: NOT defined" -endif if ROSE_USING_ROSE @echo "Automake conditional ROSE_USING_ROSE: DEFINED" else diff --git a/config/support-rose.m4 b/config/support-rose.m4 index 2eb08b38a7b..85eeed6bb09 100644 --- a/config/support-rose.m4 +++ b/config/support-rose.m4 @@ -262,15 +262,6 @@ fi # AC_DEFINE([ROSE_USE_NEW_GRAPH_NODES], [], [Whether to use the new graph IR nodes]) #fi -# DQ (5/2/2009): Added support for backward compatability of new IR nodes with older API. -AC_ARG_ENABLE(use_new_graph_node_backward_compatability, - AS_HELP_STRING([--enable-use_new_graph_node_backward_compatability], [Enable new (experimental) graph IR nodes backward compatability API])) -AM_CONDITIONAL(ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY, [test "x$enable_use_new_graph_node_backward_compatability" = xyes]) -if test "x$enable_use_new_graph_node_backward_compatability" = "xyes"; then - AC_MSG_WARN([using the new graph IR nodes in ROSE (experimental)!]) - AC_DEFINE([ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY], [], [Whether to use the new graph IR nodes compatability option with older API]) -fi - # Set the value of srcdir so that it will be an absolute path instead of a relative path # srcdir=`dirname "$0"` # echo "In ROSE/con figure: srcdir = $srcdir" diff --git a/rose_config.h.in.cmake b/rose_config.h.in.cmake index 2cc322f3828..350eb72e8b4 100644 --- a/rose_config.h.in.cmake +++ b/rose_config.h.in.cmake @@ -501,10 +501,6 @@ //AS Don't know what to do with this #undef ROSE_USE_VALGRIND -/* Whether to use the new graph IR nodes compatability option with older API - */ -//#undef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY - /* Simple preprocessor as default in ROSE */ //AS Need configure option to allow wave to be default #define ROSE_WAVE_DEFAULT false diff --git a/src/ROSETTA/Grammar/Support.code b/src/ROSETTA/Grammar/Support.code index 9663080669e..21498919c6f 100644 --- a/src/ROSETTA/Grammar/Support.code +++ b/src/ROSETTA/Grammar/Support.code @@ -601,11 +601,6 @@ HEADER_GRAPH_START void display_string_to_node_index_multimap() const; void display_string_to_edge_index_multimap() const; -#ifdef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY - void display_nodes() const; - void display_edges() const; -#endif - //! Resize the internal hash tables based on the number of nodes (hash_maps and hash_multimaps for edges are made larger by multiplying by the value "numberOfEdges" ). void resize_hash_maps( size_t numberOfNodes, size_t numberOfEdges = 10 ); @@ -22182,16 +22177,9 @@ SOURCE_GRAPHEDGE_END SOURCE_GRAPH_START -//#if defined(ROSE_USE_NEW_GRAPH_NODES) && !defined(ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY) -//#warning "ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY not set" -//#endif - - // DQ (4/29/2009): Declaration of space for static data member. int SgGraph::p_index_counter = 0; - - // tps : todo : remove me ----------------------------------------- void SgGraph::append_properties( int addr, const std::string & prop ) diff --git a/src/ROSETTA/src/support.C b/src/ROSETTA/src/support.C index c3bef046688..00e39698502 100644 --- a/src/ROSETTA/src/support.C +++ b/src/ROSETTA/src/support.C @@ -1548,13 +1548,6 @@ Grammar::setUpSupport () // in favor of the same API, but implemented using a map of maps at // the SgGraph indexed by integer values. -// DQ (5/2/2009): This is put into rose_paths.h -// the warning macro is causing problems in Windows -#if !_MSC_VER -#ifndef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -#warning "ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY not set" -#endif -#endif // ****************************************************************************** // SgGraphNode // ****************************************************************************** @@ -1653,21 +1646,6 @@ Grammar::setUpSupport () UndirectedGraphEdge.setFunctionPrototype ( "HEADER_UNDIRECTED_GRAPH_EDGE", "../Grammar/Support.code"); - - // These IR nodes might be eliminated in favor of just a function to generate the same level - // of support using a combination of two maps in SgGraph. - -#ifdef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY - GraphNodeList.setFunctionPrototype ( "HEADER_GRAPH_NODE_LIST", "../Grammar/Support.code"); - GraphNodeList.setDataPrototype("rose_graph_hash_multimap","nodes","", - NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE); - - GraphEdgeList.setFunctionPrototype ( "HEADER_GRAPH_EDGE_LIST", "../Grammar/Support.code"); - GraphEdgeList.setDataPrototype("rose_graph_node_edge_hash_multimap","edges","", - NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE); -#endif - - // ****************************************************************************** // SgGraph // ****************************************************************************** diff --git a/src/frontend/SageIII/rose_graph_support.C b/src/frontend/SageIII/rose_graph_support.C index 27b06b6ce44..917e4549e6d 100644 --- a/src/frontend/SageIII/rose_graph_support.C +++ b/src/frontend/SageIII/rose_graph_support.C @@ -570,12 +570,6 @@ SgGraph::display_node_index_to_edge_multimap() const // #endif } -#ifdef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -void display_nodes(); -void display_edges(); -#endif - - void SgGraph::resize_hash_maps( size_t numberOfNodes, size_t numberOfEdges ) { @@ -657,178 +651,6 @@ SgGraph::memory_usage() return memory_usage; } - -// #ifdef ROSE_USE_NEW_GRAPH_NODES -// Required for Boost Spanning Tree support. -#include -#include - -int -source(boost::detail::edge_desc_impl& edge_descriptor, SgGraph&) - { - int edge_source_node = edge_descriptor.m_source; - return edge_source_node; - } - -int -target(boost::detail::edge_desc_impl& edge_descriptor, SgGraph&) - { - int edge_target_node = edge_descriptor.m_target; - return edge_target_node; - } -// #endif - - - -// std::vector -std::vector -SgGraph::generateSpanningTree() - { - ROSE_ASSERT(this != NULL); - - // return rose_spanning_tree; - std::vector returnEdgeList; - - - -#ifdef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY - ROSE_ABORT(); - // tps , commented this out because it is baded on the old graph structure - // Dan needs to look at this later -#if 0 - ROSE_ASSERT(get_edges() != NULL); - - // Assemble the representation of the edges for Boost. - SgGraphEdgeList::iterator edgeIt = get_edges()->get_edges().begin(); - while(edgeIt != get_edges()->get_edges().end()) - { - // We want the edges to have an index ordering (could be computed or saved, for now we will save it explicitly). - int i = edgeIt->second->get_node_A()->get_index(); - int j = edgeIt->second->get_node_B()->get_index(); - - // Generate the edge vector for MST (required for many BGL algorithms) - p_boost_edges.push_back(BoostEdgeType(i,j)); - - // Use constant edge weight for now (I think that the edge weights are required by the MST algorithm) - p_boost_edge_weights.push_back(1); - - edgeIt++; - } - - ROSE_ASSERT(get_nodes() != NULL); - - // DQ (4/29/2009): Boost Graph Type used to represent ROSE graphs within Boost Graph Algorithms. - typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, boost::property < boost::edge_weight_t, int > > BoostGraphType; - - // Supporting graph type required by Boost Graph Library. - typedef boost::graph_traits < BoostGraphType >::edge_descriptor BoostEdgeDescriptor; - - BoostGraphType rose_BGL_graph(p_boost_edges.begin(), p_boost_edges.end(), p_boost_edge_weights.begin(), get_nodes()->get_nodes().size()); - - // If we want to add edge weights then this is now we have to do it. - // property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g); - - // Result - std::vector < BoostEdgeDescriptor > rose_spanning_tree; - -#if 1 - // printf ("Computing the kruskal_minimum_spanning_tree() \n"); - boost::kruskal_minimum_spanning_tree(rose_BGL_graph, std::back_inserter(rose_spanning_tree)); - // printf ("DONE: Computing the kruskal_minimum_spanning_tree() \n"); - - printf ("rose_spanning_tree.size() = %" PRIuPTR " \n",rose_spanning_tree.size()); -#endif - -#if 0 - std::cout << "Print the edges in the MST:" << std::endl; - for (std::vector < Edge >::iterator ei = spanning_tree.begin(); ei != spanning_tree.end(); ++ei) - { - cout << source(*ei, g) << " <--> " << target(*ei, g) - << " with weight of " << weight[*ei] - << endl; - - int s = source(*ei, g); - int t = target(*ei, g); - SgGraphNode* nodeA = get_nodes()->get_nodes()[s]; - SgGraphNode* nodeB = get_nodes()->get_nodes()[t]; - - // Now to we find the edge? - // SgGraphEdge* edge = nodeA->get_edges()[s]; - - // How to I get the edge that ends at t? - - returnEdgeList.push_back(*ei); - } -#endif - -#else - // This implementation uses the future ROSE Graph API. - // ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY is undefined - - // A BoostEdgeType is a "std::pair" - // A SgBoostEdgeList is a "std::vector" - SgBoostEdgeList boost_edges; - SgBoostEdgeWeightList boost_edge_weights; - rose_graph_integerpair_edge_hash_multimap::iterator i = p_node_index_pair_to_edge_multimap.begin(); - while (i != p_node_index_pair_to_edge_multimap.end()) - { - // printf ("Building up the boost_edges (%d,%d) \n",i->first.first,i->first.second); - - boost_edges.push_back(i->first); - boost_edge_weights.push_back(1); - i++; - } - - // DQ (4/29/2009): Boost Graph Type used to represent ROSE graphs within Boost Graph Algorithms. - typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, boost::no_property, boost::property < boost::edge_weight_t, int > > BoostGraphType; - - // Supporting graph type required by Boost Graph Library. - typedef boost::graph_traits < BoostGraphType >::edge_descriptor BoostEdgeDescriptor; - - BoostGraphType rose_BGL_graph(p_boost_edges.begin(), p_boost_edges.end(), p_boost_edge_weights.begin(), numberOfGraphNodes()); - - // If we want to add edge weights then this is now we have to do it. - // property_map < Graph, edge_weight_t >::type weight = get(edge_weight, g); - - // Result - std::vector < BoostEdgeDescriptor > rose_spanning_tree; - -#if 1 - // printf ("Computing the kruskal_minimum_spanning_tree() \n"); - boost::kruskal_minimum_spanning_tree(rose_BGL_graph, std::back_inserter(rose_spanning_tree)); - // printf ("DONE: Computing the kruskal_minimum_spanning_tree() \n"); - - printf ("rose_spanning_tree.size() = %" PRIuPTR " \n",rose_spanning_tree.size()); -#endif - -#if 1 - std::cout << "Print the edges in the MST:" << std::endl; - for (std::vector < BoostEdgeDescriptor >::iterator ei = rose_spanning_tree.begin(); ei != rose_spanning_tree.end(); ++ei) - { -#if 1 - // Use the source() and target() functions defined above to extract the node index values from the edge. - int source_node = source(*ei, *this); - int target_node = target(*ei, *this); - - printf ("rose_spanning_tree: source_node = %d target_node = %d \n",source_node,target_node); -#endif - } -#endif - - -// endif for ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -#endif - -// endif for ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -#endif - - - return returnEdgeList; - } - - - - //! Generate a set of SgGraphEdge pointers associated with a given SgGraphNode. std::set SgIncidenceDirectedGraph::computeEdgeSetIn( SgGraphNode* node ) diff --git a/src/frontend/SageIII/rtiHelpers.h b/src/frontend/SageIII/rtiHelpers.h index d99bc5abe24..b30f4a6ff8e 100644 --- a/src/frontend/SageIII/rtiHelpers.h +++ b/src/frontend/SageIII/rtiHelpers.h @@ -165,18 +165,6 @@ static std::string toStringForRTI(const std::mapfirst << "->" << i->second;} - ss << "]"; - return ss.str(); -} -#endif - static std::string toStringForRTI(const rose_graph_integer_node_hash_map & x) { std::ostringstream ss; @@ -246,19 +234,6 @@ static std::string toStringForRTI(const rose_directed_graph_hash_multimap & x) } #endif -#ifdef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -// DQ (8/18/2008): Added support for new Graph IR node. -// static std::string toStringForRTI(const SgStringGraphNodeMapPtrList & x) -static std::string toStringForRTI(const rose_graph_hash_multimap & x) -{ - std::ostringstream ss; - ss << "["; -// for (SgStringGraphNodeMapPtrList::const_iterator i = x.begin(); i != x.end(); ++i) {if (i != x.begin()) ss << ", "; ss << i->first << "->" << i->second;} - ss << "]"; - return ss.str(); -} -#endif - #if 0 // DQ (5/1/2009): This is no longer used and is replaced by an implementation using a hash_map. // DQ (8/18/2008): Added support for new Graph IR node. diff --git a/src/util/rose_paths.h b/src/util/rose_paths.h index fd3ecdc01da..774e6aa231c 100644 --- a/src/util/rose_paths.h +++ b/src/util/rose_paths.h @@ -59,16 +59,5 @@ ROSE_UTIL_API extern const std::string ROSE_OFP_VERSION_STRING; * @endcode */ extern const unsigned long ROSE_NUMERIC_VERSION; - -// DQ (5/2/2009): This is temporary while we work out the details of the new Graph IR nodes. -// #define USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY 0 - -//#ifdef ROSE_USE_NEW_GRAPH_NODES -//#ifndef ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY -//#warning "ROSE_USING_GRAPH_IR_NODES_FOR_BACKWARD_COMPATABILITY IS NOT SET" -//#endif -//#endif - - #endif /* ROSE_PATHS_H */ From b00e4cc39c98fa77d8832f27fd34459375197557 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Thu, 14 Nov 2024 23:15:36 -0500 Subject: [PATCH 28/42] deBoost: remove boost related test and fix wave-related linking errors before we figure out how to keep or remove boost::wave --- config/support-rose.m4 | 2 - scripts/Makefile.am | 1 - src/frontend/SageIII/Makefile.am | 3 +- .../SageIII/astTokenStream/Makefile.am | 2 - src/frontend/SageIII/rose_attributes_list.h | 5 +- .../functional/CompileTests/CMakeLists.txt | 1 - .../functional/CompileTests/Makefile.am | 4 +- .../CompileTests/boost_tests/CMakeLists.txt | 18 --- .../CompileTests/boost_tests/Makefile.am | 115 ------------------ .../CompileTests/boost_tests/README | 15 --- .../boost_tests/include_ordering.C | 43 ------- .../boost_tests/test_boost_lambda.C | 37 ------ .../boost_tests/test_boost_macro_include.cpp | 16 --- .../boost_tests/test_boost_phoenix_v1.C | 29 ----- .../boost_tests/test_boost_phoenix_v2.C | 50 -------- .../boost_tests/test_unordered_map_include.C | 4 - tests/smoke/unit/Boost/Makefile.am | 61 ---------- tests/smoke/unit/Boost/testBoost.C | 53 -------- tests/smoke/unit/Boost/testBoostRegex.C | 15 --- tests/smoke/unit/Boost/testBoostThreads.C | 41 ------- tests/smoke/unit/Makefile.am | 2 +- 21 files changed, 8 insertions(+), 509 deletions(-) delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/CMakeLists.txt delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/Makefile.am delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/README delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/include_ordering.C delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_lambda.C delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_macro_include.cpp delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v1.C delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v2.C delete mode 100644 tests/nonsmoke/functional/CompileTests/boost_tests/test_unordered_map_include.C delete mode 100644 tests/smoke/unit/Boost/Makefile.am delete mode 100644 tests/smoke/unit/Boost/testBoost.C delete mode 100644 tests/smoke/unit/Boost/testBoostRegex.C delete mode 100644 tests/smoke/unit/Boost/testBoostThreads.C diff --git a/config/support-rose.m4 b/config/support-rose.m4 index 85eeed6bb09..b41ca8a2ab1 100644 --- a/config/support-rose.m4 +++ b/config/support-rose.m4 @@ -1277,7 +1277,6 @@ tests/nonsmoke/functional/CompileTests/RoseExample_tests/Makefile tests/nonsmoke/functional/CompileTests/STL_tests/Makefile tests/nonsmoke/functional/CompileTests/UnparseHeadersTests/Makefile tests/nonsmoke/functional/CompileTests/UnparseHeadersUsingTokenStream_tests/Makefile -tests/nonsmoke/functional/CompileTests/boost_tests/Makefile tests/nonsmoke/functional/CompileTests/colorAST_tests/Makefile tests/nonsmoke/functional/CompileTests/copyAST_tests/Makefile tests/nonsmoke/functional/CompileTests/frontend_integration/Makefile @@ -1371,7 +1370,6 @@ tests/smoke/specimens/Makefile tests/smoke/specimens/c++/Makefile tests/smoke/specimens/c/Makefile tests/smoke/specimens/fortran/Makefile -tests/smoke/unit/Boost/Makefile tests/smoke/unit/Makefile tests/smoke/unit/Utility/Makefile tools/Makefile diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 21383a026b0..8dfc7bcb86b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,7 +7,6 @@ distributedScripts = \ Git.pm \ buildExampleRoseWorkspaceScript.sh \ check-dist-file dotgenLetter \ - check_boost_linkage.sh \ dotgen \ dotgen2 \ dotgenLetterPDF \ diff --git a/src/frontend/SageIII/Makefile.am b/src/frontend/SageIII/Makefile.am index 9c76172d0ab..1908cfbb067 100644 --- a/src/frontend/SageIII/Makefile.am +++ b/src/frontend/SageIII/Makefile.am @@ -155,7 +155,8 @@ libsage3_la_LIBADD= \ sageInterface/libsageInterface.la \ virtualCFG/libvirtualCFG.la \ astHiddenTypeAndDeclarationLists/libastHiddenTypeAndDeclarationLists.la \ - includeDirectivesProcessing/libincludeDirectivesProcessing.la + includeDirectivesProcessing/libincludeDirectivesProcessing.la \ + astTokenStream/libastTokenStream.la #endif # DQ (6/25/2011): Readded this directory so that we can support the older behavior as a default diff --git a/src/frontend/SageIII/astTokenStream/Makefile.am b/src/frontend/SageIII/astTokenStream/Makefile.am index ae7f5044221..283b7d58397 100644 --- a/src/frontend/SageIII/astTokenStream/Makefile.am +++ b/src/frontend/SageIII/astTokenStream/Makefile.am @@ -33,7 +33,5 @@ pkginclude_HEADERS = createMap.h doCompleteMapping.h linearizeAST.h unparseMac tokenStreamMapping.h frontierDetection.h simpleFrontierDetection.h previousAndNextNode.h \ maxExtents.h detectMacroOrIncludeFileExpansions.h detectMacroExpansionsToBeUnparsedAsAstTransformations.h - - EXTRA_DIST = CMakeLists.txt diff --git a/src/frontend/SageIII/rose_attributes_list.h b/src/frontend/SageIII/rose_attributes_list.h index 99bd034b113..3ff264a0729 100644 --- a/src/frontend/SageIII/rose_attributes_list.h +++ b/src/frontend/SageIII/rose_attributes_list.h @@ -6,10 +6,11 @@ //#include //#include #include - +#include +#include // Include the ROSE lex specific definitions of tokens #include "general_token_defs.h" -#define ROSE_SKIP_COMPILATION_OF_WAVE 1 +//#define ROSE_SKIP_COMPILATION_OF_WAVE 1 // #ifdef CAN_NOT_COMPILE_WITH_ROSE // #warning "CAN_NOT_COMPILE_WITH_ROSE IS defined" diff --git a/tests/nonsmoke/functional/CompileTests/CMakeLists.txt b/tests/nonsmoke/functional/CompileTests/CMakeLists.txt index 756ba777b77..d198da5bcdf 100644 --- a/tests/nonsmoke/functional/CompileTests/CMakeLists.txt +++ b/tests/nonsmoke/functional/CompileTests/CMakeLists.txt @@ -74,7 +74,6 @@ else() add_subdirectory(colorAST_tests) add_subdirectory(unparseToString_tests) add_subdirectory(sourcePosition_tests) - add_subdirectory(boost_tests) # requires Valgrind #add_subdirectory(uninitializedField_tests) add_subdirectory(OvertureCode) diff --git a/tests/nonsmoke/functional/CompileTests/Makefile.am b/tests/nonsmoke/functional/CompileTests/Makefile.am index a69d2e8808e..84b5bc56459 100644 --- a/tests/nonsmoke/functional/CompileTests/Makefile.am +++ b/tests/nonsmoke/functional/CompileTests/Makefile.am @@ -7,7 +7,7 @@ include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs # copyAST_tests RoseExample_tests PythonExample_tests \ # colorAST_tests mergeAST_tests unparseToString_tests \ # sourcePosition_tests OpenMP_tests \ -# boost_tests virtualCFG_tests uninitializedField_tests \ +# virtualCFG_tests uninitializedField_tests \ # A++Tests OvertureCode P++Tests A++Code ElsaTestCases \ # ExpressionTemplateExample_tests hiddenTypeAndDeclarationListTests \ # sizeofOperation_tests MicrosoftWindows_tests nameQualificationAndTypeElaboration_tests \ @@ -106,7 +106,7 @@ if ROSE_BUILD_CXX_LANGUAGE_SUPPORT copyAST_tests \ colorAST_tests unparseToString_tests \ sourcePosition_tests \ - boost_tests uninitializedField_tests \ + uninitializedField_tests \ OvertureCode \ ExpressionTemplateExample_tests hiddenTypeAndDeclarationListTests \ sizeofOperation_tests nameQualificationAndTypeElaboration_tests \ diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/CMakeLists.txt b/tests/nonsmoke/functional/CompileTests/boost_tests/CMakeLists.txt deleted file mode 100644 index 0b14cdfbc7d..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -set(ROSE_FLAGS --edg:no_warnings -w -rose:verbose 0 --edg:restrict) - -# the following tests either fail or take too long to run -#test_boost_lambda.C -#test_boost_phoenix_v1.C -#test_boost_phoenix_v2.C - -if(EDG_VERSION STREQUAL "4.3") - set(files_to_test - test_boost_lambda.C - test_boost_phoenix_v1.C - ) - set(translator testFrontEnd) -endif() - -foreach(file_to_test ${files_to_test}) - compile_test(${file_to_test} BOOSTTEST) -endforeach() diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/Makefile.am b/tests/nonsmoke/functional/CompileTests/boost_tests/Makefile.am deleted file mode 100644 index 780c3a62163..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/Makefile.am +++ /dev/null @@ -1,115 +0,0 @@ -include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs -EXTRA_DIST = -TEST_TARGETS = - -######################################################################################################################## -# Input specimens for the tests - -# All input specimens for the tests, regardless of whether they are expected to pass or fail. -SPECIMENS_all = \ - test_unordered_map_include.C \ - test_boost_lambda.C \ - test_boost_phoenix_v1.C \ - test_boost_phoenix_v2.C - -EXTRA_DIST += $(SPECIMENS_all) - -######################################################################################################################## -# STUFF FOR THE "testTranslator" TESTS RUN ON EACH INPUT SPECIMEN - -# The test executable which runs some test (encoded in the executable) on each specimen. -TRANSLATOR = ../../testTranslator - -../../testTranslator: - make -C ../.. testTranslator - -# Flags to use when running the tests. Note that we need both the preinclude and normal include directories for -# boost because the pre-include path might be empty in some configurations (e.g., when configuring with -# --with-boost=NON_SYSTEM_DIRECTORY as of 2014-04-08). -TRANSLATOR_FLAGS = \ - --edg:no_warnings \ - -w \ - -rose:verbose 0 \ - --edg:restrict \ - $(ROSE_BOOST_PREINCLUDE_PATH) \ - $(ROSE_BOOST_NORMAL_INCLUDE_PATH) - -# Split specimens into separate lists. The "special" are those specimens that must be run differently than all the rest (i.e., -# they need to be run with different command-line switches). -TRANSLATOR_SPECIMENS_special = \ - test_boost_phoenix_v2.C -TRANSLATOR_SPECIMENS_normal = \ - $(filter-out $(TRANSLATOR_SPECIMENS_special), $(SPECIMENS_all)) -TRANSLATOR_SPECIMENS_failing = \ - test_boost_lambda.C \ - test_boost_phoenix_v1.C \ - test_boost_phoenix_v2.C -TRANSLATOR_SPECIMENS_passing = \ - $(filter-out $(TRANSLATOR_SPECIMENS_failing), $(SPECIMENS_all)) - - -# Makefile targets for running tests. The "special" things need to be separated out because they need different -# rules. If they appear as the target for multiple rules then we'll get warnings from make. -TRANSLATOR_TARGETS_special = $(addprefix translator-, $(addsuffix .passed, $(TRANSLATOR_SPECIMENS_special))) -TRANSLATOR_TARGETS_normal = $(addprefix translator-, $(addsuffix .passed, $(TRANSLATOR_SPECIMENS_normal))) -TRANSLATOR_TARGETS_failing = $(addprefix translator-, $(addsuffix .passed, $(TRANSLATOR_SPECIMENS_failing))) -TRANSLATOR_TARGETS_passing = $(addprefix translator-, $(addsuffix .passed, $(TRANSLATOR_SPECIMENS_passing))) - -# Rules for testing normal specimens regardless of whether we expect them to pass or fail. -$(TRANSLATOR_TARGETS_normal): translator-%.passed: % $(TRANSLATOR) - @$(RTH_RUN) \ - TITLE="testTranslator $* [$@]" \ - USE_SUBDIR=yes \ - CMD="$(abspath $(TRANSLATOR)) $(TRANSLATOR_FLAGS) -c $(srcdir)/$*" \ - $(top_srcdir)/scripts/test_exit_status $@ - -# Rules for the special specimens regardless of whether we expect them to pass or fail. -test_boost_phoenix_v2_flags = \ - -rose:verbose 0 \ - -I$(srcdir)/usr/local/mstools/include \ - -I$(srcdir)/usr/local/mstools/include/phoenix_v2 \ - $(ROSE_BOOST_PREINCLUDE_PATH) \ - $(ROSE_BOOST_NORMAL_INCLUDE_PATH) -translator-test_boost_phoenix_v2.C.passed: test_boost_phoenix_v2.C $(TRANSLATOR) - @$(RTH_RUN) \ - TITLE="testTranslator $< [$@]" \ - USE_SUBDIR=yes \ - CMD="$(abspath $(TRANSLATOR)) $(test_boost_phoenix_v2_flags) -c $(abspath $<)" \ - $(top_srcdir)/scripts/test_exit_status $@ - -# These are the targets that are run by "make check", those that we expect to pass. -TEST_TARGETS += $(TRANSLATOR_TARGETS_passing) - -# These are targets that we might want to run manually. -.PHONY: check-translator-passing check-translator-failing check-translator -check-translator-passing: $(TRANSLATOR_TARGETS_passing) -check-translator-failing: $(TRANSLATOR_TARGETS_failing) -check-translator: check-translator-passing check-translator-failing - -# DQ (8/17/2015): This could be made less boost specific, I think. -test_boost_include_ordering: - ../../testTranslator -I/nfs/casc/overture/ROSE/opt/rhel6/x86_64/boost/1_53_0/gcc/4.4.7/include -c $(srcdir)/include_ordering.C - - -######################################################################################################################## -# The original makefile also had $(QMTEST_Objects) which were test targets, but the rules did not work and they were -# not run by "make check". See the Git commit if you're interested. [Robb P Matzke 2014-04-08] - - -######################################################################################################################## -# Automake boilerplate - -# check-local: $(TEST_TARGETS) -check-local: - @echo "Tests for boot specific regresstion tests operation." -if USING_GNU_COMPILER - @echo "USING_GCC_COMPILER == true" - @$(MAKE) $(TEST_TARGETS) -endif - @echo "*********************************************************************************************************************" - @echo "****** ROSE/tests/nonsmoke/functional/CompileTests/boost_tests: make check rule complete (terminated normally) ******" - @echo "*********************************************************************************************************************" - -clean-local: - rm -f $(TEST_TARGETS) $(TEST_TARGETS:.passed=.failed) - rm -f $(TRANSLATOR_TARGETS_failing) $(TRANSLATOR_TARGETS_failing:.passed=.failed) diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/README b/tests/nonsmoke/functional/CompileTests/boost_tests/README deleted file mode 100644 index fabb644e20b..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/README +++ /dev/null @@ -1,15 +0,0 @@ -ROSE Tests: Markus Schordan -Here is a short summary of the encountered problems and files that demonstrate it. See the test files for detailed problem descriptions. - -test_boost_lambda.C -ROSE 0.8.7a source: OK -ROSE 0.8.8a binary: FAIL - -test_boost_phoenix_v1.C [use phoenix V1 for testing!] -ROSE 0.8.7a source: OK -ROSE 0.8.8a binary: OK - -test_boost_phoenix_v2.C [use phoenix V2 for testing!] -ROSE 0.8.7a source: FAIL -ROSE 0.8.8a binary: FAIL - diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/include_ordering.C b/tests/nonsmoke/functional/CompileTests/boost_tests/include_ordering.C deleted file mode 100644 index ea5b59c0616..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/include_ordering.C +++ /dev/null @@ -1,43 +0,0 @@ - -#include - -// boost 1.53.0 and later moved to dynamic_pointer_cast from dynamic_cast_tag -#include "boost/version.hpp" - -// #if 1 -#if BOOST_VERSION > 105200 - #define SHARED_PTR_CAST(TYPE,VAR) boost::dynamic_pointer_cast(VAR) -#else - #define SHARED_PTR_CAST(TYPE,VAR) VAR, boost::detail::dynamic_cast_tag() -#endif - -#if BOOST_VERSION > 105200 - #warning "using later version of boost" -#else - #warning "using earlier version of boost" -#endif - -struct TTT {}; - - -template class df_shared_ptr: public boost::shared_ptr - { - public: - df_shared_ptr() {} - - template - explicit df_shared_ptr(Y * p) - { - boost::shared_ptr::reset(p); - } - - // template df_shared_ptr(df_shared_ptr const & r) : boost::shared_ptr(r,boost::detail::dynamic_cast_tag()) {} - template df_shared_ptr(df_shared_ptr const & r) : boost::shared_ptr(SHARED_PTR_CAST(df_shared_ptr,r)) {} - - }; - - -void foobar() - { - df_shared_ptr tt; - } diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_lambda.C b/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_lambda.C deleted file mode 100644 index 8182b2f07ed..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_lambda.C +++ /dev/null @@ -1,37 +0,0 @@ -/* - This file demonstrates that ROSE 0.8.8a fails processing a for_each loop with - the boost lambda library - BUT ROSE 0.8.7a CAN process this file without problems! - - ROSE 0.8.8a binary: defaultTranslator -3 FAILS (Aborted) - ROSE 0.8.7a source: defaultTranslator -5 OK - - Author: Markus Schordan, 17-Aug-2006 -*/ - -#include -#include -#include -#include -#include - - -using namespace boost; - -int main() -{ - typedef double numeric_type; - - // container ====== - // - std::vector mycontainer(4); - - // ------------------------------------------------- - // - // == Lambda - // - std::for_each(mycontainer.begin(), mycontainer.end(), - boost::lambda::_1 +=1.0 ); - - return 0; -} diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_macro_include.cpp b/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_macro_include.cpp deleted file mode 100644 index 355f86b8451..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_macro_include.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include -#include - -#define X() 4 - -#define BOOST_PP_VALUE 1 + 2 + 3 + X() -#include BOOST_PP_ASSIGN_SLOT(1) - -#undef X - -int main(int argc, char** argv) { - printf("%s\n", BOOST_PP_STRINGIZE(BOOST_PP_SLOT(1))); - return 0; -} \ No newline at end of file diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v1.C b/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v1.C deleted file mode 100644 index 157b48eeba0..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v1.C +++ /dev/null @@ -1,29 +0,0 @@ -/* - This file demonstrates that ROSE 0.8.8a can process Boost Phoenix V1.0 - Note: this test fails with Phoenix V2.0, see test_phoenix_v2.cc - Author: Markus Schordan, 17-Aug-2006 -*/ - -#include -#include -#include -#include - -#include - -using namespace boost; - -int main() -{ - typedef double numeric_type; - - // container ====== - // - std::vector mycontainer(4); - std::vector::iterator it; - - std::for_each(mycontainer.begin(), mycontainer.end(), - phoenix::arg1 += 1.0 ); - - return 0; -} diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v2.C b/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v2.C deleted file mode 100644 index 18c40b52d70..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/test_boost_phoenix_v2.C +++ /dev/null @@ -1,50 +0,0 @@ -/* - This file demonstrates a problem with ROSE 0.8.8a: - The Boost Phoenix library V2.0 is using template template parameters. - The EDG-ROSE connection does not handle such parameters. - - Error: case tak_template reached in sage_form_template_args() - ROSE/src/frontend/EDG_SAGE_Connection/sage_il_to_str.C:347: SgTemplateArgumentPtrList* sage_form_template_args(a_template_arg*, an_il_to_str_output_control_block*): Assertion `false' failed. - - Code from EDG-ROSE connection from sage_il_to_str.C, line 347: - - case tak_template: // A template template argument. - { - // form_template(tap->variant.templ.ptr, octl); - printf ("Error: case tak_template reached in sage_form_template_args() \n"); - ROSE_ASSERT (false); - break; - } - - - Remark: Note that the Boost Phoenix Library V1.0 does work with the same user code. - See test_phoenix_v1.cc - - Bug reported: Markus Schordan, 17-Aug-2006 -*/ - -#include -#include -#include -#include - -#include -#include -#include - -using namespace boost; - -int main() -{ - typedef double numeric_type; - - // container ====== - // - std::vector mycontainer(4); - std::vector::iterator it; - - std::for_each(mycontainer.begin(), mycontainer.end(), - phoenix::arg1 += 1.0 ); - - return 0; -} diff --git a/tests/nonsmoke/functional/CompileTests/boost_tests/test_unordered_map_include.C b/tests/nonsmoke/functional/CompileTests/boost_tests/test_unordered_map_include.C deleted file mode 100644 index 2b525d74168..00000000000 --- a/tests/nonsmoke/functional/CompileTests/boost_tests/test_unordered_map_include.C +++ /dev/null @@ -1,4 +0,0 @@ -// Test this boost header file. - -#include - diff --git a/tests/smoke/unit/Boost/Makefile.am b/tests/smoke/unit/Boost/Makefile.am deleted file mode 100644 index 3ed6c968ec4..00000000000 --- a/tests/smoke/unit/Boost/Makefile.am +++ /dev/null @@ -1,61 +0,0 @@ -include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs -SUBDIRS = - -noinst_PROGRAMS = -TEST_TARGETS = - -AM_CPPFLAGS = $(ROSE_INCLUDES) -AM_LDFLAGS = $(ROSE_RPATHS) -LDADD = $(ROSE_LIBS) - -############################################################################################################################### -# Check boost library linkage consistency -############################################################################################################################### - -noinst_PROGRAMS += testBoost -testBoost_SOURCES = testBoost.C - -TEST_TARGETS += testBoost.passed - -testBoost.passed: $(top_srcdir)/scripts/test_exit_status testBoost - @$(RTH_RUN) \ - TITLE="boost linkage [$@]" \ - CMD="./testBoost" \ - $< $@ - - -############################################################################################################################### -# Test that boost::regex works. Also ensures that boost hasn't been compiled with -DBOOST_REGEX_MATCH_EXTRA -############################################################################################################################### - -noinst_PROGRAMS += testBoostRegex -testBoostRegex_SOURCES = testBoostRegex.C - -TEST_TARGETS += testBoostRegex.passed - -testBoostRegex.passed: $(top_srcdir)/scripts/test_exit_status testBoostRegex - @$(RTH_RUN) \ - TITLE="boost regex library [$@]" \ - CMD=./testBoostRegex \ - $< $@ - -############################################################################################################################### -# Test that boost::thread works. -############################################################################################################################### - -noinst_PROGRAMS += testBoostThreads -testBoostThreads_SOURCES = testBoostThreads.C - -TEST_TARGETS += testBoostThreads.passed - -testBoostThreads.passed: $(top_srcdir)/scripts/test_exit_status testBoostThreads - @$(RTH_RUN) \ - TITLE="boost threads [$@]" \ - CMD=./testBoostThreads \ - $< $@ - -############################################################################################################################### -# Boilerplate -############################################################################################################################### - -check-local: $(TEST_TARGETS) diff --git a/tests/smoke/unit/Boost/testBoost.C b/tests/smoke/unit/Boost/testBoost.C deleted file mode 100644 index a57477ecad7..00000000000 --- a/tests/smoke/unit/Boost/testBoost.C +++ /dev/null @@ -1,53 +0,0 @@ -#include "rose_getline.h" - -#include -#include -#include -#include -#include - -int -main(int argc, char *argv[]) -{ - size_t nchecked=0, nerrors=0; - - // What version of boost headers was I compiled with? - char hdr_version[64]; - sprintf(hdr_version, "%d.%d.%d", BOOST_VERSION/100000, (BOOST_VERSION/100)%1000, BOOST_VERSION%100); - - // What version of boost libraries was I compiled with? We want to check every boost library individually, so we look at - // our memory map rather than calling a particular boost library function. - FILE *f = fopen("/proc/self/maps", "r"); - if (!f) - return 0; - char *line = NULL; - size_t linesz = 0; - ssize_t n; - while ((n=rose_getline(&line, &linesz, f))>0) { - while (n>0 && isspace(line[n-1])) - line[--n]='\0'; - char *basename = strrchr(line, '/'); - basename = basename ? basename+1 : line; - if (strncmp(basename, "libboost", 8)) - continue; - char *so = strstr(basename, ".so."); - if (!so) - continue; - char *lib_ver = so+4; - - ++nchecked; - if (strcmp(hdr_version, lib_ver)) { - std::cerr < - -int main() { - const char *s = "[;,]\\s*"; - const char *t = "one, two"; - boost::regex re(s); - boost::cmatch matched; - if (regex_search(t, matched, re) && 3==matched.position()) - return 0; - return 1; -} diff --git a/tests/smoke/unit/Boost/testBoostThreads.C b/tests/smoke/unit/Boost/testBoostThreads.C deleted file mode 100644 index ad406f67db7..00000000000 --- a/tests/smoke/unit/Boost/testBoostThreads.C +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include - -#define NWORKERS 12ul -#define WORKER_MAJOR 10000ul -#define WORKER_MINOR 1000ul - -boost::mutex globalAccumulatorMutex; -static boost::uint64_t globalAccumulator = 0; - -void -worker() { - for (boost::uint64_t i = 0; i < WORKER_MAJOR; ++i) { - boost::uint64_t accum = 0; - for (boost::uint64_t j = 0; j < WORKER_MINOR; ++j) { - accum = (accum << 13) ^ (accum >> 7); - accum += j; - } - - boost::lock_guard lock(globalAccumulatorMutex); - globalAccumulator += accum; - } -} - -int -main() { - boost::thread *workers = new boost::thread[NWORKERS]; - for (size_t i = 0; i < NWORKERS; ++i) - workers[i] = boost::thread(worker); - for (size_t i = 0; i < NWORKERS; ++i) - workers[i].join(); - delete[] workers; - std::cout <> 32) & 0xfffffffful) == 0x0a31b218ul) - ? 0 : 1; -} diff --git a/tests/smoke/unit/Makefile.am b/tests/smoke/unit/Makefile.am index c14d049081f..c0aff38eefe 100644 --- a/tests/smoke/unit/Makefile.am +++ b/tests/smoke/unit/Makefile.am @@ -4,4 +4,4 @@ include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs # Matzke (4/21/2017): None of these tests do anything with EDG, so this complicated logic shouldn't be necessary here. Reverting. # These unit test directories should be listed so lower software layers are tested before higher layers. -SUBDIRS = Boost +SUBDIRS = From 99e67627f8e9a16d94272697ce792bf0b90b60ed Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Fri, 15 Nov 2024 01:03:35 -0500 Subject: [PATCH 29/42] deBoost: remove boost-based useless graph processing headers --- .../Tokens.h | 12 +- .../astProcessing/Makefile.am-recursive | 4 +- src/midend/astProcessing/Makefile_variables | 4 - src/midend/astProcessing/SgGraphTemplate.h | 201 -- src/midend/astProcessing/graphProcessing.h | 1559 -------------- .../astProcessing/graphProcessingSgIncGraph.h | 1865 ----------------- src/midend/astProcessing/graphTemplate.h | 531 ----- .../astProcessingTests/processnew3Down4.C | 68 - 8 files changed, 8 insertions(+), 4236 deletions(-) delete mode 100644 src/midend/astProcessing/SgGraphTemplate.h delete mode 100644 src/midend/astProcessing/graphProcessing.h delete mode 100644 src/midend/astProcessing/graphProcessingSgIncGraph.h delete mode 100644 src/midend/astProcessing/graphTemplate.h delete mode 100644 tests/nonsmoke/functional/roseTests/astProcessingTests/processnew3Down4.C diff --git a/src/frontend/Experimental_General_Language_Support/Tokens.h b/src/frontend/Experimental_General_Language_Support/Tokens.h index dfc46531800..c1b8ed0816d 100644 --- a/src/frontend/Experimental_General_Language_Support/Tokens.h +++ b/src/frontend/Experimental_General_Language_Support/Tokens.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace Rose { namespace builder { @@ -67,15 +67,15 @@ class TokenStream { TokenStream() = delete; TokenStream(std::istringstream &); - boost::optional const getNextToken() { + std::optional const getNextToken() { if (next_ < tokens_.size()) { - return boost::optional(tokens_[next_]); + return std::optional(tokens_[next_]); } - return boost::none; + return std::nullopt; } - boost::optional consumeNextToken() { - boost::optional nextToken{getNextToken()}; + std::optional consumeNextToken() { + std::optional nextToken{getNextToken()}; next_ += 1; return nextToken; } diff --git a/src/midend/astProcessing/Makefile.am-recursive b/src/midend/astProcessing/Makefile.am-recursive index 9c5f1317410..ce0b756cecd 100644 --- a/src/midend/astProcessing/Makefile.am-recursive +++ b/src/midend/astProcessing/Makefile.am-recursive @@ -15,8 +15,8 @@ include_HEADERS = \ AstReverseSimpleProcessing.h AstRestructure.h AstClearVisitFlags.h \ AstTraversal.h AstCombinedProcessing.h AstCombinedProcessingImpl.h \ AstCombinedSimpleProcessing.h StackFrameVector.h AstSharedMemoryParallelProcessing.h \ - AstSharedMemoryParallelProcessingImpl.h AstSharedMemoryParallelSimpleProcessing.h graphProcessing.h \ - graphTemplate.h SgGraphTemplate.h TreeTraversal.h plugin.h + AstSharedMemoryParallelProcessingImpl.h AstSharedMemoryParallelSimpleProcessing.h \ + TreeTraversal.h plugin.h libastprocessingSources = \ diff --git a/src/midend/astProcessing/Makefile_variables b/src/midend/astProcessing/Makefile_variables index 4160261d8c6..d3b38ec7bb6 100644 --- a/src/midend/astProcessing/Makefile_variables +++ b/src/midend/astProcessing/Makefile_variables @@ -41,10 +41,6 @@ mAstProcessing_includeHeaders=\ $(mAstProcessingPath)/AstSharedMemoryParallelProcessing.h \ $(mAstProcessingPath)/AstSharedMemoryParallelProcessingImpl.h \ $(mAstProcessingPath)/AstSharedMemoryParallelSimpleProcessing.h \ - $(mAstProcessingPath)/graphProcessing.h \ - $(mAstProcessingPath)/graphProcessingSgIncGraph.h \ - $(mAstProcessingPath)/graphTemplate.h \ - $(mAstProcessingPath)/SgGraphTemplate.h \ $(mAstProcessingPath)/TreeTraversal.h mAstProcessing_extraDist=\ diff --git a/src/midend/astProcessing/SgGraphTemplate.h b/src/midend/astProcessing/SgGraphTemplate.h deleted file mode 100644 index 9429026a6b4..00000000000 --- a/src/midend/astProcessing/SgGraphTemplate.h +++ /dev/null @@ -1,201 +0,0 @@ -#include -#include -//#include -#include -#include -#include -struct Vertex{ - SgGraphNode* sg; - CFGNode cfgnd; -}; - -struct Edge { - SgDirectedGraphEdge* gedge; -}; - -typedef boost::adjacency_list< - boost::vecS, - boost::vecS, - boost::bidirectionalS, - Vertex, - Edge -> myGraph; - -typedef myGraph::vertex_descriptor VertexID; -typedef myGraph::edge_descriptor EdgeID; - -//myGraph* instantiateGraph(SgIncidencedDirectedGraph* g, StaticCFG::CFG cfg); -std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start); -std::map getGraphNode; -std::map VSlink; - -myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::InterproceduralCFG& cfg, SgNode* pstart) { - //SgNode* prestart = cfg.getEntry(); - //cfg.buildFullCFG(); - CFGNode startN = cfg.getEntry(); - SgGraphNode* start = cfg.toGraphNode(startN); - ROSE_ASSERT(startN != NULL); - ROSE_ASSERT(start != NULL); - myGraph* graph = new myGraph; - //std::map VSlink; - std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); - std::vector nods = alledsnds.first; - std::vector eds = alledsnds.second; - std::set > prs; - //for (std::vector i = nods.begin(); i != nods.end(); i++) { - // VertexID vID = boost::add_vertex(graph); - // graph[vID].cfgnd = cfg->toCFGNode(*i); - //} - for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { - SgDirectedGraphEdge* u = *j; - SgGraphNode* u1 = u->get_from(); - SgGraphNode* u2 = u->get_to(); - VertexID v1; - VertexID v2; - if (VSlink.find(u1) == VSlink.end()) { - v1 = boost::add_vertex(*graph); - getGraphNode[v1] = u1; - VSlink[u1] = v1; - (*graph)[v1].sg = u1; - (*graph)[v1].cfgnd = cfg.toCFGNode(u1); - } - else { - v1 = VSlink[u1]; - } - if (VSlink.find(u2) != VSlink.end()) { - v2 = VSlink[u2]; - } - else { - v2 = boost::add_vertex(*graph); - VSlink[u2] = v2; - (*graph)[v2].sg = u2; - getGraphNode[v2] = u2; - (*graph)[v2].cfgnd = cfg.toCFGNode(u2); - } - bool ok; - EdgeID uE; - std::pair pr; - pr.first = v1; - pr.second = v2; - if (prs.find(pr) == prs.end()) { - prs.insert(pr); - boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); - } - } - //std::cout << "prs.size: " << prs.size() << std::endl; - return graph; -} - - - -myGraph* instantiateGraph(SgIncidenceDirectedGraph*& g, StaticCFG::CFG& cfg) { - SgGraphNode* start = cfg.getEntry(); - myGraph* graph = new myGraph; - //std::map VSlink; - std::pair, std::vector > alledsnds = getAllNodesAndEdges(g, start); - std::vector nods = alledsnds.first; - std::vector eds = alledsnds.second; - std::set > prs; - //for (std::vector i = nods.begin(); i != nods.end(); i++) { - // VertexID vID = boost::add_vertex(graph); - // graph[vID].cfgnd = cfg->toCFGNode(*i); - //} - for (std::vector::iterator j = eds.begin(); j != eds.end(); j++) { - SgDirectedGraphEdge* u = *j; - SgGraphNode* u1 = u->get_from(); - SgGraphNode* u2 = u->get_to(); - VertexID v1; - VertexID v2; - if (VSlink.find(u1) == VSlink.end()) { - v1 = boost::add_vertex(*graph); - getGraphNode[v1] = u1; - VSlink[u1] = v1; - (*graph)[v1].sg = u1; - (*graph)[v1].cfgnd = cfg.toCFGNode(u1); - } - else { - v1 = VSlink[u1]; - } - if (VSlink.find(u2) != VSlink.end()) { - v2 = VSlink[u2]; - } - else { - v2 = boost::add_vertex(*graph); - VSlink[u2] = v2; - (*graph)[v2].sg = u2; - getGraphNode[v2] = u2; - (*graph)[v2].cfgnd = cfg.toCFGNode(u2); - } - bool ok; - EdgeID uE; - std::pair pr; - pr.first = v1; - pr.second = v2; - if (prs.find(pr) == prs.end()) { - prs.insert(pr); - boost::tie(uE, ok) = boost::add_edge(v1, v2, *graph); - } - } - //std::cout << "prs.size: " << prs.size() << std::endl; - return graph; -} - - - - -std::pair, std::vector > getAllNodesAndEdges(SgIncidenceDirectedGraph* g, SgGraphNode* start) { - //for (int i = 0; i < starts.size(); i++) { - SgGraphNode* n = start; - std::vector nods; - std::vector newnods; - std::set edsnew; - std::vector eds; - std::vector feds; - std::vector fnods; - std::set > prs; - std::set oeds = g->computeEdgeSetOut(start); - fnods.push_back(start); - newnods.push_back(n); - - while (oeds.size() > 0) { - for (std::set::iterator j = oeds.begin(); j != oeds.end(); j++) { - //if (find(eds.begin(), eds.end(), *j) == eds.end()) { - if (find(feds.begin(), feds.end(), *j) == feds.end()) { - feds.push_back(*j); - edsnew.insert(*j); - } - if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { - fnods.push_back((*j)->get_to()); - } - newnods.push_back((*j)->get_to()); - //} - } - - for (unsigned int i = 0; i < newnods.size(); i++) { - std::set oedsp = g->computeEdgeSetOut(newnods[i]); - for (std::set::iterator j = oedsp.begin(); j != oedsp.end(); j++) { - if (find(feds.begin(), feds.end(), *j) == feds.end()) { - // feds.push_back(*j); - edsnew.insert(*j); - - } - //if (find(fnods.begin(), fnods.end(), (*j)->get_to()) == fnods.end()) { - // fnods.push_back((*j)->get_to()); - // newnods.push_back((*j)->get_to()); - // } - // newnods.push_back((*j)->get_to()); - } - } - nods = newnods; - oeds = edsnew; - edsnew.clear(); - newnods.clear(); - } - std::pair, std::vector > retpr; - retpr.first = fnods; - retpr.second = feds; - //std::cout << "fnods.size()" << fnods.size() << std::endl; - //std::cout << "feds.size()" << feds.size() << std::endl; - return retpr; -} - diff --git a/src/midend/astProcessing/graphProcessing.h b/src/midend/astProcessing/graphProcessing.h deleted file mode 100644 index 0d8baadcf09..00000000000 --- a/src/midend/astProcessing/graphProcessing.h +++ /dev/null @@ -1,1559 +0,0 @@ -/* - -FINISH TEMPFLATPATH CODE - -AS WRITTEN, THESE FUNCTIONS WILL ONLY WORK WITH GRAPHS THAT ARE IMPLEMENTED IN THE boost NAMESPACE. - -*/ - - - - -#define LP 1 -#define PERFDEBUG 0 -//#define FULLDEBUG 1 -#ifdef _OPENMP -#include -#endif -#include -#include -#include -#include -#include -#include - -/** -*@file graphProcessing.h - -*Brief Overview of Algorithm: - -*********************** -*Current Implementation -*********************** - -*This implementation uses BOOSTs graph structure to analyze the paths of the graph - -*The path analyzer sends the user paths to be evaluated by the "analyzePath" function that is user defined - -************************** -*Further Improvements: TODO -************************** - -@todo utilize BOOST visitors to take advantage of the BOOST graph structures abilities - -*************** -*Contact Info -*************** - -*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed - -*if I'm still at Lawrence -*hoffman34 AT llnl DOT gov -*@author Michael Hoffman -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include - - - -#include -#include -#include -#include -#include -#include -#include - - - - - - -template -class SgGraphTraversal -{ -public: - - typedef typename boost::graph_traits::vertex_descriptor Vertex; - typedef typename boost::graph_traits:: edge_descriptor Edge; - - void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); - virtual void analyzePath(std::vector& pth) = 0; - std::vector getInEdges(int& node, CFG*& g); - std::vector getOutEdges(int& node, CFG*& g); - int getTarget(int& n, CFG*& g); - int getSource(int& n, CFG*& g); - std::map vertintmap; - std::map edgeintmap; - std::map intvertmap; - std::map intedgemap; - SgGraphTraversal(); - virtual ~SgGraphTraversal(); - SgGraphTraversal( SgGraphTraversal &); - SgGraphTraversal &operator=( SgGraphTraversal &); - int pathnum; - - - void firstPrepGraph(CFG*& g); - -private: - - int normals; - int abnormals; - bool needssafety; - int recursed; - int checkedfound; - // typedef typename boost::graph_traits::vertex_descriptor Vertex; - // typedef typename boost::graph_traits:: edge_descriptor Edge; - // std::vector getInEdges(int& node, CFG*& g); - // std::vector getOutEdges(int& node, CFG*& g); - void prepareGraph(CFG*& g); - void findClosuresAndMarkersAndEnumerate(CFG*& g); - // void constructPathAnalyzer(CFG* g, bool unbounded=false, Vertex end=0, Vertex begin=0, bool ns = true); - // virtual void analyzePath(std::vector& pth) = 0; - // void firstPrepGraph(CFG*& g); - int stoppedpaths; - std::set > traversePath(int begin, int end, CFG*& g, bool loop=false); - std::set > uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& localLoops); - std::vector > bfsTraversePath(int begin, int end, CFG*& g, bool loop=false); - std::vector unzipPath(std::vector& path, CFG*& g, int start, int end); - std::vector zipPath(std::vector& path, CFG*& g, int start, int end); - std::vector zipPath2(std::vector& path, CFG*& g); - void printCFGNode(int& cf, std::ofstream& o); - void printCFGNodeGeneric(int& cf, std::string prop, std::ofstream& o); - void printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o); - void printHotness(CFG*& g); - void printPathDot(CFG*& g); - void computeOrder(CFG*& g, const int& begin); - void computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential); - //int getTarget(int& n, CFG*& g); - //int getSource(int& n, CFG*& g); - std::vector sources; - std::vector sinks; - std::vector recursiveLoops; - std::vector recurses; - std::map ptsNum; - bool borrowed; - std::set badloop; - std::map > > totalLoops; -// int pathnum; - std::map nodeStrings; - int sourcenum; - unsigned long long evaledpaths; - int badpaths; - int workingthreadnum; - bool workingthread; - std::map > > loopStore; - std::vector > pathStore; - std::map > subpathglobal; - std::map, int> subpathglobalinv; - int nextsubpath; - std::vector orderOfNodes; -// std::map vertintmap; -// std::map edgeintmap; -// std::map intvertmap; -// std::map intedgemap; - std::vector > SubGraphGraphMap; - std::vector > GraphSubGraphMap; - std::vector subGraphVector; - void getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath ); - void storeCompact(std::vector path); - int nextNode; - int nextEdge; - std::vector markers; - std::vector closures; - std::map markerIndex; - std::map > pathsAtMarkers; - typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; - typedef typename boost::graph_traits::edge_iterator edge_iterator; - bool bound; -// SgGraphTraversal(); -// virtual ~SgGraphTraversal(); -// SgGraphTraversal( SgGraphTraversal &); -// SgGraphTraversal &operator=( SgGraphTraversal &); - - -}; - - -template -SgGraphTraversal:: -SgGraphTraversal() -{ -} - - - -template -SgGraphTraversal & -SgGraphTraversal:: -operator=( SgGraphTraversal &other) -{ - return *this; -} - -#ifndef SWIG - -template -SgGraphTraversal:: -~SgGraphTraversal() -{ -} - -#endif - -/** - Gets the source of an edge - SgGraphTraversal::getSource - Input: - @param[edge] int& integer representation of edge in question - @param[g] CFG*& the CFG used -*/ -template -inline int -SgGraphTraversal:: -getSource(int& edge, CFG*& g) -{ - Edge e = intedgemap[edge]; - Vertex v = boost::source(e, *g); - return(vertintmap[v]); -} - -/** - Gets the target of an edge - SgGraphTraversal::getTarget - Input: - @param[edge] int& integer representation of edge in quesution - @param[g] the CFG*& CFG used -*/ - - -template -inline int -SgGraphTraversal:: -getTarget(int& edge, CFG*& g) -{ - Edge e = intedgemap[edge]; - Vertex v = boost::target(e, *g); - return(vertintmap[v]); -} - -/** -Gets out edges with integer inputs, internal use only -SgGraphTraversal::getInEdges -Input: -@param[node] int, integer representation of the node to get the in edges from -@param[g] CFG* g, CFG -*/ - -template -std::vector -SgGraphTraversal:: -getInEdges(int& node, CFG*& g) -{ - Vertex getIns = intvertmap[node]; - std::vector inedges; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - in_edge_iterator i, j; -#else - // This does not compile. - in_edge_iterator i = inedges.begin(); - in_edge_iterator j = i; -#endif - for (boost::tie(i, j) = boost::in_edges(getIns, *g); i != j; ++i) - { - inedges.push_back(edgeintmap[*i]); - } - return inedges; -} - -/** -Gets out edges with integer inputs, internal use only -SgGraphTraversal::getOutEdges -Input: -@param[node] int, integer representation of the node to get the out edges from -@param[g] CFG* g, CFG -*/ - - - -template -std::vector -SgGraphTraversal:: -getOutEdges(int &node, CFG*& g) -{ - Vertex getOuts = intvertmap[node]; - std::vector outedges; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - out_edge_iterator i, j; -#else - // This does not compile. - out_edge_iterator i = outedges.begin(); - out_edge_iterator j = i; -#endif - for (boost::tie(i, j) = boost::out_edges(getOuts, *g); i != j; ++i) - { - outedges.push_back(edgeintmap[*i]); - } - return outedges; -} - -/** -Condenses paths, currently deprecated... -Input: -@param[pth] std::vector the original path -@param[g] CFG*, the ambient graph -Output: -zipped path -*/ - -template -inline -std::vector -SgGraphTraversal:: -zipPath2(std::vector& pth, CFG*& g) { - std::vector npth; - npth.push_back(pth[0]); - for (int i = 1; i < pth.size()-1; i++) { - if (find(closures.begin(), closures.end(), pth[i]) != closures.end()) { - npth.push_back(pth[i]); - } - } - npth.push_back(pth.back()); - return npth; -} - -/** -Condenses paths to simply the first and last node and the ordered set of edges -taken at nodes with more than 1 outedge -Input: -@param[pth] std::vector, the original path -@param[g] CFG*, the ambient graph -@param[start] integer representation of the first node -@param[end] integer representation of the last node -*/ - - -template -std::vector -SgGraphTraversal:: -zipPath(std::vector& pth, CFG*& g, int start, int end) { - std::vector subpath; - std::vector movepath; - movepath.push_back(pth.front()); - movepath.push_back(pth.back()); - for (unsigned int qw = 0; qw < pth.size()-1; qw++) { - if (find(markers.begin(), markers.end(), pth[qw]) != markers.end()) { - std::vector oeds = getOutEdges(pth[qw], g); - for (unsigned int i = 0; i < oeds.size(); i++) { - if (getTarget(oeds[i], g) == pth[qw+1]) { - movepath.push_back(oeds[i]); - } - } - } - } - return movepath; - } - - - - - - -/** -unzips the paths zipped by zipPath -Input: -@param[pzipped] the zipped path -@param[CFG] the ambient graph -@param[start] the integer representation of the first node (used to check that zipPath is working correctly) -@param[end] the integer representation of the end node -*/ - - -template -std::vector -SgGraphTraversal:: -unzipPath(std::vector& pzipped, CFG*& g, int start, int end) { - ROSE_ASSERT(pzipped[0] == start && (pzipped[1] == end || end == -1)); - std::vector zipped; - for (unsigned int i = 2; i < pzipped.size(); i++) { - zipped.push_back(pzipped[i]); - } - std::vector unzipped; - unzipped.push_back(start); - std::vector oeds = getOutEdges(start, g); - if (oeds.size() == 0) { - return unzipped; - } - for (unsigned int i = 0; i < zipped.size(); i++) { - oeds = getOutEdges(unzipped.back(), g); - while (oeds.size() == 1) { - if (getTarget(oeds[0], g) == end && unzipped.size() != 1) { - unzipped.push_back(end); - return unzipped; - } - unzipped.push_back(getTarget(oeds[0], g)); - oeds = getOutEdges(unzipped.back(), g); - } - if (oeds.size() == 0) { - return unzipped; - } - if (oeds.size() > 1 && (unzipped.back() != end || (unzipped.size() == 1 && unzipped.back() == end))) { - ROSE_ASSERT(getSource(zipped[i], g) == unzipped.back()); - unzipped.push_back(getTarget(zipped[i], g)); - } - - } - std::vector oeds2 = getOutEdges(unzipped.back(), g); - if (unzipped.back() != end && oeds2.size() != 0) { - while (oeds2.size() == 1 && unzipped.back() != end) { - unzipped.push_back(getTarget(oeds2[0], g)); - oeds2 = getOutEdges(unzipped.back(), g); - } - } - return unzipped; -} - -/* -Example Time - - Example: - timeval tim; - gettimeofday(&tim, NULL); - double t1=tim.tv_sec+(tim.tv_usec/1000000.0); - do_something_long(); - gettimeofday(&tim, NULL); - double t2=tim.tv_sec+(tim.tv_usec/1000000.0); - printf("%.6lf seconds elapsed\n", t2-t1); - -*/ - -/** -The function responsible for collecting all paths without loops, and all paths within lops that do not include other loops -then sending those to uTraverse to assemble them into all paths with any combination of loops -Input: -@param[begin] integer representation of the first node -@param[end] integer representation of the last node (or -1 if its not bounded) -@param[g] CFG*, the ambient CFG -@param[loop] boolean expressing whether or not we are calculating paths contained within a loop -*/ - - -template -std::vector > -SgGraphTraversal:: -bfsTraversePath(int begin, int end, CFG*& g, bool loop) { -//perfdebug allows for examining the speed of traversal - #ifdef PERFDEBUG - //timeval tim; - //gettimeofday(&tim, NULL); - //double tim1 = tim.tv_sec+(tim.tv_usec/1000000.0); - #endif - bool recursedloop = loop; - std::map > > PtP; - std::set nodes; - std::vector > pathContainer; - //std::vector > oldPaths; - std::vector completedLoops; - std::vector > npc; - std::vector bgpath; - bgpath.push_back(begin); - pathContainer.push_back(bgpath); - std::vector > newPathContainer; - std::vector > paths; - std::vector localLoops; - std::map > > globalLoopPaths; - //std::cout << "at the while" << std::endl; -//To keep - while (pathContainer.size() != 0 /*|| oldPaths.size() != 0*/) { -/* - unsigned int mpc = 50000; - if (pathContainer.size() == 0) { - unsigned int mxl = 0; - if (oldPaths.size() > mpc) { - mxl = mpc/2; - } - else { - mxl = oldPaths.size(); - } - for (unsigned int k = 0; k < mxl; k++) { - pathContainer.push_back(oldPaths.back()); - oldPaths.pop_back(); - } - } - if (pathContainer.size() > mpc) { - unsigned int j = 0; - while (j < mpc) { - npc.push_back(pathContainer.back()); - pathContainer.pop_back(); - j++; - } - oldPaths.insert(oldPaths.end(), pathContainer.begin(), pathContainer.end()); - pathContainer = npc; - npc.clear(); - } -*/ - -//iterating through the currently discovered subpaths to build them up - for (unsigned int i = 0; i < pathContainer.size(); i++) { - std::vector npth = pathContainer[i]; - std::vector oeds = getOutEdges(npth.back(), g); - std::vector ieds = getInEdges(npth.back(), g); - - npth = pathContainer[i]; - oeds = getOutEdges(npth.back(), g); - - if ((!recursedloop && ((bound && npth.back() == end && npth.size() != 1) || (!bound && oeds.size() == 0))) || (recursedloop && npth.back() == end && npth.size() != 1)) { - std::vector newpth; - newpth = (pathContainer[i]); - std::vector movepath = newpth;//zipPath(newpth, g); - if (recursedloop && newpth.back() == end && newpth.size() != 1) { - paths.push_back(movepath); - } - else if (!recursedloop) { - if (bound && newpth.size() != 1 && newpth.back() == end) { - paths.push_back(movepath); - } - else if (!bound) { - paths.push_back(movepath); - } - } - - } - else { -std::vector oeds = getOutEdges(pathContainer[i].back(), g); - - for (unsigned int j = 0; j < oeds.size(); j++) { - - -int tg = getTarget(oeds[j], g); - - - std::vector newpath = (pathContainer[i]); - //we split up paths into pieces so that they don't take up a lot of memory, basically this is when we run into a path - //more than once, so we attach all paths that go to that path to that particular node via PtP - if (nodes.find(tg) != nodes.end() && find(newpath.begin(), newpath.end(), tg) == newpath.end() && tg != end) { - if (PtP.find(tg) == PtP.end()) { - std::vector nv; - nv.push_back(tg); - newPathContainer.push_back(nv); - PtP[tg].push_back(/*zipPath(*(*/newpath);//, g, newpath.front(), newpath.back())); - } - else { - PtP[tg].push_back(/*zipPath(*/newpath);//, g, newpath.front(), newpath.back())); - } - } - else if (find(newpath.begin(), newpath.end(), getTarget(oeds[j], g)) == newpath.end() || getTarget(oeds[j], g) == end) { - newpath.push_back(tg); - std::vector ieds = getInEdges(tg, g); - if (ieds.size() > 1) {//find(closures.begin(), closures.end(), tg) != closures.end()) { - nodes.insert(tg); - } - newPathContainer.push_back(newpath); - } - else if (tg == end && recursedloop) { - newpath.push_back(tg); - newPathContainer.push_back(newpath); - } - else {//if (find(newpath.begin(), newpath.end(), tg) != newpath.end() && tg != end) { - std::vector ieds = getInEdges(tg, g); - if (ieds.size() > 1/*find(closures.begin(), closures.end(), tg) != closures.end()*/ && find(completedLoops.begin(), completedLoops.end(), tg) == completedLoops.end() /*&& find(localLoops.begin(), localLoops.end(), tg) == localLoops.end()*/ && find(recurses.begin(), recurses.end(), tg) == recurses.end()) { - localLoops.push_back(tg); - nodes.insert(tg); - } - // else if (find(recurses.begin(), recurses.end(), tg) != recurses.end()) { - // } - } - //else { - // std::cout << "problem" << std::endl; - // ROSE_ASSERT(false); - // } - } - } - } - pathContainer = newPathContainer; - newPathContainer.clear(); - } - // std::cout << "done while" << std::endl; - pathContainer.clear(); - std::vector > finnpts; - std::vector > npts; - while (true) { - if (paths.size() > 1000000) { - std::cout << "too many paths, consider a subgraph" << std::endl; - ROSE_ABORT(); - } - //#pragma omp parallel for schedule(guided) - for (unsigned int qq = 0; qq < paths.size(); qq++) { - std::vector pq = paths[qq]; - std::vector qp; - int ppf = paths[qq].front(); - if (PtP.find(ppf) != PtP.end()) { - for (unsigned int kk = 0; kk < PtP[ppf].size(); kk++) { - std::vector newpath = /*unzipPath(*/PtP[ppf][kk];//, g, PtP[ppf][kk][0], PtP[ppf][kk][1]); - bool good = true; - if (newpath.back() == newpath.front() && newpath.front() != begin && newpath.size() > 1) { - good = false; - } - else { - - // if (find(pq.begin(), pq.end(), newpath.front()) != pq.end() && newpath.front() != begin) { - // good = false; - // } - - - // else { - for (unsigned int kk1 = 0; kk1 < newpath.size(); kk1++) { - - /* - if (newpath.front() == newpath.back()) { - good = false; - break; - } - else */if (find(pq.begin(), pq.end(), newpath[kk1]) != pq.end() && newpath[kk1] != begin) { - good = false; - break; - - } - } - //} - } - if (good) { - newpath.insert(newpath.end(), pq.begin(), pq.end()); - #pragma omp critical - { - npts.push_back(newpath); - } - } - } - } - else { - std::vector ppq = pq;// zipPath(pq, g, pq.front(), pq.back()); - #pragma omp critical - { - finnpts.push_back(ppq); - } - } - } - if (npts.size() == 0) { - break; - } - else { - paths = npts; - npts.clear(); - } - } - paths = finnpts; - finnpts.clear(); - for (unsigned int k = 0; k < localLoops.size(); k++) { - int lk = localLoops[k]; - std::vector > loopp; - if (loopStore.find(localLoops[k]) != loopStore.end()) { - loopp.insert(loopp.end(), loopStore[localLoops[k]].begin(), loopStore[localLoops[k]].end()); - } - else { - std::map > > localLoopPaths; - completedLoops.push_back(lk); - recurses.push_back(lk); - loopp = bfsTraversePath(lk, lk, g, true); - recurses.pop_back(); - } - for (unsigned int ik = 0; ik < loopp.size(); ik++) { - - if (find(globalLoopPaths[lk].begin(), globalLoopPaths[lk].end(), loopp[ik]) == globalLoopPaths[lk].end()) { - globalLoopPaths[localLoops[k]].push_back(loopp[ik]); - } - } - - - - } - borrowed = true; - std::vector > lps2; - //unsigned int maxpaths = 1000; - //unsigned int pathdivisor = 1;//paths.size()/maxpaths;///paths.size(); - - //if (pathdivisor < 1) { - //pathdivisor = 1; - //maxpaths = paths.size(); - // } -/* - for (unsigned int j = 0; j < pathdivisor+1; j++) { - std::vector > npaths; - std::vector dummyvec; - unsigned int mxpths; - if (j < pathdivisor) { - mxpths = maxpaths; - } - else { - mxpths = paths.size() % pathdivisor; - } - for (unsigned int k = 0; k < mxpths; k++) { - npaths.push_back(paths.back());//unzipPath(paths.back(), g, begin, end)); - paths.pop_back(); - } -*/ - pathStore = paths; - paths.clear(); - if (!recursedloop) { - uTraversePath(begin, end, g, false, globalLoopPaths); - } - else { - recursed++; - - std::set > lps = uTraversePath(begin, end, g, true, globalLoopPaths); - recursed--; - for (std::set >::iterator ij = lps.begin(); ij != lps.end(); ij++) { - std::vector ijk = (*ij); - - lps2.push_back(*ij); - } - } - //} - #ifdef PERFDEBUG - // timeval tim; - //std::cout << "begin: " << begin << " end: " << end << std::endl; - //gettimeofday(&tim, NULL); - //double tim2 = tim.tv_sec+(tim.tv_usec/1000000); - //double timeRet = tim2 - tim1; - //std::cout << "bfs time elapsed: " << timeRet << std::endl; - #endif - return lps2; - -} - - -/** -This function calculates all the permutations of loops on paths -it also throws away duplicate paths -Input: -@param[begin] integer representation of first node -@param[end] integer representation of the final node -@param[g] ambient CFG -@param[globalLoopPaths] connects an integer representation of a node to all possible loops starting at that node -*/ - - -template -std::set > -SgGraphTraversal:: -uTraversePath(int begin, int end, CFG*& g, bool loop, std::map > >& globalLoopPaths) { - //std::cout << "uTraverse" << std::endl; - //int doubledpaths = 0; - int newmil = 1; - //#ifdef LP - //if (loop && loopStore.find(begin) != loopStore.end()) { - // return loopStore[begin]; - //} - //#endif - #ifdef PERFDEBUG - //timeval tim; - //gettimeofday(&tim, NULL); - //double t1 = tim.tv_sec+(tim.tv_usec/1000000); - #endif - std::set > newpaths; - std::set > npaths; - pathnum = 0; - std::vector path; - std::vector > paths; - int truepaths = 0; - std::vector > checkpaths; - std::vector > npathchecker; - std::map currents; - //int nnumpaths = 0; - std::set > loopPaths; - //bool threadsafe = true; - bool done = false; - std::set > fts; - //double ttfors = 0; - //double tperms = 0; - while (true) { - //std::cout << "paths.size() " << paths.size() << std::endl; - if (paths.size() > 1000000) { - std::cout << "nearly 1 million paths with no loops, stopping" << std::endl; - return loopPaths; - std::cout << "ended early" << std::endl; - } - if (done || borrowed) { - - if (borrowed) { - paths = pathStore; - pathStore.clear(); - } - //std::cout << "paths.size(): " << paths.size() << std::endl; - if (paths.size() != 0) { - } - else { - return loopPaths; - } - - // #pragma omp parallel - // { - #pragma omp parallel for schedule(guided) - for (unsigned int qqq = 0; qqq < paths.size(); qqq++) { - // std::cout << "pathcheck" << std::endl; - //int pathevals = 0; - //std::vector zpt = zipPath2(paths[qqq], g); - //std::set > boxpaths; - std::set > movepaths; - std::vector path;// = paths[qqq]; - path = paths[qqq];//unzipPath(paths[qqq], g, begin, end); - truepaths++; - int permnums = 1; - std::vector perms; - std::vector qs; - std::map > > localLoops; - std::vector takenLoops; - takenLoops.push_back(path[0]); - bool taken = false; - //timeval timfor; - int lost = 0; - //gettimeofday(&timfor, NULL); - //double t1for = timfor.tv_sec + (timfor.tv_usec/1000000); - for (unsigned int q = 1; q < path.size()-1; q++) { - //if (find(closures.begin(), closures.end(), path[q]) != closures.end()) { - if (globalLoopPaths.find(path[q]) != globalLoopPaths.end() /*&& find(lloops.begin(), lloops.end(), path[q]) != lloops.end()*/ && globalLoopPaths[path[q]].size() != 0 /*&& path[q] != begin && path[q] != end*/) { - for (unsigned int qp1 = 0; qp1 < globalLoopPaths[path[q]].size(); qp1++) { - - std::vector gp = globalLoopPaths[path[q]][qp1]; //unzipPath(globalLoopPaths[path[q]][qp1],g,path[q],path[q]); - // std::vector zgp = zipPath2(globalLoopPaths[zpt[q]][qp1], g); - for (unsigned int qp2 = 0; qp2 < takenLoops.size(); qp2++) { - if (find(gp.begin(),gp.end(), takenLoops[qp2]) != gp.end()) { - taken = true; - } - } - - if (!taken) { - localLoops[path[q]].push_back(gp); - } - else { - lost++; - taken = false; - } - } - if (localLoops[path[q]].size() != 0) { - takenLoops.push_back(path[q]); - permnums *= (localLoops[path[q]].size()+1); - perms.push_back(permnums); - qs.push_back(path[q]); - } - } - } - - //} - //if (loop) { - //std::cout << "lostloop: " << lost << std::endl; - //} - //else { - //std::cout << "lostpath: " << lost << std::endl; - //} - //std::cout << "endpathcheck" << std::endl; - //std::cout << "rest" << std::endl; - //std::cout << "permnums: " << permnums << std::endl; - //gettimeofday(&timfor, NULL); - //double t2for = timfor.tv_sec + (timfor.tv_usec/1000000); - //double ttfor = t2for - t1for; - //#pragma omp atomic - //ttfors += ttfor; - - //std::set > movepaths2; - std::set > movepathscheck; - //timeval timperms; - //gettimeofday(&timperms, NULL); - // double t1perm = timperms.tv_sec + (timperms.tv_usec/1000000); - std::vector nvec; - std::vector > boxpaths(permnums, nvec); - //#pragma omp parallel for schedule(guided) - for (int i = 1; i <= permnums; i++) { - //bool goodthread = false; - std::vector loopsTaken; - //bool stop = false; - unsigned int j = 0; - std::vector npath; - while (true) { - if (j == perms.size() || perms[j] > i) { - break; - } - else { - j++; - } - } - int pn = i; - std::vector pL; - for (unsigned int j1 = 0; j1 <= j; j1++) { - pL.push_back(-1); - } - for (unsigned int k = j; k > 0; k--) { - int l = 1; - while (perms[k-1]*l < pn) { - l++; - } - pL[k] = l-2; - pn -= (perms[k-1]*(l-1)); - } - pL[0] = pn-2; - - unsigned int q2 = 0; - for (unsigned int q1 = 0; q1 < path.size(); q1++) { - if (q2 < qs.size()) { - if (qs.size() != 0 && (unsigned)path[q1] == qs[q2] && (size_t)q2 != pL.size()) { - if (pL[q2] == -1) { - npath.push_back(path[q1]); - } - else { - // if (!stop) { - npath.insert(npath.end(), localLoops[path[q1]][pL[q2]].begin(), - localLoops[path[q1]][pL[q2]].end()); - // } - } - q2++; - } - else { - npath.push_back(path[q1]); - } - } - else { - npath.push_back(path[q1]); - } - } - #ifdef FULLDEBUG - std::cout << "path: " << std::endl; - for (int qe = 0; qe < npath.size(); qe++) { - std::cout << ", " << npath[qe]; - } - std::cout << std::endl; - std::cout << "permnum: " << i << std::endl; - #endif - // bool addit = false; - //if (!stop) { - // if (loop && npath.front() == npath.back()) { - // addit = true; - // } - // else if (!loop && bound && npath.front() == begin && npath.back() == end && npath.size() != 1) { - // addit = true; - // } - // else if (!loop && !bound) { - // addit = true; - // } - // if (!addit) { - // std::cout << "bad path" << std::endl; - // } - //bool extra = false; - //if (addit && !loop) { - //if (movepathscheck.find(npath) == movepathscheck.end()) { - //int mpc = movepathscheck.size(); - //std::set > movepathspre = movepathscheck; - // movepaths2.insert(npath); - //movepathscheck.insert(npath); - //ROSE_ASSERT(movepathscheck.size() == mpc || movepathspre.find(npath) == movepathspre.end()); - //if (movepathscheck.size() == mpc) { - // extra = true; - // } - - //} - //else { - //#pragma omp atomic - // doubledpaths++; - // } - //} - - //if (!workingthread || threadsafe) { - //if ((newpaths.size() > 1 || i == permnums || threadsafe)) { - // } - // } - - // } - //if (!extra) - // { - //if (movepaths2.size() > 0) //|| i == permnums || threadsafe) - // #pragma omp critical - // { - boxpaths[i-1] = npath; - // } - // } - //std::cout << "endrest" << std::endl; - } - - evaledpaths += boxpaths.size(); - if (evaledpaths > newmil*100000ull) { - //std::cout << "evaledpaths: " << evaledpaths << std::endl; - newmil++; - } - // #pragma omp critical - // { - if (!loop) { - for (std::vector >::iterator box = boxpaths.begin(); box != boxpaths.end(); box++) { - std::vector verts; - getVertexPath((*box), g, verts); - #pragma omp critical - { - analyzePath(verts); - } - } - } - else { - #pragma omp critical - { - loopPaths.insert(boxpaths.begin(), boxpaths.end());; - } - } - } - } - //} - -/* - #pragma omp atomic - evaledpaths++; - //pathevals++; - if (evaledpaths % 10000 == 0 && evaledpaths != 0) { - std::cout << "evaled paths: " << evaledpaths << std::endl; - } - if (!loop) { - std::vector verts; - getVertexPath(npath, g, verts); - #pragma omp critical - { - #ifdef FULLDEBUG - for (unsigned int aa = 0; aa < npath.size(); aa++) { - if (ptsNum.find(npath[aa]) != ptsNum.end()) { - ptsNum[npath[aa]] += 1; - } - else { - ptsNum[npath[aa]] = 1; - } - } - #endif - analyzePath(verts); - } - } - else if (loop) - { - //std::vector zpth = zipPath(npath, g, npath.front(), npath.back()); - #pragma omp critical - { - loopPaths.insert(npath);//zipPath(npath, g, npath.front(), npath.back())); - } - } - else { - } - - } -*/ - - // movepaths2.clear(); - - // std::cout << "permnums: " << permnums << std::endl; - // std::cout << "evaledpaths final: " << pathevals << std::endl; - //gettimeofday(&timperms, NULL); - //double t2perm = timperms.tv_sec+(timperms.tv_usec/1000000); - //#pragma omp atomic - //tperms += t2perm - t1perm; - // } - //} - //} - //} - - - - - - - #ifdef PERFDEBUG - //gettimeofday(&tim, NULL); - // double t2 = tim.tv_sec+(tim.tv_usec/1000000.0); - // double tperm = t2 - t1perm - //double tX = t2 - t1; - //std::cout << "begin: " << begin << " end: " << end << std::endl; - // std::cout << "uTraverse time: " << tX << std::endl; - // std::cout << "tperms: " << tperms << std::endl; - // std::cout << "ttfors: " << ttfors << std::endl; - // std::cout << "doubledpaths: " << doubledpaths << std::endl; - #endif - #ifdef LP - if (loop) { - #ifdef PERFDEBUG - // std::cout << "loopPaths: " << loopPaths.size() << std::endl; - #endif - loopStore[begin] = loopPaths; - } - #endif - return loopPaths; - - } - } - - - - - - - - -/** -This is the function that is used by the user directly to start the algorithm. It is immediately available to the user - -SgGraphTraversal::constructPathAnalyzer -Input: -@param[begin] Vertex, starting node -@param[end] Vertex, endnode -@param[g] CFG* g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -constructPathAnalyzer(CFG* g, bool unbounded, Vertex begin, Vertex end, bool ns) { - abnormals = 0; - normals = 0; - if (ns) { - needssafety = true; - } - else { - needssafety = false; - } - checkedfound = 0; - recursed = 0; - nextsubpath = 0; - borrowed = true; - stoppedpaths = 0; - evaledpaths = 0; - badpaths = 0; - sourcenum = 0; - prepareGraph(g); - workingthread = false; - workingthreadnum = -1; - //std::cout << "markers: " << markers.size() << std::endl; - //std::cout << "closures: " << closures.size() << std::endl; - //std::cout << "sources: " << sources.size() << std::endl; - //std::cout << "sinks" << sinks.size() << std::endl; -// printHotness(g); - bool subgraph = false; - if (!subgraph) { - if (!unbounded) { - bound = true; - recursiveLoops.clear(); - recurses.clear(); - std::vector > spaths = bfsTraversePath(vertintmap[begin], vertintmap[end], g); - // std::cout << "spaths: " << spaths.size() << std::endl; - } - else { - std::set usedsources; - bound = false; - std::vector localLps; - for (unsigned int j = 0; j < sources.size(); j++) { - sourcenum = sources[j]; - recursiveLoops.clear(); - recurses.clear(); - std::vector > spaths = bfsTraversePath(sources[j], -1, g); - - - } - } - } - //std::cout << "checkedfound: " << checkedfound << std::endl; - printHotness(g); -} - -/** DEPRECATED -This is a function to construct subgraphs for parallelization -SgGraphTraversal::computeSubGraphs -Input: -@param[begin] const int, starting point -@param[end] const int ending point -@param[g] const CFG*, control flow graph to compute -@param[depthDifferential] int, used to specify how large the subgraph should be - */ - -template -void -SgGraphTraversal:: -computeSubGraphs(const int& begin, const int &end, CFG*& g, int depthDifferential) { - int minDepth = 0; - int maxDepth = minDepth + depthDifferential; - int currSubGraph = 0; - CFG* subGraph; - std::set foundNodes; - while (true) { - Vertex begin = boost::add_vertex(*subGraphVector[currSubGraph]); - GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[minDepth]]] = intvertmap[begin]; - SubGraphGraphMap[currSubGraph][intvertmap[begin]] = intvertmap[orderOfNodes[minDepth]]; - for (int i = minDepth; i <= maxDepth; i++) { - Vertex v = GraphSubGraphMap[currSubGraph][intvertmap[orderOfNodes[i]]]; - std::vector outEdges = getOutEdges(orderOfNodes[i], g); - for (unsigned int j = 0; j < outEdges.size(); j++) { - Vertex u; - if (foundNodes.find(getTarget(outEdges[j], g)) == foundNodes.end()) { - u = GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]]; - } - else { - u = boost::add_vertex(*subGraphVector[currSubGraph]); - foundNodes.insert(getTarget(outEdges[j], g)); - SubGraphGraphMap[currSubGraph][u] = intvertmap[getTarget(outEdges[j], g)]; - GraphSubGraphMap[currSubGraph][intvertmap[getTarget(outEdges[j], g)]] = u; - - } - Edge edge; - bool ok; - boost::tie(edge, ok) = boost::add_edge(v,u,*subGraphVector[currSubGraph]); - } - } - minDepth = maxDepth; - if ((unsigned int) minDepth == orderOfNodes.size()-1) { - break; - } - maxDepth += depthDifferential; - if ((unsigned int) maxDepth > orderOfNodes.size()-1) - { - maxDepth = orderOfNodes.size()-1; - } - CFG* newSubGraph; - subGraphVector.push_back(newSubGraph); - currSubGraph++; - } - return; -} - - -/* -These should NOT be used by the user. They are simply for writing interesting information on the DOT graphs of the CFG -*/ - - - - template - void - SgGraphTraversal:: - printCFGNodeGeneric(int &cf, std::string prop, std::ofstream& o) { - std::string nodeColor = "black"; - o << cf << " [label=\"" << " num:" << cf << " prop: " << prop << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - } - - template - void - SgGraphTraversal:: - printCFGNode(int& cf, std::ofstream& o) - { - #ifdef FULLDEBUG - int pts = ptsNum[cf]; - std::string nodeColor = "black"; - o << cf << " [label=\"" << " pts: " << pts << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - #endif - #ifndef FULLDEBUG - std::string nodeColor = "black"; - o << cf << " [label=\"" << " num:" << cf << "\", color=\"" << nodeColor << "\", style=\"" << "solid" << "\"];\n"; - #endif - - } - - template - void - SgGraphTraversal:: - printCFGEdge(int& cf, CFG*& cfg, std::ofstream& o) - { - int src = getSource(cf, cfg); - int tar = getTarget(cf, cfg); - o << src << " -> " << tar << " [label=\"" << src << " " << tar << "\", style=\"" << "solid" << "\"];\n"; - } - - template - void - SgGraphTraversal:: - printHotness(CFG*& g) - { - const CFG* gc = g; - int currhot = 0; - std::ofstream mf; - std::stringstream filenam; - filenam << "hotness" << currhot << ".dot"; - currhot++; - std::string fn = filenam.str(); - mf.open(fn.c_str()); - - mf << "digraph defaultName { \n"; - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v, vend; - edge_iterator e, eend; -#else - // This does not compile. - vertex_iterator v = vertices(*gc).begin(); - vertex_iterator vend = v; - edge_iterator e = edges(*gc).begin(); - edge_iterator eend = e; -#endif - for (boost::tie(v, vend) = vertices(*gc); v != vend; ++v) - { - printCFGNode(vertintmap[*v], mf); - } - for (tie(e, eend) = edges(*gc); e != eend; ++e) - { - printCFGEdge(edgeintmap[*e], g, mf); - } - mf.close(); - } - template - void - SgGraphTraversal:: - printPathDot(CFG*& g) - { - const CFG* gc = g; - std::ofstream mf; - std::stringstream filenam; - filenam << "pathnums.dot"; - std::string fn = filenam.str(); - mf.open(fn.c_str()); - - mf << "digraph defaultName { \n"; - vertex_iterator v, vend; - edge_iterator e, eend; - for (tie(v, vend) = vertices(*gc); v != vend; ++v) - { - if (nodeStrings.find(vertintmap[*v]) != nodeStrings.end()) { - int nn = vertintmap[*v]; - printCFGNodeGeneric(vertintmap[*v], nodeStrings[nn], mf); - } - else { - printCFGNodeGeneric(vertintmap[*v], "noprop", mf); - } - } - for (tie(e, eend) = edges(*gc); e != eend; ++e) - { - printCFGEdge(edgeintmap[*e], g, mf); - } - - mf.close(); - } - - - -/** -This is the function that preps the graph for traversal - -SgGraphTraversal::prepareGraph -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -prepareGraph(CFG*& g) { - nextNode = 1; - nextEdge = 1; - findClosuresAndMarkersAndEnumerate(g); -} - - -/** -DEPRECATED -This is the function that preps the graph for traversal, currently this one isn't used but for many traversals on one visitor -may necessitate - -SgGraphTraversal::firstPrepGraph -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - -template -void -SgGraphTraversal:: -firstPrepGraph(CFG*& g) { - nextNode = 1; - nextEdge = 1; - findClosuresAndMarkersAndEnumerate(g); -} - -/** -This calculates nodes with more than one in edge or more than one out edge - -SgGraphTraversal::findClosuresAndMarkers -Input: -@param[g] CFG*& g, CFG calculated previously -*/ - - - - -template -void -SgGraphTraversal:: -findClosuresAndMarkersAndEnumerate(CFG*& g) -{ - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - edge_iterator e, eend; -#else - edge_iterator e = edges(*g).begin(); - edge_iterator eend = e; -#endif - for (tie(e, eend) = edges(*g); e != eend; ++e) { - intedgemap[nextEdge] = *e; - edgeintmap[*e] = nextEdge; - nextEdge++; - } - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v1, vend1; -#else - vertex_iterator v1 = vertices(*g).begin(); - vertex_iterator vend1 = v1; -#endif - for (boost::tie(v1, vend1) = vertices(*g); v1 != vend1; ++v1) - { - vertintmap[*v1] = nextNode; - intvertmap[nextNode] = *v1; - nextNode++; - } - // DQ (4/11/2017): Fix Klockworks issue of uninitialized variables. -#if 1 - vertex_iterator v, vend; -#else - vertex_iterator v = vertices(*g).begin(); - vertex_iterator vend = v; -#endif - for (boost::tie(v, vend) = vertices(*g); v != vend; ++v) { - std::vector outs = getOutEdges(vertintmap[*v], g); - std::vector ins = getInEdges(vertintmap[*v], g); - if (outs.size() > 1) - { - markers.push_back(vertintmap[*v]); - - markerIndex[vertintmap[*v]] = markers.size()-1; - for (unsigned int i = 0; i < outs.size(); i++) { - pathsAtMarkers[vertintmap[*v]].push_back(getTarget(outs[i], g)); - } - } - if (ins.size() > 1) - { - closures.push_back(vertintmap[*v]); - } - if (outs.size() == 0) { - sinks.push_back(vertintmap[*v]); - } - if (ins.size() == 0) { - sources.push_back(vertintmap[*v]); - } - } - return; -} - - - -/** DEPRECATED -Currently unused but will be necessary for parallelization in progress -SgGraphTraversal::computeOrder -@param[g] CFG* cfg in question -@parm[begin] const int, integer representation of source node -*/ -template -void -SgGraphTraversal:: -computeOrder(CFG*& g, const int& begin) { - std::vector currentNodes; - std::vector newCurrentNodes; - currentNodes.push_back(begin); - std::map reverseCurrents; - orderOfNodes.push_back(begin); - std::set heldBackNodes; - while (currentNodes.size() != 0) { - for (unsigned int j = 0; j < currentNodes.size(); j++) { - - std::vector inEdges = getInEdges(currentNodes[j], g); - if (inEdges.size() > 1) { - if (reverseCurrents.find(currentNodes[j]) == reverseCurrents.end()) { - reverseCurrents[currentNodes[j]] = 0; - } - if ((unsigned int) reverseCurrents[currentNodes[j]] == inEdges.size() - 1) { - heldBackNodes.erase(currentNodes[j]); - reverseCurrents[currentNodes[j]]++; - std::vector outEdges = getOutEdges(currentNodes[j], g); - for (unsigned int k = 0; k < outEdges.size(); k++) { - newCurrentNodes.push_back(getTarget(outEdges[k], g)); - orderOfNodes.push_back(getTarget(outEdges[k], g)); - } - } - else if (reverseCurrents[currentNodes[j]] < reverseCurrents.size()) { - reverseCurrents[currentNodes[j]]++; - if (heldBackNodes.find(currentNodes[j]) == heldBackNodes.end()) { - heldBackNodes.insert(currentNodes[j]); - } - } - } - else { - std::vector outEdges = getOutEdges(currentNodes[j], g); - for (unsigned int k = 0; k < outEdges.size(); k++) { - newCurrentNodes.push_back(getTarget(outEdges[k], g)); - orderOfNodes.push_back(getTarget(outEdges[k], g)); - - } - } - } - if (newCurrentNodes.size() == 0 && heldBackNodes.size() != 0) { - for (std::set::iterator q = heldBackNodes.begin(); q != heldBackNodes.end(); q++) { - int qint = *q; - std::vector heldBackOutEdges = getOutEdges(qint, g); - for (unsigned int p = 0; p < heldBackOutEdges.size(); p++) { - newCurrentNodes.push_back(getTarget(heldBackOutEdges[p], g)); - } - } - heldBackNodes.clear(); - } - currentNodes = newCurrentNodes; - newCurrentNodes.clear(); - } - return; -} - -/** -Converts the path calculated by this algorithm to Vertices so users can -access data -SgGraphTraversal::getVertexPath -@param[path] integer representation of path -@param[g] CFG*, cfg in question -@param[vertexPath] for some reason this can't be a return value so it is changed via pass by reference -*/ - -template -void -SgGraphTraversal:: -getVertexPath(std::vector path, CFG*& g, std::vector& vertexPath) { - for (unsigned int i = 0; i < path.size(); i++) { - vertexPath.push_back(intvertmap[path[i]]); - } - - - -} - -/** -DEPRECATED -Currently unused, may eventually be modified for optimal storage purposes -SgGraphTraversal::storeCompact -@param[compactPath] path to be compactified -*/ -template -void -SgGraphTraversal:: -storeCompact(std::vector compactPath) { -return; -} - - - - - diff --git a/src/midend/astProcessing/graphProcessingSgIncGraph.h b/src/midend/astProcessing/graphProcessingSgIncGraph.h deleted file mode 100644 index 382dc09079d..00000000000 --- a/src/midend/astProcessing/graphProcessingSgIncGraph.h +++ /dev/null @@ -1,1865 +0,0 @@ -/* - -FINISH TEMPFLATPATH CODE - -*/ - - - - -// Original Author (SgGraphTraversal mechanisms): Michael Hoffman -//$id$ -#include -#include -#include -#include -#include - -/** -*@file graphProcessing.h - -*Brief Overview of Algorithm: - -*********************** -*Current Implementation -*********************** - -*The idea behind the algorithm here is to decompose the given Control Flow Graph into a Tree structure (still stored as a Control Flow Graph, though it may be possible to change this). This tree splits on children of a graph node, but does not connect in the case of multiple parents of a single node. In this we refer to out nodes as "children" and in nodes as "parents". However, we do this from the end node to the start node. This is best because then you get one value on the end node, and that value is the only one we want (however, the function takes a pointer to an empty SgIncidenceDirectedGraph as an argument, this can then be analyzed post traversal if that is wanted. - -*Also, following the algorithm explained above, one must realize that the tree has one leaf for EACH path. Thus small programs can lead from a small-ish graph to a VERY large tree. For example, a program with 20 if else statements would end with 2^20 paths, which means the number of nodes in the tree is greater than this. Thus with 32 or 64 you can overflow a 32 or 64 bit integer. - -*However, this can be partially resolved by setting the deleteTree boolean to true. This is set to false as the default, however if you don't need the tree then deleteTree will allow you to deal with much larger trees and thus much larger original graphs. - -*Realize that because of the potentially massive growth rate of path number, that in large cases path enumeration and counting is extremely prohibitive, as it is not difficult to create a program which has more paths than 2^64, thus an unsigned (signed?) 64 bit integer could not store the number. - -*Further, this is still a relatively compact method. You could just as easily force enumeration of paths, which could in some cases drastically increase the number of nodes necessary to store all the information. - -*The advantage of the tree structure is two-fold. First it relieves the algorithm of having to keep even more in memory than it has to at the moment, and if you want to deal with GoTo statements, one case can develop that cannot be solved otherwise, e.g. - -*Consider the four node tree with nodes a, b, c, d, and edges atb, atc, btc, ctb, btd, ctd. There are FOUR legitimate paths here (a, b, d; a, b, c, d; a, c, d; a, c, b, d), and any other method would recognize this as a loop and, without a special algorithm for loop behavior, this would be ignored. - -*The tree structure also allows for very strong parallelization, currently implemented in openMP. This is because depth has meaning in terms of a tree (it doesn't in terms of a general graph) and that you know you can evaluate all nodes at a certain depth if you have solved all the nodes at depth + 1. - -************************** -*Further Improvements: TODO -************************** - -@todo *One improvement that should be implemented ASAP is changing the algorithm from a recursive algorithm to an iterative algorithm. Keeping the memory requirements down is much easier in this form and would probably increase the size of graph that the algorithm can handle. - -@todo *Another improvement that should be implemented when possible is to allow for loop analysis. This could be implemented by simply running the algorithm on the loop, but there would need to be a provision that kept the algorithm from stopping as soon as it starts. This could be done by separating the node into two nodes, one with all the inedges and one with all the outedges. OR one could collect the loops when they are deleted (the whole loop is calculated necessarily), though nested loops would have to be considered further in order to find a way to deal with them. - -@todo *It is possible that graph matching algorithms might prove useful to distinguish different types of graphs contained within the CFG and optimize traversal over them. Look up graph matching algorithms or pattern matching (potentially) for more information on such algorithms, though I do not believe there is an existant literature on matching subgraphs for this purpose. - -@todo *The parallelism in this program should be optimized by someone experienced in parallelization optimization - -*************** -*Contact Info -*************** - -*Finally, blame can be assigned to and questions can be forwarded to the author, though response is not guaranteed - -*archangel DOT associate AT gmail DOT com -*or, if I'm still at Lawrence -*hoffman34 AT llnl DOT gov -*@author Michael Hoffman -*/ - - - - - -#include "staticCFG.h" -#include -#include -#include -#include -#include -#include -//#include "graphBot.h" - -//This is necessary for technical reasons with regards to the graphnodeinheritedmap - - - -struct Bot { - std::vector > path; - std::vector > pthloops; - std::vector currpth; - std::vector > nodelst; - bool on; - bool remove; -}; - -double timeDifference(const struct timeval& end, const struct timeval& begin) -{ - return (end.tv_sec + end.tv_usec / 1.0e6) - (begin.tv_sec + begin.tv_usec / 1.0e6); -} - -static inline timeval getCPUTime() { - rusage ru; - getrusage(RUSAGE_SELF, &ru); - return ru.ru_utime; -} - - -struct compareSgGraphNode { - bool operator()(const SgGraphNode* a, const SgGraphNode* b) const - { - return a==b; - } -}; - - -/* The SgGraphTraversal class is utilized specifically for StaticCFG traversals, -though the input must be in terms of a SgIncidenceDirectedGraph*/ -template -class SgGraphTraversal -{ - public: - std::set > > subpathmap; - int loopNum; - int nullNum; - std::set nullEdgesOrdered; - std::map loopNumMap; - std::map pathValMap; - int nullloops; - std::vector > looppaths; - std::vector > iLoops; - std::vector ifstatements; - virtual ~SgGraphTraversal(); - SgGraphTraversal(); - // Copy operations - int nullEdgesPaths; - int turns; - SgGraphTraversal(const SgGraphTraversal &); - const SgGraphTraversal &operator=(const SgGraphTraversal &); - //This is not used, but will be important if SynthesizedAttributes become useful - typedef StackFrameVector SynthesizedAttributesList; - //one of the most important structures in the algorithm, this attaches SgGraphNode*s to InheritedAttributeTypes so that - //looking up the values is possible. - //int numnodes; - //std::map seen; - int numnodes; - //InheritedAttributeType pthgraphinherit; - //StaticCFG::CFG* SgCFG; - SgGraphNode* nullnode; - std::map primenode; - bool done; - //std::set startnodes; - std::set lstN; - std::map > > lstordmap; - std::set solvedLoops; - std::map > checkednodes; - std::map > downed; - - //std::map nodeinedgordmap; - //a value for nodes that have no value, set in the traverse function - InheritedAttributeType nullInherit; - //the user invoked function, runs the algorithm - InheritedAttributeType traverse(SgGraphNode* basenode, SgIncidenceDirectedGraph* g, - InheritedAttributeType inheritedValue, InheritedAttributeType nullInherit, - SgGraphNode* endnode, bool insep = false, bool pcHk = false); - std::set loopSet; - - protected: - //User defined functions to do whatever is needed in evaluation - //All the user gets access to is the node in question - //and the values of the parent nodes (this should be all that is necessary) - virtual InheritedAttributeType evaluateInheritedAttribute(SgGraphNode* n, - std::vector inheritedValues) = 0; - //Not used, but may be useful if SynthesizedAttributes become workable in this context - virtual SynthesizedAttributeType evaluateSynthesizedAttribute(SgGraphNode* n, - InheritedAttributeType in, - SynthesizedAttributesList l) = 0; - -#if !USE_ROSE - // DQ (11/3/2011): EDG compilains about this (but GNU allowed it, I think that EDG might be correct, - // namely that the value of a reference must be an lvalue (not NULL). But since we are only trying - // to compile ROSE with ROSE (using the new EDG 4.3 front-end as a tests) we can just skip this case for now. - virtual void pathAnalyze(std::vector& pth, bool loop=false, std::set >& incloops=NULL) = 0; -#else - virtual void pathAnalyze(std::vector& pth, bool loop, std::set >& incloops) = 0; -#endif - - //also not used, but important for possible later use of SynthesizedAttributes - SynthesizedAttributeType defaultSynthesizedAttribute(InheritedAttributeType); - private: - double distime; - //std::set, std::pair > > flpset; - //std::set, std::pair > > goodset; - std::set ploops; - std::map > > lpbegins; - std::map frksLeft; - int currm; - int dpMax; - int repEval; - bool pathCheck; - int pathsSize; - //this constructs the graph tree for computation of inheritedValues - - - std::map known; - std::vector connectNodes; - std::map solved; - std::set solvedset; - //these two are not used, but will be important if SynthesizedAttributes are made reasonable in this context - SynthesizedAttributesList *synthesizedAttributes; - SynthesizedAttributeType traversalResult(); - //finally we have two functions necessary for parallel processing if that is chosen to be used by the user - - - - - std::map nodeInEdgesNum; - int currprime; - std::vector endnodefakes; - std::map > > pathsAtMk; - std::set mkloops; - std::map > > mkloopmap; - std::map > > subPathsAtMk; - std::vector mkglobal; - std::vector clglobal; - bool inseparable; - void solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); - std::vector > closuresVec; - void evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); - void evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode); - bool disjoint(std::vector& path, std::vector& vec2) const; - std::set > flatpaths; -// void evalNode(SgIncidenceDirectedGraph* g, SgGraphNode* n); - bool canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::map inhVals; - std::set seenEdges; - std::set nullEdges; - std::set clsT; - void computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode); - void computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::pair getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::pair getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n); - bool computable(SgIncidenceDirectedGraph* g, SgGraphNode* n); - void evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n); - std::map oVals; - bool canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n); - void setPathVal(SgIncidenceDirectedGraph*g, SgGraphNode* n); - void printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss); - void printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss); - void printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream& ss); - std::set completedNodesPath; - std::set > completedEdgesPath; - void printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream& ss); - void printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream& ss); - std::map iVals; - - std::set nullEdgesOrderedOut; - std::set completedEdgesOut; - std::set completedEdges; - std::set compPar; - std::set compChild; - std::set computedNodes; - SgGraphNode* st; - SgGraphNode* en; - double fllp; - int loopnum; - //std::set solved; - //InheritedAttributeType findAndReverse(SgGraphNode* n, SgIncidenceDirectedGraph* g); - //evaluateAllInheritedAttribute(std::vector endNodeInhVec, SgGraphNode* endnode, std::vector nodes, std::vector inh); -//std::vector getZeroInhs(std::vector > > qAnsSetSet, std::vector endnodeInhVec, SgGraphNode* node); - -}; - - - -/* -template -void -GraphBot:: -travelDown(SgIncidenceDirectedGraph* g) { - std::set oedgs = g->computeEdgeSetOut(iAmHere); - bool taken = false; - if (oedgs.size() > 1) { - std::set edgeTrav = clEdgeTrav[iAmHere]; - ROSE_ASSERT(clEdgeTrav.find(iAmHere) != clEdgeTrav.end()); - for (std::set::iterator i = oedgs.begin(); i != oedgs.end(); i++) { - if (edgTrav.find(*i) == edgTrav.end() || !taken) { - taken = true; - iAmHere = (*i)->get_to(); - lastEdge = *i; - } - } - } - else { - iAmHere = (*(oedgs.begin())->get_to(); - } -} -*/ - - - - - - -/* -*************************** -Various Admin Functions -*************************** -*/ -template -SgGraphTraversal:: -SgGraphTraversal() - : synthesizedAttributes(new SynthesizedAttributesList()) -{ -} - -#ifndef SWIG - -template -SgGraphTraversal:: -~SgGraphTraversal() -{ - ROSE_ASSERT(synthesizedAttributes != NULL); - delete synthesizedAttributes; - synthesizedAttributes = NULL; -} - -#endif - - -template -const SgGraphTraversal & -SgGraphTraversal:: -operator=(const SgGraphTraversal &other) -{ - - ROSE_ASSERT(synthesizedAttributes != NULL); - delete synthesizedAttributes; - synthesizedAttributes = other.synthesizedAttributes->deepCopy(); - - return *this; -} - -/** -This is the function that is used by the user directly to start the algorithm. It is immediately available to the user - -SgGraphTraversal::traverse -Input: -@param[n] n starting node -@param[g] SgIncidenceDirectedGraph* g, CFG calculated previously -@param[inheritedValue] InheritedAttributeType inheritedValue, value of the starting node -@param[nullI] InheritedAttributeType nullI, value of the null Attribute, i.e. what to attribute to a node with no value\ -@param[endnode] SgGraphNode* endnode, final node -@param[insep] boolean to decide inseparability of the analysis function, not yet in use, set automatically to false -@param[pCh] deprecated, set to false -@return InheritedAttributeType, the value of the attribute at the end node - -*/ - - -template -InheritedAttributeType -SgGraphTraversal:: -traverse(SgGraphNode* n, SgIncidenceDirectedGraph* g, InheritedAttributeType inheritedValue, InheritedAttributeType nullI, SgGraphNode* endnode, bool insep, bool pCh) { - //numnodes = 0; - //primes.clear(); - looppaths.clear(); - iLoops.clear(); - completedEdgesPath.clear(); - pathValMap.clear(); - loopNumMap.clear(); - nullloops = 0; - nullEdgesPaths = 0; - fllp = 0.0; - mkglobal.clear(); - clglobal.clear(); - - lpbegins.clear(); - //currents.clear(); - inhVals.clear(); - iVals.clear(); - oVals.clear(); - //reservedEdges.clear(); - completedEdges.clear(); - completedEdgesOut.clear(); - //completedNodes.clear(); - computedNodes.clear(); - nullEdgesOrdered.clear(); - nullEdgesOrderedOut.clear(); - loopSet.clear(); - pathsAtMk.clear(); - - st = n; - en = endnode; - distime = 0.0; - int currm = 1; - int turns = 0; - pathsSize = 0; - done = false; - numnodes = 1; - std::cout << "starting traversal" << std::endl; - pathCheck = pCh; - currprime = 1; - inseparable = insep; - synthesizedAttributes->resetStack(); - ROSE_ASSERT(synthesizedAttributes->debugSize() == 0); - //SgCFG = cfg; - inhVals[n] = inheritedValue; - //GraphBot::inhVals[n] = inheritedValue; - //primes = generatePrimesSieve(); - - -// graphnodeinheritedordmap[ncpy] = inheritedValue; -// nodenodeordmap[ncpy] = n; -// std::vector lst; -// lst.push_back(n); -// lstordmap[ncpy] = lst; - - nullInherit = nullI; -InheritedAttributeType inh; - struct timeval t1, t2, t3, t4, t5, t6, t7, t8; - //else { - loopnum = 0; - //InheritedAttributeType inh; - t1 = getCPUTime(); - - //this function essentially sets up for the evaluate later, it makes putting together the paths much easier - solvePaths(g, n, endnode); - - t2 = getCPUTime(); - -//making sure that endnode hasn't already been evaluated before the traversal starts, unlikely but just in case - ROSE_ASSERT(inhVals.find(endnode) == inhVals.end()); - - std::cout << "solvePaths done" << std::endl; - double diff = timeDifference(t2, t1); - t5 = getCPUTime(); - //InheritedAttributeType pthgraphinherit = botTraverse(g, n, endnode); - oVals[n] = 0; - iVals[0] = n; - pathValMap[n] = 1; -//inserting n as a computed node - computedNodes.insert(n); -//computes the order in which the nodes must be evaluated, makes computeInheritedOrdered much faster - computeOrder(g, n, endnode); - std::cout << "order computed" << std::endl; -//computes the nodal inheritance values - computeInheritedOrdered(g, n); - std::cout << "inheritance computed" << std::endl; - ROSE_ASSERT(oVals.find(endnode) != oVals.end()); - ROSE_ASSERT(inhVals.find(endnode) != inhVals.end()); -//value at the endnode - InheritedAttributeType pthgraphinherit = inhVals[endnode]; - //= evaluateGraph(g, n, endnode, inheritedValue); - t6 = getCPUTime(); - std::cout << "evaluateGraph done" << std::endl; - double diff3 = timeDifference(t6, t5); - t3 = getCPUTime(); -//actually evaluates every path with a user defined pathAnalyze function - //for (int i = 0; i < 10; i++) { - evaluatePaths(g, n, endnode); - //} - t4 = getCPUTime(); - - t7 = getCPUTime(); - //evaluatePathsPar(g, n, endnode); - t8 = getCPUTime(); - - std::cout << "evaluatePaths done " << std::endl; - double diff2 = timeDifference(t4, t3); - double diff2Par = timeDifference(t8, t7); - std::cout << "pathsolve took: " << diff << std::endl; - std::cout << "patheval took: " << diff2 << std::endl; - std::cout << "parpatheval took: " << diff2Par << std::endl; - std::cout << "grapheval took: " << diff3 << std::endl; - std::cout << "entire pathsolve took: " << diff+diff2+diff3+diff2Par << std::endl; - std::cout << "potential loops: " << nullEdgesOrdered.size() << std::endl; - std::cout << "nullNum: " << nullNum << std::endl; - //std::cout << "goodsets: " << goodset.size() << std::endl; - //std::cout << "flpsets: " << flpset.size() << std::endl; - std::cout << "mkloops: " << mkloops.size() << std::endl; - std::cout << "distime: " << distime << std::endl; - std::cout << "fllp: " << fllp << std::endl; - return pthgraphinherit; - //} - //std::cout << "number of endnodefakes: " << endnodefakes.size() << std::endl; - //std::cout << "should be number of nodes: " << currprime << std::endl; - //if (pathanalysis == true) { - // analyzepaths(endnode, g); - //} - //return inh; - //Currently this is not very useful, but it does nothing if traversalResult is not set. -} - -/* WARNING: - This is not a general is_disjoint. It skips the -first element of the second set because in the way I assemble -paths the last element of the path and the first element of addend -must be the same. Hence I simply skip the first node -*/ -bool is_disjoint(std::set set1, std::set set2) { - - if (set1.empty() || set2.empty()) { - return true; - } - std::set::iterator it1 = set1.begin(); - std::set::iterator it2 = set2.begin(); - std::set::iterator it1End = set1.end(); - std::set::iterator it2End = set2.end(); - - if (*it1 > *set2.rbegin() || *it2 > *set1.rbegin()) { - return true; - } - - while (it1 != it1End && it2 != it2End) { - if (*it1 == *it2) { - return false; - } - if (*it1 < *it2) { - it1++; - } - else { - it2++; - } - } - return true; -} - - - -//Checks for disjoint, necessary in computing the paths -template -bool -SgGraphTraversal:: -disjoint(std::vector& pthloops, std::vector& vec2) const { -/* - time_t t1, t2; - time(&t1); - int a = 0; - std::set s1; - std::set s2; - std::vector mkloopvec; - bool goodsetbool; - bool pbool = true; - //std::cout << "calculating disjoint" << std::endl; - ROSE_ASSERT((path.back()).back() == vec2.front()); - - //copy(vec2.begin(), vec2.end(), inserter(s2, s2.end())); -/* - for (int i = 0; i < vec2.size(); i++) { - if (ploops.find(vec2[i]) != ploops.end()) { - pbool = false; - } - } - if (pbool) { - return true; - } - if ( -*/ //for (int q = 0; q < pthloops->size(); q++) { - for (int i = 0; i < pthloops.size(); i++) { - if (find(vec2.begin(), vec2.end(), pthloops[i]) != vec2.end()) { - return false; - } - } - return true; -} -/* - if (pbool) { - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - return true; - } - for (unsigned int k = 0; k < path.size(); k++) { - s1.clear(); -*/ -/* - pbool = true; - for (int p = 0; p < path[k].size(); p++) { - if (ploops.find(path[k][p]) != ploops.end()) { - pbool = false; - } - } -// copy(path[k].begin(), path[k].end(), inserter(s1, s1.end())); - if (!pbool) { -*/ -/* - std::pair, std::pair > flp; - flp.second.first = vec2[0]; - flp.second.first = vec2[1]; - - flp.first.first = path[k][0]; - flp.first.second = path[k][1]; - if (vec2.front() == vec2.back()) { - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } - if (flpset.find(flp) != flpset.end()) { - //std::cout << "already seen" << std::endl; - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } -*/ -/* - else if (goodset.find(flp) != goodset.end()) { - goodsetbool = true; - } -*/ -/* - if (is_disjoint(s1,s2)) { - //goodset.insert(flp); - continue; - } - else { - return false; - } -*/ -/* - else { - std::vector vec1 = path[k]; - - //for (unsigned int i = 0; i < vec1.size(); i++) { - for (unsigned int j = 0; j < mkloopvec.size(); j++) { - std::vector::iterator q = find(vec1.begin(), vec1.end(), mkloopvec[j]); - if (q != vec1.end()) { - if (*q != vec1[vec1.size() - 1] || j != 0) { - - flpset.insert(flp); - // std::cout << "not disjoint" << std::endl; - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return false; - } - } - } - //} - //goodset.insert(flp); - } - } - //} -*/ - - -/* - for (unsigned int p = 0; p < vec2.size(); p++) { - for (unsigned int q = 0; q < vec2.size(); q++) { - if (p != q) { - if (vec2[p] == vec2[q]) { - return false; - } - } - } - } -*/ -/* - time(&t2); - double diff = difftime(t2, t1); - distime += diff; - - return true; -} -*/ -//checks for solvability of a node in nodal analysis - -template -bool -SgGraphTraversal:: -canSolve(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool loop = false; - if (inhVals.find(n) != inhVals.end()) { - return true; - } - std::set oed = g->computeEdgeSetIn(n); - if (oed.size() == 0) { - return false; - } - for (std::set::iterator i = oed.begin(); i != oed.end(); i++) { - if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdges.find(*i) == nullEdges.end()) { - return false; - } - } - return true; -} - -//this function evaluates values of paths via the user-defined pathAnalyze function - -template -void -SgGraphTraversal:: -evaluatePathsPar(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { -std::vector > path; -std::vector spath; -SgGraphNode* n = realstartnode; -int successes = 0; -int failures = 0; -int j = 0; -std::vector currpthorg; -int currint = 0; -std::map intPath; -intPath[n] = currint; -currint++; -std::map currents; -SgGraphNode* currnode; -bool step = false; -bool midstep = false; - -//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) - -std::vector > pth = pathsAtMk[realstartnode]; -std::vector > cpth = pathsAtMk[realstartnode]; - path.clear(); - int disjoints = 0; - int disjointtrues = 0; - currpthorg = pth[0]; - intPath[pth[0].front()] = currint; - std::set pthloopstmp; - SgGraphNode* fakenode; - pthloopstmp.insert(fakenode); - std::vector > pthloops; - pthloops.push_back(pthloopstmp); - pthloopstmp.clear(); - currint++; - - int stepnum = 0; - std::vector rs; - rs.push_back(realstartnode); - path.push_back(rs); - currents.clear(); - - step = false; - std::vector sub; - - - std::set > nullIncLoops; - std::vector todobotlst; - std::vector botlst; - struct Bot* rootBot = new Bot; - rootBot->remove = false; - - rootBot->path = path; - rootBot->currpth = currpthorg; - rootBot->pthloops = pthloops; - rootBot->on = true; - botlst.push_back(rootBot); - int tip = 1; - int ti = 1; - std::vector, std::vector > > > collectedPaths; - int maxlst = 0; - while (true) { - if (todobotlst.size()+botlst.size() > maxlst) { - maxlst = todobotlst.size()+botlst.size(); - std::cout << "maxlst: " << maxlst << std::endl; - std::cout << "todobotlst.size(): " << todobotlst.size() << std::endl; - std::cout << "botlst.size(): " << botlst.size() << std::endl; - } - int MAXBOTS = 10000; - int MINPATHS = 1000; - int LOCALMAXBOTS = 10; - int LOCALMAXNODES = 0; - std::vector lstnullbot; - std::vector > newbotlsts (MAXBOTS, lstnullbot); - //std::vector newbotlsts (MAXBOTS, lstnullbot); - //tip = ti; - //ti = 0; - ROSE_ASSERT(botlst.size() >= 0); - if (botlst.size() == 0) { - if (todobotlst.size() != 0) { - while (todobotlst.size() > 0 && botlst.size() < MAXBOTS) { - todobotlst.back()->on = true; - botlst.push_back(todobotlst.back()); - todobotlst.pop_back(); - } - } - else { - if (collectedPaths.size() > 0) { - for (int i = 0; i < collectedPaths.size(); i++) { - std::set > incloops; - std::vector > pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - collectedPaths.clear(); - } - break; - } - } - if (botlst.size() > 0) { - std::pair, std::vector > > nullpr; - std::vector, std::vector > > > newpathslst (MAXBOTS, nullpr); - #pragma omp parallel for - for (int i = 0; i < botlst.size(); i++) { - //std::map > > mkloopmaptmp = mkloopmap; - std::vector localbotlst; - std::pair, std::vector > > localnewpath; - struct Bot* currBot = botlst[i]; - if (currBot->on) { - std::vector currpth = currBot->currpth; - std::vector > path = currBot->path; - std::vector > pthloops = currBot->pthloops; - - if (currpth.back() == endnode) { - path.push_back(currpth); - std::vector flatpath; - std::set > incloops; - struct timeval q1, q2; - ROSE_ASSERT(path.size() == pthloops.size() + 1); - q1 = getCPUTime(); - for (unsigned int q = 0; q < pthloops.size(); q++) { - for (unsigned int r = 0; r < path[q].size(); r++) { - flatpath.push_back(path[q][r]); - } - -/* -#pragma omp critical -{ - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } -} -*/ - - } - - for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { - flatpath.push_back(path[path.size()-1][pt2]); - } - q2 = getCPUTime(); - fllp += timeDifference(q2,q1); - flatpath.push_back(endnode); -//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops -/* - #pragma omp critical (analyze) -{ - pathAnalyze(flatpath, false, incloops); -} -*/ - std::pair , std::vector > > newcol; - newcol.first = flatpath; - newcol.second = pthloops; - localnewpath = newcol; - incloops.clear(); - - int pts = pathsSize++; - pathsSize += 1; - - flatpath.clear(); - path.pop_back(); - int rounds = 0; - bool starter = false; - -// This gets a bit complicated so here is an overview: -// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. -/* - if (currBot->nodelst.size() != 0) { - while (path.back().back() != currBot->nodelst.back().first) { - ROSE_ASSERT(path.size() != 0); - path.pop_back(); - pthloops.pop_back(); - - } - currBot->path = path; - currBot->pthloops = pthloops; - currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; - currBot->nodelst.pop_back(); - localbotlst.push_back(currBot); - } - else { -*/ - currBot->remove = true; - localbotlst.push_back(currBot); - //} - } - else { - -//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node - bool disj = true; - struct timeval tdisb, tdise; - //tdisb = getCPUTime(); - for (int x = 0; x < pthloops.size(); x++) { - for (std::set::iterator j = pthloops[x].begin(); j != pthloops[x].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - } - } - } - //tdise = getCPUTime(); - //distime += timeDifference(tdise, tdisb); - if (disj) { - - disjointtrues++; - //std::cout << "disjoints: " << disjointtrues << std::endl; - midstep = false; -std::set pthloopstmp; - pthloopstmp.clear(); - for (int i = 0; i < currpth.size(); i++) { - //currflat.push_back(currpth[i]); - if (mkloops.find(currpth[i]) != mkloops.end()) { - pthloopstmp.insert(currpth[i]); - } - } - pthloops.push_back(pthloopstmp); - path.push_back(currpth); - pthloopstmp.clear(); - - //std::set > lpth; - std::vector oldcurrpth = currpth; - currpth.clear(); - SgGraphNode* frontnode = (path.back()).front(); - SgGraphNode* backnode = (path.back()).back(); - - ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); - ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); - std::vector > tmppths = pathsAtMk[backnode]; - currBot->currpth = tmppths[0]; - currBot->path = path; - currBot->pthloops = pthloops; - //newbotlst.push_back(currBot); - for (int tp = 1; tp < tmppths.size(); tp++) { - //if (localbotlst.size() < LOCALMAXBOTS) { -/* - if (currBot->nodelst.size() < LOCALMAXNODES) { - std::pair cur; - cur.second = tp; - cur.first = path.back().back(); - currBot->nodelst.push_back(cur); - } - else { -*/ - struct Bot* newBot = new Bot; - newBot->remove = false; - newBot->currpth = tmppths[tp]; - newBot->path = path; - newBot->pthloops = pthloops; - localbotlst.push_back(newBot); - //ti++; - // } - } - localbotlst.push_back(currBot); - //ti++; - } - else { -/* - if (currBot->nodelst.size() != 0) { - while (path.back().back() != currBot->nodelst.back().first) { - ROSE_ASSERT(path.size() != 0); - path.pop_back(); - pthloops.pop_back(); - - } - currBot->path = path; - currBot->pthloops = pthloops; - currBot->currpth = pathsAtMk[(path.back()).back()][currBot->nodelst.back().second]; - currBot->nodelst.pop_back(); - localbotlst.push_back(currBot); - //ti++; - } - - else { -*/ - currBot->remove = true; - localbotlst.push_back(currBot); - //delete currBot; - // } - - } - } - newpathslst[i] = localnewpath; - newbotlsts[i] = localbotlst; - } -} - botlst.clear(); - int num = 0; - - for (int i = 0; i < newbotlsts.size(); i++) { - if (newpathslst[i].first.size() > 0) { - collectedPaths.push_back(newpathslst[i]); - } - for (int j = 0; j < newbotlsts[i].size(); j++) { - if (newbotlsts[i][j]->remove == true) { - delete newbotlsts[i][j]; - } - else if (num < MAXBOTS) { - newbotlsts[i][j]->on = true; - botlst.push_back(newbotlsts[i][j]); - num++; - } - else { - newbotlsts[i][j]->on = false; - todobotlst.push_back(newbotlsts[i][j]); - } - } -} - -if (collectedPaths.size() > MINPATHS) { - - for (int i = 0; i < collectedPaths.size(); i++) { - std::vector > pthloops; - std::set > incloops; - pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - collectedPaths.clear(); -} -} - else { - if (collectedPaths.size() > 0) { - for (int i = 0; i < collectedPaths.size(); i++) { - std::set > incloops; - pthloops = collectedPaths[i].second; - for (int q = 0; q < pthloops.size(); q++) { - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - - pathAnalyze(collectedPaths[i].first, false, incloops); - } - } - collectedPaths.clear(); - break; - } -} - -std::cout << "successes: " << successes << std::endl; -std::cout << "failures: " << failures << std::endl; -std::cout << "maxlst: " << maxlst << std::endl; -return; -} - - - -template -void -SgGraphTraversal:: -evaluatePaths(SgIncidenceDirectedGraph* g, SgGraphNode* realstartnode, SgGraphNode* endnode) { -//std::set seen; -//for (std::map > >::iterator i = pathsAtMk.begin(); i != pathsAtMk.end(); i++) { -/* - std::vector > tocheck = (*i).second; - for (int j = 0; j < tocheck.size(); j++) { - for (int k = 0; k < tocheck[j].size(); k++) { - if (seen.find(tocheck[j][k]) != seen.end()) { - ploops.insert(tocheck[j][k]); - } - else { - seen.insert(tocheck[j][k]); - } - } - } -} -*/ -std::vector > path; -std::vector spath; -SgGraphNode* n = realstartnode; -int successes = 0; -int failures = 0; -int j = 0; -std::vector currpth; -int currint = 0; -std::map intPath; -intPath[n] = currint; -currint++; -std::map currents; -SgGraphNode* currnode; -bool step = false; -bool midstep = false; - -//note: pathsAtMk is referring to subpaths connected to that marker, a marker is a split in the graph (usually an if statement) - -std::vector > pth = pathsAtMk[realstartnode]; -std::vector > cpth = pathsAtMk[realstartnode]; - path.clear(); - int disjoints = 0; - int disjointtrues = 0; - currpth = pth[0]; - intPath[pth[0].front()] = currint; - std::set pthloopstmp; - SgGraphNode* fakenode; - pthloopstmp.insert(fakenode); - std::vector > pthloops; - pthloops.push_back(pthloopstmp); - pthloopstmp.clear(); - currint++; - - int stepnum = 0; - std::vector rs; - rs.push_back(realstartnode); - path.push_back(rs); - //currflat.push_back(realstartnode); - currents.clear(); - - step = false; - //std::vector currflat; - std::vector sub; - -/* - std::ofstream mz; - mz.open("pathanalysis.dot"); - mz << "digraph defaultName { \n"; -*/ - std::set > nullIncLoops; - -/* - for (unsigned int p = 0; p < looppaths.size(); p++) { - std::vector lp = looppaths[p]; - - for (unsigned int i = 0; i < lp.size()-1; i++) { - for (unsigned int l = i+1; l < lp.size(); l++) { - if (lp[i] == lp[l] && lp[i] != realstartnode && lp[i] != endnode) { - std::vector interiorloop; - interiorloop.clear(); - for (unsigned int j = i; j < l+1; j++) { - interiorloop.push_back(lp[j]); - } - if (interiorloop.size() > 2) { - } - if (interiorloop.size() > 2 && interiorloop.back() != endnode) { - if (find(iLoops.begin(), iLoops.end(), interiorloop) == iLoops.end()) { - if (find(looppaths.begin(), looppaths.end(), interiorloop) == looppaths.end()) { - iLoops.push_back(interiorloop); - loopnum++; - for (unsigned int k = 0; k < interiorloop.size(); k++) { - loopNumMap[interiorloop[k]] = loopnum; - } - lpbegins[interiorloop.front()].insert(interiorloop); - pathAnalyze(interiorloop, true, nullIncLoops); - - } - } - } - } - } - } - if (lp.size() > 2) { - lpbegins[lp.front()].insert(lp); - pathAnalyze(lp, true, nullIncLoops); - //for (unsigned int i = 1; i < lp.size(); i++) { - // printNodePlusEdgesForAnalysisPath(g, lp, p, p, mz); - //} - } - } -*/ - while (step == false) { - stepnum++; - - if (currpth.back() == endnode) { - path.push_back(currpth); - //for (int i = 0; i < currpth.size(); i++) { - // currflat.push_back(currpth[i]); - //} - std::vector flatpath; - //std::vector sub; - std::set > incloops; - struct timeval q1, q2; - //std::cout << "path.size(): " << path.size() << std::endl; - //std::cout << "pthloops.size(): " << pthloops.size() << std::endl; - ROSE_ASSERT(path.size() == pthloops.size() + 1); - q1 = getCPUTime(); - for (unsigned int q = 0; q < pthloops.size(); q++) { - //sub = path[q]; - //sub.pop_back(); - for (unsigned int r = 0; r < path[q].size(); r++) { - flatpath.push_back(path[q][r]); - } - for (std::set::iterator p = pthloops[q].begin(); p != pthloops[q].end(); p++) { - for (std::set >::iterator o = mkloopmap[*p].begin(); o != mkloopmap[*p].end(); o++) { - incloops.insert(*o); - } - } - } - for (unsigned int pt2 = 0; pt2 < path[path.size()-1].size(); pt2++) { - flatpath.push_back(path[path.size()-1][pt2]); - } - - q2 = getCPUTime(); - fllp += timeDifference(q2,q1); - flatpath.push_back(endnode); -/* - for (unsigned int ps = 0; ps < flatpath.size(); ps++) { - if (lpbegins.find(flatpath[ps]) != lpbegins.end()) { - for (std::set >::iterator sv = lpbegins[flatpath[ps]].begin(); sv != lpbegins[flatpath[ps]].end(); sv++) { - incloops.insert(*sv); - } - } - } -*/ -//user defined function, run on the final path, gives the user loops that are included via "incloops" a set of vectors that contain the individual loops - pathAnalyze(flatpath, false, incloops); - incloops.clear(); - //printNodePlusEdgesForAnalysisPath(g, flatpath, -1, -1, mz); - - int pts = pathsSize++; - pathsSize += 1; - - flatpath.clear(); - path.pop_back(); - int rounds = 0; - bool starter = false; - -// This gets a bit complicated so here is an overview: -// This is running down the graph and finding the endnode. Once it finds the endnode it goes back up to the last unevaluated subpath. It does this quickly with an integer that counts how many times that node has been used for a path. If this ends up being the number of outnodes, we don't need that node anymore, so we clear it to zero, then continue up the graph. We HAVE to reset because every time a new pathway is chosen above that node, it needs to have the ability to traverse that node. - - - while (true) { - rounds++; - ROSE_ASSERT(pathsAtMk.find((path.back()).back()) != pathsAtMk.end()); - if ((path.back()).front() == realstartnode) { - starter = true; - } - if (currents[(path.back()).back()] < (pathsAtMk[(path.back()).back()].size()) /*|| (path.back()).front() == realstartnode*/) { - std::vector > cpths = pathsAtMk[(path.back()).back()]; - currpth = cpths[currents[(path.back()).back()]]; - currents[(path.back()).back()]++; - break; - } - else { - currents[(path.back()).back()] = 0; - path.pop_back(); - pthloops.pop_back(); - } - if (starter == true) { - step = true; - break; - } - - } - } - else { - -//this checks first to see if we have any loops in our path. If not it continues down, if there is it goes back to the last nonloop node - bool disj = true; - struct timeval tdisb, tdise; - tdisb = getCPUTime(); - for (int i = 0; i < pthloops.size(); i++) { - for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - } - } - } -/* - #pragma omp parallel for num_threads(4) private(i,j) - for (i = 0; i < pthloops.size(); i++) { - if (disj) { - for (std::set::iterator j = pthloops[i].begin(); j != pthloops[i].end(); j++) { - if (find(currpth.begin(), currpth.end(), *j) != currpth.end()) { - disj = false; - //j = pthloops[i].size(); - } - } - } - - } -*/ - tdise = getCPUTime(); - distime += timeDifference(tdise, tdisb); - if (disj) { - - disjointtrues++; - //std::cout << "disjoints: " << disjointtrues << std::endl; - midstep = false; - std::set pthloopstmp; - pthloopstmp.clear(); - for (int i = 0; i < currpth.size(); i++) { - //currflat.push_back(currpth[i]); - if (mkloops.find(currpth[i]) != mkloops.end()) { - pthloopstmp.insert(currpth[i]); - } - } - pthloops.push_back(pthloopstmp); - path.push_back(currpth); - pthloopstmp.clear(); - - //std::set > lpth; - std::vector oldcurrpth = currpth; - currpth.clear(); - if (currents.find((path.back()).back()) == currents.end()) { - currents[(path.back()).back()] = 0; - } - SgGraphNode* frontnode = (path.back()).front(); - SgGraphNode* backnode = (path.back()).back(); - - ROSE_ASSERT(pathsAtMk.find(backnode) != pathsAtMk.end() || backnode == endnode); - ROSE_ASSERT(pathsAtMk.find(frontnode) != pathsAtMk.end()); - if (currents.find(backnode) == currents.end()) { - currents[backnode] = 0; - } - else { - ROSE_ASSERT(currents[backnode] == 0); - } - std::vector > tmppths = pathsAtMk[backnode]; - - currpth = tmppths[currents[backnode]]; - ROSE_ASSERT(currpth != oldcurrpth); - currents[backnode]++; - } - else { - disjoints++; - //std::cout << "disjoint false: " << s << std::endl; - - while (true) { - if (currents[(path.back()).back()] < pathsAtMk[(path.back()).back()].size() || path.back().back() == realstartnode) { - break; - } - currents[(path.back()).back()] = 0; - path.pop_back(); - pthloops.pop_back(); - } - if ((path.back()).back() != realstartnode) { - currpth = (pathsAtMk[(path.back()).back()])[currents[(path.back()).back()]]; - currents[(path.back()).back()]++; - } - else { - step = true; - } - } - } - } -std::cout << "successes: " << successes << std::endl; -std::cout << "failures: " << failures << std::endl; - -return; -} - - -//these are debugging functions, used to visually ascertain where the paths are going to check to make sure everything is evaluated - - -/* DEBUGGING */ - -template -void -SgGraphTraversal:: -printNodePlusEdgesForAnalysis(SgIncidenceDirectedGraph* g, SgGraphNode* n, int loopNum, int pathVal, std::ofstream& ss) { - printNodeForAnalysis(n, loopNum, pathVal, ss); - std::set outEdges = g->computeEdgeSetOut(n); - for (std::set::iterator i = outEdges.begin(); i != outEdges.end(); i++) { - if (nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - printEdgeForAnalysis(*i, false, ss); - } - else { - printEdgeForAnalysis(*i, true, ss); - } - } -} - -template -void -SgGraphTraversal:: -printNodePlusEdgesForAnalysisPath(SgIncidenceDirectedGraph* g, std::vector n, int loopNum, int pathVal, std::ofstream& ss) { - for (unsigned int i = 0; i < n.size()-1; i++) { - if (completedNodesPath.find(n[i]) == completedNodesPath.end()) { - printNodeForAnalysis(n[i], loopNum, pathVal, ss); - completedNodesPath.insert(n[i]); - } - std::pair prnod; - prnod.first = n[i+1]; - prnod.second = n[i]; - if (completedEdgesPath.find(prnod) == completedEdgesPath.end()) { - printEdgeForAnalysisPath(n[i+1], n[i], ss); - completedEdgesPath.insert(prnod); - } - } - if (completedNodesPath.find(n[n.size() - 1]) == completedNodesPath.end()) { - printNodeForAnalysis(n[n.size()-1], loopNum, pathVal, ss); - completedNodesPath.insert(n[n.size() - 1]); - } - -} - - -template -void -SgGraphTraversal:: -printNodeForAnalysis(SgGraphNode* n, int loopNum, int pathNum, std::ofstream &ss) { - int id = n->get_index(); - std::string nodeColor = "black"; - if (loopNum != 0) { - ss << id << " [label=\"" << "LoopNumS" << loopNum << "\", color=\"" << "green" << "\", style=\"" << "solid" << "\"];\n"; - } - else { - ss << id << " [label=\"" << "pathNumS" << pathNum << "\", color=\"" << "black" << "\", style=\"" << "dotted" << "\"];\n"; - } - -} -template -void -SgGraphTraversal:: -printEdgeForAnalysis(SgDirectedGraphEdge* e, bool isNullEdge, std::ofstream &ss) { - if (isNullEdge) { - ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "NullEdge" << "\", style=\"" << "dotted" << "\"];\n"; - } - else { - ss << e->get_from()->get_index() << " -> " << e->get_to()->get_index() << " [label=\"" << "\", style=\"" << "solid" << "\"];\n"; - } -} -template -void -SgGraphTraversal:: -printEdgeForAnalysisPath(SgGraphNode* g1, SgGraphNode* g2, std::ofstream &ss) { - ss << g2->get_index() << " -> " << g1->get_index() << " [label=\"" << "Edge" << "\", style=\"" << "solid" << "\"];\n"; -} - -/* END DEBUGGING */ - -//This function sets up the graph so that the evaluatePath function can easily traverse the paths - -template -void -SgGraphTraversal:: -solvePaths(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { - bool done = false; - bool edges = true; - bool tookone = false; - std::vector mkpath; - std::vector marks; - marks.push_back(n); - mkglobal.push_back(n); - SgGraphNode* currn = n; - SgGraphNode* took; - std::set taken; - std::vector toTake; - std::vector path; - path.push_back(n); - mkpath.push_back(n); - int itr = 0; - int bifurcations = 0; - std::map completed; - while (done == false) { - ROSE_ASSERT(currn != NULL); -//check to see if we've hit the endnode or if we're done, if not continue, if so push the subpath into the "pathsAtMk" repository - if (currn == endnode || completed.find(currn) != completed.end()) { - if (pathsAtMk.find(marks.back()) == pathsAtMk.end()) { - std::vector > emptypath; - pathsAtMk[marks.back()] = emptypath; - } - edges = false; - pathsAtMk[marks.back()].push_back(mkpath); - //for (int mk = 0; mk < mkpath.size(); mk++) { - // std::set iedg = g->computeEdgeSetIn(mkpath[mk]); - //if (iedg.size() > 1) { - // ploops.insert(mkpath[mk]); - // } - //} - ROSE_ASSERT(mkpath.front() == marks.back()); - if (marks.size() == 0) { - return; - } - mkpath.clear(); - bool y = true; - bool haventtaken = false; - bool p = true; - int place; - bool found = false; - while (found == false) { - if (marks.size() == 0) { - return; - } - SgDirectedGraphEdge* tooked; - SgGraphNode* mark1 = marks.back(); - std::set oedg = g->computeEdgeSetOut(mark1); - ROSE_ASSERT(oedg.size() > 1 || mark1 == n); - for (std::set::iterator j = oedg.begin(); j != oedg.end(); j++) { - if (taken.find(*j) == taken.end() && haventtaken == false) { - tooked = *j; - haventtaken = true; - } - } - if (haventtaken == true) { - if (marks.back() == n) { - path.clear(); - } - path.push_back(marks.back()); - if ( mkpath.empty() || (mkpath.back() != marks.back()) ) { - ROSE_ASSERT(!marks.empty()); - mkpath.push_back(marks.back()); - } - taken.insert(tooked); - took = tooked->get_to(); - found = true; - } - else { - completed[marks.back()] = true; - bifurcations++; - marks.pop_back(); - } - } - if (marks.size() == 0) { - return; - } - haventtaken = false; - found = false; - - } -//if we haven't reached the endnode or completed, continue down the graph - else { - std::set oedg = g->computeEdgeSetOut(currn); - std::set iedg = g->computeEdgeSetIn(currn); - if (oedg.size() > 1) { - if (mkpath.back() != currn) { - mkpath.push_back(currn); - } - pathsAtMk[marks.back()].push_back(mkpath); - mkpath.clear(); - mkpath.push_back(currn); - marks.push_back(currn); - if (find(mkglobal.begin(), mkglobal.end(), currn) == mkglobal.end()) { - mkglobal.push_back(currn); - } - for (std::set::iterator i = oedg.begin(); i != oedg.end(); i++) { - if (taken.find(*i) == taken.end() && tookone == false) { - taken.insert(*i); - tookone = true; - took = (*i)->get_to(); - } - else if (taken.find(*i) == taken.end() && tookone == true) { - //toTake.push_back((*i)->get_to()); - } - } - tookone = false; - } - else { - took = (*(oedg.begin()))->get_to(); - } - } - itr++; - - if (find(path.begin(), path.end(), took) == path.end()) { - mkpath.push_back(took); - path.push_back(took); - currn = took; - } - else { - mkloops.insert(took); - std::vector lptemp; - lptemp.clear(); - lptemp.push_back(took); - while (path.back() != took) { - - path.pop_back(); - - lptemp.push_back(path.back()); - - } - (mkloopmap[took]).insert(lptemp); -/* - if (lptemp.size() > 1) { - if (find(looppaths.begin(), looppaths.end(), lptemp) == looppaths.end() && find(lptemp.begin(), lptemp.end(), st) == lptemp.end() && find(lptemp.begin(), lptemp.end(), endnode) == lptemp.end()) { - looppaths.push_back(lptemp); - loopnum++; - for (unsigned int i = 0; i < lptemp.size(); i++) { - loopNumMap[lptemp[i]] = loopnum; - } - } - } -*/ - path.push_back(took); - currn = path.back(); - mkpath.push_back(took); - } - - -} - return; -} - -//not currently useful -template -SynthesizedAttributeType -SgGraphTraversal:: -defaultSynthesizedAttribute(InheritedAttributeType inh) -{ - SynthesizedAttributeType s = SynthesizedAttributeType(); - return s; -} - - -//computes the order in which to evaluate the nodes in nodal analysis so that you don't evaluate a node before you evaluate its parents - -template -void -SgGraphTraversal:: -computeOrder(SgIncidenceDirectedGraph* g, SgGraphNode* n, SgGraphNode* endnode) { - std::map incomputables; - std::set lpposs; - //std::set lps; - SgGraphNode* currn; - currn = n; - int orders = 0; - while (true) { - if (orders % 10000 == 0) { - std::cout << "orders: " << orders << std::endl; - } - orders++; - if (currn == endnode) { - } - if (computable(g, currn) || currn == n) { - int mp; - if (oVals.find(currn) == oVals.end()) { - oVals[currn] = currm++; - iVals[currm++] = currn; - currm += 1; - } - if (currn == endnode) { - - break; - } - std::pair pbs = getNextChild(g, currn); - computedNodes.insert(currn); - ROSE_ASSERT(pbs.first == true); - currn = pbs.second; - } - else { - std::pair pbp = getNextPar(g, currn); - ROSE_ASSERT(pbp.first == true); - currn = pbp.second; - - } - - } - std::cout << "required orders" << orders << std::endl; - std::cout << "incomputables.size() " << incomputables.size() << std::endl; -} - -//simple fucntion to check the computability under nodal analysis -template -bool -SgGraphTraversal:: -computable(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - if (computedNodes.find(n) != computedNodes.end()) { - return true; - } - std::set ed = g->computeEdgeSetIn(n); - bool comp = true; - for (std::set::iterator i = ed.begin(); i != ed.end(); i++) { - if (oVals.find((*i)->get_from()) == oVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - comp = false; - } - } - return comp; -} - - -//computes the inherited attribute values in nodal analysis - -template -void -SgGraphTraversal:: -computeInheritedOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - int runs = 0; -// std::ofstream mf; -// mf.open("analysis.dot"); -// mf << "digraph defaultName { \n"; - for (std::map::iterator i = iVals.begin(); i != iVals.end(); i++) { - runs++; - ROSE_ASSERT(canEval(g, (*i).second)); - setPathVal(g, n); - //printNodePlusEdgesForAnalysis(g, (*i).second, loopNumMap[(*i).second], pathValMap[(*i).second], mf); - evalNodeOrdered(g, (*i).second); - } -} - -//checks to see if evaluation is possible under nodal analysis -template -bool -SgGraphTraversal:: -canEval(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool evaled = true; - if (inhVals.find(n) == inhVals.end()) { - std::set ins = g->computeEdgeSetIn(n); - for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { - if (inhVals.find((*i)->get_from()) == inhVals.end() && nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()) { - evaled = false; - } - } - } - return evaled; -} - - -//actually does the evaluation -template -void -SgGraphTraversal:: -evalNodeOrdered(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - if (inhVals.find(n) != inhVals.end()) { - return; - } - std::set par = g->computeEdgeSetIn(n); - std::vector inh; - for (std::set::iterator i = par.begin(); i != par.end(); i++) { - if (inhVals.find((*i)->get_from()) != inhVals.end()) { - inh.push_back(inhVals[(*i)->get_from()]); - } - } - - if (n != st || inh.size() > 0) { - InheritedAttributeType inhX; - inhX = evaluateInheritedAttribute(n, inh); - inhVals[n] = inhX; - } - //std::cout << "num of inhVals: " << inh.size() << std::endl; - -} - - -//debugging function, currently not useful for the end user -template -void -SgGraphTraversal:: -setPathVal(SgIncidenceDirectedGraph* g, SgGraphNode* currn) { - if (pathValMap.find(currn) != pathValMap.end()) { - return; - } - std::set ined = g->computeEdgeSetIn(currn); - int tmppathcount = 0; - for (std::set::iterator i = ined.begin(); i != ined.end(); i++) { - ROSE_ASSERT(pathValMap.find((*i)->get_from()) != pathValMap.end() /*|| nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()*/); - //if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - // pathValMap[(*i)->get_from()] = 0; - // } - int pv = pathValMap[(*i)->get_from()]; - if (pv != 0) { - tmppathcount += pv; - } - } - pathValMap[currn] = tmppathcount; - return; - } - -//computes the next child to be analyzed in nodal analysis -template -std::pair -SgGraphTraversal:: -getNextChild(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - bool nullPoss = false; - //std::cout << "nextChild" << std::endl; - std::set outs = g->computeEdgeSetOut(n); - //std::cout << "outs.size(): " << outs.size() << std::endl; - //std::cout << "outs: " << outs.size() << std::endl; - SgGraphNode* nextNode; - SgGraphNode* nullNode; - bool completed = false; - bool completeNull = false; - - for (std::set::iterator i = outs.begin(); i != outs.end(); i++) { - - if (outs.size() == 1) { - nextNode = (*i)->get_to(); - if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - nullNum++; - } - //completedEdges.insert(*i); - completed = true; - } - else if (completed == false && computedNodes.find((*i)->get_to()) == computedNodes.end()) { - completed = true; - nextNode = (*i)->get_to(); - if (nullEdgesOrdered.find(*i) != nullEdgesOrdered.end()) { - nullNum++; - } - completedEdgesOut.insert(*i); - } - - - } - std::pair pr; - ROSE_ASSERT (completed == true || completeNull == true); - if (completed == true) { - pr.first = completed; - pr.second = nextNode; - return pr; - } - else { - pr.first = true; - pr.second = nullNode; - return pr; - } - -} - -//computes the next parent to be analyzed in nodal analysis -template -std::pair -SgGraphTraversal:: -getNextPar(SgIncidenceDirectedGraph* g, SgGraphNode* n) { - std::set ins = g->computeEdgeSetIn(n); - SgGraphNode* nextPar; - SgDirectedGraphEdge* nullEdgeO; - bool completed = false; - bool completeNull = false; - for (std::set::iterator i = ins.begin(); i != ins.end(); i++) { - - if (ins.size() == 1 /*&& completedEdges.find(*i) == completedEdges.end()*/) { - completed = true; - completedEdges.insert(*i); - nextPar = (*i)->get_from(); - } - - else if (completedEdges.find(*i) == completedEdges.end() && completed == false) { - completed = true; - nextPar = (*i)->get_from(); - completedEdges.insert(*i); - } - - else if (completedEdges.find(*i) != completedEdges.end() && computedNodes.find((*i)->get_from()) == computedNodes.end() && completed == false /*&& nullEdgesOrdered.find(*i) == nullEdgesOrdered.end()*/) { - completeNull = true; - std::pair lpp; - nextPar = n; - nullEdgesOrdered.insert(*i); - nullEdgesPaths++; - - } - } - ROSE_ASSERT(completed == true || completeNull == true); - std::pair pr; - pr.first = completed; - pr.second = nextPar; - - if (completeNull == true && completed == false) { - pr.first = completeNull; - pr.second = nextPar; - } - - return pr; -} - - - - - - - - - - - - - - - diff --git a/src/midend/astProcessing/graphTemplate.h b/src/midend/astProcessing/graphTemplate.h deleted file mode 100644 index a0935ffdb1b..00000000000 --- a/src/midend/astProcessing/graphTemplate.h +++ /dev/null @@ -1,531 +0,0 @@ -#ifndef BACKSTROKE_CFG_H -#define BACKSTROKE_CFG_H - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace Backstroke -{ - - - -//! This function helps to write the DOT file for vertices. -template -void writeCFGNode(std::ostream& out, const CFGNodeType& cfgNode) -{ - SgNode* node = cfgNode.getNode(); - ROSE_ASSERT(node); - - std::string nodeColor = "black"; - if (isSgStatement(node)) - nodeColor = "blue"; - else if (isSgExpression(node)) - nodeColor = "green"; - else if (isSgInitializedName(node)) - nodeColor = "red"; - - std::string label; - - if (SgFunctionDefinition* funcDef = isSgFunctionDefinition(node)) - { - std::string funcName = funcDef->get_declaration()->get_name().str(); - if (cfgNode.getIndex() == 0) - label = "Entry\\n" + funcName; - else if (cfgNode.getIndex() == 3) - label = "Exit\\n" + funcName; - } - - if (!isSgScopeStatement(node) && !isSgCaseOptionStmt(node) && !isSgDefaultOptionStmt(node)) - { - std::string content = node->unparseToString(); - boost::replace_all(content, "\"", "\\\""); - boost::replace_all(content, "\\n", "\\\\n"); - label += content; - } - else - label += "<" + node->class_name() + ">"; - - if (label == "") - label += "<" + node->class_name() + ">"; - - out << "[label=\"" << label << "\", color=\"" << nodeColor << - "\", style=\"" << (cfgNode.isInteresting()? "solid" : "dotted") << "\"]"; -} - - -//! This function helps to write the DOT file for edges. -template -void writeCFGEdge(std::ostream& out, const CFGEdgeType& e) -{ - out << "[label=\"" << escapeString(e.toString()) << - "\", style=\"" << "solid" << "\"]"; -} - - -// Predeclaration of class CFG. -template class CFG; - -struct FullCFGNodeFilter -{ - bool operator()(const VirtualCFG::CFGNode& cfgNode) const - { return true; } -}; - -struct InterestingCFGNodeFilter -{ - bool operator()(const VirtualCFG::CFGNode& cfgNode) const - { return cfgNode.isInteresting(); } -}; - -//! A full CFG without any filtered nodes. -typedef CFG FullCFG; - - -//! A filtered CFG which only contains interesting nodes and edges. -typedef CFG FilteredCFG; - - - - - -/********************************************************************/ -// The concept required to be fulfilled by CFGNodeFilter is -// -// struct CFGNodeFilter -// { -// bool operator()(const VirtualCFG::CFGNode& cfgNode) const; -// }; -// -/********************************************************************/ - -//! A class holding a Control Flow Graph. - -template -class CFG : public boost::adjacency_list >, - boost::shared_ptr > > -{ - typedef typename boost::graph_traits > GraphTraits; - -public: - typedef VirtualCFG::FilteredCFGNode CFGNodeType; - typedef VirtualCFG::FilteredCFGEdge CFGEdgeType; - - typedef boost::shared_ptr CFGNodePtr; - typedef boost::shared_ptr CFGEdgePtr; - - typedef typename GraphTraits::vertex_descriptor Vertex; - typedef typename GraphTraits::edge_descriptor Edge; - - typedef std::map VertexVertexMap; - //! The entry node. - Vertex entry_; - - //! The exit node. - Vertex exit_; - - -protected: - - //! The function definition of this CFG. - SgFunctionDefinition* funcDef_; - - - //! A map from a CFG node to the corresponding vertex - std::map nodesToVertices_; - - //! The dominator tree of this CFG. - VertexVertexMap dominatorTree_; - - //! The postdominator tree of this CFG. - VertexVertexMap postdominatorTree_; - -public: - std::map getNodeVert() { - return nodesToVertices_; - } - - //! The default constructor. - CFG() - : funcDef_(NULL), - entry_(GraphTraits::null_vertex()), - exit_(GraphTraits::null_vertex()) - { - } - - //! The constructor building the CFG. - explicit CFG(SgFunctionDefinition* funcDef) - : funcDef_(funcDef), - entry_(GraphTraits::null_vertex()), - exit_(GraphTraits::null_vertex()) - { - build(funcDef); - } - - //! Build the actual CFG for the given function. - void build(SgFunctionDefinition* funcDef); - - //! Get the function definition of this CFG. - SgFunctionDefinition* getFunctionDefinition() const - { return funcDef_; } - - //! Get the entry node of the CFG - const Vertex& getEntry() const - { return entry_; } - - //! Get the exit node of the CFG - const Vertex& getExit() const - { return exit_; } - - //! Build the dominator tree of this CFG. - //! @returns A map from each node to its immediate dominator. - const VertexVertexMap& getDominatorTree(); - - //! Build the postdominator tree of this CFG. - const VertexVertexMap& getPostdominatorTree(); - - //! Build a reverse CFG. - CFG makeReverseCopy() const; - - //! Output the graph to a DOT file. - void toDot(const std::string& filename) const; - - //! Get all CFG nodes in this graph. - std::vector getAllNodes() const; - - //! Get all CFG edges in this graph. - std::vector getAllEdges() const; - - //! Given a CFG node, returns the corresponding vertex in the graph. - //! Returns Vertex::null_vertex() if the given node is not in the graph - Vertex getVertexForNode(const CFGNodeType &node) const; - - //! Return if this CFG is reducible (if all loops are natural loops, the - //! CFG is reducible). - bool isReducible() const { return true; } - - //! Get all back edges in the CFG. A back edge is one whose target dominates its source. - std::vector getAllBackEdges(); - - //! Get all loop headers in this CFG. A natural loop only has one header. - std::vector getAllLoopHeaders(); - -protected: - - //! A internal funtion which builds the actual CFG (boost::graph). - void buildCFG(const CFGNodeType& node, - std::map& nodesAdded, - std::set& nodesProcessed); - - //! Find the entry and exit of this CFG and set the corresponding members. - void setEntryAndExit(); - - //! This function helps to write the DOT file for vertices. - void writeGraphNode(std::ostream& out, const Vertex& node) const - { - writeCFGNode(out, *(*this)[node]); - //VirtualCFG::printNode(out, (*this)[node]); - } - - //! This function helps to write the DOT file for edges. - void writeGraphEdge(std::ostream& out, const Edge& edge) const - { - writeCFGEdge(out, *(*this)[edge]); - //VirtualCFG::printEdge(out, (*this)[edge], true); - } - - //! This class is used to copy vertices when calling copy_graph(). - struct VertexCopier - { - VertexCopier(const CFG& g1, CFG& g2) - : cfg1(g1), cfg2(g2) {} - - void operator()(const Vertex& v1, Vertex& v2) const - { cfg2[v2] = cfg1[v1]; } - - const CFG& cfg1; - CFG& cfg2; - }; - - //! This class is used to copy edges when calling copy_graph(). - struct EdgeCopier - { - EdgeCopier(const CFG& g1, CFG& g2) - : cfg1(g1), cfg2(g2) {} - - void operator()(const Edge& e1, Edge& e2) const - { cfg2[e2] = cfg1[e1]; } - - const CFG& cfg1; - CFG& cfg2; - }; -}; - - - -template -void CFG::toDot(const std::string& filename) const -{ - std::ofstream ofile(filename.c_str(), std::ios::out); - boost::write_graphviz(ofile, *this, - boost::bind(&CFG::writeGraphNode, this, ::_1, ::_2), - boost::bind(&CFG::writeGraphEdge, this, ::_1, ::_2)); -} - -template -void CFG::build(SgFunctionDefinition* funcDef) -{ - ROSE_ASSERT(funcDef); - funcDef_ = funcDef; - - // The following two variables are used to record the nodes traversed. - nodesToVertices_.clear(); - std::set nodesProcessed; - - // Remove all nodes and edges first. - this->clear(); - entry_ = GraphTraits::null_vertex(); - exit_ = GraphTraits::null_vertex(); - - buildCFG(CFGNodeType(funcDef->cfgForBeginning()), nodesToVertices_, nodesProcessed); - - // Find the entry and exit of this CFG. - setEntryAndExit(); - - ROSE_ASSERT(isSgFunctionDefinition((*this)[entry_]->getNode())); - ROSE_ASSERT(isSgFunctionDefinition((*this)[exit_]->getNode())); -} - -template -void CFG::setEntryAndExit() -{ - for (Vertex v: boost::vertices(*this)) - { - CFGNodePtr node = (*this)[v]; - if (isSgFunctionDefinition(node->getNode())) - { - if (node->getIndex() == 0) - entry_ = v; - else if (node->getIndex() == 3) - exit_ = v; - } - } - - //In graphs with an infinite loop, we might never get to the end vertex - //In those cases, we need to add it explicitly - if (exit_ == GraphTraits::null_vertex()) - { - std::cerr << "This function may contain an infinite loop " - "inside so that its CFG cannot be built" << std::endl; - exit_ = add_vertex(*this); - (*this)[exit_] = CFGNodePtr(new CFGNodeType(funcDef_->cfgForEnd())); - } - - ROSE_ASSERT(entry_ != GraphTraits::null_vertex()); - ROSE_ASSERT(exit_ != GraphTraits::null_vertex()); -} - -template -void CFG::buildCFG( - const CFGNodeType& node, - std::map& nodesAdded, - std::set& nodesProcessed) -{ - ROSE_ASSERT(node.getNode()); - - if (nodesProcessed.count(node) > 0) - return; - nodesProcessed.insert(node); - - typename std::map::iterator iter; - bool inserted; - Vertex from, to; - - // Add the source node. - const CFGNodeType& src = node; - ROSE_ASSERT(src.getNode()); - - boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src, Vertex())); - - if (inserted) - { - from = add_vertex(*this); - (*this)[from] = CFGNodePtr(new CFGNodeType(src)); - iter->second = from; - } - else - { - from = iter->second; - } - - std::vector outEdges = node.outEdges(); - - for(const CFGEdgeType& cfgEdge: outEdges) - { - // For each out edge, add the target node. - CFGNodeType tar = cfgEdge.target(); - ROSE_ASSERT(tar.getNode()); - - boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar, Vertex())); - - if (inserted) - { - to = add_vertex(*this); - (*this)[to] = CFGNodePtr(new CFGNodeType(tar)); - iter->second = to; - } - else - { - to = iter->second; - } - - // Add the edge. - Edge edge = add_edge(from, to, *this).first; - (*this)[edge] = CFGEdgePtr(new CFGEdgeType(cfgEdge)); - - // Build the CFG recursively. - buildCFG(tar, nodesAdded, nodesProcessed); - } -} - -template -const typename CFG::VertexVertexMap& CFG::getDominatorTree() -{ - if (!dominatorTree_.empty()) - return dominatorTree_; - - boost::associative_property_map domTreePredMap(dominatorTree_); - - // Here we use the algorithm in boost::graph to build a map from each node to its immediate dominator. - boost::lengauer_tarjan_dominator_tree(*this, entry_, domTreePredMap); - return dominatorTree_; -} - -template -const typename CFG::VertexVertexMap& CFG::getPostdominatorTree() -{ - if (!postdominatorTree_.empty()) - return postdominatorTree_; - - boost::associative_property_map postdomTreePredMap(postdominatorTree_); - - // Here we use the algorithm in boost::graph to build an map from each node to its immediate dominator. - boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*this), exit_, postdomTreePredMap); - return postdominatorTree_; -} - -template -CFG CFG::makeReverseCopy() const -{ - CFG reverseCFG; - // The following function makes a reverse CFG copy. - boost::transpose_graph(*this, reverseCFG, - boost::vertex_copy(VertexCopier(*this, reverseCFG)). - edge_copy(EdgeCopier(*this, reverseCFG))); - - // Swap entry and exit. - reverseCFG.entry_ = this->exit_; - reverseCFG.exit_ = this->entry_; - return reverseCFG; -} - - -template -std::vector::CFGNodePtr> -CFG::getAllNodes() const -{ - std::vector allNodes; - for (Vertex v: boost::vertices(*this)) - allNodes.push_back((*this)[v]); - return allNodes; -} - -/* -template -std::vector::CFGNodeType> -CFG::getAllNodesNoPtrs() const -{ - std::vector allNodes; - for (Vertex v: boost::vertices(*this)) - allNodes.push_back(&((*this)[v])); - return allNodes; -} -*/ - -template -std::vector::CFGEdgePtr> -CFG::getAllEdges() const -{ - std::vector allEdges; - for (const Edge& e: boost::edges(*this)) - allEdges.push_back((*this)[e]); - return allEdges; -} - -template -typename CFG::Vertex CFG::getVertexForNode(const CFGNodeType &node) const -{ - typename std::map::const_iterator vertexIter = nodesToVertices_.find(node); - if (vertexIter == nodesToVertices_.end()) - return GraphTraits::null_vertex(); - else - { - ROSE_ASSERT(*(*this)[vertexIter->second] == node); - return vertexIter->second; - } -} - -template -std::vector::Edge> CFG::getAllBackEdges() -{ - std::vector backEdges; - - // If the dominator tree is not built yet, build it now. - getDominatorTree(); - - for (const Edge& e: boost::edges(*this)) - { - Vertex src = boost::source(e, *this); - Vertex tar = boost::target(e, *this); - - //Vertex v = *(dominatorTree.find(src)); - typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src); - while (iter != dominatorTree_.end()) - { - if (iter->second == tar) - { - backEdges.push_back(e); - break; // break the while loop - } - iter = dominatorTree_.find(iter->second); - } - } - - return backEdges; -} - -template -std::vector::Vertex> CFG::getAllLoopHeaders() -{ - std::vector backEdges = getAllBackEdges(); - std::vector headers; - for (Edge e: backEdges) - headers.push_back(boost::target(e, *this)); - return headers; -} - -#undef foreach - -} // End of namespace Backstroke - - -#endif /* BACKSTROKE_CFG_H */ diff --git a/tests/nonsmoke/functional/roseTests/astProcessingTests/processnew3Down4.C b/tests/nonsmoke/functional/roseTests/astProcessingTests/processnew3Down4.C deleted file mode 100644 index 92f87c1a585..00000000000 --- a/tests/nonsmoke/functional/roseTests/astProcessingTests/processnew3Down4.C +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include -#include "graphProcessing.h" -#include "graphTemplate.h" - - -using namespace std; -using namespace boost; -using namespace Rose; - -using namespace Backstroke; - -struct CFGNodeFilter2 -{ - bool operator()(const VirtualCFG::CFGNode& cfgNode) const - { - return true; - } -}; - - - -typedef CFG CFGforT; - - - -class visitorTraversal : public SgGraphTraversal - { - public: - int tltnodes; - virtual void analyzePath(vector& pth); - int pths; - }; - - -void visitorTraversal::analyzePath(vector& pth) { - tltnodes += pth.size(); - pths++; - std::cout << "pth" << std::endl; - for (int i = 0; i < pth.size(); i++) { - std::cout << intvertmap[pth[i]] << ", "; - } - std::cout << "end" << std::endl; -} - - -int main(int argc, char *argv[]) { - - SgProject* proj = frontend(argc,argv); - ROSE_ASSERT (proj != NULL); - SgFunctionDeclaration* mainDefDecl = SageInterface::findMain(proj); - SgFunctionDefinition* mainDef = mainDefDecl->get_definition(); - CFGforT* cfggraph = new CFGforT; - cfggraph->build(mainDef); - visitorTraversal* vis = new visitorTraversal; - string fileName= StringUtility::stripPathFromFileName(mainDef->get_file_info()->get_filenameString()); - cfggraph->toDot("dotcheck.dot"); - vis->pths = 0; - vis->tltnodes = 0; - vis->firstPrepGraph(cfggraph) - vis->constructPathAnalyzer(cfggraph); - cout << "path creation solution: " << vis->pths << std::endl; - cout << "total nodes traversed (including duplications): " << vis->tltnodes << std::endl; - return 0; -} From c0b190fac0d7d947de9f22655faaf8cfdadfb18b Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Fri, 15 Nov 2024 01:32:07 -0500 Subject: [PATCH 30/42] remove src/frontend/Experimental_General_Language_Support and src/frontend/SageIII/sageInterface/untypedBuilder.h.C --- config/support-rose.m4 | 1 - .../Makefile.am | 11 - .../PosInfo.C | 20 - .../PosInfo.h | 44 -- .../Tokens.C | 90 ---- .../Tokens.h | 95 ---- .../general_language_translation.h | 271 ----------- .../SageIII/sageInterface/untypedBuilder.C | 458 ------------------ .../SageIII/sageInterface/untypedBuilder.h | 66 --- 9 files changed, 1056 deletions(-) delete mode 100644 src/frontend/Experimental_General_Language_Support/Makefile.am delete mode 100644 src/frontend/Experimental_General_Language_Support/PosInfo.C delete mode 100644 src/frontend/Experimental_General_Language_Support/PosInfo.h delete mode 100644 src/frontend/Experimental_General_Language_Support/Tokens.C delete mode 100644 src/frontend/Experimental_General_Language_Support/Tokens.h delete mode 100644 src/frontend/Experimental_General_Language_Support/general_language_translation.h delete mode 100644 src/frontend/SageIII/sageInterface/untypedBuilder.C delete mode 100644 src/frontend/SageIII/sageInterface/untypedBuilder.h diff --git a/config/support-rose.m4 b/config/support-rose.m4 index b41ca8a2ab1..48b8860e950 100644 --- a/config/support-rose.m4 +++ b/config/support-rose.m4 @@ -1209,7 +1209,6 @@ src/ROSETTA/src/Makefile src/backend/Makefile src/frontend/CxxFrontend/Clang/Makefile src/frontend/CxxFrontend/Makefile -src/frontend/Experimental_General_Language_Support/Makefile src/frontend/Makefile src/frontend/OpenFortranParser_SAGE_Connection/Makefile src/frontend/SageIII/GENERATED_CODE_DIRECTORY_Cxx_Grammar/Makefile diff --git a/src/frontend/Experimental_General_Language_Support/Makefile.am b/src/frontend/Experimental_General_Language_Support/Makefile.am deleted file mode 100644 index 5d18d6e436c..00000000000 --- a/src/frontend/Experimental_General_Language_Support/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs - -AM_CPPFLAGS = $(ROSE_INCLUDES) - -noinst_LTLIBRARIES = libexperimentalRoseGeneralLanguage.la - -libexperimentalRoseGeneralLanguage_la_SOURCES = \ - SageTreeBuilder.C ModuleBuilder.C PosInfo.C Tokens.C - -noinst_HEADERS = \ - SageTreeBuilder.h ModuleBuilder.h PosInfo.h Tokens.h diff --git a/src/frontend/Experimental_General_Language_Support/PosInfo.C b/src/frontend/Experimental_General_Language_Support/PosInfo.C deleted file mode 100644 index 84681090561..00000000000 --- a/src/frontend/Experimental_General_Language_Support/PosInfo.C +++ /dev/null @@ -1,20 +0,0 @@ -#include "sage3basic.h" -#include "PosInfo.h" - -namespace Rose { -namespace builder { - -PosInfo::PosInfo(SgLocatedNode* fromNode) { - ROSE_ASSERT(fromNode != NULL); - ROSE_ASSERT(fromNode->get_startOfConstruct() != NULL); - ROSE_ASSERT(fromNode->get_endOfConstruct() != NULL); - - startLine_ = fromNode->get_startOfConstruct()->get_line(); - startCol_ = fromNode->get_startOfConstruct()->get_col(); - endLine_ = fromNode->get_endOfConstruct()->get_line(); - endCol_ = fromNode->get_endOfConstruct()->get_col(); - } - -} // namespace builder -} // namespace Rose - diff --git a/src/frontend/Experimental_General_Language_Support/PosInfo.h b/src/frontend/Experimental_General_Language_Support/PosInfo.h deleted file mode 100644 index 57d3713e774..00000000000 --- a/src/frontend/Experimental_General_Language_Support/PosInfo.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef POS_INFO_H_ -#define POS_INFO_H_ - -class SgLocatedNode; - -namespace Rose { -namespace builder { - -class PosInfo { -public: - PosInfo() : startLine_(0), startCol_(0), endLine_(0), endCol_(0) { - } - - PosInfo(int strtLine, int strtCol, int endLine, int endCol) - : startLine_{strtLine}, startCol_{strtCol}, endLine_{endLine}, endCol_{endCol} { - } - - PosInfo(SgLocatedNode* fromNode); - - int getStartLine() const { return startLine_; } - int getStartCol() const { return startCol_; } - int getEndLine() const { return endLine_; } - int getEndCol() const { return endCol_; } - - void setStartLine (int line) { startLine_ = line; } - void setStartCol (int col ) { startCol_ = col; } - void setEndLine (int line) { endLine_ = line; } - void setEndCol (int col ) { endCol_ = col; } - - friend std::ostream& operator<< (std::ostream &os, const PosInfo &p) { - os << "(" << p.startLine_ << ',' << p.startCol_ - << "," << p.endLine_ << ',' << p.endCol_ << ")"; - return os; - } - -protected: - int startLine_, startCol_; // location (line,col) of first character ( 1 based) - int endLine_, endCol_; // location (line,col) of last character (+1 col) -}; - -} // namespace builder -} // namespace Rose - -#endif // POS_INFO_H_ diff --git a/src/frontend/Experimental_General_Language_Support/Tokens.C b/src/frontend/Experimental_General_Language_Support/Tokens.C deleted file mode 100644 index 0591291c41f..00000000000 --- a/src/frontend/Experimental_General_Language_Support/Tokens.C +++ /dev/null @@ -1,90 +0,0 @@ -//===-- src/frontend/Experimental_General_Language_Support/Tokens.C ----*- C++ -*-===// -// -// Supports reading tokens from files (for now) -// -//===-----------------------------------------------------------------------------===// - -#include "Tokens.h" -#include -#include - -namespace Rose { - namespace builder { - -TokenStream::TokenStream(std::istringstream &is) { - std::vector row(6); - int error = 0; - - while (is.peek() != std::istream::traits_type::eof()) { - // Read type and line,column information - for (int i = 0; i < 5; i++) { - row[i].clear(); // clear old string - if ((error = getTokenElement(is,row[i])) < 0) break; - } - - // Read lexeme - JovialEnum type = static_cast(std::stoi(row[0])); - if (!error && type == JovialEnum::comment) { - row[5].clear(); // clear old string - error = getTokenComment(is,row[5]); - } - - if (!error) { - // Append the token - tokens_.emplace_back(Token{row}); - } - else { - std::cerr << "TokenStream:: WARNING, error occurred, skipping row\n"; - break; - } - } - next_ = 0; -} - -int TokenStream::getTokenElement(std::istream &is, std::string &word) { - char c; - - while (is.get(c)) { - if (c != ',') word.append(1,c); - else return 0; // success - } - std::cerr << "TokenStream::getTokenElement: WARNING, error finding token element\n"; - return 1; // failure -} - -int TokenStream::getTokenComment(std::istream &is, std::string &comment) { - char c, terminal; - int error = 1; - - // Get comment terminal ('%' or '"' for Jovial) - if (is.get(terminal)) { - if (terminal == '%' || terminal == '"') { - comment.append(1,terminal); - } - error = 0; - } - - if (!error) { - while (is.get(c)) { - comment.append(1,c); - if (c == terminal && is.get(c)) { - if (c == '\n') return 0; // success - } - } - } - - // Report an error - std::cerr << "TokenStream::getTokenComment: WARNING, error finding comment, lexeme will be empty\n"; - comment.clear(); - return 1; // failure -} - -std::ostream& operator<< (std::ostream &os, const Token &tk) { - os << static_cast(tk.type_) << ',' - << tk.bLine_ << ',' << tk.bCol_ << ',' - << tk.eLine_ << ',' << tk.eCol_ << ',' << tk.lexeme_; - return os; -} - - } // namespace builder -} // namespace Rose diff --git a/src/frontend/Experimental_General_Language_Support/Tokens.h b/src/frontend/Experimental_General_Language_Support/Tokens.h deleted file mode 100644 index c1b8ed0816d..00000000000 --- a/src/frontend/Experimental_General_Language_Support/Tokens.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- src/frontend/Experimental_General_Language_Support/Tokens.h ----*- C++ -*-===// -// -// Reads tokens from a file into a TokenStream (vector) -// -//===-----------------------------------------------------------------------------===// - -#ifndef ROSE_EXPERIMENTAL_GENERAL_TOKENS_H_ -#define ROSE_EXPERIMENTAL_GENERAL_TOKENS_H_ - -#include -#include -#include -#include - -namespace Rose { - namespace builder { - -enum class JovialEnum { - unknown = 0, - define = 98, - comment = 99 -}; - -using JE = JovialEnum; - -class Token { -public: - -//Need to explore C++17 move (see SageTreeBuilder::consumePrecedingComments()) -//Token(Token &&) = default; -//Token &operator=(Token &&) = default; -//Token(const Token &) = delete; -//Token &operator=(const Token &) = delete; - Token() = delete; - - Token(std::vector row) - : type_{JE::unknown}, bLine_{0},eLine_{0},bCol_{0},eCol_{0} { - if (row.size() == 6) { - type_ = static_cast(std::stoi(row[0])); - bLine_ = std::stoi(row[1]); - eLine_ = std::stoi(row[3]); - bCol_ = std::stoi(row[2]); - eCol_ = std::stoi(row[4]); - lexeme_ = row[5]; - } - } - - friend std::ostream& operator<< (std::ostream &os, const Token &tk); - - int getStartLine() const { return bLine_; } - int getStartCol() const { return bCol_; } - int getEndLine() const { return eLine_; } - int getEndCol() const { return eCol_; } - - JovialEnum getTokenType() const { return type_; } - const std::string & getLexeme() const { return lexeme_; } - -private: - enum JovialEnum type_; // token type - int bLine_, eLine_; // beginning and ending line - int bCol_, eCol_; // beginning and ending column - std::string lexeme_; -}; // Token - -class TokenStream { -public: - TokenStream() = delete; - TokenStream(std::istringstream &); - - std::optional const getNextToken() { - if (next_ < tokens_.size()) { - return std::optional(tokens_[next_]); - } - return std::nullopt; - } - - std::optional consumeNextToken() { - std::optional nextToken{getNextToken()}; - next_ += 1; - return nextToken; - } - -private: - std::vector tokens_; - int next_; - - int getTokenElement(std::istream &, std::string &); - int getTokenComment(std::istream &, std::string &); -}; - - } // namespace builder -} // namespace Rose - - -#endif // ROSE_EXPERIMENTAL_GENERAL_TOKENS_H_ diff --git a/src/frontend/Experimental_General_Language_Support/general_language_translation.h b/src/frontend/Experimental_General_Language_Support/general_language_translation.h deleted file mode 100644 index bf0f3ac730a..00000000000 --- a/src/frontend/Experimental_General_Language_Support/general_language_translation.h +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef GENERAL_LANGUAGE_TRANSLATION_H -#define GENERAL_LANGUAGE_TRANSLATION_H - -class SgExpression; - -namespace LanguageTranslation - { - // Forward declarations - struct FormalParameter; - struct LocationSpecifier; - struct StructureSpecifier; - - - enum FunctionModifier - { - e_function_modifier_none = 0, - - e_function_modifier_reentrant, - e_function_modifier_recursive, - - // Jovial - e_function_modifier_definition, - e_function_modifier_reference, - - // Fortran - // e_function_modifier_list, - e_function_modifier_elemental, - e_function_modifier_impure, - e_function_modifier_module, - e_function_modifier_pure, - - e_function_modifier_last - }; - - enum PackingSpecifier - { - e_packing_spec_unknown = 0, - e_packing_spec_none, // "N" from grammar - e_packing_spec_mixed, // "M" from grammar - e_packing_spec_dense, // "D" from grammar - }; - - // Enum for different types of expressions (used with untyped IR nodes). - // - enum ExpressionKind - { - e_none = 0, - e_unknown = 1, - - // Access modifiers - // -------------- - e_access_modifier_public, - e_access_modifier_private, - - // Storage modifiers - // -------------- - e_storage_modifier_contiguous, - e_storage_modifier_external, - e_storage_modifier_static, - e_storage_modifier_location, - e_storage_modifier_jovial_def, /* SimpleDef or CompoundDef */ - e_storage_modifier_jovial_ref, /* SimpleRef or CompoundRef */ - - // Type modifiers - // -------------- - e_type_modifier_list, - e_type_modifier_allocatable, - e_type_modifier_asynchronous, - e_type_modifier_const, - e_type_modifier_intent_in, - e_type_modifier_intent_out, - e_type_modifier_intent_inout, - e_type_modifier_intrinsic, - e_type_modifier_optional, - e_type_modifier_pointer, - e_type_modifier_protected, - e_type_modifier_round, - e_type_modifier_save, - e_type_modifier_target, - e_type_modifier_truncate, - e_type_modifier_volatile, - e_type_modifier_z, - - // Function formal parameters - // -------------------------- - e_param_binding_value, - e_param_binding_reference, - e_param_binding_result, - - // Structure modifiers - e_struct_modifier_list, - e_struct_item_modifier_list, - - // Operators - // --------- - - // Assignment operator - e_operator_assign, - - // Arithmetic operators - e_operator_exponentiate, - e_operator_concatenate, - e_operator_add, - e_operator_subtract, - e_operator_mod, - e_operator_multiply, - e_operator_divide, - - // Logical operators - e_operator_and, - e_operator_or, - e_operator_xor, - e_operator_equiv, - - // Relational operators - e_operator_less_than, - e_operator_greater_than, - e_operator_less_or_equal, - e_operator_greater_or_equal, - e_operator_equality, - e_operator_not_equal, - e_operator_eqv, // equivalent for relational expressions - e_operator_not_eqv, // not equivalent for relational expressions - - // Unary operators - e_operator_unary_plus, - e_operator_unary_minus, - e_operator_unary_not, - - // for optional sign - e_operator_unity, - - // Expressions - // ----------- - - e_literalExpression, - - e_function_reference, - e_procedure_call, - e_argument_list, - e_argument_keyword, - - e_variable_reference, - e_array_reference, - - e_case_range, - e_case_selector, - - // Special expressions denoting array declaration type - e_array_shape, - e_explicit_shape, - e_assumed_or_implied_shape, - e_assumed_shape, - e_assumed_size, - - // Expressions for array indexing - e_array_subscripts, - e_array_index_triplet, - e_section_subscripts, - - // Explicitly for Jovial but try to reuse for Fortran - e_explicit_dimension, - e_star_dimension, - - e_star_expression, - - // Expressions for initialization (preset in Jovial) - e_initializer, - e_struct_initializer, - - // Statements - // ---------- - - // General - e_switch_stmt, - e_end_switch_stmt, - e_case_option_stmt, - e_case_default_option_stmt, - - e_end_proc_ref_stmt, - e_end_proc_def_stmt, - - e_define_directive_stmt, - - // Fortran specific - e_fortran_dimension_stmt, - e_fortran_import_stmt, - - e_fortran_if_stmt, - e_fortran_if_then_stmt, - e_fortran_else_if_stmt, - e_fortran_else_stmt, - e_fortran_end_do_stmt, - - e_fortran_do_concurrent_stmt, - e_fortran_concurrent_header, - e_fortran_concurrent_control, - e_fortran_concurrent_locality, - - e_fortran_forall_stmt, - e_fortran_end_forall_stmt, - - e_fortran_sync_all_stmt, - e_fortran_sync_images_stmt, - e_fortran_sync_memory_stmt, - e_fortran_sync_team_stmt, - e_fortran_lock_stmt, - e_fortran_unlock_stmt, - - e_fortran_sync_stat_list, - e_fortran_sync_stat_stat, - e_fortran_sync_stat_errmsg, - e_fortran_stat_acquired_lock, - - // Jovial specific - e_jovial_compool_stmt, - - // CUDA Attributes - // --------------- - e_cuda_host, - e_cuda_device, - e_cuda_global_function, - e_cuda_grid_global, /* all threads within a thread group guaranteed to be coresident */ - - e_cuda_global, - e_cuda_device_memory, - e_cuda_managed, - e_cuda_constant, - e_cuda_shared, - e_cuda_pinned, - e_cuda_texture, - - e_last - }; - - struct FormalParameter - { - FormalParameter() - : name(std::string("")), output(false), binding(LanguageTranslation::e_none) {} // want to use C++11 = delete - FormalParameter(const std::string ¶m_name, bool out, const ExpressionKind ¶m_binding) - : name(param_name), output(out), binding(param_binding) {} - std::string name; - bool output; - ExpressionKind binding; - }; - - struct LocationSpecifier { - LocationSpecifier() : start_bit(NULL), start_word(NULL) {} - LocationSpecifier(SgExpression* sbit, SgExpression* sword) : start_bit(sbit), start_word(sword) {} - SgExpression* start_bit; - SgExpression* start_word; - }; - - struct StructureSpecifier { - StructureSpecifier() : is_parallel(false), is_tight(false), bits_per_entry(0) {} - bool is_parallel; - bool is_tight; - int bits_per_entry; - }; - - struct TableSpecifier { - TableSpecifier() : packing_spec(e_packing_spec_unknown) {} - StructureSpecifier struct_spec; - PackingSpecifier packing_spec; - }; - - typedef std::list FunctionModifierList; - - } // namespace LanguageTranslation - -#endif diff --git a/src/frontend/SageIII/sageInterface/untypedBuilder.C b/src/frontend/SageIII/sageInterface/untypedBuilder.C deleted file mode 100644 index 0f73993d508..00000000000 --- a/src/frontend/SageIII/sageInterface/untypedBuilder.C +++ /dev/null @@ -1,458 +0,0 @@ -#include "sage3basic.h" - -#include "untypedBuilder.h" -#include "general_language_translation.h" - -namespace UntypedBuilder { - -SgFile::languageOption_enum language_enum = SgFile::e_error_language; - -void set_language(SgFile::languageOption_enum current_language) -{ - language_enum = current_language; -} - - -template -ScopeClass* buildScope() -{ - return buildScope(""); -} - -template -ScopeClass* buildScope(const std::string & label) -{ - SgUntypedDeclarationStatementList* decl_list = new SgUntypedDeclarationStatementList(); - ROSE_ASSERT(decl_list); - SageInterface::setSourcePosition(decl_list); - - SgUntypedStatementList* stmt_list = new SgUntypedStatementList(); - ROSE_ASSERT(stmt_list); - SageInterface::setSourcePosition(stmt_list); - - SgUntypedFunctionDeclarationList* func_list = new SgUntypedFunctionDeclarationList(); - ROSE_ASSERT(func_list); - SageInterface::setSourcePosition(func_list); - - ScopeClass* scope = new ScopeClass(label, decl_list, stmt_list, func_list); - ROSE_ASSERT(scope); - SageInterface::setSourcePosition(scope); - - return scope; -} - -// Explicit instantiations for library usage -// -template SgUntypedScope* buildScope(); -template SgUntypedScope* buildScope(const std::string & label); - -template SgUntypedGlobalScope* buildScope(); -template SgUntypedGlobalScope* buildScope(const std::string & label); - -template SgUntypedFunctionScope* buildScope(); -template SgUntypedFunctionScope* buildScope(const std::string & label); - - -SgUntypedType* buildType(SgUntypedType::type_enum type_enum, std::string name) -{ - SgUntypedExpression* type_kind = NULL; - bool has_kind = false; - bool is_literal = false; - bool is_class = false; - bool is_intrinsic = true; - bool is_constant = false; - bool is_user_defined = false; - SgUntypedExpression* char_length_expr = NULL; - std::string char_length; - bool char_length_is_string = false; - - SgUntypedExprListExpression* modifiers = new SgUntypedExprListExpression(); - ROSE_ASSERT(modifiers); - SageInterface::setSourcePosition(modifiers); - - SgUntypedType* type = NULL; - - switch(language_enum) - { - case SgFile::e_Fortran_language: - { - switch(type_enum) - { - case SgUntypedType::e_unknown: - { - type = new SgUntypedType("UNKNOWN",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_implicit: - { - type = new SgUntypedType("IMPLICIT",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_void: - { - type = new SgUntypedType("void",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_int: - { - type = new SgUntypedType("integer",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_float: - { - type = new SgUntypedType("real",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_complex: - { - type = new SgUntypedType("complex",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_bool: - { - type = new SgUntypedType("logical",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_char: - case SgUntypedType::e_string: - { - type = new SgUntypedType("character",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - case SgUntypedType::e_user_defined: - { - is_user_defined = true; - is_intrinsic = false; - type = new SgUntypedType(name,type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum); - break; - } - default: - { - fprintf(stderr, "UntypedBuilder::buildType: unimplemented for Fortran type_enum %d \n", type_enum); - ROSE_ABORT(); // NOT IMPLEMENTED - } - } - break; - } - - default: - { - fprintf(stderr, "UntypedBuilder::buildType: unimplemented for language_enum %d \n", language_enum); - ROSE_ABORT(); // NOT IMPLEMENTED - } - - } // switch(language_enum) - - return type; -} - -SgUntypedArrayType* buildArrayType(SgUntypedType::type_enum type_enum, SgUntypedExprListExpression* shape, int rank) -{ - SgUntypedExpression* type_kind = NULL; - bool has_kind = false; - bool is_literal = false; - bool is_class = false; - bool is_intrinsic = true; - bool is_constant = false; - bool is_user_defined = false; - SgUntypedExpression* char_length_expr = NULL; - std::string char_length; - bool char_length_is_string = false; - - SgUntypedExprListExpression* modifiers = new SgUntypedExprListExpression(); - ROSE_ASSERT(modifiers); - SageInterface::setSourcePosition(modifiers); - - SgUntypedArrayType* type = NULL; - - ROSE_ASSERT(shape != NULL); - - switch(language_enum) - { - case SgFile::e_Fortran_language: - { - switch(type_enum) - { - case SgUntypedType::e_unknown: - { - type = new SgUntypedArrayType("UNKNOWN",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - case SgUntypedType::e_implicit: - { - type = new SgUntypedArrayType("IMPLICIT",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - case SgUntypedType::e_void: - { - type = new SgUntypedArrayType("void",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - case SgUntypedType::e_int: - { - type = new SgUntypedArrayType("integer",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - case SgUntypedType::e_float: - { - type = new SgUntypedArrayType("real",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - case SgUntypedType::e_bool: - { - type = new SgUntypedArrayType("logical",type_kind,has_kind,is_literal,is_class,is_intrinsic,is_constant, - is_user_defined,char_length_expr,char_length,char_length_is_string,modifiers,type_enum, - shape, rank); - break; - } - default: - { - fprintf(stderr, "UntypedBuilder::buildArrayType: unimplemented for Fortran type_enum %d \n", type_enum); - ROSE_ABORT(); // NOT IMPLEMENTED - } - } - break; - } - - default: - { - fprintf(stderr, "UntypedBuilder::buildArrayType: unimplemented for language_enum %d \n", language_enum); - ROSE_ABORT(); // NOT IMPLEMENTED - } - - } // switch(language_enum) - - return type; -} - - -SgUntypedInitializedName* -buildInitializedName(const std::string & name, SgUntypedType* type, SgUntypedExpression* initializer) -{ - ROSE_ASSERT(type); - - SgUntypedInitializedName* initialized_name = new SgUntypedInitializedName(type, name); - ROSE_ASSERT(initialized_name); - SageInterface::setSourcePosition(initialized_name); - - if (initializer != NULL) { - initialized_name->set_has_initializer(true); - initialized_name->set_initializer(initializer); - } - - return initialized_name; -} - - -SgUntypedInitializedNameList* -buildInitializedNameList(SgUntypedInitializedName* initialized_name) -{ - SgUntypedInitializedNameList* name_list = new SgUntypedInitializedNameList(); - ROSE_ASSERT(name_list); - SageInterface::setSourcePosition(name_list); - - if (initialized_name != NULL) - { - // This case works when there is only one variable - name_list->get_name_list().push_back(initialized_name); - } - - return name_list; -} - - -SgUntypedVariableDeclaration* -buildVariableDeclaration(const std::string & name, SgUntypedType* type, SgUntypedExprListExpression* attr_list, SgUntypedExpression* initializer) -{ - ROSE_ASSERT(type); - ROSE_ASSERT(attr_list); - - std::string label = ""; - - bool has_base_type = false; - SgUntypedDeclarationStatement* base_type_decl = NULL; - - SgUntypedInitializedName* initialized_name = buildInitializedName(name, type, initializer); - ROSE_ASSERT(initialized_name); - - SgUntypedInitializedNameList* var_name_list = buildInitializedNameList(initialized_name); - ROSE_ASSERT(var_name_list); - - SgUntypedVariableDeclaration* - variable_decl = new SgUntypedVariableDeclaration(label, type, base_type_decl, has_base_type, attr_list, var_name_list); - ROSE_ASSERT(variable_decl); - SageInterface::setSourcePosition(variable_decl); - - return variable_decl; -} - -SgUntypedVariableDeclaration* -buildVariableDeclaration(const std::string & name, SgUntypedType* type, SgUntypedStructureDeclaration* base_type_decl, SgUntypedExprListExpression* attr_list, SgUntypedExpression* initializer) -{ - ROSE_ASSERT(type); - ROSE_ASSERT(base_type_decl); - ROSE_ASSERT(attr_list); - - SgUntypedVariableDeclaration* variable_decl = buildVariableDeclaration(name, type, attr_list, initializer); - ROSE_ASSERT(variable_decl != NULL); - - // Set the base-type declaration - variable_decl->set_has_base_type(true); - variable_decl->set_base_type_declaration(base_type_decl); - - return variable_decl; -} - -// Build an untyped StructureDeclaration. This version builds a contained StructureDefinition with a type name created -// based on the declared variable name. -SgUntypedStructureDeclaration* buildStructureDeclaration(const std::string struct_name) -{ - SgUntypedStructureDeclaration* struct_decl = NULL; - std::string struct_type_name = ""; - bool has_body = true; - - struct_decl = buildStructureDeclaration(struct_name, struct_type_name, has_body); - ROSE_ASSERT(struct_decl != NULL); - - return struct_decl; -} - - -// Build an untyped StructureDeclaration. -// If the has_body flag is true an untyped StructureDefinition is created. -// Source position for the initializer and structure definition should be set after construction. -SgUntypedStructureDeclaration* buildStructureDeclaration(const std::string struct_name, - const std::string struct_type_name, bool has_body) -{ - SgUntypedStructureDeclaration* struct_decl = NULL; - SgUntypedStructureDefinition* struct_def = NULL; - SgUntypedExprListExpression* modifiers = NULL; - SgUntypedExprListExpression* shape = NULL; - - std::string type_name = struct_type_name; - - if (struct_type_name.length() < 1) { - // There should be a function created for this - type_name = "_anon_typeof_" + struct_type_name; - } - - if (has_body) { - struct_def = buildStructureDefinition(type_name, has_body, /*scope*/NULL); - ROSE_ASSERT(struct_def != NULL); - SageInterface::setSourcePosition(struct_def); - } - - modifiers = new SgUntypedExprListExpression(LanguageTranslation::e_struct_modifier_list); - ROSE_ASSERT(modifiers != NULL); - SageInterface::setSourcePosition(modifiers); - -// There may be a shape if a Jovial table - shape = new SgUntypedExprListExpression(LanguageTranslation::e_array_shape); - ROSE_ASSERT(shape); - SageInterface::setSourcePosition(shape); - - std::string label = ""; - int stmt_enum = LanguageTranslation::e_unknown; - struct_decl = new SgUntypedStructureDeclaration(label, stmt_enum, type_name, modifiers, shape, struct_def); - ROSE_ASSERT(struct_decl); - SageInterface::setSourcePosition(struct_decl); - - return struct_decl; -} - - -// Build an untyped StructureDefinition. This version has a body and thus a scope. -// Source position for the initializer and modifier lists and table description should be set after construction. -SgUntypedStructureDefinition* buildStructureDefinition() -{ - SgUntypedStructureDefinition* struct_def = buildStructureDefinition("", /*has_body*/true, /*scope*/NULL); - ROSE_ASSERT(struct_def); - - ROSE_ASSERT(struct_def->get_has_body() == true); - ROSE_ASSERT(struct_def->get_scope() != NULL); - - return struct_def; -} - - -// Build an untyped StructureDefinition. This version has a type name and body/scope (default is NULL). -// If the has_body flag is true and the scope is NULL, a scope will be created. -// Source position for the initializer and table description should be set after construction. -SgUntypedStructureDefinition* buildStructureDefinition(const std::string type_name, bool has_body, SgUntypedScope* scope) -{ - int expr_enum; - bool has_type_name = true; - SgUntypedStructureDefinition* struct_def = NULL; - - if (type_name.length() == 0) - { - has_type_name = false; - } - - if (has_body == true && scope == NULL) - { - scope = UntypedBuilder::buildScope(); - ROSE_ASSERT(scope != NULL); - } - - expr_enum = LanguageTranslation::e_struct_modifier_list; - SgUntypedExprListExpression* modifier_list = new SgUntypedExprListExpression(expr_enum); - ROSE_ASSERT(modifier_list); - SageInterface::setSourcePosition(modifier_list); - - expr_enum = LanguageTranslation::e_struct_initializer; - SgUntypedExprListExpression* struct_init = new SgUntypedExprListExpression(expr_enum); - ROSE_ASSERT(struct_init); - SageInterface::setSourcePosition(struct_init); - - struct_def = new SgUntypedStructureDefinition(type_name, has_type_name, has_body, struct_init, modifier_list, /*base_type*/NULL, scope); - ROSE_ASSERT(struct_def); - SageInterface::setSourcePosition(struct_def); - - return struct_def; -} - - -// Build an untyped directive declaration statement (SgUntypedDirectiveDeclaration) -SgUntypedDirectiveDeclaration* buildDirectiveDeclaration(std::string directive_string) -{ - int statement_enum = LanguageTranslation::e_define_directive_stmt; - - SgUntypedDirectiveDeclaration* define_decl = new SgUntypedDirectiveDeclaration(statement_enum, directive_string); - ROSE_ASSERT(define_decl); - SageInterface::setSourcePosition(define_decl); - - return define_decl; -} - - -SgUntypedNullExpression* buildUntypedNullExpression() -{ - SgUntypedNullExpression* expr = new SgUntypedNullExpression(); - ROSE_ASSERT(expr); - SageInterface::setSourcePosition(expr); - - return expr; -} - - -} // namespace UntypedBuilder diff --git a/src/frontend/SageIII/sageInterface/untypedBuilder.h b/src/frontend/SageIII/sageInterface/untypedBuilder.h deleted file mode 100644 index 70776ba4f40..00000000000 --- a/src/frontend/SageIII/sageInterface/untypedBuilder.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef UNTYPED_BUILDER_H -#define UNTYPED_BUILDER_H - -namespace UntypedBuilder { - -void set_language(SgFile::languageOption_enum language); - -//! Build an untyped scope including empty lists contained in the scope -template -ScopeClass* buildScope(); - -//! Build an untyped scope including empty lists contained in the scope -template -ScopeClass* buildScope(const std::string & label); - -//! Build an untyped type -SgUntypedType* buildType (SgUntypedType::type_enum type_enum = SgUntypedType::e_unknown, std::string name = ""); - -//! Build an untyped array type -SgUntypedArrayType* buildArrayType (SgUntypedType::type_enum type_enum, SgUntypedExprListExpression* shape, int rank); - -//! Build an untyped initialized name for the given name and type. The initializer may be a nullptr. -SgUntypedInitializedName* buildInitializedName(const std::string & name, SgUntypedType* type, SgUntypedExpression* initializer = NULL); - -//! Build an untyped initialized name list with potentially one name. The list will be empty if the initialized name parameter is a nullptr. -SgUntypedInitializedNameList* buildInitializedNameList(SgUntypedInitializedName* initialized_name = NULL); - -//! Build a variable declaration for only one variable with the given name and type. -SgUntypedVariableDeclaration* buildVariableDeclaration(const std::string & name, SgUntypedType* type, - SgUntypedExprListExpression* attr_list, - SgUntypedExpression* initializer = NULL); - - //! Build a variable declaration for only one variable with the given name and base-type declaration. -SgUntypedVariableDeclaration* buildVariableDeclaration(const std::string & name, SgUntypedType* type, - SgUntypedStructureDeclaration* base_type_decl, - SgUntypedExprListExpression* attr_list, - SgUntypedExpression* initializer = NULL); - -//! Build an untyped StructureDefinition. This version has a body and thus a scope. -//! Source position for the initializer and modifier lists and table description should be set after construction. -SgUntypedStructureDefinition* buildStructureDefinition(); - -//! Build an untyped StructureDefinition. This version has a type name and body/scope (default is NULL). -//! If the has_body flag is true and the scope is NULL, a scope will be created. -//! Source position for the initializer and table description should be set after construction. -SgUntypedStructureDefinition* buildStructureDefinition(const std::string type_name, bool has_body=false, SgUntypedScope* scope=NULL); - -//! Build an untyped StructureDeclaration. This version builds a contained StructureDefinition with a type name created -//! based on the declared variable name. -SgUntypedStructureDeclaration* buildStructureDeclaration(const std::string struct_name); - -//! Build an untyped StructureDeclaration. -//! If the has_body flag is true an untyped StructureDefinition is created. -//! Source position for the initializer and structure definition should be set after construction. -SgUntypedStructureDeclaration* buildStructureDeclaration(const std::string struct_name, - const std::string struct_type_name, bool has_body=false); - -//! Build an untyped directive declaration statement (SgUntypedDirectiveDeclaration) -SgUntypedDirectiveDeclaration* buildDirectiveDeclaration(std::string directive_string); - -//! Build a null expression, set file info as the default one -ROSE_DLL_API SgUntypedNullExpression* buildUntypedNullExpression(); - -} // namespace UntypedBuilder - -#endif From 07eaad017e55886436f567e2a6071c0a99f5bb90 Mon Sep 17 00:00:00 2001 From: Yonghong Yan Date: Sat, 16 Nov 2024 00:08:27 -0500 Subject: [PATCH 31/42] cleaning up doxygen-based doc systems, still not yet finish --- config/support-rose.m4 | 1 - docs/CMakeLists.txt | 38 +- docs/Makefile.am | 17 +- docs/Rose/BinaryTutorial.dox | 434 ---- docs/Rose/CMakeLists.txt | 2 +- docs/Rose/Makefile.am | 11 - docs/Rose/Tutorial/CMakeLists.txt | 4 +- docs/Rose/Tutorial/Makefile.am | 7 +- docs/Rose/Tutorial/binaryAnalysis.tex | 347 --- docs/Rose/Tutorial/binaryConstruction.tex | 416 --- docs/Rose/Tutorial/dwarfDebugSupport.tex | 179 -- docs/Rose/Tutorial/roseHPCT.tex | 496 ---- docs/Rose/Tutorial/tutorial.tex.in | 14 - docs/Rose/UPCsupport.tex | 432 ---- docs/Rose/binaryAnalysis.tex | 486 ---- docs/Rose/documents.html | 5 - docs/Rose/projects.html | 66 - docs/Rose/rose.cfg.in | 2797 ++++++++++++-------- docs/Rose/roseQtWidgets.doxygen.in | 1254 --------- docs/Rose/rose_exam_1.tex | 19 - docs/Rose/sage.cfg.in | 2867 ++++++++++++++++----- 21 files changed, 4014 insertions(+), 5878 deletions(-) delete mode 100644 docs/Rose/BinaryTutorial.dox delete mode 100644 docs/Rose/Tutorial/binaryAnalysis.tex delete mode 100644 docs/Rose/Tutorial/binaryConstruction.tex delete mode 100644 docs/Rose/Tutorial/dwarfDebugSupport.tex delete mode 100644 docs/Rose/Tutorial/roseHPCT.tex delete mode 100644 docs/Rose/UPCsupport.tex delete mode 100644 docs/Rose/binaryAnalysis.tex delete mode 100644 docs/Rose/projects.html delete mode 100644 docs/Rose/roseQtWidgets.doxygen.in diff --git a/config/support-rose.m4 b/config/support-rose.m4 index 48b8860e950..8a068ecb22b 100644 --- a/config/support-rose.m4 +++ b/config/support-rose.m4 @@ -1184,7 +1184,6 @@ docs/Rose/leftmenu.html docs/Rose/manual.tex docs/Rose/rose-install-demo.cfg docs/Rose/rose.cfg -docs/Rose/roseQtWidgets.doxygen docs/Rose/sage.cfg docs/testDoxygen/Makefile docs/testDoxygen/test.cfg diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index f68f0994b4c..fd85a65dcfa 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,38 +1,6 @@ -include_directories(${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ) - add_subdirectory(Rose) +# add_subdirectory(Rosetta) +# add_subdirectory(testDoxygen) -message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}: skipped subdir $(DEVELOPER_DISTRIBUTION_DIRECTORY)") - -########### install files ############### - - - - -#original Makefile.am contents follow: - -# -## DQ (7/24/2008): Only the developer version needs the test directory specific to Doxygen support -## JJW (8/3/2008): This line will be removed in binary distributions -#DEVELOPER_DISTRIBUTION_DIRECTORY = testDoxygen -# -## Later we will add ROSETTA documentation here ... -## SUBDIRS = Rose Rosetta testDoxygen -# -## DQ (9/11/2006): Removed Rosetta directory, an internal tool not documented -## within ROSE for use externally. -## SUBDIRS = Rose Rosetta testDoxygen -## SUBDIRS = Rose testDoxygen -#SUBDIRS = Rose $(DEVELOPER_DISTRIBUTION_DIRECTORY) -# -## New rule to simplify generation of documentation (we want to avoid using the -## automake generated "docs" rule because the generation of documentation is -## dependent upon separate tools which the user might not have available -## (true for bothe the LaTeX and html documentation). -## documentation: -#docs: -# @echo " Generate all possible documentation cd Rose; make documentation;" -# @cd Rose; $(MAKE) docs; -# -#EXTRA_DIST = +message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}: skipped subdir Rosetta and testDoxygen") \ No newline at end of file diff --git a/docs/Makefile.am b/docs/Makefile.am index 29f9f33aaaa..6f005587b37 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,22 +1,7 @@ - -# DQ (7/24/2008): Only the developer version needs the test directory specific to Doxygen support -# JJW (8/3/2008): This line will be removed in binary distributions -DEVELOPER_DISTRIBUTION_DIRECTORY = testDoxygen - -# Later we will add ROSETTA documentation here ... -# SUBDIRS = Rose Rosetta testDoxygen - -# DQ (9/11/2006): Removed Rosetta directory, an internal tool not documented -# within ROSE for use externally. # SUBDIRS = Rose Rosetta testDoxygen # SUBDIRS = Rose testDoxygen -SUBDIRS = Rose $(DEVELOPER_DISTRIBUTION_DIRECTORY) +SUBDIRS = Rose -# New rule to simplify generation of documentation (we want to avoid using the -# automake generated "docs" rule because the generation of documentation is -# dependent upon separate tools which the user might not have available -# (true for bothe the LaTeX and html documentation). -# documentation: docs: @echo " Generate all possible documentation cd Rose; make documentation;" @cd Rose; $(MAKE) docs; diff --git a/docs/Rose/BinaryTutorial.dox b/docs/Rose/BinaryTutorial.dox deleted file mode 100644 index 55f36a6cf9f..00000000000 --- a/docs/Rose/BinaryTutorial.dox +++ /dev/null @@ -1,434 +0,0 @@ -// -*- c++ -*- - -namespace Rose { -namespace BinaryAnalysis { - -/** @page binary_tutorial Binary analysis tutorial - * - * Getting started guide for binary analysis. - * - * @section bintut_why Why binary analysis? - * - * ROSE was originally designed as a source-to-source analysis and transformation system, but it turns out that parsing and - * analyzing a binary specimen shares many of the same basic ideas: - * - * @li A binary specimen usually lives in a container that describes areas of memory, symbols, and other things needed when - * the specimen is executed or linked. These various containers (executables, libraries, object files, core dumps) can be - * parsed by a ROSE frontend and result in an abstract syntax tree (AST) much like parsing of source code. - * - * @li The machine instructions of a binary specimen can be parsed an have semantics similar to statements in a source - * language. They also result in abstract syntax trees. - * - * @li Data areas in the specimen can be parsed and are similar to initialized data in a source language. These also become - * abstract syntax trees. - * - * @li %Analysis can be performed on an intermediate representation (IR) for both binaries and source code. One such - * intermediate representation is the abstract syntax tree. - * - * @li Transformations modify the AST and the resulting AST can be "unparsed" to create a new binary specimen, much like - * unparsing transformed source code results in a new implementation. - * - * Of course there are also many differences between source code and binary specimens, but ROSE is situated in the unique - * position of being able to process both. On the one hand, it can operate on a specimen for which no source code is - * available, and on the other it can perform analysis and transformations where both source and binary are available at - * once. - * - * - * - * - * @section bintut_features What binary analysis features are available? - * - * ROSE can parse a variety of binary inputs. It can parse executable formats such as Linux ELF executables, shared libraries, - * core dumps, object files, and library archives; and Microsoft Windows PE and DOS executables and libraries. It can parse - * memory initialization formats such as Motorola S-Records, Intel HEX files, and raw memory dumps. It can analyze running or - * paused programs on Linux. ROSE can also analyze combinations of these formats&emdash;such as an ELF file extended by - * providing additional initialized memory from an S-Record file&emdash;and has a mini command-line language for specifying - * this for all binary analysis tools. - * - * The ROSE disassembler uses a hybrid linear sweep and recursive descent approach that handles things like overlapping - * instructions (on architectures where that's possible), interleaved functions, rewritten execution flow, and more. ROSE has - * instruction decoders for ARM, AMD64 (x86_64), Intel x86, MIPS, Motorola 68k, and PowerPC (32- and 64-bit). ROSE is designed - * so that most analysis is architecture independent. - * - * ROSE understands semantics for common subsets of AMD64, Intel x86, Motorola 68k, and PowerPC (32- and 64-bit) and can - * therefore reason about how execution of instructions affects a machine's state. It can perform this reasoning symbolically, - * using only concrete values, using sets of intervals of concrete values, and many more special-purpose domains. If an - * Satisfiability Modulo Theory (SMT) solver is available, ROSE can use it to increase the fidelity of its analyses, including - * reasoning that's employed during the disassembly phase. - * - * ROSE is able to construct control flow graphs and call graphs and has a number of pre-built analysis capabilities such as - * tainted flow analysis, edit distances, code statistics, memory maps, reasoning about register interactions, address usage - * maps, execution paths and their feasibility, generic inlining and interprocedural data-flow, no-op sequence detection, - * opaque predicate detection, algorithmic CFG rewriting, calling convention detection, function may-return analysis, address - * labeling passes, thunk detection and manipulating, switch statement analysis, interrupt vector processing, overlapping - * instructions, cross referencing, function stack delta analysis, register and memory usage analysis, magic numbers, static - * and dynamic string decoding, control flow dominance, pointer detection, DWARF parsing, library identification, etc. - * - * %Analysis results are available in a number of formats, depending on the analysis: through various APIs, decoration of the - * abstract syntax tree or control flow graph, commentary in assembly listings, databases, or to a certain extent as a new - * translated binary specimen. - * - * This document only attempts to describe a few of the easiest features to get you started. - * - * - * - * - * @section bintut_config Installing and confguring ROSE for binary analysis - * - * The binary analysis features have a large number of software dependencies beyond what the source-to-source side of ROSE - * uses, but fortunately all of them are optional. If a software dependency is not available then the analysis that uses it - * is simply not available. In a few cases cases the analysis can use a different dependency or a slower or less accurate - * implementation. See @ref installation for instructions on how to install ROSE. ROSE must be configured with "binaries" - * being one of the "--enable-languages" values. - * - * - * - * - * @section bintut_helloworld Hello, World! - * - * Every system needs a basic "Hello, World!" example, so here's that example for binary analysis within the ROSE - * framework. It parses a specimen from a variety of formats (see its "--help" output), then disassembles the instructions - * optionally using instruction semantics to help drive the disassembly, then partitions the instructions into functional - * units, and finally displays an assembly listing. - * - * @snippet binaryHelloWorld.C rose include - * - * All programs start by including the main ROSE include file that declares most things that are common to source and binary - * analysis. This must be the first ROSE header to be included. - * - * @snippet binaryHelloWorld.C other includes - * - * ROSE's binary components are declared in individual header files that can only be included after including "rose.h". The - * binary headers themselves can be included in any order (after rose.h) since each header includes those other headers on - * which it depends. The binary analysis headers usually have the same names as the primary class they contain. - * - * @snippet binaryHelloWorld.C commandline - * - * The binary analysis uses a different command-line processor than most of the rest of ROSE because the command-line options - * for these tools don't typically interact with a compiler and therefore don't need to parse the host of compiler switches - * that the source tools need to recognize. This also frees the binary tool's command-line parser to be able to generate Unix - * man pages on the fly. For instance, if you invoke this tool with "--help" (or just "-h") you should see quite lengthy - * documentation about how to invoke the tool and what all its switches mean. A tool more advanced than "Hello, World!" can - * modify the command-line parser. - * - * @snippet binaryHelloWorld.C disassembly - * - * ROSE divides disassembly into two phases. Within ROSE, a @ref Disassembler is responsible for parsing the bytes of a single - * machine instruction and turning them into an abstract syntax tree, while the @ref Partitioner2 namespace contains the - * machinery for driving disassembly. The partitioner partitions the specimen's memory image into parts that are either - * instructions or data (actually, "partitioner" is a bit of a misnomer since instructions and data can also overlap, although - * they seldom do in practice). - * - * The Partitioner2 namespace contains many classes, but @ref Partitioner2::Engine "Engine" and @ref Partitioner2::Partitioner - * "Partitioner" are the two most important classes. The @ref Partitioner2::Engine "Engine" is used to drive the disassembly - * process and create a @ref Partitioner2::Partitioner "Partitioner", which holds the results in data structures that have - * better time complexities than an AST when it comes to most forms of analysis. In this example, we are invoking the @ref - * Partitioner2::Engine::frontend "Engine::frontend", which is similar in nature to ROSE's global @ref ::frontend in that it - * does everything necessary to make ROSE ready to do analysis: it parses, loads, disassembles, partitions, runs basic - * analysis, and checks consistency. In the end, it returns an abstract syntax tree (AST) instead of a @ref - * Partitioner2::Partitioner "Partitioner". - * - * AST nodes in ROSE all begin with the letters "Sg" (from "Sage"). Those nodes that are specific to binary analysis begin - * with "SgAsm" (from "Sage assembly"). Within source code analysis, source files combine to form a single @ref SgProject - * node, and the same is often true with binary analysis also. For specimens that have a container, like Linux ELF and - * Windows PE files, the AST has two large subtrees: one subtree describes the containers (there may be more than one), and - * another subtree describes the instructions organized into interpretation subtrees (@ref SgAsmInterpretation). - * Interpretations organize instructions into coherent sets, such as the PE32 and DOS subcomponents of a Windows PE - * file. However not all specimen formats have containers, in which case the AST is abbreviated and contains only the - * instructions rooted at a "global block" (SgAsmBlock). - * - * @snippet binaryHelloWorld.C unparsing - * - * Now that an abstract syntax tree has been created we can "unparse" it. Unparsing in a binary is slightly different - * than unparsing source code. Binary specimens are usually not transformed like source code, so the unparser for a binary - * generates a human-readable pseudo-assembly listing instead. We could have also called the global @ref ::backend (same as - * source code) which would have produced a number of output files including a new executable, but backend only works on - * SgProject nodes which might not be present (see above). Note that there are better ways to obtain an unparser, and we'll - * see them later. - * - * Here's the entire "Hello, World!" program: - * - * @includelineno binaryHelloWorld.C - * - * - * - * @section bintut_compile Compiling programs that use ROSE - * - * To compile this program you'll want to use the same compiler, preprocessor switches, compiler switches, and loader switches - * as are used when compiling ROSE. This is important! Since C++ has no official, documented application binary interface, - * mixing libraries compiled with different compilers, compiler versions, compiler optimization levels, or even other - * seemingly benign compiler switches is not guaranteed to work. The easiest way to compile the above example is to change - * directories to $ROSE_BUILD/tutorial, where $ROSE_BUILD is the top of your build tree, and run make - * binaryHelloWorld. Similar commands will work for the other examples in this tutorial. - * - * On the other hand, if you've already installed the ROSE library and blown away your build tree, or if you're writing your - * own programs that use ROSE, you won't be able to leverage ROSE's own build system to compile your program, and you probably - * have no idea what compiler command was used to compile ROSE. Fear not, ROSE installed a "rose-config.cfg" file that has the - * information you need, and in a format that can be included directly into GNU make files. See @ref tooldev for an example - * Makefile. - * - * - * - * @section bintut_fcfg Generating a function control flow graph. - * - * This example shows how to load a specimen into analysis space and generate a control flow graph for each function. First we - * include @c rose.h and then any additional binary analysis header files: - * - * @snippet binaryFunctionCfg.C prologue - * - * Then, in the @c main program, we create a disassembling and partitioning engine and use it to parse the command-line. This - * allows our tool to easily support the multitude of partitioner settings and container formats. The command-line parser and - * its documentation is easily customizable for more advanced tools, but the following works fine for this tool: - * - * @snippet binaryFunctionCfg.C setup - * - * The "mlog[FATAL]" in the previous code uses ROSE's diagnostics facility, a large set of coordinated streams for different - * software components and message severity levels, all of which can be controlled from the command-line. - * - * Next, now that the engine is configured and we know the name(s) or resources for the specimen, we can parse the specimen - * container, load the specimen into memory, disassemble, and discover functions. The results are stored in a @ref - * Partitioner2::Partitioner "Partitioner" object: - * - * @snippet binaryFunctionCfg.C partition - * - * Finally, we'll iterate over those functions to create function control flow graphs and print each graph. The @ref - * Partitioner2::Partitioner::cfg "cfg" method returns a const reference to a global control flow graph, which normally serves - * as the starting point for many analyses. But in this case, we want only the subgraph that represents an individual - * function, so we copy the global CFG and then remove those vertices and edges that are uninteresting: - * - * @snippet binaryFunctionCfg.C function cfg - * - * In the above code, the @ref Partitioner2::ControlFlowGraph is a specialization of @ref Sawyer::Graph, which is a generic - * yet easy-to-use graph implementation with very good time complexity for most operations. So the previous "for" loop has - * linear time complexity with respect to the total number of vertices and edges. - * - * The @ref Partitioner2::DataFlow namespace has a @ref Partitioner2::DataFlow::buildDfCfg "buldDfCfg" function that creates a - * slightly different kind of control flow graph--one that's more useful for data-flow--which also permits intra- and - * inter-procedural analysis based on user criteria. - * - * Here's the entire program: - * - * @includelineno binaryFunctionCfg.C - * - * - * - * @section bintut_cg Generating a binary function call graph in GraphViz format. - * - * This example is similar to the @ref bintut_helloworld example, but demonstrates how to analyze function call information to - * construct a function call graph (CG) and then emit that graph as a GraphViz file. The output can be converted to a picture - * with the "dot" command, or visualized interactively with ZGRViewer. - * - * @snippet binaryCallGraph.C headers - * - * As before, the "rose.h" header is the first of the ROSE headers to be included, followed by the binary analysis headers in - * any order. - * - * @snippet binaryCallGraph.C namespaces - * - * This time we'll use a few namespaces to reduce our typing. The @ref Rose::Diagnostics namespace brings into scope the - * diagnostic support (@c mlog and @c FATAL in this example) which is accessed through the "--log" command-line switches and - * controls what kinds of diagnostic output is produced. If you run this program with "--log=all" you'll get traces and - * debugging from all the ROSE components that use this mechanism (lots of output); see "--log=help" for info about fine - * tuning this. - * - * @snippet binaryCallGraph.C settings - * - * Many of the binary analysis tools find that holding all command-line settings in a single struct is a convenient way to - * organize things. This example only has one tool-specific setting--the name of the output file for the call graph. - * - * @snippet binaryCallGraph.C commandline - * - * The @ref bintut_helloworld example showed the simplest way to parse a command-line, but this time we'll do something a - * little more complex. This time we want to augment the command-line parser so it knows about the switches that this tool - * supports. The parser itself comes from the [Sawyer](https://github.com/matzke1/sawyer) library, part of which is - * distributed along with the ROSE source code. We obtain the default parser from the disassembly and partitioning engine, - * and augment it with a switch group containing the switches specific to this tool. Our "--output" or "-O" switch takes a - * single argument, a file name that can be any string. The "doc" property is the documentation for our switch and will - * appear in the Unix man page produced by running with "--help". Finally, we invoke the parser with our additional switch - * group on the argument list in @c argv. If the parsing is successful we apply the results to our @c settings and then return - * the rest of the command line (probably information about the specimen). - * - * @snippet binaryCallGraph.C setup - * - * In the @p main program we initialize our @p settings and instantiate a disassembly/partitioning engine, then parse the - * command-line and get the list of non-switch arguments. If there are none, give the user some help; this is often an - * indication that the user invoked the command with no arguments at all in order to get an error message that hopefully - * contains some usage hints. - * - * @snippet binaryCallGraph.C partition - * - * Instead of calling @ref Partitioner2::Engine::frontend "engine.frontend", this time we call @ref - * Partitioner2::Engine::partition "engine.partition" in order to get access to the partitioning analysis results. No AST is - * created in this case, although we could get one if we wanted by querying the engine for it. The data structures used by - * the partitioner are much more efficiently tuned for analysis than an AST, so we'll stick with the partitioner. - * - * @snippet binaryCallGraph.C callgraph - * - * The partitioner knows how to construct a call graph from its internal data structures. The @ref - * Partitioner2::FunctionCallGraph "FunctionCallGraph" class can also be manipulated directly. Now's a good time to point out - * that many binary analysis data structures use pointers to shared objects. The objects are reference counted and deleted - * automatically. Classes that are used in this way do not have public constructors, but rather @c instance methods (and - * sometimes additional factories as well) that allocate and initialize the object and return a smart pointer. In this - * example, if we were to delete the @c partitioner or @c engine the @c callgraph would still point to valid functions, which - * still point to valid instructions, etc. - * - * @snippet binaryCallGraph.C emit - * - * Finally we can emit the call graph as a GraphViz file. This is done through a @ref Partitioner2::GraphViz::CgEmitter - * "CgEmitter" that specializes a more general GraphViz emitter. The emitter API allows you to fine tune the output by - * adjusting colors and other GraphViz edge and vertex properties. - * - * Here's the full listing. Compile it using the same instructions as for the @ref bintut_helloworld example. - * - * @includelineno binaryCallGraph.C - * - * - * - * - * @section bintut_strings Finding static strings in a binary specimen - * - * This example parses and disassembles a binary specimen and search for all static strings, similar to the Unix "strings" - * command. This simple example can be a starting point for a more in depth strings analysis than what's possible with the - * Unix command. - * - * @snippet binaryStrings.C headers - * - * Include headers. The "rose.h" must always be before other ROSE headers. - * - * @snippet binaryStrings.C commandline - * - * Yet another way to parse a command-line. This time we're trying to avoid calling @ref Partitioner2::Engine::frontend - * because we don't actually need to disassemble or partition anything--string searching operates on raw memory rather than - * instructions, so we can save some time. - * - * @snippet binaryStrings.C load - * - * The @ref Partitioner2::Engine::loadSpecimens "engine.loadSpecimens" method parses the speicmen container if present (e.g., - * Linux ELF) and determines how the specimen should be mapped into memory. The result is a @ref MemoryMap that describes - * memory segments with addresses, permissions, names, etc. Try inserting a call to @ref MemoryMap::dump here to get an - * idea of what it contains. - * - * The byte order will be needed by the string decoder in order to know how to decode the multi-byte length fields. We could - * have gotten this same information any number of other ways, but this is the most convenient in this situation. Note that - * knowledge of the byte order depends upon knowledge of the specimen architecture even though we don't actually need to - * disassemble anything. - * - * @snippet binaryStrings.C analysis - * - * Here we perform the string searching. Most binary analysis algorithms are packaged into a class. The idea is that one - * instantiates the analyzer, configures it, calls some method to perform the analysis (here it's @ref - * Strings::StringFinder::find "find"), and then queries the results. - * - * The @ref MemoryMap::require and @ref MemoryMap::prohibit methods are a form of filtering. They're filtering the memory - * map so that the string analyzer only sees memory that's readable but not writable. - * - * @snippet binaryStrings.C output - * - * Generating the output is a matter of iterating over the strings that were found and printing some information. Most - * analyzer objects also know how to print themselves although those defaults are not always suitable for a polished tool. - * - * Here's the entire program: - * - * @includelineno binaryStrings.C - * - * - * - * @section bintut_dominators Graph dominators and post dominators - * - * Loosely speaking, the dominator of a vertex of a graph is another vertex that's visited on every path from some - * starting vertex to the vertex in question. Most of the time, we're interested in an immediate dominator, which is the - * closest dominator to the vertex in question. A more rigorous definition can be found in Wikipedia, among other places. - * Post-dominators are similar in that a post dominator of a vertex is some other vertex that's visited on every path from the - * vertex in question to some ending vertex. - * - * ROSE uses the @ref Sawyer::Container::Graph "Sawyer Graph API" for all binary analysis graphs, and Sawyer has functions for - * calculating dominators and post-dominators. The following example is a tool that finds the dominator for each vertex in the - * control flow graph of each function. - * - * @snippet binaryDominance.C headers - * - * The first step, above, is to include the appropriate declarations. Our convention for writing tools is to describe the tool - * with a couple of strings that appear at the very top of the source code. These strings are used later in the program to - * generate the documentation for the "--help" output. - * - * This tool is so simple that everything else is in "main". First we initialize things: - * - * @snippet binaryDominance.C init - * - * The @ref Rose::initialize "ROSE_INITIALIZE" macro is always the first ROSE-related statement and checks that this tool was - * compiled with header files that are binary compatible with the ROSE library. Then we create a partitioning engine to parse - * the command-line to get the specimen resources. The specimen is some combination of a ELF or PE file name, raw memory - * dumps, S-Records, and/or process IDs. The @ref Rose::BinaryAnalysis::Partitioner2::Engine::partition "engine.partition" - * call does all the hard work of parsing containers, loading data into the virtual address space, decoding CPU instructions, - * and creating basic blocks and functions. It returns a @ref Rose::BinaryAnalysis::Partitioner2::Partitioner "partitioner" - * object that stores all the results, which include a global control flow graph. - * - * Then we iterate over the functions: - * - * @snippet binaryDominance.C iterate - * - * We want to create a function CFG, but all we have from the partitioner is a global CFG. We can use the fact that a function - * CFG is a subset of the global CFG and therefore create the function CFG by copying the global CFG and removing all vertices - * and edges that are not part of the function CFG. Although this isn't the most efficient way to create function CFGs in a - * loop over all functions, it is very simple. - * - * We'll need to know the entry vertex of the function's CFG: - * - * @snippet binaryDominance.C cfg_enter - * - * We found the entry vertex in the function CFG by first finding it in the global CFG and then using a feature of Sawyer - * graphs, namely, when a graph is copied its vertices and edges have the same IDs as those in the source graph, and we can - * obtain a vertex pointer (iterator) in constant time if we know its ID. We have to convert the ID to a vertex pointer - * before removing the non-function vertices because IDs are not stable across erase operations, but iterators are. - * - * Next we erase the non-function vertices and edges: - * - * @snippet binaryDominance.C cfg_build - * - * This is the simple way to build a function CFG from a global CFG. It's important to use a post-increment in the - * @c eraseVertex call. Since we're inside a loop iterating over every function, a more efficient implementation would have - * created all the function CFGs in a single pass over the global CFG. As of June 2017, ROSE does not have functions for - * returning function CFGs -- it only has a global CFG -- because there are many details that need to be considered depending - * on the situation (e.g., function calls and returns are two cases that typically need massaging in a function CFG depending - * on the purpose of the CFG). - * - * Finally, we get to the real meat of this example: finding the immediate dominator for every vertex in the function CFG - * given the CFG's entry vertex: - * - * @snippet binaryDominance.C dominators - * - * The @ref Sawyer::Container::Algorithm::graphDominators "graphDominators" function can handle any type of Sawyer graph, thus - * we could also pass a function call graph or a data-flow graph. - * - * The return value is a vector indexed by vertex ID, whose values point to either the corresponding immediate dominator or - * the vertex end iterator (not all vertices have an immediate dominator). Using a vector indexed by vertex ID is an idiom - * used throughout ROSE whenever we need to associated extra data with an existing graph. Since a vertex pointer (iterator) - * can be converted to a vertex ID in constant time, and indexing into the vector is constant time, we can always find the - * extra data in constant time. And since vertex IDs are consecutive integers beginning at zero, this is also a - * space-efficient way to represent data that's present for most, if not all, vertices. - * - * Finally, let us iterate over the results to print them: - * - * @snippet binaryDominance.C results - * - * Since vector indexes are equivalent to vertex IDs, we can obtain a vertex with a constant-time @c findVertex call and a - * constant-time iterator dereference. Since this is a CFG from the partitioner (or at least a copy thereof), we can use the - * @ref Rose::BinaryAnalysis::Partitioner2::Partitioner::vertexName "vertexName" static method to print some info about - * it. Using the static method (that takes a vertex value) is important; the non-static method (that takes a vertex iterator) - * will think that we're handing it a pointer to some vertex in the partitioner's own global CFG. - * - * Here's the entire program: - * - * @includelineno binaryDominance.C - * - * - * - * @section bintut_next Next steps - * - * Most binary analysis capabilities are documented in the @ref Rose::BinaryAnalysis namespace. The test directory, - * "$ROSE_SOURCE/tests/nonsmoke/functional/roseTests/BinaryTests", also has many examples, some of which are slightly hard to read since there - * main purpose is to test rather than demonstrate. The "$ROSE_SOURCE/projects/BinaryAnalysisTools" directory (as well as - * some other project directories) has real programs that use the binary analysis interface. */ - -} // namespace -} // namespace diff --git a/docs/Rose/CMakeLists.txt b/docs/Rose/CMakeLists.txt index 4e1187b6acc..232a9b0d462 100644 --- a/docs/Rose/CMakeLists.txt +++ b/docs/Rose/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ) +# include_directories() add_subdirectory(Tutorial) diff --git a/docs/Rose/Makefile.am b/docs/Rose/Makefile.am index daa7f8bd303..081eba13b65 100644 --- a/docs/Rose/Makefile.am +++ b/docs/Rose/Makefile.am @@ -192,17 +192,11 @@ make-web-pages: $(RoseDoxygenDocumentation) $(PACKAGE_NAME)-$(PACKAGE_VERSION)-U cp -f footer.html ROSE_WebPages/footer.html cp -f $(srcdir)/rose.html ROSE_WebPages/rose.html cp -f $(srcdir)/rose.html ROSE_WebPages/index.html - cp -f $(srcdir)/projects.html ROSE_WebPages/projects.html cp -f $(srcdir)/FAQ.html ROSE_WebPages/FAQ.html cp -f $(srcdir)/documents.html ROSE_WebPages/documents.html cp -f $(srcdir)/highlights.html ROSE_WebPages/highlights.html cp -f $(srcdir)/news.html ROSE_WebPages/news.html cp -f $(srcdir)/regressionTest.html ROSE_WebPages/regressionTest.html - cp -f $(COMPASS_MANUAL) ROSE_WebPages/ - cp -f $(AUTOTUNING_MANUAL) ROSE_WebPages/ - cp -f $(QROSE_MANUAL) ROSE_WebPages/ -# mkdir -p ROSE_WebPages/ROSE_HaskellAPI -# cp -fr $(HASKELLPORT_APIDOCS)/* ROSE_WebPages/ROSE_HaskellAPI/ cp -fr $(srcdir)/powerpoints ROSE_WebPages/ cp -f ROSE_InstallationInstructions.pdf ROSE_WebPages/ROSE_InstallationInstructions.pdf cp -f ROSE_Exam.pdf ROSE_WebPages/ROSE_Exam.pdf @@ -217,12 +211,7 @@ make-web-pages: $(RoseDoxygenDocumentation) $(PACKAGE_NAME)-$(PACKAGE_VERSION)-U # Upload web pages to the LBL server copyWebPages: make-web-pages -# Liao 5/6/2010 migrate to the new web server -# Liao, 7/13/2009, must ensure the file permissions here -# Liao, 12/8/2010, use dedicated data transferring node dtn01 cd ROSE_WebPages; chmod -R a+rx *; rsync -avz * liaoch@dtn01.nersc.gov:/project/projectdirs/rosecompiler/www.rosecompiler.org -# cd ROSE_WebPages; chmod -R a+rx *; rsync -avz * liaoch@portal-auth.nersc.gov:/project/projectdirs/rosecompiler/www.rosecompiler.org -# cd ROSE_WebPages; chmod -R a+rx *; rsync -avz * liaoch@web-dev.nersc.gov:/www/host/rosecompiler # scp $(PACKAGE_NAME)-$(PACKAGE_VERSION)-HTML-Docs.tar.gz quinlan1@cmg-1.llnl.gov:/green_dev/www/casc/rose # Liao 12/7/2009, we mirror the content of the internal diff --git a/docs/Rose/Tutorial/CMakeLists.txt b/docs/Rose/Tutorial/CMakeLists.txt index 9fd4aa54267..7936f8ffdf9 100644 --- a/docs/Rose/Tutorial/CMakeLists.txt +++ b/docs/Rose/Tutorial/CMakeLists.txt @@ -23,14 +23,14 @@ include_directories(${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ) # templateParameter.tex instrumentationExample.tex addVariableDeclaration.tex \ # addAssignmentStmt.tex addExpression.tex\ # addFunctionDeclaration.tex buildCFG.tex parallelChecker.tex defuseAnalysis.tex \ -# binaryAnalysis.tex buildCallGraph.tex classHierarchyGraph.tex loopOptimization.tex inliner.tex outliner.tex \ +# buildCallGraph.tex classHierarchyGraph.tex loopOptimization.tex inliner.tex outliner.tex \ # parser-docs.tex codeCoverage.tex globalVariableHandling.tex scopeInformation.tex sideeffect-docs.tex \ # tauInstrumentation.tex templateSupport.tex dataBaseSupport.tex recognitionOfAbstractions.tex \ # debuggingSupport.tex commandlineProcessing.tex customGraphs.tex tutorialMakefile.tex wrapup.tex \ # appendix.tex astFileIO.tex uniqueNames.tex wholeGraphAST.tex addingComments.tex \ # partialRedundancyElimination.tex codeGenerationFormatControl.tex copyHelp.tex \ # roseHPCT.tex sharedMemoryTraversals.tex distributedMemoryTraversals.tex bugSeeding.tex \ -# modifiers.tex howToContribute.tex virtualCFG.tex binaryConstruction.tex reductionRecognition.tex \ +# modifiers.tex howToContribute.tex virtualCFG.tex reductionRecognition.tex \ # haskell.tex # ## This is an evolving list, but these are a few of the required files diff --git a/docs/Rose/Tutorial/Makefile.am b/docs/Rose/Tutorial/Makefile.am index 8241c103387..b1120147484 100644 --- a/docs/Rose/Tutorial/Makefile.am +++ b/docs/Rose/Tutorial/Makefile.am @@ -11,14 +11,14 @@ latexFiles = \ traversal.tex loopRecognition.tex typeInfoFromFunctionParameters.tex resolveOverloadedFunction.tex \ templateParameter.tex \ buildCFG.tex parallelChecker.tex defuseAnalysis.tex \ - binaryAnalysis.tex GenericDFA.tex buildCallGraph.tex buildVFA.tex classHierarchyGraph.tex loopOptimization.tex inliner.tex outliner.tex \ + GenericDFA.tex buildCallGraph.tex buildVFA.tex classHierarchyGraph.tex loopOptimization.tex inliner.tex outliner.tex \ parser-docs.tex codeCoverage.tex scopeInformation.tex sideeffect-docs.tex \ tauInstrumentation.tex templateSupport.tex dataBaseSupport.tex recognitionOfAbstractions.tex \ debuggingSupport.tex commandlineProcessing.tex customGraphs.tex tutorialMakefile.tex wrapup.tex \ appendix.tex astFileIO.tex uniqueNames.tex wholeGraphAST.tex addingComments.tex \ partialRedundancyElimination.tex codeGenerationFormatControl.tex copyHelp.tex \ - roseHPCT.tex sharedMemoryTraversals.tex distributedMemoryTraversals.tex bugSeeding.tex \ - modifiers.tex howToContribute.tex virtualCFG.tex binaryConstruction.tex reductionRecognition.tex \ + sharedMemoryTraversals.tex distributedMemoryTraversals.tex bugSeeding.tex \ + modifiers.tex howToContribute.tex virtualCFG.tex reductionRecognition.tex \ livenessAnalysis.tex CFGTraversalTutorial.tex parserBuildingBlocks.tex astConstruction.tex # This is an evolving list, but these are a few of the required files @@ -35,7 +35,6 @@ generatedCodeExamples = \ $(top_builddir)/tutorial/codeCoverage.out \ $(top_builddir)/tutorial/vcfg.pdf \ $(top_builddir)/tutorial/rose_inputCode_inlineTransformations.C \ - $(top_builddir)/tutorial/roseHPCT/profiled.out \ $(top_builddir)/tutorial/sourceTraversalTutorial.C \ $(top_builddir)/tutorial/binaryTraversalTutorial.C diff --git a/docs/Rose/Tutorial/binaryAnalysis.tex b/docs/Rose/Tutorial/binaryAnalysis.tex deleted file mode 100644 index b213187a0f0..00000000000 --- a/docs/Rose/Tutorial/binaryAnalysis.tex +++ /dev/null @@ -1,347 +0,0 @@ -\chapter{Binary Analysis} - -% This tutorial has been replaced by a doxygen version. - -See doxgyen ``Getting started with binary analysis'' chapter. - -\section{DataFlow Analysis} - -%\begin{figure} -%%\centerline{\epsfig{file=\TutorialExampleBuildDirectory/controlFlowGraph.ps, -%% height=1.3\linewidth,width=1.0\linewidth,angle=0}} -%\includegraphics[scale=0.7]{\TutorialExampleBuildDirectory/binaryAnalysis_pic2} -%\caption{Dataflowflow graph for example program.} -%\label{Tutorial:examplefig2} -%\end{figure} - -Based on the control flow many forms of dataflow analysis may be performed. -Dataflow analyses available are: - -\subsection{Def-Use Analysis} - -Definition-Usage is one way to compute dataflow information about a binary program. - -\subsection{Variable Analysis} - -This analysis helps to detect different types within a binary. -Currently, we use this analysis to detect interrupt calls and their parameters together with the def-use analysis. -This allows us to track back the value of parameters to the calls, such as eax and therefore -determine whether a interrupt call is for instance a write or read. -Another feature is the buffer overflow analysis. By traversing the CFG, we can detect buffer overflows. - - -\section{Dynamic Analysis} - - ROSE has support for dynamic analysis and for mixing of dynamic -and static analysis using the Intel Pin framework. This optional support in ROSE -requires a configure option ({\tt --with-IntelPin=$}). The {\tt path} in -the configure option is the {\bf absolute path} to the top level directory of the location of -the Intel Pin distribution. This support for Intel Pin has only been tested -on a 64bit Linux system using the most recent distribution of Intel Pin (version 2.6). - -Note: The dwarf support in ROSE is currently incompatable with the dwarf support in -Intel Pin. A message in the configuration of ROSE will detect if both support for -Dwarf and Intel Pin are both specified and exit with an error message that they -are incompatable options. - -See {\tt tutorial/intelPin} directory for examples using static and dynamic analysis. -These example will be improved in the future, at the moment they just call the -generation of the binary AST. - - -Note: We have added a fix to Intel Pin pin.H file: -\begin{verbatim} -// DQ (3/9/2009): Avoid letting "using" declarations into header files. -#ifndef REQUIRE_PIN_TO_USE_NAMESPACES -using namespace LEVEL_PINCLIENT; -#endif -\end{verbatim} -so that the namespace of Intel Pin would not be a problem for ROSE. -The development team have suggested that they may fix their use of "using" -declarations for namespaces in their header files. - -Also note that the path must be absolute since it will be the -prefix for the {\bf pin} executable to be run in the internal tests and -anything else might be a problem if the path does not contain the -current directory ({\bf "."}). Or, perhaps we should test for this -in the future. - -Note 2: Linking to libdwarf.a is a special problem. -Both ROSE and Intel Pin use libdwarf.a and both build shred libraries -that link to the static version of the library (libdwarf.a). This is -a problem im building Pin Tools since both the PinTool and librose.so will use -a statically linked dwarf library (internally). This causes the first -use of dwarf to fail, because there are then two versions of the same -library in place. The solution is to force at most one static version -of the library and let the other one be a shared library. - - Alternatively both the Pin tool and librose.so can be -built using the shared version of dwarf (libdwarf.so). -There is a makefile rule in libdwarf to build the shared -version of the library, but the default is to only build the -static library (libdwarf.a), so use {\tt make make libdwarf.so} -to build the shared library. So we allow ROSE to link to -the libdwarf.a (statically), which is how ROSE has always -worked (this may be revisited in the future). And we force -the Pin tool to link using the shared dwarf library (libdwarf.so). -% but with rpath so that we don't require the user to modify the LD\_LIBRARY\_PATH. -{\em Note: The specification of the location of libdwarf.so in the Intel Pin -directory structure is problematic using {\bf rpath}, so for the case of -using the Intel Pin package with ROSE please set the {\bf LD\_LIBRARY\_PATH} -explicitly (a better solution using {\bf rpath} may be made available in -the future).} - - - -\section{Analysis and Transformations on Binaries} - - This section demonstrates how the binary can be analyized and -transformed via operations on the AST. In this tutorial example we will -recognize sequences of NOP (No OPeration) instructions (both single byte -and less common multi-byte NOPs) and replace them in the binary with as -few multi-byte NOP instructions as required to overwrite the identified -NOP sequence (also called a {\em nop sled}). - -In the following subsections we will demonstrate three example codes that -work together to demonstrate aspects of the binary analysis and transforamation using -ROSE. All of these codes are located in the directory {\em tutorial/binaryAnalysis} -of the ROSE distribution. We show specifically: -\begin{enumerate} - \item How to insert NOP sequences into binaries via source-to-source transformations. - The tutorial example will demonstrate the trival insertion of random length - nop sequences into all functions of an input source code application. - The purpose of this is to really just generate arbitrary test codes - upon which to use in sperately demonstrating (and testing) the binary analysis - support and the binary transformation support (next). This example is - shown in figure~\ref{Tutorial:exampleTransformSourceToInsertNOPs}. - The file name is: - \item How to identify sequences of NOP instructions in the binary ({\em nop sleds}). - The tutorial example show how to identify arbitrary NOP sequences in the - binary. Note that our approach looks only for single instructions that have - no side-effect operations and thus qualify as a NOP, and specifically does not - look at collections of multiple statements that taken togehter have no - side-effect and thus could be considered a NOP sequence. Our test on each - instruciton is isolated to the {\tt SageInterface::isNOP(SgAsmInstruction*)} - function. Initially this function only detects NOP instructions that are - single and multi-byte Intel x86 suggested NOP instructions. The catagory of - NOP instructions that have no side-effects is broader than this and will - be addressed more completely in the future. This example is - shown in figures \ref{Tutorial:exampleTransformBinaryToDetectNOPs_header}, - \ref{Tutorial:exampleTransformBinaryToDetectNOPs_source}, and - \ref{Tutorial:exampleTransformBinaryToDetectNOPs_main}. - \item How transformations on the binary executable are done to support rewriting - all identified NOP sequences as Intel x86 suggested NOP instructions. - Importantly, this tutorial example of an AST rewrite does not change the - size of any part of the final executable. This example is - shown in figure~\ref{Tutorial:exampleTransformBinaryToInsertNOPs}. -\end{enumerate} - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/binaryAnalysis/nopSourceTransform.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/binaryAnalysis/nopSourceTransform.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Source-to-source transformation to introduce NOP assemble instructions in the - generated binary executable.} -\label{Tutorial:exampleTransformSourceToInsertNOPs} -\end{figure} - - -\subsection{Source-to-source transformations to introduce NOPs} - - This tutorial example (see figure~\ref{Tutorial:exampleTransformSourceToInsertNOPs}) -is a source-to-source trnasformation that is used to -generate test codes for the binary NOP sequence detection example and the -NOP sequence transformation example (the next two tutorial examples). -This tutorial uses C language {\em asm} statements that are inserted into -each function in the source code, the resulting generated source code (with {\em asm} -statements) is then compiled to generate inputs to use in our detection and -transformation of NOP sequences. Although it is possible, the backend -compiler (at least the one we are using), does not optimize away these -{\em asm} statements that represent NOP instructions. In general all -C and C++ compilers turn off optimizations upon encountering the {\em asm} -language construct, so it is easy to use this approach to build binaries -from arbitrary source code that have a range of properties. Seeding -the source code with such properties causes the binary to have the similar -properties. We include this example in the tutorial because it is a cute -example of how we can combine source code analsys with binary analysis -(in this case we are only supporting testing of the binary analysis). -Much more interesting example of the connection of source code and -binary analysis are available. - - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/binaryAnalysis/detectNopSequencesTraversal.h} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/binaryAnalysis/detectNopSequencesTraversal.h} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Header file for the traversal used to identify the NOP sequences in the binary executable.} -\label{Tutorial:exampleTransformBinaryToDetectNOPs_header} -\end{figure} - - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/binaryAnalysis/detectNopSequencesTraversal.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/binaryAnalysis/detectNopSequencesTraversal.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example code to identify the NOP sequences in the binary executable.} -\label{Tutorial:exampleTransformBinaryToDetectNOPs_source} -\end{figure} - - - - - - - - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/binaryAnalysis/detectNopSequences.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/binaryAnalysis/detectNopSequences.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Main program using the traversal to identify the NOP sequences in the binary executable.} -\label{Tutorial:exampleTransformBinaryToDetectNOPs_main} -\end{figure} - - -\subsection{Detection of NOP sequences in the binary AST} - - The tutorial example (see figures \ref{Tutorial:exampleTransformBinaryToDetectNOPs_header}, -\ref{Tutorial:exampleTransformBinaryToDetectNOPs_source}, and -\ref{Tutorial:exampleTransformBinaryToDetectNOPs_main}) -shows the detection of NOP sequences and is separated into three -figures (the header file, the source code, and the main program). The header file -and source file will be reused in the next tutorial example to demonstrate the -transformation of the NOP sequences that this tutorial identifies. The -transformation will be done on the AST (and a new modified executable generated -by unparsing the AST). - - Using a simple preorder traversal over the AST we identify independent sequences of -NOP instructions. This traversal save the sequence so that it can be used in both the -tutorial example that detects the NOP sequences and also the tutorial example that -will transform them to be more compact multi-byte NOP sequences that will use the -suggested Intel x86 multi-byte NOP instructions. - - In this example, the sequence of a NOP sequence is saved as the address of the -starting NOP instruction and the number of instructions in the sequence. The function -{\tt SageInterface::isNOP(SgAsmInstruction*)} is used to test of an instruction is -a NOP. Presently this test only identifies single or multi-byte NOP instrucitons -that have been suggested for use as single and multi-byte NOP instructions by Intel. -Other instruction may semantically be equivalent to a NOP instruction and they are -not identified in this initial work. Later work may include this capability and -for this purpose we have isolated out the {\tt SageInterface::isNOP(SgAsmInstruction*)}. -Note also that sequences of instructions may be semantically equivalent to a -NOP sequence and we also do not attempt to identify these (separate interface -functions in the {\tt SageInterface} namespace have been defined to support this -work; these functions are presently unimplemented. - -\begin{figure}[!h] -{\indent -{ -% \mySmallFontSize -\tiny - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/binaryAnalysis/nopBinaryTransform.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/binaryAnalysis/nopBinaryTransform.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example code showing the transformation of the binary executable.} -\label{Tutorial:exampleTransformBinaryToInsertNOPs} -\end{figure} - -\subsection{Transformations on the NOP sequences in the binary AST} - - Using the results from the previously presented traversal to identify -NOP sequences, we demonstrate the transformation to change these -locations of the binary (in the AST) and then regenerate the executable -to have a different representation. The new representation is a more clear -(obvious within manual binary analysis) and likely more compressed -representation using only the suggested Intel x86 multi-byte NOP. - - - -\subsection{Conclusions} - -\fixme{Not sure if the resulting executable will use the assembler on each -instruction in the generated binary from the unparsing within ROSE. This might -require some more work. So at the moment the AST is transformed and I have -to look into if the binary sees the effect of the transformation in the AST.} - - The identification and transformation have been deomonstrated on the AST -and can be expressed in the binary binary by calling the {\em backend()} -function in ROSE; which will regenerate the executable. The capability to -regenerate the executable will not always result in a properly formed -executable that can be executed, this depends upon the transformations done -and does ROSE does not have specialized support for this beyond regnerating -the binary executable from the AST. In the case of this NOP transformation -we have not changed the size of any part of the binary so any relative offsets -need not be fixed up. Assumeing we have not accedentaly interpreted data that -had values that matched parts of the opcodes that were transformed, then resulting -binary executable should execute without problems. This transformation however -makes clear how critical it is that data not be interpreted as instructions -(which could randomly be interpreted as NOPs in the case of this tutorial example). - diff --git a/docs/Rose/Tutorial/binaryConstruction.tex b/docs/Rose/Tutorial/binaryConstruction.tex deleted file mode 100644 index 351cc90878f..00000000000 --- a/docs/Rose/Tutorial/binaryConstruction.tex +++ /dev/null @@ -1,416 +0,0 @@ -\chapter{Binary Construction} - -ROSE is normally used in such a way that a file (source code or -binary) is parsed to construct an AST, then operations are performed -on the AST, and the modified AST is unparsed to create a new source or -binary file. However, it is also possible to construct an AST -explicitly without parsing and then use that AST to generate the -output. The AST construction interface for binary files was designed -so that working files could be created simply, while still providing -methods to control the finer details of the resulting file. - -The example in this chapter shows how to construct a statically linked -ELF executable containing a small ``.text'' section that simply causes -the process to exit with a specific non-zero value. - -\section{Constructors} - -The AST node constructors are designed to construct the tree from the -root down, and thus generally take the parent node as an -argument. Nodes that refer to other nodes as prerequisites also take -those prerequisites as arguments. For instance, an ELF Relocation -Section is a child of the ELF File Header but also needs an ELF Symbol -Table and therefore takes both objects as constructor arguments. - -\section{Read-Only Data Members} - -When two or more file formats have a similar notion then that notion -is represented in a base class. However, part of the information may -continue to survive in the specialized class. In these situations -modifications to the specilized data will probably be overridden by -the generic values from the base class. For instance, all formats -have a notion of byte order which is represented in the base class -SgAsmGenericHeader as little- or big-endian (an enumeration -constant). The ELF specification provides an 8-bit unsigned field to -store the byte order and therefore has potentially more than two -possibilities. Any value assigned to the ELF-specific byte order will -likely be overwritten by the generic byte order before the AST is -unparsed. - -A similar situation arises with section offsets, sizes, memory -mappings, permissions, etc. The SgAsmGenericSection class represents -ELF Sections, ELF Segments, PE Objects, and other contiguous regions -of a file and has methods for obtaining/setting these values. In -addition, many of the formats have some sort of table that describes -these sections and which also contains similar information (e.g., the -ELF Segment Table, a.k.a., the ELF Program Header Table). As above, -the generic representation of these notions (stored in -SgAsmGenericSection) override the format-specific values (stored in -SgAsmElfSegmentEntry). - -ROSETTA doesn't make a distinction between data members that can be -user-modified and data members that should be modified only by the -parser. Therefore it is up to the user to be aware that certain data -members will have their values computed or copied from other locations -in the AST during the unparsing phase. - -\section{Constructing the Executable File Container} - -All executable files are stored as children of an SgAsmGenericFile -node. The children are file format headers (SgAsmGenericHeader) such -as an ELF File Header (SgAsmElfFileHeader). This design allows a -single executable file to potentially contain more than one executable -and is used by formats like Windows-PE where the file contains a DOS -File Header as well as a PE File Header. - -For the purposes of this example the SgAsmGenericFile node will serve -as the root of the AST and therefore we do not need to specify a -parent in the constructor argument list. - -\begin{verbatim} -SgAsmGenericFile *ef = new SgAsmGenericFile; -\end{verbatim} - -\section{Constructing the ELF File Header} - -The ELF File Header is the first thing in the file, always at offset -zero. File headers are always children of an SgAsmGenericFile which is -specified as the constructor argument. - -The section constructors (a file header is a kind of section) always -create the new section so it begins at the current end-of-file and -contains at least one byte. This ensures that each section has a -unique starting address, which will be important when file memory is -actually allocated and sections need to be moved around--the allocator -needs to know the relative positions of the sections in order to -correctly relocate them. - -If we were parsing an ELF file we would usually use ROSE's frontend() -method. However, one can also parse the file by first constructing the -SgAsmElfFileHeader and then invoking its parse() method, which parses -the ELF File Header and everything that can be reached from that -header. - -We use the typical 0x400000 as the virtual address of the main LOAD -segment, which occupies the first part of the file up through the end -of the ``.text'' section (see below). ELF File Headers don't actually -store a base address, so instead of assigning one to the -SgAsmElfFileHeader we'll leave the header's base address at the -default zero and add base\_va explicitly whenever we need to. - -\begin{verbatim} -SgAsmElfFileHeader *fhdr = new SgAsmElfFileHeader(ef); -fhdr->get_exec_format()->set_word_size(8); /* default is 32-bit; we want 64-bit */ -fhdr->set_isa(SgAsmExecutableFileFormat::ISA_X8664_Family); /* instruction set architecture; default is ISA_IA32_386 */ -rose_addr_t base_va = 0x400000; /* base virtual address */ -\end{verbatim} - -\section{Constructing the ELF Segment Table} - -ELF executable files always have an ELF Segment Table (also called the -ELF Program Header Table), which usually appears immediately after the -ELF File Header. The ELF Segment Table describes contiguous regions of -the file that should be memory mapped by the loader. ELF Segments -don't have names--names are imparted to the segment by virtue of the -segment also being described by the ELF Section Table, which we'll -create later. - -Being a contiguous region of the file, an ELF Segment Table -(SgAsmElfSegmentTable) is derived from SgAsmGenericSection. All -non-header sections have a header as a parent, which we supply as an -argument to the constructor. Since all ELF Segments will be children of -the ELF File Header rather than children of the ELF Segment Table, we -could define the ELF Segment Table at the end rather than here. But -defining it now is an easy way to get it located in its usuall -location immediately after the ELF File Header. - -\begin{verbatim} -SgAsmElfSegmentTable *segtab = new SgAsmElfSegmentTable(fhdr); -\end{verbatim} - -\section{Constructing the .text Section} - -ROSE doesn't treat a ``.text'' section as being anything particularly -special--it's just a regular SgAsmElfSection, which derives from -SgAsmGenericSection. However, in this example, we want to make sure -that our ``.text'' section gets initialized with some -instructions. The easiest way to do that is to specialize -SgAsmElfSection and override or augment a few of the virtual -functions. - -We need to override two functions. First, the calculate\_sizes() -function should return the size we need to store the -instructions. We'll treat the instructions as an array of entries each -entry being one byte of the instruction stream. In other words, each -``entry'' is one byte in length consisting of one required byte and no -optional bytes. - -We need to also override the unparse() method since the base class -will just fill the ``.text'' section with zeros. The -SgAsmGenericSection::write method we use will write the instructions -starting at the first byte of the section. - -Finally, we need to augment the reallocate() method. This method is -reponsible for allocating space in the file for the section and -performing any other necessary pre-unparsing actions. We don't need to -allocate space since the base class's method will take care of that in -conjuction with our version of calculate\_sizes(), but we do need to -set a special ELF flag (SHF\_ALLOC) in the ELF Segment Table entry for -this section. There's a few ways to accomplish this. We do it this way -because the ELF Section Table Entry is not created until later and we -want to demonstrate how to keep all .text-related code in close -proximity. - -\begin{verbatim} -class TextSection : public SgAsmElfSection { -public: - TextSection(SgAsmElfFileHeader *fhdr, size_t ins_size, const unsigned char *ins_bytes) - : SgAsmElfSection(fhdr), ins_size(ins_size), ins_bytes(ins_bytes) - {} - virtual rose_addr_t calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const { - if (entsize) *entsize = 1; /* an "entry" is one byte of instruction */ - if (required) *required = 1; /* each "entry" is also stored in one byte of the file */ - if (optional) *optional = 0; /* there is no extra data per instruction byte */ - if (entcount) *entcount = ins_size; /* number of "entries" is the total instruction bytes */ - return ins_size; /* return value is section size required */ - } - virtual bool reallocate() { - bool retval = SgAsmElfSection::reallocate(); /* returns true if size or position of any section changed */ - SgAsmElfSectionTableEntry *ste = get_section_entry(); - ste->set_sh_flags(ste->get_sh_flags() | 0x02); /* set the SHF_ALLOC bit */ - return retval; - } - virtual void unparse(std::ostream &f) const { - write(f, 0, ins_size, ins_bytes); /* Write the instructions at offset zero in section */ - } - size_t ins_size; - const unsigned char *ins_bytes; -}; -\end{verbatim} - -The section constructors and reallocators don't worry about alignment -issues--they always allocate from the next available byte. However, -instructions typically need to satisfy some alignment constraints. We -can easily adjust the file offset chosen by the constructor, but we -also need to tell the reallocator about the alignment constraint. Even -if we didn't ever resize the ``.text'' section the reallocator could -be called for some other section in such a way that it needs to move -the ``.text'' section to a new file offset. - -For the purpose of this tutorial we want to be very picky about the -location of the ELF Segment Table. We want it to immediately follow -the ELF File Header without any intervening bytes of padding. At the -current time, the ELF File Header has a size of one byte and will -eventually be reallocated. When we reallocate the header the -subsequent sections will need to be shifted to higher file -offsets. When this happens, the allocator shifts them all by the same -amount taking care to satisfy all alignment constraints, which means -that an alignment constraint of byte bytes on the ``.text'' section -will induce a similar alignment on the ELF Segment Table. Since we -don't want that, the best practice is to call reallocate() now, before -we create the ``.text'' section. - -\begin{verbatim} -ef->reallocate(); /* Give existing sections a chance to allocate file space */ -static const unsigned char instructions[] = {0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x56, 0x00, 0x00, 0x00, 0xcd, 0x80}; -SgAsmElfSection *text = new TextSection(fhdr, NELMTS(instructions), instructions); -text->set_purpose(SgAsmGenericSection::SP_PROGRAM); /* Program-supplied text/data/etc. */ -text->set_offset(alignUp(text->get_offset(), 4)); /* Align on an 8-byte boundary */ -text->set_file_alignment(4); /* Tell reallocator about alignment constraint */ -text->set_mapped_alignment(4); /* Alignment constraint for memory mapping */ -text->set_mapped_rva(base_va+text->get_offset()); /* Mapped address is based on file offset */ -text->set_mapped_size(text->get_size()); /* Mapped size is same as file size */ -text->set_mapped_rperm(true); /* Readable */ -text->set_mapped_wperm(false); /* Not writable */ -text->set_mapped_xperm(true); /* Executable */ -\end{verbatim} - -At this point the text section doesn't have a name. We want to name it -``.text'' and we want those characters to eventually be stored in the -ELF file in a string table which we'll provide later. In ELF, section -names are represented by the section's entry in the ELF Section Table -as an offset into an ELF String Table for a NUL-terminated ASCII -string. ROSE manages strings using the SgAsmGenericString class, which -has two subclasses: one for strings that aren't stored in the -executable file (SgAsmBasicString) and one for strings that are stored -in the file (SgAsmStoredString). Both are capable of string an -std::string value and querying its byte offset (although -SgAsmBasicString::get\_offset() will always return -SgAsmGenericString::unallocated). Since we haven't added the -``.text'' section to the ELF Section Table yet the new section has an -SgAsmBasicString name. We can assign a string to the name now and the -string will be allocated in the ELF file when we've provided further -information. - -\begin{verbatim} -text->get_name()->set_string(".text"); -\end{verbatim} - -The ELF File Header needs to know the virtual address at which to -start running the program. In ROSE, virtual addresses can be attached -to a specific section so that if the section is ever moved the address -is automatically updated. Some formats allow more than one entry -address which is why the method is called add\_entry\_rva() rather than -set\_entry\_rva(). ELF, however, only allows one entry address. - -\begin{verbatim} -rose_rva_t entry_rva(text->get_mapped_rva(), text); -fhdr->add_entry_rva(entry_rva); -\end{verbatim} - -\section{Constructing a LOAD Segment} - -ELF Segments define parts of an executable file that should be mapped -into memory by the loader. A program will typically have a LOAD -segment that begins at the first byte of the file and continues -through the last instruction (in our case, the end of the ``.text'' -section) and which is mapped to virtual address 0x400000. - -We've already created the ELF Segment Table, so all we need to do now -is create an ELF Segment and add it to the ELF Segment Table. ELF -Segments, like ELF Sections, are represented by SgAsmElfSection. An -SgAsmElfSection is an ELF Section if it has an entry in the ELF -Section Table, and/or it's an ELF Segment if it has an entry in the -ELF Segment Table. The methods get\_section\_entry() and -get\_segment\_entry() retrieve the actual entries in those tables. - -Recall that the constructor creates new sections located at the -current end-of-file and containing one byte. Our LOAD segment needs to -have a different offset and size. - -\begin{verbatim} -SgAsmElfSection *seg1 = new SgAsmElfSection(fhdr); /* ELF Segments are represented by SgAsmElfSection */ -seg1->get_name()->set_string("LOAD"); /* Segment names aren't saved (but useful for debugging) */ -seg1->set_offset(0); /* Starts at beginning of file */ -seg1->set_size(text->get_offset() + text->get_size()); /* Extends to end of .text section */ -seg1->set_mapped_rva(base_va); /* Typically mapped by loader to this memory address */ -seg1->set_mapped_size(seg1->get_size()); /* Make mapped size match size in the file */ -seg1->set_mapped_rperm(true); /* Readable */ -seg1->set_mapped_wperm(false); /* Not writable */ -seg1->set_mapped_xperm(true); /* Executable */ -segtab->add_section(seg1); /* Add definition to ELF Segment Table */ -\end{verbatim} - -\section{Constructing a PAX Segment} - -This documentation shows how to construct a generic ELF Segment, -giving it a particular file offset and size. ELF Segments don't have -names stored in the file, but we can assign a name to the AST node to -aid in debugging--it just won't be written out. When parsing an ELF -file, segment names are generated based on the type stored in the -entry of the ELF Segment Table. For a PAX segment we want this type to -be PT\_PAX\_FLAGS (the default is PT\_LOAD). - -\begin{verbatim} -SgAsmElfSection *pax = new SgAsmElfSection(fhdr); -pax->get_name()->set_string("PAX Flags"); /* Name just for debugging */ -pax->set_offset(0); /* Override address to be at zero rather than EOF */ -pax->set_size(0); /* Override size to be zero rather than one byte */ -segtab->add_section(pax); /* Add definition to ELF Segment Table */ -pax->get_segment_entry()->set_type(SgAsmElfSegmentTableEntry::PT_PAX_FLAGS); -\end{verbatim} - -\section{Constructing a String Table} - -An ELF String Table always corresponds to a single ELF Section of -class SgAsmElfStringSection and thus you'll often see the term ``ELF -String Section'' used interchangeably with ``ELF String Table'' even -though they're two unique but closely tied classes internally. - -When the ELF String Section is created a corresponding ELF String -Table is also created under the covers. Since string tables manage -their own memory in reponse to the strings they contain, one should -never adjust the size of the ELF String Section (it's actually fine to -enlarge the section and the new space will become free space in the -string table). - -ELF files typically have multiple string tables so that section names -are in a different section than symbol names, etc. In this tutorial -we'll create the section names string table, typically called -``.shstrtab'', but use it for all string storage. - -\begin{verbatim} -SgAsmElfStringSection *shstrtab = new SgAsmElfStringSection(fhdr); -shstrtab->get_name()->set_string(".shstrtab"); -\end{verbatim} - -\section{Constructing an ELF Section Table} - -We do this last because we want the ELF Section Table to appear at the -end of the file and this is the easiest way to achieve that. There's -really not much one needs to do to create the ELF Section Table other -than provide the ELF File Header as a parent and supply a string -table. - -The string table we created above isn't activated until we assign it -to the ELF Section Table. The first SgAsmElfStringSection added to the -SgAsmElfSectionTable becomes the string table for storing section -names. It is permissible to add other sections to the table before -adding the string table. - -\begin{verbatim} -SgAsmElfSectionTable *sectab = new SgAsmElfSectionTable(fhdr); -sectab->add_section(text); /* Add the .text section */ -sectab->add_section(shstrtab); /* Add the string table to store section names. */ -\end{verbatim} - -\section{Allocating Space} - -Prior to calling unparse(), we need to make sure that all sections -have a chance to allocate space for themselves, and perform any other -operations necessary. It's not always possible to determine sizes at -an earlier time, and most constructors would have declared sizes of -only one byte. - -The reallocate() method is defined in the SgAsmGenericFile class since -it operates over the entire collection of sections simultaneously. In -other words, if a section needs to grow then all the sections located -after it in the file need to be shifted to higher file offsets. - -\begin{verbatim} -ef->reallocate(); -\end{verbatim} - -The reallocate() method has a shortcoming (as of 2008-12-19) in that -it might not correctly update memory mappings in the case when the -mapping for a section is inferred from the mapping of a containing -segment. This can happen in our example since the ``.text'' section's -memory mapping is a function of the LOAD Segment mapping. The -work-around is to adjust mappings for these situations and then call -reallocate() one final time. This final reallocate() call won't move -any sections, but should always be the last thing to call before -unparsing() (it gives sections a chance to update data dependencies -which is not possible during unparse() due to its const nature). - -\begin{verbatim} -text->set_mapped_rva(seg1->get_mapped_rva()+(text->get_offset()-seg1->get_offset())); -ef->reallocate(); /*won't resize or move things this time since we didn't modify much since the last call to reallocate()*/ -\end{verbatim} - -\section{Produce a Debugging Dump} - -A debugging dump can be made with the following code. This dump will -not be identical to the one produced by parsing and dumping the -resulting file since we never parsed a file (a dump contains some -information that's parser-specific). - -\begin{verbatim} -ef->dump(stdout); -SgAsmGenericSectionPtrList all = ef->get_sections(true); -for (size_t i=0; idump(stdout, " ", -1); -} -\end{verbatim} - -\section{Produce the Executable File} - -The executable file is produced by unparsing the AST. - -\begin{verbatim} -std::ofstream f("a.out"); -ef->unparse(f); -\end{verbatim} - -Note that the resulting file will not be created with execute -permission--that must be added manually. diff --git a/docs/Rose/Tutorial/dwarfDebugSupport.tex b/docs/Rose/Tutorial/dwarfDebugSupport.tex deleted file mode 100644 index 8a21fc737a1..00000000000 --- a/docs/Rose/Tutorial/dwarfDebugSupport.tex +++ /dev/null @@ -1,179 +0,0 @@ -\chapter{Dwarf Debug Support} - -% Copied from the Dwarf wikipedia page. -DWARF is a widely used, standardized debugging data format. DWARF was originally designed -along with ELF, although it is independent of object file formats. The name is a -pun on "ELF" that has no official meaning but "may be an acronym for 'Debug With -Attributed Record Format'". See Wikipedia for more information about the Dwarf -debug format. - -This chapter presents the support in ROSE for Dwarf 3 debug information; its -representation in the AST and its use in binary analysis tools. This work is part of -general work to support as much information as possible about binaries. - -In the following sections we use a small example (see figure \ref{Tutorial:dwarfAnalysisExampleSourceCode}) -that demonstrates various features of Dwarf. The source code of our binary example is: - -\commentout{ -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/dwarfAnalysis.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/dwarfAnalysis.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example source code (typical for reading in a binary or source file).} -\label{Tutorial:dwarfAnalysisExampleSourceCode} -\end{figure} -} - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/inputCode_dwarfAnalysis.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/inputCode_dwarfAnalysis.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example source code used to generate Dwarf AST for analysis.} -\label{Tutorial:dwarfAnalysisExampleSourceCode} -\end{figure} - - -Much larger binaries can be analyzed, but such larger binary executables are more -difficult to present (in this tutorial). - - -\section{ROSE AST of Dwarf IR nodes} - - ROSE tools process the binary into an AST that is used to represent all the -information in the binary executable. Figure \ref{Tutorial:Dwarf_AST_example} -shows the subset of that AST (which includes the rest of the binary file format -and the disassembled instructions) that is specific to Dwarf. A command line option -({\em -rose:visualize\_dwarf\_only}) is used to restrict the generated dot file -visualization to just the Dwarf information. This option is used in combination with -{\em -rose:read\_executable\_file\_format\_only} to process only the binary file format -(thus skipping the instruction disassembly). - -\begin{figure}[h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} -% \includegraphics[scale=0.9]{\TutorialExampleBuildDirectory/inputCode_dwarfAnalysis} - \includegraphics[viewport=5 1 50 500,scale=0.9]{\TutorialExampleBuildDirectory/inputCode_dwarfAnalysis} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \includegraphics{\TutorialExampleBuildDirectory/inputCode_dwarfAnalysis} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Dwarf AST (subset of ROSE binary AST).} -\label{Tutorial:Dwarf_AST_example} -\end{figure} - - - -\section{Source Position to Instruction Address Mapping} - - One of the valuable parts of Dwarf is the mapping between the -source lines and the instruction addresses at a statement level -(provided in the {\em .debug\_line} section). -Even though Dwarf does not represent all statements in the source -code, the mapping is significantly finer granularity than that -provided at only the function level by the symbol table (which -identifies the functions by instruction address, but not the -source file line numbers; the later requires source code analysis). - -The example code in \ref{Tutorial:dwarfInstructionAddressToSourceLineExampleSourceCode} -shows the mapping between the source code lines and the instruction addresses. - -\fixme{This need to be improved to correctly return sets of lines and sets of addresses in - what might be a second interface.} - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleDirectory/dwarfInstructionAddressToSourceLineAnalysis.C} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/dwarfInstructionAddressToSourceLineAnalysis.C} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example source code (typical for reading in a binary or source file).} -\label{Tutorial:dwarfInstructionAddressToSourceLineExampleSourceCode} -\end{figure} - -Output from the compilation of this test code and running it with the example input -results in the output shown in figure \ref{Tutorial:dwarfInstructionAddressToSourceLineExampleOutput}. -This output shows the binary executables instruction address range (binary compiled on -Linux x86 system), the range of lines of source code used by the binary executable, -the mapping of a source code range of line numbers to the instruction addresses, -and the mapping of a range of instruction addresses to the source code line numbers. - -%\fixme{Need to handle case of were each query can return a set of line or set of -% addresses. This may be a different interface for simplicty.} - -\begin{figure}[!h] -{\indent -{\mySmallFontSize - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting{\TutorialExampleBuildDirectory/inputCode_dwarfAnalysis.out} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/inputCode_dwarfAnalysis.out} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{Example source code (typical for reading in a binary or source file).} -\label{Tutorial:dwarfInstructionAddressToSourceLineExampleOutput} -\end{figure} - - - - - - diff --git a/docs/Rose/Tutorial/roseHPCT.tex b/docs/Rose/Tutorial/roseHPCT.tex deleted file mode 100644 index 2ce177095e7..00000000000 --- a/docs/Rose/Tutorial/roseHPCT.tex +++ /dev/null @@ -1,496 +0,0 @@ -%========================================================================== -\chapter{ROSE-HPCToolKit Interface} -\label{chap:rosehpct} -ROSE-HPCToolKit is designed to read in performance data generated -by HPCToolkit (and recently GNU gprof) and annotate ROSE AST with performance -metrics. -It is included in the ROSE distribution and -enabled by default if an existing installation of the Gnome XML library, libxml2 -(\url{http://xmlsoft.org}) can be detected by ROSE's configure script. -Or it can be enabled explicitly by specifying the \texttt{--enable-rosehpct} option -when running configure. -% and be sure that you have an existing installation of the Gnome XML library, libxml2 (\url{http://xmlsoft.org}). - -The HPCToolkit (\url{http://www.hipersoft.rice.edu/hpctoolkit}) is a -set of tools for analyzing the dynamic performance behavior of -applications. It includes a tool that instruments a program's binary, -in order to observe CPU hardware counters during execution; additional -post-processing tools attribute the observed data to statements in the -original source code. HPCToolkit stores this data and the source -attributions in XML files. In this chapter, we give an overview of -simple interfaces in ROSE that can read this data and attach it to the -AST. - -GNU gprof is a basic but easy to use profiling tool. -It produces an execution profile of applications. -gprof's output is a flat profile for each function by default, which is not -very interesting to us. -We use a line-by-line output with full file path information generated by using -option {\tt -l -L} with gprof. - -\input{\TutorialExampleBuildDirectory/roseHPCT/is-static} - -%========================================================================== -\section{An HPCToolkit Example Run} -\label{chap:rosehpct:run} - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[language=C,numbers=left,stepnumber=5]{\TutorialExampleBuildDirectory/roseHPCT/profiled.c.aa} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/profiled.c.aa} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{profiled.c (part 1 of 2): Sample input program, profiled using the HPCToolkit.} -\label{Tutorial:roseHPCT:profiled:aa} -\end{figure} -%-------------------------------------------------------------------------- - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[language=C,numbers=left,stepnumber=5,firstnumber=66]{\TutorialExampleBuildDirectory/roseHPCT/profiled.c.ab} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/profiled.c.ab} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{profiled.c (part 2 of 2): Sample input program, profiled using the HPCToolkit.} -\label{Tutorial:roseHPCT:profiled:ab} -\end{figure} -%-------------------------------------------------------------------------- - -Consider the sample source program shown in -Figures~\ref{Tutorial:roseHPCT:profiled:aa}--\ref{Tutorial:roseHPCT:profiled:ab}. -This program takes an integer $n$ on the command line, and has a -number of loops whose flop and memory-operation complexity are either -$\Theta(n)$ or $\Theta(n^2)$. For this example, we would expect the -loop nest at line 56, which has $O(n^2)$ cost, to be the most -expensive loop in the program for large $n$. - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[language=XML,numbers=left,stepnumber=5]{\TutorialExampleBuildDirectory/roseHPCT/PAPI_TOT_CYC.xml.aa} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/PAPI_TOT_CYC.xml.aa} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{XML schema for HPCToolkit data files: This schema, prepended -to each of the HPCToolkit-generated XML files, describes the format of -the profiling data. This particular schema was generated by HPCToolkit -1.0.4.} -\label{Tutorial:roseHPCT:xml:schema} -\end{figure} -%-------------------------------------------------------------------------- - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[language=XML,numbers=left,stepnumber=5,firstnumber=62]{\TutorialExampleBuildDirectory/roseHPCT/PAPI_TOT_CYC.xml.ab} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/PAPI_TOT_CYC.xml.ab} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{PAPI\_TOT\_CYC.xml: Sample cycle counts observed during -profiling, generated from running the HPCToolkit on profiled.c -(Figures~\ref{Tutorial:roseHPCT:profiled:aa}--\ref{Tutorial:roseHPCT:profiled:ab}.) -These lines would appear after the schema shown in -Figure~\ref{Tutorial:roseHPCT:xml:schema}.} -\label{Tutorial:roseHPCT:xml:cycles} -\end{figure} -%-------------------------------------------------------------------------- - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[language=XML,numbers=left,stepnumber=5,firstnumber=62]{\TutorialExampleBuildDirectory/roseHPCT/PAPI_FP_OPS.xml.ab} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/PAPI_FP_OPS.xml.ab} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{PAPI\_FP\_OPS.xml: Sample flop counts observed during -profiling, generated from running the HPCToolkit on profiled.c -(Figures~\ref{Tutorial:roseHPCT:profiled:aa}--\ref{Tutorial:roseHPCT:profiled:ab}.) -These lines would appear after the schema shown in -Figure~\ref{Tutorial:roseHPCT:xml:schema}.} -\label{Tutorial:roseHPCT:xml:flops} -\end{figure} -%-------------------------------------------------------------------------- - -Suppose we use the HPCToolkit to profile this program, collecting -cycle counts and floating-point instructions.\footnote{In this -example, HPCToolkit uses the PAPI to read CPU counters -(\url{http://icl.cs.utk.edu/papi}).} HPCToolkit will generate one XML -file for each metric. - -A schema specifying the format of these XML files appears in -Figure~\ref{Tutorial:roseHPCT:xml:schema}. In essence, this schema -specifies that the XML file will contain a structured, abstract -representation of the program in terms of abstract program entities -such as ``modules,'' ``procedures,'' ``loops,'' and ``statements.'' -Each of these entities may have line number information and a -``metric'' value. (Refer to the HPCToolkit documentation for more -information.) This schema is always the first part of an -HPCToolkit-generated XML profile data file. - -We ran HPCToolkit on the program in -Figures~\ref{Tutorial:roseHPCT:profiled:aa}--\ref{Tutorial:roseHPCT:profiled:ab}, -and collected cycle and flop counter data. The actual XML files -storing this data appear in Figures~\ref{Tutorial:roseHPCT:xml:cycles} -and~\ref{Tutorial:roseHPCT:xml:flops}. By convention, these metrics -are named according to their PAPI symbolic name, as shown on line 67 -in both Figures~\ref{Tutorial:roseHPCT:xml:cycles} -and~\ref{Tutorial:roseHPCT:xml:flops}. According to the cycle data on -line 90 of Figure~\ref{Tutorial:roseHPCT:xml:cycles}, the most -expensive statement in profiled.c is line 62 of -Figure~\ref{Tutorial:roseHPCT:profiled:aa}, as expected. - -%========================================================================== -\clearpage -\section{Attaching HPCToolkit Data to the ROSE AST} -\label{chap:rosehpct:attach} - -To attach the data of Figures~\ref{Tutorial:roseHPCT:xml:cycles} -and~\ref{Tutorial:roseHPCT:xml:flops} to the AST, we augment a basic -ROSE translator with two additional calls, as shown in -Figure~\ref{Tutorial:roseHPCT:attach}, lines 47--48 and 54. We -describe these calls below. - -%-------------------------------------------------------------------------- -\begin{figure}[!h] -{\indent -{\mySmallFontSize - - -% Do this when processing latex to generate non-html (not using latex2html) -\begin{latexonly} - \lstinputlisting[numbers=left,stepnumber=5]{\TutorialExampleDirectory/roseHPCT/attachMetrics.cc} -\end{latexonly} - -% Do this when processing latex to build html (using latex2html) -\begin{htmlonly} - \verbatiminput{\TutorialExampleDirectory/roseHPCT/attachMetrics.cc} -\end{htmlonly} - -% end of scope in font size -} -% End of scope in indentation -} -\caption{attachMetrics.cc: Sample translator to attach HPCToolkit metrics to the AST.} -\label{Tutorial:roseHPCT:attach} -\end{figure} -%-------------------------------------------------------------------------- - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Calling ROSE-HPCT} - -We must first include rosehpct/rosehpct.hh, as shown on line 6 of -Figure~\ref{Tutorial:roseHPCT:attach}. All ROSE-HPCT routines and -intermediate data structures reside in the RoseHPCT namespace. - -Next, lines 47--48 of Figure~\ref{Tutorial:roseHPCT:attach} store the -contents of the raw XML file into an intermediate data structure of -type RoseHPCT::ProgramTreeList\_t. The RoseHPCT::loadProfilingFiles() -routine processes command-line arguments, extracting -ROSE-HPCT-specific options that specify the files. We discuss these -options in Section~\ref{sec:rosehpct:cmdlineopts}. - -Line 54 of Figure~\ref{Tutorial:roseHPCT:attach}, attaches the -intermediate profile data structure to the ROSE AST. The -RoseHPCT::attachMetrics() routine creates new persistent attributes -that store the counter data.\footnote{The last parameter to -RoseHPCT::attachMetrics() is a boolean that, when true, enables -verbose (debugging) messages to standard error.} The attributes are -named using the metric name taken from the XML file (see lines 67 of -Figures~\ref{Tutorial:roseHPCT:xml:cycles}--\ref{Tutorial:roseHPCT:xml:flops}); -in this example, the attributes are named PAPI\_TOT\_CYC and -PAPI\_FP\_OPS. Following the conventions of persistent attribute -mechanism as described in Chapter~\ref{chap:traversals}, the -attributes themselves are of type RoseHPCT::MetricAttr, which derives -from the AstAttribute type. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Retrieving the attribute values} - -We retrieve the attribute values as described in -Chapter~\ref{chap:traversals}. In particular, given a located node -with cycle and flop attribute values, the printFlopRate() routine -defined in lines 11--42 of Figure~\ref{Tutorial:roseHPCT:attach} -prints the source position, AST node type, and estimated flops per -cycle. We call printFlopRate() for each expression statement -(SgExpressionStmt), for-initializer (SgForInitStatement), and -for-statement (SgForStatement) in lines 59--66 of -Figure~\ref{Tutorial:roseHPCT:attach}. The output is shown in -Figure~\ref{Tutorial:roseHPCT:profiled:out}. - -Inspecting the output carefully, you may notice seeming discrepancies -between the values shown and the values that appear in the XML files, -or other values which seem unintuitive. We explain how these values -are derived in Section~\ref{sec:rosehpct:metprop}. - -This example dumps the AST as a PDF file, as shown on line 68 of -Figure~\ref{Tutorial:roseHPCT:attach}. You can inspect this file to -confirm where attributes have been attached. We show an example of -such a page in Figure~\ref{Tutorial:roseHPCT:pdf}. This page is the -SgExprStatement node representing the sum-accumulate on line 26 of -Figure~\ref{Tutorial:roseHPCT:profiled:aa}. - -\begin{figure}[!ht] -{\mySmallFontSize - \verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/profiled.out} -} -\caption{Sample output, when running attachMetrics.cc -(Figure~\ref{Tutorial:roseHPCT:attach}) with the XML inputs in -Figures~\ref{Tutorial:roseHPCT:xml:cycles}--\ref{Tutorial:roseHPCT:xml:flops}. Here, -we only show the output sent to standard output (\emph{i.e.}, cout and -not cerr).} -\label{Tutorial:roseHPCT:profiled:out} -\end{figure} - -\begin{figure}[!hb] -\includegraphics[width=6in,trim=0in 7.8in 2in 0in, clip]{\TutorialExampleBuildDirectory/roseHPCT/profiled-p93.pdf} -\caption{Sample PDF showing attributes.} -\label{Tutorial:roseHPCT:pdf} -\end{figure} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\subsection{Metric propagation} -\label{sec:rosehpct:metprop} - -The example program in Figure~\ref{Tutorial:roseHPCT:attach} dumps -metric values at each expression statement, for-initializer, and -for-statement, but the input XML files in -Figure~\ref{Tutorial:roseHPCT:xml:cycles}--\ref{Tutorial:roseHPCT:xml:flops} -only attribute the profile data to ``statements'' that are not loop -constructs. (The \texttt{} XML tags refer to statements, -intended to be ``simple'' non-scoping executable statements; a -separate \texttt{} tag would refer to a loop.) Since the XML -file specifies statements only by source line number, -RoseHPCT::attachMetrics() attributes measurements to AST nodes in a -heuristic way. - -For example, lines 78--80 of Figure~\ref{Tutorial:roseHPCT:xml:cycles} -indicate that all executions of the ``simple statements'' of line 25 -of the original source (Figure~\ref{Tutorial:roseHPCT:profiled:aa}) -accounted for 65534 observed cycles, and that line 26 accounted for an -additional 65534 cycles. In the AST, there are multiple ``statement'' -and expression nodes that occur on line 25; indeed, -Figure~\ref{Tutorial:roseHPCT:profiled:out} lists 4 such -statements. - -The ROSE-HPCT modules uses a heuristic which only assigns \texttt{} metric values to non-scoping nodes derived from -SgStatement. When multiple SgStatement nodes occur at a particular -source line, -%ROSE-HPCT simply divides the observed metric equally among all the SgStatement nodes on that line. -ROSE-HPCT simply attaches the metric to each of them. -But only one of them will be used for propagating metrics to parent scopes. - -How is the measurement of 65534 cycles attributed to all of the AST -nodes corresponding to line 25 of -Figure~\ref{Tutorial:roseHPCT:profiled:aa}? Indeed, line 25 actually -``contains'' four different SgStatement nodes: an SgForStatement -representing the whole loop on lines 25--26, an SgForInitStatement -(initializer), and two SgExprStatements (one which is a child of the -SgForInitStatement, and another for the for-loop's test -expression). The loop's increment is stored in the SgForStatement node -as an SgExpression, not an SgStatement. The SgForStatement node is a -scoping statement, and so it ``receives'' none of the 65534 -cycles. Since the increment is not a statement and one of the -SgExprStatements is a child of the initializer, this leaves only two -direct descendants of the SgForStatement---the initializer and the -test expression statement---among which to divide the 65534 -cycles. Thus, each receives 32767 cycles. The initializer's -SgExprStatement child gets the same 32767 as its parent, since the two -nodes are equivalent (see first two cases of -Figure~\ref{Tutorial:roseHPCT:profiled:out}). - -For the entire loop on lines 25--26 of -Figure~\ref{Tutorial:roseHPCT:profiled:aa}, the original XML files -attribute 65534 cycles to line 25, and another 65534 cycles to line 26 -(see Figure~\ref{Tutorial:roseHPCT:xml:cycles}). Moreover, the XML -files do not attribute any costs to this loop \emph{via} an explicit -\texttt{} tag. Thus, the best we can infer is that the -entire for-statement's costs is the sum of its immediate child costs; -in this case, 131068 cycles. The RoseHPCT::attachMetrics() routine -will heuristically accumulate and propagate metrics in this way to -assign higher-level scopes approximate costs. - -The RoseHPCT::attachMetrics() routine automatically propagates metric -values through parent scopes. A given metric attribute, -RoseHPCT::MetricAttr* x, is ``derived'' through propagation if -x-$>$isDerived() returns true. In fact, if you call x-$>$toString() to -obtain a string representation of the metric's value, two asterisks -will be appended to the string as a visual indicator that the metric -is derived. We called RoseHPCT::MetricAttr::toString() on lines 27 and -29 of Figure~\ref{Tutorial:roseHPCT:attach}, and all of the -SgForStatement nodes appearing in the output in -Figure~\ref{Tutorial:roseHPCT:profiled:out} are marked as derived. - -Alternatively, you cann call RoseHPCT::attachMetricsRaw(), rather than -calling RoseHPCT::attachMetrics(). The ``raw'' routine takes the same -arguments but only attaches the raw data, \emph{i.e.}, without -attempting to propagate metric values through parent scopes. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Working with GNU gprof} -ROSE-HPCT can also accept the line-by-line profiling output generated by -GNU gprof. -Currently, we only use the self seconds associated with each line -and attach them to ROSE AST as AST attributes named {\tt WALLCLK}. - -A typical session to generate compatible gprof profiling file for ROSE-HPCT -is given below: -\begin{verbatim} -[liao@codes]$ gcc -g seq-pi.c -pg -[liao@codes]$ ./a.out -[liao@codes]$ gprof -l -L a.out gmon.out &>profile.result -\end{verbatim} - -{\tt -l} tells gprof to output line-by-line profiling information and {\tt --L} causes gprof to output full file path information. - -An excerpt of an output file looks like the following: -{\scriptsize -\begin{verbatim} -Flat profile: - -Each sample counts as 0.01 seconds. - % cumulative self self total - time seconds seconds calls Ts/call Ts/call name - 38.20 8.84 8.84 jacobi (/home/liao6/temp/jacobi.c:193 @ 804899c) - 36.43 17.27 8.43 jacobi (/home/liao6/temp/jacobi.c:196 @ 8048a3f) - 11.00 19.82 2.54 jacobi (/home/liao6/temp/jacobi.c:188 @ 804893e) - 5.66 21.12 1.31 jacobi (/home/liao6/temp/jacobi.c:187 @ 8048968) - 3.93 22.04 0.91 jacobi (/home/liao6/temp/jacobi.c:197 @ 8048a71) - 3.24 22.79 0.75 jacobi (/home/liao6/temp/jacobi.c:191 @ 8048a7f) - 0.95 23.00 0.22 jacobi (/home/liao6/temp/jacobi.c:186 @ 8048976) - 0.50 23.12 0.12 jacobi (/home/liao6/temp/jacobi.c:187 @ 8048935) - 0.09 23.14 0.02 jacobi (/home/liao6/temp/jacobi.c:190 @ 8048a94) - 0.00 23.14 0.00 1 0.00 0.00 driver (/home/liao6/temp/jacobi.c:91 @ 8048660) - 0.00 23.14 0.00 1 0.00 0.00 error_check (/home/liao6/temp/jacobi.c:220 @ 8048b7c) - 0.00 23.14 0.00 1 0.00 0.00 initialize (/home/liao6/temp/jacobi.c:116 @ 8048722) - 0.00 23.14 0.00 1 0.00 0.00 jacobi (/home/liao6/temp/jacobi.c:160 @ 8048892) -\end{verbatim} -} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Command-line options} -\label{sec:rosehpct:cmdlineopts} - -The call to RoseHPCT::loadProfilingFiles() on line 49 of -Figure~\ref{Tutorial:roseHPCT:attach} processes and extracts -ROSE-HPCT-specific command-line options. To generate the output in -this chapter, we invoked Figure~\ref{Tutorial:roseHPCT:attach} with -the following command-line: - -\verbatiminput{\TutorialExampleBuildDirectory/roseHPCT/command-line} - -The main option is \texttt{-rose:hpct:prof }, which specifies -the HPCToolkit-generated XML file containing metric data. Here, we use -this option twice to specify the names of the cycle and flop data -files -(Figures~\ref{Tutorial:roseHPCT:xml:cycles}--\ref{Tutorial:roseHPCT:xml:flops}). -To accept gprof output file, please use another option \texttt{-rose:gprof:linebyline }. -This option cannot be used with \texttt{-rose:hpct:prof } currently. - -We need the other option, \texttt{-rose:hpct:eqpath =}, to -specify how paths in the HPCToolkit XML files can be mapped to file -paths in the ROSE AST. -This option allows users to generate performance files on one machine and -analyze the results on another machine. -In this example, the XML -files specify the source file as, ``./profiled.c'' (line 73 of -Figures~\ref{Tutorial:roseHPCT:xml:cycles} -and~\ref{Tutorial:roseHPCT:xml:flops}); the ``eqpath'' command-line -option above remaps the relative path ``.'' to an absolute path as it -would appear in the ROSE AST. -Another example is to use the same performance file even after the original source tree is moved to another location. -ROSE-HPCT can still correctly match performance data if the root source paths are given as \texttt{-rose:hpct:eqpath =}. - -Yet another option \texttt{-rose:hpct:enable\_debug} is provided to display runtime debugging information -such as metrics reading, attaching, and propagating. -It also adds performance metrics into the ROSE output source file as source comments as shown below. -Users can examine the source comments to make sure performance metrics are attached and propagated properly. -As we can see, ROSE-HPCT attaches each performance metric to each matching statement. -If there are multiple statements showing in the same line, the same metric will be attached to each of them. -The metric propagation step will only propagate one of them to upper-level language constructs to ensure the correctness. - -{\scriptsize -\begin{verbatim} -/* ROSE-HPCT propagated metrics WALLCLK:18.95[SgForStatement at 0xb7beb218] */ - for ( -/* ROSE-HPCT raw data: Statement WALLCLK:0.02@File jacobi.c 190-0 -> SgForInitStatement 0x94e8d08 at 190 */ -i = 1; -/* ROSE-HPCT raw data: Statement WALLCLK:0.02@File jacobi.c 190-0 -> SgExprStatement 0x94516d8 at 190 */ -i < (n - 1); i++) -/* ROSE-HPCT propagated metrics WALLCLK:18.93[SgForStatement at 0xb7beb29c] */ - for ( -/* ROSE-HPCT raw data: Statement WALLCLK:0.75@File jacobi.c 191-0 -> SgForInitStatement 0x94e8d38 at 191 */ -j = 1; -/* ROSE-HPCT raw data: Statement WALLCLK:0.75@File jacobi.c 191-0 -> SgExprStatement 0x9451728 at 191 */ -j < (m - 1); j++) -/* ROSE-HPCT propagated metrics WALLCLK:18.18[SgBasicBlock at 0x93f60b4] */ -{ -/* ROSE-HPCT raw data: Statement WALLCLK:8.84@File jacobi.c 193-0 -> SgExprStatement 0x9451750 at 193 */ - resid = (((((ax * (((( *uold)[i - 1])[j]) + ((( *uold)[i + 1])[j]))) + (ay * (((( *uold)[i])[j - 1]) - + ((( *uold)[i])[j + 1])))) + (b * ((( *uold)[i])[j]))) - ((( *f)[i])[j])) / b); -/* ROSE-HPCT raw data: Statement WALLCLK:8.43@File jacobi.c 196-0 -> SgExprStatement 0x9451778 at 196 */ - (( *u)[i])[j] = (((( *uold)[i])[j]) - (omega * resid)); -/* ROSE-HPCT raw data: Statement WALLCLK:0.91@File jacobi.c 197-0 -> SgExprStatement 0x94517a0 at 197 */ - error = (error + (resid * resid)); - } -\end{verbatim} -} -% eof diff --git a/docs/Rose/Tutorial/tutorial.tex.in b/docs/Rose/Tutorial/tutorial.tex.in index 23dba4dde73..d781e726f57 100644 --- a/docs/Rose/Tutorial/tutorial.tex.in +++ b/docs/Rose/Tutorial/tutorial.tex.in @@ -331,18 +331,6 @@ debugging.} \input{codeCoverage} \input{bugSeeding} -%----------------------------------------------------------- -% Binary Support -%----------------------------------------------------------- -\part[Binary Support]{ Binary Support \\ -\vspace{1.0in} -\normalsize{Tutorials of using ROSE to handle binary executable files.} -} -\input{instructionSemantics} -\input{binaryAnalysis} -\input{binaryConstruction} -\input{dwarfDebugSupport} - %----------------------------------------------------------- % Interacting with Other Tools %----------------------------------------------------------- @@ -351,8 +339,6 @@ debugging.} \normalsize{How to build interoperable tools using ROSE.} } \input{abstractHandle} -\input{roseHPCT} -\input{tauInstrumentation} %----------------------------------------------------------- % Parallelism diff --git a/docs/Rose/UPCsupport.tex b/docs/Rose/UPCsupport.tex deleted file mode 100644 index 633c18ae9d8..00000000000 --- a/docs/Rose/UPCsupport.tex +++ /dev/null @@ -1,432 +0,0 @@ -\chapter{UPC Support} -\label{chap::upcsupport} - -%------------------------------------------------------------- -%------------------------------------------------------------- -\section{Introduction} -ROSE supports Unified Parallel C (UPC) programs. -UPC~\cite{UPC:Web} is a famous extension of the C99 programming language to support high performance computing using a partitioned global address space (PGAS) memory model. -ROSE leverages the EDG frontend to parse input UPC programs and generate EDG IR with UPC extensions. -It then converts the EDG IR into ROSE's internal AST and provides unparsing support for the AST. -An example UPC-to-C translator is also provided to demonstrate how one can use ROSE to -translate UPC programs into C programs with runtime calls to the Berkeley UPC (BUPC) runtime system V. 2.6.0~\cite{BUPC:Web}. -More information on UPC is availalbe from the language specification at: -\htmladdnormallink{UPC Language Specifications (pdf)}{http://www.gwu.edu/~upc/publications/LBNL-59208.pdf}. - -%------------------------------------------------------------- -%------------------------------------------------------------- -\section{Supported UPC Constructs} -% ROSE currently supports all UPC constructs as defined in UPC 1.1.1. -ROSE currently supports all UPC constructs as defined in UPC 1.2, using -all the standard header files: {\em upc.h}, {\em upc\_relaxed.h}, {\em upc\_strict.h}, -{\em upc\_collective.h}, {\em upc\_io.h}. Additional Non-standard Berkeley -UPC extensions are supported using the UCB {\em bupc\_extensions.h} header file. - -\footnote{ -The supported version is limited by the EDG -frontend, which only supports UPC 1.1.1 (\lstinline{__UPC_VERSION__} string -is defined as 200310L). -ROSE uses EDG 3.3 currently and it originally only supported UPC 1.0. -We merged the UPC 1.1.1 support from EDG 3.10 into our EDG 3.3 frontend. -%It seems like that the latest EDG 4.0 still only supports UPC 1.1.1 but we -%can easily extend it to support UPC 1.2 given the minor language changes from 1.1.1 to 1.2. -We have also added the required wotk to support UPC 1.2. Please let us know if anything is -left out and we will fix it.}. -A list of those UPC constructs and their corresponding ROSE AST representations are given below: -\begin{verbatim} -MYTHREAD SgUpcMythread -THREADS SgUpcThreads -upc_barrier SgUpcBarrierStatement -upc_blocksizeof SgUpcBlocksizeofExpression -upc_elemsizeof SgUpcElemsizeofExpression -upc_fence SgUpcFenceStatement -upc_forall SgUpcForAllStatement -upc_localsizeof SgUpcLocalsizeofExpression -upc_notify SgUpcNotifyStatement -upc_wait SgUpcWaitStatement -strict/relaxed/shared SgUPC_AccessModifier -UPC_MAX_BLOCKSIZE 1073741823 (~1GB) -\end{verbatim} -As we can see, most UPC constructs are represented by their corresponding dedicated ROSE AST nodes. -A few others, such as \lstinline{strict}, \lstinline{relaxed} and -\lstinline{shared}, are represented as instances of \lstinline{SgUPC_AccessModifier}. -\lstinline{UPC_MAX_BLOCKSIZE} is treated as a macro and is expanded to a predefined integer constant value. - -Much of the UPC language is supported via UPC specific language runtime -libraries. These calls are simply normal functions and not represented -as special UPC specific IR nodes. -Such runtime library function calls are, in general, -not a property of the UPC grammar and thus not represented in the AST -as specialized IR nodes. -The function names are those from the -UPC Langauge Specifications and so must be detected based on the function -name. No specialized support in currently present in ROSE to classify -these function or identify them as UPC secific, but such functionality -could be easily written. Such support could be added to the SageInteface. -If users write such specific support they are welcme to contribute it -back to ROSE. - -Alternatively ROSE provides function identification based on header files -where the declarations occured and this would be used to automate the recognition of UPC -specific runtime support functions. See the use of the {\em classifyFileName()} -function in {\em tests/nonsmoke/functional/roseTests/fileLocation\_tests} -directory for examples of how file names can be classified. Alternatively, -just the infomation in the source position reports the file name of the -original declaration and this can be used to identify specific functions as -defined in there associated header files, e.g. {\em upc\_collective.h}, -{\em upc\_io.h}, or {\em bupc\_extensions.h}. - -%------------------------------------------------------------- -%------------------------------------------------------------- -\section{Command Line Options} -ROSE can automatically recognize a source file with a suffix of \textit{.upc} as a UPC input and turn on its UPC support. -For other UPC files without the \textit{.upc} extension, a command line -option (\textit{-rose:UPC\_only or -rose:UPC}) is available to turn on the -UPC support explicitly. -In addition, \textit{-rose:upc\_threads n} can be used to enable ROSE's -support for UPC static threads compilation with n threads. - -%------------------------------------------------------------- -%------------------------------------------------------------- -\section{Example UPC Code Acceptable for ROSE} -We give some output after ROSE's source-to-source translation of some example UPC input. -These UPC input are actually some of ROSE's daily regression test input available from \textit{ROSE/tests/nonsmoke/functional/CompileTests/UPC\_tests}. - -Figure~\ref{Manual:UPC:hello} shows the output of the ROSE -identityTranslator handling a hello program in UPC. -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_hello.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_hello.upc} - \end{htmlonly} - } -} -\caption{Output of an UPC hello program} -\label{Manual:UPC:hello} -\end{figure} - -Figure~\ref{Manual:UPC:strict} shows the handling of UPC language -constructs related to memory consistency. -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_consistency.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_consistency.upc} - \end{htmlonly} - } -} -\caption{Output for UPC strict} -\label{Manual:UPC:strict} -\end{figure} - - -Figure~\ref{Manual:UPC:forall1} shows the use of \lstinline{upc_forall} -with \lstinline{continue} and Figure~\ref{Manual:UPC:forall2} shows the use -of \lstinline{upc_forall} with \lstinline{affinity}. - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_forall_continue.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_forall_continue.upc} - \end{htmlonly} - } -} -\caption{Output for upc\_forall with continue} -\label{Manual:UPC:forall1} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_forall_affinity.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_forall_affinity.upc} - \end{htmlonly} - } -} -\caption{Output for upc\_forall with affinity } -\label{Manual:UPC:forall2} -\end{figure} - -\clearpage -ROSE's support for various uses of \lstinline{shared} and unshared UPC -variables is given in -Figure~\ref{Manual:UPC:sharedaa} and Figure~\ref{Manual:UPC:sharedab}. -All kinds of shared, shared to shared, shared to private, and private to -shared variables can be correctly parsed and unparsed. -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_shared.upc.aa} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_shared.upc.aa} - \end{htmlonly} - } -} -\caption{Output for UPC shared: part A} -\label{Manual:UPC:sharedaa} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_shared.upc.ab} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_shared.upc.ab} - \end{htmlonly} - } -} -\caption{Output for UPC shared: part B} -\label{Manual:UPC:sharedab} -\end{figure} - -\clearpage -Support for UPC \lstinline{lock}s is demonstrated in -Figure~\ref{Manual:UPC:lock}. -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_lock.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/tests/tests/nonsmoke/functional/CompileTests/UPC_tests/rose_lock.upc} - \end{htmlonly} - } -} -\caption{Output for UPC Locks} -\label{Manual:UPC:lock} -\end{figure} - -%------------------------------------------------------------- -%------------------------------------------------------------- -\clearpage -\section{An Example UPC-to-C Translator Using ROSE} -An example UPC-to-C translator, namely roseupcc, is provided to -demonstrate how one can use ROSE to build a translator translating UPC -programs into C programs with runtime calls to the Berkeley UPC (BUPC) -runtime system V. 2.6.0. -The source files of roseupcc are located in -\textit{ROSE/projects/UpcTranslation}. -%roseupcc follows the BUPC runtime interface specification -%3.10~\cite{BUPC3.10}. -%we don't reiterate details about why the translation is done in a certain way here. -Please be advised that only a subset of UPC (including variable handling) is -translated currently since the translator is meant to be a starting example. -Also variable handling is arguably the most difficult part of a UPC -implementation. - -Translation result for the UPC hello program (shown in -Figure~\ref{Manual:UPC:hello}) is given in Figure~\ref{Manual:UPC:hello-trans}. -Mostly, high level \lstinline{SageInterface} functions are used to -easily translate the ROSE AST. -BUPC-specified preprocessing directives, such as \lstinline{#include "upcr.h"} -and \lstinline{#define UPCR_WANT_MAJOR 3}, are inserted. -The original user main function is rewritten to \lstinline{user_main} with -runtime initialization (\lstinline{UPCR_BEGIN_FUNCTION}) and termination -(\lstinline{UPCR_EXIT_FUNCTION}) functions. -\lstinline{upc_barrier} is simply replaced with a call to its corresponding -runtime function \lstinline{upcr_barrier()}. -\lstinline{UPCRI_ALLOC_filename_xxx()} handles per file UPCRI allocation of -possible shared variables (none here). -\lstinline{UPCRI_INIT_filename_xxx()} function is used for per-file initialization of -shared and unshared (thread local) data. - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/projects/UpcTranslation/tests/rose_hello.c} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/projects/UpcTranslation/tests/rose_hello.c} - \end{htmlonly} - } -} -\caption{Translation of upc hello} -\label{Manual:UPC:hello-trans} -\end{figure} - - -%\clearpage -Implementing various UPC variable accesses is complex due to the two level -memory scheme used by the partitioned global memory address space. -The translation has to handle variable declaration, memory allocation, -value initialization, variable access, and so on. - -UPC variables can be roughly categorized as shared and unshared (or thread -local) variables. -For shared variables, they can be divided into two categories: -statically allocated shared variables (including global shared variables -and local static shared variables) and dynamically allocated shared -variables. -%Runtime library routines are sufficient to support dynamically allocated -%shared variables. -We focus on statically allocated shared variables here as -an example. -%But extra compiler translation is needed for -%implementing statically allocated shared variables. -Translation of statically allocated \lstinline{shared} variables is demonstrated in -Figure~\ref{Manual:UPC:shared1-transaa} and -Figure~\ref{Manual:UPC:shared1-transab} for an input code shown in -Figure~\ref{Manual:UPC:shared1}. -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopSourceDirectory/projects/UpcTranslation/tests/shared_1.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopSourceDirectory/projects/UpcTranslation/tests/shared_1.upc} - \end{htmlonly} - } -} -\caption{Example input for shared variables} -\label{Manual:UPC:shared1} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/projects/UpcTranslation/tests/rose_shared_1.c.aaf} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/projects/UpcTranslation/tests/rose_shared_1.c.aaf} - \end{htmlonly} - } -} -\caption{Translation of UPC shared variables, part A} -\label{Manual:UPC:shared1-transaa} -\end{figure} - -The BUPC runtime distinguishes between phaseless (blocksize ==1 or 0 or -unspecified) and phased (all other cases) shared -pointers for better performance. -So two types of global scoped proxy pointers (\lstinline{upcr_pshared_ptr_t} -and \lstinline{upcr_shared_ptr_t}) are used to represent static shared variables. -Global static shared variables directly use their names as the proxy -pointer names (such as \lstinline{global_counter}). -Local static variables use their mangled name (e.g. \lstinline{_lsscounter3769188422_}) for those pointers to -avoid name collision. -Accesses to shared variables are implemented by a set of runtime library -calls, such as \lstinline{UPCR_GET_SHARED()} and -\lstinline{UPCR_PUT_SHARED_VAL}. -Again, as shown in Figure~\ref{Manual:UPC:shared1-transab}, \lstinline{UPCRI_ALLOC_filename_xxx()} handles per file UPCRI allocation of shared variables and -\lstinline{UPCRI_INIT_filename_xxx()} function is used for per-file -initialization of those data. - -ROSE provides a set of AST interface functions to help developers handle -UPC-specific types and facilitate translation. Those functions include -\lstinline{bool isUpcSharedType()}, -\lstinline{bool isUpcSharedArrayType()}, -\lstinline{bool isUpcPhaseLessSharedType()}, -\lstinline{bool isUpcPrivateToSharedType()}, etc. -A type mangling function (\lstinline{mangleType()}) is also provided -to implement the Itanium C++ ABI specification~\cite{ItaniumCppABI}. - -Unshared variables in UPC (also called Thread local data, or TLD) consists -of local auto variables and global ( and static local) variables. -Local auto variables do not need special translation. -But global and static local variables do. -Implementation details for them vary depending on their scope, internal or -external linkage, if they are scalar or array types, if they point to -shared data, if they have initializers, and so on. -But the basic scheme for variable declaration, allocation/initialization, and -accesses is similar to the handling of shared UPC variables. -Please refer to the BUPC runtime interface specification -3.10~\cite{BUPC3.10} for details. -We only provide a translation example in -Figure~\ref{Manual:UPC:unshared1-transaa} and -Figure~\ref{Manual:UPC:unshared1-transab} for an input code shown in -Figure~\ref{Manual:UPC:unshared1}. - -%No translations are needed for extern global unshared variables unless they -%are pointers to shared data. -%Local static unshared variables are promoted to non-static type at global -%scope using lstinline{UPCR_TLD_DEFINE or UPCR_TLD_DEFINE_TENTATIVE}) -%Unshared pointer to shared data - - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/projects/UpcTranslation/tests/rose_shared_1.c.abf} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/projects/UpcTranslation/tests/rose_shared_1.c.abf} - \end{htmlonly} - } -} -\caption{Translation of UPC shared variables, part B} -\label{Manual:UPC:shared1-transab} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopSourceDirectory/projects/UpcTranslation/tests/unshared_1.upc} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopSourceDirectory/projects/UpcTranslation/tests/unshared_1.upc} - \end{htmlonly} - } -} -\caption{Example input for non-shared variables} -\label{Manual:UPC:unshared1} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/projects/UpcTranslation/tests/rose_unshared_1.c.aaf} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/projects/UpcTranslation/tests/rose_unshared_1.c.aaf} - \end{htmlonly} - } -} -\caption{Translation of UPC unshared variables, part A} -\label{Manual:UPC:unshared1-transaa} -\end{figure} - -\begin{figure}[!h] -{\indent - {\mySmallFontSize - \begin{latexonly} - \lstinputlisting{\TopBuildDirectory/projects/UpcTranslation/tests/rose_unshared_1.c.abf} - \end{latexonly} - \begin{htmlonly} - \verbatiminput{\TopBuildDirectory/projects/UpcTranslation/tests/rose_unshared_1.c.abf} - \end{htmlonly} - } -} -\caption{Translation of UPC unshared variables, part B} -\label{Manual:UPC:unshared1-transab} -\end{figure} - - -%------------------------------------------------------------- -%------------------------------------------------------------- -%\section{Summary} - diff --git a/docs/Rose/binaryAnalysis.tex b/docs/Rose/binaryAnalysis.tex deleted file mode 100644 index e1ed871ba7a..00000000000 --- a/docs/Rose/binaryAnalysis.tex +++ /dev/null @@ -1,486 +0,0 @@ - -\chapter{Binary Analysis: Support for the Analysis of Binary Executables} - -\label{binaryAnalysis::overview} - -\section{Introduction} - - ROSE supports the disassembly and analysis of binary executables for x86, PowerPC, and AMR -instruction sets. ROSE implements this support as part of general research work -to support combining analysis for source code and analysis for binaries and supporting -performance analysis and optimization. Through this support ROSE addresses the -requirements for the analysis and transformation of software in a general context useful -to as wide a group of users as possible. - - ROSE handles a number of binary executable file formats and also reads Dwarf information -into the AST to support additional analysis. - - Recent work in ROSE has added support for dynamic analysis and for mixing of dynamic -and static analysis using the Intel Pin framework. -Intel Pin support in ROSE is presented in section~\ref{intel_pin}. - -\section{The Binary AST} - -\subsection{The Binary Executable Format} - - ROSE handles Linux and Windows binary formats; thus ELF format for Linux and PE, NE, -LE, DOS formats for Windows. The details of each format are represented in IR nodes in -the AST (using structures common to the representation of such low level data). About -60 IR nodes have been added to ROSE to support the binary executable formats; this -support allows the analysis of any Linux, Windows, OS\/2, or DOS binary executable. - - The binary executable file format can be analyzed separately from the instructions -using the command line option: {\tt -rose:read\_executable\_file\_format\_only}. This -allows graphs generated using the ROSE visualization mechanisms (and even some analysis) -to be easily restricted (in size) to the just the IR nodes specific to the binary -executable file format. - -% \fixme{We need an example of the binary executable format AST.} - -\begin{figure} -% \includegraphics[angle=90,scale=0.75,width=5in,height=1in]{\TopSourceDirectory/src/frontend/ExecFormats/BinaryFileFormat} -\includegraphics[angle=90,width=7.5in,height=8.5in]{\TopSourceDirectory/src/frontend/BinaryFormats/BinaryFileFormat} -\caption{The class design of the IR nodes for the binary file format.} - -\label{binaryAnalysis:BinaryExecutableFormatDesign} -\end{figure} - -Figure \ref{binaryAnalysis:BinaryExecutableFormatDesign} shows the class design of the IR -nodes for the binary file format address the -requirements of ELF (Linux, and others), PE (MS Windows), NE (older MS Windows), -LE (OS\/2), and DOS (MS Dos) executable formats. The colors represent different -executable formats, brown classes are used as base classes for more than one -format. Dark colors represent principle IR nodes in the AST, lighter color IR nodes -represent supporting infrastructure in the AST. Arrows are either dark colored or -light colored; dark colors represent class derivation, and light colors represent -member relationships. - -% DQ (10/29/2008): Added documentation for file format (plus examples). -% This figure uses a saved (static) pdf file (not generated during the ``make docs'' rule). -% This was done because it is cropped using predefined pixel values which would not be -% easy to generate for a pdf that might be constantly changed. -\begin{figure} -% \includegraphics[angle=90,scale=0.75,width=5in,height=1in]{\TopSourceDirectory/src/frontend/ExecFormats/BinaryFileFormat} -% \includegraphics[scale=0.50]{\TopSourceDirectory/docs/Rose/asm_code_samples_gcc} -\includegraphics[,viewport=5 1 100 30,scale=2]{\TopSourceDirectory/docs/Rose/asm_code_samples_gcc} -\caption{The AST for a PE (Windows) binary executable (binary file format only), with long - list of symbols (half of which are clipped on the right side of the image).} - -\label{binaryAnalysis:BinaryExecutableFormatAST_1} -\end{figure} - -Figure \ref{binaryAnalysis:BinaryExecutableFormatAST_1} shows the graph of the AST -formed by just the binary file format (sections, symbols, etc.). This figure shows -the different IR nodes used to represent the binary file format (without the disassembled -instructions, in this case) and the large list of symbols within the symbol table (the -long list that is partially truncated on the right edge of the figure). -This graph is quite large and does not fit well on the page, the next figure -\ref{binaryAnalysis:BinaryExecutableFormatAST_2} shows a clipped image with more detail. - - -\begin{figure} -% \includegraphics[angle=90,scale=0.75,width=5in,height=1in]{\TopSourceDirectory/src/frontend/ExecFormats/BinaryFileFormat} -\includegraphics*[angle=90,viewport=5 1 40 30,scale=18]{\TopSourceDirectory/docs/Rose/asm_code_samples_gcc} -\caption{The CROPPED AST for a PE (Windows) binary executable (binary file format only).} - -\label{binaryAnalysis:BinaryExecutableFormatAST_2} -\end{figure} - -Figure \ref{binaryAnalysis:BinaryExecutableFormatAST_2} shows a cropped view of the graph -of the AST formed by just the binary file format (sections, symbols, etc.). This figure -shows two {\em SgAsmInterpretation} IR nodes; this is a Windows PE binary and all windows -PE binaries contain both a 16-bit MS-DOS header (and some 16-bit code) and a 32-bit Windows -PE header (with sections that have 32-bit code); thus there are two SgAsmInterpretation IR -nodes (one for the 16-bit interpretation of the instructions and one for the 32-bit -interpretation of the instructions). Note that ELF format files will have only one -SgAsmInterpretation IR nodes (because there is only a single interpretation possible), but -other file formats can contain many interpretations; formed form a composite of code to -support wide ranges of portability. - -*Note: The actually file used is in these figures is: {\tt ROSE/docs/Rose/asm\_code\_samples\_gcc.pdf}. - -\subsection{Instruction Disassembly} - -See API documentation for Rose::BinaryAnalysis::Disassemble. - -\subsection{Instruction Partitioning} - -See API documentation for Rose::BinaryAnalysis::Partitioner2. - -\subsection{Dwarf Debug Support} -% NOTE: - - ROSE can now read the Dwarf debug information stored into binary executables (ELF only -at this point). This information is represented as Dwarf specific IR nodes in the AST and -thus can be optionally used (when it is available in the binary) as part of any binary -analysis. Only a few sections are supported at present: {\em .debug\_info}, -{\em .debug\_line}, etc. The dwarf support in ROSE uses {\em libdwarf} and is enabled in -ROSE using a configuration option: {\tt (configure --with-dwarf={\em}}. -Note that {\em libdwarf} is optional, must be separately installed by the user, and -thus is obviously not distributed within ROSE. -% The future of the Dwarf support in ROSE is not clear, -We anticipate the Dwarf information in the AST to be useful for performance tools that -operate on the binary executable when the binary executable has been generated to include -Dwarf debug information. - -\section{Binary Analysis} - -See API documentation for Rose::BinaryAnalysis. - -\section{Compass as a Binary Analysis Tool} - - Compass is a tool framework for building software analysis tools using rules (on source -code and alternatively directly on binary executables). Compass -reports violations of the rules in the evaluation of the software. Compass is a -relatively simple application built on top of ROSE. Most of the complexity and code -within Compass is that it includes a large collection to rules, each rule has its -own implementation of an arbitrary test over the source code or the binary. Rules -(checkers) may be defined over the AST or any other graph built within ROSE to store -program analysis information. See the Compass manual for more details on supported -binary analysis. The ability to perform analysis of binary executables using Compass -makes no assumptions that it is compiled with any specific options or that it contains -debug information, symbols, etc. - - -\section{Static Binary Rewriting} - As part of general research on transformations of binaries (separate from analysis) -a number of techniques have been developed to support classes of transformations. -This static rewriting of the binary permits the development of performance tools -that could support the analysis and rewriting of binaries for support of High -Performance Computing (HPC). A principal focus is on IBM BGL and Cray XT support -(DOE Office of Science supercomputers). - -\subsection{Generic Section/Segment Modifications} -%=============================================================================================================================== -%Generic Section/Segment Modifications -%=============================================================================================================================== - -\subsubsection{1a. Section/Segment file address shifting (low-level)} - - The low-level movement of an ELF Section or Segment within the file address space is performed with - SgAsmGenericSection::set\_offset. It changes the location of the section in the file and updates all relative virtual - addresses (RVAs) that were primarily associated with the moved section. - - The main problems with this function are that it doesn't take into account the file locations of other sections, the file - alignment constraints of the moved section, or the memory mapping. Specifically, after calling this function to move {\bf.text} - one byte later in the file: -\begin{itemize} - \item {\bf.text} might not satisfy its file alignment constraint. - - \item The end of {\bf.text} might overlap with the following section. The ELF unparser has undefined behavior when two sections - overlap without storing identical bytes at the overlapping regions. - - \item {\bf.text}, if memory mapped (which it surely is), might not be consistent with the mapping of other adjacent or overlapping - sections. For instance, {\bf.text} is contained in "ELF Load Segment 2" both in the file address space and in the mapped - memory space. The offset from ELF Load Segment 2 to {\bf.text} must be identical in both file and memory. - - \item RVAs that point to instructions in {\bf.text} can be associated with the {\bf.text} section or with ELF Load Segment 2, - depending on how they were parsed. Normally it doesn't matter which since the relationship between file address space and - memory address space is consistent. But if you change the file addresses without changing memory addresses then the byte - to which the RVA points could be ambiguous. -\end{itemize} - - Changes to ELF Section or Segment file addresses are reflected in the ELF Section Table and/or ELF Segment Table. If the - particular SgAsmGenericSection is present in both tables then modifying its file address will result in updates to both - tables. - - NOTE: Do not modify section offsets and sizes by modifying the section table entries. Changes to these values will be - overwritten with actual, current section offsets and sizes when the section table is unparsed: -\begin{itemize} - \item SgAsmElfSectionTableEntry::set\_sh\_offset - \item SgAsmElfSectionTableEntry::set\_sh\_size - \item SgAsmElfSectionTableEntry::set\_sh\_addr -\end{itemize} - - NOTE: Do not modify segment offsets and sizes by modifying the segment table entries. Changes to these values will be - overwritten with actual, current segment offsets and sizes when the segment table is unparsed: -\begin{itemize} - \item SgAsmElfSegmentTableEntry::set\_offset - \item SgAsmElfSegmentTableEntry::set\_filesz - \item SgAsmElfSegmentTableEntry::set\_vaddr - \item SgAsmElfSegmentTableEntry::set\_memsz -\end{itemize} - -\subsubsection{1b. Section/Segment file address shifting (high-level)} - - The SgAsmGenericFile::shift\_extend method is the preferred way to make minor offset and/or size adjustments to an ELF - Section or Segment. It is able to shift a section to a high file and/or memory address and/or extend the segment: -\begin{itemize} - \item It takes into account all sections in the file, adjusting their offsets and/or sizes accordingly. - - \item Sections to the right of the the section in question (Sq) are shifted upward to make room and prevent overlaps. - - \item Sections overlapping with Sq are extended to contain all of what they previously contained. - - \item The shift amounts are adjusted to satisfy alignment constraints of all affected sections. - - \item Unreferenced areas of the file can optionally be utilized as unused address space. - - \item Adjusting file address spaces also adjusts the memory address spaces in a compatible manner. -\end{itemize} - - NOTE: Do not modify section offsets and sizes by modifying the section table entries. Changes to these values will be - overwritten with actual, current section offsets and sizes when the section table is unparsed: -\begin{itemize} - \item SgAsmElfSectionTableEntry::set\_sh\_offset - \item SgAsmElfSectionTableEntry::set\_sh\_size - \item SgAsmElfSectionTableEntry::set\_sh\_addr -\end{itemize} - - NOTE: Do not modify segment offsets and sizes by modifying the segment table entries. Changes to these values will be - overwritten with actual, current segment offsets and sizes when the segment table is unparsed: -\begin{itemize} - \item SgAsmElfSegmentTableEntry::set\_offset - \item SgAsmElfSegmentTableEntry::set\_filesz - \item SgAsmElfSegmentTableEntry::set\_vaddr - \item SgAsmElfSegmentTableEntry::set\_memsz -\end{itemize} - -\subsubsection{2a. Section/Segment resizing (low-level)} - - The size of an ELF Section or Segment can be modified by calling SgAsmGenericSection::set\_size (for file size) and - set\_mapped\_size (for mapped memory). However, this is a low-level interface that doesn't take into account other sections in - the same file. The preferred way to resize a section is with SgAsmGenericFile::shift\_extend. - - NOTE: For many kinds of sections, making the section larger will create an unreferenced area ("internal hole") at the end of - the section. Other sections will automatically do something with the new address space (e.g., SgAsmElfStringSection will - add the new address space to its free list). - -\subsubsection{2b. Section/Segment resizing (high-level)} - - The preferred way to extend a section is to call SgAsmGenericFile::shift\_extend, which extends sections that contain the - resized-section and shifts sections that are right (higher address) of the resized-section. This function also takes into - account alignment constraints, memory address space, and (optionally) holes in the address space. - -\subsection{Modifications to the ELF File Header} -%=============================================================================================================================== -%Modifications to the ELF File Header -%=============================================================================================================================== - -\subsubsection{1. Entry Point RVA} - - The entry RVA stored in the ELF File Header is adjusted whenever the section into which it points is moved in memory. It is - also possible to adjust this address explicitly by modifying the first (and only) entry in SgAsmGenericHeader::entry\_rvas. - - NOTE: An RVA (rose\_rva\_t) is an offset with respect to the beginning of some section. If the section starting memory address - changes then the RVA implicitly changes (RVA's are virtual addresses relative to some format-wide base address). Multiple - sections can be mapped to the same memory (e.g., {\bf.text} and {\bf ELF Load Segment 2} are typically overlap in memory), but - since an RVA is associated with only one section, modifying the other section(s) has no effect on the RVA even if the RVA - happens to be inside the other sections as well. - - NOTE: The binding between an RVA and a section can be modified with rose\_rva\_t::set\_section. In fact, the link can be - completely broken by passing a null section pointer, in which case the RVA is not relative to any section. - -\subsubsection{2. File Format Byte order} - - File byte order can be changed by modifying the SgAsmGenericFormat object pointed to by the file header: - - SgAsmGenericHeader *fhdr = ....; - fhdr->get\_exec\_format()->set\_sex(ORDER\_MSB); - - NOTE: Modifying the byte order affects only those sections that are actually parsed. If the ELF file contains a section - whose purpose we don't recognize then the original section data is written to the new file. - -\fixme{If the byte order is not specified in the ELF header (e\_ident\_data\_encoding other than 1 or 2) then the parser will - make an educated guess and assign a byte order. The unparsed file will differ from the original in this case at the sixth - byte of the file.} - -\subsubsection{3. ELF Word Size} - - File word size can be changed between 4 bytes and 8 bytes by modifying the SgAsmGenericFormat object pointed to by the file - header: - - SgAsmGenericHeader *fhdr = ....; - fhdr->get\_exec\_format()->set\_word\_size(4); - - When changing word sizes, any fields that have values too large to represent in the new word size will cause the unparser - to abort. - - NOTE: Modifying the word size affects only those sections that are actually parsed. If the ELF file contains a section whose - purpose we don't recognize then the original section data is written to the new file. - -\fixme{Increasing word size probably requires allocating more space for many of the sections. Vice versa for decreasing the - word size.} - -\subsubsection{4. ELF Header Magic Number} - - An ELF header has a four-byte magic number, usually 0x7f, 'E', 'L', 'F'. The magic number can be modified by changing the - string from SgAsmGenericHeader::get\_magic. It must be exactly four characters in length. - -\subsubsection{5. ELF File Purpose (lib, executable, core, etc.)} - - The file purpose should be modified by setting two fields, using - -\begin{enumerate} - \item SgAsmElfFileHeader::set\_p\_e\_type - \item SgAsmGenericFormat::set\_purpose -\end{enumerate} - - Both members should be set to compatible values. The former is the value from the ELF specification and the latter is a - constant: PURPOSE\_UNSPECIFIED, PURPOSE\_LIBRARY, PURPOSE\_EXECUTABLE, PURPOSE\_CORE\_DUMP, PURPOSE\_PROC\_SPECIFIC, PURPOSE\_OTHER. - -\fixme{set\_p\_e\_type should probably call set\_purpose, but we can't go the other direction because the mapping is N:1.} - -\subsubsection{6. ELF Version} - - To change the ELF version assign a new value by calling set\_version on the object returned by - SgAsmGenericHeader::get\_exec\_format. This doesn't have any effect on the code generated by the unparser since the parser - only knows about ELF format 1. - -\subsubsection{7. ELF Target Architecture} - - Modify the target architecture by calling two functions: - - SgAsmElfHeader::set\_e\_machine -- sets the ELF specific value - SgAsmGenericHeader::set\_isa -- sets the generic value - - You should call both with consistent values. - -\subsubsection{8. ELF Section or Segment Table location} - - The SgAsmElfFileHeader::set\_e\_shoff and set\_e\_phoff methods have been removed since calling them had no lasting effect - anyway. Instead, if you want to change one of these values for unparsing, then modify the actual SgAsmGenericSection that - holds the table (e.g., calling SgAsmGenericFile::shift\_extend). - -\subsubsection{9. ELF Section or Segment Table size} - - The number of entries in the section or segment table cannot be modified by calling set\_e\_shnum or set\_e\_phnum on the - SgAsmElfFileHeader \fixme{Remove these functions.}. Rather, the sizes are obtained by looking at what sections and segments - are currently defined and writing an entry to the file for each one. - -\subsubsection{10. ELF Section Names} - - Elf section names can be modified. Doing so may cause extensive changes to the executable due to reallocation of the section - holding the string table. - - Do not call SgAsmElfSectionTableEntry::set\_sh\_name since that value will be overwritten based on the actual, current - location of the name in the associated string table. - -\subsubsection{11. ELF Segment Names} - - ELF segment names are often parser-generated based on constants in the ELF Segment Table. However, if the segment - corresponds to an actual ELF Section defined in the ELF Section Table then the segment and section share the same - SgAsmGenericSection object and changing the name causes the ELF Section name to change with no effect on the segment table. - -\subsubsection{12. ELF Section Name Table} - - The section that holds the section names is identified in the ELF File Header (get\_e\_shstrndx). Although it is possible to - change this value, doing so will have no effect on the currently-defined sections: they will continue to use the original - string table for their names. - -\subsection{Modifications to ELF String Tables and their Containing Sections} -%=============================================================================================================================== -%Modifications to ELF String Tables and their Containing Sections -%=============================================================================================================================== - -\subsubsection{1. Move/Extend} - - See SgGenericFile::shift\_extend. When a string table is extended the new address space is added to the table's free list. - -\subsubsection{2. New String} - - A new string can be created by calling the SgAsmStoredString allocator and passing a string table (something derived from - SgAsmGenericStrtab) and the initial string value. The string is not actually allocated space in the file until the new file - is unparsed or until someone calls SgAsmStoredString::get\_offset. - -\subsubsection{3. Value modification} - - A string can be modified by assigning a new value via SgAsmStoredString::set\_string. Storage is not allocated for the new - value until the AST is unparsed or someone calls SgAsmStoredString::get\_offset. The previous value is freed. - -\subsubsection{4. Shared strings} - - Three forms of sharing are supported: - -\begin{enumerate} - \item Two objects (section names, symbol names, etc) share the same string and changing one string causes the other to change - as well. This kind of sharing is not typically encountered in ELF although the underlying string table classes support - it. - - \item Two objects have independent strings that happen to have the same value and point to the same offset in the string - table. In this case, changing one string doesn't change the other. This kind of sharing is often encountered in ELF. - - \item Two objects have independent strings and one is an ending substring of another (e.g., "main" and "domain"). Changing one - string does not affect the other. This kind of sharing is also common in ELF. -\end{enumerate} - -\subsubsection{5. String table internal holes} - - If a sequence of bytes in a string table is not referenced by anything known to the parser, then those bytes are marked as - internal holes and are prevented from moving with respect to the beginning of the string table. Internal holes are not - placed on the string table free list (because something we didn't parse might be pointing to them). The internal holes are - available with SgAsmGenericSection::congeal. - -\subsubsection{6. Reallocation of all strings} - - A string table can be repacked by freeing all it's strings and then reallocating. We can reallocate around the internal - holes or through the internal holes. - - strtab.free\_all\_strings(); /* free\_all\_strings(true) blows away internal holes */ - strtab.reallocate(); - - The ELF allocator will do its best to overlap storage (e.g., "domain" overlaps with "main"). - -\subsubsection{7. Deletion of a string} - - A string is deleted by changing its value to the empty string. - -\subsubsection{8. Stored strings vs. non-stored strings.} - - If a string value has storage space in a file (such as an ELF Section name), then it's an instance of - SgAsmStoredString. Otherwise the string is either an std::string or SgAsmBasicString. SgAsmBasicString and SgAsmStoredString - both derive from SgAsmGenericString. Changing the value of an SgAsmBasicString has no effect on the unparsed file. - -\subsection{Modifications ELF Section Table Entries} -%=============================================================================================================================== -%Modifications ELF Section Table Entries -%=============================================================================================================================== - -Every ELF Section defined by the ELF Section Table is parsed as an SgAsmElfSection, which is derived from SgAsmGenericSection. -The SgAsmElfSection::get\_section\_entry returns a pointer to the ELF Section Table Entry (SgAsmElfSectionTableEntry). Some -members of these objects can be modified and some can't. - -\subsubsection{1. These functions should not be called since their values are overwritten during the unparse phase:} - -\begin{itemize} - \item SgAsmElfSectionTableEntry::set\_sh\_name -- see SgAsmGenericSection::set\_name - \item SgAsmElfSectionTableEntry::set\_sh\_addr -- see SgAsmGenericFile::shift\_extend - \item SgAsmElfSectionTableEntry::set\_sh\_offset -- see SgAsmGenericFile::shift\_extend - \item SgAsmElfSectionTableEntry::set\_sh\_size -- see SgAsmGenericFile::shift\_extend - \item SgAsmElfSectionTableEntry::set\_sh\_link -- don't call (no alternative yet) -\end{itemize} - -\subsubsection{2. Can modify} - -\fixme{What text should go here?} - -\begin{itemize} - \item SgAsmElfSectionTableEntry::set\_sh\_type - \item SgAsmElfSectionTableEntry::set\_sh\_flags, although the Write and Execute bits are ignored - \item SgAsmElfSectionTableEntry::set\_sh\_info \fixme{Is this complete?} - \item SgAsmElfSectionTableEntry::set\_sh\_addralign \fixme{Is this complete?} - \item SgAsmElfSectionTableEntry::set\_sh\_entsize \fixme{Is this complete?} -\end{itemize} - - -\section{Dynamic Analysis Support} -\label{intel_pin} - - Recent work in ROSE has added support for dynamic analysis and for mixing of dynamic -and static analysis using the Intel Pin framework. This optional support in ROSE -requires a configure option ({\tt --with-IntelPin=$}. The {\tt path} in -the configure option is the path to the top level directory of the location of -the Intel Pin distribution. This support for Intel Pin has only been tested -on a 64bit Linux system using the most recent distribution of Intel Pin (version 2.6). - -Note: The dwarf support in ROSE is currently incompatible with the dwarf support in -Intel Pin. A message in the configuration of ROSE will detect if both support for -Dwarf and Intel Pin are both specified and exit with an error message that they -are incompatible options. - - -\section{Usage} - See the ROSE Tutorial for examples. - - - diff --git a/docs/Rose/documents.html b/docs/Rose/documents.html index 49bcd0222a0..951a154ccdd 100644 --- a/docs/Rose/documents.html +++ b/docs/Rose/documents.html @@ -39,11 +39,6 @@
  • Tutorials (pdf)
  • Doxygen Documentation ROSE (html)
  • -
  • Doxygen Documentation for ROSE Qt Widgets (html)
  • -
  • Doxygen Documentation for ROSE Haskell Binding API (html)
  • -
  • Compass Manual (pdf)
  • -
  • Autotuning Tutorials (pdf)
  • -
  • QROSE Manual (pdf)
  •  

     

    diff --git a/docs/Rose/projects.html b/docs/Rose/projects.html deleted file mode 100644 index 8067accd645..00000000000 --- a/docs/Rose/projects.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - -ROSE Projects - - - - - - - - - - - - - - - - - - - -
    - - - -   - - - - -
    -

    ROSE has been used to facilitate a number of projects for exploring program analyses and optimizations, supporting new programming languages, and building correctness and performance tools. Representative examples include: -

    -

      -
    • Compass: a tool for the checking of source code. - Compass is based on the ROSE compiler infrastructure and demonstrates the use of ROSE - to build many simple pattern detectors for analysis of C, C++, and Fortran - source code. See the current Compass Manual for details.
    • -
    • Whole-program empirical optimization: participation in the PERI project. - ROSE is a central component in the PERI project to enable performance portability of DOE applications - through an empirical optimization system, - which incorporates a set of external tools interacting with ROSE to - support the entire life-cycle of automated empirical optimization. - See the current draft autotuning tutorial for details. -
    • -
    • Loop optimizer: support for aggressive loop optimizations such as loop fusion, - fission, unrolling and blocking. An extended dependence analysis algorithm has been implemented to support both perfectly nested loops and irregular loop nests.
    • -
    • OpenMP: a project to support OpenMP using ROSE. ROSE already has a lightweight parser for OpenMP C/C++ pragmas and a translator for OpenMP 2.5 constructs. We are extending it to support Fortran and the new OpenMP 3.0 specification.
    • -
    • UPC: ongoing work to support UPC using ROSE. We are leveraging the existing UPC support available in the EDG frontend to build an environment for program analysis and optimizations for UPC applications.
    • -
    • Haskellport: an interface to ROSE's IR for the Haskell programming language. See the tutorial (a chapter of the ROSE Tutorial) and API documentation for details. -
    • Windows support: We are currently working to support ROSE under Windows using Visual Studio (via CMake generation of the MSVC Solutions file)
    • -

    -
    - -
    - - diff --git a/docs/Rose/rose.cfg.in b/docs/Rose/rose.cfg.in index f71223e73a0..cde451f6382 100644 --- a/docs/Rose/rose.cfg.in +++ b/docs/Rose/rose.cfg.in @@ -1,117 +1,137 @@ -# Doxyfile 1.8.1.1 -# -# This is the minimum doxygen version supported by ROSE. Newer -# versions of doxygen will probably produce warnings about certain -# things in this file. Do not regenerate this file to a newer version -# without prior discussion. [The ROSE Team] - - +# Doxyfile 1.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored. +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. # The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. PROJECT_NAME = ROSE -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. PROJECT_NUMBER = @VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. OUTPUT_DIRECTORY = ./ROSE_WebPages -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = YES + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. -CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. +# The default value is: YES. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# doxygen will generate a detailed section even if there is only a brief # description. +# The default value is: NO. ALWAYS_DETAILED_SEC = NO @@ -119,581 +139,754 @@ ALWAYS_DETAILED_SEC = NO # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. +# The default value is: NO. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. JAVADOC_AUTOBRIEF = YES -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. MARKDOWN_SUPPORT = YES +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. +# The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. +# The default value is: NO. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. +# The default value is: NO. DISTRIBUTE_GROUP_DOC = YES -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. SUBGROUPING = YES -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. INLINE_GROUPED_CLASSES = NO -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. INLINE_SIMPLE_STRUCTS = NO -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -# DQ (12/19/2015): This is no longer used (reported as a warning by doxygen). -# SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which efficively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. EXTRACT_ALL = @DOXYGEN_EXTRACT_ALL@ -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@ -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@ -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_MEMBERS = @DOXYGEN_HIDE_UNDOC_MEMBERS@ -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. HIDE_UNDOC_CLASSES = @DOXYGEN_HIDE_UNDOC_CLASSES@ -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the # documentation. +# The default value is: NO. HIDE_FRIEND_COMPOUNDS = @DOXYGEN_HIDE_FRIEND_COMPOUNDS@ -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. INTERNAL_DOCS = @DOXYGEN_INTERNAL_DOCS@ -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# The default value is: system dependent. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. SHOW_INCLUDE_FILES = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. SORT_MEMBER_DOCS = NO -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. SORT_MEMBERS_CTORS_1ST = YES -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. GENERATE_TODOLIST = NO -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. GENERATE_TESTLIST = NO -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. GENERATE_BUGLIST = NO -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. GENERATE_DEPRECATEDLIST= NO -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. ENABLED_SECTIONS = @DOXYGEN_ENABLED_SECTIONS@ -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. +# The default value is: YES. SHOW_USED_FILES = YES -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. LAYOUT_FILE = @top_srcdir@/docs/Rose/roseDoxygenLayout.xml -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- -# configuration options related to warning and progress messages +# Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. WARN_IF_DOC_ERROR = YES -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- -# configuration options related to the input files +# Configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -# NOTE: If your file isn't being picked up by doxygen, then perhaps it's listed -# in the EXCLUDE variable below. - -# NOTE: Do not add EDG source files to this list or else source code may leak -# into the documentation. - -# NOTE: The order of the files/directories listed here is generally the same order -# they'll appear in the documentation except when some other sort order -# prevails (e.g., alphabetical or source-order). +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. INPUT = @top_srcdir@/docs/Rose/MainPage.dox \ - @top_srcdir@/docs/Rose/ToolDevelopment \ - @top_srcdir@/docs/Rose/LibraryGeneralPrinciples.dox \ - @top_srcdir@/docs/Rose/BinaryTutorial.dox \ - @top_srcdir@/docs/Rose/Developers.dox \ + @top_srcdir@/docs/Rose/ToolDevelopment \ + @top_srcdir@/docs/Rose/LibraryGeneralPrinciples.dox \ + @top_srcdir@/docs/Rose/Developers.dox \ @top_srcdir@/docs/Rose \ @top_pwd@/src/frontend/SageIII \ @top_srcdir@/src/frontend/frontend.docs \ @top_srcdir@/docs/testDoxygen \ - @top_srcdir@/src/Rose \ - @top_srcdir@/src/Rose/CommandLine \ - @top_srcdir@/src/Rose/StringUtility \ - @top_srcdir@/src/Rose/AST \ + @top_srcdir@/src/frontend/CxxFrontend/EDG/edgRose \ + @top_srcdir@/src/frontend/OpenFortranParser_SAGE_Connection \ @top_srcdir@/src/frontend/SageIII/ \ + @top_srcdir@/src/frontend/SageIII/sage.docs \ @top_srcdir@/src/frontend/SageIII/docs \ - @top_srcdir@/src/frontend/SageIII/astPostProcessing/checkIsModifiedFlag.C \ + @top_srcdir@/src/frontend/SageIII/astFixup \ + @top_srcdir@/src/frontend/SageIII/astHiddenTypeAndDeclarationLists \ + @top_srcdir@/src/frontend/SageIII/astPostProcessing \ + @top_srcdir@/src/frontend/SageIII/astTokenStream \ + @top_srcdir@/src/frontend/SageIII/includeDirectivesProcessing \ + @top_srcdir@/src/frontend/SageIII/sage_support \ @top_srcdir@/src/frontend/SageIII/sageInterface \ @top_srcdir@/src/frontend/SageIII/virtualCFG \ @top_srcdir@/src/midend/programTransformation/ompLowering \ @top_srcdir@/src/midend/midend.docs \ + @top_srcdir@/src/midend/abstractLayer \ + @top_srcdir@/src/midend/astDiagnostics \ @top_srcdir@/src/midend/astDiagnostics/AstDiagnostics.docs \ + @top_srcdir@/src/midend/astDump \ + @top_srcdir@/src/midend/astDump/MSTL.docs \ + @top_srcdir@/src/midend/astProcessing \ + @top_srcdir@/src/midend/astProcessing/AstProcessing.docs \ + @top_srcdir@/src/midend/astQuery \ + @top_srcdir@/src/midend/astQuery/QueryLib.docs \ + @top_srcdir@/src/midend/astUtil \ @top_srcdir@/src/midend/programAnalysis/CallGraphAnalysis \ @top_srcdir@/src/midend/programAnalysis/genericDataflow \ @top_srcdir@/src/midend/programAnalysis/genericDataflow/analysis \ @@ -707,8 +900,6 @@ INPUT = @top_srcdir@/docs/Rose/MainPage.dox \ @top_srcdir@/src/midend/programTransformation/documentation.docs \ @top_srcdir@/src/midend/programTransformation/extractFunctionArgumentsNormalization \ @top_srcdir@/src/midend/programTransformation/ompLowering/omp_lowering.h \ - @top_srcdir@/src/midend/astProcessing \ - @top_srcdir@/src/midend/astQuery/QueryLib.docs \ @top_srcdir@/src/backend/backend.docs \ @top_srcdir@/src/backend/unparser/unparser.docs \ @top_srcdir@/src/backend/unparser/languageIndependenceSupport/documentation.docs \ @@ -716,57 +907,60 @@ INPUT = @top_srcdir@/docs/Rose/MainPage.dox \ @top_srcdir@/src/backend/unparser/FortranCodeGeneration/documentation.docs \ @top_srcdir@/src/util \ @top_srcdir@/src/util/utilDocumentation.docs \ - @top_srcdir@/src/util/stringSupport/stringSupportDocumentation.docs \ - @top_srcdir@/src/util/stringSupport/ \ @top_srcdir@/src/util/commandlineProcessing \ + @top_srcdir@/src/util/graphs \ + @top_srcdir@/src/util/StringUtility/stringSupportDocumentation.docs \ + @top_srcdir@/src/util/StringUtility \ + @top_srcdir@/src/util/support \ @top_srcdir@/src/3rdPartyLibraries/3rdPartyLibraries.docs \ - @top_srcdir@/src/3rdPartyLibraries/MSTL/MSTL.docs \ @top_srcdir@/src/extra.docs # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl, +# *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.h \ *.docs \ *.dox \ *.hh -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. +# # Note that relative paths are relative to the directory from which doxygen is # run. -# Use this to "comment out" whole files that are deprecated. [Robb Matzke, 2015-10-01] - EXCLUDE = @top_srcdir@/src/frontend/CxxFrontend/EDG \ - @top_srcdir@/AST_RewriteMechanism/testRewrite.h \ - @top_srcdir@/AST_RewriteMechanism/testRewrite.C \ - @top_srcdir@/AST_RewriteMechanism/testNewRewrite.h \ - @top_srcdir@/AST_RewriteMechanism/testNewRewrite.C \ - @top_srcdir@/AST_RewriteMechanism/testRewritePermutations.C \ - @top_srcdir@/AST_RewriteMechanism/testRewriteReplacementPermutations.C \ - @top_srcdir@/AST_RewriteMechanism/test1.C \ - @top_srcdir@/AST_RewriteMechanism/inputProgram1.C \ @top_srcdir@/src/frontend/SageIII/sageInterface/highLevelInterface.h \ @top_srcdir@/src/midend/ompLowering/libgomp_g.h \ @top_srcdir@/util/testStrings.C \ @@ -779,14 +973,16 @@ EXCLUDE = @top_srcdir@/src/frontend/CxxFrontend/EDG \ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. +# The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = @@ -795,761 +991,1226 @@ EXCLUDE_PATTERNS = # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). EXAMPLE_PATH = @top_srcdir@ \ - @top_srcdir@/tutorial \ - @top_srcdir@/src/util/Sawyer/docs/examples + @top_srcdir@/tutorial # If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). IMAGE_PATH = @top_srcdir@/docs/Rose # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + #--------------------------------------------------------------------------- -# configuration options related to source browsing +# Configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. REFERENCES_RELATION = YES -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled and the CLANG_ADD_INC_PATHS tag is set to +# YES then doxygen will add the directory of each input to the include path. +# The default value is: YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + #--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index +# Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- -# configuration options related to the HTML output +# Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = ROSE_HTML_Reference -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# style sheet in the HTML output directory as well, or it will be erased! +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = @top_srcdir@/docs/Rose/roseDoxygen.css +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: +# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be # written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 1 -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /
  • User Manual (pdf)