// 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 } } }
// advances this iterator 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 void iterator::advance(bool fwDir, bool pushAllChildren) { ROSE_ASSERT(initialized); /*printf(" iterator::advance(%d) remainingNodes.size()=%d\n", fwDir, remainingNodes.size()); cout<<" visited=\n"; for(set<DataflowNode>::iterator it=visited.begin(); it!=visited.end(); it++) cout << " <"<<it->getNode()->class_name()<<" | "<<it->getNode()<<" | "<<it->getNode()->unparseToString()<<">\n";*/ if(remainingNodes.size()>0) { // pop the next CFG node from the front of the list DataflowNode cur = remainingNodes.front(); remainingNodes.pop_front(); if(pushAllChildren) { // find its followers (either successors or predecessors, depending on value of fwDir), push back // those that have not yet been visited vector<DataflowEdge> nextE; if(fwDir) nextE = cur.outEdges(); else nextE = cur.inEdges(); for(vector<DataflowEdge>::iterator it=nextE.begin(); it!=nextE.end(); it++) { DataflowNode nextN((*it).target()/* need to put something here because DataflowNodes don't have a default constructor*/); if(fwDir) nextN = (*it).target(); else nextN = (*it).source(); /*cout << " iterator::advance "<<(fwDir?"descendant":"predecessor")<<": "<< "<"<<nextN.getNode()->class_name()<<" | "<<nextN.getNode()<<" | "<<nextN.getNode()->unparseToString()<<">, "<< "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[remainingNodes.front()] = true; visited.insert(remainingNodes.front()); } } }
void dataflowCFGIterator::add(const CFGNode next) { // If this dataflow CFGIterator is not initialized, initialize it now since it will now have real state if(!initialized) initialized = true; // never add the terminator node if(next==terminator) return; // if next is not currently in remainingNodes, add it if(!isRemaining(next)) { set<CFGNode>::iterator nextLoc = visited.find(next); if(nextLoc != visited.end()) visited.erase(visited.find(next)); remainingNodes.push_back(next); } }
void dataflow::add(const DataflowNode &next) { // If this dataflow iterator is not initialized, initialize it now since it will now have real state if(!initialized) initialized = true; // never add the terminator node if(next==terminator) return; // if next is not currently in remainingNodes, add it //cout << "dataflow::add() isRemaining()="<<isRemaining(next)<<" next = <"<<next.getNode()->class_name()<<" | "<<next.getNode()->unparseToString()<<">\n"; if(!isRemaining(next)) { set<DataflowNode>::iterator nextLoc = visited.find(next); //printf(" visited=%d\n", nextLoc != visited.end()); if(nextLoc != visited.end()) visited.erase(visited.find(next)); remainingNodes.push_back(next); } //printf("dataflow::add() remainingNodes.size()=%d\n", remainingNodes.size()); }