Static Value-Flow Analysis
ICFG.cpp
Go to the documentation of this file.
1 //===- ICFG.cpp -- Sparse value-flow graph-----------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2018> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * ICFG.cpp
25  *
26  * Created on: Sep 11, 2018
27  * Author: Yulei Sui
28  */
29 
30 #include "Graphs/ICFG.h"
31 #include "Graphs/PTACallGraph.h"
32 #include "SVFIR/SVFIR.h"
33 #include "SVFIR/SVFModule.h"
34 #include <Util/Options.h>
35 
36 using namespace SVF;
37 using namespace SVFUtil;
38 
39 
41 {
42  fun = f;
43  // if function is implemented
44  if (f->begin() != f->end())
45  {
46  bb = f->getEntryBlock();
47  }
48 }
49 
51  : InterICFGNode(id, FunExitBlock), formalRet(nullptr)
52 {
53  fun = f;
54  // if function is implemented
55  if (f->begin() != f->end())
56  {
57  bb = f->getExitBB();
58  }
59 }
60 
62 {
63  std::string str;
64  std::stringstream rawstr(str);
65  rawstr << "ICFGNode" << getId();
66  return rawstr.str();
67 }
68 
69 void ICFGNode::dump() const
70 {
71  outs() << this->toString() << "\n";
72 }
73 
75 {
76  std::string str;
77  std::stringstream rawstr(str);
78  rawstr << "GlobalICFGNode" << getId();
79  for (const SVFStmt *stmt : getSVFStmts())
80  rawstr << "\n" << stmt->toString();
81  return rawstr.str();
82 }
83 
84 
86 {
87  std::string str;
88  std::stringstream rawstr(str);
89  rawstr << "IntraICFGNode" << getId();
90  rawstr << " {fun: " << getFun()->getName() << getSourceLoc() << "}";
91  for (const SVFStmt *stmt : getSVFStmts())
92  rawstr << "\n" << stmt->toString();
93  if(getSVFStmts().empty())
94  rawstr << "\n" << valueOnlyToString();
95  return rawstr.str();
96 }
97 
98 
100 {
101  std::string str;
102  std::stringstream rawstr(str);
103  rawstr << "FunEntryICFGNode" << getId();
104  rawstr << " {fun: " << getFun()->getName();
105  if (isExtCall(getFun())==false)
106  rawstr << getFun()->getSourceLoc();
107  rawstr << "}";
108  for (const SVFStmt *stmt : getSVFStmts())
109  rawstr << "\n" << stmt->toString();
110  return rawstr.str();
111 }
112 
114 {
115  const SVFFunction *fun = getFun();
116  std::string str;
117  std::stringstream rawstr(str);
118  rawstr << "FunExitICFGNode" << getId();
119  rawstr << " {fun: " << fun->getName();
120  // ensure the enclosing function has exit basic block
121  if (!isExtCall(fun) && fun->hasReturn())
122  if(const IntraICFGNode* intraICFGNode = dyn_cast<IntraICFGNode>(fun->getExitBB()->front()))
123  rawstr << intraICFGNode->getSourceLoc();
124  rawstr << "}";
125  for (const SVFStmt *stmt : getSVFStmts())
126  rawstr << "\n" << stmt->toString();
127  return rawstr.str();
128 }
129 
130 
132 {
133  std::string str;
134  std::stringstream rawstr(str);
135  rawstr << "CallICFGNode" << getId();
136  rawstr << " {fun: " << getFun()->getName() << ICFGNode::getSourceLoc() << "}";
137  for (const SVFStmt *stmt : getSVFStmts())
138  rawstr << "\n" << stmt->toString();
139  if(getSVFStmts().empty())
140  rawstr << "\n" << valueOnlyToString();
141  return rawstr.str();
142 }
143 
145 {
146  std::string str;
147  std::stringstream rawstr(str);
148  rawstr << "RetICFGNode" << getId();
149  rawstr << " {fun: " << getFun()->getName() << ICFGNode::getSourceLoc() << "}";
150  for (const SVFStmt *stmt : getSVFStmts())
151  rawstr << "\n" << stmt->toString();
152  if(getSVFStmts().empty())
153  rawstr << "\n" << valueOnlyToString();
154  return rawstr.str();
155 }
156 
158 {
159  std::string str;
160  std::stringstream rawstr(str);
161  rawstr << "ICFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t";
162  return rawstr.str();
163 }
164 
166 {
167  std::string str;
168  std::stringstream rawstr(str);
169  if(getCondition() == nullptr)
170  rawstr << "IntraCFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t";
171  else
172  rawstr << "IntraCFGEdge: [ICFGNode" << getDstID() << " <-- ICFGNode" << getSrcID() << "] (branchCondition:" << getCondition()->toString() << ") (succCondValue: " << getSuccessorCondValue() << ") \t";
173 
174  return rawstr.str();
175 }
176 
178 {
179  std::string str;
180  std::stringstream rawstr(str);
181  rawstr << "CallCFGEdge " << " [ICFGNode";
182  rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getSrcNode()->toString() << "\t";
183  return rawstr.str();
184 }
185 
187 {
188  std::string str;
189  std::stringstream rawstr(str);
190  rawstr << "RetCFGEdge " << " [ICFGNode";
191  rawstr << getDstID() << " <-- ICFGNode" << getSrcID() << "]\t CallSite: " << getDstNode()->toString() << "\t";
192  return rawstr.str();
193 }
194 
197 {
198  assert(SVFUtil::isa<RetICFGNode>(getDstNode()) && "not a RetICFGNode?");
199  return SVFUtil::cast<RetICFGNode>(getDstNode())->getCallICFGNode();
200 }
201 
210 ICFG::ICFG(): totalICFGNode(0), globalBlockNode(nullptr)
211 {
212 }
213 
215 {
216  Set<const SVFLoop*> loops;
217  for (const auto &it: icfgNodeToSVFLoopVec)
218  {
219  for (const auto &loop: it.second)
220  {
221  loops.insert(loop);
222  }
223  }
224 
225  for (const auto &it: loops)
226  {
227  delete it;
228  }
229  icfgNodeToSVFLoopVec.clear();
230 }
231 
232 
235 {
236  FunEntryICFGNode* entry = getFunEntryBlock(fun);
237  assert (entry && "fun entry not created in ICFGBuilder?");
238  return entry;
239 }
242 {
243  FunExitICFGNode* exit = getFunExitBlock(fun);
244  assert (exit && "fun exit not created in ICFGBuilder?");
245  return exit;
246 }
247 
252 {
253  ICFGEdge edge(src,dst,kind);
254  ICFGEdge* outEdge = src->hasOutgoingEdge(&edge);
255  ICFGEdge* inEdge = dst->hasIncomingEdge(&edge);
256  if (outEdge && inEdge)
257  {
258  assert(outEdge == inEdge && "edges not match");
259  return outEdge;
260  }
261  else
262  return nullptr;
263 }
264 
269 {
270  ICFGEdge edge(src,dst, kind);
271  ICFGEdge* outEdge = src->hasOutgoingEdge(&edge);
272  ICFGEdge* inEdge = dst->hasIncomingEdge(&edge);
273  if (outEdge && inEdge)
274  {
275  assert(outEdge == inEdge && "edges not match");
276  return outEdge;
277  }
278  else
279  return nullptr;
280 }
281 
286 {
287  ICFGEdge edge(src,dst,kind);
288  ICFGEdge* outEdge = src->hasOutgoingEdge(&edge);
289  ICFGEdge* inEdge = dst->hasIncomingEdge(&edge);
290  if (outEdge && inEdge)
291  {
292  assert(outEdge == inEdge && "edges not match");
293  return outEdge;
294  }
295  else
296  return nullptr;
297 }
298 
299 
304 {
305 
306  ICFGEdge * edge = nullptr;
307  u32_t counter = 0;
308  for (ICFGEdge::ICFGEdgeSetTy::iterator iter = src->OutEdgeBegin();
309  iter != src->OutEdgeEnd(); ++iter)
310  {
311  if ((*iter)->getDstID() == dst->getId() && (*iter)->getEdgeKind() == kind)
312  {
313  counter++;
314  edge = (*iter);
315  }
316  }
317  assert(counter <= 1 && "there's more than one edge between two ICFG nodes");
318  return edge;
319 
320 }
321 
326 {
327  checkIntraEdgeParents(srcNode, dstNode);
328  ICFGEdge* edge = hasIntraICFGEdge(srcNode, dstNode, ICFGEdge::IntraCF);
329  if (edge != nullptr)
330  {
331  assert(edge->isIntraCFGEdge() && "this should be an intra CFG edge!");
332  return nullptr;
333  }
334  else
335  {
336  IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode,dstNode);
337  return (addICFGEdge(intraEdge) ? intraEdge : nullptr);
338  }
339 }
340 
344 ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, s64_t branchCondVal)
345 {
346 
347  checkIntraEdgeParents(srcNode, dstNode);
348  ICFGEdge* edge = hasIntraICFGEdge(srcNode, dstNode, ICFGEdge::IntraCF);
349  if (edge != nullptr)
350  {
351  assert(edge->isIntraCFGEdge() && "this should be an intra CFG edge!");
352  return nullptr;
353  }
354  else
355  {
356  IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode,dstNode);
357  intraEdge->setBranchCondVal(branchCondVal);
358  return (addICFGEdge(intraEdge) ? intraEdge : nullptr);
359  }
360 }
361 
362 
367 {
368  ICFGEdge* edge = hasInterICFGEdge(srcNode,dstNode, ICFGEdge::CallCF);
369  if (edge != nullptr)
370  {
371  assert(edge->isCallCFGEdge() && "this should be a call CFG edge!");
372  return nullptr;
373  }
374  else
375  {
376  CallCFGEdge* callEdge = new CallCFGEdge(srcNode,dstNode);
377  return (addICFGEdge(callEdge) ? callEdge : nullptr);
378  }
379 }
380 
385 {
386  ICFGEdge* edge = hasInterICFGEdge(srcNode, dstNode, ICFGEdge::RetCF);
387  if (edge != nullptr)
388  {
389  assert(edge->isRetCFGEdge() && "this should be a return CFG edge!");
390  return nullptr;
391  }
392  else
393  {
394  RetCFGEdge* retEdge = new RetCFGEdge(srcNode,dstNode);
395  return (addICFGEdge(retEdge) ? retEdge : nullptr);
396  }
397 }
398 
399 
403 void ICFG::dump(const std::string& file, bool simple)
404 {
405  GraphPrinter::WriteGraphToFile(outs(), file, this, simple);
406 }
407 
412 {
413  SVF::ViewGraph(this, "Interprocedural Control-Flow Graph");
414 }
415 
420 {
421  PTACallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
422  PTACallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
423  for (; iter != eiter; iter++)
424  {
425  CallICFGNode* callBlockNode = const_cast<CallICFGNode*>(iter->first);
426  assert(callBlockNode->isIndirectCall() && "this is not an indirect call?");
427  const PTACallGraph::FunctionSet & functions = iter->second;
428  for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
429  {
430  const SVFFunction* callee = *func_iter;
431  RetICFGNode* retBlockNode = const_cast<RetICFGNode*>(callBlockNode->getRetICFGNode());
433  if (isExtCall(callee))
434  addIntraEdge(callBlockNode, retBlockNode);
435  else
436  {
437  FunEntryICFGNode* calleeEntryNode = getFunEntryBlock(callee);
438  FunExitICFGNode* calleeExitNode = getFunExitBlock(callee);
439  if(ICFGEdge* callEdge = addCallEdge(callBlockNode, calleeEntryNode))
440  {
441  for (const SVFStmt *stmt : callBlockNode->getSVFStmts())
442  {
443  if(const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(stmt))
444  {
445  if(callPE->getFunEntryICFGNode() == calleeEntryNode)
446  SVFUtil::cast<CallCFGEdge>(callEdge)->addCallPE(callPE);
447  }
448  }
449  }
450  if(ICFGEdge* retEdge = addRetEdge(calleeExitNode, retBlockNode))
451  {
452  for (const SVFStmt *stmt : retBlockNode->getSVFStmts())
453  {
454  if(const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(stmt))
455  {
456  if(retPE->getFunExitICFGNode() == calleeExitNode)
457  SVFUtil::cast<RetCFGEdge>(retEdge)->addRetPE(retPE);
458  }
459  }
460  }
461 
463  if(ICFGEdge* edge = hasIntraICFGEdge(callBlockNode,retBlockNode, ICFGEdge::IntraCF))
464  removeICFGEdge(edge);
465  }
466 
467  }
468  }
469  // dump ICFG
470  if (Options::DumpICFG())
471  {
472  dump("icfg_final");
473  }
474 }
475 
479 namespace SVF
480 {
481 template<>
483 {
484 
486  DOTGraphTraits(bool isSimple = false) :
487  DOTGraphTraits<SVFIR*>(isSimple)
488  {
489  }
490 
493  {
494  return "ICFG";
495  }
496 
498  {
499  return getSimpleNodeLabel(node, graph);
500  }
501 
504  {
505  return node->toString();
506  }
507 
508  static bool isNodeHidden(ICFGNode *node, ICFG *)
509  {
511  return false;
512  else
513  return node->getInEdges().empty() && node->getOutEdges().empty();
514  }
515 
517  {
518  std::string str;
519  std::stringstream rawstr(str);
520 
521  if(SVFUtil::isa<IntraICFGNode>(node))
522  {
523  rawstr << "color=black";
524  }
525  else if(SVFUtil::isa<FunEntryICFGNode>(node))
526  {
527  rawstr << "color=yellow";
528  }
529  else if(SVFUtil::isa<FunExitICFGNode>(node))
530  {
531  rawstr << "color=green";
532  }
533  else if(SVFUtil::isa<CallICFGNode>(node))
534  {
535  rawstr << "color=red";
536  }
537  else if(SVFUtil::isa<RetICFGNode>(node))
538  {
539  rawstr << "color=blue";
540  }
541  else if(SVFUtil::isa<GlobalICFGNode>(node))
542  {
543  rawstr << "color=purple";
544  }
545  else
546  assert(false && "no such kind of node!!");
547 
548  rawstr << "";
549 
550  return rawstr.str();
551  }
552 
553  template<class EdgeIter>
554  static std::string getEdgeAttributes(NodeType*, EdgeIter EI, ICFG*)
555  {
556  ICFGEdge* edge = *(EI.getCurrent());
557  assert(edge && "No edge found!!");
558  if (SVFUtil::isa<CallCFGEdge>(edge))
559  return "style=solid,color=red";
560  else if (SVFUtil::isa<RetCFGEdge>(edge))
561  return "style=solid,color=blue";
562  else
563  return "style=solid";
564  return "";
565  }
566 
567  template<class EdgeIter>
569  {
570  ICFGEdge* edge = *(EI.getCurrent());
571  assert(edge && "No edge found!!");
572 
573  std::string str;
574  std::stringstream rawstr(str);
575  if (CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge))
576  rawstr << dirCall->getSrcNode();
577  else if (RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge))
578  {
579  if(RetICFGNode* ret = SVFUtil::dyn_cast<RetICFGNode>(dirRet->getDstNode()))
580  rawstr << ret->getCallICFGNode();
581  }
582 
583  return rawstr.str();
584  }
585 };
586 } // End namespace llvm
const char *const string
Definition: cJSON.h:172
virtual const std::string toString() const
Definition: ICFG.cpp:177
const std::string toString() const override
Definition: ICFG.cpp:131
bool isIndirectCall() const
Return true if this is an indirect call.
Definition: ICFGNode.h:482
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition: ICFGNode.h:457
FunEntryICFGNode(NodeID id)
Constructor to create empty FunEntryICFGNode (for SVFIRReader/deserialization)
Definition: ICFGNode.h:289
const SVFFunction * getFun() const override
Return function.
Definition: ICFGNode.h:295
const std::string toString() const override
Definition: ICFG.cpp:99
const std::string toString() const override
Definition: ICFG.cpp:113
FunExitICFGNode(NodeID id)
Constructor to create empty FunExitICFGNode (for SVFIRReader/deserialization)
Definition: ICFGNode.h:360
const SVFFunction * getFun() const override
Return function.
Definition: ICFGNode.h:366
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
Definition: GenericGraph.h:442
bool hasOutgoingEdge() const
Definition: GenericGraph.h:446
iterator OutEdgeEnd()
Definition: GenericGraph.h:458
const GEdgeSetTy & getOutEdges() const
Definition: GenericGraph.h:430
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:454
const GEdgeSetTy & getInEdges() const
Definition: GenericGraph.h:434
const std::string toString() const override
Definition: ICFG.cpp:74
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56
bool isCallCFGEdge() const
Definition: ICFGEdge.h:77
bool isIntraCFGEdge() const
Definition: ICFGEdge.h:85
virtual const std::string toString() const
Definition: ICFG.cpp:157
bool isRetCFGEdge() const
Definition: ICFGEdge.h:81
const SVFFunction * fun
Definition: ICFGNode.h:148
const SVFBasicBlock * bb
Definition: ICFGNode.h:149
void dump() const
Definition: ICFG.cpp:69
const SVFStmtList & getSVFStmts() const
Definition: ICFGNode.h:117
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
Definition: ICFGNode.h:76
virtual const std::string toString() const
Definition: ICFG.cpp:61
Definition: ICFG.h:48
void view()
View graph from the debugger.
Definition: ICFG.cpp:411
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
Definition: ICFG.cpp:234
FunExitICFGNode * getFunExitBlock(const SVFFunction *fun)
Get/Add a function exit node.
Definition: ICFG.h:296
ICFGEdge * hasThreadICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition: ICFG.cpp:285
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
Definition: ICFG.h:277
void removeICFGEdge(ICFGEdge *edge)
Remove a ICFG edge.
Definition: ICFG.h:151
void updateCallGraph(PTACallGraph *callgraph)
update ICFG for indirect calls
Definition: ICFG.cpp:419
ICFGEdge * getICFGEdge(const ICFGNode *src, const ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition: ICFG.cpp:303
ICFG()
Constructor.
Definition: ICFG.cpp:210
void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
Definition: ICFG.h:165
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition: ICFG.cpp:366
ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec
map ICFG node to the SVF loops where it resides
Definition: ICFG.h:72
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition: ICFG.cpp:268
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition: ICFG.cpp:403
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Definition: ICFG.cpp:384
ICFGEdge * hasIntraICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Whether we has a SVFG edge.
Definition: ICFG.cpp:251
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
Definition: ICFG.cpp:344
FunEntryICFGNode * getFunEntryBlock(const SVFFunction *fun)
Get/Add a function entry node.
Definition: ICFG.h:287
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
Definition: ICFG.cpp:325
~ICFG() override
Destructor.
Definition: ICFG.cpp:214
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
Definition: ICFG.cpp:241
s64_t getSuccessorCondValue() const
Definition: ICFGEdge.h:147
virtual const std::string toString() const
Definition: ICFG.cpp:165
void setBranchCondVal(s64_t bVal)
Definition: ICFGEdge.h:173
const SVFVar * getCondition() const
Definition: ICFGEdge.h:142
const std::string toString() const override
Definition: ICFG.cpp:85
static const Option< bool > ShowHiddenNode
Definition: Options.h:228
static const Option< bool > DumpICFG
Definition: Options.h:123
Set< const SVFFunction * > FunctionSet
Definition: PTACallGraph.h:251
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition: PTACallGraph.h:304
const CallICFGNode * getCallSite() const
Return call ICFGNode at the callsite.
Definition: ICFG.cpp:196
virtual const std::string toString() const
Definition: ICFG.cpp:186
const std::string toString() const override
Definition: ICFG.cpp:144
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const std::string valueOnlyToString() const
Definition: LLVMUtil.cpp:688
virtual const std::string getSourceLoc() const
Definition: GenericGraph.h:281
const ICFGNode * front() const
Definition: SVFValue.h:594
const_iterator end() const
Definition: SVFValue.h:440
const_iterator begin() const
Definition: SVFValue.h:435
bool hasReturn() const
Definition: SVFValue.h:460
const SVFBasicBlock * getEntryBlock() const
Definition: SVFValue.h:409
const SVFBasicBlock * getExitBB() const
Definition: SVFValue.cpp:186
const std::string & getName() const
Definition: SVFValue.h:243
virtual const std::string getSourceLoc() const
Definition: SVFValue.h:280
virtual const std::string toString() const
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
Definition: GraphWriter.h:371
unsigned u32_t
Definition: GeneralType.h:46
signed long long s64_t
Definition: GeneralType.h:49
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96
std::string getNodeLabel(NodeType *node, ICFG *graph)
Definition: ICFG.cpp:497
static std::string getGraphName(ICFG *)
Return name of the graph.
Definition: ICFG.cpp:492
static bool isNodeHidden(ICFGNode *node, ICFG *)
Definition: ICFG.cpp:508
static std::string getSimpleNodeLabel(NodeType *node, ICFG *)
Return the label of an ICFG node.
Definition: ICFG.cpp:503
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
Definition: ICFG.cpp:568
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, ICFG *)
Definition: ICFG.cpp:554
static std::string getNodeAttributes(NodeType *node, ICFG *)
Definition: ICFG.cpp:516
DOTGraphTraits(bool isSimple=false)
Definition: ICFG.cpp:486