From 0c46f2d29bb123c0fb3b59f0722163b46fed201b Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 27 Sep 2019 09:27:20 -0400
Subject: [PATCH 39/62] {HAS FIXMES} analyzer: new files: analyzer.{cc|h}

gcc/ChangeLog:
	* analyzer/analyzer.cc: New file.
	* analyzer/analyzer.h: New file.
---
 gcc/analyzer/analyzer.cc | 135 +++++++++++++++++++++++++++++++++++++++++++++++
 gcc/analyzer/analyzer.h  |  77 +++++++++++++++++++++++++++
 2 files changed, 212 insertions(+)
 create mode 100644 gcc/analyzer/analyzer.cc
 create mode 100644 gcc/analyzer/analyzer.h

diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
new file mode 100644
index 0000000..c74fdce
--- /dev/null
+++ b/gcc/analyzer/analyzer.cc
@@ -0,0 +1,135 @@
+/* Utility functions for the analyzer.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+/* FIXME.  */
+#include "config.h"
+#include "gcc-plugin.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tm.h"
+#include "toplev.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "context.h"
+#include "diagnostic.h"
+#include "bitmap.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-pretty-print.h"
+#include "tree-pretty-print.h"
+#include "analyzer.h"
+#include "graphviz.h"
+#include "cgraph.h"
+#include "diagnostic-path.h"
+#include "gcc-rich-location.h"
+#include <string>
+#include "stringpool.h"
+
+/* Helper function for checkers.  Is the CALL to the given function name?  */
+
+bool
+is_named_call_p (const gcall *call, const char *funcname)
+{
+  gcc_assert (funcname);
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return false;
+
+  return 0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname);
+}
+
+/* Helper function for checkers.  Is the CALL to the given function name,
+   and with the given number of arguments?  */
+
+bool
+is_named_call_p (const gcall *call, const char *funcname,
+		 unsigned int num_args)
+{
+  gcc_assert (funcname);
+
+  if (!is_named_call_p (call, funcname))
+    return false;
+
+  if (gimple_call_num_args (call) != num_args)
+    return false;
+
+  return true;
+}
+
+// FIXME: horrible hack, so that we can use %qE, which needs subclassing of
+// pretty_printer.  Do we need a cloning op?
+
+static char *
+global_dc_print (const char *fmt, ...)
+{
+  pretty_printer *pp = global_dc->printer->clone ();
+  pp_clear_output_area (pp);
+
+  text_info ti;
+  rich_location rich_loc (line_table, UNKNOWN_LOCATION);
+
+  va_list ap;
+
+  va_start (ap, fmt);
+
+  ti.format_spec = _(fmt);
+  ti.args_ptr = &ap;
+  ti.err_no = 0;
+  ti.x_data = NULL;
+  ti.m_richloc = &rich_loc;
+
+  pp_show_color (pp) = 0;
+  pp_format (pp, &ti);
+  pp_output_formatted_text (pp);
+
+  va_end (ap);
+
+  char *result = xstrdup (pp_formatted_text (pp));
+
+  delete pp;
+
+  return result;
+}
+
+std::string
+expr_to_string (tree t)
+{
+  char *tmp;
+  if (TREE_CODE (t) == SSA_NAME)
+    // FIXME: is there a non-hacky way to distinguish these from the underlying var?
+    tmp = global_dc_print ("%<%E_%i%>", t, SSA_NAME_VERSION (t));
+  else
+    tmp = global_dc_print ("%qE", t);
+  std::string result = tmp;
+  free (tmp);
+  return result;
+}
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
new file mode 100644
index 0000000..2d9f281
--- /dev/null
+++ b/gcc/analyzer/analyzer.h
@@ -0,0 +1,77 @@
+/* Utility functions for the analyzer.
+   Copyright (C) 2019 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ANALYZER_ANALYZER_H
+#define GCC_ANALYZER_ANALYZER_H
+
+class graphviz_out;
+
+extern bool is_named_call_p (const gcall *call, const char *funcname);
+extern bool is_named_call_p (const gcall *call, const char *funcname,
+			     unsigned int num_args);
+
+extern void register_analyzer_pass ();
+
+extern std::string expr_to_string (tree t);
+
+/* An RAII-style class for pushing/popping cfun within a scope.
+   Doing so ensures we get "In function " announcements
+   from the diagnostics subsystem.  */
+
+class auto_cfun
+{
+public:
+  auto_cfun (function *fun) { push_cfun (fun); }
+  ~auto_cfun () { pop_cfun (); }
+};
+
+/* Begin suppressing -Wformat and -Wformat-extra-args.  */
+
+#define PUSH_IGNORE_WFORMAT \
+  _Pragma("GCC diagnostic push") \
+  _Pragma("GCC diagnostic ignored \"-Wformat\"") \
+  _Pragma("GCC diagnostic ignored \"-Wformat-extra-args\"")
+
+/* Finish suppressing -Wformat and -Wformat-extra-args.  */
+
+#define POP_IGNORE_WFORMAT \
+  _Pragma("GCC diagnostic pop")
+
+/* Implement an optimized allocator for TYPENAME objects of fixed size,
+   without requiring a default ctor.  */
+
+#define IMPL_POOL_ALLOCATOR(TYPENAME) \
+  static pool_allocator TYPENAME##_pool (#TYPENAME, sizeof (TYPENAME)); \
+									\
+  void *								\
+  TYPENAME::operator new (size_t sz)					\
+  {									\
+    gcc_assert (sz == sizeof (TYPENAME));				\
+    return TYPENAME##_pool.allocate ();					\
+  }									\
+									\
+  void									\
+  TYPENAME::operator delete (void* ptr, size_t sz)			\
+  {									\
+    gcc_assert (sz == sizeof (TYPENAME));				\
+    TYPENAME##_pool.remove (ptr);					\
+  }
+
+#endif /* GCC_ANALYZER_ANALYZER_H */
-- 
1.8.5.3

