//! start from a CFG node 'n', collect all other CFG nodes which can be reached from 'n' void getReachableNodes(CFGNode n, set<CFGNode>& s) { if (s.find(n) != s.end()) return; // n is already in s s.insert(n); vector<CFGEdge> oe = n.outEdges(); for (vector<CFGEdge>::const_iterator i = oe.begin(); i != oe.end(); ++i) { getReachableNodes(i->target(), s); } }
// advances this CFGIterator in the given direction. Forwards if fwDir=true and backwards if fwDir=false. // if pushAllChildren=true, all of the current node's unvisited children (predecessors or successors, // depending on fwDir) are pushed onto remainingNodes // It is assumed that for a given CFGIterator pushAllChildren either always = true or always = false. void CFGIterator::advance(bool fwDir, bool pushAllChildren) { assert(initialized); /*scope s(txt()<<"CFGIterator::advance(fwDir="<<fwDir<<", pushAllChildren="<<pushAllChildren<<") #remainingNodes="<<remainingNodes.size()); dbg<<" visited=\n"; for(set<CFGNode>::iterator it=visited.begin(); it!=visited.end(); it++) dbg << " "<<CFGNode2Str(*it)<<"\n";*/ if(remainingNodes.size()>0) { // pop the next CFG node from the front of the list CFGNode cur = remainingNodes.front(); remainingNodes.pop_front(); //dbg << "cur="<<CFGNode2Str(cur)<<endl; if(pushAllChildren) { // find its followers (either successors or predecessors, depending on value of fwDir), push back // those that have not yet been visited vector<CFGEdge> nextE; if(fwDir) { /* // Do not proceed forward if we've reached the end of a function if(!(isSgFunctionDefinition(cur.getNode()) && cur.getIndex()==3))*/ nextE = cur.outEdges(); } else { /* // Do not proceed backward if we've reached the end of a function if(!(isSgFunctionParameterList(cur.getNode()) && cur.getIndex()==0)) */ nextE = cur.inEdges(); } //dbg << " #nextE="<<nextE.size()<<endl; for(vector<CFGEdge>::iterator it=nextE.begin(); it!=nextE.end(); it++) { CFGNode nextN = (fwDir ? it->target() : nextN = it->source()); /*dbg << " nextN="<<CFGNode2Str(nextN)<<endl; dbg << " CFGIterator::advance "<<(fwDir?"descendant":"predecessor")<<": "<< "visited="<<(visited.find(nextN) != visited.end())<< " remaining="<<isRemaining(nextN)<<"\n";*/ // if we haven't yet visited this node and don't yet have it on the remainingNodes list if(visited.find(nextN) == visited.end() && !isRemaining(nextN)) { //printf(" pushing back node <%s: 0x%x: %s> visited=%d\n", nextN.getNode()->class_name().c_str(), nextN.getNode(), nextN.getNode()->unparseToString().c_str(), visited.find(nextN)!=visited.end()); remainingNodes.push_back(nextN); } } // if we still have any nodes left remaining if(remainingNodes.size()>0) { // take the next node from the front of the list and mark it as visited visited.insert(remainingNodes.front()); //cout << " remainingNodes.front()=["<<remainingNodes.front().getNode()->unparseToString()<<" | "<<remainingNodes.front().getNode()->class_name()<<"]"<<endl; } // Since pushAllChildren always = true or = false, we only need to worry about managing visited in the true case } } }
std::map<SgNode*,std::string> PathCollector::getAssociationsForPath(std::vector<SgGraphNode*> path) { std::map<SgNode*,std::string> conditionValueForPath; for (int i = 0; i < path.size(); i++) { //std::vector<SgGraphNode*> successors; //pathCollector->getGraph()->getSuccessors(path[i],successors); CFGNode node = cfg->toCFGNode(path[i]); std::vector<CFGEdge> edges = node.outEdges(); if (edges.size() > 1) { //std::cout << "associated node: " << path[i]->get_SgNode()->class_name() << std::endl; CFGNode eck_result = cfg->toCFGNode(path[i+1]); CFGEdge conditionEdge; int k = 0; int found = -1; while (k < edges.size()) { if (edges[k].target() == eck_result) { conditionEdge = edges[k]; found = k; break; } k++; } EdgeConditionKind edgeKind = conditionEdge.condition(); if (edgeKind == eckTrue) { conditionValueForPath[path[i]->get_SgNode()] = "true"; } else if (edgeKind == eckFalse) { conditionValueForPath[path[i]->get_SgNode()] = "false"; } else { std::cout << "edge kind not handled! exiting..." << std::endl; ROSE_ASSERT(false); } // std::cout << "edge value: " << conditionValueForPath[path[i]->get_SgNode()] << std::endl; } } return conditionValueForPath; }
void CFG::buildCFG(CFGNode n) { ROSE_ASSERT(n.getNode()); if (explored_.count(n) > 0) return; explored_.insert(n); SgGraphNode* from = NULL; if (all_nodes_.count(n) > 0) { from = all_nodes_[n]; } else { from = new SgGraphNode; from->set_SgNode(n.getNode()); from->addNewAttribute("info", new CFGNodeAttribute(n.getIndex(), graph_)); all_nodes_[n] = from; graph_->addNode(from); } std::vector<VirtualCFG::CFGEdge> outEdges = n.outEdges(); foreach (const VirtualCFG::CFGEdge& edge, outEdges) { CFGNode tar = edge.target(); SgGraphNode* to = NULL; if (all_nodes_.count(tar) > 0) to = all_nodes_[tar]; else { to = new SgGraphNode; to->set_SgNode(tar.getNode()); to->addNewAttribute("info", new CFGNodeAttribute(tar.getIndex(), graph_)); all_nodes_[tar] = to; graph_->addNode(to); } graph_->addDirectedEdge(new SgDirectedGraphEdge(from, to)); }