aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostics/context.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/diagnostics/context.h')
-rw-r--r--gcc/diagnostics/context.h959
1 files changed, 959 insertions, 0 deletions
diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h
new file mode 100644
index 0000000..f47370b
--- /dev/null
+++ b/gcc/diagnostics/context.h
@@ -0,0 +1,959 @@
+/* Declare diagnostics::context and related types.
+ Copyright (C) 2000-2025 Free Software Foundation, Inc.
+
+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_DIAGNOSTICS_CONTEXT_H
+#define GCC_DIAGNOSTICS_CONTEXT_H
+
+#include "lazily-created.h"
+#include "unique-argv.h"
+#include "diagnostics/option-classifier.h"
+#include "diagnostics/context-options.h"
+
+namespace diagnostics {
+
+ namespace changes {
+ class change_set;
+ }
+
+ namespace digraphs { class digraph; }
+
+ namespace logical_locations {
+ class manager;
+ }
+
+ class buffer;
+ class client_data_hooks;
+ class diagram;
+ class sink;
+ class text_sink;
+
+ class source_effect_info;
+
+} // namespace diagnostics
+
+namespace text_art
+{
+ class theme;
+} // namespace text_art
+
+namespace xml
+{
+ class printer;
+} // namespace xml
+
+namespace diagnostics {
+
+/* Forward declarations. */
+class context;
+class location_print_policy;
+class source_print_policy;
+
+typedef void (*text_starter_fn) (text_sink &,
+ const diagnostic_info *);
+
+struct to_text;
+struct to_html;
+
+extern pretty_printer *get_printer (to_text &);
+
+template <typename TextOrHtml>
+using start_span_fn = void (*) (const location_print_policy &,
+ TextOrHtml &text_or_html,
+ expanded_location);
+
+typedef void (*text_finalizer_fn) (text_sink &,
+ const diagnostic_info *,
+ enum kind);
+
+/* Abstract base class for the diagnostic subsystem to make queries
+ about command-line options. */
+
+class option_manager
+{
+public:
+ virtual ~option_manager () {}
+
+ /* Return 1 if option OPT_ID is enabled, 0 if it is disabled,
+ or -1 if it isn't a simple on-off switch
+ (or if the value is unknown, typically set later in target). */
+ virtual int option_enabled_p (option_id opt_id) const = 0;
+
+ /* Return malloced memory for the name of the option OPT_ID
+ which enabled a diagnostic, originally of type ORIG_DIAG_KIND but
+ possibly converted to DIAG_KIND by options such as -Werror.
+ May return NULL if no name is to be printed.
+ May be passed 0 as well as the index of a particular option. */
+ virtual char *make_option_name (option_id opt_id,
+ enum kind orig_diag_kind,
+ enum kind diag_kind) const = 0;
+
+ /* Return malloced memory for a URL describing the option that controls
+ a diagnostic.
+ May return NULL if no URL is available.
+ May be passed 0 as well as the index of a particular option. */
+ virtual char *make_option_url (option_id opt_id) const = 0;
+};
+
+/* A bundle of options relating to printing the user's source code
+ (potentially with a margin, underlining, labels, etc). */
+
+struct source_printing_options
+{
+ /* True if we should print the source line with a caret indicating
+ the location.
+ Corresponds to -fdiagnostics-show-caret. */
+ bool enabled;
+
+ /* Maximum width of the source line printed. */
+ int max_width;
+
+ /* Character used at the caret when printing source locations. */
+ char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
+
+ /* When printing source code, should the characters at carets and ranges
+ be colorized? (assuming colorization is on at all).
+ This should be true for frontends that generate range information
+ (so that the ranges of code are colorized),
+ and false for frontends that merely specify points within the
+ source code (to avoid e.g. colorizing just the first character in
+ a token, which would look strange). */
+ bool colorize_source_p;
+
+ /* When printing source code, should labelled ranges be printed?
+ Corresponds to -fdiagnostics-show-labels. */
+ bool show_labels_p;
+
+ /* When printing source code, should there be a left-hand margin
+ showing line numbers?
+ Corresponds to -fdiagnostics-show-line-numbers. */
+ bool show_line_numbers_p;
+
+ /* If printing source code, what should the minimum width of the margin
+ be? Line numbers will be right-aligned, and padded to this width.
+ Corresponds to -fdiagnostics-minimum-margin-width=VALUE. */
+ int min_margin_width;
+
+ /* Usable by plugins; if true, print a debugging ruler above the
+ source output. */
+ bool show_ruler_p;
+
+ /* When printing events in an inline path, should we print lines
+ visualizing links between related events (e.g. for CFG paths)?
+ Corresponds to -fdiagnostics-show-event-links. */
+ bool show_event_links_p;
+};
+
+/* A bundle of state for determining column numbers in diagnostics
+ (tab stops, whether to start at 0 or 1, etc).
+ Uses a file_cache to handle tabs. */
+
+class column_policy
+{
+public:
+ column_policy (const context &dc);
+
+ int converted_column (expanded_location s) const;
+
+ label_text get_location_text (const expanded_location &s,
+ bool show_column,
+ bool colorize) const;
+
+ int get_tabstop () const { return m_tabstop; }
+
+private:
+ file_cache &m_file_cache;
+ enum diagnostics_column_unit m_column_unit;
+ int m_column_origin;
+ int m_tabstop;
+};
+
+/* A bundle of state for printing locations within diagnostics
+ (e.g. "FILENAME:LINE:COLUMN"), to isolate the interactions between
+ context and the start_span callbacks. */
+
+class location_print_policy
+{
+public:
+ location_print_policy (const context &dc);
+ location_print_policy (const text_sink &);
+
+ bool show_column_p () const { return m_show_column; }
+
+ const column_policy &
+ get_column_policy () const { return m_column_policy; }
+
+ void
+ print_text_span_start (const context &dc,
+ pretty_printer &pp,
+ const expanded_location &exploc);
+
+ void
+ print_html_span_start (const context &dc,
+ xml::printer &xp,
+ const expanded_location &exploc);
+
+private:
+ column_policy m_column_policy;
+ bool m_show_column;
+};
+
+/* Abstract base class for optionally supplying extra tags when writing
+ out annotation labels in HTML output. */
+
+class html_label_writer
+{
+public:
+ virtual ~html_label_writer () {}
+ virtual void begin_label () = 0;
+ virtual void end_label () = 0;
+};
+
+/* A bundle of state for printing source within a diagnostic,
+ to isolate the interactions between context and the
+ implementation of diagnostic_show_locus. */
+
+class source_print_policy
+{
+public:
+ source_print_policy (const context &);
+ source_print_policy (const context &,
+ const source_printing_options &);
+
+ void
+ print (pretty_printer &pp,
+ const rich_location &richloc,
+ enum kind diagnostic_kind,
+ source_effect_info *effect_info) const;
+
+ void
+ print_as_html (xml::printer &xp,
+ const rich_location &richloc,
+ enum kind diagnostic_kind,
+ source_effect_info *effect_info,
+ html_label_writer *label_writer) const;
+
+ const source_printing_options &
+ get_options () const { return m_options; }
+
+ start_span_fn<to_text>
+ get_text_start_span_fn () const { return m_text_start_span_cb; }
+
+ start_span_fn<to_html>
+ get_html_start_span_fn () const { return m_html_start_span_cb; }
+
+ file_cache &
+ get_file_cache () const { return m_file_cache; }
+
+ enum diagnostics_escape_format
+ get_escape_format () const
+ {
+ return m_escape_format;
+ }
+
+ text_art::theme *
+ get_diagram_theme () const { return m_diagram_theme; }
+
+ const column_policy &get_column_policy () const
+ {
+ return m_location_policy.get_column_policy ();
+ }
+
+ const location_print_policy &get_location_policy () const
+ {
+ return m_location_policy;
+ }
+
+private:
+ const source_printing_options &m_options;
+ location_print_policy m_location_policy;
+ start_span_fn<to_text> m_text_start_span_cb;
+ start_span_fn<to_html> m_html_start_span_cb;
+ file_cache &m_file_cache;
+
+ /* Other data copied from context. */
+ text_art::theme *m_diagram_theme;
+ enum diagnostics_escape_format m_escape_format;
+};
+
+/* A collection of counters of diagnostics, per-kind
+ (e.g. "3 errors and 1 warning"), for use by both context
+ and by diagnostics::buffer. */
+
+struct counters
+{
+ counters ();
+
+ void dump (FILE *out, int indent) const;
+ void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
+
+ int get_count (enum kind kind) const
+ {
+ return m_count_for_kind[static_cast<size_t> (kind)];
+ }
+
+ void move_to (counters &dest);
+ void clear ();
+
+ int m_count_for_kind[static_cast<size_t> (kind::last_diagnostic_kind)];
+};
+
+/* This class encapsulates the state of the diagnostics subsystem
+ as a whole (either directly, or via owned objects of other classes, to
+ avoid global variables).
+
+ It has responsibility for:
+ - being a central place for clients to report diagnostics
+ - reporting those diagnostics to zero or more output sinks
+ (e.g. text vs SARIF)
+ - providing a "dump" member function for a debug dump of the state of
+ the diagnostics subsytem
+ - direct vs buffered diagnostics (see class diagnostics::buffer)
+ - tracking the original argv of the program (for SARIF output)
+ - crash-handling
+
+ It delegates responsibility to various other classes:
+ - the various output sinks (instances of diagnostics::sink
+ subclasses)
+ - formatting of messages (class pretty_printer)
+ - an optional urlifier to inject URLs into formatted messages
+ - counting the number of diagnostics reported of each kind
+ (class diagnostics::counters)
+ - calling out to a option_manager to determine if
+ a particular warning is enabled or disabled
+ - tracking pragmas that enable/disable warnings in a range of
+ source code
+ - a cache for use when quoting the user's source code (class file_cache)
+ - a text_art::theme
+ - a diagnostics::changes::change_set for generating patches from fix-it hints
+ - diagnostics::client_data_hooks for metadata.
+
+ Try to avoid adding new responsibilities to this class itself, to avoid
+ the "blob" anti-pattern. */
+
+class context
+{
+public:
+ /* Give access to m_text_callbacks. */
+ // FIXME: these need updating
+ friend text_starter_fn &
+ text_starter (context *dc);
+ friend start_span_fn<to_text> &
+ start_span (context *dc);
+ friend text_finalizer_fn &
+ text_finalizer (context *dc);
+
+ friend class source_print_policy;
+ friend class text_sink;
+ friend class buffer;
+
+ typedef void (*set_locations_callback_t) (context *,
+ diagnostic_info *);
+
+ void initialize (int n_opts);
+ void color_init (int value);
+ void urls_init (int value);
+ void set_pretty_printer (std::unique_ptr<pretty_printer> pp);
+ void refresh_output_sinks ();
+
+ void finish ();
+
+ void dump (FILE *out) const;
+ void DEBUG_FUNCTION dump () const { dump (stderr); }
+
+ bool execution_failed_p () const;
+
+ void set_original_argv (unique_argv original_argv);
+ const char * const *get_original_argv ()
+ {
+ return const_cast<const char * const *> (m_original_argv);
+ }
+
+ void set_set_locations_callback (set_locations_callback_t cb)
+ {
+ m_set_locations_cb = cb;
+ }
+
+ void
+ initialize_input_context (diagnostic_input_charset_callback ccb,
+ bool should_skip_bom);
+
+ void begin_group ();
+ void end_group ();
+
+ void push_nesting_level ();
+ void pop_nesting_level ();
+
+ bool warning_enabled_at (location_t loc, option_id opt_id);
+
+ bool option_unspecified_p (option_id opt_id) const
+ {
+ return m_option_classifier.option_unspecified_p (opt_id);
+ }
+
+ bool emit_diagnostic_with_group (enum kind kind,
+ rich_location &richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ const char *gmsgid, ...)
+ ATTRIBUTE_GCC_DIAG(6,7);
+ bool emit_diagnostic_with_group_va (enum kind kind,
+ rich_location &richloc,
+ const metadata *metadata,
+ option_id opt_id,
+ const char *gmsgid, va_list *ap)
+ ATTRIBUTE_GCC_DIAG(6,0);
+
+ bool report_diagnostic (diagnostic_info *);
+ void report_verbatim (text_info &);
+
+ /* Report a directed graph associated with the run as a whole
+ to any sinks that support directed graphs. */
+ void
+ report_global_digraph (const lazily_created<digraphs::digraph> &);
+
+ enum kind
+ classify_diagnostic (option_id opt_id,
+ enum kind new_kind,
+ location_t where)
+ {
+ return m_option_classifier.classify_diagnostic (this,
+ opt_id,
+ new_kind,
+ where);
+ }
+
+ void push_diagnostics (location_t where ATTRIBUTE_UNUSED)
+ {
+ m_option_classifier.push ();
+ }
+ void pop_diagnostics (location_t where)
+ {
+ m_option_classifier.pop (where);
+ }
+
+ void maybe_show_locus (const rich_location &richloc,
+ const source_printing_options &opts,
+ enum kind diagnostic_kind,
+ pretty_printer &pp,
+ source_effect_info *effect_info);
+ void maybe_show_locus_as_html (const rich_location &richloc,
+ const source_printing_options &opts,
+ enum kind diagnostic_kind,
+ xml::printer &xp,
+ source_effect_info *effect_info,
+ html_label_writer *label_writer);
+
+ void emit_diagram (const diagram &diag);
+
+ /* Various setters for use by option-handling logic. */
+ void set_sink (std::unique_ptr<sink> sink_);
+ void set_text_art_charset (enum diagnostic_text_art_charset charset);
+ void set_client_data_hooks (std::unique_ptr<client_data_hooks> hooks);
+
+ void push_owned_urlifier (std::unique_ptr<urlifier>);
+ void push_borrowed_urlifier (const urlifier &);
+ void pop_urlifier ();
+
+ void initialize_fixits_change_set ();
+ void set_warning_as_error_requested (bool val)
+ {
+ m_warning_as_error_requested = val;
+ }
+ void set_report_bug (bool val) { m_report_bug = val; }
+ void set_extra_output_kind (enum diagnostics_extra_output_kind kind)
+ {
+ m_extra_output_kind = kind;
+ }
+ void set_show_cwe (bool val) { m_show_cwe = val; }
+ void set_show_rules (bool val) { m_show_rules = val; }
+ void set_show_highlight_colors (bool val);
+ void set_path_format (enum diagnostic_path_format val)
+ {
+ m_path_format = val;
+ }
+ void set_show_path_depths (bool val) { m_show_path_depths = val; }
+ void set_show_option_requested (bool val) { m_show_option_requested = val; }
+ void set_max_errors (int val) { m_max_errors = val; }
+ void set_escape_format (enum diagnostics_escape_format val)
+ {
+ m_escape_format = val;
+ }
+
+ void set_format_decoder (printer_fn format_decoder);
+ void set_prefixing_rule (diagnostic_prefixing_rule_t rule);
+
+ /* Various accessors. */
+ bool warning_as_error_requested_p () const
+ {
+ return m_warning_as_error_requested;
+ }
+ bool show_path_depths_p () const { return m_show_path_depths; }
+ sink &get_sink (size_t idx) const;
+ enum diagnostic_path_format get_path_format () const { return m_path_format; }
+ enum diagnostics_escape_format get_escape_format () const
+ {
+ return m_escape_format;
+ }
+
+ file_cache &
+ get_file_cache () const
+ {
+ gcc_assert (m_file_cache);
+ return *m_file_cache;
+ }
+
+ changes::change_set *get_fixits_change_set () const
+ {
+ return m_fixits_change_set;
+ }
+ const client_data_hooks *get_client_data_hooks () const
+ {
+ return m_client_data_hooks;
+ }
+
+ const logical_locations::manager *
+ get_logical_location_manager () const;
+
+ const urlifier *get_urlifier () const;
+
+ text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
+
+ int &diagnostic_count (enum kind kind)
+ {
+ return m_diagnostic_counters.m_count_for_kind[static_cast<size_t> (kind)];
+ }
+ int diagnostic_count (enum kind kind) const
+ {
+ return m_diagnostic_counters.get_count (kind);
+ }
+
+ /* Option-related member functions. */
+ inline bool option_enabled_p (option_id opt_id) const
+ {
+ if (!m_option_mgr)
+ return true;
+ return m_option_mgr->option_enabled_p (opt_id);
+ }
+
+ inline char *make_option_name (option_id opt_id,
+ enum kind orig_diag_kind,
+ enum kind diag_kind) const
+ {
+ if (!m_option_mgr)
+ return nullptr;
+ return m_option_mgr->make_option_name (opt_id,
+ orig_diag_kind,
+ diag_kind);
+ }
+
+ inline char *make_option_url (option_id opt_id) const
+ {
+ if (!m_option_mgr)
+ return nullptr;
+ return m_option_mgr->make_option_url (opt_id);
+ }
+
+ void
+ set_option_manager (std::unique_ptr<option_manager> mgr,
+ unsigned lang_mask);
+
+ unsigned get_lang_mask () const
+ {
+ return m_lang_mask;
+ }
+
+ bool diagnostic_impl (rich_location *, const metadata *,
+ option_id, const char *,
+ va_list *, enum kind) ATTRIBUTE_GCC_DIAG(5,0);
+ bool diagnostic_n_impl (rich_location *, const metadata *,
+ option_id, unsigned HOST_WIDE_INT,
+ const char *, const char *, va_list *,
+ enum kind) ATTRIBUTE_GCC_DIAG(7,0);
+
+ int get_diagnostic_nesting_level () const
+ {
+ return m_diagnostic_groups.m_diagnostic_nesting_level;
+ }
+
+ char *build_indent_prefix () const;
+
+ int
+ pch_save (FILE *f)
+ {
+ return m_option_classifier.pch_save (f);
+ }
+
+ int
+ pch_restore (FILE *f)
+ {
+ return m_option_classifier.pch_restore (f);
+ }
+
+
+ void set_diagnostic_buffer (buffer *);
+ buffer *get_diagnostic_buffer () const
+ {
+ return m_diagnostic_buffer;
+ }
+ void clear_diagnostic_buffer (buffer &);
+ void flush_diagnostic_buffer (buffer &);
+
+ std::unique_ptr<pretty_printer> clone_printer () const
+ {
+ return m_reference_printer->clone ();
+ }
+
+ pretty_printer *get_reference_printer () const
+ {
+ return m_reference_printer;
+ }
+
+ void
+ add_sink (std::unique_ptr<sink>);
+
+ void remove_all_output_sinks ();
+
+ bool supports_fnotice_on_stderr_p () const;
+
+ /* Raise SIGABRT on any diagnostic of severity kind::error or higher. */
+ void
+ set_abort_on_error (bool val)
+ {
+ m_abort_on_error = val;
+ }
+
+ /* Accessor for use in serialization, e.g. by C++ modules. */
+ auto &
+ get_classification_history ()
+ {
+ return m_option_classifier.m_classification_history;
+ }
+
+ void set_main_input_filename (const char *filename);
+
+ void
+ set_permissive_option (option_id opt_permissive)
+ {
+ m_opt_permissive = opt_permissive;
+ }
+
+ void
+ set_fatal_errors (bool fatal_errors)
+ {
+ m_fatal_errors = fatal_errors;
+ }
+
+ void
+ set_internal_error_callback (void (*cb) (context *,
+ const char *,
+ va_list *))
+ {
+ m_internal_error = cb;
+ }
+
+ void
+ set_adjust_diagnostic_info_callback (void (*cb) (context *,
+ diagnostic_info *))
+ {
+ m_adjust_diagnostic_info = cb;
+ }
+
+ void
+ inhibit_notes () { m_inhibit_notes_p = true; }
+
+ source_printing_options &
+ get_source_printing_options ()
+ {
+ return m_source_printing;
+ }
+ const source_printing_options &
+ get_source_printing_options () const
+ {
+ return m_source_printing;
+ }
+
+ void set_caret_max_width (int value);
+
+private:
+ void error_recursion () ATTRIBUTE_NORETURN;
+
+ bool diagnostic_enabled (diagnostic_info *diagnostic);
+
+ void get_any_inlining_info (diagnostic_info *diagnostic);
+
+ void check_max_errors (bool flush);
+ void action_after_output (enum kind diag_kind);
+
+ /* Data members.
+ Ideally, all of these would be private. */
+
+private:
+ /* A reference instance of pretty_printer created by the client
+ and owned by the context. Used for cloning when creating/adding
+ output formats.
+ Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ pretty_printer *m_reference_printer;
+
+ /* Cache of source code.
+ Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ file_cache *m_file_cache;
+
+ /* The number of times we have issued diagnostics. */
+ counters m_diagnostic_counters;
+
+ /* True if it has been requested that warnings be treated as errors. */
+ bool m_warning_as_error_requested;
+
+ /* The number of option indexes that can be passed to warning() et
+ al. */
+ int m_n_opts;
+
+ /* The stack of sets of overridden diagnostic option severities. */
+ option_classifier m_option_classifier;
+
+ /* True if we should print any CWE identifiers associated with
+ diagnostics. */
+ bool m_show_cwe;
+
+ /* True if we should print any rules associated with diagnostics. */
+ bool m_show_rules;
+
+ /* How should diagnostics::paths::path objects be printed. */
+ enum diagnostic_path_format m_path_format;
+
+ /* True if we should print stack depths when printing diagnostic paths. */
+ bool m_show_path_depths;
+
+ /* True if we should print the command line option which controls
+ each diagnostic, if known. */
+ bool m_show_option_requested;
+
+ /* True if we should raise a SIGABRT on errors. */
+ bool m_abort_on_error;
+
+public:
+ /* True if we should show the column number on diagnostics. */
+ bool m_show_column;
+
+ /* True if pedwarns are errors. */
+ bool m_pedantic_errors;
+
+ /* True if permerrors are warnings. */
+ bool m_permissive;
+
+private:
+ /* The option to associate with turning permerrors into warnings,
+ if any. */
+ option_id m_opt_permissive;
+
+ /* True if errors are fatal. */
+ bool m_fatal_errors;
+
+public:
+ /* True if all warnings should be disabled. */
+ bool m_inhibit_warnings;
+
+ /* True if warnings should be given in system headers. */
+ bool m_warn_system_headers;
+
+private:
+ /* Maximum number of errors to report. */
+ int m_max_errors;
+
+ /* Client-supplied callbacks for use in text output. */
+ struct {
+ /* This function is called before any message is printed out. It is
+ responsible for preparing message prefix and such. For example, it
+ might say:
+ In file included from "/usr/local/include/curses.h:5:
+ from "/home/gdr/src/nifty_printer.h:56:
+ ...
+ */
+ text_starter_fn m_begin_diagnostic;
+
+ /* This function is called by diagnostic_show_locus in between
+ disjoint spans of source code, so that the context can print
+ something to indicate that a new span of source code has begun. */
+ start_span_fn<to_text> m_text_start_span;
+ start_span_fn<to_html> m_html_start_span;
+
+ /* This function is called after the diagnostic message is printed. */
+ text_finalizer_fn m_end_diagnostic;
+ } m_text_callbacks;
+
+ /* Client hook to report an internal error. */
+ void (*m_internal_error) (context *, const char *, va_list *);
+
+ /* Client hook to adjust properties of the given diagnostic that we're
+ about to issue, such as its kind. */
+ void (*m_adjust_diagnostic_info)(context *, diagnostic_info *);
+
+ /* Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ option_manager *m_option_mgr;
+ unsigned m_lang_mask;
+
+ /* A stack of optional hooks for adding URLs to quoted text strings in
+ diagnostics. Only used for the main diagnostic message.
+ Typically a single one owner by the context, but can be temporarily
+ overridden by a borrowed urlifier (e.g. on-stack). */
+ struct urlifier_stack_node
+ {
+ urlifier *m_urlifier;
+ bool m_owned;
+ };
+ auto_vec<urlifier_stack_node> *m_urlifier_stack;
+
+public:
+ /* Auxiliary data for client. */
+ void *m_client_aux_data;
+
+ /* Used to detect that the last caret was printed at the same location. */
+ location_t m_last_location;
+
+private:
+ int m_lock;
+
+ bool m_inhibit_notes_p;
+
+ source_printing_options m_source_printing;
+
+ /* True if -freport-bug option is used. */
+ bool m_report_bug;
+
+ /* Used to specify additional diagnostic output to be emitted after the
+ rest of the diagnostic. This is for implementing
+ -fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
+ enum diagnostics_extra_output_kind m_extra_output_kind;
+
+public:
+ /* What units to use when outputting the column number. */
+ enum diagnostics_column_unit m_column_unit;
+
+ /* The origin for the column number (1-based or 0-based typically). */
+ int m_column_origin;
+
+ /* The size of the tabstop for tab expansion. */
+ int m_tabstop;
+
+private:
+ /* How should non-ASCII/non-printable bytes be escaped when
+ a diagnostic suggests escaping the source code on output. */
+ enum diagnostics_escape_format m_escape_format;
+
+ /* If non-NULL, a diagnostics::changes::change_set to which fix-it hints
+ should be applied, for generating patches.
+ Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ changes::change_set *m_fixits_change_set;
+
+ /* Fields relating to diagnostic groups. */
+ struct {
+ /* How many diagnostic_group instances are currently alive. */
+ int m_group_nesting_depth;
+
+ /* How many nesting levels have been pushed within this group. */
+ int m_diagnostic_nesting_level;
+
+ /* How many diagnostics have been emitted since the bottommost
+ diagnostic_group was pushed. */
+ int m_emission_count;
+
+ /* The "group+diagnostic" nesting depth from which to inhibit notes. */
+ int m_inhibiting_notes_from;
+ } m_diagnostic_groups;
+
+ void inhibit_notes_in_group (bool inhibit = true);
+ bool notes_inhibited_in_group () const;
+
+ /* The various sinks to which diagnostics are to be outputted
+ (text vs structured formats such as SARIF).
+ The sinks are owned by the context; this would be a
+ std::vector<std::unique_ptr> if context had a
+ proper ctor. */
+ auto_vec<sink *> m_sinks;
+
+ /* Callback to set the locations of call sites along the inlining
+ stack corresponding to a diagnostic location. Needed to traverse
+ the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
+ of a diagnostic's location. */
+ set_locations_callback_t m_set_locations_cb;
+
+ /* A bundle of hooks for providing data to the context about its client
+ e.g. version information, plugins, etc.
+ Used by SARIF output to give metadata about the client that's
+ producing diagnostics.
+ Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ client_data_hooks *m_client_data_hooks;
+
+ /* Support for diagrams. */
+ struct
+ {
+ /* Theme to use when generating diagrams.
+ Can be NULL (if text art is disabled).
+ Owned by the context; this would be a std::unique_ptr if
+ context had a proper ctor. */
+ text_art::theme *m_theme;
+
+ } m_diagrams;
+
+ /* Owned by the context. */
+ char **m_original_argv;
+
+ /* Borrowed pointer to the active diagnostics::buffer, if any.
+ If null (the default), then diagnostics that are reported to the
+ context are immediately issued to the output format.
+ If non-null, then diagnostics that are reported to the context
+ are buffered in the buffer, and may be issued to the output format
+ later (if the buffer is flushed), moved to other buffers, or
+ discarded (if the buffer is cleared). */
+ buffer *m_diagnostic_buffer;
+};
+
+/* Client supplied function to announce a diagnostic
+ (for text-based diagnostic output). */
+inline text_starter_fn &
+text_starter (context *dc)
+{
+ return dc->m_text_callbacks.m_begin_diagnostic;
+}
+
+/* Client supplied function called between disjoint spans of source code,
+ so that the context can print
+ something to indicate that a new span of source code has begun. */
+inline start_span_fn<to_text> &
+start_span (context *dc)
+{
+ return dc->m_text_callbacks.m_text_start_span;
+}
+
+/* Client supplied function called after a diagnostic message is
+ displayed (for text-based diagnostic output). */
+inline text_finalizer_fn &
+text_finalizer (context *dc)
+{
+ return dc->m_text_callbacks.m_end_diagnostic;
+}
+
+} // namespace diagnostics
+
+#endif /* ! GCC_DIAGNOSTICS_CONTEXT_H */