From 756567e4091a77b67021eb2af0349672367b3d78 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 7 Apr 2020 06:46:03 -0400
Subject: [PATCH 011/132] FIXME: more WIP on state revamp, mostly JSON support

---
 gcc/analyzer/call-string.cc   | 13 ++++++++++
 gcc/analyzer/call-string.h    |  3 +++
 gcc/analyzer/engine.cc        | 23 ++++++++++++++++++
 gcc/analyzer/exploded-graph.h |  2 ++
 gcc/analyzer/program-point.cc | 22 +++++++++++++++++
 gcc/analyzer/program-point.h  |  2 ++
 gcc/analyzer/program-state.cc | 11 +++++++++
 gcc/analyzer/program-state.h  |  1 +
 gcc/analyzer/revamp-state.cc  | 46 ++++++++++++++++++++++++++++++++---
 gcc/analyzer/revamp-state.h   |  7 ++++++
 10 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc
index 288953ed37c..227ae78a7ef 100644
--- a/gcc/analyzer/call-string.cc
+++ b/gcc/analyzer/call-string.cc
@@ -102,6 +102,19 @@ call_string::print (pretty_printer *pp) const
   pp_string (pp, "]");
 }
 
+/* FIXME.  */
+
+json::value *
+call_string::to_json () const
+{
+  json::array *arr = new json::array ();
+  const return_superedge *e;
+  int i;
+  FOR_EACH_VEC_ELT (m_return_edges, i, e)
+    arr->append (new json::object ()); // TODO
+  return arr;
+}
+
 /* Generate a hash value for this call_string.  */
 
 hashval_t
diff --git a/gcc/analyzer/call-string.h b/gcc/analyzer/call-string.h
index 1b5db0a4a20..335f4d4e118 100644
--- a/gcc/analyzer/call-string.h
+++ b/gcc/analyzer/call-string.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_CALL_STRING_H
 #define GCC_ANALYZER_CALL_STRING_H
 
+#include "json.h"
+
 namespace ana {
 
 class supergraph;
@@ -46,6 +48,7 @@ public:
   bool operator== (const call_string &other) const;
 
   void print (pretty_printer *pp) const;
+  json::value *to_json () const;
 
   hashval_t hash () const;
 
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 08c67aa5f1c..914cc0db7b1 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -959,6 +959,18 @@ exploded_node::dump (const extrinsic_state &ext_state) const
   dump (stderr, ext_state);
 }
 
+/* FIXME.  */
+
+json::value *
+exploded_node::to_json () const
+{
+  json::object *obj = new json::object ();
+  obj->set ("index", new json::integer_number (m_index));
+  obj->set ("point", m_ps.get_point ().to_json ());
+  obj->set ("state", m_ps.get_state ().to_json ());
+  return obj;
+}
+
 } // namespace ana
 
 /* Return true if FNDECL has a gimple body.  */
@@ -2060,6 +2072,17 @@ exploded_graph::get_or_create_node (const program_point &point,
       logger->end_log_line ();
     }
 
+  if (1)
+    {
+      pretty_printer pp;
+      pp_show_color (&pp) = pp_show_color (global_dc->printer);
+      json::value *js = node->to_json ();
+      js->print (&pp); // FIXME: format, colorize
+      inform (point.get_location (), "EN: %i%s",
+	      node->m_index, pp_formatted_text (&pp));
+      delete js;
+    }
+
   /* Add the new node to the worlist.  */
   m_worklist.add_node (node);
   return node;
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index b3e89d4a094..c252d76477f 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -188,6 +188,8 @@ class exploded_node : public dnode<eg_traits>
   void dump (FILE *fp, const extrinsic_state &ext_state) const;
   void dump (const extrinsic_state &ext_state) const;
 
+  json::value *to_json () const;
+
   /* The result of on_stmt.  */
   struct on_stmt_flags
   {
diff --git a/gcc/analyzer/program-point.cc b/gcc/analyzer/program-point.cc
index 7bf2de4e3bf..ee07a141cc0 100644
--- a/gcc/analyzer/program-point.cc
+++ b/gcc/analyzer/program-point.cc
@@ -135,6 +135,17 @@ function_point::print (pretty_printer *pp, const format &f) const
     }
 }
 
+/* FIXME.  */
+
+json::value *
+function_point::to_json () const
+{
+  json::object *obj = new json::object ();
+  obj->set ("kind", new json::string (point_kind_to_string (get_kind ())));
+  // TODO
+  return obj;
+}
+
 /* Generate a hash value for this function_point.  */
 
 hashval_t
@@ -233,6 +244,17 @@ program_point::dump () const
   pp_flush (&pp);
 }
 
+/* FIXME.  */
+
+json::value *
+program_point::to_json () const
+{
+  json::object *obj = new json::object ();
+  obj->set ("callstring", m_call_string.to_json ());
+  obj->set ("function_point", m_function_point.to_json ());
+  return obj;
+}
+
 /* Generate a hash value for this program_point.  */
 
 hashval_t
diff --git a/gcc/analyzer/program-point.h b/gcc/analyzer/program-point.h
index 3772a419d1a..c110d5003c5 100644
--- a/gcc/analyzer/program-point.h
+++ b/gcc/analyzer/program-point.h
@@ -88,6 +88,7 @@ public:
   void print (pretty_printer *pp, const format &f) const;
   void print_source_line (pretty_printer *pp) const;
   void dump () const;
+  json::value *to_json () const;
 
   hashval_t hash () const;
   bool operator== (const function_point &other) const
@@ -197,6 +198,7 @@ public:
   void print (pretty_printer *pp, const format &f) const;
   void print_source_line (pretty_printer *pp) const;
   void dump () const;
+  json::value *to_json () const;
 
   hashval_t hash () const;
   bool operator== (const program_point &other) const
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 858c7b2006f..64b61745166 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -809,6 +809,17 @@ program_state::dump (const extrinsic_state &ext_state,
   dump_to_file (ext_state, summarize, stderr);
 }
 
+/* FIXME.  */
+
+json::value *
+program_state::to_json () const
+{
+  json::object *obj = new json::object ();
+  if (m_revamp_state)
+    obj->set ("revamp_state", m_revamp_state->to_json ());
+  return obj;
+}
+
 void
 program_state::push_frame (const extrinsic_state &ext_state,
 			   function *fun)
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index b1f43ef7b02..70ef9656d3a 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -260,6 +260,7 @@ public:
   void dump_to_file (const extrinsic_state &ext_state, bool summarize,
 		     FILE *outf) const;
   void dump (const extrinsic_state &ext_state, bool summarize) const;
+  json::value *to_json () const;
 
   void push_frame (const extrinsic_state &ext_state, function *fun);
 
diff --git a/gcc/analyzer/revamp-state.cc b/gcc/analyzer/revamp-state.cc
index 573fa20f7f6..09321ce64d3 100644
--- a/gcc/analyzer/revamp-state.cc
+++ b/gcc/analyzer/revamp-state.cc
@@ -66,6 +66,16 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace ana {
 
+static json::object *
+make_obj_with_address (const void *ptr)
+{
+  json::object *obj = new json::object ();
+  char buf[20];
+  sprintf (buf, "%p", ptr);
+  obj->set ("address", new json::string (buf));
+  return obj;
+}
+
 /* class sval.  */
 
 hashval_t
@@ -95,6 +105,17 @@ sval::dump ()
   pp_flush (&pp);
 }
 
+json::value *
+sval::to_json () const
+{
+  json::object *obj = make_obj_with_address (this);
+  pretty_printer pp;
+  pp_format_decoder (&pp) = default_tree_printer;
+  dump_to_pp (&pp);
+  obj->set ("desc", new json::string (pp_formatted_text (&pp)));
+  return obj;
+}
+
 /* hash implementations.  */
 
 void
@@ -160,6 +181,16 @@ ssa_name_region::dump_to_pp (pretty_printer *pp) const
 
 /* class store.  */
 
+store::store ()
+: m_map ()
+{
+}
+
+store::store (const store &other)
+: m_map (other.m_map)
+{
+}
+
 void
 store::bind (const region_val *dst, const sval *val)
 {
@@ -170,7 +201,9 @@ store::bind (const region_val *dst, const sval *val)
 json::value *
 store::to_json () const
 {
+  json::object *store_obj = make_obj_with_address (this);
   json::array *store_arr = new json::array ();
+  store_obj->set ("items", store_arr);
   for (map_t::iterator iter = m_map.begin ();
        iter != m_map.end ();
        ++iter)
@@ -178,10 +211,11 @@ store::to_json () const
       const region_val *reg = (*iter).first;
       const sval *val = (*iter).second;
       json::object *item_obj = new json::object ();
-      // TODO
+      item_obj->set ("region", reg->to_json ());
+      item_obj->set ("value", val->to_json ());
       store_arr->append (item_obj);
     }
-  return store_arr;
+  return store_obj;
 }
 
 DEBUG_FUNCTION void
@@ -258,6 +292,12 @@ revamp_state::revamp_state (const extrinsic_state &ext_state)
 {
 }
 
+revamp_state::revamp_state (const extrinsic_state &ext_state,
+			    const revamp_state &other)
+: m_store (new store (*other.m_store))
+{
+}
+
 bool
 revamp_state::on_stmt (const extrinsic_state &ext_state,
 		       const supernode *snode,
@@ -471,7 +511,7 @@ revamp_state::get_rvalue (const extrinsic_state &ext_state, tree expr)
 json::value *
 revamp_state::to_json () const
 {
-  json::object *state_obj = new json::object ();
+  json::object *state_obj = make_obj_with_address (this);
   state_obj->set ("store", m_store->to_json ());
   return state_obj;
 }
diff --git a/gcc/analyzer/revamp-state.h b/gcc/analyzer/revamp-state.h
index 05ec299de95..bde81d71804 100644
--- a/gcc/analyzer/revamp-state.h
+++ b/gcc/analyzer/revamp-state.h
@@ -48,6 +48,8 @@ public:
 
   void dump ();
   virtual void dump_to_pp (pretty_printer *pp) const = 0;
+  json::value *to_json () const;
+
   virtual const region_val *dyn_cast_region_val () const { return NULL; }
 
  protected:
@@ -144,6 +146,9 @@ class store
   typedef hash_map <const region_val *, const sval *> map_t; // or region * ?
   typedef map_t::iterator iterator_t;
 
+  store ();
+  store (const store &other);
+
   void bind (const region_val *dst, const sval *val);
 
   json::value *to_json () const;
@@ -163,6 +168,8 @@ class revamp_state
 {
 public:
   revamp_state (const extrinsic_state &ext_state);
+  revamp_state (const extrinsic_state &ext_state,
+		const revamp_state &other);
 
   json::value *to_json () const;
 
-- 
2.21.0

