2#include "filteredCFG.h"
8#define SgNULL_FILE Sg_File_Info::generateDefaultFileInfoForTransformationNode()
10#define DEBUG_CFG_HEADER 0
26 template <
typename FindSuccessors,
28 typename DontAddChildren,
30 typename FilteredEdge >
33 std::set < CFGNode > visitedNodes;
34 std::vector < CFGPath > visitedPaths;
35 const FindSuccessors & findSuccessors;
36 const FindEnd & findEnd;
37 const DontAddChildren & dontAddChildren;
41 const FindEnd & findEnd,
42 const DontAddChildren & dontAddChildren,
44 findSuccessors(findSuccessors), findEnd(findEnd),
45 dontAddChildren(dontAddChildren), join(join)
55 if (visitedNodes.find(end) != visitedNodes.end())
57 visitedNodes.insert(end);
58 visitedPaths.push_back(p);
60 if (dontAddChildren(end))
64 std::vector < CFGEdge > edges = findSuccessors(end);
65 for (
unsigned int i = 0; i < edges.size(); ++i)
67 go(join(p, edges[i]));
72 std::vector < FilteredEdge >
filter()
const
74 std::vector < FilteredEdge > edges;
76 for (std::vector < CFGPath >::const_iterator i = visitedPaths.begin(); i != visitedPaths.end(); ++i)
79 if (dontAddChildren(findEnd(p)))
80 edges.push_back(FilteredEdge(*i));
86 template <
typename FilteredEdge,
87 typename FindSuccessors,
91 std::vector < FilteredEdge > makeClosure(
const std::vector < CFGPath > &p,
92 const FindSuccessors & findSuccessors,
93 const FindEnd & findEnd,
94 const AddChildren & addChildren,
97 MakeClosure < FindSuccessors, FindEnd, AddChildren, Join, FilteredEdge >
98 mc(findSuccessors, findEnd, addChildren, join);
99 for (
unsigned int i = 0; i < p.size(); ++i)
105 template <
typename FilteredEdge,
typename Filter >
106 std::vector < FilteredEdge > makeClosure(
const std::vector < CFGEdge > &orig,
107 std::vector < CFGEdge > (CFGNode::*closure) ()const,
108 CFGNode(CFGPath::*otherSide) ()const,
109 CFGPath(*
merge) (const CFGPath &, const CFGPath &),
110 const Filter & filter)
112 std::vector < CFGPath > paths(orig.begin(), orig.end());
113 return makeClosure < FilteredEdge > (paths,
114 std::mem_fn(closure),
115 std::mem_fn(otherSide),
123 template <
typename FilterFunction >
124 std::vector < FilteredCFGEdge < FilterFunction > > FilteredCFGNode < FilterFunction >::outEdges()
const
126 return makeClosure < FilteredCFGEdge < FilterFunction > >(n.outEdges(),
133 template <
typename FilterFunction >
134 std::vector < FilteredCFGEdge < FilterFunction > > FilteredCFGNode < FilterFunction >::inEdges()
const
136 return makeClosure < FilteredCFGEdge < FilterFunction > >(n.inEdges(),
144 template <
typename NodeT,
typename EdgeT ,
bool Debug>
147 std::multimap < SgNode *, NodeT > exploredNodes;
148 std::set < SgNode * >nodesPrinted;
153 exploredNodes(), nodesPrinted(), o(o)
156 void processNodes(NodeT n);
160template <
typename NodeT >
162void printNode(std::ostream & o,
const NodeT & n)
164 std::string
id = n.id();
165 std::string nodeColor =
"black";
167 if (isSgStatement(n.getNode()))
169 else if (isSgExpression(n.getNode()))
171 else if (isSgInitializedName(n.getNode()))
174 o <<
id <<
" [label=\"" << escapeString(n.toString()) <<
"\", color=\"" << nodeColor <<
175 "\", style=\"" << (n.isInteresting()?
"solid" :
"dotted") <<
"\"];\n";
179template <
typename EdgeT >
180inline void printEdge(std::ostream & o,
const EdgeT & e,
bool isInEdge)
183 std::cout <<
"In printEdge(): e.toString() = " << e.toString() << std::endl;
185 o << e.source().id() <<
" -> " << e.target().id() <<
" [label=\"" <<
186 escapeString(e.toString()) <<
"\", style=\"" << (isInEdge ?
"dotted" :
"solid") <<
"\"];\n";
190template <
typename NodeT,
typename EdgeT >
191void printNodePlusEdges(std::ostream & o,NodeT n);
194template <
typename NodeT,
typename EdgeT ,
bool Debug>
195void CfgToDotImpl < NodeT, EdgeT, Debug >::processNodes(NodeT n)
197 ROSE_ASSERT(n.getNode());
198 std::pair < typename std::multimap < SgNode *, NodeT >::const_iterator,
typename std::multimap < SgNode *, NodeT >::const_iterator > ip = exploredNodes.equal_range(n.getNode());
200 for (
typename std::multimap < SgNode *, NodeT >::const_iterator i = ip.first; i != ip.second; ++i)
208 exploredNodes.insert(std::make_pair(n.getNode(), n));
212 printf (
"In CfgToDotImpl < NodeT, EdgeT, Debug >::processNodes(): n.getNode() = %p = %s \n",n.getNode(),n.getNode()->class_name().c_str());
215 printNodePlusEdges<NodeT, EdgeT>(o, n);
217 std::vector < EdgeT > outEdges = n.outEdges();
218 for (
unsigned int i = 0; i < outEdges.size(); ++i)
220 ROSE_ASSERT(outEdges[i].source() == n);
221 processNodes(outEdges[i].target());
224 std::vector < EdgeT > inEdges = n.inEdges();
225 for (
unsigned int i = 0; i < inEdges.size(); ++i)
227 ROSE_ASSERT(inEdges[i].target() == n);
228 processNodes(inEdges[i].source());
233template <
typename NodeT,
typename EdgeT >
234void printNodePlusEdges(std::ostream & o, NodeT n)
237 printf (
"In printNodePlusEdges(): n.getNode() = %p = %s \n",n.getNode(),n.getNode()->class_name().c_str());
242 std::vector < EdgeT > outEdges = n.outEdges();
243 for (
unsigned int i = 0; i < outEdges.size(); ++i)
246 printf (
"In printNodePlusEdges(): output edges: i = %u \n",i);
248 printEdge(o, outEdges[i],
false);
255 printf (
"In printNodePlusEdges(): output the inEdges for debugging \n");
257 std::vector < EdgeT > inEdges = n.inEdges();
258 for (
unsigned int i = 0; i < inEdges.size(); ++i)
261 printf (
"In printNodePlusEdges(): input edges: i = %u \n",i);
263 printEdge(o, inEdges[i],
true);
268 printf (
"Leaving printNodePlusEdges(): n.getNode() = %p = %s \n",n.getNode(),n.getNode()->class_name().c_str());
273template <
typename NodeT,
typename EdgeT >
274void CfgToDotImpl < NodeT, EdgeT >::processNodes(
SgNode *)
276 for (
typename std::multimap < SgNode *, NodeT >::const_iterator it =
277 exploredNodes.begin(); it != exploredNodes.end(); ++it)
279 printNodePlusEdges < NodeT, EdgeT > (o, it->second);
285template <
typename FilterFunction >
286std::ostream & cfgToDot(std::ostream & o,
287 std::string graphName,
288 FilteredCFGNode < FilterFunction > start)
290 o <<
"digraph " << graphName <<
" {\n";
291 CfgToDotImpl < FilteredCFGNode < FilterFunction >,
292 FilteredCFGEdge < FilterFunction > ,
294 impl.processNodes(start);
This class represents the base class for all IR nodes within Sage III.
A node in the control flow graph.
std::vector< CFGEdge > inEdges() const
Incoming control flow edges to this node.
std::vector< CFGEdge > outEdges() const
Outgoing control flow edges from this node.
ROSE_DLL_API void merge(SgProject *project)
Performs sharing of AST nodes followed by linking accross translation units.
std::vector< FilteredEdge > filter() const
Process visited CFGPaths: convert them into edges.
void go(const CFGPath &p)
Process one CFGPath at a time: make sure the end edge is an interesting one (should not be filtered o...