filteredCFGImpl.h

Go to the documentation of this file.
00001 //#include <rose.h>
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     // Class Impl
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     // Class Impl
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     // DOT OUT IMPL
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 }

Generated on Tue Jan 31 05:31:37 2012 for ROSE by  doxygen 1.4.7