#include "analyzer/analyzer.h"
#include "analyzer/analyzer-language.h"
#include "analyzer/analyzer-logging.h"
+#include "diagnostic.h"
/* Map from identifier to INTEGER_CST. */
static GTY (()) hash_map <tree, tree> *analyzer_stashed_constants;
If found, stash its value within analyzer_stashed_constants. */
static void
-maybe_stash_named_constant (const translation_unit &tu, const char *name)
+maybe_stash_named_constant (logger *logger,
+ const translation_unit &tu,
+ const char *name)
{
+ LOG_FUNC_1 (logger, "name: %qs", name);
+
if (!analyzer_stashed_constants)
analyzer_stashed_constants = hash_map<tree, tree>::create_ggc ();
{
gcc_assert (TREE_CODE (t) == INTEGER_CST);
analyzer_stashed_constants->put (id, t);
+ if (logger)
+ logger->log ("%qs: %qE", name, t);
+ }
+ else
+ {
+ if (logger)
+ logger->log ("%qs: not found", name);
}
}
+/* Call into TU to try to find values for the names we care about.
+ If found, stash their values within analyzer_stashed_constants. */
+
+static void
+stash_named_constants (logger *logger, const translation_unit &tu)
+{
+ LOG_SCOPE (logger);
+
+ /* Stash named constants for use by sm-fd.cc */
+ maybe_stash_named_constant (logger, tu, "O_ACCMODE");
+ maybe_stash_named_constant (logger, tu, "O_RDONLY");
+ maybe_stash_named_constant (logger, tu, "O_WRONLY");
+ maybe_stash_named_constant (logger, tu, "SOCK_STREAM");
+ maybe_stash_named_constant (logger, tu, "SOCK_DGRAM");
+}
+
/* Hook for frontend to call into analyzer when TU finishes.
This exists so that the analyzer can stash named constant values from
header files (e.g. macros and enums) for later use when modeling the
if (!flag_analyzer)
return;
- /* Stash named constants for use by sm-fd.cc */
- maybe_stash_named_constant (tu, "O_ACCMODE");
- maybe_stash_named_constant (tu, "O_RDONLY");
- maybe_stash_named_constant (tu, "O_WRONLY");
- maybe_stash_named_constant (tu, "SOCK_STREAM");
- maybe_stash_named_constant (tu, "SOCK_DGRAM");
+ FILE *logfile = get_or_create_any_logfile ();
+ log_user the_logger (NULL);
+ if (logfile)
+ the_logger.set_logger (new logger (logfile, 0, 0,
+ *global_dc->printer));
+ stash_named_constants (the_logger.get_logger (), tu);
}
/* Lookup NAME in the named constants stashed when the frontend TU finished.
delete purge_map;
}
+/* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
+static FILE *dump_fout = NULL;
+
+/* Track if we're responsible for closing dump_fout. */
+static bool owns_dump_fout = false;
+
+/* If dumping is enabled, attempt to create dump_fout if it hasn't already
+ been opened. Return it. */
+
+FILE *
+get_or_create_any_logfile ()
+{
+ if (!dump_fout)
+ {
+ if (flag_dump_analyzer_stderr)
+ dump_fout = stderr;
+ else if (flag_dump_analyzer)
+ {
+ char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
+ dump_fout = fopen (dump_filename, "w");
+ free (dump_filename);
+ if (dump_fout)
+ owns_dump_fout = true;
+ }
+ }
+ return dump_fout;
+}
+
/* External entrypoint to the analysis "engine".
Set up any dumps, then call impl_run_checkers. */
/* Save input_location. */
location_t saved_input_location = input_location;
- /* Handle -fdump-analyzer and -fdump-analyzer-stderr. */
- FILE *dump_fout = NULL;
- /* Track if we're responsible for closing dump_fout. */
- bool owns_dump_fout = false;
- if (flag_dump_analyzer_stderr)
- dump_fout = stderr;
- else if (flag_dump_analyzer)
- {
- char *dump_filename = concat (dump_base_name, ".analyzer.txt", NULL);
- dump_fout = fopen (dump_filename, "w");
- free (dump_filename);
- if (dump_fout)
- owns_dump_fout = true;
- }
-
{
log_user the_logger (NULL);
+ get_or_create_any_logfile ();
if (dump_fout)
the_logger.set_logger (new logger (dump_fout, 0, 0,
*global_dc->printer));
}
if (owns_dump_fout)
- fclose (dump_fout);
+ {
+ fclose (dump_fout);
+ owns_dump_fout = false;
+ dump_fout = NULL;
+ }
/* Restore input_location. Subsequent passes may assume that input_location
is some arbitrary value *not* in the block tree, which might be violated