NoQ created this revision.
NoQ added a reviewer: Charusso.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, Szelethus, 
mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun.
Herald added a project: clang.

Instead of rewriting the whole graph, rewrite the leftmost path in the graph. 
Useful for trimmed graphs that are still too large to display due to multiple 
equivalent reports mixed into them.


Repository:
  rC Clang

https://reviews.llvm.org/D64263

Files:
  clang/test/Analysis/exploded-graph-rewriter/explorers.dot
  clang/utils/analyzer/exploded-graph-rewriter.py

Index: clang/utils/analyzer/exploded-graph-rewriter.py
===================================================================
--- clang/utils/analyzer/exploded-graph-rewriter.py
+++ clang/utils/analyzer/exploded-graph-rewriter.py
@@ -804,8 +804,7 @@
 #===-----------------------------------------------------------------------===#
 
 
-# A class that encapsulates traversal of the ExplodedGraph. Different explorer
-# kinds could potentially traverse specific sub-graphs.
+# BasicExplorer explores the whole graph in no particular order.
 class BasicExplorer(object):
     def __init__(self):
         super(BasicExplorer, self).__init__()
@@ -821,6 +820,39 @@
         visitor.visit_end_of_graph()
 
 
+# SinglePathExplorer traverses only a single path - the leftmost path
+# from the root. Useful when the trimmed graph is still too large
+# due to a large amount of equivalent reports.
+class SinglePathExplorer(object):
+    def __init__(self):
+        super(SinglePathExplorer, self).__init__()
+
+    def explore(self, graph, visitor):
+        visitor.visit_begin_graph(graph)
+
+        # Keep track of visited nodes in order to avoid loops.
+        visited = set()
+        node_id = graph.root_id
+        while True:
+            visited.add(node_id)
+            node = graph.nodes[node_id]
+            logging.debug('Visiting ' + node_id)
+            visitor.visit_node(node)
+            if len(node.successors) == 0:
+                break
+
+            succ_id = node.successors[0]
+            succ = graph.nodes[succ_id]
+            logging.debug('Visiting edge: %s -> %s ' % (node_id, succ_id))
+            visitor.visit_edge(node, succ)
+            if succ_id in visited:
+                break
+
+            node_id = succ_id
+
+        visitor.visit_end_of_graph()
+
+
 #===-----------------------------------------------------------------------===#
 # The entry point to the script.
 #===-----------------------------------------------------------------------===#
@@ -836,6 +868,11 @@
     parser.add_argument('-d', '--diff', action='store_const', dest='diff',
                         const=True, default=False,
                         help='display differences between states')
+    parser.add_argument('-s', '--single-path', action='store_const',
+                        dest='single_path', const=True, default=False,
+                        help='only display the leftmost path in the graph '
+                             '(useful for trimmed graphs that still '
+                             'branch too much)')
     parser.add_argument('--dark', action='store_const', dest='dark',
                         const=True, default=False,
                         help='dark mode')
@@ -851,8 +888,9 @@
             raw_line = raw_line.strip()
             graph.add_raw_line(raw_line)
 
-    explorer = BasicExplorer()
+    explorer = SinglePathExplorer() if args.single_path else BasicExplorer()
     visitor = DotDumpVisitor(args.diff, args.dark, args.gray)
+
     explorer.explore(graph, visitor)
 
 
Index: clang/test/Analysis/exploded-graph-rewriter/explorers.dot
===================================================================
--- /dev/null
+++ clang/test/Analysis/exploded-graph-rewriter/explorers.dot
@@ -0,0 +1,37 @@
+// RUN: %exploded_graph_rewriter %s \
+// RUN:     | FileCheck %s -check-prefixes=CHECK,BASIC
+// RUN: %exploded_graph_rewriter -s %s \
+// RUN:     | FileCheck %s -check-prefixes=CHECK,SINGLE
+
+// FIXME: Substitution doesn't seem to work on Windows.
+// UNSUPPORTED: system-windows
+
+Node0x1 [shape=record,label=
+ "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
+      "program_state": null, "program_points": []}\l}"];
+
+Node0x2 [shape=record,label=
+ "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
+      "program_state": null, "program_points": []}\l}"];
+
+Node0x3 [shape=record,label=
+ "{{ "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
+      "program_state": null, "program_points": []}\l}"];
+
+Node0x4 [shape=record,label=
+ "{{ "node_id": 4, "pointer": "0x4", "has_report": false, "is_sink": false,
+      "program_state": null, "program_points": []}\l}"];
+
+// CHECK: Node0x1 -> Node0x2;
+Node0x1 -> Node0x2;
+
+// BASIC: Node0x1 -> Node0x3;
+// SINGLE-NOT: Node0x1 -> Node0x3;
+Node0x1 -> Node0x3;
+
+// CHECK: Node0x2 -> Node0x4;
+Node0x2 -> Node0x4;
+
+// BASIC: Node0x3 -> Node0x4;
+// SINGLE-NOT: Node0x3 -> Node0x4;
+Node0x3 -> Node0x4;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to