00001 00016 //-------------------------------------------------------------------- 00017 //-------------------------------------------------------------------- 00018 00019 #ifndef ICFG_H 00020 #define ICFG_H 00021 00022 //-------------------------------------------------------------------- 00023 // STL headers 00024 #include <list> 00025 #include <map> 00026 00027 // OpenAnalysis headers 00028 #include <OpenAnalysis/Utils/OA_ptr.hpp> 00029 #include <OpenAnalysis/Utils/DGraph/DGraphImplement.hpp> 00030 #include <OpenAnalysis/Utils/DGraph/DGraphInterface.hpp> 00031 #include <OpenAnalysis/CFG/CFG.hpp> 00032 #include "ICFGInterface.hpp" 00033 00034 //================================================================= 00035 // ICFG is the special case of CFG and it can access CFG directly 00036 // without using CFGInterface. 00037 //================================================================= 00038 00039 //-------------------------------------------------------------------- 00040 00041 namespace OA { 00042 namespace ICFG { 00043 00044 // Changes here must be also reflected in edgeTypeToString 00045 // and nodeTypeToString. 00046 00047 //-------------------------------------------------------------------- 00053 class Node; 00054 class Edge; 00055 00056 class NodesIterator; 00057 00058 class EdgesIterator; 00059 class ICFG; 00060 00061 00062 //-------------------------------------------------------- 00063 class Node : public virtual NodeInterface, 00064 public virtual DGraph::NodeImplement 00065 { 00066 public: 00067 Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType); 00068 Node (OA_ptr<ICFG> pICFG, ProcHandle proc, NodeType pType, 00069 OA_ptr<CFG::NodeInterface> cNode); 00070 // from MustMayActive branch: 00071 Node (Node& other) ; 00072 00073 ~Node (); 00074 00075 //======================================================== 00076 // Info specific to ICFG 00077 //======================================================== 00078 00079 NodeType getType() const; 00080 00081 ProcHandle getProc() const; 00082 00084 unsigned int size () const; 00085 00087 OA_ptr<CFG::NodeStatementsIteratorInterface> 00088 getNodeStatementsIterator() const; 00089 00091 OA_ptr<CFG::NodeStatementsRevIteratorInterface> 00092 getNodeStatementsRevIterator() const; 00093 00094 //======================================================== 00095 // Construction Methods 00096 //======================================================== 00097 00098 void addCallEdge(OA_ptr<Edge> e); 00099 void addReturnEdge(OA_ptr<Edge> e); 00100 00101 // from MustMayActive branch: 00102 void removeCallEdge( OA_ptr<Edge> e); 00103 void removeReturnEdge( OA_ptr<Edge> e); 00104 00105 /* 00106 //======================================================== 00107 // Construction 00108 //======================================================== 00109 void addIncomingEdge(OA_ptr<DGraph::EdgeInterface> e); 00110 00111 void addOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e); 00112 00113 void removeIncomingEdge(OA_ptr<DGraph::EdgeInterface> e); 00114 00115 void removeOutgoingEdge(OA_ptr<DGraph::EdgeInterface> e); 00116 */ 00117 00118 // from MustMayActive branch: 00119 // void removeCallEdge( OA_ptr<Edge> e) { mCallEdges->remove(e); } 00120 // void removeReturnEdge( OA_ptr<Edge> e) { mReturnEdges->remove(e); } 00121 //======================================================== 00122 // DGraph::Interface::Node interface 00123 //======================================================== 00124 00126 //unsigned int getId() const; 00127 00128 /* 00130 int num_incoming () const; 00131 00133 int num_outgoing () const; 00134 00136 bool isAnEntry() const; 00137 00139 bool isAnExit() const; 00140 00141 bool operator==(DGraph::NodeInterface& other); 00142 bool operator<(DGraph::NodeInterface& other); 00143 */ 00144 00145 /* 00146 //=============================================================== 00147 // These methods shadow the same named methods in 00148 // the DGraph::Interface class and allow us to return 00149 // the more specific subclass 00150 //======================================================== 00151 OA_ptr<DGraph::EdgesIteratorInterface> getIncomingEdgesIterator() const; 00152 00153 OA_ptr<DGraph::EdgesIteratorInterface> getOutgoingEdgesIterator() const; 00154 00155 OA_ptr<DGraph::NodesIteratorInterface> getSourceNodesIterator() const; 00156 00157 OA_ptr<DGraph::NodesIteratorInterface> getSinkNodesIterator() const; 00158 */ 00159 00160 //===================================================================== 00161 00162 OA_ptr<EdgesIteratorInterface> getICFGIncomingEdgesIterator() const; 00163 00164 OA_ptr<EdgesIteratorInterface> getICFGOutgoingEdgesIterator() const; 00165 00166 OA_ptr<NodesIteratorInterface> getICFGSourceNodesIterator() const; 00167 00168 OA_ptr<NodesIteratorInterface> getICFGSinkNodesIterator() const; 00169 00170 //======================================================== 00171 // Output 00172 //======================================================== 00173 void dump(std::ostream& os) {} // for full override 00174 void dumpbase(std::ostream& os) {} 00175 void dump(std::ostream& os, OA_ptr<IRHandlesIRInterface> ir); 00176 void dumpdot(ICFG&, 00177 std::ostream& os, OA_ptr<IRHandlesIRInterface> ir); 00178 00179 void longdump(ICFG& icfg, std::ostream& os, 00180 OA_ptr<IRHandlesIRInterface> ir); 00181 00182 virtual void output(OA::IRHandlesIRInterface& ir); 00183 00184 00185 //------------------------------------------------------------------ 00186 00187 00188 private: 00189 void Ctor(); 00190 00191 // ========================================================== 00192 // if we are a ENTRY_Node and have CallEdges then we 00193 // are the entry to a CFG and the CallEdges are incoming 00194 // if we are a EXIT_Node and have ReturnEdges then 00195 // we are the exit to a CFG and the return edges are outgoing 00196 // if we are a Call node then the call edges are outgoing 00197 // if we are a return node then the call edges are incoming 00198 // ========================================================== 00199 // 00200 OA_ptr<std::list<OA_ptr<Edge> > > mCallEdges; 00201 OA_ptr<std::list<OA_ptr<Edge> > > mReturnEdges; 00202 00203 00204 OA_ptr<ICFG> mICFG; // enclosing ICFG 00205 ProcHandle mProc; // enclosing procedure 00206 NodeType mType; // node type 00207 OA_ptr<CFG::NodeInterface> mCFGNode; // corresponding CFG node 00208 //DGraph::NodeImplement mDGNode; // corresponding DGraph node 00209 // in DGraph that keeps 00210 // structure 00211 00212 friend class ICFG; 00213 friend class Edge; 00214 }; 00215 00216 // lt_Node: function object that compares by id. Useful for sorting. 00217 class lt_Node : public DGraph::lt_NodeInterface { 00218 public: 00219 // return true if n1 < n2; false otherwise 00220 bool operator()(const OA_ptr<DGraph::NodeInterface> n1, 00221 const OA_ptr<DGraph::NodeInterface> n2) const ; 00222 }; 00223 00224 /* 00226 OA::OA_ptr<DGraph::Interface::lt_Node> getNodeCompare() const 00227 { OA::OA_ptr<DGraph::Interface::lt_Node> retval; retval= new lt_Node(); 00228 return retval; 00229 } 00230 */ 00231 00232 //-------------------------------------------------------- 00233 class Edge : public virtual EdgeInterface, 00234 public virtual DGraph::EdgeImplement 00235 { 00236 public: 00237 00238 00239 Edge (OA_ptr<ICFG> pICFG, 00240 OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType, 00241 CallHandle call); 00242 00243 00244 Edge (OA_ptr<ICFG> pICFG, 00245 OA_ptr<DGraph::NodeInterface> pNode1, OA_ptr<DGraph::NodeInterface> pNode2, EdgeType pType); 00246 00247 00248 ~Edge (); 00249 00250 //======================================================== 00251 // Info specific to ICFG 00252 //======================================================== 00253 00254 EdgeType getType() const; 00255 00256 ProcHandle getSourceProc() const; 00257 ProcHandle getSinkProc() const; 00258 00259 CallHandle getCall() const; 00260 00261 //======================================================== 00262 // DGraph::Interface::Edge interface 00263 //======================================================== 00264 00266 //unsigned int getId() const; 00267 00268 00269 /* 00271 OA_ptr<DGraph::NodeInterface> getSource () const; 00272 // FIXME: tail and head should be done like source and sink 00273 // in DGraph::Interface and here 00274 OA_ptr<DGraph::NodeInterface> getTail () const; 00275 00277 OA_ptr<DGraph::NodeInterface> getSink () const; 00278 OA_ptr<DGraph::NodeInterface> getHead () const; 00279 */ 00280 00281 OA_ptr<NodeInterface> getICFGSource() const; 00282 00283 OA_ptr<NodeInterface> getICFGSink() const; 00284 00285 /* 00286 bool operator==(DGraph::EdgeInterface& other); 00287 bool operator<(DGraph::EdgeInterface& other); 00288 */ 00289 00290 void dump (std::ostream& os); 00291 void dumpdot (std::ostream& os); 00292 void dumpbase (std::ostream& os) {} 00293 virtual void output(OA::IRHandlesIRInterface& ir); 00294 00295 00296 private: 00297 00298 OA_ptr<ICFG> mICFG; 00299 OA_ptr<Node> mNode1, mNode2; 00300 //DGraph::EdgeImplement mDGEdge; 00301 00302 EdgeType mType; 00303 CallHandle mCall; 00304 00305 friend class ICFG; 00306 friend class Node; 00307 00308 }; 00309 00310 // lt_Edge: function object that compares by source and sink node 00311 // ids. Useful for sorting. Not used to put edges in sets or other 00312 // STL containers. 00313 00314 class lt_Edge : public DGraph::lt_EdgeInterface { 00315 public: 00316 bool operator()(const OA_ptr<DGraph::EdgeInterface> e1, 00317 const OA_ptr<DGraph::EdgeInterface> e2) const; 00318 }; 00319 00320 /* 00321 00323 OA::OA_ptr<DGraph::Interface::lt_Edge> getEdgeCompare() const 00324 { OA::OA_ptr<DGraph::Interface::lt_Edge> retval; retval= new lt_Edge(); 00325 return retval; 00326 } 00327 00328 */ 00329 00330 //------------------------------------------------------------------ 00334 class NodesIterator : public DGraph::NodesIteratorImplement, 00335 public virtual NodesIteratorInterface 00336 { 00337 public: 00338 NodesIterator(OA_ptr<DGraph::NodesIteratorInterface> ni); 00339 00340 OA_ptr<NodeInterface> currentICFGNode() const ; 00341 00342 }; 00343 00344 //------------------------------------------------------------------ 00348 class EdgesIterator : public DGraph::EdgesIteratorImplement, 00349 public virtual EdgesIteratorInterface 00350 { 00351 public: 00352 00353 EdgesIterator(OA_ptr<DGraph::EdgesIteratorInterface> ni); 00354 00355 OA_ptr<EdgeInterface> currentICFGEdge() const; 00356 00357 }; 00358 00359 00360 //------------------------------------------------------------------ 00361 class ICFG : public virtual ICFGInterface, 00362 public virtual DGraph::DGraphImplement 00363 { 00364 00365 public: 00366 ICFG (); 00367 virtual ~ICFG (); 00368 00369 /* 00370 int getNumNodes(); 00371 int getNumEdges(); 00372 */ 00373 00374 //------------------------------------- 00375 // ICFG information access 00376 //------------------------------------- 00377 //OA_ptr<Node> getEntry() { return mEntry; } 00378 //OA_ptr<Node> getExit() { return mExit; } 00379 00382 /* 00383 OA_ptr<Edge> getICFGEdge(OA_ptr<DGraph::EdgeImplement> dgEdge) const; 00384 */ 00387 00388 /* 00389 OA_ptr<Node> getICFGNode(OA_ptr<DGraph::NodeImplement> dgNode) const; 00390 */ 00391 00392 //======================================================== 00393 // Construction 00394 //======================================================== 00395 //void addNode(OA_ptr<Node> pNode); 00396 void addEdge(OA_ptr<Edge> pEdge); 00397 00398 //======================================================= 00399 // From MustMayActive 00400 // ===================================================== 00401 // 00402 void removeEdge(OA_ptr<Edge> e); 00403 00404 //void removeNode(OA_ptr<DGraph::NodeInterface> n); 00405 00406 // can't do connect by creating a new edge in a member function 00407 // because edges have to have an OA_ptr to containing ICFG 00408 //void connect(OA_ptr<Node> pNode1, OA_ptr<Node> pNode2, 00409 // EdgeType pType); 00410 00411 //======================================================== 00412 // Output 00413 //======================================================== 00414 void dump (std::ostream& os, OA_ptr<IRHandlesIRInterface> ir); 00415 void dumpdot (std::ostream& os, OA_ptr<IRHandlesIRInterface> ir); 00416 void dumpbase(std::ostream& os) {} 00417 virtual void output(OA::IRHandlesIRInterface& ir); 00418 00419 00420 //======================================================== 00421 // Construction 00422 //======================================================== 00423 /* 00424 void addNode(OA_ptr<DGraph::NodeInterface> n); 00425 00426 void addEdge(OA_ptr<DGraph::EdgeInterface> e); 00427 */ 00428 00429 // ================================================================= 00430 // Using trick of imitating covariance when getting all iterators 00431 // so that get an iterator specific to actual subclass 00432 // This is why have these getBlahIterator methods that shadow those 00433 // in DGraph::Interface and also have the protected ones 00434 // that must be defined here which override implementation in 00435 // DGraph::Interface 00436 //================================================================== 00437 00438 /* 00439 OA_ptr<DGraph::NodesIteratorInterface> 00440 getNodesIterator() const; 00441 00442 OA_ptr<DGraph::NodesIteratorInterface> 00443 getEntryNodesIterator() const; 00444 00445 OA_ptr<DGraph::NodesIteratorInterface> 00446 getExitNodesIterator() const; 00447 00448 OA_ptr<DGraph::EdgesIteratorInterface> 00449 getEdgesIterator() const; 00450 00451 OA_ptr<DGraph::NodesIteratorInterface> 00452 getReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient); 00453 00454 OA_ptr<DGraph::NodesIteratorInterface> 00455 getDFSIterator(OA_ptr<DGraph::NodeInterface> n); 00456 */ 00457 00458 OA_ptr<NodesIteratorInterface> 00459 getICFGNodesIterator() const; 00460 00461 OA_ptr<EdgesIteratorInterface> 00462 getICFGEdgesIterator() const; 00463 00464 OA_ptr<NodesIteratorInterface> 00465 getICFGEntryNodesIterator() const; 00466 00467 OA_ptr<NodesIteratorInterface> 00468 getICFGExitNodesIterator() const; 00469 00470 OA_ptr<NodesIteratorInterface> 00471 getICFGReversePostDFSIterator(DGraph::DGraphEdgeDirection pOrient); 00472 00473 OA_ptr<NodesIteratorInterface> 00474 getICFGDFSIterator(OA_ptr<NodeInterface> n); 00475 00476 private: 00477 OA_ptr<Node> mEntry; 00478 OA_ptr<Node> mExit; 00479 00480 00481 00482 // dgraph that will store underlying graph structure 00483 //DGraph::DGraphImplement mDGraph; 00484 00485 00486 // using lists instead of sets because some of the iterators 00487 // need an ordered list of things and only want to have one 00488 // NodeIterator and EdgesIterator implementation 00489 OA_ptr<std::list<OA_ptr<Node> > > mCallNodes; 00490 OA_ptr<std::list<OA_ptr<Edge> > > mCallEdges; 00491 OA_ptr<std::list<OA_ptr<Node> > > mReturnNodes; 00492 OA_ptr<std::list<OA_ptr<Edge> > > mReturnEdges; 00493 00494 00495 }; 00496 //-------------------------------------------------------------------- 00497 00498 } // end of ICFG namespace 00499 } // end of OA namespace 00500 00501 #endif
1.7.1