svf-lib 1.0.2675 → 1.0.2677

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/SVF-linux-aarch64/bin/mta +0 -0
  2. package/SVF-linux-aarch64/bin/svf-ex +0 -0
  3. package/SVF-linux-aarch64/include/Graphs/CallGraph.h +18 -0
  4. package/SVF-linux-aarch64/include/Graphs/DOTGraphTraits.h +33 -20
  5. package/SVF-linux-aarch64/include/Graphs/GraphPrinter.h +1 -1
  6. package/SVF-linux-aarch64/include/Graphs/GraphWriter.h +6 -7
  7. package/SVF-linux-aarch64/include/Graphs/ICFG.h +40 -0
  8. package/SVF-linux-aarch64/include/Graphs/SVFG.h +8 -0
  9. package/SVF-linux-aarch64/include/Graphs/SlicedGraphs.h +1801 -0
  10. package/SVF-linux-aarch64/include/Graphs/ThreadCallGraph.h +13 -4
  11. package/SVF-linux-aarch64/include/MSSA/MemRegion.h +17 -0
  12. package/SVF-linux-aarch64/include/MSSA/MemSSA.h +7 -5
  13. package/SVF-linux-aarch64/include/MSSA/SVFGBuilder.h +6 -0
  14. package/SVF-linux-aarch64/include/MTA/FSMPTA.h +91 -0
  15. package/SVF-linux-aarch64/include/MTA/LockAnalysis.h +40 -25
  16. package/SVF-linux-aarch64/include/MTA/MHP.h +54 -21
  17. package/SVF-linux-aarch64/include/MTA/MTA.h +186 -3
  18. package/SVF-linux-aarch64/include/MTA/MTASVFGBuilder.h +176 -0
  19. package/SVF-linux-aarch64/include/MTA/MTASlicer.h +275 -0
  20. package/SVF-linux-aarch64/include/MTA/MTAStat.h +0 -2
  21. package/SVF-linux-aarch64/include/MTA/TCT.h +70 -29
  22. package/SVF-linux-aarch64/include/Util/CommandLine.h +5 -0
  23. package/SVF-linux-aarch64/include/Util/CxtStmt.h +29 -19
  24. package/SVF-linux-aarch64/include/Util/Options.h +12 -6
  25. package/SVF-linux-aarch64/include/Util/ThreadAPI.h +12 -0
  26. package/SVF-linux-aarch64/lib/cmake/SVF/SVFTargets.cmake +1 -1
  27. package/SVF-linux-aarch64/lib/libSvfCore.so.3.4 +0 -0
  28. package/SVF-osx/bin/mta +0 -0
  29. package/SVF-osx/include/Graphs/CallGraph.h +18 -0
  30. package/SVF-osx/include/Graphs/DOTGraphTraits.h +33 -20
  31. package/SVF-osx/include/Graphs/GraphPrinter.h +1 -1
  32. package/SVF-osx/include/Graphs/GraphWriter.h +6 -7
  33. package/SVF-osx/include/Graphs/ICFG.h +40 -0
  34. package/SVF-osx/include/Graphs/SVFG.h +8 -0
  35. package/SVF-osx/include/Graphs/SlicedGraphs.h +1801 -0
  36. package/SVF-osx/include/Graphs/ThreadCallGraph.h +13 -4
  37. package/SVF-osx/include/MSSA/MemRegion.h +17 -0
  38. package/SVF-osx/include/MSSA/MemSSA.h +7 -5
  39. package/SVF-osx/include/MSSA/SVFGBuilder.h +6 -0
  40. package/SVF-osx/include/MTA/FSMPTA.h +91 -0
  41. package/SVF-osx/include/MTA/LockAnalysis.h +40 -25
  42. package/SVF-osx/include/MTA/MHP.h +54 -21
  43. package/SVF-osx/include/MTA/MTA.h +186 -3
  44. package/SVF-osx/include/MTA/MTASVFGBuilder.h +176 -0
  45. package/SVF-osx/include/MTA/MTASlicer.h +275 -0
  46. package/SVF-osx/include/MTA/MTAStat.h +0 -2
  47. package/SVF-osx/include/MTA/TCT.h +70 -29
  48. package/SVF-osx/include/Util/CommandLine.h +5 -0
  49. package/SVF-osx/include/Util/CxtStmt.h +29 -19
  50. package/SVF-osx/include/Util/Options.h +12 -6
  51. package/SVF-osx/include/Util/ThreadAPI.h +12 -0
  52. package/SVF-osx/lib/cmake/SVF/SVFTargets.cmake +1 -1
  53. package/SVF-osx/lib/libSvfCore.3.4.dylib +0 -0
  54. package/package.json +1 -1
@@ -58,8 +58,6 @@ public:
58
58
  void performThreadCallGraphStat(ThreadCallGraph* tcg);
59
59
  /// Statistics for thread creation tree
60
60
  void performTCTStat(TCT* tct);
61
- /// Statistics for MHP statement pairs
62
- void performMHPPairStat(MHP* mhp, LockAnalysis* lsa);
63
61
  /// Statistics for annotation
64
62
  //void performAnnotationStat(MTAAnnotator* anno);
65
63
 
@@ -44,7 +44,6 @@ namespace SVF
44
44
 
45
45
  class TCTNode;
46
46
 
47
-
48
47
  /*
49
48
  * Thread creation edge represents a spawning relation between two context sensitive threads
50
49
  */
@@ -143,7 +142,7 @@ public:
143
142
  //@}
144
143
 
145
144
 
146
- private:
145
+ protected:
147
146
  const CxtThread ctx; /// Thread creation context, <fork site, call string context>
148
147
  bool multiforked;
149
148
  };
@@ -159,7 +158,18 @@ public:
159
158
  typedef SVFLoopAndDomInfo::LoopBBs LoopBBs;
160
159
  typedef TCTEdge::ThreadCreateEdgeSet ThreadCreateEdgeSet;
161
160
  typedef ThreadCreateEdgeSet::iterator TCTNodeIter;
162
- typedef Set<const FunObjVar*> FunSet;
161
+ /// Order functions by id (thread ids are assigned in iteration order over
162
+ /// the entry-function set). Null-safe: null functions order first.
163
+ struct FunObjVarIdCmp
164
+ {
165
+ bool operator()(const FunObjVar* lhs, const FunObjVar* rhs) const
166
+ {
167
+ if (lhs == nullptr || rhs == nullptr)
168
+ return lhs == nullptr && rhs != nullptr;
169
+ return lhs->getId() < rhs->getId();
170
+ }
171
+ };
172
+ typedef OrderedSet<const FunObjVar*, FunObjVarIdCmp> FunSet;
163
173
  typedef std::vector<const ICFGNode*> InstVec;
164
174
  typedef Set<const ICFGNode*> InstSet;
165
175
  typedef Set<const CallGraphNode*> PTACGNodeSet;
@@ -171,22 +181,13 @@ public:
171
181
  typedef FIFOWorkList<CxtThreadProc> CxtThreadProcVec;
172
182
  typedef Set<CxtThreadProc> CxtThreadProcSet;
173
183
  typedef SCCDetection<CallGraph*> ThreadCallGraphSCC;
184
+ typedef Set<const ICFGNode*> DummyForkSiteSet;
174
185
 
175
186
  /// Constructor
176
- TCT(PointerAnalysis* p) :pta(p),TCTNodeNum(0),TCTEdgeNum(0),MaxCxtSize(0)
177
- {
178
- tcg = SVFUtil::dyn_cast<ThreadCallGraph>(pta->getCallGraph());
179
- assert(tcg != nullptr && "TCT::TCT: call graph is not a ThreadCallGraph!");
180
- tcg->updateCallGraph(pta);
181
- //tcg->updateJoinEdge(pta);
182
- tcgSCC = pta->getCallGraphSCC();
183
- tcgSCC->find();
184
- build();
185
- }
187
+ TCT(PointerAnalysis* p);
186
188
 
187
189
  /// Destructor
188
- virtual ~TCT()
189
- { }
190
+ virtual ~TCT();
190
191
 
191
192
  /// Get TCG
192
193
  inline ThreadCallGraph* getThreadCallGraph() const
@@ -420,7 +421,7 @@ public:
420
421
  /// Context helper functions
421
422
  //@{
422
423
  /// Push calling context
423
- void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
424
+ virtual void pushCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
424
425
  /// Match context
425
426
  bool matchAndPopCxt(CallStrCxt& cxt, const CallICFGNode* call, const FunObjVar* callee);
426
427
  /// If lhs is a suffix of rhs, including equal
@@ -442,7 +443,7 @@ public:
442
443
  /// Print TCT information
443
444
  void print() const;
444
445
 
445
- private:
446
+ protected:
446
447
  ThreadCallGraph* tcg;
447
448
  PointerAnalysis* pta;
448
449
  u32_t TCTNodeNum;
@@ -475,16 +476,36 @@ private:
475
476
  }
476
477
 
477
478
  /// Build TCT
478
- void build();
479
+ virtual void build();
480
+
481
+ /// Free the built graph and clear all bookkeeping so build() can run again from
482
+ /// a clean state (SlicedTCT rebuilds the tree over a sliced view).
483
+ void reset()
484
+ {
485
+ destroy();
486
+ IDToNodeMap.clear();
487
+ ctpToNodeMap.clear();
488
+ ctToForkCxtsMap.clear();
489
+ ctToRoutineFunMap.clear();
490
+ candidateFuncSet.clear();
491
+ entryFuncSet.clear();
492
+ joinSiteToLoopMap.clear();
493
+ inRecurJoinSites.clear();
494
+ ctpList.clear();
495
+ visitedCTPs.clear();
496
+ TCTNodeNum = 0;
497
+ TCTEdgeNum = 0;
498
+ MaxCxtSize = 0;
499
+ }
479
500
 
480
501
  /// Mark relevant procedures that are backward reachable from any fork/join site
481
502
  //@{
482
- void markRelProcs();
483
- void markRelProcs(const FunObjVar* fun);
503
+ virtual void markRelProcs();
504
+ virtual void markRelProcs(const FunObjVar* fun);
484
505
  //@}
485
506
 
486
507
  /// Get entry functions that are neither called by other functions nor extern functions
487
- void collectEntryFunInCallGraph();
508
+ virtual void collectEntryFunInCallGraph();
488
509
 
489
510
  /// Collect multi-forked threads whose 1, cxt is in loop or recursion;
490
511
  /// 2, parent thread is a multi-forked thread.
@@ -493,7 +514,7 @@ private:
493
514
  /// Handle join site in loop
494
515
  //@{
495
516
  /// collect loop info for join sites
496
- void collectLoopInfoForJoin();
517
+ virtual void collectLoopInfoForJoin();
497
518
  /// Whether a given bb is a loop head of a inloop join site
498
519
  bool isLoopHeaderOfJoinLoop(const SVFBasicBlock* bb);
499
520
  /// Whether a given bb is an exit of a inloop join site
@@ -509,7 +530,7 @@ private:
509
530
  //@}
510
531
 
511
532
  /// Handle call relations
512
- void handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, const CallICFGNode* call);
533
+ virtual void handleCallRelation(CxtThreadProc& ctp, const CallGraphEdge* cgEdge, const CallICFGNode* call);
513
534
 
514
535
  /// Get or create a tct node based on CxtThread
515
536
  //@{
@@ -519,6 +540,10 @@ private:
519
540
  CxtThreadToNodeMap::const_iterator it = ctpToNodeMap.find(ct);
520
541
  if(it!=ctpToNodeMap.end())
521
542
  {
543
+ // A second spawn context merged onto this truncated CxtThread: the
544
+ // node stands for multiple dynamic instances, so mark it multiforked.
545
+ if (addCxtOfCxtThread(forkSiteCtp.getTid(), forkSiteCtp.getContext(), ct))
546
+ it->second->setMultiforked(true);
522
547
  return it->second;
523
548
  }
524
549
 
@@ -533,14 +558,19 @@ private:
533
558
  /// Set multi-forked thread attributes
534
559
  void setMultiForkedAttrs(CxtThread& ct)
535
560
  {
536
- /// non-main thread
537
- if(ct.getThread() != nullptr)
561
+ /// non-main thread spawned at a real fork site. The main thread uses a
562
+ /// synthetic dummy fork site (see createDummyForkSite); it has no real
563
+ /// function/call-graph node, is never in a loop or recursion, and must be
564
+ /// treated like the null (main) case -- otherwise isInLoopInstruction would
565
+ /// look up a call-graph node that does not exist.
566
+ if(ct.getThread() != nullptr &&
567
+ dummyForkSites.find(ct.getThread()) == dummyForkSites.end())
538
568
  {
539
569
  const ICFGNode* svfInst = ct.getThread();
540
570
  ct.setInloop(isInLoopInstruction(svfInst));
541
571
  ct.setIncycle(isInRecursion(svfInst));
542
572
  }
543
- /// main thread
573
+ /// main thread (null or dummy fork site)
544
574
  else
545
575
  {
546
576
  ct.setInloop(false);
@@ -548,10 +578,11 @@ private:
548
578
  }
549
579
  }
550
580
 
551
- /// Add context for a thread at its spawning site (fork site)
552
- void addCxtOfCxtThread(NodeID pTid, const CallStrCxt& cxt, const CxtThread& ct)
581
+ /// Add context for a thread at its spawning site (fork site).
582
+ /// Returns true if this (parent tid, context) pair was not recorded before.
583
+ bool addCxtOfCxtThread(NodeID pTid, const CallStrCxt& cxt, const CxtThread& ct)
553
584
  {
554
- ctToForkCxtsMap[ct].insert(std::make_pair(pTid, cxt));
585
+ return ctToForkCxtsMap[ct].insert(std::make_pair(pTid, cxt)).second;
555
586
  }
556
587
 
557
588
  /// Add start routine function of a cxt thread
@@ -560,6 +591,14 @@ private:
560
591
  ctToRoutineFunMap[ct] = fun;
561
592
  }
562
593
 
594
+ /// Create and get a new dummy fork site for starter routines
595
+ ICFGNode* createDummyForkSite()
596
+ {
597
+ ICFGNode* dummyForkSite = new ICFGNode(dummyForkICFGNodeID--, SVFValue::GlobalBlock);
598
+ dummyForkSites.insert(dummyForkSite);
599
+ return dummyForkSite;
600
+ }
601
+
563
602
  /// WorkList helper functions
564
603
  //@{
565
604
  inline bool pushToCTPWorkList(const CxtThreadProc& ctp)
@@ -592,6 +631,8 @@ private:
592
631
  CxtThreadToFun ctToRoutineFunMap; /// Map a CxtThread to its start routine function.
593
632
  InstToLoopMap joinSiteToLoopMap; ///< map an inloop join to its loop class
594
633
  Set<const ICFGNode*> inRecurJoinSites; ///< Fork or Join sites in recursions
634
+ DummyForkSiteSet dummyForkSites; ///< set of dummy fork sites for starter routines
635
+ NodeID dummyForkICFGNodeID = UINT32_MAX; ///< unique ID generator for dummy
595
636
  };
596
637
 
597
638
  } // End namespace SVF
@@ -353,6 +353,11 @@ public:
353
353
  value = v;
354
354
  }
355
355
 
356
+ bool isSet(void) const
357
+ {
358
+ return isExplicitlySet;
359
+ }
360
+
356
361
  T operator()(void) const
357
362
  {
358
363
  return value;
@@ -454,47 +454,57 @@ private:
454
454
  };
455
455
 
456
456
  } // End namespace SVF
457
- // Specialise has for class defined in this header file
457
+ // Specialise hash for the classes defined in this header file.
458
+ // Each hash must combine every field that operator== compares; hashing only a
459
+ // subset (e.g. the tid alone) collapses all keys sharing that field into one
460
+ // bucket. IDs are hashed instead of raw pointers so the bucket layout does not
461
+ // depend on allocation addresses.
458
462
  template <> struct std::hash<SVF::CxtThread>
459
463
  {
460
- size_t operator()(const SVF::CxtThread& cs) const
464
+ size_t operator()(const SVF::CxtThread& ct) const
461
465
  {
462
- std::hash<SVF::CallStrCxt> h;
463
- return h(cs.getContext());
466
+ std::hash<SVF::CallStrCxt> ch;
467
+ SVF::Hash<std::pair<SVF::NodeID, size_t>> pairH;
468
+ const SVF::NodeID forksite =
469
+ ct.getThread() != nullptr ? ct.getThread()->getId() : 0;
470
+ return pairH({forksite, ch(ct.getContext())});
464
471
  }
465
472
  };
466
473
  template <> struct std::hash<SVF::CxtThreadProc>
467
474
  {
468
475
  size_t operator()(const SVF::CxtThreadProc& ctp) const
469
476
  {
470
- std::hash<SVF::NodeID> h;
471
- return h(ctp.getTid());
477
+ std::hash<SVF::CallStrCxt> ch;
478
+ SVF::Hash<std::pair<SVF::NodeID, size_t>> pairH;
479
+ return pairH({ctp.getTid(),
480
+ pairH({ctp.getProc()->getId(), ch(ctp.getContext())})});
472
481
  }
473
482
  };
474
- template <> struct std::hash<SVF::CxtThreadStmt>
483
+ template <> struct std::hash<SVF::CxtStmt>
475
484
  {
476
- size_t operator()(const SVF::CxtThreadStmt& cts) const
485
+ size_t operator()(const SVF::CxtStmt& cs) const
477
486
  {
478
- std::hash<SVF::NodeID> h;
479
- return h(cts.getTid());
487
+ std::hash<SVF::CallStrCxt> ch;
488
+ SVF::Hash<std::pair<SVF::NodeID, size_t>> pairH;
489
+ return pairH({cs.getStmt()->getId(), ch(cs.getContext())});
480
490
  }
481
491
  };
482
- template <> struct std::hash<SVF::CxtStmt>
492
+ template <> struct std::hash<SVF::CxtThreadStmt>
483
493
  {
484
- size_t operator()(const SVF::CxtStmt& cs) const
494
+ size_t operator()(const SVF::CxtThreadStmt& cts) const
485
495
  {
486
- std::hash<SVF::ICFGNode*> h;
487
- SVF::ICFGNode* inst = const_cast<SVF::ICFGNode*> (cs.getStmt());
488
- return h(inst);
496
+ std::hash<SVF::CxtStmt> csH;
497
+ SVF::Hash<std::pair<SVF::NodeID, size_t>> pairH;
498
+ return pairH({cts.getTid(), csH(cts)});
489
499
  }
490
500
  };
491
501
  template <> struct std::hash<SVF::CxtProc>
492
502
  {
493
- size_t operator()(const SVF::CxtProc& cs) const
503
+ size_t operator()(const SVF::CxtProc& cp) const
494
504
  {
495
- std::hash<SVF::FunObjVar*> h;
496
- SVF::FunObjVar* fun = const_cast<SVF::FunObjVar*> (cs.getProc());
497
- return h(fun);
505
+ std::hash<SVF::CallStrCxt> ch;
506
+ SVF::Hash<std::pair<SVF::NodeID, size_t>> pairH;
507
+ return pairH({cp.getProc()->getId(), ch(cp.getContext())});
498
508
  }
499
509
  };
500
510
  #endif /* INCLUDE_UTIL_CXTSTMT_H_ */
@@ -78,7 +78,7 @@ public:
78
78
 
79
79
  // DDAPass.cpp
80
80
  static const Option<u32_t> MaxPathLen;
81
- static const Option<u32_t> MaxContextLen;
81
+ static Option<u32_t> MaxContextLen;
82
82
  static const Option<u32_t> MaxStepInWrapper;
83
83
  static const Option<std::string> UserInputQuery;
84
84
  static const Option<bool> InsenRecur;
@@ -155,9 +155,6 @@ public:
155
155
  static const Option<bool> PrintInterLev;
156
156
  static const Option<bool> DoLockAnalysis;
157
157
 
158
- //MTAStat.cpp
159
- static const Option<bool> AllPairMHP;
160
-
161
158
  // TCT.cpp
162
159
  static const Option<bool> TCTDotGraph;
163
160
 
@@ -255,8 +252,17 @@ public:
255
252
  static const Option<bool> FileCheck;
256
253
  /// double free checker, Default: false
257
254
  static const Option<bool> DFreeCheck;
258
- /// data race checker, Default: false
259
- static const Option<bool> RaceCheck;
255
+ /// MTA: flow-sensitive (FSAM) main analysis; false = Andersen flow-insensitive base, Default: true
256
+ static const Option<bool> MTFlowSensitive;
257
+ /// MTA: dump the pointer-analysis and thread call graphs (ptacg/tcg.dot), Default: false
258
+ static const Option<bool> DumpMTAGraphs;
259
+
260
+ /// MTA slicing: slice before the FSAM main analysis (false = whole-program baseline), Default: true
261
+ static const Option<bool> EnableSlicing;
262
+ /// MTA slicing: one unified slice for ILA + FSPTA (single-pass baseline), Default: false
263
+ static const Option<bool> SlicingSingle;
264
+ /// MTA slicing: dump intermediate dot graphs (ICFG/TCG/SVFG/...), Default: false
265
+ static const Option<bool> SlicedDumpDot;
260
266
  /// if the access index of gepstmt is unknown, skip it, Default: false
261
267
  static const Option<bool> GepUnknownIdx;
262
268
  static const Option<bool> RunUncallFuncs;
@@ -41,6 +41,7 @@ class SVFVar;
41
41
  class ValVar;
42
42
  class ObjVar;
43
43
  class FunObjVar;
44
+ class PointerAnalysis;
44
45
 
45
46
  /*
46
47
  * ThreadAPI class contains interfaces for pthread programs
@@ -152,6 +153,17 @@ public:
152
153
  const SVFVar* getRetParmAtJoinedSite(const CallICFGNode *inst) const;
153
154
  //@}
154
155
 
156
+ /// If fork join the same thread
157
+ struct ForkJoinAliasCache
158
+ {
159
+ Map<const SVFVar*, NodeBS> joinedThreadObjects;
160
+ };
161
+
162
+ bool isAliasedForkJoin(PointerAnalysis* pta, const SVFVar* forkArg,
163
+ const SVFVar* joinArg) const;
164
+ bool isAliasedForkJoin(PointerAnalysis* pta, const SVFVar* forkArg,
165
+ const SVFVar* joinArg, ForkJoinAliasCache& cache) const;
166
+
155
167
 
156
168
  /// Return true if this call exits/terminate a thread
157
169
  //@{
@@ -81,7 +81,7 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
81
81
  FILE_SET "HEADERS"
82
82
  TYPE "HEADERS"
83
83
  BASE_DIRS "${_IMPORT_PREFIX}/include"
84
- FILES "${_IMPORT_PREFIX}/include/AE/Core/AbstractState.h" "${_IMPORT_PREFIX}/include/AE/Core/AbstractValue.h" "${_IMPORT_PREFIX}/include/AE/Core/AddressValue.h" "${_IMPORT_PREFIX}/include/AE/Core/ICFGWTO.h" "${_IMPORT_PREFIX}/include/AE/Core/IntervalValue.h" "${_IMPORT_PREFIX}/include/AE/Core/NumericValue.h" "${_IMPORT_PREFIX}/include/AE/Core/RelExeState.h" "${_IMPORT_PREFIX}/include/AE/Core/RelationSolver.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEDetector.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEStat.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEWTO.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbsExtAPI.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbstractInterpretation.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/SparseAbstractInterpretation.h" "${_IMPORT_PREFIX}/include/CFL/CFGNormalizer.h" "${_IMPORT_PREFIX}/include/CFL/CFGrammar.h" "${_IMPORT_PREFIX}/include/CFL/CFLAlias.h" "${_IMPORT_PREFIX}/include/CFL/CFLBase.h" "${_IMPORT_PREFIX}/include/CFL/CFLGramGraphChecker.h" "${_IMPORT_PREFIX}/include/CFL/CFLGraphBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSVFGBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSolver.h" "${_IMPORT_PREFIX}/include/CFL/CFLStat.h" "${_IMPORT_PREFIX}/include/CFL/CFLVF.h" "${_IMPORT_PREFIX}/include/CFL/GrammarBuilder.h" "${_IMPORT_PREFIX}/include/DDA/ContextDDA.h" "${_IMPORT_PREFIX}/include/DDA/DDAClient.h" "${_IMPORT_PREFIX}/include/DDA/DDAPass.h" "${_IMPORT_PREFIX}/include/DDA/DDAStat.h" "${_IMPORT_PREFIX}/include/DDA/DDAVFSolver.h" "${_IMPORT_PREFIX}/include/DDA/FlowDDA.h" "${_IMPORT_PREFIX}/include/FastCluster/fastcluster.h" "${_IMPORT_PREFIX}/include/Graphs/BasicBlockG.h" "${_IMPORT_PREFIX}/include/Graphs/CDG.h" "${_IMPORT_PREFIX}/include/Graphs/CFLGraph.h" "${_IMPORT_PREFIX}/include/Graphs/CHG.h" "${_IMPORT_PREFIX}/include/Graphs/CallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/ConsG.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGNode.h" "${_IMPORT_PREFIX}/include/Graphs/DOTGraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GenericGraph.h" "${_IMPORT_PREFIX}/include/Graphs/GraphPrinter.h" "${_IMPORT_PREFIX}/include/Graphs/GraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GraphWriter.h" "${_IMPORT_PREFIX}/include/Graphs/ICFG.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/IRGraph.h" "${_IMPORT_PREFIX}/include/Graphs/SCC.h" "${_IMPORT_PREFIX}/include/Graphs/SVFG.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGOPT.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/ThreadCallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/VFG.h" "${_IMPORT_PREFIX}/include/Graphs/VFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/VFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/WTO.h" "${_IMPORT_PREFIX}/include/MSSA/MSSAMuChi.h" "${_IMPORT_PREFIX}/include/MSSA/MemPartition.h" "${_IMPORT_PREFIX}/include/MSSA/MemRegion.h" "${_IMPORT_PREFIX}/include/MSSA/MemSSA.h" "${_IMPORT_PREFIX}/include/MSSA/SVFGBuilder.h" "${_IMPORT_PREFIX}/include/MTA/LockAnalysis.h" "${_IMPORT_PREFIX}/include/MTA/MHP.h" "${_IMPORT_PREFIX}/include/MTA/MTA.h" "${_IMPORT_PREFIX}/include/MTA/MTAStat.h" "${_IMPORT_PREFIX}/include/MTA/TCT.h" "${_IMPORT_PREFIX}/include/MemoryModel/AbstractPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/AccessPath.h" "${_IMPORT_PREFIX}/include/MemoryModel/ConditionalPT.h" "${_IMPORT_PREFIX}/include/MemoryModel/MutablePointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PTATY.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToCache.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysis.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysisImpl.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointsTo.h" "${_IMPORT_PREFIX}/include/MemoryModel/SVFLoop.h" "${_IMPORT_PREFIX}/include/SABER/DoubleFreeChecker.h" "${_IMPORT_PREFIX}/include/SABER/FileChecker.h" "${_IMPORT_PREFIX}/include/SABER/LeakChecker.h" "${_IMPORT_PREFIX}/include/SABER/ProgSlice.h" "${_IMPORT_PREFIX}/include/SABER/SaberCheckerAPI.h" "${_IMPORT_PREFIX}/include/SABER/SaberCondAllocator.h" "${_IMPORT_PREFIX}/include/SABER/SaberSVFGBuilder.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkDDA.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkSolver.h" "${_IMPORT_PREFIX}/include/SVFIR/ObjTypeInfo.h" "${_IMPORT_PREFIX}/include/SVFIR/PAGBuilderFromFile.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFIR.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFStatements.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFType.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFValue.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFVariables.h" "${_IMPORT_PREFIX}/include/Util/BitVector.h" "${_IMPORT_PREFIX}/include/Util/CDGBuilder.h" "${_IMPORT_PREFIX}/include/Util/CallGraphBuilder.h" "${_IMPORT_PREFIX}/include/Util/Casting.h" "${_IMPORT_PREFIX}/include/Util/CommandLine.h" "${_IMPORT_PREFIX}/include/Util/CoreBitVector.h" "${_IMPORT_PREFIX}/include/Util/CxtStmt.h" "${_IMPORT_PREFIX}/include/Util/DPItem.h" "${_IMPORT_PREFIX}/include/Util/ExtAPI.h" "${_IMPORT_PREFIX}/include/Util/GeneralType.h" "${_IMPORT_PREFIX}/include/Util/GraphReachSolver.h" "${_IMPORT_PREFIX}/include/Util/Hash.h" "${_IMPORT_PREFIX}/include/Util/NodeIDAllocator.h" "${_IMPORT_PREFIX}/include/Util/Options.h" "${_IMPORT_PREFIX}/include/Util/PTAStat.h" "${_IMPORT_PREFIX}/include/Util/SVFBugReport.h" "${_IMPORT_PREFIX}/include/Util/SVFLoopAndDomInfo.h" "${_IMPORT_PREFIX}/include/Util/SVFStat.h" "${_IMPORT_PREFIX}/include/Util/SVFUtil.h" "${_IMPORT_PREFIX}/include/Util/SparseBitVector.h" "${_IMPORT_PREFIX}/include/Util/ThreadAPI.h" "${_IMPORT_PREFIX}/include/Util/WorkList.h" "${_IMPORT_PREFIX}/include/Util/Z3Expr.h" "${_IMPORT_PREFIX}/include/Util/cJSON.h" "${_IMPORT_PREFIX}/include/Util/iterator.h" "${_IMPORT_PREFIX}/include/Util/iterator_range.h" "${_IMPORT_PREFIX}/include/WPA/Andersen.h" "${_IMPORT_PREFIX}/include/WPA/AndersenPWC.h" "${_IMPORT_PREFIX}/include/WPA/CSC.h" "${_IMPORT_PREFIX}/include/WPA/FlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/Steensgaard.h" "${_IMPORT_PREFIX}/include/WPA/TypeAnalysis.h" "${_IMPORT_PREFIX}/include/WPA/VersionedFlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/WPAFSSolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAPass.h" "${_IMPORT_PREFIX}/include/WPA/WPASolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAStat.h"
84
+ FILES "${_IMPORT_PREFIX}/include/AE/Core/AbstractState.h" "${_IMPORT_PREFIX}/include/AE/Core/AbstractValue.h" "${_IMPORT_PREFIX}/include/AE/Core/AddressValue.h" "${_IMPORT_PREFIX}/include/AE/Core/ICFGWTO.h" "${_IMPORT_PREFIX}/include/AE/Core/IntervalValue.h" "${_IMPORT_PREFIX}/include/AE/Core/NumericValue.h" "${_IMPORT_PREFIX}/include/AE/Core/RelExeState.h" "${_IMPORT_PREFIX}/include/AE/Core/RelationSolver.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEDetector.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEStat.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AEWTO.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbsExtAPI.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/AbstractInterpretation.h" "${_IMPORT_PREFIX}/include/AE/Svfexe/SparseAbstractInterpretation.h" "${_IMPORT_PREFIX}/include/CFL/CFGNormalizer.h" "${_IMPORT_PREFIX}/include/CFL/CFGrammar.h" "${_IMPORT_PREFIX}/include/CFL/CFLAlias.h" "${_IMPORT_PREFIX}/include/CFL/CFLBase.h" "${_IMPORT_PREFIX}/include/CFL/CFLGramGraphChecker.h" "${_IMPORT_PREFIX}/include/CFL/CFLGraphBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSVFGBuilder.h" "${_IMPORT_PREFIX}/include/CFL/CFLSolver.h" "${_IMPORT_PREFIX}/include/CFL/CFLStat.h" "${_IMPORT_PREFIX}/include/CFL/CFLVF.h" "${_IMPORT_PREFIX}/include/CFL/GrammarBuilder.h" "${_IMPORT_PREFIX}/include/DDA/ContextDDA.h" "${_IMPORT_PREFIX}/include/DDA/DDAClient.h" "${_IMPORT_PREFIX}/include/DDA/DDAPass.h" "${_IMPORT_PREFIX}/include/DDA/DDAStat.h" "${_IMPORT_PREFIX}/include/DDA/DDAVFSolver.h" "${_IMPORT_PREFIX}/include/DDA/FlowDDA.h" "${_IMPORT_PREFIX}/include/FastCluster/fastcluster.h" "${_IMPORT_PREFIX}/include/Graphs/BasicBlockG.h" "${_IMPORT_PREFIX}/include/Graphs/CDG.h" "${_IMPORT_PREFIX}/include/Graphs/CFLGraph.h" "${_IMPORT_PREFIX}/include/Graphs/CHG.h" "${_IMPORT_PREFIX}/include/Graphs/CallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/ConsG.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ConsGNode.h" "${_IMPORT_PREFIX}/include/Graphs/DOTGraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GenericGraph.h" "${_IMPORT_PREFIX}/include/Graphs/GraphPrinter.h" "${_IMPORT_PREFIX}/include/Graphs/GraphTraits.h" "${_IMPORT_PREFIX}/include/Graphs/GraphWriter.h" "${_IMPORT_PREFIX}/include/Graphs/ICFG.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/ICFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/IRGraph.h" "${_IMPORT_PREFIX}/include/Graphs/SCC.h" "${_IMPORT_PREFIX}/include/Graphs/SVFG.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGOPT.h" "${_IMPORT_PREFIX}/include/Graphs/SVFGStat.h" "${_IMPORT_PREFIX}/include/Graphs/SlicedGraphs.h" "${_IMPORT_PREFIX}/include/Graphs/ThreadCallGraph.h" "${_IMPORT_PREFIX}/include/Graphs/VFG.h" "${_IMPORT_PREFIX}/include/Graphs/VFGEdge.h" "${_IMPORT_PREFIX}/include/Graphs/VFGNode.h" "${_IMPORT_PREFIX}/include/Graphs/WTO.h" "${_IMPORT_PREFIX}/include/MSSA/MSSAMuChi.h" "${_IMPORT_PREFIX}/include/MSSA/MemPartition.h" "${_IMPORT_PREFIX}/include/MSSA/MemRegion.h" "${_IMPORT_PREFIX}/include/MSSA/MemSSA.h" "${_IMPORT_PREFIX}/include/MSSA/SVFGBuilder.h" "${_IMPORT_PREFIX}/include/MTA/FSMPTA.h" "${_IMPORT_PREFIX}/include/MTA/LockAnalysis.h" "${_IMPORT_PREFIX}/include/MTA/MHP.h" "${_IMPORT_PREFIX}/include/MTA/MTA.h" "${_IMPORT_PREFIX}/include/MTA/MTASVFGBuilder.h" "${_IMPORT_PREFIX}/include/MTA/MTASlicer.h" "${_IMPORT_PREFIX}/include/MTA/MTAStat.h" "${_IMPORT_PREFIX}/include/MTA/TCT.h" "${_IMPORT_PREFIX}/include/MemoryModel/AbstractPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/AccessPath.h" "${_IMPORT_PREFIX}/include/MemoryModel/ConditionalPT.h" "${_IMPORT_PREFIX}/include/MemoryModel/MutablePointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PTATY.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToCache.h" "${_IMPORT_PREFIX}/include/MemoryModel/PersistentPointsToDS.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysis.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointerAnalysisImpl.h" "${_IMPORT_PREFIX}/include/MemoryModel/PointsTo.h" "${_IMPORT_PREFIX}/include/MemoryModel/SVFLoop.h" "${_IMPORT_PREFIX}/include/SABER/DoubleFreeChecker.h" "${_IMPORT_PREFIX}/include/SABER/FileChecker.h" "${_IMPORT_PREFIX}/include/SABER/LeakChecker.h" "${_IMPORT_PREFIX}/include/SABER/ProgSlice.h" "${_IMPORT_PREFIX}/include/SABER/SaberCheckerAPI.h" "${_IMPORT_PREFIX}/include/SABER/SaberCondAllocator.h" "${_IMPORT_PREFIX}/include/SABER/SaberSVFGBuilder.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkDDA.h" "${_IMPORT_PREFIX}/include/SABER/SrcSnkSolver.h" "${_IMPORT_PREFIX}/include/SVFIR/ObjTypeInfo.h" "${_IMPORT_PREFIX}/include/SVFIR/PAGBuilderFromFile.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFIR.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFStatements.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFType.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFValue.h" "${_IMPORT_PREFIX}/include/SVFIR/SVFVariables.h" "${_IMPORT_PREFIX}/include/Util/BitVector.h" "${_IMPORT_PREFIX}/include/Util/CDGBuilder.h" "${_IMPORT_PREFIX}/include/Util/CallGraphBuilder.h" "${_IMPORT_PREFIX}/include/Util/Casting.h" "${_IMPORT_PREFIX}/include/Util/CommandLine.h" "${_IMPORT_PREFIX}/include/Util/CoreBitVector.h" "${_IMPORT_PREFIX}/include/Util/CxtStmt.h" "${_IMPORT_PREFIX}/include/Util/DPItem.h" "${_IMPORT_PREFIX}/include/Util/ExtAPI.h" "${_IMPORT_PREFIX}/include/Util/GeneralType.h" "${_IMPORT_PREFIX}/include/Util/GraphReachSolver.h" "${_IMPORT_PREFIX}/include/Util/Hash.h" "${_IMPORT_PREFIX}/include/Util/NodeIDAllocator.h" "${_IMPORT_PREFIX}/include/Util/Options.h" "${_IMPORT_PREFIX}/include/Util/PTAStat.h" "${_IMPORT_PREFIX}/include/Util/SVFBugReport.h" "${_IMPORT_PREFIX}/include/Util/SVFLoopAndDomInfo.h" "${_IMPORT_PREFIX}/include/Util/SVFStat.h" "${_IMPORT_PREFIX}/include/Util/SVFUtil.h" "${_IMPORT_PREFIX}/include/Util/SparseBitVector.h" "${_IMPORT_PREFIX}/include/Util/ThreadAPI.h" "${_IMPORT_PREFIX}/include/Util/WorkList.h" "${_IMPORT_PREFIX}/include/Util/Z3Expr.h" "${_IMPORT_PREFIX}/include/Util/cJSON.h" "${_IMPORT_PREFIX}/include/Util/iterator.h" "${_IMPORT_PREFIX}/include/Util/iterator_range.h" "${_IMPORT_PREFIX}/include/WPA/Andersen.h" "${_IMPORT_PREFIX}/include/WPA/AndersenPWC.h" "${_IMPORT_PREFIX}/include/WPA/CSC.h" "${_IMPORT_PREFIX}/include/WPA/FlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/Steensgaard.h" "${_IMPORT_PREFIX}/include/WPA/TypeAnalysis.h" "${_IMPORT_PREFIX}/include/WPA/VersionedFlowSensitive.h" "${_IMPORT_PREFIX}/include/WPA/WPAFSSolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAPass.h" "${_IMPORT_PREFIX}/include/WPA/WPASolver.h" "${_IMPORT_PREFIX}/include/WPA/WPAStat.h"
85
85
  )
86
86
  else()
87
87
  set_property(TARGET SVF::SvfCore
package/SVF-osx/bin/mta CHANGED
Binary file
@@ -502,6 +502,24 @@ struct GenericGraphTraits<Inverse<SVF::CallGraphNode*> > : public GenericGraphTr
502
502
  template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTraits<SVF::GenericGraph<SVF::CallGraphNode,SVF::CallGraphEdge>* >
503
503
  {
504
504
  typedef SVF::CallGraphNode*NodeRef;
505
+
506
+ // Graph-intrinsic queries shared with the sliced-view specialisation
507
+ // (GenericGraphTraits<const SlicedThreadCallGraphView*>).
508
+ //@{
509
+ /// In-edges of n under this graph (whole CallGraph: all of them).
510
+ static void getInEdges(const SVF::CallGraph*, const SVF::CallGraphNode* n,
511
+ std::vector<const SVF::CallGraphEdge*>& out)
512
+ {
513
+ out.clear();
514
+ for (SVF::CallGraphEdge* e : n->getInEdges())
515
+ out.push_back(e);
516
+ }
517
+ /// The CallGraph object whose nodes an analysis over this graph scans.
518
+ static const SVF::CallGraph* getCallGraph(const SVF::CallGraph* g)
519
+ {
520
+ return g;
521
+ }
522
+ //@}
505
523
  };
506
524
 
507
525
  } // End namespace llvm
@@ -66,18 +66,29 @@ public:
66
66
  return false;
67
67
  }
68
68
 
69
+ /// getNodeIdentifier - The value written after "Node" as the dot node id.
70
+ /// Defaults to the node reference reinterpreted as an address, which works
71
+ /// for pointer NodeRefs; value NodeRefs (e.g. sliced views) override this to
72
+ /// return a stable per-node address. (Node params below are templated so the
73
+ /// defaults accept any NodeRef, pointer or value.)
74
+ template <typename NodeT>
75
+ static const void *getNodeIdentifier(NodeT N)
76
+ {
77
+ return static_cast<const void *>(N);
78
+ }
79
+
69
80
  /// isNodeHidden - If the function returns true, the given node is not
70
81
  /// displayed in the graph.
71
- template <typename GraphType>
72
- static bool isNodeHidden(const void *, const GraphType &)
82
+ template <typename NodeT, typename GraphType>
83
+ static bool isNodeHidden(NodeT, const GraphType &)
73
84
  {
74
85
  return false;
75
86
  }
76
87
 
77
88
  /// getNodeLabel - Given a node and a pointer to the top level graph, return
78
89
  /// the label to print in the node.
79
- template<typename GraphType>
80
- std::string getNodeLabel(const void *, const GraphType &)
90
+ template<typename NodeT, typename GraphType>
91
+ std::string getNodeLabel(NodeT, const GraphType &)
81
92
  {
82
93
  return "";
83
94
  }
@@ -85,22 +96,22 @@ public:
85
96
  // getNodeIdentifierLabel - Returns a string representing the
86
97
  // address or other unique identifier of the node. (Only used if
87
98
  // non-empty.)
88
- template <typename GraphType>
89
- static std::string getNodeIdentifierLabel(const void *, const GraphType &)
99
+ template <typename NodeT, typename GraphType>
100
+ static std::string getNodeIdentifierLabel(NodeT, const GraphType &)
90
101
  {
91
102
  return "";
92
103
  }
93
104
 
94
- template<typename GraphType>
95
- static std::string getNodeDescription(const void *, const GraphType &)
105
+ template<typename NodeT, typename GraphType>
106
+ static std::string getNodeDescription(NodeT, const GraphType &)
96
107
  {
97
108
  return "";
98
109
  }
99
110
 
100
111
  /// If you want to specify custom node attributes, this is the place to do so
101
112
  ///
102
- template<typename GraphType>
103
- static std::string getNodeAttributes(const void *,
113
+ template<typename NodeT, typename GraphType>
114
+ static std::string getNodeAttributes(NodeT,
104
115
  const GraphType &)
105
116
  {
106
117
  return "";
@@ -108,8 +119,8 @@ public:
108
119
 
109
120
  /// If you want to override the dot attributes printed for a particular edge,
110
121
  /// override this method.
111
- template<typename EdgeIter, typename GraphType>
112
- static std::string getEdgeAttributes(const void *, EdgeIter,
122
+ template<typename NodeT, typename EdgeIter, typename GraphType>
123
+ static std::string getEdgeAttributes(NodeT, EdgeIter,
113
124
  const GraphType &)
114
125
  {
115
126
  return "";
@@ -117,8 +128,8 @@ public:
117
128
 
118
129
  /// getEdgeSourceLabel - If you want to label the edge source itself,
119
130
  /// implement this method.
120
- template<typename EdgeIter>
121
- static std::string getEdgeSourceLabel(const void *, EdgeIter)
131
+ template<typename NodeT, typename EdgeIter>
132
+ static std::string getEdgeSourceLabel(NodeT, EdgeIter)
122
133
  {
123
134
  return "";
124
135
  }
@@ -126,8 +137,8 @@ public:
126
137
  /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
127
138
  /// should actually target another edge source, not a node. If this method is
128
139
  /// implemented, getEdgeTarget should be implemented.
129
- template<typename EdgeIter>
130
- static bool edgeTargetsEdgeSource(const void *, EdgeIter)
140
+ template<typename NodeT, typename EdgeIter>
141
+ static bool edgeTargetsEdgeSource(NodeT, EdgeIter)
131
142
  {
132
143
  return false;
133
144
  }
@@ -135,8 +146,8 @@ public:
135
146
  /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
136
147
  /// called to determine which outgoing edge of Node is the target of this
137
148
  /// edge.
138
- template<typename EdgeIter>
139
- static EdgeIter getEdgeTarget(const void *, EdgeIter I)
149
+ template<typename NodeT, typename EdgeIter>
150
+ static EdgeIter getEdgeTarget(NodeT, EdgeIter I)
140
151
  {
141
152
  return I;
142
153
  }
@@ -150,14 +161,16 @@ public:
150
161
 
151
162
  /// numEdgeDestLabels - If hasEdgeDestLabels, this function returns the
152
163
  /// number of incoming edge labels the given node has.
153
- static unsigned numEdgeDestLabels(const void *)
164
+ template<typename NodeT>
165
+ static unsigned numEdgeDestLabels(NodeT)
154
166
  {
155
167
  return 0;
156
168
  }
157
169
 
158
170
  /// getEdgeDestLabel - If hasEdgeDestLabels, this function returns the
159
171
  /// incoming edge label with the given index in the given node.
160
- static std::string getEdgeDestLabel(const void *, unsigned)
172
+ template<typename NodeT>
173
+ static std::string getEdgeDestLabel(NodeT, unsigned)
161
174
  {
162
175
  return "";
163
176
  }
@@ -92,7 +92,7 @@ public:
92
92
  node_iterator E = GTraits::nodes_end(GT);
93
93
  for (; I != E; ++I)
94
94
  {
95
- NodeRef *Node = *I;
95
+ NodeRef Node = *I;
96
96
  O << "node :" << Node << "'\n";
97
97
  child_iterator EI = GTraits::child_begin(Node);
98
98
  child_iterator EE = GTraits::child_end(Node);
@@ -72,10 +72,9 @@ class GraphWriter
72
72
  using child_iterator = typename GTraits::ChildIteratorType;
73
73
  DOTTraits DTraits;
74
74
 
75
- static_assert(std::is_pointer<NodeRef>::value,
76
- "FIXME: Currently GraphWriter requires the NodeRef type to be "
77
- "a pointer.\nThe pointer usage should be moved to "
78
- "DOTGraphTraits, and removed from GraphWriter itself.");
75
+ // NodeRef may be a pointer or a value type (e.g. a sliced-view contextual
76
+ // NodeRef). Node identity for the dot output is obtained from
77
+ // DOTGraphTraits::getNodeIdentifier (defaults to the pointer value).
79
78
 
80
79
  // Writes the edge labels of the node to O and returns true if there are any
81
80
  // edge labels not equal to the empty string "".
@@ -172,7 +171,7 @@ public:
172
171
  {
173
172
  std::string NodeAttributes = DTraits.getNodeAttributes(Node, G);
174
173
 
175
- O << "\tNode" << static_cast<const void*>(Node) << " [";
174
+ O << "\tNode" << DTraits.getNodeIdentifier(Node) << " [";
176
175
  if (!NodeAttributes.empty()) O << NodeAttributes << ",";
177
176
  O << "label=\"{";
178
177
 
@@ -271,8 +270,8 @@ public:
271
270
  if (DTraits.getEdgeSourceLabel(Node, EI).empty())
272
271
  edgeidx = -1;
273
272
 
274
- emitEdge(static_cast<const void*>(Node), edgeidx,
275
- static_cast<const void*>(TargetNode), DestPort,
273
+ emitEdge(DTraits.getNodeIdentifier(Node), edgeidx,
274
+ DTraits.getNodeIdentifier(TargetNode), DestPort,
276
275
  DTraits.getEdgeAttributes(Node, EI, G));
277
276
  }
278
277
  }