00001
00002 #include "filteredCFG.h"
00003 #include <sstream>
00004 #include <iomanip>
00005 #include <stdint.h>
00006 #include <set>
00007
00008 #define SgNULL_FILE Sg_File_Info::generateDefaultFileInfoForTransformationNode()
00009
00010 namespace VirtualCFG
00011 {
00012
00013 template < typename FindSuccessors, typename FindEnd, typename DontAddChildren,
00014 typename Join, typename FilteredEdge > struct MakeClosure
00015 {
00016 std::set < CFGNode > visitedNodes;
00017 std::vector < CFGPath > visitedPaths;
00018 const FindSuccessors & findSuccessors;
00019 const FindEnd & findEnd;
00020 const DontAddChildren & dontAddChildren;
00021 const Join & join;
00022
00023 MakeClosure(const FindSuccessors & findSuccessors, const FindEnd & findEnd,
00024 const DontAddChildren & dontAddChildren,
00025 const Join & join) :
00026 findSuccessors(findSuccessors), findEnd(findEnd),
00027 dontAddChildren(dontAddChildren), join(join)
00028 {
00029 }
00030
00031
00032 void go(const CFGPath & p)
00033 {
00034 CFGNode end = findEnd(p);
00035
00036 if (visitedNodes.find(end) != visitedNodes.end())
00037 return;
00038 visitedNodes.insert(end);
00039 visitedPaths.push_back(p);
00040 if (dontAddChildren(end))
00041 return;
00042 std::vector < CFGEdge > edges = findSuccessors(end);
00043 for (unsigned int i = 0; i < edges.size(); ++i)
00044 {
00045 go(join(p, edges[i]));
00046 }
00047 }
00048
00049 std::vector < FilteredEdge > filter() const
00050 {
00051 std::vector < FilteredEdge > edges;
00052 for (std::vector < CFGPath >::const_iterator i = visitedPaths.begin();
00053 i != visitedPaths.end(); ++i)
00054 {
00055 const CFGPath & p = *i;
00056 if (dontAddChildren(findEnd(p)))
00057 edges.push_back(FilteredEdge(*i));
00058 }
00059 return edges;
00060 }
00061 };
00062
00063 template < typename FilteredEdge, typename FindSuccessors, typename FindEnd,
00064 typename AddChildren,
00065 typename Join > std::vector < FilteredEdge > makeClosure(const std::vector < CFGPath > &p,
00066 const FindSuccessors &
00067 findSuccessors,
00068 const FindEnd & findEnd,
00069 const AddChildren & addChildren,
00070 const Join & join)
00071 {
00072 MakeClosure < FindSuccessors, FindEnd, AddChildren, Join,
00073 FilteredEdge > mc(findSuccessors, findEnd, addChildren, join);
00074 for (unsigned int i = 0; i < p.size(); ++i)
00075 mc.go(p[i]);
00076 return mc.filter();
00077 }
00078
00079 template < typename FilteredEdge, typename Filter >
00080 std::vector < FilteredEdge > makeClosure(const std::vector < CFGEdge > &orig,
00081 std::vector < CFGEdge > (CFGNode::*closure) ()const,
00082 CFGNode(CFGPath::*otherSide) ()const,
00083 CFGPath(*merge) (const CFGPath &, const CFGPath &),
00084 const Filter & filter)
00085 {
00086 std::vector < CFGPath > paths(orig.begin(), orig.end());
00087 return makeClosure < FilteredEdge > (paths, std::mem_fun_ref(closure),
00088 std::mem_fun_ref(otherSide), filter, merge);
00089 }
00090
00091
00092
00093 template < typename FilterFunction > std::vector < FilteredCFGEdge < FilterFunction >
00094 >FilteredCFGNode < FilterFunction >::outEdges()const
00095 {
00096 return makeClosure < FilteredCFGEdge < FilterFunction > >(n.outEdges(),
00097 &CFGNode::outEdges,
00098 &CFGPath::target, &mergePaths,
00099 filter);
00100 }
00101
00102 template < typename FilterFunction > std::vector < FilteredCFGEdge < FilterFunction >
00103 >FilteredCFGNode < FilterFunction >::inEdges() const
00104 {
00105 return makeClosure < FilteredCFGEdge < FilterFunction > >(n.inEdges(),
00106 &CFGNode::inEdges,
00107 &CFGPath::source,
00108 &mergePathsReversed,
00109 filter);
00110 }
00111
00112
00113 template < typename NodeT, typename EdgeT ,bool Debug> class CfgToDotImpl
00114 {
00115 std::multimap < SgNode *, NodeT > exploredNodes;
00116 std::set < SgNode * >nodesPrinted;
00117 std::ostream & o;
00118
00119 public:
00120 CfgToDotImpl(std::ostream & o) :
00121 exploredNodes(), nodesPrinted(), o(o)
00122 {
00123 }
00124 void processNodes(NodeT n);
00125 };
00126
00127 template < typename NodeT > inline void printNode(std::ostream & o, const NodeT & n)
00128 {
00129 std::string id = n.id();
00130 std::string nodeColor = "black";
00131
00132 if (isSgStatement(n.getNode()))
00133 nodeColor = "blue";
00134 else if (isSgExpression(n.getNode()))
00135 nodeColor = "green";
00136 else if (isSgInitializedName(n.getNode()))
00137 nodeColor = "red";
00138
00139 o << id << " [label=\"" << escapeString(n.
00140 toString()) << "\", color=\"" << nodeColor <<
00141 "\", style=\"" << (n.isInteresting()? "solid" : "dotted") << "\"];\n";
00142 }
00143
00144 template < typename EdgeT >
00145 inline void printEdge(std::ostream & o, const EdgeT & e, bool isInEdge)
00146 {
00147 o << e.source().id() << " -> " << e.target().id() << " [label=\"" << escapeString(e.
00148 toString
00149 ()) <<
00150 "\", style=\"" << (isInEdge ? "dotted" : "solid") << "\"];\n";
00151 }
00152
00153 template < typename NodeT, typename EdgeT > void printNodePlusEdges(std::ostream & o,
00154 NodeT n);
00155
00156 template < typename NodeT, typename EdgeT ,bool Debug>
00157 void CfgToDotImpl < NodeT, EdgeT, Debug >::processNodes(NodeT n)
00158 {
00159 ROSE_ASSERT(n.getNode());
00160 std::pair < typename std::multimap < SgNode *, NodeT >::const_iterator,
00161 typename std::multimap < SgNode *, NodeT >::const_iterator > ip =
00162 exploredNodes.equal_range(n.getNode());
00163 for (typename std::multimap < SgNode *, NodeT >::const_iterator i = ip.first;
00164 i != ip.second; ++i)
00165 {
00166 if (i->second == n)
00167 return;
00168 }
00169 exploredNodes.insert(std::make_pair(n.getNode(), n));
00170 printNodePlusEdges<NodeT, EdgeT>(o, n);
00171 std::vector < EdgeT > outEdges = n.outEdges();
00172 for (unsigned int i = 0; i < outEdges.size(); ++i)
00173 {
00174 ROSE_ASSERT(outEdges[i].source() == n);
00175 processNodes(outEdges[i].target());
00176 }
00177 std::vector < EdgeT > inEdges = n.inEdges();
00178 for (unsigned int i = 0; i < inEdges.size(); ++i)
00179 {
00180 ROSE_ASSERT(inEdges[i].target() == n);
00181 processNodes(inEdges[i].source());
00182 }
00183 }
00184
00185 template < typename NodeT, typename EdgeT > void printNodePlusEdges(std::ostream & o,
00186 NodeT n)
00187 {
00188 printNode(o, n);
00189 std::vector < EdgeT > outEdges = n.outEdges();
00190 for (unsigned int i = 0; i < outEdges.size(); ++i)
00191 {
00192 printEdge(o, outEdges[i], false);
00193 }
00194 #ifdef DEBUG
00195 std::vector < EdgeT > inEdges = n.inEdges();
00196 for (unsigned int i = 0; i < inEdges.size(); ++i)
00197 {
00198 printEdge(o, inEdges[i], true);
00199 }
00200 #endif
00201 }
00202 #if 0
00203 template < typename NodeT, typename EdgeT >
00204 void CfgToDotImpl < NodeT, EdgeT >::processNodes(SgNode *)
00205 {
00206 for (typename std::multimap < SgNode *, NodeT >::const_iterator it =
00207 exploredNodes.begin(); it != exploredNodes.end(); ++it)
00208 {
00209 printNodePlusEdges < NodeT, EdgeT > (o, it->second);
00210 }
00211 }
00212 #endif
00213
00214
00215 template < typename FilterFunction > std::ostream & cfgToDot(std::ostream & o,
00216 std::string graphName,
00217 FilteredCFGNode <
00218 FilterFunction > start)
00219 {
00220 o << "digraph " << graphName << " {\n";
00221 CfgToDotImpl < FilteredCFGNode < FilterFunction >,
00222 FilteredCFGEdge < FilterFunction > ,false>impl(o);
00223 impl.processNodes(start);
00224 o << "}\n";
00225 return o;
00226 }
00227 }