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 * General non-owning sliced views of the ICFG, PAG, and (Thread)CallGraph, and
29 * their GenericGraphTraits specialisations, so a slice works with SVF's generic
30 * graph algorithms and GraphWriter.
31 */
32
33#ifndef GRAPHS_SLICEDGRAPHS_H
34#define GRAPHS_SLICEDGRAPHS_H
35
36#include "Graphs/ICFG.h"
37#include "Graphs/ICFGNode.h"
38#include "Graphs/ICFGEdge.h"
39#include "Graphs/CallGraph.h"
41#include "Graphs/SVFG.h"
42#include "Graphs/SVFGNode.h"
43#include "Graphs/GraphTraits.h"
44#include "SVFIR/SVFIR.h"
45#include "SVFIR/SVFStatements.h"
46#include "SVFIR/SVFVariables.h"
47#include <cstddef>
48#include <fstream>
49#include <iterator>
50#include <memory>
51#include <set>
52#include <string>
53#include <unordered_map>
54#include <unordered_set>
55#include <vector>
56#include <utility>
57
58namespace SVF
59{
60
61//===----------------------------------------------------------------------===//
62// SlicedICFGView - sliced view of the ICFG.
63// Provides getSuccNodes()/getPredNodes() restricted to kept nodes, plus the
64// bridged edges produced by contracting removed nodes.
65//===----------------------------------------------------------------------===//
67{
68public:
70 // buildBridged=false skips bridged-edge construction for views whose control
71 // flow is never walked (e.g. the FSPTA view, used only for isKeptNode).
76 bool buildBridged = true);
77
79 void getSuccNodes(const ICFGNode* node, std::vector<const ICFGNode*>& out) const;
80
82 void getPredNodes(const ICFGNode* node, std::vector<const ICFGNode*>& out) const;
83
85 bool isKeptNode(const ICFGNode* node) const;
86
89 const ICFGNode* getFunEntry(const FunObjVar* fun) const;
90
92 void getFunICFGNodes(const FunObjVar* fun, std::vector<const ICFGNode*>& out) const;
93
96 {
97 return keptNodes;
98 }
99
103 {
104 auto it = bridgedEdges.find(n);
105 return it == bridgedEdges.end() ? nullptr : &it->second;
106 }
108 {
109 auto it = bridgedPreds.find(n);
110 return it == bridgedPreds.end() ? nullptr : &it->second;
111 }
112
114 void dump(const std::string& filename) const;
115
117 inline ICFG* getOriginalICFG() const
118 {
119 return icfg;
120 }
121
122private:
127 // Reverse of bridgedEdges (dst -> srcs), so getPredNodes is O(preds) instead
128 // of scanning every bridged edge.
131
134 void buildBridgedEdges();
135};
136
137//===----------------------------------------------------------------------===//
138// SlicedPAGView - a sliced view of the PAG, built from the kept statements.
139//===----------------------------------------------------------------------===//
141{
142public:
144
147 {
148 return keptStmts;
149 }
150
152 inline const Set<NodeID>& getKeptNodeIds() const
153 {
154 return keptNodeIds;
155 }
156
159 inline bool isKeptStmt(const SVFStmt* s) const
160 {
161 return keptStmts.count(s) > 0;
162 }
163
165 inline SVFIR* getSVFIR() const
166 {
167 return pag;
168 }
169
171 void dump(const std::string& filename) const;
172
173private:
176 Set<NodeID> keptNodeIds; // node IDs extracted from kept statements
177
178 void buildKeptNodeIds();
179};
180
181//===----------------------------------------------------------------------===//
182// SlicedThreadCallGraphView - sliced view of the ThreadCallGraph, built from the
183// kept functions.
184//===----------------------------------------------------------------------===//
186{
187public:
191
193 void getOutEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
194
196 void getInEdgesOf(const CallGraphNode* node, std::vector<const CallGraphEdge*>& out) const;
197
199 bool isKeptNode(const CallGraphNode* node) const;
200
203 {
204 return keptNodes;
205 }
206
208 {
209 return keptFunctionsSet;
210 }
211
214 {
215 return keptEdges;
216 }
217
220 inline bool isKeptEdge(const CallGraphEdge* e) const
221 {
222 return keptEdges.find(const_cast<CallGraphEdge*>(e)) != keptEdges.end();
223 }
224
230
232 void dump(const std::string& filename) const;
233
236 {
237 return tcg;
238 }
239
242 {
243 return tcg;
244 }
245
246private:
252 OrderedSet<const ICFGNode*> extendedKeptNodes; // For checking if call sites are kept
253
254 void buildKeptNodes();
255 void buildCallGraphSets();
256};
257
258//===----------------------------------------------------------------------===//
259// SlicedSVFGView - non-owning sliced view of the (thread-aware) SVFG.
260// Retained nodes: everything except Load/Store statement nodes whose ICFG node
261// was sliced out; structural nodes (Addr/Copy/Gep, MSSA phi/mu/chi, call/return
262// boundaries) always remain so inter-procedural and memory-SSA flow is intact.
263// Deliberately NO bridge edges: bridging removed SVFG nodes could fabricate
264// value-flow paths that do not exist in the original graph. Removed nodes act
265// as propagation barriers (matching the sliced FSAM solve).
266//===----------------------------------------------------------------------===//
268{
269public:
272 explicit SlicedSVFGView(const SlicedICFGView* icfgView, const SVFG* svfg = nullptr)
273 : icfgView(icfgView), svfg(svfg) {}
274
276 bool isKeptNode(const SVFGNode* n) const;
277
279 inline bool isKeptEdge(const SVFGEdge* e) const
280 {
281 return isKeptNode(e->getSrcNode()) && isKeptNode(e->getDstNode());
282 }
283
284 inline const SlicedICFGView* getICFGView() const
285 {
286 return icfgView;
287 }
288 inline const SVFG* getSVFG() const
289 {
290 return svfg;
291 }
293 inline void setSVFG(const SVFG* g)
294 {
295 svfg = g;
296 }
297
299 void dump(const std::string& filename) const;
300
301private:
303 const SVFG* svfg;
304};
305
306//===----------------------------------------------------------------------===//
307// SlicedSVFIRView - unified facade over the three sliced graph views.
308// The MTA pipeline always slices over a ThreadCallGraph.
309//===----------------------------------------------------------------------===//
311{
312public:
314 CallGraph* cg,
315 ICFG* icfg,
317 bool buildBridged = true);
318
320 inline const SlicedICFGView* getICFG() const
321 {
322 return icfgView.get();
323 }
325 {
326 return icfgView.get();
327 }
328
330 inline const SlicedPAGView* getPAG() const
331 {
332 return pagView.get();
333 }
335 {
336 return pagView.get();
337 }
338
341 {
342 return tcgView.get();
343 }
345 {
346 return tcgView.get();
347 }
348
351 {
352 return tcgView->getKeptFunctions();
353 }
354
357 {
358 return tcgView->getIndirectSitesWithEmptyTargets();
359 }
360
363 {
364 return pagView->getKeptStmts();
365 }
366
370 std::vector<const CallGraphEdge*>& out) const;
371
374 const CallGraph* getAnalysisCallGraph() const;
375
377 void dumpAll(const std::string& prefix) const;
378
380 inline SVFIR* getSVFIR() const
381 {
382 return svfIr;
383 }
384
386 void dumpStats(const std::string& prefix = "") const;
387
388private:
390 std::unique_ptr<SlicedICFGView> icfgView;
391 std::unique_ptr<SlicedPAGView> pagView;
392 std::unique_ptr<SlicedThreadCallGraphView> tcgView;
393};
394
395//===----------------------------------------------------------------------===//
396// GenericGraphTraits for the sliced leaf views. The views do NOT inherit
397// GenericGraph (they are non-owning); these stateless specializations make them
398// usable with SVF's generic graph algorithms and GraphWriter. The NodeRef is a
399// light value carrying (view, raw-node) so the same raw node under two different
400// slices is a distinct node. (Kept in this header next to the views, as ICFG.h
401// keeps GenericGraphTraits<ICFG*>.)
402//===----------------------------------------------------------------------===//
403
404// Contextual value NodeRef: a raw node paired with the view it is viewed under.
405template <class ViewT, class RawNodeT>
407{
408 const ViewT* view = nullptr;
409 const RawNodeT* raw = nullptr;
410
411 SlicedNodeRef() = default;
412 SlicedNodeRef(const ViewT* v, const RawNodeT* r) : view(v), raw(r) {}
413
414 explicit operator bool() const
415 {
416 return raw != nullptr;
417 }
418
420 {
421 return lhs.view == rhs.view && lhs.raw == rhs.raw;
422 }
424 {
425 return !(lhs == rhs);
426 }
427};
428
430
431// A sliced ICFG edge. underlying==nullptr && bridged==true for synthetic bridges.
439
440// Forward/reverse child-edge iterator over a kept node: first its kept original
441// edges, then its bridged edges. Forward==true walks out-edges/bridgedSuccs;
442// Forward==false walks in-edges/bridgedPreds. A standard forward iterator.
443template <bool Forward>
445{
446public:
447 using iterator_category = std::forward_iterator_tag;
449 using difference_type = std::ptrdiff_t;
452
454
456 {
458 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
459 it.realIt = edges.begin();
460 it.realEnd = edges.end();
461 it.bridged = Forward ? v->bridgedSuccsOf(n) : v->bridgedPredsOf(n);
462 it.brIt = it.bridged ? it.bridged->begin() : emptySet().begin();
463 it.brEnd = it.bridged ? it.bridged->end() : emptySet().end();
464 it.skipNonKeptReal();
465 it.refresh();
466 return it;
467 }
469 {
471 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
472 it.realIt = edges.end();
473 it.realEnd = edges.end();
474 it.bridged = Forward ? v->bridgedSuccsOf(n) : v->bridgedPredsOf(n);
475 it.brIt = it.bridged ? it.bridged->end() : emptySet().end();
476 it.brEnd = it.bridged ? it.bridged->end() : emptySet().end();
477 return it;
478 }
479
481 {
482 return cur;
483 }
485 {
486 return &cur;
487 }
488
489 // The node this edge traverses to (successor for Forward, predecessor for Inverse).
491 {
492 return Forward ? cur.dst : cur.src;
493 }
494
496 {
497 if (realIt != realEnd)
498 {
499 ++realIt;
501 }
502 else if (brIt != brEnd)
503 {
504 ++brIt;
505 }
506 refresh();
507 return *this;
508 }
510 {
511 SlicedICFGEdgeIterImpl t = *this;
512 ++*this;
513 return t;
514 }
515
517 {
518 return a.view == b.view && a.src == b.src && a.realIt == b.realIt && a.brIt == b.brIt;
519 }
521 {
522 return !(a == b);
523 }
524
525private:
528
529 const SlicedICFGView* view = nullptr;
530 const ICFGNode* src = nullptr;
535
537
539 {
540 static const OrderedSet<const ICFGNode*> e;
541 return e;
542 }
543 static const ICFGNode* other(const ICFGEdge* e)
544 {
545 return Forward ? e->getDstNode() : e->getSrcNode();
546 }
548 {
549 while (realIt != realEnd && !view->isKeptNode(other(*realIt))) ++realIt;
550 }
551 void refresh()
552 {
553 if (realIt != realEnd)
554 {
555 const ICFGEdge* e = *realIt;
557 cur = SlicedICFGEdgeRef{a, b, e, false};
558 }
559 else if (brIt != brEnd)
560 {
562 cur = Forward ? SlicedICFGEdgeRef{self, adj, nullptr, true}
563 :
564 SlicedICFGEdgeRef{adj, self, nullptr, true};
565 }
566 else
567 {
569 }
570 }
571};
572
573// Node-child iterator: adapts the edge iterator, dereferencing to the traversed
574// node; currentEdge() exposes the domain edge (for bridged-aware DOT styling).
575template <bool Forward>
577{
578public:
579 using iterator_category = std::forward_iterator_tag;
581 using difference_type = std::ptrdiff_t;
584
587
589 {
590 return e.target();
591 }
593 {
594 return *e;
595 }
596
598 {
599 ++e;
600 return *this;
601 }
603 {
604 SlicedICFGChildIterImpl t = *this;
605 ++e;
606 return t;
607 }
608
610 {
611 return a.e == b.e;
612 }
614 {
615 return !(a == b);
616 }
617
618private:
620};
621
622// Node iterator over the kept-node set, yielding contextual NodeRefs.
624{
625public:
626 using iterator_category = std::forward_iterator_tag;
628 using difference_type = std::ptrdiff_t;
631
635
637 {
638 return SlicedICFGNodeRef{view, *it};
639 }
641 {
642 ++it;
643 return *this;
644 }
646 {
647 SlicedICFGNodeIter t = *this;
648 ++it;
649 return t;
650 }
651
653 {
654 return a.it == b.it;
655 }
657 {
658 return !(a == b);
659 }
660
661private:
662 const SlicedICFGView* view = nullptr;
664};
665
666//===----------------------------------------------------------------------===//
667// SlicedThreadCallGraphView traits support (no bridged edges; canonical
668// adjacency is the kept-edge set, so pruned-call-site edges never appear).
669//===----------------------------------------------------------------------===//
670
672
679
680// Forward==true walks kept out-edges; Forward==false walks kept in-edges. Join
681// edges are not part of the node's normal adjacency, so they never appear here.
682template <bool Forward>
684{
685public:
686 using iterator_category = std::forward_iterator_tag;
688 using difference_type = std::ptrdiff_t;
691
693
695 {
697 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
698 it.realIt = edges.begin();
699 it.realEnd = edges.end();
700 it.skipNonKept();
701 it.refresh();
702 return it;
703 }
705 {
707 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
708 it.realIt = edges.end();
709 it.realEnd = edges.end();
710 return it;
711 }
712
714 {
715 return cur;
716 }
718 {
719 return &cur;
720 }
722 {
723 return Forward ? cur.dst : cur.src;
724 }
725
727 {
728 if (realIt != realEnd)
729 {
730 ++realIt;
731 skipNonKept();
732 }
733 refresh();
734 return *this;
735 }
737 {
738 SlicedCGEdgeIterImpl t = *this;
739 ++*this;
740 return t;
741 }
742
744 {
745 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
746 }
748 {
749 return !(a == b);
750 }
751
752private:
755 const CallGraphNode* src = nullptr;
758
760
762 {
763 while (realIt != realEnd && !view->isKeptEdge(*realIt)) ++realIt;
764 }
765 void refresh()
766 {
767 if (realIt != realEnd)
768 {
769 const CallGraphEdge* e = *realIt;
771 }
772 else
773 {
775 }
776 }
777};
778
779template <bool Forward>
781{
782public:
783 using iterator_category = std::forward_iterator_tag;
785 using difference_type = std::ptrdiff_t;
788
791
793 {
794 return e.target();
795 }
797 {
798 return *e;
799 }
801 {
802 ++e;
803 return *this;
804 }
806 {
807 SlicedCGChildIterImpl t = *this;
808 ++e;
809 return t;
810 }
812 {
813 return a.e == b.e;
814 }
816 {
817 return !(a == b);
818 }
819
820private:
822};
823
825{
826public:
827 using iterator_category = std::forward_iterator_tag;
829 using difference_type = std::ptrdiff_t;
832
833 SlicedCGNodeIter() = default;
836
838 {
840 }
842 {
843 ++it;
844 return *this;
845 }
847 {
848 SlicedCGNodeIter t = *this;
849 ++it;
850 return t;
851 }
852 friend bool operator==(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
853 {
854 return a.it == b.it;
855 }
856 friend bool operator!=(const SlicedCGNodeIter& a, const SlicedCGNodeIter& b)
857 {
858 return !(a == b);
859 }
860
861private:
864};
865
866//===----------------------------------------------------------------------===//
867// SlicedPAGView traits support. Nodes are the SVFVars touched by kept statements;
868// edges are the kept SVFStmts (a kept var may have non-kept incident statements,
869// so keptStmts membership is the canonical filter). MultiOpndStmts use the
870// underlying SVFStmt src/dst (first operand -> result), not an operand fan-out.
871//===----------------------------------------------------------------------===//
872
874
881
882template <bool Forward>
884{
885public:
886 using iterator_category = std::forward_iterator_tag;
888 using difference_type = std::ptrdiff_t;
889 using pointer = const SlicedPAGEdgeRef*;
891
893
895 {
897 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
898 it.realIt = edges.begin();
899 it.realEnd = edges.end();
900 it.skipNonKept();
901 it.refresh();
902 return it;
903 }
905 {
907 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
908 it.realIt = edges.end();
909 it.realEnd = edges.end();
910 return it;
911 }
912
914 {
915 return cur;
916 }
918 {
919 return &cur;
920 }
922 {
923 return Forward ? cur.dst : cur.src;
924 }
925
927 {
928 if (realIt != realEnd)
929 {
930 ++realIt;
931 skipNonKept();
932 }
933 refresh();
934 return *this;
935 }
937 {
938 SlicedPAGEdgeIterImpl t = *this;
939 ++*this;
940 return t;
941 }
942
944 {
945 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
946 }
948 {
949 return !(a == b);
950 }
951
952private:
954 const SlicedPAGView* view = nullptr;
955 const SVFVar* src = nullptr;
958
960
962 {
963 while (realIt != realEnd && !view->isKeptStmt(*realIt)) ++realIt;
964 }
965 void refresh()
966 {
967 if (realIt != realEnd)
968 {
969 const SVFStmt* s = *realIt;
970 cur = SlicedPAGEdgeRef{{view, s->getSrcNode()}, {view, s->getDstNode()}, s};
971 }
972 else
973 {
975 }
976 }
977};
978
979template <bool Forward>
981{
982public:
983 using iterator_category = std::forward_iterator_tag;
985 using difference_type = std::ptrdiff_t;
986 using pointer = const SlicedPAGNodeRef*;
988
991
993 {
994 return e.target();
995 }
997 {
998 return *e;
999 }
1001 {
1002 ++e;
1003 return *this;
1004 }
1006 {
1007 SlicedPAGChildIterImpl t = *this;
1008 ++e;
1009 return t;
1010 }
1012 {
1013 return a.e == b.e;
1014 }
1016 {
1017 return !(a == b);
1018 }
1019
1020private:
1022};
1023
1024// Node iterator over the kept SVFVar ids (resolved against the SVFIR).
1026{
1027public:
1028 using iterator_category = std::forward_iterator_tag;
1030 using difference_type = std::ptrdiff_t;
1033
1037
1039 {
1041 }
1043 {
1044 ++it;
1045 return *this;
1046 }
1048 {
1049 SlicedPAGNodeIter t = *this;
1050 ++it;
1051 return t;
1052 }
1054 {
1055 return a.it == b.it;
1056 }
1058 {
1059 return !(a == b);
1060 }
1061
1062private:
1063 const SlicedPAGView* view = nullptr;
1065};
1066
1067//===----------------------------------------------------------------------===//
1068// SlicedSVFGView traits support (no bridged edges; membership is the view's
1069// retained-node rule, so removed nodes are propagation barriers).
1070//===----------------------------------------------------------------------===//
1071
1073
1080
1081// Forward==true walks kept out-edges; Forward==false walks kept in-edges.
1082template <bool Forward>
1084{
1085public:
1086 using iterator_category = std::forward_iterator_tag;
1088 using difference_type = std::ptrdiff_t;
1091
1093
1095 {
1097 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
1098 it.realIt = edges.begin();
1099 it.realEnd = edges.end();
1100 it.skipNonKept();
1101 it.refresh();
1102 return it;
1103 }
1105 {
1107 const auto& edges = Forward ? n->getOutEdges() : n->getInEdges();
1108 it.realIt = edges.end();
1109 it.realEnd = edges.end();
1110 return it;
1111 }
1112
1114 {
1115 return cur;
1116 }
1118 {
1119 return &cur;
1120 }
1122 {
1123 return Forward ? cur.dst : cur.src;
1124 }
1125
1127 {
1128 if (realIt != realEnd)
1129 {
1130 ++realIt;
1131 skipNonKept();
1132 }
1133 refresh();
1134 return *this;
1135 }
1137 {
1138 SlicedSVFGEdgeIterImpl t = *this;
1139 ++*this;
1140 return t;
1141 }
1142
1144 {
1145 return a.view == b.view && a.src == b.src && a.realIt == b.realIt;
1146 }
1148 {
1149 return !(a == b);
1150 }
1151
1152private:
1154 const SlicedSVFGView* view = nullptr;
1155 const SVFGNode* src = nullptr;
1158
1160
1162 {
1163 while (realIt != realEnd &&
1164 !view->isKeptNode(Forward ? (*realIt)->getDstNode() : (*realIt)->getSrcNode()))
1165 ++realIt;
1166 }
1167 void refresh()
1168 {
1169 if (realIt != realEnd)
1170 {
1171 const SVFGEdge* e = *realIt;
1172 cur = SlicedSVFGEdgeRef{{view, e->getSrcNode()}, {view, e->getDstNode()}, e};
1173 }
1174 else
1175 {
1177 }
1178 }
1179};
1180
1181template <bool Forward>
1183{
1184public:
1185 using iterator_category = std::forward_iterator_tag;
1187 using difference_type = std::ptrdiff_t;
1190
1193
1195 {
1196 return e.target();
1197 }
1199 {
1200 return *e;
1201 }
1203 {
1204 ++e;
1205 return *this;
1206 }
1208 {
1209 SlicedSVFGChildIterImpl t = *this;
1210 ++e;
1211 return t;
1212 }
1214 {
1215 return a.e == b.e;
1216 }
1218 {
1219 return !(a == b);
1220 }
1221
1222private:
1224};
1225
1226// Node iterator: filters the underlying SVFG's node map by the retained rule.
1228{
1229public:
1230 using iterator_category = std::forward_iterator_tag;
1232 using difference_type = std::ptrdiff_t;
1235
1242
1244 {
1245 return SlicedSVFGNodeRef{view, it->second};
1246 }
1248 {
1249 ++it;
1250 skipNonKept();
1251 return *this;
1252 }
1254 {
1255 SlicedSVFGNodeIter t = *this;
1256 ++*this;
1257 return t;
1258 }
1260 {
1261 return a.it == b.it;
1262 }
1264 {
1265 return !(a == b);
1266 }
1267
1268private:
1269 const SlicedSVFGView* view = nullptr;
1272 {
1273 while (it != endIt && !view->isKeptNode(it->second)) ++it;
1274 }
1275};
1276
1277} // End namespace SVF
1278
1279//===----------------------------------------------------------------------===//
1280// Traits specializations must be at namespace SVF scope too (that is where the
1281// GenericGraphTraits primary template and Inverse live).
1282//===----------------------------------------------------------------------===//
1283namespace SVF
1284{
1285
1286// Forward traits for SlicedICFGView.
1287template <>
1289{
1295
1296 // Escape hatch to the underlying node so graph-generic algorithms can reach
1297 // domain data (getFun/getSVFStmts) uniformly. Full-ICFG traits return the node.
1299 {
1300 return n.raw;
1301 }
1302
1303 // Graph-intrinsic queries mirroring GenericGraphTraits<ICFG*>, so a
1304 // graph-parameterised analysis resolves the right behaviour from the type.
1306 static const ICFGNode* getFunEntry(const SlicedICFGView* g, const FunObjVar* fun)
1307 {
1308 return g->getFunEntry(fun);
1309 }
1310 static void getFunICFGNodes(const SlicedICFGView* g, const FunObjVar* fun,
1311 std::vector<const ICFGNode*>& out)
1312 {
1313 g->getFunICFGNodes(fun, out);
1314 }
1315 static void getSuccNodes(const SlicedICFGView* g, const ICFGNode* n,
1316 std::vector<const ICFGNode*>& out)
1317 {
1318 g->getSuccNodes(n, out);
1319 }
1320 static void getPredNodes(const SlicedICFGView* g, const ICFGNode* n,
1321 std::vector<const ICFGNode*>& out)
1322 {
1323 g->getPredNodes(n, out);
1324 }
1325 static bool containsNode(const SlicedICFGView* g, const ICFGNode* n)
1326 {
1327 return g->isKeptNode(n);
1328 }
1330
1332 {
1333 return NodeRef{};
1334 }
1335
1337 {
1338 return SlicedICFGNodeIter(v, v->getKeptNodes().begin());
1339 }
1341 {
1342 return SlicedICFGNodeIter(v, v->getKeptNodes().end());
1343 }
1344
1346 {
1347 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1348 }
1350 {
1351 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1352 }
1354 {
1355 return child_begin(n);
1356 }
1358 {
1359 return child_end(n);
1360 }
1361
1363 {
1364 return ChildEdgeIteratorType::begin(n.view, n.raw);
1365 }
1367 {
1368 return ChildEdgeIteratorType::end(n.view, n.raw);
1369 }
1370
1371 static NodeRef edge_dest(const EdgeRef& e)
1372 {
1373 return e.dst;
1374 }
1375
1376 static unsigned graphSize(const SlicedICFGView* v)
1377 {
1378 return static_cast<unsigned>(v->getKeptNodes().size());
1379 }
1380 static inline unsigned getNodeID(NodeRef n)
1381 {
1382 return n.raw->getId();
1383 }
1385 {
1386 const ICFGNode* raw = v->getOriginalICFG()->getGNode(id);
1387 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1388 }
1389};
1390
1391// Inverse (reverse-traversal) traits for SlicedICFGView.
1392template <>
1394{
1399
1401 {
1402 return NodeRef{};
1403 }
1404
1406 {
1407 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1408 }
1410 {
1411 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1412 }
1413
1415 {
1416 return ChildEdgeIteratorType::begin(n.view, n.raw);
1417 }
1419 {
1420 return ChildEdgeIteratorType::end(n.view, n.raw);
1421 }
1422
1423 // Inverse: the traversed "child" is the predecessor -> the edge source.
1424 static NodeRef edge_dest(const EdgeRef& e)
1425 {
1426 return e.src;
1427 }
1428 static inline unsigned getNodeID(NodeRef n)
1429 {
1430 return n.raw->getId();
1431 }
1432};
1433
1434// Forward traits for SlicedThreadCallGraphView.
1435template <>
1437{
1443
1445 {
1446 return n.raw;
1447 }
1448
1449 // Graph-intrinsic queries mirroring GenericGraphTraits<CallGraph*>.
1452 std::vector<const CallGraphEdge*>& out)
1453 {
1454 g->getInEdgesOf(n, out);
1455 }
1457 {
1458 return g->getOriginalCallGraph();
1459 }
1461
1463 {
1464 return NodeRef{};
1465 }
1466
1468 {
1469 return SlicedCGNodeIter(v, v->getKeptNodes().begin());
1470 }
1472 {
1473 return SlicedCGNodeIter(v, v->getKeptNodes().end());
1474 }
1475
1477 {
1478 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1479 }
1481 {
1482 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1483 }
1485 {
1486 return child_begin(n);
1487 }
1489 {
1490 return child_end(n);
1491 }
1492
1494 {
1495 return ChildEdgeIteratorType::begin(n.view, n.raw);
1496 }
1498 {
1499 return ChildEdgeIteratorType::end(n.view, n.raw);
1500 }
1501
1502 static NodeRef edge_dest(const EdgeRef& e)
1503 {
1504 return e.dst;
1505 }
1506
1507 static unsigned graphSize(const SlicedThreadCallGraphView* v)
1508 {
1509 return static_cast<unsigned>(v->getKeptNodes().size());
1510 }
1511 static inline unsigned getNodeID(NodeRef n)
1512 {
1513 return n.raw->getId();
1514 }
1516 {
1517 const CallGraphNode* raw = v->getOriginalCallGraph()->getGNode(id);
1518 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1519 }
1520};
1521
1522// Inverse traits for SlicedThreadCallGraphView.
1523template <>
1525{
1530
1535
1537 {
1538 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1539 }
1541 {
1542 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1543 }
1545 {
1546 return ChildEdgeIteratorType::begin(n.view, n.raw);
1547 }
1549 {
1550 return ChildEdgeIteratorType::end(n.view, n.raw);
1551 }
1552
1553 static NodeRef edge_dest(const EdgeRef& e)
1554 {
1555 return e.src;
1556 }
1557 static inline unsigned getNodeID(NodeRef n)
1558 {
1559 return n.raw->getId();
1560 }
1561};
1562
1563// Forward traits for SlicedPAGView.
1564template <>
1566{
1572
1574 {
1575 return n.raw;
1576 }
1577
1579 {
1580 return NodeRef{};
1581 }
1582
1584 {
1585 return SlicedPAGNodeIter(v, v->getKeptNodeIds().begin());
1586 }
1588 {
1589 return SlicedPAGNodeIter(v, v->getKeptNodeIds().end());
1590 }
1591
1593 {
1594 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1595 }
1597 {
1598 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1599 }
1601 {
1602 return child_begin(n);
1603 }
1605 {
1606 return child_end(n);
1607 }
1608
1610 {
1611 return ChildEdgeIteratorType::begin(n.view, n.raw);
1612 }
1614 {
1615 return ChildEdgeIteratorType::end(n.view, n.raw);
1616 }
1617
1618 static NodeRef edge_dest(const EdgeRef& e)
1619 {
1620 return e.dst;
1621 }
1622
1623 static unsigned graphSize(const SlicedPAGView* v)
1624 {
1625 return static_cast<unsigned>(v->getKeptNodeIds().size());
1626 }
1627 static inline unsigned getNodeID(NodeRef n)
1628 {
1629 return n.raw->getId();
1630 }
1632 {
1633 const bool kept = v->getKeptNodeIds().count(id) > 0;
1634 return NodeRef{v, kept ? v->getSVFIR()->getGNode(id) : nullptr};
1635 }
1636};
1637
1638// Inverse traits for SlicedPAGView.
1639template <>
1641{
1646
1648 {
1649 return NodeRef{};
1650 }
1651
1653 {
1654 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1655 }
1657 {
1658 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1659 }
1661 {
1662 return ChildEdgeIteratorType::begin(n.view, n.raw);
1663 }
1665 {
1666 return ChildEdgeIteratorType::end(n.view, n.raw);
1667 }
1668
1669 static NodeRef edge_dest(const EdgeRef& e)
1670 {
1671 return e.src;
1672 }
1673 static inline unsigned getNodeID(NodeRef n)
1674 {
1675 return n.raw->getId();
1676 }
1677};
1678
1679// Forward traits for SlicedSVFGView.
1680template <>
1682{
1688
1690 {
1691 return n.raw;
1692 }
1693
1695 static bool containsNode(const SlicedSVFGView* g, const SVFGNode* n)
1696 {
1697 return g->isKeptNode(n);
1698 }
1699
1701 {
1702 return NodeRef{};
1703 }
1704
1706 {
1707 assert(v->getSVFG() && "SlicedSVFGView: bind the SVFG before iterating nodes");
1708 return SlicedSVFGNodeIter(v, v->getSVFG()->begin(), v->getSVFG()->end());
1709 }
1711 {
1712 assert(v->getSVFG() && "SlicedSVFGView: bind the SVFG before iterating nodes");
1713 return SlicedSVFGNodeIter(v, v->getSVFG()->end(), v->getSVFG()->end());
1714 }
1715
1717 {
1718 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1719 }
1721 {
1722 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1723 }
1725 {
1726 return child_begin(n);
1727 }
1729 {
1730 return child_end(n);
1731 }
1732
1734 {
1735 return ChildEdgeIteratorType::begin(n.view, n.raw);
1736 }
1738 {
1739 return ChildEdgeIteratorType::end(n.view, n.raw);
1740 }
1741
1742 static NodeRef edge_dest(const EdgeRef& e)
1743 {
1744 return e.dst;
1745 }
1746 static inline unsigned getNodeID(NodeRef n)
1747 {
1748 return n.raw->getId();
1749 }
1751 {
1752 const SVFGNode* raw =
1753 (v->getSVFG() != nullptr) ? v->getSVFG()->getGNode(id) : nullptr;
1754 return NodeRef{v, (raw != nullptr && v->isKeptNode(raw)) ? raw : nullptr};
1755 }
1756};
1757
1758// Inverse traits for SlicedSVFGView.
1759template <>
1761{
1766
1768 {
1769 return NodeRef{};
1770 }
1771
1773 {
1774 return ChildIteratorType(ChildEdgeIteratorType::begin(n.view, n.raw));
1775 }
1777 {
1778 return ChildIteratorType(ChildEdgeIteratorType::end(n.view, n.raw));
1779 }
1781 {
1782 return ChildEdgeIteratorType::begin(n.view, n.raw);
1783 }
1785 {
1786 return ChildEdgeIteratorType::end(n.view, n.raw);
1787 }
1788
1789 static NodeRef edge_dest(const EdgeRef& e)
1790 {
1791 return e.src;
1792 }
1793 static inline unsigned getNodeID(NodeRef n)
1794 {
1795 return n.raw->getId();
1796 }
1797};
1798
1799} // End namespace SVF
1800
1801#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
CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet
Definition CallGraph.h:241
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
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
OrderedSet< const ICFGEdge * > keptEdges
void buildICFGSets(const OrderedSet< const ICFGNode * > &keepNodes, const OrderedSet< const FunObjVar * > &keptFunctions)
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
bool isKeptNode(const SVFGNode *n) const
Whether the node is retained (see the class comment for the rule).
SlicedSVFGView(const SlicedICFGView *icfgView, const SVFG *svfg=nullptr)
const SlicedICFGView * icfgView
bool isKeptEdge(const SVFGEdge *e) const
Whether the edge is retained: both endpoints kept (no bridges).
const SlicedICFGView * getICFGView() const
void dump(const std::string &filename) const
Dump the sliced SVFG (retained nodes/edges only) via GraphWriter.
void setSVFG(const SVFG *g)
Bind the underlying SVFG (enables node iteration and dumping).
const CallGraph * getAnalysisCallGraph() const
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 getInEdgesOfCallGraphNode(const CallGraphNode *node, std::vector< const CallGraphEdge * > &out) const
void dumpStats(const std::string &prefix="") const
Output statistics.
const OrderedSet< const SVFStmt * > & getKeptStatements() const
Get all kept statements.
const Set< const CallICFGNode * > & getIndirectSitesWithEmptyTargets() const
Get indirect call sites that lost all targets after filtering.
const OrderedSet< const CallGraphNode * > & getKeptNodes() const
Get all kept nodes.
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 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
const CallGraph::CallGraphEdgeSet & getKeptEdges() const
Get all kept edges.
CallGraph::CallGraphEdgeSet keptEdges
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)
CallGraph * getOriginalCallGraph() const
Get original CallGraph (ThreadCallGraph inherits from CallGraph)
ThreadCallGraph * getOriginalThreadCallGraph() const
Get original ThreadCallGraph.
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 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 NodeRef edge_dest(const EdgeRef &e)
static ChildEdgeIteratorType child_edge_begin(NodeRef n)
static nodes_iterator nodes_end(const SlicedThreadCallGraphView *v)
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 unsigned graphSize(const SlicedThreadCallGraphView *v)
static void getInEdges(const SlicedThreadCallGraphView *g, const CallGraphNode *n, std::vector< const CallGraphEdge * > &out)
static const CallGraph * getCallGraph(const SlicedThreadCallGraphView *g)
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