void virtual visit (SgNode* n) { if (isSgProject(n)|| isSgSourceFile(n)||isSgInitializedName(n)||isSgLocatedNode(n)) { setId (n); } }
//! A helper function to build a single abstract handle item static abstract_handle * buildSingleAbstractHandle(SgNode* snode, abstract_handle * p_handle = NULL) { abstract_handle * result = NULL; ROSE_ASSERT (snode != NULL); abstract_node * anode = buildroseNode(snode); ROSE_ASSERT (anode != NULL); // look up first result = handle_map[anode]; if (result != NULL) return result; //Create the single handle item if (isSgSourceFile (snode) || isSgProject(snode) ||isSgGlobal(snode)) result = new abstract_handle (anode); // default name or file location specifiers are used else { // any other types of AST node, use numbering or name within the parent handle ROSE_ASSERT (p_handle != NULL); if (isSgFunctionDefinition(snode)) result = new abstract_handle (anode, e_name, p_handle); else result = new abstract_handle (anode, e_numbering, p_handle); } ROSE_ASSERT (result != NULL); // cache the result handle_map[anode] = result; return result; }
void CFG::buildFilteredCFG() { all_nodes_.clear(); clearNodesAndEdges(); std::set<VirtualCFG::InterestingNode> explored; std::map<VirtualCFG::InterestingNode, SgGraphNode*> all_nodes; graph_ = new SgIncidenceDirectedGraph; if (SgProject* project = isSgProject(start_)) { Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition); for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) { SgFunctionDefinition* proc = isSgFunctionDefinition(*i); if (proc) { buildCFG<VirtualCFG::InterestingNode, VirtualCFG::InterestingEdge> (VirtualCFG::makeInterestingCfg(proc), all_nodes, explored); } } } else buildCFG<VirtualCFG::InterestingNode, VirtualCFG::InterestingEdge> (VirtualCFG::makeInterestingCfg(start_), all_nodes, explored); typedef std::pair<VirtualCFG::InterestingNode, SgGraphNode*> pair_t; foreach (const pair_t& p, all_nodes) all_nodes_[VirtualCFG::CFGNode(p.first.getNode(), 0)] = p.second; }
//! A default builder function handles all details: file use name, others use numbering // Algorithm: // Go through all parent scopes until reach SgSourceFile. store them into a list // iterate on the list to generate all abstract handles, with optional the parent handle information abstract_handle * buildAbstractHandle(SgNode* snode) { ROSE_ASSERT (snode != NULL); // simple nodes if (isSgSourceFile (snode) || isSgProject(snode) ||isSgGlobal(snode)) return buildSingleAbstractHandle (snode); // all other nodes, trace back to SgGlobal, store all intermediate scope nodes std::vector<SgNode*> scope_list; SgScopeStatement* p_scope = SageInterface::getEnclosingScope(snode); while (!isSgGlobal(p_scope)) { scope_list.push_back(p_scope); p_scope = SageInterface::getEnclosingScope(p_scope); } ROSE_ASSERT (isSgGlobal(p_scope)); abstract_handle * p_handle = buildSingleAbstractHandle (p_scope); // Now go through the list to generate numbering handles std::vector<SgNode*>::reverse_iterator riter; for (riter = scope_list.rbegin(); riter!= scope_list.rend(); riter++) { SgNode* c_node = *riter; p_handle = buildSingleAbstractHandle (c_node, p_handle); } ROSE_ASSERT (p_handle != NULL); return buildSingleAbstractHandle (snode, p_handle); }
SgFunctionDeclaration *RoseToLLVM::findEnclosingFunction(SgNode *node) { return (node == NULL || isSgProject(node) ? (SgFunctionDeclaration *) NULL : isSgFunctionDeclaration(node) ? (SgFunctionDeclaration *) node : findEnclosingFunction(node -> get_parent())); }
SgFile *RoseToLLVM::findEnclosingFile(SgNode *node) { return (node == NULL || isSgProject(node) ? (SgFile *) NULL : isSgFile(node) ? (SgFile *) node : findEnclosingFile(node -> get_parent())); }
void CFG::buildFullCFG() { // Before building a new CFG, make sure to clear all nodes built before. all_nodes_.clear(); clearNodesAndEdges(); std::set<VirtualCFG::CFGNode> explored; graph_ = new SgIncidenceDirectedGraph; if (SgProject* project = isSgProject(start_)) { Rose_STL_Container<SgNode*> functions = NodeQuery::querySubTree(project, V_SgFunctionDefinition); for (Rose_STL_Container<SgNode*>::const_iterator i = functions.begin(); i != functions.end(); ++i) { SgFunctionDefinition* proc = isSgFunctionDefinition(*i); if (proc) { buildCFG<VirtualCFG::CFGNode, VirtualCFG::CFGEdge> (proc->cfgForBeginning(), all_nodes_, explored); } } } else buildCFG<VirtualCFG::CFGNode, VirtualCFG::CFGEdge> (start_->cfgForBeginning(), all_nodes_, explored); }
/* we need a file handle, not just the file name string * so a node for file is needed to generate the file handle legally. */ abstract_node* roseNode::getFileNode() const { ROSE_ASSERT(mNode!=NULL); if (isSgProject(mNode)) // project node has no single file associated. return NULL; SgFile* filenode = getEnclosingFileNode(mNode); abstract_node* result = buildroseNode(filenode); return result; }
void fixupAstSymbolTables( SgNode* node ) { // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer1 ("Fixup symbol tables:"); // DQ (1/31/2006): Modified to build all types in the memory pools // DQ (6/26/2005): The global function type symbol table should be rebuilt (since the names of templates // used in qualified names of types have been reset (in post processing). // extern SgFunctionTypeTable Sgfunc_type_table; // fixupGlobalFunctionSymbolTable(Sgfunc_type_table); ROSE_ASSERT(SgNode::get_globalFunctionTypeTable() != NULL); fixupGlobalFunctionSymbolTable(SgNode::get_globalFunctionTypeTable()); // DQ (5/16/2006): Fixup the parent of the globalFunctionTypeTable to be either the SgProject or SgFile if (SgNode::get_globalFunctionTypeTable()->get_parent() == NULL) { SgProject* project = isSgProject(node); SgFile* file = isSgFile(node); if (project != NULL || file != NULL) SgNode::get_globalFunctionTypeTable()->set_parent(node); } // DQ (7/25/2010): Set the parent of the global type table to the SgProject if (SgNode::get_globalTypeTable()->get_parent() == NULL) { SgProject* project = isSgProject(node); SgFile* file = isSgFile(node); if (project != NULL || file != NULL) SgNode::get_globalTypeTable()->set_parent(node); } // DQ (7/7/2005): Introduce tracking of performance of ROSE. TimingPerformance timer2 ("Fixup local symbol tables:"); // Now fixup the local symbol tables // This simplifies how the traversal is called! FixupAstSymbolTables astFixupTraversal; // I think the default should be preorder so that the interfaces would be more uniform astFixupTraversal.traverse(node,preorder); }
void SgProject::fixupCopy_symbols(SgNode* copy, SgCopyHelp & help) const { #if DEBUG_FIXUP_COPY printf ("Inside of SgProject::fixupCopy_symbols() \n"); #endif SgProject* project_copy = isSgProject(copy); ROSE_ASSERT(project_copy != NULL); // Call fixup on all fo the files (SgFile objects) for (int i = 0; i < numberOfFiles(); i++) { SgFile & file = get_file(i); SgFile & file_copy = project_copy->get_file(i); file.fixupCopy_symbols(&file_copy,help); } }
MetricsConfig *ProjectManager::getMetricsConfig( SgNode *node ) { if( node == NULL ) return NULL; if( rootNode == NULL ) return NULL; // finding the project root ... SgNode *proj = node; while( proj->get_parent() ) { proj = proj->get_parent(); } assert( isSgProject( proj ) ); for( int i = 0; i < getProjectCount(); ++i ) { if( proj == getSgProject( i ) ) { return getProject( i )->getMetricsConfig(); } } return NULL; }
/* * The function * findScope() * takes as a parameter a SgNode* which is a SgStatement*. It returns a SgNodePtrVector of all * preceding scopes the SgStatement is in. * */ SgNodePtrVector findScopes (SgNode * astNode) { ROSE_ASSERT (isSgStatement (astNode)); SgNodePtrVector returnVector; SgScopeStatement *currentScope; if (isSgScopeStatement (astNode)) { currentScope = isSgScopeStatement (astNode); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (astNode); } else { SgStatement *sageStatement = isSgStatement (astNode); ROSE_ASSERT (sageStatement != NULL); currentScope = sageStatement->get_scope (); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (currentScope); } while (currentScope->variantT () != V_SgGlobal) { currentScope = currentScope->get_scope (); ROSE_ASSERT (currentScope != NULL); returnVector.push_back (currentScope); } //Must also include the Global Scopes of the other files in the project if (currentScope->variantT () == V_SgGlobal) { SgFile *sageFile = isSgFile ((currentScope)->get_parent ()); ROSE_ASSERT (sageFile != NULL); SgProject *sageProject = isSgProject (sageFile->get_parent ()); ROSE_ASSERT (sageProject != NULL); //Get a list of all files in the current project const SgFilePtrList sageFilePtrList = sageProject->get_fileList (); //Iterate over the list of files to find all Global Scopes SgNodePtrVector globalScopes; for (unsigned int i = 0; i < sageFilePtrList.size (); i += 1) { const SgFile *sageFile = isSgFile (sageFilePtrList[i]); ROSE_ASSERT (sageFile != NULL); if( isSgSourceFile(sageFile) != NULL ) { SgGlobal *sageGlobal = isSgSourceFile(sageFile)->get_globalScope (); ROSE_ASSERT (sageGlobal != NULL); returnVector.push_back (sageGlobal); } } } return returnVector; };
//return name for various named constructs string roseNode::getName() const { string result; ROSE_ASSERT(mNode!=NULL); // only declarations with symbols in ROSE have user-level names // need to double check this if (isSgFile(mNode)) { return isSgFile(mNode)->get_file_info()->get_filenameString (); } else if (isSgProject(mNode)) { // No name field for rose projects return ""; } else if (isSgFunctionDefinition(mNode)) { SgFunctionDefinition* def = isSgFunctionDefinition(mNode); return (def->get_declaration()->search_for_symbol_from_symbol_table()->get_name()).getString(); } SgDeclarationStatement* decl = isSgDeclarationStatement(mNode); if (decl) { switch (decl->variantT()) { case V_SgVariableDeclaration: { SgVariableSymbol * symbol=SageInterface::getFirstVarSym(isSgVariableDeclaration(decl)); result = symbol->get_name(); break; } case V_SgClassDeclaration: case V_SgTypedefDeclaration: case V_SgNamespaceDeclarationStatement: case V_SgFunctionDeclaration: case V_SgTemplateDeclaration: case V_SgMemberFunctionDeclaration: { result = (decl->search_for_symbol_from_symbol_table()->get_name()).getString(); ROSE_ASSERT(result.length()!=0); break; } // No explicit name available case V_SgCtorInitializerList: case V_SgPragmaDeclaration: case V_SgFunctionParameterList: case V_SgUsingDirectiveStatement: case V_SgStmtDeclarationStatement: { break; } default: { cerr<<"error, unhandled declaration type in roseNode::getName(): "<<mNode->class_name()<<endl; ROSE_ASSERT(false); break; } }// end switch } return result ; }
string globalUnparseToString ( SgNode* astNode, SgUnparse_Info* inputUnparseInfoPointer ) { // This global function permits any SgNode (including it's subtree) to be turned into a string // DQ (3/2/2006): Let's make sure we have a valid IR node! ROSE_ASSERT(astNode != NULL); string returnString; // all options are now defined to be false. When these options can be passed in // from the prompt, these options will be set accordingly. bool _auto = false; bool linefile = false; bool useOverloadedOperators = false; bool num = false; // It is an error to have this always turned off (e.g. pointer = this; will not unparse correctly) bool _this = true; bool caststring = false; bool _debug = false; bool _class = false; bool _forced_transformation_format = false; bool _unparse_includes = false; // printf ("In globalUnparseToString(): astNode->sage_class_name() = %s \n",astNode->sage_class_name()); Unparser_Opt roseOptions( _auto, linefile, useOverloadedOperators, num, _this, caststring, _debug, _class, _forced_transformation_format, _unparse_includes ); int lineNumber = 0; // Zero indicates that ALL lines should be unparsed // Initialize the Unparser using a special string stream inplace of the usual file stream ostringstream outputString; SgLocatedNode* locatedNode = isSgLocatedNode(astNode); string fileNameOfStatementsToUnparse; if (locatedNode == NULL) { // printf ("WARNING: applying AST -> string for non expression/statement AST objects \n"); fileNameOfStatementsToUnparse = "defaultFileNameInGlobalUnparseToString"; } else { ROSE_ASSERT (locatedNode != NULL); // DQ (5/31/2005): Get the filename from a traversal back through the parents to the SgFile // fileNameOfStatementsToUnparse = locatedNode->getFileName(); // fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode); if (locatedNode->get_parent() == NULL) { // DQ (7/29/2005): // Allow this function to be called with disconnected AST fragments not connected to // a previously generated AST. This happens in Qing's interface where AST fragements // are built and meant to be unparsed. Only the parent of the root of the AST // fragement is expected to be NULL. fileNameOfStatementsToUnparse = locatedNode->getFileName(); } else { fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode); } } ROSE_ASSERT (fileNameOfStatementsToUnparse.size() > 0); Unparser roseUnparser ( &outputString, fileNameOfStatementsToUnparse, roseOptions, lineNumber ); // Information that is passed down through the tree (inherited attribute) // Use the input SgUnparse_Info object if it is available. SgUnparse_Info* inheritedAttributeInfoPointer = NULL; if (inputUnparseInfoPointer != NULL) { // printf ("Using the input inputUnparseInfoPointer object \n"); // Use the user provided SgUnparse_Info object inheritedAttributeInfoPointer = inputUnparseInfoPointer; } else { // DEFINE DEFAULT BEHAVIOUR FOR THE CASE WHEN NO inputUnparseInfoPointer (== NULL) IS // PASSED AS ARGUMENT TO THE FUNCTION // printf ("Building a new Unparse_Info object \n"); // If no input parameter has been specified then allocate one // inheritedAttributeInfoPointer = new SgUnparse_Info (NO_UNPARSE_INFO); inheritedAttributeInfoPointer = new SgUnparse_Info(); ROSE_ASSERT (inheritedAttributeInfoPointer != NULL); // MS: 09/30/2003: comments de-activated in unparsing ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == false); // Skip all comments in unparsing inheritedAttributeInfoPointer->set_SkipComments(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == true); // Skip all whitespace in unparsing (removed in generated string) inheritedAttributeInfoPointer->set_SkipWhitespaces(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipWhitespaces() == true); // Skip all directives (macros are already substituted by the front-end, so this has no effect on those) inheritedAttributeInfoPointer->set_SkipCPPDirectives(); ROSE_ASSERT (inheritedAttributeInfoPointer->SkipCPPDirectives() == true); } ROSE_ASSERT (inheritedAttributeInfoPointer != NULL); SgUnparse_Info & inheritedAttributeInfo = *inheritedAttributeInfoPointer; // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called // SgUnparse_Info::forceDefaultConstructorToTriggerError = true; #if 1 // DQ (10/19/2004): Cleaned up this code, remove this dead code after we are sure that this worked properly // Actually, this code is required to be this way, since after this branch the current function returns and // some data must be cleaned up differently! So put this back and leave it this way, and remove the // "Implementation Note". // Both SgProject and SgFile are handled via recursive calls if ( (isSgProject(astNode) != NULL) || (isSgFile(astNode) != NULL) ) { // printf ("Implementation Note: Put these cases (unparsing the SgProject and SgFile into the cases for nodes derived from SgSupport below! \n"); // Handle recursive call for SgProject if (isSgProject(astNode) != NULL) { SgProject* project = isSgProject(astNode); ROSE_ASSERT(project != NULL); for (int i = 0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); ROSE_ASSERT(file != NULL); string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer); string prefixString = string("/* TOP:") + string(rose::getFileName(file)) + string(" */ \n"); string suffixString = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n"); returnString += prefixString + unparsedFileString + suffixString; } } // Handle recursive call for SgFile if (isSgFile(astNode) != NULL) { SgFile* file = isSgFile(astNode); ROSE_ASSERT(file != NULL); SgGlobal* globalScope = file->get_root(); ROSE_ASSERT(globalScope != NULL); returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer); } } else #endif { // DQ (1/12/2003): Only now try to trap use of SgUnparse_Info default constructor // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called SgUnparse_Info::set_forceDefaultConstructorToTriggerError(true); if (isSgStatement(astNode) != NULL) { SgStatement* stmt = isSgStatement(astNode); roseUnparser.unparseStatement ( stmt, inheritedAttributeInfo ); } if (isSgExpression(astNode) != NULL) { SgExpression* expr = isSgExpression(astNode); roseUnparser.unparseExpression ( expr, inheritedAttributeInfo ); } if (isSgType(astNode) != NULL) { SgType* type = isSgType(astNode); roseUnparser.unparseType ( type, inheritedAttributeInfo ); } if (isSgSymbol(astNode) != NULL) { SgSymbol* symbol = isSgSymbol(astNode); roseUnparser.unparseSymbol ( symbol, inheritedAttributeInfo ); } if (isSgSupport(astNode) != NULL) { // Handle different specific cases derived from SgSupport // (e.g. template parameters and template arguments). switch (astNode->variantT()) { #if 0 case V_SgProject: { SgProject* project = isSgProject(astNode); ROSE_ASSERT(project != NULL); for (int i = 0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); ROSE_ASSERT(file != NULL); string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer); string prefixString = string("/* TOP:") + string(rose::getFileName(file)) + string(" */ \n"); string suffixString = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n"); returnString += prefixString + unparsedFileString + suffixString; } break; } case V_SgFile: { SgFile* file = isSgFile(astNode); ROSE_ASSERT(file != NULL); SgGlobal* globalScope = file->get_root(); ROSE_ASSERT(globalScope != NULL); returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer); break; } #endif case V_SgTemplateParameter: { SgTemplateParameter* templateParameter = isSgTemplateParameter(astNode); roseUnparser.unparseTemplateParameter(templateParameter,inheritedAttributeInfo); break; } case V_SgTemplateArgument: { SgTemplateArgument* templateArgument = isSgTemplateArgument(astNode); roseUnparser.unparseTemplateArgument(templateArgument,inheritedAttributeInfo); break; } case V_SgInitializedName: { // QY: not sure how to implement this // DQ (7/23/2004): This should unparse as a declaration // (type and name with initializer). break; } case V_Sg_File_Info: { // DQ (5/11/2006): Not sure how or if we shoul implement this break; } // Perhaps the support for SgFile and SgProject shoud be moved to this location? default: printf ("Error: default reached in node derived from SgSupport astNode = %s \n",astNode->sage_class_name()); ROSE_ABORT(); } } // Turn OFF the error checking which triggers an if the default SgUnparse_Info constructor is called SgUnparse_Info::set_forceDefaultConstructorToTriggerError(false); // MS: following is the rewritten code of the above outcommented // code to support ostringstream instead of ostrstream. returnString = outputString.str(); // Call function to tighten up the code to make it more dense if (inheritedAttributeInfo.SkipWhitespaces() == true) { returnString = roseUnparser.removeUnwantedWhiteSpace ( returnString ); } // delete the allocated SgUnparse_Info object if (inputUnparseInfoPointer == NULL) delete inheritedAttributeInfoPointer; } return returnString; }
// GB (05/30/2007): This was completely rewritten from the old version to // use much more efficient comparisons now available to us; it also never // causes visits to included files, something that happened from time to // time with the old version. bool SgTreeTraversal_inFileToTraverse(SgNode* node, bool traversalConstraint, SgFile* fileToVisit) { // If traversing without constraint, just continue. // if (!traversalConstraint) if (traversalConstraint == false) { return true; } #if 0 // DQ (8/20/2018): Added debugging for support unparsing of header files. printf ("In SgTreeTraversal_inFileToTraverse(): fileToVisit = %p filename = %s \n",fileToVisit,fileToVisit->getFileName().c_str()); #endif // DQ (1/21/2008): Recently added SgAsmNodes for binaries also do not // have a SgFileInfo object. // Of all the nodes to be traversed, only SgProject is allowed to have // a NULL file info; go ahead and try to traverse it (even though this // does not make sense since it is not within any file). if (node->get_file_info() == NULL) { // DQ (1/20/2008): This fails for binary files, why is this! // if (isSgProject(node) == NULL) // printf ("What node is this: node = %p = %s \n",node,node->class_name().c_str()); // SageInterface::get_name(node).c_str()); // ROSE_ASSERT(isSgProject(node) != NULL); // DQ (11/20/2013): Added SgJavaImportStatementList and SgJavaClassDeclarationList to the exception list since they don't have a source position field. // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL) if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL) { printf ("Error: SgTreeTraversal_inFileToTraverse() --- node->get_file_info() == NULL: node = %p = %s \n",node,node->class_name().c_str()); SageInterface::dumpInfo(node); } #if 0 // DQ (11/19/2013): Allow this to pass while we are evaluating the AST traversal for Java. // ROSE_ASSERT(isSgProject(node) != NULL || isSgAsmNode(node) != NULL); // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL) if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL) { printf ("WARNING: isSgProject(node) == NULL && isSgAsmNode(node) == NULL: this could be Java code using an incomplete AST: node = %p = %s \n",node,node->class_name().c_str()); } #endif return true; } // Traverse compiler generated code and code generated from // transformations, unless it is "frontend specific" like the stuff in // rose_edg_required_macros_and_functions.h. bool isFrontendSpecific = node->get_file_info()->isFrontendSpecific(); bool isCompilerGeneratedOrPartOfTransformation; if (isFrontendSpecific) { isCompilerGeneratedOrPartOfTransformation = false; } else { // DQ (11/14/2008): Implicitly defined functions in Fortran are not marked as compiler generated // (the function body is at least explicit in the source file), but the function declaration IR // nodes is marked as coming from file == NULL_FILE and it is also marked as "outputInCodeGeneration" // So it should be traversed so that we can see the function body and so that it can be a proper // part of the definition of the AST. // isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation(); bool isOutputInCodeGeneration = node->get_file_info()->isOutputInCodeGeneration(); isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation() || isOutputInCodeGeneration; } // Traverse this node if it is in the file we want to visit. bool isRightFile = node->get_file_info()->isSameFile(fileToVisit); #if 0 printf ("In SgTreeTraversal_inFileToTraverse(): node = %p = %s isRightFile = %s \n",node,node->class_name().c_str(),isRightFile ? "true" : "false"); #endif // This function is meant to traverse input files in the sense of not // visiting "header" files (a fuzzy concept). But not every #included file // is a header, "code" (another fuzzy concept) can also be #included; see // test2005_157.C for an example. We want to traverse such code, so we // cannot rely on just comparing files. // The following heuristic is therefore used: If a node is included from // global scope or from within a namespace definition, we guess that it is // a header and don't traverse it. Otherwise, we guess that it is "code" // and do traverse it. bool isCode = node->get_parent() != NULL && !isSgGlobal(node->get_parent()) && !isSgNamespaceDefinitionStatement(node->get_parent()); bool traverseNode; if (isCompilerGeneratedOrPartOfTransformation || isRightFile || isCode) traverseNode = true; else traverseNode = false; #if 0 // DQ (8/17/2018): Need to stop here and debug this function tomorrow. printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif return traverseNode; }
//! This removes the original expression tree from value expressions where it has been constant folded by EDG. void resetConstantFoldedValues( SgNode* node ) { // This is the initial default, it will be changed later to be an optional behavior. // Note that all unparsing will use the original expression tree and is verified to generate // correct for all of the regression tests in C and C++. The original expression trees are // saved in ROSE as part of supporting source to source work. One could conclude that the // original expression tree should always of never used as part of analysis, but not both // the constant folded value AND the original expression tree. // This is a temporary option, if false then we pass all tests and are consistent with historical configurations // of the ROSE AST, but it is inconsistent so we want to fix that (because it causes control flow problems). #if 1 // DQ (11/5/2012): Original value bool makeASTConstantFoldingExpressionConsistant = true; #else // DQ (11/5/2012): An experimental value while I play with the original expression trees. bool makeASTConstantFoldingExpressionConsistant = false; #endif #if 1 // This should be turned on except for internal testing. ROSE_ASSERT(makeASTConstantFoldingExpressionConsistant == true); #else printf ("WARNING: INTERNAL TESTING MODE: In resetConstantFoldedValues() \n"); ROSE_ASSERT(makeASTConstantFoldingExpressionConsistant == false); #endif // This will become an input option in the near future. Once they can be supported through all of the test codes. // The default is to use the original expression trees and replace the saved constant folded values in the AST. // Note that having both can lead to some confusion (e.g. in the control flow graph and analysis, so we select one // (no constant folded values) and make it an option to have the other (using constant folded values)). Note also // This this is EDG's definition of constant folding which is fairly aggressive. bool makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = true; // Constant folding is optional and can be specified as an optional parameter to "frontend()" function. // If set it sets a flag in the SgProject IR node. SgProject* project = isSgProject(node); if (project != NULL) { // Read the optional setting for constant folding in the frontend (only applied to C/C++ when using EDG). makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = (project->get_frontendConstantFolding() == false); } // ROSE_ASSERT(project != NULL); // printf ("project->get_frontendConstantFolding() = %s \n",(project->get_frontendConstantFolding() == true) ? "true" : "false"); #if 0 // SgProject* project = isSgProject(node); // Output an optional graph of the AST (the whole graph, of bounded complexity, when active) const int MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH = 8000; ROSE_ASSERT(project != NULL); if (project != NULL) { printf ("OUTPUT A GRAPH BEFORE CONSTANT FOLDING \n"); generateAstGraph(project,MAX_NUMBER_OF_IR_NODES_TO_GRAPH_FOR_WHOLE_GRAPH,"_before_constantfolding"); } #endif // printf ("In resetConstantFoldedValues(): makeASTConstantFoldingExpressionConsistant = %s \n",makeASTConstantFoldingExpressionConsistant ? "true" : "false"); if (makeASTConstantFoldingExpressionConsistant == true) { // printf ("In resetConstantFoldedValues(): makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees = %s \n",makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees ? "true" : "false"); if (makeASTConstantFoldingExpressionConsistant_useOriginalExpressionTrees == true) { // We want this to be the default for ROSE, since it matches what is output by the unparser and thus what // is required to pass all of the tests codes. // DQ (9/17/2011): This case fails dozens of test codes! // However, this case fails lot of tests codes due to the verification of all OriginalExpressionTree pointer // to be NULL and the name qualification tests (which fail as a result of the transformations to eliminate the // constant folded expressions and instead use the original expression trees). // printf ("WARNING: Testing current default to replace constant folded value with the original expression tree (future default setting for ROSE). \n"); // This replaces the constant folded value with the saved original expression tree (default). // This fails for test2011_113.C since we don't handle expressions in array types that contain // original expression trees. The reason is that original expression tree is not used to replace // the constant folded value and then (because of recent changes to the AST traversal) the variables // in the array types index expression is not processed for name qualification. // We need to either: // 1) uniformly define the how constants are replaced (everywhere) with their original expressions, or // 2) fix the name qualification to look into the original expression trees explicitly. // or both. // Note: If we fix #1 then we will not have to worry about #2, also I think that #1 defines a consistent // AST, where as #2 pushes the name qualification to simple work on the non-consistent AST. removeConstantFoldedValue(node); } else { // DQ (9/17/2011): This case fails only 2 test codes. Where the constant folded expression is unparsed but // does not generate the correct code. This may be a separate issue to investigate after we get the original // expression trees to be used (and the constant folding overridden; the other face below). // DQ (9/18/2011): Leave this warning message in place for now (we will likely remove it later). printf ("WARNING: Current default is to reset constant folding by removing the original expression tree. \n"); // This removes the original expression tree leaving the constant folded values (optional; not the default). // This fails for test2006_112.C (fails to compile unparsed code because the original expression is correct // code (if unparsed) while the constant folded expression is not correct code (if unparsed). In this case // the constant folded values are mostly useful for purposes of analysis. removeOriginalExpressionTrees(node); } // DQ (11/5/2012): I think this should be here rather than outside of this (put it back the way it was). // verifyOriginalExpressionTreesSetToNull(node); // DQ (4/26/2013): Moved here to permit makeASTConstantFoldingExpressionConsistant == false for debugging. // DQ (11/5/2012): Moved to inside of conditional (put this back the way it was). // verifyOriginalExpressionTreesSetToNull(node); } else { // DQ (4/26/2013): Added warning to support debugging of default argument handling in function call arguments. printf ("WARNING: makeASTConstantFoldingExpressionConsistant == false (temporary state for debugging mixed AST with constants and their original expression trees). \n"); } // DQ (4/26/2013): Commented out (see comment above). // DQ (11/5/2012): Moved to inside of conditional (put this back the way it was). verifyOriginalExpressionTreesSetToNull(node); }
POETCode* POETAstInterface::Ast2POET(const Ast& n) { static SgTemplateInstantiationFunctionDecl* tmp=0; SgNode* input = (SgNode*) n; if (input == 0) return EMPTY; POETCode* res = POETAstInterface::find_Ast2POET(input); if (res != 0) return res; { SgProject* sageProject=isSgProject(input); if (sageProject != 0) { int filenum = sageProject->numberOfFiles(); for (int i = 0; i < filenum; ++i) { SgSourceFile* sageFile = isSgSourceFile(sageProject->get_fileList()[i]); SgGlobal *root = sageFile->get_globalScope(); SgDeclarationStatementPtrList declList = root->get_declarations (); POETCode* curfile = ROSE_2_POET_list(declList, 0, tmp); curfile = new POETCode_ext(sageFile, curfile); POETAstInterface::set_Ast2POET(sageFile, curfile); res=LIST(curfile, res); } POETAstInterface::set_Ast2POET(sageProject,res); return res; } } { SgBasicBlock* block = isSgBasicBlock(input); if (block != 0) { res=ROSE_2_POET_list(block->get_statements(), res, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgExprListExp* block = isSgExprListExp(input); if (block != 0) { res=ROSE_2_POET_list(block->get_expressions(), 0, tmp); POETAstInterface::set_Ast2POET(block, res); return res; } } { SgForStatement *f = isSgForStatement(input); if (f != 0) { POETCode* init = ROSE_2_POET_list(f->get_for_init_stmt()->get_init_stmt(),0, tmp); POETCode* ctrl = new POETCode_ext(f, TUPLE3(init,Ast2POET(f->get_test_expr()), Ast2POET(f->get_increment()))); res = CODE_ACC("Nest", PAIR(ctrl,Ast2POET(f->get_loop_body()))); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgVarRefExp * v = isSgVarRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgMemberFunctionRefExp * v = isSgMemberFunctionRefExp(input); if (v != 0) { res = STRING(v->get_symbol()->get_name().str()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgIntVal * v = isSgIntVal(input); if (v != 0) { res = ICONST(v->get_value()); POETAstInterface::set_Ast2POET(input, res); return res; } } { SgInitializedName* var = isSgInitializedName(input); if (var != 0) { POETCode* name = STRING(var->get_name().str()); POETCode* init = Ast2POET(var->get_initializer()); res = new POETCode_ext(var, PAIR(name,init)); POETAstInterface::set_Ast2POET(input, res); return res; } } /* { std::string fname; AstInterface::AstList params; AstNodeType returnType; AstNodePtr body; if (AstInterface :: IsFunctionDefinition( input, &fname, ¶ms, (AstInterface::AstList*)0, &body, (AstInterface::AstTypeList*)0, &returnType)) { if (body != AST_NULL) std::cerr << "body not empty:" << fname << "\n"; POETCode* c = TUPLE4(STRING(fname), ROSE_2_POET_list(0,params,0), STRING(AstInterface::GetTypeName(returnType)), Ast2POET(body.get_ptr())); res = new POETCode_ext(input, c); POETAstInterface::set_Ast2POET(input,res); return res; } } */ AstInterface::AstList c = AstInterface::GetChildrenList(input); switch (input->variantT()) { case V_SgCastExp: case V_SgAssignInitializer: res = Ast2POET(c[0]); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDotExp: { POETCode* v1 = Ast2POET(c[1]); if (dynamic_cast<POETString*>(v1)->get_content() == "operator()") return Ast2POET(c[0]); res = CODE_ACC("Bop",TUPLE3(STRING("."), Ast2POET(c[0]), v1)); return res; } case V_SgLessThanOp: res = CODE_ACC("Bop",TUPLE3(STRING("<"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgSubtractOp: res = CODE_ACC("Bop",TUPLE3(STRING("-"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAddOp: res = CODE_ACC("Bop",TUPLE3(STRING("+"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgMultiplyOp: res = CODE_ACC("Bop",TUPLE3(STRING("*"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgDivideOp: res = CODE_ACC("Bop",TUPLE3(STRING("/"),Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgAssignOp: res = CODE_ACC("Assign",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; case V_SgFunctionCallExp: res = CODE_ACC("FunctionCall",PAIR(Ast2POET(c[0]), Ast2POET(c[1]))); POETAstInterface::set_Ast2POET(input, res); return res; } POETCode * c2 = 0; if (tmp == 0) tmp=isSgTemplateInstantiationFunctionDecl(input); switch (c.size()) { case 0: break; case 1: c2 = Ast2POET(c[0]); break; case 2: c2 = PAIR(Ast2POET(c[0]),Ast2POET(c[1])); break; case 3: c2 = TUPLE3(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2])); break; case 4: c2 = TUPLE4(Ast2POET(c[0]),Ast2POET(c[1]),Ast2POET(c[2]),Ast2POET(c[3])); break; default: //std::cerr << "too many children: " << c.size() << ":" << input->unparseToString() << "\n"; c2 = EMPTY; } if (tmp == input) tmp = 0; res = new POETCode_ext(input, c2); POETAstInterface::set_Ast2POET(input,res); return res; }