Static Value-Flow Analysis
Loading...
Searching...
No Matches
SlicedGraphs.h
Go to the documentation of this file.
1//===- SlicedGraphs.h -- General sliced graph views ------------------------===//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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 * SlicedGraphs.h
25 *
26 * Author: Jiawei Yang
27 */
28
29#ifndef GRAPHS_SLICEDGRAPHS_H
30#define GRAPHS_SLICEDGRAPHS_H
31
32#include "Graphs/ICFG.h"
33#include "Graphs/ICFGNode.h"
34#include "Graphs/ICFGEdge.h"
35#include "Graphs/CallGraph.h"
37#include "Graphs/SVFG.h"
38#include "Graphs/SVFGNode.h"
39#include "Graphs/GraphTraits.h"
40#include "SVFIR/SVFIR.h"
41#include "SVFIR/SVFStatements.h"
42#include "SVFIR/SVFVariables.h"
43#include <cstddef>
44#include <iterator>
45#include <memory>
46#include <string>
47#include <vector>
48#include <utility>
49
50namespace SVF
51{
52
53//===----------------------------------------------------------------------===//
54// SlicedICFGView - sliced view of the ICFG.
55// Provides getSuccNodes()/getPredNodes() restricted to kept nodes, plus the
56// bridged edges produced by contracting removed nodes.
57//===----------------------------------------------------------------------===//
59{
60public:
64
66 void getSuccNodes(const ICFGNode* node, std::vector<const ICFGNode*>& out) const;
67
69 void getPredNodes(const ICFGNode* node, std::vector<const ICFGNode*>& out) const;
70
72 bool isKeptNode(const ICFGNode* node) const;
73
75 const ICFGNode* getFunEntry(const FunObjVar* fun) const;
76
78 const ICFGNode* getFunExit(const FunObjVar* fun) const;
79
81 void getFunICFGNodes(const FunObjVar* fun, std::vector<const ICFGNode*>& out) const;
82
85 {
86 return keptNodes;
87 }
88
92 {
93 auto it = bridgedEdges.find(n);
94 return it == bridgedEdges.end() ? nullptr : &it->second;
95 }
97 {
98 auto it = bridgedPreds.find(n);
99 return it == bridgedPreds.end() ? nullptr : &it->second;
100 }
101
103 void dump(const std::string& filename) const;
104
106 inline ICFG* getOriginalICFG() const
107 {
108 return icfg;
109 }
110
111private:
115 // Reverse of bridgedEdges (dst -> srcs), so getPredNodes is O(preds) instead
116 // of scanning every bridged edge.
119
121 void buildBridgedEdges();
122 static void getLocalSuccessors(
123 const ICFGNode* node,
125 std::vector<const ICFGNode*>& successors);
126};
127
128//===----------------------------------------------------------------------===//
129// SlicedPAGView - a sliced view of the PAG, built from the kept statements.
130//===----------------------------------------------------------------------===//
132{
133public:
135
138 {
139 return keptStmts;
140 }
141
143 inline const Set<NodeID>& getKeptNodeIds() const
144 {
145 return keptNodeIds;
146 }
147
150 inline bool isKeptStmt(const SVFStmt* s) const
151 {
152 return keptStmts.count(s) > 0;
153 }
154
156 inline SVFIR* getSVFIR() const
157 {
158 return pag;
159 }
160
162 void dump(const std::string& filename) const;
163
164private:
167 Set<NodeID> keptNodeIds; // node IDs extracted from kept statements
168
169 void buildKeptNodeIds();
170};
171
172//===----------------------------------------------------------------------===//
173// SlicedThreadCallGraphView - sliced view of the ThreadCallGraph, built from the
174// kept functions.
175//===----------------------------------------------------------------------===//
177{
178public:
182
184 void getOutEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
185
187 void getInEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
188
191 std::vector<const CallICFGNode*>& out) const;
193 std::vector<const CallICFGNode*>& out) const;
194
197 const CallICFGNode* callSite) const;
198
202
206 std::vector<const CallGraphEdge*>& out) const;
208 std::vector<const CallGraphEdge*>& out) const;
209
211 bool isKeptNode(const CallGraphNode* node) const;
212
215 {
216 return keptNodes;
217 }
218
220 {
221 return keptFunctionsSet;
222 }
223
226 inline bool isKeptEdge(const CallGraphEdge* e) const
227 {
228 return keptEdges.find(e) != keptEdges.end();
229 }
230
236
238 void dump(const std::string& filename) const;
239
243 {
244 return tcg;
245 }
246
247private:
255 OrderedSet<const ICFGNode*> extendedKeptNodes; // For checking if call sites are kept
256
257 void buildKeptNodes();
258 void buildCallGraphSets();
259};
260
261//===----------------------------------------------------------------------===//
262// SlicedSVFGView - non-owning exact node-induced view of an SVFG.
263// Membership is supplied as an explicit node-ID set; an edge is visible iff
264// both endpoints are retained. There are deliberately no bridge edges, since
265// bridging would fabricate value-flow paths.
266//===----------------------------------------------------------------------===//
268{
269public:
272
274 bool isKeptNode(const SVFGNode* n) const;
275
277 inline bool isKeptEdge(const SVFGEdge* e) const
278 {
279 return isKeptNode(e->getSrcNode()) && isKeptNode(e->getDstNode());
280 }
281
282 inline const SVFG* getSVFG() const
283 {
284 return svfg;
285 }
286 size_t getKeptNodeCount() const;
287
289 void dump(const std::string& filename) const;
290
291private:
292 const SVFG* svfg = nullptr;
294};
295
296//===----------------------------------------------------------------------===//
297// SlicedSVFIRView - unified facade over the three sliced graph views.
298// The MTA pipeline always slices over a ThreadCallGraph.
299//===----------------------------------------------------------------------===//
301{
302public:
304 ThreadCallGraph& callGraph,
305 ICFG* icfg,
307
309 inline const SlicedICFGView* getICFG() const
310 {
311 return icfgView.get();
312 }
314 {
315 return icfgView.get();
316 }
317
319 inline const SlicedPAGView* getPAG() const
320 {
322 return pagView.get();
323 }
325 {
327 return pagView.get();
328 }
329
332 {
333 return tcgView.get();
334 }
336 {
337 return tcgView.get();
338 }
339
342 {
343 return tcgView->getKeptFunctions();
344 }
345
348 {
349 return tcgView->getIndirectSitesWithEmptyTargets();
350 }
351
354 {
355 return getPAG()->getKeptStmts();
356 }
357
359 void dumpAll(const std::string& prefix) const;
360
362 inline SVFIR* getSVFIR() const
363 {
364 return svfir;
365 }
366
368 void dumpStats(const std::string& prefix = "") const;
369
370private:
371 void ensurePAGView() const;
372
374 std::unique_ptr<SlicedICFGView> icfgView;
375 mutable std::unique_ptr<SlicedPAGView> pagView;
376 std::unique_ptr<SlicedThreadCallGraphView> tcgView;
377};
378
379//===----------------------------------------------------------------------===//
380// GenericGraphTraits for the sliced leaf views. The views do NOT inherit
381// GenericGraph (they are non-owning); these stateless specializations make them
382// usable with SVF's generic graph algorithms and GraphWriter. The NodeRef is a
383// light value carrying (view, raw-node) so the same raw node under two different
384// slices is a distinct node. (Kept in this header next to the views, as ICFG.h
385// keeps GenericGraphTraits<ICFG*>.)
386//===----------------------------------------------------------------------===//
387
388// Contextual value NodeRef: a raw node paired with the view it is viewed under.
389template <class ViewT, class RawNodeT>
391{
392 const ViewT* view = nullptr;
393 const RawNodeT* raw = nullptr;
394
395 SlicedNodeRef() = default;
396 SlicedNodeRef(const ViewT* v, const RawNodeT* r) : view(v), raw(r) {}
397
398 explicit operator bool() const
399 {
400 return raw != nullptr;
401 }
402
404 {
405 return lhs.view == rhs.view && lhs.raw == rhs.raw;
406 }
408 {
409 return !(lhs == rhs);
410 }
411};
412
414
415// A sliced ICFG edge. underlying==nullptr && bridged==true for synthetic bridges.
423
424// Forward/reverse child-edge iterator over a kept node: first its kept original
425// edges, then its bridged edges. Forward==true walks out-edges/bridgedSuccs;
426// Forward==false walks in-edges/bridgedPreds. A standard forward iterator.
427template <bool Forward>
429{
430public:
431 using iterator_category = std::forward_iterator_tag;
433 using difference_type = std::ptrdiff_t;
436
438
440 {
442 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
443 it.realIt = edges.begin();
444 it.realEnd = edges.end();
445 it.bridged = Forward ? v->bridgedSuccsOf(n) : v->bridgedPredsOf(n);
446 it.brIt = it.bridged ? it.bridged->begin() : emptySet().begin();
447 it.brEnd = it.bridged ? it.bridged->end() : emptySet().end();
448 it.skipNonKeptReal();
449 it.refresh();
450 return it;
451 }
453 {
455 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
456 it.realIt = edges.end();
457 it.realEnd = edges.end();
458 it.bridged = Forward ? v->bridgedSuccsOf(n) : v->bridgedPredsOf(n);
459 it.brIt = it.bridged ? it.bridged->end() : emptySet().end();
460 it.brEnd = it.bridged ? it.bridged->end() : emptySet().end();
461 return it;
462 }
463
465 {
466 return cur;
467 }
469 {
470 return &cur;
471 }
472
473 // The node this edge traverses to (successor for Forward, predecessor for Inverse).
475 {
476 return Forward ? cur.dst : cur.src;
477 }
478
480 {
481 if (realIt != realEnd)
482 {
483 ++realIt;
485 }
486 else if (brIt != brEnd)
487 {
488 ++brIt;
489 }
490 refresh();
491 return *this;
492 }
494 {
495 SlicedICFGEdgeIterImpl t = *this;
496 ++*this;
497 return t;
498 }
499
501 {
502 return a.view == b.view && a.src == b.src && a.realIt == b.realIt && a.brIt == b.brIt;
503 }
505 {
506 return !(a == b);
507 }
508
509private:
512
513 const SlicedICFGView* view = nullptr;
514 const ICFGNode* src = nullptr;
519
521
523 {
524 static const OrderedSet<const ICFGNode*> e;
525 return e;
526 }
527 static const ICFGNode* other(const ICFGEdge* e)
528 {
529 return Forward ? e->getDstNode() : e->getSrcNode();
530 }
532 {
533 while (realIt != realEnd && !view->isKeptNode(other(*realIt))) ++realIt;
534 }
535 void refresh()
536 {
537 if (realIt != realEnd)
538 {
539 const ICFGEdge* e = *realIt;
541 cur = SlicedICFGEdgeRef{a, b, e, false};
542 }
543 else if (brIt != brEnd)
544 {
546 cur = Forward ? SlicedICFGEdgeRef{self, adj, nullptr, true}
547 :
548 SlicedICFGEdgeRef{adj, self, nullptr, true};
549 }
550 else
551 {
553 }
554 }
555};
556
557// Node-child iterator: adapts the edge iterator, dereferencing to the traversed
558// node; currentEdge() exposes the domain edge (for bridged-aware DOT styling).
559template <bool Forward>
561{
562public:
563 using iterator_category = std::forward_iterator_tag;
565 using difference_type = std::ptrdiff_t;
568
571
573 {
574 return e.target();
575 }
577 {
578 return *e;
579 }
580
582 {
583 ++e;
584 return *this;
585 }
587 {
588 SlicedICFGChildIterImpl t = *this;
589 ++e;
590 return t;
591 }
592
594 {
595 return a.e == b.e;
596 }
598 {
599 return !(a == b);
600 }
601
602private:
604};
605
606// Node iterator over the kept-node set, yielding contextual NodeRefs.
608{
609public:
610 using iterator_category = std::forward_iterator_tag;
612 using difference_type = std::ptrdiff_t;
615
619
621 {
622 return SlicedICFGNodeRef{view, *it};
623 }
625 {
626 ++it;
627 return *this;
628 }
630 {
631 SlicedICFGNodeIter t = *this;
632 ++it;
633 return t;
634 }
635
637 {
638 return a.view == b.view && a.it == b.it;
639 }
641 {
642 return !(a == b);
643 }
644
645private:
646 const SlicedICFGView* view = nullptr;
648};
649
650//===----------------------------------------------------------------------===//
651// SlicedThreadCallGraphView traits support (no bridged edges; canonical
652// adjacency is the kept-edge set, so pruned-call-site edges never appear).
653//===----------------------------------------------------------------------===//
654
656
663
664// Forward==true walks kept out-edges; Forward==false walks kept in-edges. Join
665// edges are not part of the node's normal adjacency, so they never appear here.
666template <bool Forward>
668{
669public:
670 using iterator_category = std::forward_iterator_tag;
672 using difference_type = std::ptrdiff_t;
675
677
679 {
681 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
682 it.realIt = edges.begin();
683 it.realEnd = edges.end();
684 it.skipNonKept();
685 it.refresh();
686 return it;
687 }
689 {
691 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
692 it.realIt = edges.end();
693 it.realEnd = edges.end();
694 return it;
695 }
696
698 {
699 return cur;
700 }
702 {
703 return &cur;
704 }
706 {
707 return Forward ? cur.dst : cur.src;
708 }
709
711 {
712 if (realIt != realEnd)
713 {
714 ++realIt;
715 skipNonKept();
716 }
717 refresh();
718 return *this;
719 }
721 {
722 SlicedCGEdgeIterImpl t = *this;
723 ++*this;
724 return t;
725 }
726
728 {
729 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
730 }
732 {
733 return !(a == b);
734 }
735
736private:
739 const CallGraphNode* src = nullptr;
742
744
746 {
747 while (realIt != realEnd && !view->isKeptEdge(*realIt)) ++realIt;
748 }
749 void refresh()
750 {
751 if (realIt != realEnd)
752 {
753 const CallGraphEdge* e = *realIt;
755 }
756 else
757 {
759 }
760 }
761};
762
763template <bool Forward>
765{
766public:
767 using iterator_category = std::forward_iterator_tag;
769 using difference_type = std::ptrdiff_t;
772
775
777 {
778 return e.target();
779 }
781 {
782 return *e;
783 }
785 {
786 ++e;
787 return *this;
788 }
790 {
791 SlicedCGChildIterImpl t = *this;
792 ++e;
793 return t;
794 }
796 {
797 return a.e == b.e;
798 }
800 {
801 return !(a == b);
802 }
803
804private:
806};
807
809{
810public:
811 using iterator_category = std::forward_iterator_tag;
813 using difference_type = std::ptrdiff_t;
816
817 SlicedCGNodeIter() = default;
820
822 {
824 }
826 {
827 ++it;
828 return *this;
829 }
831 {
832 SlicedCGNodeIter t = *this;
833 ++it;
834 return t;
835 }
836 friend bool operator==(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
837 {
838 return a.view == b.view && a.it == b.it;
839 }
840 friend bool operator!=(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
841 {
842 return !(a == b);
843 }
844
845private:
848};
849
850//===----------------------------------------------------------------------===//
851// SlicedPAGView traits support. Nodes are the SVFVars touched by kept statements;
852// edges are the kept SVFStmts (a kept var may have non-kept incident statements,
853// so keptStmts membership is the canonical filter). MultiOpndStmts use the
854// underlying SVFStmt src/dst (first operand -> result), not an operand fan-out.
855//===----------------------------------------------------------------------===//
856
858
865
866template <bool Forward>
868{
869public:
870 using iterator_category = std::forward_iterator_tag;
872 using difference_type = std::ptrdiff_t;
873 using pointer = const SlicedPAGEdgeRef*;
875
877
879 {
881 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
882 it.realIt = edges.begin();
883 it.realEnd = edges.end();
884 it.skipNonKept();
885 it.refresh();
886 return it;
887 }
889 {
891 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
892 it.realIt = edges.end();
893 it.realEnd = edges.end();
894 return it;
895 }
896
898 {
899 return cur;
900 }
902 {
903 return &cur;
904 }
906 {
907 return Forward ? cur.dst : cur.src;
908 }
909
911 {
912 if (realIt != realEnd)
913 {
914 ++realIt;
915 skipNonKept();
916 }
917 refresh();
918 return *this;
919 }
921 {
922 SlicedPAGEdgeIterImpl t = *this;
923 ++*this;
924 return t;
925 }
926
928 {
929 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
930 }
932 {
933 return !(a == b);
934 }
935
936private:
938 const SlicedPAGView* view = nullptr;
939 const SVFVar* src = nullptr;
942
944
946 {
947 while (realIt != realEnd && !view->isKeptStmt(*realIt)) ++realIt;
948 }
949 void refresh()
950 {
951 if (realIt != realEnd)
952 {
953 const SVFStmt* s = *realIt;
954 cur = SlicedPAGEdgeRef{{view, s->getSrcNode()}, {view, s->getDstNode()}, s};
955 }
956 else
957 {
959 }
960 }
961};
962
963template <bool Forward>
965{
966public:
967 using iterator_category = std::forward_iterator_tag;
969 using difference_type = std::ptrdiff_t;
970 using pointer = const SlicedPAGNodeRef*;
972
975
977 {
978 return e.target();
979 }
981 {
982 return *e;
983 }
985 {
986 ++e;
987 return *this;
988 }
990 {
991 SlicedPAGChildIterImpl t = *this;
992 ++e;
993 return t;
994 }
996 {
997 return a.e == b.e;
998 }
1000 {
1001 return !(a == b);
1002 }
1003
1004private:
1006};
1007
1008// Node iterator over the kept SVFVar ids (resolved against the SVFIR).
1010{
1011public:
1012 using iterator_category = std::forward_iterator_tag;
1014 using difference_type = std::ptrdiff_t;
1017
1021
1023 {
1025 }
1027 {
1028 ++it;
1029 return *this;
1030 }
1032 {
1033 SlicedPAGNodeIter t = *this;
1034 ++it;
1035 return t;
1036 }
1038 {
1039 return a.view == b.view && a.it == b.it;
1040 }
1042 {
1043 return !(a == b);
1044 }
1045
1046private:
1047 const SlicedPAGView* view = nullptr;
1049};
1050
1051//===----------------------------------------------------------------------===//
1052// SlicedSVFGView traits support (no bridged edges; membership is the view's
1053// retained-node rule, so removed nodes never enter SCC/worklist traversal).
1054//===----------------------------------------------------------------------===//
1055
1057
1064
1065// Forward==true walks kept out-edges; Forward==false walks kept in-edges.
1066template <bool Forward>
1068{
1069public:
1070 using iterator_category = std::forward_iterator_tag;
1072 using difference_type = std::ptrdiff_t;
1075
1077
1079 {
1081 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
1082 it.realIt = edges.begin();
1083 it.realEnd = edges.end();
1084 it.skipNonKept();
1085 it.refresh();
1086 return it;
1087 }
1089 {
1091 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
1092 it.realIt = edges.end();
1093 it.realEnd = edges.end();
1094 return it;
1095 }
1096
1098 {
1099 return cur;
1100 }
1102 {
1103 return &cur;
1104 }
1106 {
1107 return Forward ? cur.dst : cur.src;
1108 }
1109
1111 {
1112 if (realIt != realEnd)
1113 {
1114 ++realIt;
1115 skipNonKept();
1116 }
1117 refresh();
1118 return *this;
1119 }
1121 {
1122 SlicedSVFGEdgeIterImpl t = *this;
1123 ++*this;
1124 return t;
1125 }
1126
1128 {
1129 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
1130 }
1132 {
1133 return !(a == b);
1134 }
1135
1136private:
1138 const SlicedSVFGView* view = nullptr;
1139 const SVFGNode* src = nullptr;
1142
1144
1146 {
1147 while (realIt != realEnd &&
1148 !view->isKeptNode(Forward ? (*realIt)->getDstNode() : (*realIt)->getSrcNode()))
1149 ++realIt;
1150 }
1151 void refresh()
1152 {
1153 if (realIt != realEnd)
1154 {
1155 const SVFGEdge* e = *realIt;
1156 cur = SlicedSVFGEdgeRef{{view, e->getSrcNode()}, {view, e->getDstNode()}, e};
1157 }
1158 else
1159 {
1161 }
1162 }
1163};
1164
1165template <bool Forward>
1167{
1168public:
1169 using iterator_category = std::forward_iterator_tag;
1171 using difference_type = std::ptrdiff_t;
1174
1177
1179 {
1180 return e.target();
1181 }
1183 {
1184 return *e;
1185 }
1187 {
1188 ++e;
1189 return *this;
1190 }
1192 {
1193 SlicedSVFGChildIterImpl t = *this;
1194 ++e;
1195 return t;
1196 }
1198 {
1199 return a.e == b.e;
1200 }
1202 {
1203 return !(a == b);
1204 }
1205
1206private:
1208};
1209
1210// Node iterator: filters the underlying SVFG's node map by the retained rule.
1212{
1213public:
1214 using iterator_category = std::forward_iterator_tag;
1216 using difference_type = std::ptrdiff_t;
1219
1226
1228 {
1229 return SlicedSVFGNodeRef{view, it->second};
1230 }
1232 {
1233 ++it;
1234 skipNonKept();
1235 return *this;
1236 }
1238 {
1239 SlicedSVFGNodeIter t = *this;
1240 ++*this;
1241 return t;
1242 }
1244 {
1245 return a.view == b.view && a.it == b.it;
1246 }
1248 {
1249 return !(a == b);
1250 }
1251
1252private:
1253 const SlicedSVFGView* view = nullptr;
1256 {
1257 while (it != endIt && !view->isKeptNode(it->second)) ++it;
1258 }
1259};
1260
1261} // End namespace SVF
1262
1263//===----------------------------------------------------------------------===//
1264// Traits specializations must be at namespace SVF scope too (that is where the
1265// GenericGraphTraits primary template and Inverse live).
1266//===----------------------------------------------------------------------===//
1267namespace SVF
1268{
1269
1270// Forward traits for SlicedICFGView.
1271template <>
1273{
1279
1280 // Escape hatch to the underlying node so graph-generic algorithms can reach
1281 // domain data (getFun/getSVFStmts) uniformly. Full-ICFG traits return the node.
1283 {
1284 return n.raw;
1285 }
1286
1287 // Graph-intrinsic queries mirroring GenericGraphTraits<ICFG*>, so a
1288 // graph-parameterised analysis resolves the right behaviour from the type.
1290 static const ICFGNode* getFunEntry(const SlicedICFGView* g, const FunObjVar* fun)
1291 {
1292 return g->getFunEntry(fun);
1293 }
1294 static const ICFGNode* getFunExit(const SlicedICFGView* g, const FunObjVar* fun)
1295 {
1296 return g->getFunExit(fun);
1297 }
1298 static void getFunICFGNodes(const SlicedICFGView* g, const FunObjVar* fun,
1299 std::vector<const ICFGNode*>& out)
1300 {
1301 g->getFunICFGNodes(fun, out);
1302 }
1303 static void getSuccNodes(const SlicedICFGView* g, const ICFGNode* n,
1304 std::vector<const ICFGNode*>& out)
1305 {
1306 g->getSuccNodes(n, out);
1307 }
1308 static void getPredNodes(const SlicedICFGView* g, const ICFGNode* n,
1309 std::vector<const ICFGNode*>& out)
1310 {
1311 g->getPredNodes(n, out);
1312 }
1313 static bool containsNode(const SlicedICFGView* g, const ICFGNode* n)
1314 {
1315 return g->isKeptNode(n);
1316 }
1318
1320 {
1321 return NodeRef{};
1322 }
1323
1325 {
1326 return SlicedICFGNodeIter(v, v->getKeptNodes().begin());
1327 }
1329 {
1330 return SlicedICFGNodeIter(v, v->getKeptNodes().end());
1331 }
1332
1334 {
1335 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1336 }
1338 {
1339 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1340 }
1342 {
1343 return child_begin(n);
1344 }
1346 {
1347 return child_end(n);
1348 }
1349
1351 {
1352 return ChildEdgeIteratorType::begin(n.view, n.raw);
1353 }
1355 {
1356 return ChildEdgeIteratorType::end(n.view, n.raw);
1357 }
1358
1359 static NodeRef edge_dest(const EdgeRef& e)
1360 {
1361 return e.dst;
1362 }
1363
1364 static unsigned graphSize(const SlicedICFGView* v)
1365 {
1366 return static_cast<unsigned>(v->getKeptNodes().size());
1367 }
1368 static inline unsigned getNodeID(NodeRef n)
1369 {
1370 return n.raw->getId();
1371 }
1373 {
1374 const ICFGNode* raw = v->getOriginalICFG()->getGNode(id);
1375 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1376 }
1377};
1378
1379// Inverse (reverse-traversal) traits for SlicedICFGView.
1380template <>
1382{
1387
1389 {
1390 return NodeRef{};
1391 }
1392
1394 {
1395 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1396 }
1398 {
1399 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1400 }
1401
1403 {
1404 return ChildEdgeIteratorType::begin(n.view, n.raw);
1405 }
1407 {
1408 return ChildEdgeIteratorType::end(n.view, n.raw);
1409 }
1410
1411 // Inverse: the traversed "child" is the predecessor -> the edge source.
1412 static NodeRef edge_dest(const EdgeRef& e)
1413 {
1414 return e.src;
1415 }
1416 static inline unsigned getNodeID(NodeRef n)
1417 {
1418 return n.raw->getId();
1419 }
1420};
1421
1422// Forward traits for SlicedThreadCallGraphView.
1423template <>
1425{
1431
1433 {
1434 return n.raw;
1435 }
1436
1437 // Graph-intrinsic queries mirroring GenericGraphTraits<CallGraph*>.
1440 std::vector<const CallGraphEdge*>& out)
1441 {
1442 g->getInEdgesOf(n, out);
1443 }
1445 std::vector<const CallGraphEdge*>& out)
1446 {
1447 g->getOutEdgesOf(n, out);
1448 }
1450 const CallGraphEdge* e,
1451 std::vector<const CallICFGNode*>& out)
1452 {
1453 g->getDirectCallsOf(e, out);
1454 }
1456 const CallGraphEdge* e,
1457 std::vector<const CallICFGNode*>& out)
1458 {
1459 g->getIndirectCallsOf(e, out);
1460 }
1462 const CallGraphEdge* e,
1463 const CallICFGNode* callSite)
1464 {
1465 return g->containsCallSite(e, callSite);
1466 }
1468 const CallICFGNode* callSite,
1470 {
1471 g->getCalleesOf(callSite, callees);
1472 }
1474 const CallICFGNode* callSite,
1475 std::vector<const CallGraphEdge*>& out)
1476 {
1477 g->getForkEdgesOf(callSite, out);
1478 }
1480 const CallICFGNode* callSite,
1481 std::vector<const CallGraphEdge*>& out)
1482 {
1483 g->getJoinEdgesOf(callSite, out);
1484 }
1486
1488 {
1489 return NodeRef{};
1490 }
1491
1493 {
1494 return SlicedCGNodeIter(v, v->getKeptNodes().begin());
1495 }
1497 {
1498 return SlicedCGNodeIter(v, v->getKeptNodes().end());
1499 }
1500
1502 {
1503 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1504 }
1506 {
1507 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1508 }
1510 {
1511 return child_begin(n);
1512 }
1514 {
1515 return child_end(n);
1516 }
1517
1519 {
1520 return ChildEdgeIteratorType::begin(n.view, n.raw);
1521 }
1523 {
1524 return ChildEdgeIteratorType::end(n.view, n.raw);
1525 }
1526
1527 static NodeRef edge_dest(const EdgeRef& e)
1528 {
1529 return e.dst;
1530 }
1531
1532 static unsigned graphSize(const SlicedThreadCallGraphView* v)
1533 {
1534 return static_cast<unsigned>(v->getKeptNodes().size());
1535 }
1536 static inline unsigned getNodeID(NodeRef n)
1537 {
1538 return n.raw->getId();
1539 }
1541 {
1542 const CallGraphNode* raw = v->getBackingCallGraph()->getGNode(id);
1543 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1544 }
1545};
1546
1547// Inverse traits for SlicedThreadCallGraphView.
1548template <>
1550{
1555
1560
1562 {
1563 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1564 }
1566 {
1567 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1568 }
1570 {
1571 return ChildEdgeIteratorType::begin(n.view, n.raw);
1572 }
1574 {
1575 return ChildEdgeIteratorType::end(n.view, n.raw);
1576 }
1577
1578 static NodeRef edge_dest(const EdgeRef& e)
1579 {
1580 return e.src;
1581 }
1582 static inline unsigned getNodeID(NodeRef n)
1583 {
1584 return n.raw->getId();
1585 }
1586};
1587
1588// Forward traits for SlicedPAGView.
1589template <>
1591{
1597
1599 {
1600 return n.raw;
1601 }
1602
1604 {
1605 return NodeRef{};
1606 }
1607
1609 {
1610 return SlicedPAGNodeIter(v, v->getKeptNodeIds().begin());
1611 }
1613 {
1614 return SlicedPAGNodeIter(v, v->getKeptNodeIds().end());
1615 }
1616
1618 {
1619 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1620 }
1622 {
1623 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1624 }
1626 {
1627 return child_begin(n);
1628 }
1630 {
1631 return child_end(n);
1632 }
1633
1635 {
1636 return ChildEdgeIteratorType::begin(n.view, n.raw);
1637 }
1639 {
1640 return ChildEdgeIteratorType::end(n.view, n.raw);
1641 }
1642
1643 static NodeRef edge_dest(const EdgeRef& e)
1644 {
1645 return e.dst;
1646 }
1647
1648 static unsigned graphSize(const SlicedPAGView* v)
1649 {
1650 return static_cast<unsigned>(v->getKeptNodeIds().size());
1651 }
1652 static inline unsigned getNodeID(NodeRef n)
1653 {
1654 return n.raw->getId();
1655 }
1657 {
1658 const bool kept = v->getKeptNodeIds().count(id) > 0;
1659 return NodeRef{v, kept ? v->getSVFIR()->getGNode(id) : nullptr};
1660 }
1661};
1662
1663// Inverse traits for SlicedPAGView.
1664template <>
1666{
1671
1673 {
1674 return NodeRef{};
1675 }
1676
1678 {
1679 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1680 }
1682 {
1683 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1684 }
1686 {
1687 return ChildEdgeIteratorType::begin(n.view, n.raw);
1688 }
1690 {
1691 return ChildEdgeIteratorType::end(n.view, n.raw);
1692 }
1693
1694 static NodeRef edge_dest(const EdgeRef& e)
1695 {
1696 return e.src;
1697 }
1698 static inline unsigned getNodeID(NodeRef n)
1699 {
1700 return n.raw->getId();
1701 }
1702};
1703
1704// Forward traits for SlicedSVFGView.
1705template <>
1707{
1713 static constexpr bool isFilteredGraph = true;
1714
1716 {
1717 return n.raw;
1718 }
1719
1721 static bool containsNode(const SlicedSVFGView* g, const SVFGNode* n)
1722 {
1723 return g->isKeptNode(n);
1724 }
1725
1726 static bool containsEdge(const SlicedSVFGView* g, const SVFGEdge* e)
1727 {
1728 return g->isKeptEdge(e);
1729 }
1730
1732 {
1733 return NodeRef{};
1734 }
1735
1737 {
1738 assert(v->getSVFG() && "SlicedSVFGView: bind the SVFG before iterating nodes");
1739 return SlicedSVFGNodeIter(v, v->getSVFG()->begin(), v->getSVFG()->end());
1740 }
1742 {
1743 assert(v->getSVFG() && "SlicedSVFGView: bind the SVFG before iterating nodes");
1744 return SlicedSVFGNodeIter(v, v->getSVFG()->end(), v->getSVFG()->end());
1745 }
1746
1748 {
1749 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1750 }
1752 {
1753 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1754 }
1756 {
1757 return child_begin(n);
1758 }
1760 {
1761 return child_end(n);
1762 }
1763
1765 {
1766 return ChildEdgeIteratorType::begin(n.view, n.raw);
1767 }
1769 {
1770 return ChildEdgeIteratorType::end(n.view, n.raw);
1771 }
1772
1773 static NodeRef edge_dest(const EdgeRef& e)
1774 {
1775 return e.dst;
1776 }
1777 static inline unsigned getNodeID(NodeRef n)
1778 {
1779 return n.raw->getId();
1780 }
1781 static unsigned graphSize(const SlicedSVFGView* v)
1782 {
1783 return static_cast<unsigned>(v->getKeptNodeCount());
1784 }
1786 {
1787 const SVFGNode* raw =
1788 (v->getSVFG() != nullptr) ? v->getSVFG()->getGNode(id) : nullptr;
1789 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1790 }
1791};
1792
1793// Inverse traits for SlicedSVFGView.
1794template <>
1796{
1801
1803 {
1804 return NodeRef{};
1805 }
1806
1808 {
1809 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1810 }
1812 {
1813 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1814 }
1816 {
1817 return ChildEdgeIteratorType::begin(n.view, n.raw);
1818 }
1820 {
1821 return ChildEdgeIteratorType::end(n.view, n.raw);
1822 }
1823
1824 static NodeRef edge_dest(const EdgeRef& e)
1825 {
1826 return e.src;
1827 }
1828 static inline unsigned getNodeID(NodeRef n)
1829 {
1830 return n.raw->getId();
1831 }
1832};
1833
1834} // End namespace SVF
1835
1836#endif // GRAPHS_SLICEDGRAPHS_H
cJSON * a
Definition cJSON.cpp:2560
cJSON * n
Definition cJSON.cpp:2558
const cJSON *const b
Definition cJSON.h:255
const char *const const char *const raw
Definition cJSON.h:270
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
NodeType * getSrcNode() const
NodeType * getDstNode() const
IDToNodeMapTy::const_iterator const_iterator
NodeType * getGNode(NodeID id) const
Get a node.
GEdgeSetTy::const_iterator const_iterator
ICFGEdge::ICFGEdgeSetTy::const_iterator const_iterator
Definition ICFGNode.h:61
SlicedCGEdgeIterImpl< Forward > e
reference operator*() const
SlicedCGChildIterImpl operator++(int)
std::forward_iterator_tag iterator_category
const SlicedCallGraphEdgeRef & currentEdge() const
friend bool operator!=(const SlicedCGChildIterImpl &a, const SlicedCGChildIterImpl &b)
SlicedCGChildIterImpl & operator++()
SlicedCGChildIterImpl(SlicedCGEdgeIterImpl< Forward > it)
std::ptrdiff_t difference_type
friend bool operator==(const SlicedCGChildIterImpl &a, const SlicedCGChildIterImpl &b)
SlicedCGEdgeIterImpl(const SlicedThreadCallGraphView *v, const CallGraphNode *n)
reference operator*() const
pointer operator->() const
SlicedCallGraphEdgeRef cur
SlicedCallGraphNodeRef target() const
static SlicedCGEdgeIterImpl end(const SlicedThreadCallGraphView *v, const CallGraphNode *n)
const CallGraphNode * src
friend bool operator!=(const SlicedCGEdgeIterImpl &a, const SlicedCGEdgeIterImpl &b)
friend bool operator==(const SlicedCGEdgeIterImpl &a, const SlicedCGEdgeIterImpl &b)
const SlicedThreadCallGraphView * view
CallGraphNode::const_iterator EdgeIt
std::forward_iterator_tag iterator_category
SlicedCGEdgeIterImpl & operator++()
SlicedCGEdgeIterImpl operator++(int)
static SlicedCGEdgeIterImpl begin(const SlicedThreadCallGraphView *v, const CallGraphNode *n)
std::ptrdiff_t difference_type
SlicedCGNodeIter & operator++()
std::forward_iterator_tag iterator_category
OrderedSet< constCallGraphNode * >::const_iterator it
SlicedCGNodeIter()=default
reference operator*() const
const SlicedThreadCallGraphView * view
friend bool operator!=(const SlicedCGNodeIter &a, const SlicedCGNodeIter &b)
friend bool operator==(const SlicedCGNodeIter &a, const SlicedCGNodeIter &b)
SlicedCGNodeIter operator++(int)
std::ptrdiff_t difference_type
SlicedCGNodeIter(const SlicedThreadCallGraphView *v, OrderedSet< const CallGraphNode * >::const_iterator i)
SlicedICFGChildIterImpl operator++(int)
const SlicedICFGEdgeRef & currentEdge() const
friend bool operator==(const SlicedICFGChildIterImpl &a, const SlicedICFGChildIterImpl &b)
std::forward_iterator_tag iterator_category
SlicedICFGChildIterImpl & operator++()
reference operator*() const
friend bool operator!=(const SlicedICFGChildIterImpl &a, const SlicedICFGChildIterImpl &b)
SlicedICFGEdgeIterImpl< Forward > e
SlicedICFGChildIterImpl(SlicedICFGEdgeIterImpl< Forward > it)
static SlicedICFGEdgeIterImpl begin(const SlicedICFGView *v, const ICFGNode *n)
static const OrderedSet< const ICFGNode * > & emptySet()
const OrderedSet< const ICFGNode * > * bridged
friend bool operator!=(const SlicedICFGEdgeIterImpl &a, const SlicedICFGEdgeIterImpl &b)
SlicedICFGNodeRef target() const
OrderedSet< const ICFGNode * >::const_iterator BrIt
const SlicedICFGView * view
std::forward_iterator_tag iterator_category
ICFGNode::const_iterator EdgeIt
SlicedICFGEdgeIterImpl operator++(int)
static SlicedICFGEdgeIterImpl end(const SlicedICFGView *v, const ICFGNode *n)
reference operator*() const
SlicedICFGEdgeIterImpl(const SlicedICFGView *v, const ICFGNode *n)
static const ICFGNode * other(const ICFGEdge *e)
SlicedICFGEdgeIterImpl & operator++()
friend bool operator==(const SlicedICFGEdgeIterImpl &a, const SlicedICFGEdgeIterImpl &b)
SlicedICFGNodeIter(const SlicedICFGView *v, OrderedSet< const ICFGNode * >::const_iterator i)
OrderedSet< constICFGNode * >::const_iterator it
std::ptrdiff_t difference_type
friend bool operator==(const SlicedICFGNodeIter &a, const SlicedICFGNodeIter &b)
SlicedICFGNodeIter & operator++()
const SlicedICFGView * view
std::forward_iterator_tag iterator_category
reference operator*() const
friend bool operator!=(const SlicedICFGNodeIter &a, const SlicedICFGNodeIter &b)
SlicedICFGNodeIter operator++(int)
const OrderedSet< const ICFGNode * > * bridgedPredsOf(const ICFGNode *n) const
const OrderedSet< const ICFGNode * > * bridgedSuccsOf(const ICFGNode *n) const
static void getLocalSuccessors(const ICFGNode *node, const Map< const ICFGNode *, const ICFGNode * > &callsiteReturnNodes, std::vector< const ICFGNode * > &successors)
const ICFGNode * getFunExit(const FunObjVar *fun) const
Kept synthetic exit node of fun, or null when fun is outside the view.
Set< const ICFGNode * > keptNodesSet
void getPredNodes(const ICFGNode *node, std::vector< const ICFGNode * > &out) const
Get predecessor nodes (including bridged edges)
Map< const ICFGNode *, OrderedSet< const ICFGNode * > > bridgedPreds
void dump(const std::string &filename) const
Dump sliced ICFG to dot file.
bool isKeptNode(const ICFGNode *node) const
Check if a node is in the sliced view.
void getSuccNodes(const ICFGNode *node, std::vector< const ICFGNode * > &out) const
Get successor nodes (including bridged edges)
Map< const ICFGNode *, OrderedSet< const ICFGNode * > > bridgedEdges
const OrderedSet< const ICFGNode * > & getKeptNodes() const
Get all kept nodes.
const ICFGNode * getFunEntry(const FunObjVar *fun) const
First kept node of fun's entry, or null when fun is outside the view.
void buildICFGSets(const OrderedSet< const ICFGNode * > &keepNodes)
void getFunICFGNodes(const FunObjVar *fun, std::vector< const ICFGNode * > &out) const
Kept ICFG nodes of fun.
OrderedSet< const ICFGNode * > keptNodes
ICFG * getOriginalICFG() const
Get original ICFG.
reference operator*() const
SlicedPAGChildIterImpl operator++(int)
SlicedPAGEdgeIterImpl< Forward > e
std::forward_iterator_tag iterator_category
const SlicedPAGEdgeRef & currentEdge() const
friend bool operator!=(const SlicedPAGChildIterImpl &a, const SlicedPAGChildIterImpl &b)
SlicedPAGChildIterImpl(SlicedPAGEdgeIterImpl< Forward > it)
friend bool operator==(const SlicedPAGChildIterImpl &a, const SlicedPAGChildIterImpl &b)
SlicedPAGChildIterImpl & operator++()
SVFVar::const_iterator EdgeIt
static SlicedPAGEdgeIterImpl end(const SlicedPAGView *v, const SVFVar *n)
SlicedPAGNodeRef target() const
friend bool operator==(const SlicedPAGEdgeIterImpl &a, const SlicedPAGEdgeIterImpl &b)
std::forward_iterator_tag iterator_category
friend bool operator!=(const SlicedPAGEdgeIterImpl &a, const SlicedPAGEdgeIterImpl &b)
SlicedPAGEdgeIterImpl & operator++()
static SlicedPAGEdgeIterImpl begin(const SlicedPAGView *v, const SVFVar *n)
const SlicedPAGView * view
reference operator*() const
std::ptrdiff_t difference_type
SlicedPAGEdgeIterImpl operator++(int)
SlicedPAGEdgeIterImpl(const SlicedPAGView *v, const SVFVar *n)
friend bool operator!=(const SlicedPAGNodeIter &a, const SlicedPAGNodeIter &b)
SlicedPAGNodeIter operator++(int)
std::ptrdiff_t difference_type
reference operator*() const
const SlicedPAGView * view
friend bool operator==(const SlicedPAGNodeIter &a, const SlicedPAGNodeIter &b)
Set< NodeID >::const_iterator it
std::forward_iterator_tag iterator_category
SlicedPAGNodeIter & operator++()
SlicedPAGNodeIter(const SlicedPAGView *v, Set< NodeID >::const_iterator i)
bool isKeptStmt(const SVFStmt *s) const
Set< NodeID > keptNodeIds
const Set< NodeID > & getKeptNodeIds() const
Node IDs (SVFVars) touched by the kept statements – the sliced PAG's nodes.
void dump(const std::string &filename) const
Dump the sliced PAG to a dot file.
OrderedSet< const SVFStmt * > keptStmts
const OrderedSet< const SVFStmt * > & getKeptStmts() const
Get all kept statements.
SVFIR * getSVFIR() const
The underlying SVFIR (to resolve node ids to SVFVars).
SlicedSVFGChildIterImpl(SlicedSVFGEdgeIterImpl< Forward > it)
const SlicedSVFGEdgeRef & currentEdge() const
SlicedSVFGChildIterImpl operator++(int)
SlicedSVFGEdgeIterImpl< Forward > e
std::forward_iterator_tag iterator_category
SlicedSVFGChildIterImpl & operator++()
friend bool operator==(const SlicedSVFGChildIterImpl &a, const SlicedSVFGChildIterImpl &b)
friend bool operator!=(const SlicedSVFGChildIterImpl &a, const SlicedSVFGChildIterImpl &b)
SVFGNode::const_iterator EdgeIt
SlicedSVFGEdgeIterImpl(const SlicedSVFGView *v, const SVFGNode *n)
SlicedSVFGEdgeIterImpl operator++(int)
SlicedSVFGEdgeIterImpl & operator++()
std::forward_iterator_tag iterator_category
friend bool operator!=(const SlicedSVFGEdgeIterImpl &a, const SlicedSVFGEdgeIterImpl &b)
SlicedSVFGNodeRef target() const
const SlicedSVFGView * view
reference operator*() const
friend bool operator==(const SlicedSVFGEdgeIterImpl &a, const SlicedSVFGEdgeIterImpl &b)
static SlicedSVFGEdgeIterImpl end(const SlicedSVFGView *v, const SVFGNode *n)
static SlicedSVFGEdgeIterImpl begin(const SlicedSVFGView *v, const SVFGNode *n)
SlicedSVFGNodeIter & operator++()
friend bool operator==(const SlicedSVFGNodeIter &a, const SlicedSVFGNodeIter &b)
friend bool operator!=(const SlicedSVFGNodeIter &a, const SlicedSVFGNodeIter &b)
SlicedSVFGNodeIter operator++(int)
const SlicedSVFGView * view
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
SlicedSVFGNodeIter(const SlicedSVFGView *v, SVFG::const_iterator i, SVFG::const_iterator e)
SVFG::const_iterator it
reference operator*() const
SVFG::const_iterator endIt
const SVFG * getSVFG() const
size_t getKeptNodeCount() const
bool isKeptNode(const SVFGNode *n) const
Whether the node is retained (see the class comment for the rule).
SlicedSVFGView(const SVFG *svfg, const NodeBS &retainedNodeIds)
bool isKeptEdge(const SVFGEdge *e) const
Whether the edge is retained: both endpoints kept (no bridges).
void dump(const std::string &filename) const
Dump the sliced SVFG (retained nodes/edges only) via GraphWriter.
const Set< const FunObjVar * > & getKeptFunctions() const
Get all kept functions.
const SlicedThreadCallGraphView * getThreadCallGraph() const
Get SlicedThreadCallGraphView.
SlicedPAGView * getPAG()
std::unique_ptr< SlicedPAGView > pagView
std::unique_ptr< SlicedThreadCallGraphView > tcgView
SVFIR * getSVFIR() const
Get original SVFIR.
void dumpAll(const std::string &prefix) const
Dump all views to files.
SlicedThreadCallGraphView * getThreadCallGraph()
const SlicedICFGView * getICFG() const
Get SlicedICFGView.
SlicedICFGView * getICFG()
std::unique_ptr< SlicedICFGView > icfgView
const SlicedPAGView * getPAG() const
Get SlicedPAGView.
void dumpStats(const std::string &prefix="") const
Output statistics.
const OrderedSet< const SVFStmt * > & getKeptStatements() const
Get all kept statements.
void ensurePAGView() const
const Set< const CallICFGNode * > & getIndirectSitesWithEmptyTargets() const
Get indirect call sites that lost all targets after filtering.
void getCalleesOf(const CallICFGNode *callSite, CallGraph::FunctionSet &callees) const
Retained callees of a callsite.
const OrderedSet< const CallGraphNode * > & getKeptNodes() const
Get all kept nodes.
void getDirectCallsOf(const CallGraphEdge *edge, std::vector< const CallICFGNode * > &out) const
Retained callsites carried by an aggregated call-graph edge.
bool isKeptNode(const CallGraphNode *node) const
Check if a node is in the sliced view.
void dump(const std::string &filename) const
Dump sliced ThreadCallGraph to dot file.
OrderedSet< const CallGraphNode * > keptNodes
Set< const CallGraphEdge * > keptEdges
bool containsCallSite(const CallGraphEdge *edge, const CallICFGNode *callSite) const
Whether this precise callsite-to-callee relation is retained.
void getIndirectCallsOf(const CallGraphEdge *edge, std::vector< const CallICFGNode * > &out) const
Set< const FunObjVar * > keptFunctionsSet
const Set< const CallICFGNode * > & getIndirectSitesWithEmptyTargets() const
Indirect call sites that lost all targets after filtering.
bool isKeptEdge(const CallGraphEdge *e) const
const Set< const FunObjVar * > & getKeptFunctions() const
Map< const CallGraphEdge *, CallGraphEdge::CallInstSet > keptDirectCalls
void getForkEdgesOf(const CallICFGNode *callSite, std::vector< const CallGraphEdge * > &out) const
void getOutEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get out edges of a node (only returns kept edges and target nodes)
Set< const CallICFGNode * > indirectSitesWithEmptyTargets
void getInEdgesOf(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
Get in edges of a node (only returns kept edges and source nodes)
void getJoinEdgesOf(const CallICFGNode *callSite, std::vector< const CallGraphEdge * > &out) const
CallGraph * getBackingCallGraph() const
Map< const CallGraphEdge *, CallGraphEdge::CallInstSet > keptIndirectCalls
OrderedSet< const ICFGNode * > extendedKeptNodes
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition VFGNode.h:55
for isBitcode
Definition BasicTypes.h:70
SlicedNodeRef< SlicedThreadCallGraphView, CallGraphNode > SlicedCallGraphNodeRef
SlicedNodeRef< SlicedSVFGView, SVFGNode > SlicedSVFGNodeRef
u32_t NodeID
Definition GeneralType.h:76
std::set< Key, Compare, Allocator > OrderedSet
Definition GeneralType.h:60
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
SlicedNodeRef< SlicedPAGView, SVFVar > SlicedPAGNodeRef
SlicedNodeRef< SlicedICFGView, ICFGNode > SlicedICFGNodeRef
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition GeneralType.h:51
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static NodeRef getEntryNode(Inverse< const SlicedICFGView * >)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static NodeRef getEntryNode(Inverse< const SlicedPAGView * >)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static NodeRef getEntryNode(Inverse< const SlicedSVFGView * >)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static NodeRef getEntryNode(Inverse< const SlicedThreadCallGraphView * >)
static NodeRef getNode(const SlicedICFGView *v, NodeID id)
static void getSuccNodes(const SlicedICFGView *g, const ICFGNode *n, std::vector< const ICFGNode * > &out)
static ChildIteratorType direct_child_begin(NodeRef n)
static nodes_iterator nodes_end(const SlicedICFGView *v)
SlicedICFGChildIterImpl< true > ChildIteratorType
SlicedICFGEdgeIterImpl< true > ChildEdgeIteratorType
static ChildIteratorType direct_child_end(NodeRef n)
static ChildIteratorType child_begin(NodeRef n)
static const ICFGNode * getRawNode(NodeRef n)
static void getPredNodes(const SlicedICFGView *g, const ICFGNode *n, std::vector< const ICFGNode * > &out)
static NodeRef getEntryNode(const SlicedICFGView *)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static void getFunICFGNodes(const SlicedICFGView *g, const FunObjVar *fun, std::vector< const ICFGNode * > &out)
static NodeRef edge_dest(const EdgeRef &e)
static const ICFGNode * getFunExit(const SlicedICFGView *g, const FunObjVar *fun)
static ChildIteratorType child_end(NodeRef n)
static const ICFGNode * getFunEntry(const SlicedICFGView *g, const FunObjVar *fun)
static nodes_iterator nodes_begin(const SlicedICFGView *v)
static bool containsNode(const SlicedICFGView *g, const ICFGNode *n)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static unsigned graphSize(const SlicedICFGView *v)
SlicedPAGEdgeIterImpl< true > ChildEdgeIteratorType
static ChildIteratorType direct_child_begin(NodeRef n)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static ChildIteratorType direct_child_end(NodeRef n)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static NodeRef getEntryNode(const SlicedPAGView *)
static const SVFVar * getRawNode(NodeRef n)
static unsigned graphSize(const SlicedPAGView *v)
static ChildIteratorType child_end(NodeRef n)
static NodeRef getNode(const SlicedPAGView *v, NodeID id)
static nodes_iterator nodes_end(const SlicedPAGView *v)
static NodeRef edge_dest(const EdgeRef &e)
SlicedPAGChildIterImpl< true > ChildIteratorType
static ChildIteratorType child_begin(NodeRef n)
static nodes_iterator nodes_begin(const SlicedPAGView *v)
static NodeRef getNode(const SlicedSVFGView *v, NodeID id)
static nodes_iterator nodes_end(const SlicedSVFGView *v)
static ChildIteratorType child_end(NodeRef n)
SlicedSVFGChildIterImpl< true > ChildIteratorType
static ChildIteratorType direct_child_end(NodeRef n)
static ChildIteratorType direct_child_begin(NodeRef n)
static const SVFGNode * getRawNode(NodeRef n)
static bool containsNode(const SlicedSVFGView *g, const SVFGNode *n)
Whether n is retained by this sliced SVFG (the solver's restriction test).
static NodeRef getEntryNode(const SlicedSVFGView *)
static ChildIteratorType child_begin(NodeRef n)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
SlicedSVFGEdgeIterImpl< true > ChildEdgeIteratorType
static nodes_iterator nodes_begin(const SlicedSVFGView *v)
static unsigned graphSize(const SlicedSVFGView *v)
static NodeRef edge_dest(const EdgeRef &e)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static bool containsEdge(const SlicedSVFGView *g, const SVFGEdge *e)
static nodes_iterator nodes_end(const SlicedThreadCallGraphView *v)
static void getForkEdges(const SlicedThreadCallGraphView *g, const CallICFGNode *callSite, std::vector< const CallGraphEdge * > &out)
static bool containsCallSite(const SlicedThreadCallGraphView *g, const CallGraphEdge *e, const CallICFGNode *callSite)
static void getIndirectCalls(const SlicedThreadCallGraphView *g, const CallGraphEdge *e, std::vector< const CallICFGNode * > &out)
static NodeRef getNode(const SlicedThreadCallGraphView *v, NodeID id)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static const CallGraphNode * getRawNode(NodeRef n)
static nodes_iterator nodes_begin(const SlicedThreadCallGraphView *v)
static void getDirectCalls(const SlicedThreadCallGraphView *g, const CallGraphEdge *e, std::vector< const CallICFGNode * > &out)
static void getJoinEdges(const SlicedThreadCallGraphView *g, const CallICFGNode *callSite, std::vector< const CallGraphEdge * > &out)
static void getCallees(const SlicedThreadCallGraphView *g, const CallICFGNode *callSite, CallGraph::FunctionSet &callees)
static unsigned graphSize(const SlicedThreadCallGraphView *v)
static void getInEdges(const SlicedThreadCallGraphView *g, const CallGraphNode *n, std::vector< const CallGraphEdge * > &out)
static void getOutEdges(const SlicedThreadCallGraphView *g, const CallGraphNode *n, std::vector< const CallGraphEdge * > &out)
static ChildEdgeIteratorType child_edge_end(NodeRef n)
static NodeRef getEntryNode(const SlicedThreadCallGraphView *)
SlicedCallGraphNodeRef src
const CallGraphEdge * underlying
SlicedCallGraphNodeRef dst
const ICFGEdge * underlying
SlicedICFGNodeRef dst
SlicedICFGNodeRef src
friend bool operator==(SlicedNodeRef lhs, SlicedNodeRef rhs)
SlicedNodeRef()=default
SlicedNodeRef(const ViewT *v, const RawNodeT *r)
friend bool operator!=(SlicedNodeRef lhs, SlicedNodeRef rhs)
const RawNodeT * raw
const ViewT * view
SlicedPAGNodeRef src
SlicedPAGNodeRef dst
const SVFStmt * underlying
SlicedSVFGNodeRef dst
SlicedSVFGNodeRef src
const SVFGEdge * underlying