context->m_source_printing.max_width = value;
}
+namespace diagnostics {
+
/* Initialize the diagnostic message outputting machinery. */
void
-diagnostics::context::initialize (int n_opts)
+context::initialize (int n_opts)
{
/* Allocate a basic pretty-printer. Clients will replace this a
much more elaborated pretty-printer if they wish. */
m_max_errors = 0;
m_internal_error = nullptr;
m_adjust_diagnostic_info = nullptr;
- m_text_callbacks.m_begin_diagnostic = diagnostics::default_text_starter;
+ m_text_callbacks.m_begin_diagnostic = default_text_starter;
m_text_callbacks.m_text_start_span
- = diagnostics::default_start_span_fn<to_text>;
+ = default_start_span_fn<to_text>;
m_text_callbacks.m_html_start_span
- = diagnostics::default_start_span_fn<to_html>;
- m_text_callbacks.m_end_diagnostic = diagnostics::default_text_finalizer;
+ = default_start_span_fn<to_html>;
+ m_text_callbacks.m_end_diagnostic = default_text_finalizer;
m_option_mgr = nullptr;
m_urlifier_stack = new auto_vec<urlifier_stack_node> ();
m_last_location = UNKNOWN_LOCATION;
m_diagnostic_groups.m_diagnostic_nesting_level = 0;
m_diagnostic_groups.m_emission_count = 0;
m_diagnostic_groups.m_inhibiting_notes_from = 0;
- m_sinks.safe_push (new diagnostics::text_sink (*this, nullptr, true));
+ m_sinks.safe_push (new text_sink (*this, nullptr, true));
m_set_locations_cb = nullptr;
m_client_data_hooks = nullptr;
m_diagrams.m_theme = nullptr;
without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
void
-diagnostics::context::color_init (int value)
+context::color_init (int value)
{
/* value == -1 is the default value. */
if (value < 0)
handling "auto". */
void
-diagnostics::context::urls_init (int value)
+context::urls_init (int value)
{
/* value == -1 is the default value. */
if (value < 0)
/* Create the file_cache, if not already created, and tell it how to
translate files on input. */
void
-diagnostics::context::
-initialize_input_context (diagnostic_input_charset_callback ccb,
- bool should_skip_bom)
+context::initialize_input_context (diagnostic_input_charset_callback ccb,
+ bool should_skip_bom)
{
m_file_cache->initialize_input_context (ccb, should_skip_bom);
}
/* Do any cleaning up required after the last diagnostic is emitted. */
void
-diagnostics::context::finish ()
+context::finish ()
{
/* We might be handling a fatal error.
Close any active diagnostic groups, which may trigger flushing
/* Dump state of this diagnostics::context to OUT, for debugging. */
void
-diagnostics::context::dump (FILE *out) const
+context::dump (FILE *out) const
{
fprintf (out, "diagnostics::context:\n");
m_diagnostic_counters.dump (out, 2);
we ought to exit with a non-zero exit code. */
bool
-diagnostics::context::execution_failed_p () const
+context::execution_failed_p () const
{
/* Equivalent to (seen_error () || werrorcount), but on
this context, rather than global_dc. */
}
void
-diagnostics::context::remove_all_output_sinks ()
+context::remove_all_output_sinks ()
{
while (!m_sinks.is_empty ())
delete m_sinks.pop ();
}
void
-diagnostics::context::set_sink (std::unique_ptr<diagnostics::sink> sink_)
+context::set_sink (std::unique_ptr<sink> sink_)
{
remove_all_output_sinks ();
m_sinks.safe_push (sink_.release ());
}
-diagnostics::sink &
-diagnostics::context::get_sink (size_t idx) const
+sink &
+context::get_sink (size_t idx) const
{
gcc_assert (idx < m_sinks.length ());
gcc_assert (m_sinks[idx]);
}
void
-diagnostics::context::add_sink (std::unique_ptr<diagnostics::sink> sink_)
+context::add_sink (std::unique_ptr<sink> sink_)
{
m_sinks.safe_push (sink_.release ());
}
/* Return true if there are no machine-readable formats writing to stderr. */
bool
-diagnostics::context::supports_fnotice_on_stderr_p () const
+context::supports_fnotice_on_stderr_p () const
{
for (auto sink_ : m_sinks)
if (sink_->machine_readable_stderr_p ())
}
void
-diagnostics::context::set_main_input_filename (const char *filename)
+context::set_main_input_filename (const char *filename)
{
for (auto sink_ : m_sinks)
sink_->set_main_input_filename (filename);
}
void
-diagnostics::context::
-set_client_data_hooks (std::unique_ptr<diagnostics::client_data_hooks> hooks)
+context::set_client_data_hooks (std::unique_ptr<client_data_hooks> hooks)
{
delete m_client_data_hooks;
/* Ideally the field would be a std::unique_ptr here. */
}
void
-diagnostics::context::set_original_argv (unique_argv original_argv)
+context::set_original_argv (unique_argv original_argv)
{
/* Ideally we'd use a unique_argv for m_original_argv, but
diagnostics::context doesn't yet have a ctor/dtor pair. */
}
void
-diagnostics::context::
-set_option_manager (std::unique_ptr<diagnostics::option_manager> mgr,
- unsigned lang_mask)
+context::set_option_manager (std::unique_ptr<option_manager> mgr,
+ unsigned lang_mask)
{
delete m_option_mgr;
m_option_mgr = mgr.release ();
}
void
-diagnostics::context::push_owned_urlifier (std::unique_ptr<urlifier> ptr)
+context::push_owned_urlifier (std::unique_ptr<urlifier> ptr)
{
gcc_assert (m_urlifier_stack);
const urlifier_stack_node node = { ptr.release (), true };
}
void
-diagnostics::context::push_borrowed_urlifier (const urlifier &loan)
+context::push_borrowed_urlifier (const urlifier &loan)
{
gcc_assert (m_urlifier_stack);
const urlifier_stack_node node = { const_cast <urlifier *> (&loan), false };
}
void
-diagnostics::context::pop_urlifier ()
+context::pop_urlifier ()
{
gcc_assert (m_urlifier_stack);
gcc_assert (m_urlifier_stack->length () > 0);
delete node.m_urlifier;
}
-const diagnostics::logical_locations::manager *
-diagnostics::context::get_logical_location_manager () const
+const logical_locations::manager *
+context::get_logical_location_manager () const
{
if (!m_client_data_hooks)
return nullptr;
}
const urlifier *
-diagnostics::context::get_urlifier () const
+context::get_urlifier () const
{
if (!m_urlifier_stack)
return nullptr;
Refresh all output sinks. */
void
-diagnostics::context::set_pretty_printer (std::unique_ptr<pretty_printer> pp)
+context::set_pretty_printer (std::unique_ptr<pretty_printer> pp)
{
delete m_reference_printer;
m_reference_printer = pp.release ();
/* Give all output sinks a chance to rebuild their pretty_printer. */
void
-diagnostics::context::refresh_output_sinks ()
+context::refresh_output_sinks ()
{
for (auto sink_ : m_sinks)
sink_->update_printer ();
of all output sinks. */
void
-diagnostics::context::set_format_decoder (printer_fn format_decoder)
+context::set_format_decoder (printer_fn format_decoder)
{
pp_format_decoder (m_reference_printer) = format_decoder;
for (auto sink_ : m_sinks)
}
void
-diagnostics::context::set_show_highlight_colors (bool val)
+context::set_show_highlight_colors (bool val)
{
pp_show_highlight_colors (m_reference_printer) = val;
for (auto sink_ : m_sinks)
}
void
-diagnostics::context::set_prefixing_rule (diagnostic_prefixing_rule_t rule)
+context::set_prefixing_rule (diagnostic_prefixing_rule_t rule)
{
pp_prefixing_rule (m_reference_printer) = rule;
for (auto sink_ : m_sinks)
}
void
-diagnostics::context::initialize_fixits_change_set ()
+context::initialize_fixits_change_set ()
{
delete m_fixits_change_set;
gcc_assert (m_file_cache);
- m_fixits_change_set = new diagnostics::changes::change_set (*m_file_cache);
+ m_fixits_change_set = new changes::change_set (*m_file_cache);
}
+} // namespace diagnostics
+
/* Initialize DIAGNOSTIC, where the message MSG has already been
translated. */
void
return diagnostic_kind_color[static_cast<int> (kind)];
}
-} // namespace diagnostics
-
/* Given an expanded_location, convert the column (which is in 1-based bytes)
to the requested units, without converting the origin.
Return -1 if the column is invalid (<= 0). */
}
}
-diagnostics::column_policy::column_policy (const diagnostics::context &dc)
+column_policy::column_policy (const context &dc)
: m_file_cache (dc.get_file_cache ()),
m_column_unit (dc.m_column_unit),
m_column_origin (dc.m_column_origin),
to the requested units and origin. Return -1 if the column is
invalid (<= 0). */
int
-diagnostics::column_policy::converted_column (expanded_location s) const
+column_policy::converted_column (expanded_location s) const
{
int one_based_col = convert_column_unit (m_file_cache,
m_column_unit, m_tabstop, s);
/* Return a string describing a location e.g. "foo.c:42:10". */
label_text
-diagnostics::column_policy::get_location_text (const expanded_location &s,
- bool show_column,
- bool colorize) const
+column_policy::get_location_text (const expanded_location &s,
+ bool show_column,
+ bool colorize) const
{
const char *locus_cs = colorize_start (colorize, "locus");
const char *locus_ce = colorize_stop (colorize);
col = converted_column (s);
}
- const char *line_col = diagnostics::maybe_line_and_column (line, col);
+ const char *line_col = maybe_line_and_column (line, col);
return label_text::take (build_message_string ("%s%s%s:%s", locus_cs, file,
line_col, locus_ce));
}
-diagnostics::location_print_policy::
-location_print_policy (const diagnostics::context &dc)
+location_print_policy::
+location_print_policy (const context &dc)
: m_column_policy (dc),
m_show_column (dc.m_show_column)
{
}
-diagnostics::location_print_policy::
-location_print_policy (const diagnostics::text_sink &text_output)
+location_print_policy::
+location_print_policy (const text_sink &text_output)
:
m_column_policy (text_output.get_context ()),
m_show_column (text_output.get_context ().m_show_column)
{
}
+} // namespace diagnostics
+
/* Functions at which to stop the backtrace print. It's not
particularly helpful to print the callers of these functions. */
if (filename == nullptr && function == nullptr)
return 0;
- /* Skip functions in diagnostic.cc. */
+ /* Skip functions in context.cc. */
if (*pcount == 0
&& filename != nullptr
- && strcmp (lbasename (filename), "diagnostic.cc") == 0)
+ && strcmp (lbasename (filename), "context.cc") == 0)
return 0;
/* Print up to 20 functions. We could make this a --param, but
errnum == 0 ? "" : xstrerror (errnum));
}
+namespace diagnostics {
+
/* Check if we've met the maximum error limit, and if so fatally exit
with a message.
FLUSH indicates whether a diagnostics::context::finish call is needed. */
void
-diagnostics::context::check_max_errors (bool flush)
+context::check_max_errors (bool flush)
{
if (!m_max_errors)
return;
is written out. This function does not always return. */
void
-diagnostics::context::action_after_output (enum kind diag_kind)
+context::action_after_output (enum kind diag_kind)
{
switch (diag_kind)
{
its future children if any. */
void
-diagnostics::context::inhibit_notes_in_group (bool inhibit)
+context::inhibit_notes_in_group (bool inhibit)
{
int curr_depth = (m_diagnostic_groups.m_group_nesting_depth
+ m_diagnostic_groups.m_diagnostic_nesting_level);
/* Return whether notes must be inhibited in the current diagnostic_group. */
bool
-diagnostics::context::notes_inhibited_in_group () const
+context::notes_inhibited_in_group () const
{
if (m_diagnostic_groups.m_inhibiting_notes_from
&& (m_diagnostic_groups.m_group_nesting_depth
/* Return true iff this is a function or method. */
bool
-diagnostics::logical_locations::manager::function_p (key k) const
+logical_locations::manager::function_p (key k) const
{
switch (get_kind (k))
{
/* Update the inlining info in this context for a DIAGNOSTIC. */
void
-diagnostics::context::get_any_inlining_info (diagnostic_info *diagnostic)
+context::get_any_inlining_info (diagnostic_info *diagnostic)
{
auto &ilocs = diagnostic->m_iinfo.m_ilocs;
as appropriate for #pragma GCC diagnostic and -Werror=foo. */
bool
-diagnostics::context::diagnostic_enabled (diagnostic_info *diagnostic)
+context::diagnostic_enabled (diagnostic_info *diagnostic)
{
/* Update the inlining stack for this diagnostic. */
get_any_inlining_info (diagnostic);
/* Returns whether warning OPT_ID is enabled at LOC. */
bool
-diagnostics::context::warning_enabled_at (location_t loc,
- diagnostics::option_id opt_id)
+context::warning_enabled_at (location_t loc,
+ option_id opt_id)
{
if (!diagnostic_report_warnings_p (this, loc))
return false;
/* Emit a diagnostic within a diagnostic group on this context. */
bool
-diagnostics::context::
-emit_diagnostic_with_group (enum kind kind,
- rich_location &richloc,
- const diagnostics::metadata *metadata,
- diagnostics::option_id opt_id,
- const char *gmsgid, ...)
+context::emit_diagnostic_with_group (enum kind kind,
+ rich_location &richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ const char *gmsgid, ...)
{
begin_group ();
/* As above, but taking a va_list *. */
bool
-diagnostics::context::
-emit_diagnostic_with_group_va (enum kind kind,
- rich_location &richloc,
- const diagnostics::metadata *metadata,
- diagnostics::option_id opt_id,
- const char *gmsgid, va_list *ap)
+context::emit_diagnostic_with_group_va (enum kind kind,
+ rich_location &richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ const char *gmsgid, va_list *ap)
{
begin_group ();
Return true if a diagnostic was printed, false otherwise. */
bool
-diagnostics::context::report_diagnostic (diagnostic_info *diagnostic)
+context::report_diagnostic (diagnostic_info *diagnostic)
{
enum kind orig_diag_kind = diagnostic->m_kind;
}
void
-diagnostics::context::report_verbatim (text_info &text)
+context::report_verbatim (text_info &text)
{
va_list *orig_args = text.m_args_ptr;
for (auto sink_ : m_sinks)
}
void
-diagnostics::context::
-report_global_digraph (const diagnostics::digraphs::lazy_digraph &ldg)
+context::report_global_digraph (const digraphs::lazy_digraph &ldg)
{
for (auto sink_ : m_sinks)
sink_->report_global_digraph (ldg);
return digits;
}
+} // namespace diagnostics
+
/* Given a partial pathname as input, return another pathname that
shares no directory elements with the pathname of __FILE__. This
is used by fancy_abort() to print `internal compiler error in expr.cc'
return p;
}
+namespace diagnostics {
+
/* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
and internal_error_no_backtrace, as documented and defined below. */
bool
-diagnostics::context::diagnostic_impl (rich_location *richloc,
- const diagnostics::metadata *metadata,
- diagnostics::option_id opt_id,
- const char *gmsgid,
- va_list *ap, enum kind kind)
+context::diagnostic_impl (rich_location *richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ const char *gmsgid,
+ va_list *ap, enum kind kind)
{
diagnostic_info diagnostic;
if (kind == kind::permerror)
/* Implement inform_n, warning_n, and error_n, as documented and
defined below. */
bool
-diagnostics::context::diagnostic_n_impl (rich_location *richloc,
- const diagnostics::metadata *metadata,
- diagnostics::option_id opt_id,
- unsigned HOST_WIDE_INT n,
- const char *singular_gmsgid,
- const char *plural_gmsgid,
- va_list *ap, enum kind kind)
+context::diagnostic_n_impl (rich_location *richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ unsigned HOST_WIDE_INT n,
+ const char *singular_gmsgid,
+ const char *plural_gmsgid,
+ va_list *ap, enum kind kind)
{
diagnostic_info diagnostic;
unsigned long gtn;
/* Emit DIAGRAM to this context, respecting the output format. */
void
-diagnostics::context::emit_diagram (const diagnostics::diagram &diag)
+context::emit_diagram (const diagram &diag)
{
if (m_diagrams.m_theme == nullptr)
return;
This mustn't use internal_error, that will cause infinite recursion. */
void
-diagnostics::context::error_recursion ()
+context::error_recursion ()
{
if (m_lock < 3)
pp_newline_and_flush (m_reference_printer);
real_abort ();
}
+} // namespace diagnostics
+
/* Report an internal compiler error in a friendly manner. This is
the function that gets called upon use of abort() in the source
code generally, thanks to a special macro. */
internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
}
+namespace diagnostics {
+
/* class diagnostics::context. */
void
-diagnostics::context::begin_group ()
+context::begin_group ()
{
m_diagnostic_groups.m_group_nesting_depth++;
}
void
-diagnostics::context::end_group ()
+context::end_group ()
{
if (--m_diagnostic_groups.m_group_nesting_depth == 0)
{
}
void
-diagnostics::context::push_nesting_level ()
+context::push_nesting_level ()
{
++m_diagnostic_groups.m_diagnostic_nesting_level;
}
void
-diagnostics::context::pop_nesting_level ()
+context::pop_nesting_level ()
{
--m_diagnostic_groups.m_diagnostic_nesting_level;
/* We're popping one level, so might need to stop inhibiting notes. */
}
void
-diagnostics::sink::dump (FILE *out, int indent) const
+sink::dump (FILE *out, int indent) const
{
fprintf (out, "%*sprinter:\n", indent, "");
m_printer->dump (out, indent + 2);
}
void
-diagnostics::sink::on_report_verbatim (text_info &)
+sink::on_report_verbatim (text_info &)
{
/* No-op. */
}
-/* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for
+/* Set the output format for DC to FORMAT, using BASE_FILE_NAME for
file-based output formats. */
void
-diagnostics::output_format_init (diagnostics::context &context,
- const char *main_input_filename_,
- const char *base_file_name,
- enum diagnostics_output_format format,
- bool json_formatting)
+output_format_init (context &dc,
+ const char *main_input_filename_,
+ const char *base_file_name,
+ enum diagnostics_output_format format,
+ bool json_formatting)
{
- diagnostics::sink *new_sink = nullptr;
+ sink *new_sink = nullptr;
switch (format)
{
default:
break;
case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR:
- new_sink = &diagnostics::init_sarif_stderr (context,
- line_table,
- json_formatting);
+ new_sink = &init_sarif_stderr (dc,
+ line_table,
+ json_formatting);
break;
case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE:
- new_sink = &diagnostics::init_sarif_file (context,
- line_table,
- json_formatting,
- base_file_name);
+ new_sink = &init_sarif_file (dc,
+ line_table,
+ json_formatting,
+ base_file_name);
break;
}
if (new_sink)
(or nullptr for "no diagrams"). */
void
-diagnostics::context::
-set_text_art_charset (enum diagnostic_text_art_charset charset)
+context::set_text_art_charset (enum diagnostic_text_art_charset charset)
{
delete m_diagrams.m_theme;
switch (charset)
/* struct diagnostics::counters. */
-diagnostics::counters::counters ()
+counters::counters ()
{
clear ();
}
void
-diagnostics::counters::dump (FILE *out, int indent) const
+counters::dump (FILE *out, int indent) const
{
fprintf (out, "%*scounts:\n", indent, "");
bool none = true;
}
void
-diagnostics::counters::move_to (diagnostics::counters &dest)
+counters::move_to (counters &dest)
{
for (int i = 0; i < static_cast<int> (kind::last_diagnostic_kind); i++)
dest.m_count_for_kind[i] += m_count_for_kind[i];
}
void
-diagnostics::counters::clear ()
+counters::clear ()
{
memset (&m_count_for_kind, 0, sizeof m_count_for_kind);
}
-/* Really call the system 'abort'. This has to go right at the end of
- this file, so that there are no functions after it that call abort
- and get the system abort instead of our macro. */
-#undef abort
-static void
-real_abort (void)
-{
- abort ();
-}
-
#if CHECKING_P
namespace selftest {
+using line_table_test = ::selftest::line_table_test;
+using temp_source_file = ::selftest::temp_source_file;
+
/* Helper function for test_print_escaped_string. */
static void
-assert_print_escaped_string (const location &loc, const char *expected_output,
+assert_print_escaped_string (const ::selftest::location &loc,
+ const char *expected_output,
const char *input)
{
pretty_printer pp;
ASSERT_EQ (8, num_digits (99999999));
}
-/* Run all of the selftests within this file. */
+/* Run all of the selftests within this file.
+
+ According to https://gcc.gnu.org/pipermail/gcc/2021-November/237703.html
+ there are some language-specific assumptions within these tests, so only
+ run them from C/C++. */
void
-c_diagnostic_cc_tests ()
+context_cc_tests ()
{
test_print_escaped_string ();
test_print_parseable_fixits_none ();
test_num_digits ();
}
-} // namespace selftest
+} // namespace diagnostics::selftest
+} // namespace diagnostics
#endif /* #if CHECKING_P */
#if __GNUC__ >= 10
# pragma GCC diagnostic pop
#endif
+
+static void real_abort (void) ATTRIBUTE_NORETURN;
+
+/* Really call the system 'abort'. This has to go right at the end of
+ this file, so that there are no functions after it that call abort
+ and get the system abort instead of our macro. */
+#undef abort
+static void
+real_abort (void)
+{
+ abort ();
+}