9#include <boost/graph/adjacency_list.hpp> 
   10#include <boost/bind/bind.hpp> 
   11#include <boost/tuple/tuple.hpp> 
   12#include <boost/graph/graphviz.hpp> 
   13#include <boost/graph/dominator_tree.hpp> 
   14#include <boost/graph/reverse_graph.hpp> 
   15#include <boost/graph/transpose_graph.hpp> 
   16#include <boost/algorithm/string.hpp> 
   22template <
class CFGNodeT, 
class CFGEdgeT>
 
   23class CFG : 
public boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, 
 
   24        boost::shared_ptr<CFGNodeT>, boost::shared_ptr<CFGEdgeT> >
 
   27    typedef typename boost::graph_traits<CFG<CFGNodeT, CFGEdgeT> > GraphTraits;
 
   30    typedef CFGNodeT CFGNodeType;
 
   31    typedef CFGEdgeT CFGEdgeType;
 
   33    typedef boost::shared_ptr<CFGNodeType> CFGNodePtr;
 
   34    typedef boost::shared_ptr<CFGEdgeType> CFGEdgePtr;
 
   36    typedef typename GraphTraits::vertex_descriptor 
Vertex;
 
   37    typedef typename GraphTraits::edge_descriptor 
Edge;
 
   39    typedef std::map<Vertex, Vertex> VertexVertexMap;
 
   66        entry_(GraphTraits::null_vertex()),
 
   67        exit_(GraphTraits::null_vertex())
 
 
   74        entry_(GraphTraits::null_vertex()),
 
   75        exit_(GraphTraits::null_vertex())
 
 
  124    void buildCFG(
const CFGNodeType& node,
 
  125            std::map<CFGNodeType, Vertex>& nodesAdded,
 
  126            std::set<CFGNodeType>& nodesProcessed);
 
  135        : cfg1(g1), cfg2(g2) {}
 
  138        { cfg2[v2] = cfg1[v1]; }
 
 
  148        : cfg1(g1), cfg2(g2) {}
 
  150        void operator()(
const Edge& e1, 
Edge& e2)
 const 
  151        { cfg2[e2] = cfg1[e1]; }
 
 
 
  162template <
class CFGNodeT, 
class CFGEdgeT>
 
  165    ROSE_ASSERT(funcDef);
 
  169    nodesToVertices_.clear();
 
  170    std::set<CFGNodeType> nodesProcessed;
 
  174    entry_ = GraphTraits::null_vertex();
 
  175    exit_ = GraphTraits::null_vertex();
 
  177    buildCFG(CFGNodeType(funcDef->
cfgForBeginning()), nodesToVertices_, nodesProcessed);
 
  182    ROSE_ASSERT(isSgFunctionDefinition((*
this)[entry_]->getNode()));
 
  183    ROSE_ASSERT(isSgFunctionDefinition((*
this)[exit_]->getNode()));
 
 
  186template <
class CFGNodeT, 
class CFGEdgeT>
 
  189    BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
 
  191        CFGNodePtr node = (*this)[v];
 
  192        if (isSgFunctionDefinition(node->getNode()))
 
  194            if (node->getIndex() == 0)
 
  196            else if (node->getIndex() == 3)
 
  203    if (exit_ == GraphTraits::null_vertex())
 
  205        std::cerr << 
"This function may contain an infinite loop " 
  206                "inside so that its CFG cannot be built" << std::endl;
 
  207        exit_ = add_vertex(*
this);
 
  208        (*this)[exit_] = CFGNodePtr(
new CFGNodeType(funcDef_->cfgForEnd()));
 
  211    ROSE_ASSERT(entry_ != GraphTraits::null_vertex());
 
  212    ROSE_ASSERT(exit_ != GraphTraits::null_vertex());
 
 
  215template <
class CFGNodeT, 
class CFGEdgeT>
 
  217        const CFGNodeType& node,
 
  218        std::map<CFGNodeType, Vertex>& nodesAdded,
 
  219        std::set<CFGNodeType>& nodesProcessed)
 
  221    ROSE_ASSERT(node.getNode());
 
  223    if (nodesProcessed.count(node) > 0)
 
  225    nodesProcessed.insert(node);
 
  227    typename std::map<CFGNodeType, Vertex>::iterator iter;
 
  232    const CFGNodeType& src = node;
 
  233    ROSE_ASSERT(src.getNode());
 
  235    boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(src, 
Vertex()));
 
  239        from = add_vertex(*
this);
 
  240        (*this)[from] = CFGNodePtr(
new CFGNodeType(src));
 
  248    std::vector<CFGEdgeType> outEdges = node.outEdges();
 
  250    BOOST_FOREACH(
const CFGEdgeType& cfgEdge, outEdges)
 
  253        CFGNodeType tar = cfgEdge.target();
 
  254        ROSE_ASSERT(tar.getNode());
 
  256        boost::tie(iter, inserted) = nodesAdded.insert(std::make_pair(tar, 
Vertex()));
 
  260            to = add_vertex(*
this);
 
  261            (*this)[to] = CFGNodePtr(
new CFGNodeType(tar));
 
  270        Edge edge = add_edge(from, to, *
this).first;
 
  271        (*this)[edge] = CFGEdgePtr(
new CFGEdgeType(cfgEdge));
 
  274        buildCFG(tar, nodesAdded, nodesProcessed);
 
 
  278template <
class CFGNodeT, 
class CFGEdgeT>
 
  281    if (!dominatorTree_.empty())
 
  282        return dominatorTree_;
 
  284    boost::associative_property_map<VertexVertexMap> domTreePredMap(dominatorTree_);
 
  287    boost::lengauer_tarjan_dominator_tree(*
this, entry_, domTreePredMap);
 
  288    return dominatorTree_;
 
 
  291template <
class CFGNodeT, 
class CFGEdgeT>
 
  294    if (!postdominatorTree_.empty())
 
  295        return postdominatorTree_;
 
  297    boost::associative_property_map<VertexVertexMap> postdomTreePredMap(postdominatorTree_);
 
  300    boost::lengauer_tarjan_dominator_tree(boost::make_reverse_graph(*
this), exit_, postdomTreePredMap);
 
  301    return postdominatorTree_;
 
 
  304template <
class CFGNodeT, 
class CFGEdgeT>
 
  309    boost::transpose_graph(*
this, reverseCFG, 
 
  314    reverseCFG.
entry_ = this->exit_;
 
  315    reverseCFG.
exit_ = this->entry_;
 
 
  319template <
class CFGNodeT, 
class CFGEdgeT>
 
  320std::vector<typename CFG<CFGNodeT, CFGEdgeT>::CFGNodePtr>
 
  323    std::vector<CFGNodePtr> allNodes;
 
  324    BOOST_FOREACH (
Vertex v, boost::vertices(*
this))
 
  325        allNodes.push_back((*
this)[v]);
 
 
  329template <
class CFGNodeT, 
class CFGEdgeT>
 
  330std::vector<typename CFG<CFGNodeT, CFGEdgeT>::CFGEdgePtr>
 
  333    std::vector<CFGEdgePtr> allEdges;
 
  334    BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
 
  335        allEdges.push_back((*
this)[e]);
 
 
  339template <
class CFGNodeT, 
class CFGEdgeT>
 
  342    typename std::map<CFGNodeType, Vertex>::const_iterator vertexIter = nodesToVertices_.find(node);
 
  343    if (vertexIter == nodesToVertices_.end())
 
  344        return GraphTraits::null_vertex();
 
  347        ROSE_ASSERT(*(*
this)[vertexIter->second] == node);
 
  348        return vertexIter->second;
 
 
  352template <
class CFGNodeT, 
class CFGEdgeT>
 
  355    std::vector<Edge> backEdges;
 
  360    BOOST_FOREACH (
const Edge& e, boost::edges(*
this))
 
  362        Vertex src = boost::source(e, *
this);
 
  363        Vertex tar = boost::target(e, *
this);
 
  366        typename VertexVertexMap::const_iterator iter = dominatorTree_.find(src);
 
  367        while (iter != dominatorTree_.end())
 
  369            if (iter->second == tar)
 
  371                backEdges.push_back(e);
 
  374            iter = dominatorTree_.find(iter->second);
 
 
  381template <
class CFGNodeT, 
class CFGEdgeT>
 
  384    std::vector<Edge> backEdges = getAllBackEdges();
 
  385    std::vector<Vertex> headers;
 
  386    BOOST_FOREACH (
Edge e, backEdges)
 
  387        headers.push_back(boost::target(e, *
this));
 
 
This class represents the concept of a scope in C++ (e.g. global scope, fuction scope,...
 
VirtualCFG::CFGNode cfgForBeginning()
Returns the CFG node for just before this AST node.
 
A class holding a Control Flow Graph.
 
void buildCFG(const CFGNodeType &node, std::map< CFGNodeType, Vertex > &nodesAdded, std::set< CFGNodeType > &nodesProcessed)
A internal funtion which builds the actual CFG (boost::graph).
 
SgFunctionDefinition * getFunctionDefinition() const
Get the function definition of this CFG.
 
VertexVertexMap postdominatorTree_
The postdominator tree of this CFG.
 
std::vector< CFGEdgePtr > getAllEdges() const
Get all CFG edges in this graph.
 
VertexVertexMap dominatorTree_
The dominator tree of this CFG.
 
void setEntryAndExit()
Find the entry and exit of this CFG and set the corresponding members.
 
std::vector< Vertex > getAllLoopHeaders()
Get all loop headers in this CFG. A natural loop only has one header.
 
std::map< CFGNodeType, Vertex > nodesToVertices_
A map from a CFG node to the corresponding vertex.
 
void build(SgFunctionDefinition *funcDef)
Build the actual CFG for the given function.
 
Vertex exit_
The exit node.
 
std::vector< CFGNodePtr > getAllNodes() const
Get all CFG nodes in this graph.
 
Vertex getVertexForNode(const CFGNodeType &node) const
Given a CFG node, returns the corresponding vertex in the graph.
 
std::vector< Edge > getAllBackEdges()
Get all back edges in the CFG. A back edge is one whose target dominates its source.
 
const Vertex & getExit() const
Get the exit node of the CFG.
 
const Vertex & getEntry() const
Get the entry node of the CFG.
 
CFG()
The default constructor.
 
const VertexVertexMap & getDominatorTree()
Build the dominator tree of this CFG.
 
Vertex entry_
The entry node.
 
CFG(SgFunctionDefinition *funcDef)
The constructor building the CFG.
 
CFG< CFGNodeT, CFGEdgeT > makeReverseCopy() const
Build a reverse CFG.
 
SgFunctionDefinition * funcDef_
The function definition of this CFG.
 
const VertexVertexMap & getPostdominatorTree()
Build the postdominator tree of this CFG.
 
This class is used to copy edges when calling copy_graph().
 
This class is used to copy vertices when calling copy_graph().