new file mode 100644
@@ -0,0 +1,150 @@
+/* Utility functions for the analyzer.
+ Copyright (C) 2019-2020 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic.h"
+#include "intl.h"
+#include "analyzer/analyzer.h"
+
+#if ENABLE_ANALYZER
+
+/* Helper function for checkers. Is the CALL to the given function name,
+ and with the given number of arguments?
+
+ This doesn't resolve function pointers via the region model;
+ is_named_call_p should be used instead, using a fndecl from
+ get_fndecl_for_call; this function should only be used for special cases
+ where it's not practical to get at the region model, or for special
+ analyzer functions such as __analyzer_dump. */
+
+bool
+is_special_named_call_p (const gcall *call, const char *funcname,
+ unsigned int num_args)
+{
+ gcc_assert (funcname);
+
+ tree fndecl = gimple_call_fndecl (call);
+ if (!fndecl)
+ return false;
+
+ return is_named_call_p (fndecl, funcname, call, num_args);
+}
+
+/* Helper function for checkers. Does FNDECL have the given FUNCNAME? */
+
+bool
+is_named_call_p (tree fndecl, const char *funcname)
+{
+ gcc_assert (fndecl);
+ gcc_assert (funcname);
+
+ return 0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname);
+}
+
+/* Helper function for checkers. Does FNDECL have the given FUNCNAME, and
+ does CALL have the given number of arguments? */
+
+bool
+is_named_call_p (tree fndecl, const char *funcname,
+ const gcall *call, unsigned int num_args)
+{
+ gcc_assert (fndecl);
+ gcc_assert (funcname);
+
+ if (!is_named_call_p (fndecl, funcname))
+ return false;
+
+ if (gimple_call_num_args (call) != num_args)
+ return false;
+
+ return true;
+}
+
+/* Return true if stmt is a setjmp call. */
+
+bool
+is_setjmp_call_p (const gimple *stmt)
+{
+ /* TODO: is there a less hacky way to check for "setjmp"? */
+ if (const gcall *call = dyn_cast <const gcall *> (stmt))
+ if (is_special_named_call_p (call, "_setjmp", 1))
+ return true;
+
+ return false;
+}
+
+/* Return true if stmt is a longjmp call. */
+
+bool
+is_longjmp_call_p (const gcall *call)
+{
+ /* TODO: is there a less hacky way to check for "longjmp"? */
+ if (is_special_named_call_p (call, "longjmp", 2))
+ return true;
+
+ return false;
+}
+
+/* Generate a label_text instance by formatting FMT, using a
+ temporary clone of the global_dc's printer (thus using its
+ formatting callbacks).
+
+ Colorize if the global_dc supports colorization and CAN_COLORIZE is
+ true. */
+
+label_text
+make_label_text (bool can_colorize, const char *fmt, ...)
+{
+ pretty_printer *pp = global_dc->printer->clone ();
+ pp_clear_output_area (pp);
+
+ if (!can_colorize)
+ pp_show_color (pp) = false;
+
+ 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 = ≈
+ ti.err_no = 0;
+ ti.x_data = NULL;
+ ti.m_richloc = &rich_loc;
+
+ pp_format (pp, &ti);
+ pp_output_formatted_text (pp);
+
+ va_end (ap);
+
+ label_text result = label_text::take (xstrdup (pp_formatted_text (pp)));
+ delete pp;
+ return result;
+}
+
+#endif /* #if ENABLE_ANALYZER */
new file mode 100644
@@ -0,0 +1,124 @@
+/* Utility functions for the analyzer.
+ Copyright (C) 2019-2020 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
+
+#include "function.h"
+
+/* Forward decls of common types, with indentation to show inheritance. */
+
+class graphviz_out;
+class supergraph;
+class supernode;
+class superedge;
+ class cfg_superedge;
+ class switch_cfg_superedge;
+ class callgraph_superedge;
+ class call_superedge;
+ class return_superedge;
+class svalue;
+ class region_svalue;
+ class constant_svalue;
+ class poisoned_svalue;
+ class unknown_svalue;
+ class setjmp_svalue;
+class region;
+ class map_region;
+ class symbolic_region;
+class region_model;
+class region_model_context;
+ class impl_region_model_context;
+class constraint_manager;
+class equiv_class;
+struct model_merger;
+struct svalue_id_merger_mapping;
+struct canonicalization;
+class pending_diagnostic;
+class state_change_event;
+class checker_path;
+class extrinsic_state;
+class sm_state_map;
+class stmt_finder;
+class program_point;
+class program_state;
+class exploded_graph;
+class exploded_node;
+class exploded_edge;
+class exploded_cluster;
+class exploded_path;
+class analysis_plan;
+class state_purge_map;
+class state_purge_per_ssa_name;
+class state_change;
+class rewind_info_t;
+
+extern bool is_special_named_call_p (const gcall *call, const char *funcname,
+ unsigned int num_args);
+extern bool is_named_call_p (tree fndecl, const char *funcname);
+extern bool is_named_call_p (tree fndecl, const char *funcname,
+ const gcall *call, unsigned int num_args);
+extern bool is_setjmp_call_p (const gimple *stmt);
+extern bool is_longjmp_call_p (const gcall *call);
+
+extern void register_analyzer_pass ();
+
+extern label_text make_label_text (bool can_colorize, const char *fmt, ...);
+
+/* 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")
+
+/* A template for creating hash traits for a POD type. */
+
+template <typename Type>
+struct pod_hash_traits : typed_noop_remove<Type>
+{
+ typedef Type value_type;
+ typedef Type compare_type;
+ static inline hashval_t hash (value_type);
+ static inline bool equal (const value_type &existing,
+ const value_type &candidate);
+ static inline void mark_deleted (Type &);
+ static inline void mark_empty (Type &);
+ static inline bool is_deleted (Type);
+ static inline bool is_empty (Type);
+};
+
+#endif /* GCC_ANALYZER_ANALYZER_H */