Static Value-Flow Analysis
Loading...
Searching...
No Matches
GenericGraph.h
Go to the documentation of this file.
1//===- CenericGraph.h -- Generic graph ---------------------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <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 * GenericGraph.h
25 *
26 * Created on: Mar 19, 2014
27 * Author: Yulei Sui
28 */
29
30#ifndef GENERICGRAPH_H_
31#define GENERICGRAPH_H_
32
33#include "SVFIR/SVFType.h"
34#include "Util/iterator.h"
35#include "Graphs/GraphTraits.h"
36
37namespace SVF
38{
41template <typename, typename> class GenericGraphWriter;
42template <typename, typename> class GenericGraphReader;
44
48template<class NodeTy>
50{
51 friend class SVFIRWriter;
52 friend class SVFIRReader;
53
54public:
63private:
67
68public:
73
75 virtual ~GenericEdge()
76 {
77 }
78
80
81 inline NodeID getSrcID() const
82 {
83 return src->getId();
84 }
85 inline NodeID getDstID() const
86 {
87 return dst->getId();
88 }
89 inline GEdgeKind getEdgeKind() const
90 {
91 return (EdgeKindMask & edgeFlag);
92 }
94 {
95 return edgeFlag;
96 }
98 {
99 return src;
100 }
102 {
103 return dst;
104 }
106
108 // and duplicated elements in the set are not inserted (binary tree comparison)
110 typedef struct equalGEdge
111 {
113 {
114 if (lhs->edgeFlag != rhs->edgeFlag)
115 return lhs->edgeFlag < rhs->edgeFlag;
116 else if (lhs->getSrcID() != rhs->getSrcID())
117 return lhs->getSrcID() < rhs->getSrcID();
118 else
119 return lhs->getDstID() < rhs->getDstID();
120 }
121 } equalGEdge;
122
123 virtual inline bool operator==(const GenericEdge<NodeType>* rhs) const
124 {
125 return (rhs->edgeFlag == this->edgeFlag &&
126 rhs->getSrcID() == this->getSrcID() &&
127 rhs->getDstID() == this->getDstID());
128 }
130
131protected:
132 static constexpr unsigned char EdgeKindMaskBits = 8;
133 static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits);
134};
135
136
138{
139
140public:
141
143 {
144 // ┌── ICFGNode: Classes of inter-procedural and intra-procedural control flow graph nodes
145 IntraBlock, // ├──Represents a node within a single procedure
146 GlobalBlock, // ├──Represents a global-level block
147 // │ └─ InterICFGNode: Classes of inter-procedural control flow graph nodes
148 FunEntryBlock, // ├──Entry point of a function
149 FunExitBlock, // ├──Exit point of a function
150 FunCallBlock, // ├──Call site in the function
151 FunRetBlock, // ├──Return site in the function
152 // └────────
153
154 // ┌── SVFVar: Classes of top-level variables (ValVar) and address-taken variables (ObjVar)
155 // │ └── ValVar: Classes of top-level variable nodes
156 ValNode, // ├──Represents a standard value variable
157 FunValNode, // ├──Represents a Function value variable
158 GepValNode, // ├──Represents a GEP value variable
159 RetNode, // ├──Represents a return value node
160 VarargNode, // ├──Represents a variadic argument node
161 DummyValNode, // ├──Dummy node for uninitialized values
162 // │ └── ObjVar: Classes of object variable nodes
163 ObjNode, // ├──Represents an object variable
164 GepObjNode, // ├──Represents a GEP object variable
165 // │ └── BaseObjVar: Classes of base object nodes
166 BaseObjNode, // ├──Represents a base object node
167 FunObjNode, // ├──Types of function object
168 HeapObjNode, // ├──Types of heap object
169 StackObjNode, // ├──Types of stack object
170 DummyObjNode, // ├──Dummy node for uninitialized objects
171 // └────────
172
173 // ┌── VFGNode: Classes of Value Flow Graph (VFG) node kinds with operations
174 Cmp, // ├──Represents a comparison operation
175 BinaryOp, // ├──Represents a binary operation
176 UnaryOp, // ├──Represents a unary operation
177 Branch, // ├──Represents a branch operation
178 DummyVProp, // ├──Dummy node for value propagation
179 NPtr, // ├──Represents a null pointer operation
180 // │ └── ArgumentVFGNode: Classes of argument nodes in VFG
181 FRet, // ├──Represents a function return value
182 ARet, // ├──Represents an argument return value
183 AParm, // ├──Represents an argument parameter
184 FParm, // ├──Represents a function parameter
185 // │ └── StmtVFGNode: Classes of statement nodes in VFG
186 Addr, // ├──Represents an address operation
187 Copy, // ├──Represents a copy operation
188 Gep, // ├──Represents a GEP operation
189 Store, // ├──Represents a store operation
190 Load, // ├──Represents a load operation
191 // │ └── PHIVFGNode: Classes of PHI nodes in VFG
192 TPhi, // ├──Represents a type-based PHI node
193 TIntraPhi, // ├──Represents an intra-procedural PHI node
194 TInterPhi, // ├──Represents an inter-procedural PHI node
195 // │ └── MRSVFGNode: Classes of Memory-related SVFG nodes
196 FPIN, // ├──Function parameter input
197 FPOUT, // ├──Function parameter output
198 APIN, // ├──Argument parameter input
199 APOUT, // ├──Argument parameter output
200 // │ └── MSSAPHISVFGNode: Classes of Mem SSA PHI nodes for SVFG
201 MPhi, // ├──Memory PHI node
202 MIntraPhi, // ├──Intra-procedural memory PHI node
203 MInterPhi, // ├──Inter-procedural memory PHI node
204 // └────────
205
206 // Additional specific graph node types
207 CallNodeKd, // Callgraph node
208 CDNodeKd, // Control dependence graph node
209 CFLNodeKd, // CFL graph node
210 CHNodeKd, // Class hierarchy graph node
211 ConstraintNodeKd, // Constraint graph node
212 TCTNodeKd, // Thread creation tree node
213 DCHNodeKd, // DCHG node
214 OtherKd // Other node kind
215 };
216
217
218
220 {
221
222 }
223
225 inline NodeID getId() const
226 {
227 return id;
228 }
229
231 inline GNodeK getNodeKind() const
232 {
233 return nodeKind;
234 }
235
236 virtual const SVFType* getType() const
237 {
238 return type;
239 }
240
241 inline virtual void setSourceLoc(const std::string& sourceCodeInfo)
242 {
244 }
245
246 virtual const std::string getSourceLoc() const
247 {
248 return sourceLoc;
249 }
250
251 const std::string valueOnlyToString() const;
252
253
254protected:
257 const SVFType* type;
258
259 std::string sourceLoc;
260
262 //{@ Check node kind
263 static inline bool isICFGNodeKinds(GNodeK n)
264 {
265 static_assert(FunRetBlock - IntraBlock == 5,
266 "the number of ICFGNodeKinds has changed, make sure "
267 "the range is correct");
269 }
270
271 static inline bool isInterICFGNodeKind(GNodeK n)
272 {
273 static_assert(FunRetBlock - FunEntryBlock == 3,
274 "the number of InterICFGNodeKind has changed, make sure "
275 "the range is correct");
277 }
278
279 static inline bool isSVFVarKind(GNodeK n)
280 {
281 static_assert(DummyObjNode - ValNode == 12,
282 "The number of SVFVarKinds has changed, make sure the "
283 "range is correct");
284
286 }
287
288 static inline bool isValVarKinds(GNodeK n)
289 {
290 static_assert(DummyValNode - ValNode == 5,
291 "The number of ValVarKinds has changed, make sure the "
292 "range is correct");
294 }
295
296 static inline bool isObjVarKinds(GNodeK n)
297 {
298 static_assert(DummyObjNode - ObjNode == 6,
299 "The number of ObjVarKinds has changed, make sure the "
300 "range is correct");
302 }
303
304 static inline bool isBaseObjVarKinds(GNodeK n)
305 {
306 static_assert(DummyObjNode - BaseObjNode == 4,
307 "The number of BaseObjVarKinds has changed, make sure the "
308 "range is correct");
310 }
311
312 static inline bool isVFGNodeKinds(GNodeK n)
313 {
314 static_assert(MInterPhi - Cmp == 24,
315 "The number of VFGNodeKinds has changed, make sure the "
316 "range is correct");
318 }
319
320 static inline bool isArgumentVFGNodeKinds(GNodeK n)
321 {
322 static_assert(FParm - FRet == 3,
323 "The number of ArgumentVFGNodeKinds has changed, make "
324 "sure the range is correct");
325 return n <= FParm && n >= FRet;
326 }
327
328 static inline bool isStmtVFGNodeKinds(GNodeK n)
329 {
330 static_assert(Load - Addr == 4,
331 "The number of StmtVFGNodeKinds has changed, make sure "
332 "the range is correct");
333 return n <= Load && n >= Addr;
334 }
335
336 static inline bool isPHIVFGNodeKinds(GNodeK n)
337 {
338 static_assert(TInterPhi - TPhi == 2,
339 "The number of PHIVFGNodeKinds has changed, make sure "
340 "the range is correct");
342 }
343
344 static inline bool isMRSVFGNodeKinds(GNodeK n)
345 {
346 static_assert(MInterPhi - FPIN == 6,
347 "The number of MRSVFGNodeKinds has changed, make sure "
348 "the range is correct");
350 }
351
352 static inline bool isMSSAPHISVFGNodeKinds(GNodeK n)
353 {
354 static_assert(MInterPhi - MPhi == 2,
355 "The number of MSSAPHISVFGNodeKinds has changed, make "
356 "sure the range is correct");
358 }
360};
361
365template<class NodeTy,class EdgeTy>
367{
368 friend class SVFIRWriter;
369 friend class SVFIRReader;
370
371public:
378 typedef typename GEdgeSetTy::iterator iterator;
379 typedef typename GEdgeSetTy::const_iterator const_iterator;
381
382private:
383
386
387public:
390 {
391
392 }
393
395 virtual ~GenericNode()
396 {
397 for (auto * edge : OutEdges)
398 delete edge;
399 }
400
403 inline const GEdgeSetTy& getOutEdges() const
404 {
405 return OutEdges;
406 }
407 inline const GEdgeSetTy& getInEdges() const
408 {
409 return InEdges;
410 }
412
414
415 inline bool hasIncomingEdge() const
416 {
417 return (InEdges.empty() == false);
418 }
419 inline bool hasOutgoingEdge() const
420 {
421 return (OutEdges.empty() == false);
422 }
424
426
428 {
429 return OutEdges.begin();
430 }
432 {
433 return OutEdges.end();
434 }
436 {
437 return InEdges.begin();
438 }
440 {
441 return InEdges.end();
442 }
444 {
445 return OutEdges.begin();
446 }
448 {
449 return OutEdges.end();
450 }
452 {
453 return InEdges.begin();
454 }
456 {
457 return InEdges.end();
458 }
460
462
464 {
465 return OutEdges.begin();
466 }
467 virtual inline iterator directOutEdgeEnd()
468 {
469 return OutEdges.end();
470 }
472 {
473 return InEdges.begin();
474 }
475 virtual inline iterator directInEdgeEnd()
476 {
477 return InEdges.end();
478 }
479
480 virtual inline const_iterator directOutEdgeBegin() const
481 {
482 return OutEdges.begin();
483 }
484 virtual inline const_iterator directOutEdgeEnd() const
485 {
486 return OutEdges.end();
487 }
488 virtual inline const_iterator directInEdgeBegin() const
489 {
490 return InEdges.begin();
491 }
492 virtual inline const_iterator directInEdgeEnd() const
493 {
494 return InEdges.end();
495 }
497
499
501 {
502 return InEdges.insert(inEdge).second;
503 }
505 {
506 return OutEdges.insert(outEdge).second;
507 }
509
513 {
514 iterator it = InEdges.find(edge);
515 assert(it != InEdges.end() && "can not find in edge in SVFG node");
516 InEdges.erase(it);
517 return 1;
518 }
520 {
521 iterator it = OutEdges.find(edge);
522 assert(it != OutEdges.end() && "can not find out edge in SVFG node");
523 OutEdges.erase(it);
524 return 1;
525 }
527
529
531 {
533 if (it != InEdges.end())
534 return *it;
535 else
536 return nullptr;
537 }
539 {
541 if (it != OutEdges.end())
542 return *it;
543 else
544 return nullptr;
545 }
547
548 static inline bool classof(const GenericNode<NodeTy, EdgeTy>*)
549 {
550 return true;
551 }
552
553 static inline bool classof(const SVFBaseNode*)
554 {
555 return true;
556 }
557};
558
559/*
560 * Generic graph for program representation
561 * It is base class and needs to be instantiated
562 */
563template<class NodeTy, class EdgeTy>
565{
566 friend class SVFIRWriter;
567 friend class SVFIRReader;
568 friend class GenericGraphWriter<NodeTy, EdgeTy>;
569 friend class GenericGraphReader<NodeTy, EdgeTy>;
570
571public:
576
578
579 typedef typename IDToNodeMapTy::iterator iterator;
580 typedef typename IDToNodeMapTy::const_iterator const_iterator;
582
585
588 {
589 destroy();
590 }
591
593 void destroy()
594 {
595 for (auto &entry : IDToNodeMap)
596 delete entry.second;
597 }
599
601 {
602 return IDToNodeMap.begin();
603 }
604 inline iterator end()
605 {
606 return IDToNodeMap.end();
607 }
608 inline const_iterator begin() const
609 {
610 return IDToNodeMap.begin();
611 }
612 inline const_iterator end() const
613 {
614 return IDToNodeMap.end();
615 }
616 //}@
617
619 inline void addGNode(NodeID id, NodeType* node)
620 {
621 IDToNodeMap[id] = node;
622 nodeNum++;
623 }
624
626 inline NodeType* getGNode(NodeID id) const
627 {
628 const_iterator it = IDToNodeMap.find(id);
629 assert(it != IDToNodeMap.end() && "Node not found!");
630 return it->second;
631 }
632
634 inline bool hasGNode(NodeID id) const
635 {
636 const_iterator it = IDToNodeMap.find(id);
637 return it != IDToNodeMap.end();
638 }
639
641 inline void removeGNode(NodeType* node)
642 {
643 assert(node->hasIncomingEdge() == false
644 && node->hasOutgoingEdge() == false
645 && "node which have edges can't be deleted");
646 iterator it = IDToNodeMap.find(node->getId());
647 assert(it != IDToNodeMap.end() && "can not find the node");
648 IDToNodeMap.erase(it);
649 delete node;
650 }
651
653 inline u32_t getTotalNodeNum() const
654 {
655 return nodeNum;
656 }
657 inline u32_t getTotalEdgeNum() const
658 {
659 return edgeNum;
660 }
662 inline void incNodeNum()
663 {
664 nodeNum++;
665 }
666 inline void incEdgeNum()
667 {
668 edgeNum++;
669 }
670
671protected:
673
674public:
677};
678
679} // End namespace SVF
680
681/* !
682 * GenericGraphTraits specializations for generic graph algorithms.
683 * Provide graph traits for traversing from a node using standard graph traversals.
684 */
685namespace SVF
686{
687
688// mapped_iter - This is a simple iterator adapter that causes a function to
689// be applied whenever operator* is invoked on the iterator.
690
691template <typename ItTy, typename FuncTy,
692 typename FuncReturnTy =
693 decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))>
695 : public iter_adaptor_base<
696 mapped_iter<ItTy, FuncTy>, ItTy,
697 typename std::iterator_traits<ItTy>::iterator_category,
698 typename std::remove_reference<FuncReturnTy>::type>
699{
700public:
702 : mapped_iter::iter_adaptor_base(std::move(U)), F(std::move(F)) {}
703
705 {
706 return this->I;
707 }
708
709 FuncReturnTy operator*() const
710 {
711 return F(*this->I);
712 }
713
714private:
715 FuncTy F;
716};
717
718// map_iter - Provide a convenient way to create mapped_iters, just like
719// make_pair is useful for creating pairs...
720template <class ItTy, class FuncTy>
722{
723 return mapped_iter<ItTy, FuncTy>(std::move(I), std::move(F));
724}
725
729template<class NodeTy,class EdgeTy> struct GenericGraphTraits<SVF::GenericNode<NodeTy,EdgeTy>* >
730{
733
734 static inline NodeType* edge_dest(const EdgeType* E)
735 {
736 return E->getDstNode();
737 }
738
739 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
741
743 {
744 return pagN;
745 }
746
748 {
749 return map_iter(N->OutEdgeBegin(), &edge_dest);
750 }
751 static inline ChildIteratorType child_end(const NodeType* N)
752 {
753 return map_iter(N->OutEdgeEnd(), &edge_dest);
754 }
756 {
757 return map_iter(N->directOutEdgeBegin(), &edge_dest);
758 }
760 {
761 return map_iter(N->directOutEdgeEnd(), &edge_dest);
762 }
763};
764
768template<class NodeTy,class EdgeTy>
769struct GenericGraphTraits<Inverse<SVF::GenericNode<NodeTy,EdgeTy>* > >
770{
773
774 static inline NodeType* edge_dest(const EdgeType* E)
775 {
776 return E->getSrcNode();
777 }
778
779 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
781
783 {
784 return G.Graph;
785 }
786
788 {
789 return map_iter(N->InEdgeBegin(), &edge_dest);
790 }
791 static inline ChildIteratorType child_end(const NodeType* N)
792 {
793 return map_iter(N->InEdgeEnd(), &edge_dest);
794 }
795
796 static inline unsigned getNodeID(const NodeType* N)
797 {
798 return N->getId();
799 }
800};
801
805template<class NodeTy,class EdgeTy> struct GenericGraphTraits<SVF::GenericGraph<NodeTy,EdgeTy>* > : public GenericGraphTraits<SVF::GenericNode<NodeTy,EdgeTy>* >
806{
810
812 {
813 return nullptr; // return null here, maybe later we could create a dummy node
814 }
815
816 typedef std::pair<SVF::NodeID, NodeType*> PairTy;
817 static inline NodeType* deref_val(PairTy P)
818 {
819 return P.second;
820 }
821
822 // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
823 typedef mapped_iter<typename GenericGraphTy::iterator, decltype(&deref_val)> nodes_iterator;
824
826 {
827 return map_iter(G->begin(), &deref_val);
828 }
830 {
831 return map_iter(G->end(), &deref_val);
832 }
833
834 static unsigned graphSize(GenericGraphTy* G)
835 {
836 return G->getTotalNodeNum();
837 }
838
839 static inline unsigned getNodeID(NodeType* N)
840 {
841 return N->getId();
842 }
844 {
845 return G->getGNode(id);
846 }
847};
848
849} // End namespace llvm
850
851#endif /* GENERICGRAPH_H_ */
#define F(f)
cJSON * n
Definition cJSON.cpp:2558
virtual bool operator==(const GenericEdge< NodeType > *rhs) const
NodeTy * src
source node
GEdgeKind getEdgeKindWithoutMask() const
NodeType * getSrcNode() const
virtual ~GenericEdge()
Destructor.
GenericEdge(NodeTy *s, NodeTy *d, GEdgeFlag k)
Constructor.
NodeType * getDstNode() const
static constexpr u64_t EdgeKindMask
GEdgeFlag edgeFlag
edge kind
NodeTy * dst
destination node
GEdgeKind getEdgeKind() const
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
static constexpr unsigned char EdgeKindMaskBits
We use the lower 8 bits to denote edge kind.
NodeTy NodeType
Node type.
void addGNode(NodeID id, NodeType *node)
Add a Node.
iterator begin()
Iterators.
void removeGNode(NodeType *node)
Delete a node.
u32_t getTotalEdgeNum() const
u32_t edgeNum
total num of node
const_iterator end() const
const_iterator begin() const
u32_t nodeNum
total num of edge
virtual ~GenericGraph()
Destructor.
IDToNodeMapTy IDToNodeMap
node map
IDToNodeMapTy::const_iterator const_iterator
bool hasGNode(NodeID id) const
Has a node.
void incNodeNum()
Increase number of node/edge.
u32_t getTotalNodeNum() const
Get total number of node/edge.
GenericGraph()
Constructor.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
void destroy()
Release memory.
OrderedMap< NodeID, NodeType * > IDToNodeMapTy
NodeID to GenericNode map.
const_iterator InEdgeEnd() const
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
GEdgeSetTy OutEdges
all outgoing edge of this node
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
static bool classof(const SVFBaseNode *)
u32_t removeOutgoingEdge(EdgeType *edge)
virtual iterator directInEdgeEnd()
iterator OutEdgeEnd()
EdgeType * hasIncomingEdge(EdgeType *edge) const
Find incoming and outgoing edges.
GEdgeSetTy InEdges
all incoming edge of this node
GEdgeSetTy::iterator iterator
const GEdgeSetTy & getOutEdges() const
virtual ~GenericNode()
Destructor.
virtual iterator directInEdgeBegin()
const_iterator OutEdgeBegin() const
virtual iterator directOutEdgeEnd()
const GEdgeSetTy & getInEdges() const
const_iterator InEdgeBegin() const
virtual const_iterator directOutEdgeEnd() const
bool addIncomingEdge(EdgeType *inEdge)
Add incoming and outgoing edges.
u32_t removeIncomingEdge(EdgeType *edge)
virtual iterator directOutEdgeBegin()
Iterators used for SCC detection, overwrite it in child class if necessary.
iterator OutEdgeBegin()
iterators
virtual const_iterator directInEdgeEnd() const
static bool classof(const GenericNode< NodeTy, EdgeTy > *)
virtual const_iterator directInEdgeBegin() const
GEdgeSetTy::const_iterator const_iterator
GenericNode(NodeID i, GNodeK k)
Constructor.
const_iterator OutEdgeEnd() const
virtual const_iterator directOutEdgeBegin() const
EdgeType * hasOutgoingEdge(EdgeType *edge) const
iterator InEdgeBegin()
bool addOutgoingEdge(EdgeType *outEdge)
iterator InEdgeEnd()
static bool isArgumentVFGNodeKinds(GNodeK n)
static bool isObjVarKinds(GNodeK n)
std::string sourceLoc
Source code information of this value.
NodeID id
Node ID.
static bool isVFGNodeKinds(GNodeK n)
const SVFType * type
SVF type.
virtual const SVFType * getType() const
static bool isMRSVFGNodeKinds(GNodeK n)
static bool isValVarKinds(GNodeK n)
static bool isPHIVFGNodeKinds(GNodeK n)
GNodeK getNodeKind() const
Get node kind.
NodeID getId() const
Get ID.
static bool isICFGNodeKinds(GNodeK n)
Helper functions to check node kinds.
static bool isMSSAPHISVFGNodeKinds(GNodeK n)
GNodeK nodeKind
Node kind.
virtual void setSourceLoc(const std::string &sourceCodeInfo)
static bool isStmtVFGNodeKinds(GNodeK n)
SVFBaseNode(NodeID i, GNodeK k, SVFType *ty=nullptr)
static bool isInterICFGNodeKind(GNodeK n)
static bool isSVFVarKind(GNodeK n)
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:746
virtual const std::string getSourceLoc() const
static bool isBaseObjVarKinds(GNodeK n)
WrappedIteratorT I
Definition iterator.h:242
mapped_iter(ItTy U, FuncTy F)
FuncReturnTy operator*() const
for isBitcode
Definition BasicTypes.h:68
unsigned long long u64_t
Definition GeneralType.h:48
u32_t NodeID
Definition GeneralType.h:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:46
mapped_iter< ItTy, FuncTy > map_iter(ItTy I, FuncTy F)
signed long long s64_t
Definition GeneralType.h:49
Add the hash function for std::set (we also can overload operator< to implement this)
bool operator()(const GenericEdge< NodeType > *lhs, const GenericEdge< NodeType > *rhs) const
mapped_iter< typename SVF::GenericNode< NodeTy, EdgeTy >::iterator, decltype(&edge_dest)> ChildIteratorType
static NodeType * getNode(GenericGraphTy *G, SVF::NodeID id)
mapped_iter< typename GenericGraphTy::iterator, decltype(&deref_val)> nodes_iterator
static ChildIteratorType direct_child_begin(const NodeType *N)
static ChildIteratorType child_end(const NodeType *N)
static ChildIteratorType direct_child_end(const NodeType *N)
mapped_iter< typename SVF::GenericNode< NodeTy, EdgeTy >::iterator, decltype(&edge_dest)> ChildIteratorType
static ChildIteratorType child_begin(const NodeType *N)
const GraphType & Graph
Definition GraphTraits.h:99