Line data Source code
1 : /* Declare diagnostics::context and related types.
2 : Copyright (C) 2000-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #ifndef GCC_DIAGNOSTICS_CONTEXT_H
21 : #define GCC_DIAGNOSTICS_CONTEXT_H
22 :
23 : #include "lazily-created.h"
24 : #include "unique-argv.h"
25 : #include "diagnostics/option-classifier.h"
26 : #include "diagnostics/option-id-manager.h"
27 : #include "diagnostics/context-options.h"
28 : #include "diagnostics/source-printing-options.h"
29 : #include "diagnostics/column-options.h"
30 : #include "diagnostics/counters.h"
31 : #include "diagnostics/logging.h"
32 :
33 : namespace diagnostics {
34 :
35 : namespace changes {
36 : class change_set;
37 : }
38 :
39 : namespace digraphs { class digraph; }
40 :
41 : namespace logical_locations {
42 : class manager;
43 : }
44 :
45 : class buffer;
46 : class client_data_hooks;
47 : class diagram;
48 : class sink;
49 : class text_sink;
50 : class metadata;
51 :
52 : class source_effect_info;
53 :
54 : } // namespace diagnostics
55 :
56 : namespace text_art
57 : {
58 : class theme;
59 : } // namespace text_art
60 :
61 : namespace xml
62 : {
63 : class printer;
64 : } // namespace xml
65 :
66 : namespace diagnostics {
67 :
68 : /* Forward declarations. */
69 : class context;
70 : class location_print_policy;
71 : class source_print_policy;
72 :
73 : typedef void (*text_starter_fn) (text_sink &,
74 : const diagnostic_info *);
75 :
76 : struct to_text;
77 : struct to_html;
78 :
79 : extern pretty_printer *get_printer (to_text &);
80 :
81 : template <typename TextOrHtml>
82 : using start_span_fn = void (*) (const location_print_policy &,
83 : TextOrHtml &text_or_html,
84 : expanded_location);
85 :
86 : typedef void (*text_finalizer_fn) (text_sink &,
87 : const diagnostic_info *,
88 : enum kind);
89 :
90 : /* A bundle of state for determining column numbers in diagnostics
91 : (tab stops, whether to start at 0 or 1, etc).
92 : Uses a file_cache to handle tabs. */
93 :
94 : class column_policy
95 : {
96 : public:
97 : column_policy (const context &dc);
98 :
99 : int converted_column (expanded_location s) const;
100 :
101 : label_text get_location_text (const expanded_location &s,
102 : bool show_column,
103 : bool colorize) const;
104 :
105 49986 : int get_tabstop () const { return m_column_options.m_tabstop; }
106 :
107 : private:
108 : file_cache &m_file_cache;
109 : column_options m_column_options;
110 : };
111 :
112 : /* A bundle of state for printing locations within diagnostics
113 : (e.g. "FILENAME:LINE:COLUMN"), to isolate the interactions between
114 : context and the start_span callbacks. */
115 :
116 : class location_print_policy
117 : {
118 : public:
119 : location_print_policy (const context &dc);
120 : location_print_policy (const text_sink &);
121 :
122 1232776 : bool show_column_p () const { return m_show_column; }
123 :
124 : const column_policy &
125 1793 : get_column_policy () const { return m_column_policy; }
126 :
127 : void
128 : print_text_span_start (const context &dc,
129 : pretty_printer &pp,
130 : const expanded_location &exploc);
131 :
132 : void
133 : print_html_span_start (const context &dc,
134 : xml::printer &xp,
135 : const expanded_location &exploc);
136 :
137 : private:
138 : column_policy m_column_policy;
139 : bool m_show_column;
140 : };
141 :
142 : /* Abstract base class for optionally supplying extra tags when writing
143 : out annotation labels in HTML output. */
144 :
145 3 : class html_label_writer
146 : {
147 : public:
148 3 : virtual ~html_label_writer () {}
149 : virtual void begin_label () = 0;
150 : virtual void end_label () = 0;
151 : };
152 :
153 : /* A bundle of state for printing source within a diagnostic,
154 : to isolate the interactions between context and the
155 : implementation of diagnostic_show_locus. */
156 :
157 : class source_print_policy
158 : {
159 : public:
160 : source_print_policy (const context &);
161 : source_print_policy (const context &,
162 : const source_printing_options &);
163 :
164 : void
165 : print (pretty_printer &pp,
166 : const rich_location &richloc,
167 : enum kind diagnostic_kind,
168 : source_effect_info *effect_info) const;
169 :
170 : void
171 : print_as_html (xml::printer &xp,
172 : const rich_location &richloc,
173 : enum kind diagnostic_kind,
174 : source_effect_info *effect_info,
175 : html_label_writer *label_writer) const;
176 :
177 : const source_printing_options &
178 49801 : get_options () const { return m_options; }
179 :
180 : start_span_fn<to_text>
181 1793 : get_text_start_span_fn () const { return m_text_start_span_cb; }
182 :
183 : start_span_fn<to_html>
184 1 : get_html_start_span_fn () const { return m_html_start_span_cb; }
185 :
186 : file_cache &
187 49798 : get_file_cache () const { return m_file_cache; }
188 :
189 : enum diagnostics_escape_format
190 554 : get_escape_format () const
191 : {
192 554 : return m_escape_format;
193 : }
194 :
195 : text_art::theme *
196 52449 : get_diagram_theme () const { return m_diagram_theme; }
197 :
198 : const column_policy &get_column_policy () const
199 : {
200 49986 : return m_location_policy.get_column_policy ();
201 : }
202 :
203 463 : const location_print_policy &get_location_policy () const
204 : {
205 463 : return m_location_policy;
206 : }
207 :
208 : private:
209 : const source_printing_options &m_options;
210 : location_print_policy m_location_policy;
211 : start_span_fn<to_text> m_text_start_span_cb;
212 : start_span_fn<to_html> m_html_start_span_cb;
213 : file_cache &m_file_cache;
214 :
215 : /* Other data copied from context. */
216 : text_art::theme *m_diagram_theme;
217 : enum diagnostics_escape_format m_escape_format;
218 : };
219 :
220 : /* This class encapsulates the state of the diagnostics subsystem
221 : as a whole (either directly, or via owned objects of other classes, to
222 : avoid global variables).
223 :
224 : It has responsibility for:
225 : - being a central place for clients to report diagnostics
226 : - reporting those diagnostics to zero or more output sinks
227 : (e.g. text vs SARIF)
228 : - providing a "dump" member function for a debug dump of the state of
229 : the diagnostics subsytem
230 : - direct vs buffered diagnostics (see class diagnostics::buffer)
231 : - tracking the original argv of the program (for SARIF output)
232 : - crash-handling
233 :
234 : It delegates responsibility to various other classes:
235 : - the various output sinks (instances of diagnostics::sink
236 : subclasses)
237 : - formatting of messages (class pretty_printer)
238 : - an optional urlifier to inject URLs into formatted messages
239 : - counting the number of diagnostics reported of each kind
240 : (class diagnostics::counters)
241 : - calling out to a option_id_manager to determine if
242 : a particular warning is enabled or disabled
243 : - tracking pragmas that enable/disable warnings in a range of
244 : source code
245 : - a cache for use when quoting the user's source code (class file_cache)
246 : - a text_art::theme
247 : - a diagnostics::changes::change_set for generating patches from fix-it hints
248 : - diagnostics::client_data_hooks for metadata.
249 :
250 : Try to avoid adding new responsibilities to this class itself, to avoid
251 : the "blob" anti-pattern. */
252 :
253 39176 : class context
254 : {
255 : public:
256 : /* Give access to m_text_callbacks. */
257 : // FIXME: these need updating
258 : friend text_starter_fn &
259 : text_starter (context *dc);
260 : friend start_span_fn<to_text> &
261 : start_span (context *dc);
262 : friend text_finalizer_fn &
263 : text_finalizer (context *dc);
264 :
265 : friend class source_print_policy;
266 : friend class text_sink;
267 : friend class buffer;
268 :
269 : typedef void (*set_locations_callback_t) (const context &,
270 : diagnostic_info *);
271 :
272 : void initialize (int n_opts);
273 : void color_init (int value);
274 : void urls_init (int value);
275 : void set_pretty_printer (std::unique_ptr<pretty_printer> pp);
276 : void refresh_output_sinks ();
277 :
278 : void finish ();
279 :
280 : void dump (FILE *out, int indent) const;
281 0 : void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
282 :
283 211858731 : logging::logger *get_logger () { return m_logger; }
284 :
285 : bool execution_failed_p () const;
286 :
287 : void set_original_argv (unique_argv original_argv);
288 418 : const char * const *get_original_argv ()
289 : {
290 418 : return const_cast<const char * const *> (m_original_argv);
291 : }
292 :
293 342201 : void set_set_locations_callback (set_locations_callback_t cb)
294 : {
295 342201 : m_set_locations_cb = cb;
296 : }
297 :
298 : void
299 : initialize_input_context (diagnostic_input_charset_callback ccb,
300 : bool should_skip_bom);
301 :
302 : void begin_group ();
303 : void end_group ();
304 :
305 : void push_nesting_level ();
306 : void pop_nesting_level ();
307 : void set_nesting_level (int new_level);
308 :
309 : bool warning_enabled_at (location_t loc, option_id opt_id);
310 :
311 2076934 : bool option_unspecified_p (option_id opt_id) const
312 : {
313 2076934 : return m_option_classifier.option_unspecified_p (opt_id);
314 : }
315 :
316 538727 : bool emitting_diagnostic_p () const
317 : {
318 538727 : return m_lock > 0;
319 : }
320 :
321 : bool emit_diagnostic_with_group (enum kind kind,
322 : rich_location &richloc,
323 : const metadata *metadata,
324 : option_id opt_id,
325 : const char *gmsgid, ...)
326 : ATTRIBUTE_GCC_DIAG(6,7);
327 : bool emit_diagnostic_with_group_va (enum kind kind,
328 : rich_location &richloc,
329 : const metadata *metadata,
330 : option_id opt_id,
331 : const char *gmsgid, va_list *ap)
332 : ATTRIBUTE_GCC_DIAG(6,0);
333 :
334 : bool report_diagnostic (diagnostic_info *);
335 : void report_verbatim (text_info &);
336 :
337 : /* Report a directed graph associated with the run as a whole
338 : to any sinks that support directed graphs. */
339 : void
340 : report_global_digraph (const lazily_created<digraphs::digraph> &);
341 :
342 : enum kind
343 5138082 : classify_diagnostic (option_id opt_id,
344 : enum kind new_kind,
345 : location_t where)
346 : {
347 5138082 : logging::log_function_params
348 5138082 : (m_logger, "diagnostics::context::classify_diagnostics")
349 5138082 : .log_param_option_id ("option_id", opt_id)
350 5138082 : .log_param_kind ("new_kind", new_kind)
351 5138082 : .log_param_location_t ("where", where);
352 5138082 : logging::auto_inc_depth depth_sentinel (m_logger);
353 :
354 5138082 : return m_option_classifier.classify_diagnostic (this,
355 : opt_id,
356 : new_kind,
357 5138082 : where);
358 5138082 : }
359 :
360 4385745 : void push_diagnostics (location_t where)
361 : {
362 4385745 : logging::log_function_params
363 4385745 : (m_logger, "diagnostics::context::push_diagnostics")
364 4385745 : .log_param_location_t ("where", where);
365 4385745 : logging::auto_inc_depth depth_sentinel (m_logger);
366 :
367 4385745 : m_option_classifier.push ();
368 4385745 : }
369 4385154 : void pop_diagnostics (location_t where)
370 : {
371 4385154 : logging::log_function_params
372 4385154 : (m_logger, "diagnostics::context::pop_diagnostics")
373 4385154 : .log_param_location_t ("where", where);
374 4385154 : logging::auto_inc_depth depth_sentinel (m_logger);
375 :
376 4385154 : m_option_classifier.pop (where);
377 4385154 : }
378 :
379 : void maybe_show_locus (const rich_location &richloc,
380 : const source_printing_options &opts,
381 : enum kind diagnostic_kind,
382 : pretty_printer &pp,
383 : source_effect_info *effect_info);
384 : void maybe_show_locus_as_html (const rich_location &richloc,
385 : const source_printing_options &opts,
386 : enum kind diagnostic_kind,
387 : xml::printer &xp,
388 : source_effect_info *effect_info,
389 : html_label_writer *label_writer);
390 :
391 : void emit_diagram (const diagram &diag);
392 :
393 : /* Various setters for use by option-handling logic. */
394 : void set_sink (std::unique_ptr<sink> sink_);
395 : void set_text_art_charset (enum diagnostic_text_art_charset charset);
396 :
397 : std::unique_ptr<client_data_hooks>
398 : set_client_data_hooks (std::unique_ptr<client_data_hooks> hooks);
399 :
400 : void push_owned_urlifier (std::unique_ptr<urlifier>);
401 : void push_borrowed_urlifier (const urlifier &);
402 : void pop_urlifier ();
403 :
404 : void initialize_fixits_change_set ();
405 4329 : void set_warning_as_error_requested (bool val)
406 : {
407 4329 : m_warning_as_error_requested = val;
408 4329 : }
409 16 : void set_report_bug (bool val) { m_report_bug = val; }
410 4 : void set_extra_output_kind (enum diagnostics_extra_output_kind kind)
411 : {
412 4 : m_extra_output_kind = kind;
413 4 : }
414 287872 : void set_show_cwe (bool val) { m_show_cwe = val; }
415 287872 : void set_show_rules (bool val) { m_show_rules = val; }
416 : void set_show_highlight_colors (bool val);
417 587042 : void set_path_format (enum diagnostic_path_format val)
418 : {
419 587042 : m_path_format = val;
420 299166 : }
421 287948 : void set_show_path_depths (bool val) { m_show_path_depths = val; }
422 287926 : void set_show_option_requested (bool val) { m_show_option_requested = val; }
423 : void set_show_nesting (bool val);
424 : void set_show_nesting_locations (bool val);
425 : void set_show_nesting_levels (bool val);
426 44 : void set_max_errors (int val) { m_max_errors = val; }
427 532 : void set_escape_format (enum diagnostics_escape_format val)
428 : {
429 532 : m_escape_format = val;
430 4 : }
431 :
432 : void set_format_decoder (printer_fn format_decoder);
433 : void set_prefixing_rule (diagnostic_prefixing_rule_t rule);
434 :
435 : /* Various accessors. */
436 30674 : bool warning_as_error_requested_p () const
437 : {
438 30674 : return m_warning_as_error_requested;
439 : }
440 15059 : bool show_path_depths_p () const { return m_show_path_depths; }
441 : sink &get_sink (size_t idx) const;
442 9677 : enum diagnostic_path_format get_path_format () const { return m_path_format; }
443 51367 : enum diagnostics_escape_format get_escape_format () const
444 : {
445 51367 : return m_escape_format;
446 : }
447 :
448 : file_cache &
449 2969549 : get_file_cache () const
450 : {
451 2969549 : gcc_assert (m_file_cache);
452 2969549 : return *m_file_cache;
453 : }
454 :
455 285807 : changes::change_set *get_fixits_change_set () const
456 : {
457 285807 : return m_fixits_change_set;
458 : }
459 3016 : const client_data_hooks *get_client_data_hooks () const
460 : {
461 3016 : return m_client_data_hooks;
462 : }
463 :
464 : const logical_locations::manager *
465 : get_logical_location_manager () const;
466 :
467 : const urlifier *get_urlifier () const;
468 :
469 54142 : text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
470 :
471 310011 : int &diagnostic_count (enum kind kind)
472 : {
473 310011 : return m_diagnostic_counters.m_count_for_kind[static_cast<size_t> (kind)];
474 : }
475 1090161 : int diagnostic_count (enum kind kind) const
476 : {
477 286117 : return m_diagnostic_counters.get_count (kind);
478 : }
479 :
480 : /* Option-related member functions. */
481 102863861 : inline bool option_enabled_p (option_id opt_id) const
482 : {
483 102863861 : if (!m_option_id_mgr)
484 : return true;
485 102863861 : return m_option_id_mgr->option_enabled_p (opt_id);
486 : }
487 :
488 1561752 : inline char *make_option_name (option_id opt_id,
489 : enum kind orig_diag_kind,
490 : enum kind diag_kind) const
491 : {
492 1561752 : if (!m_option_id_mgr)
493 : return nullptr;
494 1561556 : return m_option_id_mgr->make_option_name (opt_id,
495 : orig_diag_kind,
496 1561556 : diag_kind);
497 : }
498 :
499 123 : inline char *make_option_url (option_id opt_id) const
500 : {
501 123 : if (!m_option_id_mgr)
502 : return nullptr;
503 123 : return m_option_id_mgr->make_option_url (opt_id);
504 : }
505 :
506 : void
507 : set_option_id_manager (std::unique_ptr<option_id_manager> option_id_mgr,
508 : unsigned lang_mask);
509 :
510 272741 : unsigned get_lang_mask () const
511 : {
512 272741 : return m_lang_mask;
513 : }
514 :
515 : bool diagnostic_impl (rich_location *, const metadata *,
516 : option_id, const char *,
517 : va_list *, enum kind) ATTRIBUTE_GCC_DIAG(5,0);
518 : bool diagnostic_n_impl (rich_location *, const metadata *,
519 : option_id, unsigned HOST_WIDE_INT,
520 : const char *, const char *, va_list *,
521 : enum kind) ATTRIBUTE_GCC_DIAG(7,0);
522 :
523 384009 : int get_diagnostic_nesting_level () const
524 : {
525 384009 : return m_diagnostic_groups.m_diagnostic_nesting_level;
526 : }
527 :
528 : char *build_indent_prefix () const;
529 :
530 : int
531 440 : pch_save (FILE *f)
532 : {
533 440 : return m_option_classifier.pch_save (f);
534 : }
535 :
536 : int
537 350 : pch_restore (FILE *f)
538 : {
539 350 : return m_option_classifier.pch_restore (f);
540 : }
541 :
542 :
543 : void set_diagnostic_buffer (buffer *);
544 1229953 : buffer *get_diagnostic_buffer () const
545 : {
546 1229953 : return m_diagnostic_buffer;
547 : }
548 : void clear_diagnostic_buffer (buffer &);
549 : void flush_diagnostic_buffer (buffer &);
550 :
551 1250893 : std::unique_ptr<pretty_printer> clone_printer () const
552 : {
553 1250831 : return m_reference_printer->clone ();
554 : }
555 :
556 3697949 : pretty_printer *get_reference_printer () const
557 : {
558 3696346 : return m_reference_printer;
559 : }
560 :
561 : void
562 : add_sink (std::unique_ptr<sink>);
563 :
564 : void remove_all_output_sinks ();
565 :
566 : bool supports_fnotice_on_stderr_p () const;
567 :
568 : /* Raise SIGABRT on any diagnostic of severity kind::error or higher. */
569 : void
570 13 : set_abort_on_error (bool val)
571 : {
572 13 : m_abort_on_error = val;
573 : }
574 :
575 : /* Accessor for use in serialization, e.g. by C++ modules. */
576 : auto &
577 2874 : get_classification_history ()
578 : {
579 8148 : return m_option_classifier.m_classification_history;
580 : }
581 :
582 : void set_main_input_filename (const char *filename);
583 :
584 : void
585 208440 : set_permissive_option (option_id opt_permissive)
586 : {
587 208440 : m_opt_permissive = opt_permissive;
588 : }
589 :
590 : void
591 8 : set_fatal_errors (bool fatal_errors)
592 : {
593 8 : m_fatal_errors = fatal_errors;
594 8 : }
595 :
596 : void
597 287894 : set_internal_error_callback (void (*cb) (context *,
598 : const char *,
599 : va_list *))
600 : {
601 287894 : m_internal_error = cb;
602 : }
603 :
604 : void
605 98119 : set_adjust_diagnostic_info_callback (void (*cb) (const context &,
606 : diagnostic_info *))
607 : {
608 98119 : m_adjust_diagnostic_info = cb;
609 : }
610 :
611 : void
612 616 : inhibit_notes () { m_inhibit_notes_p = true; }
613 :
614 : source_printing_options &
615 741365 : get_source_printing_options ()
616 : {
617 741365 : return m_source_printing;
618 : }
619 : const source_printing_options &
620 1616 : get_source_printing_options () const
621 : {
622 1616 : return m_source_printing;
623 : }
624 :
625 418 : column_options &get_column_options () { return m_column_options; }
626 2348668 : const column_options &get_column_options () const { return m_column_options; }
627 :
628 : void set_caret_max_width (int value);
629 :
630 : private:
631 : void error_recursion () ATTRIBUTE_NORETURN;
632 :
633 : bool diagnostic_enabled (diagnostic_info *diagnostic);
634 :
635 : void get_any_inlining_info (diagnostic_info *diagnostic);
636 :
637 : void check_max_errors (bool flush);
638 : void action_after_output (enum kind diag_kind);
639 :
640 : /* Data members.
641 : Ideally, all of these would be private. */
642 :
643 : private:
644 : /* A reference instance of pretty_printer created by the client
645 : and owned by the context. Used for cloning when creating/adding
646 : output formats.
647 : Owned by the context; this would be a std::unique_ptr if
648 : context had a proper ctor. */
649 : pretty_printer *m_reference_printer;
650 :
651 : /* Cache of source code.
652 : Owned by the context; this would be a std::unique_ptr if
653 : context had a proper ctor. */
654 : file_cache *m_file_cache;
655 :
656 : /* The number of times we have issued diagnostics. */
657 : counters m_diagnostic_counters;
658 :
659 : /* True if it has been requested that warnings be treated as errors. */
660 : bool m_warning_as_error_requested;
661 :
662 : /* The number of option indexes that can be passed to warning() et
663 : al. */
664 : int m_n_opts;
665 :
666 : /* The stack of sets of overridden diagnostic option severities. */
667 : option_classifier m_option_classifier;
668 :
669 : /* True if we should print any CWE identifiers associated with
670 : diagnostics. */
671 : bool m_show_cwe;
672 :
673 : /* True if we should print any rules associated with diagnostics. */
674 : bool m_show_rules;
675 :
676 : /* How should diagnostics::paths::path objects be printed. */
677 : enum diagnostic_path_format m_path_format;
678 :
679 : /* True if we should print stack depths when printing diagnostic paths. */
680 : bool m_show_path_depths;
681 :
682 : /* True if we should print the command line option which controls
683 : each diagnostic, if known. */
684 : bool m_show_option_requested;
685 :
686 : /* True if we should raise a SIGABRT on errors. */
687 : bool m_abort_on_error;
688 :
689 : public:
690 : /* True if we should show the column number on diagnostics. */
691 : bool m_show_column;
692 :
693 : /* True if pedwarns are errors. */
694 : bool m_pedantic_errors;
695 :
696 : /* True if permerrors are warnings. */
697 : bool m_permissive;
698 :
699 : private:
700 : /* The option to associate with turning permerrors into warnings,
701 : if any. */
702 : option_id m_opt_permissive;
703 :
704 : /* True if errors are fatal. */
705 : bool m_fatal_errors;
706 :
707 : public:
708 : /* True if all warnings should be disabled. */
709 : bool m_inhibit_warnings;
710 :
711 : /* True if warnings should be given in system headers. */
712 : bool m_warn_system_headers;
713 :
714 : private:
715 : /* Maximum number of errors to report. */
716 : int m_max_errors;
717 :
718 : /* Client-supplied callbacks for use in text output. */
719 : struct {
720 : /* This function is called before any message is printed out. It is
721 : responsible for preparing message prefix and such. For example, it
722 : might say:
723 : In file included from "/usr/local/include/curses.h:5:
724 : from "/home/gdr/src/nifty_printer.h:56:
725 : ...
726 : */
727 : text_starter_fn m_begin_diagnostic;
728 :
729 : /* This function is called by diagnostic_show_locus in between
730 : disjoint spans of source code, so that the context can print
731 : something to indicate that a new span of source code has begun. */
732 : start_span_fn<to_text> m_text_start_span;
733 : start_span_fn<to_html> m_html_start_span;
734 :
735 : /* This function is called after the diagnostic message is printed. */
736 : text_finalizer_fn m_end_diagnostic;
737 : } m_text_callbacks;
738 :
739 : /* Client hook to report an internal error. */
740 : void (*m_internal_error) (context *, const char *, va_list *);
741 :
742 : /* Client hook to adjust properties of the given diagnostic that we're
743 : about to issue, such as its kind. */
744 : void (*m_adjust_diagnostic_info)(const context &, diagnostic_info *);
745 :
746 : /* Owned by the context; this would be a std::unique_ptr if
747 : context had a proper ctor. */
748 : option_id_manager *m_option_id_mgr;
749 : unsigned m_lang_mask;
750 :
751 : /* A stack of optional hooks for adding URLs to quoted text strings in
752 : diagnostics. Only used for the main diagnostic message.
753 : Typically a single one owner by the context, but can be temporarily
754 : overridden by a borrowed urlifier (e.g. on-stack). */
755 : struct urlifier_stack_node
756 : {
757 : urlifier *m_urlifier;
758 : bool m_owned;
759 : };
760 : auto_vec<urlifier_stack_node> *m_urlifier_stack;
761 :
762 : public:
763 : /* Auxiliary data for client. */
764 : void *m_client_aux_data;
765 :
766 : /* Used to detect that the last caret was printed at the same location. */
767 : location_t m_last_location;
768 :
769 : private:
770 : int m_lock;
771 :
772 : bool m_inhibit_notes_p;
773 :
774 : source_printing_options m_source_printing;
775 : column_options m_column_options;
776 :
777 : /* True if -freport-bug option is used. */
778 : bool m_report_bug;
779 :
780 : /* Used to specify additional diagnostic output to be emitted after the
781 : rest of the diagnostic. This is for implementing
782 : -fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
783 : enum diagnostics_extra_output_kind m_extra_output_kind;
784 :
785 : /* How should non-ASCII/non-printable bytes be escaped when
786 : a diagnostic suggests escaping the source code on output. */
787 : enum diagnostics_escape_format m_escape_format;
788 :
789 : /* If non-NULL, a diagnostics::changes::change_set to which fix-it hints
790 : should be applied, for generating patches.
791 : Owned by the context; this would be a std::unique_ptr if
792 : context had a proper ctor. */
793 : changes::change_set *m_fixits_change_set;
794 :
795 : /* Fields relating to diagnostic groups. */
796 : struct {
797 : /* How many diagnostic_group instances are currently alive. */
798 : int m_group_nesting_depth;
799 :
800 : /* How many nesting levels have been pushed within this group. */
801 : int m_diagnostic_nesting_level;
802 :
803 : /* How many diagnostics have been emitted since the bottommost
804 : diagnostic_group was pushed. */
805 : int m_emission_count;
806 :
807 : /* The "group+diagnostic" nesting depth from which to inhibit notes. */
808 : int m_inhibiting_notes_from;
809 : } m_diagnostic_groups;
810 :
811 : void inhibit_notes_in_group (bool inhibit = true);
812 : bool notes_inhibited_in_group () const;
813 :
814 : /* The various sinks to which diagnostics are to be outputted
815 : (text vs structured formats such as SARIF).
816 : The sinks are owned by the context; this would be a
817 : std::vector<std::unique_ptr> if context had a
818 : proper ctor. */
819 : auto_vec<sink *> m_sinks;
820 :
821 : /* Callback to set the locations of call sites along the inlining
822 : stack corresponding to a diagnostic location. Needed to traverse
823 : the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
824 : of a diagnostic's location. */
825 : set_locations_callback_t m_set_locations_cb;
826 :
827 : /* A bundle of hooks for providing data to the context about its client
828 : e.g. version information, plugins, etc.
829 : Used by SARIF output to give metadata about the client that's
830 : producing diagnostics.
831 : Owned by the context; this would be a std::unique_ptr if
832 : context had a proper ctor. */
833 : client_data_hooks *m_client_data_hooks;
834 :
835 : /* Support for diagrams. */
836 : struct
837 : {
838 : /* Theme to use when generating diagrams.
839 : Can be NULL (if text art is disabled).
840 : Owned by the context; this would be a std::unique_ptr if
841 : context had a proper ctor. */
842 : text_art::theme *m_theme;
843 :
844 : } m_diagrams;
845 :
846 : /* Owned by the context. */
847 : char **m_original_argv;
848 :
849 : /* Borrowed pointer to the active diagnostics::buffer, if any.
850 : If null (the default), then diagnostics that are reported to the
851 : context are immediately issued to the output format.
852 : If non-null, then diagnostics that are reported to the context
853 : are buffered in the buffer, and may be issued to the output format
854 : later (if the buffer is flushed), moved to other buffers, or
855 : discarded (if the buffer is cleared). */
856 : buffer *m_diagnostic_buffer;
857 :
858 : /* Owned by the context.
859 : Debugging option: if non-NULL, report information to the logger
860 : on what the context is doing. */
861 : logging::logger *m_logger;
862 : };
863 :
864 : /* Client supplied function to announce a diagnostic
865 : (for text-based diagnostic output). */
866 : inline text_starter_fn &
867 : text_starter (context *dc)
868 : {
869 : return dc->m_text_callbacks.m_begin_diagnostic;
870 : }
871 :
872 : /* Client supplied function called between disjoint spans of source code,
873 : so that the context can print
874 : something to indicate that a new span of source code has begun. */
875 : inline start_span_fn<to_text> &
876 18813 : start_span (context *dc)
877 : {
878 18813 : return dc->m_text_callbacks.m_text_start_span;
879 : }
880 :
881 : /* Client supplied function called after a diagnostic message is
882 : displayed (for text-based diagnostic output). */
883 : inline text_finalizer_fn &
884 : text_finalizer (context *dc)
885 : {
886 : return dc->m_text_callbacks.m_end_diagnostic;
887 : }
888 :
889 : } // namespace diagnostics
890 :
891 : #endif /* ! GCC_DIAGNOSTICS_CONTEXT_H */
|