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 50742 : 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 1255837 : 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 50557 : 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 50554 : 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 53205 : get_diagram_theme () const { return m_diagram_theme; }
197 :
198 : const column_policy &get_column_policy () const
199 : {
200 50742 : 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 subsystem
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 224035996 : 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 349456 : void set_set_locations_callback (set_locations_callback_t cb)
294 : {
295 349456 : 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 2514898 : bool option_unspecified_p (option_id opt_id) const
312 : {
313 2514898 : return m_option_classifier.option_unspecified_p (opt_id);
314 : }
315 :
316 235265 : bool emitting_diagnostic_p () const
317 : {
318 235265 : 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 : void
343 5630908 : classify_diagnostic (option_id opt_id,
344 : enum kind new_kind,
345 : location_t where)
346 : {
347 5630908 : logging::log_function_params
348 5630908 : (m_logger, "diagnostics::context::classify_diagnostics")
349 5630908 : .log_param_option_id ("option_id", opt_id)
350 5630908 : .log_param_kind ("new_kind", new_kind)
351 5630908 : .log_param_location_t ("where", where);
352 5630908 : logging::auto_inc_depth depth_sentinel (m_logger);
353 :
354 5630908 : m_option_classifier.classify_diagnostic (this, opt_id, new_kind, where);
355 5630908 : }
356 :
357 4877556 : void push_diagnostics (location_t where)
358 : {
359 4877556 : logging::log_function_params
360 4877556 : (m_logger, "diagnostics::context::push_diagnostics")
361 4877556 : .log_param_location_t ("where", where);
362 4877556 : logging::auto_inc_depth depth_sentinel (m_logger);
363 :
364 4877556 : m_option_classifier.push ();
365 4877556 : }
366 4876951 : void pop_diagnostics (location_t where)
367 : {
368 4876951 : logging::log_function_params
369 4876951 : (m_logger, "diagnostics::context::pop_diagnostics")
370 4876951 : .log_param_location_t ("where", where);
371 4876951 : logging::auto_inc_depth depth_sentinel (m_logger);
372 :
373 4876951 : m_option_classifier.pop (where);
374 4876951 : }
375 :
376 : void maybe_show_locus (const rich_location &richloc,
377 : const source_printing_options &opts,
378 : enum kind diagnostic_kind,
379 : pretty_printer &pp,
380 : source_effect_info *effect_info);
381 : void maybe_show_locus_as_html (const rich_location &richloc,
382 : const source_printing_options &opts,
383 : enum kind diagnostic_kind,
384 : xml::printer &xp,
385 : source_effect_info *effect_info,
386 : html_label_writer *label_writer);
387 :
388 : void emit_diagram (const diagram &diag);
389 :
390 : /* Various setters for use by option-handling logic. */
391 : void set_sink (std::unique_ptr<sink> sink_);
392 : void set_text_art_charset (enum diagnostic_text_art_charset charset);
393 :
394 : std::unique_ptr<client_data_hooks>
395 : set_client_data_hooks (std::unique_ptr<client_data_hooks> hooks);
396 :
397 : void push_owned_urlifier (std::unique_ptr<urlifier>);
398 : void push_borrowed_urlifier (const urlifier &);
399 : void pop_urlifier ();
400 :
401 : void initialize_fixits_change_set ();
402 4373 : void set_warning_as_error_requested (bool val)
403 : {
404 4373 : m_warning_as_error_requested = val;
405 4373 : }
406 16 : void set_report_bug (bool val) { m_report_bug = val; }
407 4 : void set_extra_output_kind (enum diagnostics_extra_output_kind kind)
408 : {
409 4 : m_extra_output_kind = kind;
410 4 : }
411 293828 : void set_show_cwe (bool val) { m_show_cwe = val; }
412 293828 : void set_show_rules (bool val) { m_show_rules = val; }
413 : void set_show_highlight_colors (bool val);
414 598764 : void set_path_format (enum diagnostic_path_format val)
415 : {
416 598764 : m_path_format = val;
417 304932 : }
418 293904 : void set_show_path_depths (bool val) { m_show_path_depths = val; }
419 293882 : void set_show_option_requested (bool val) { m_show_option_requested = val; }
420 : void set_show_nesting (bool val);
421 : void set_show_nesting_locations (bool val);
422 : void set_show_nesting_levels (bool val);
423 44 : void set_max_errors (int val) { m_max_errors = val; }
424 532 : void set_escape_format (enum diagnostics_escape_format val)
425 : {
426 532 : m_escape_format = val;
427 4 : }
428 :
429 : void set_format_decoder (printer_fn format_decoder);
430 : void set_prefixing_rule (diagnostic_prefixing_rule_t rule);
431 :
432 : /* Various accessors. */
433 31259 : bool warning_as_error_requested_p () const
434 : {
435 31259 : return m_warning_as_error_requested;
436 : }
437 15880 : bool show_path_depths_p () const { return m_show_path_depths; }
438 : sink &get_sink (size_t idx) const;
439 9866 : enum diagnostic_path_format get_path_format () const { return m_path_format; }
440 52123 : enum diagnostics_escape_format get_escape_format () const
441 : {
442 52123 : return m_escape_format;
443 : }
444 :
445 : file_cache &
446 3056754 : get_file_cache () const
447 : {
448 3056754 : gcc_assert (m_file_cache);
449 3056754 : return *m_file_cache;
450 : }
451 :
452 291763 : changes::change_set *get_fixits_change_set () const
453 : {
454 291763 : return m_fixits_change_set;
455 : }
456 3016 : const client_data_hooks *get_client_data_hooks () const
457 : {
458 3016 : return m_client_data_hooks;
459 : }
460 :
461 : const logical_locations::manager *
462 : get_logical_location_manager () const;
463 :
464 : const urlifier *get_urlifier () const;
465 :
466 54936 : text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
467 :
468 316019 : int &diagnostic_count (enum kind kind)
469 : {
470 316019 : return m_diagnostic_counters.m_count_for_kind[static_cast<size_t> (kind)];
471 : }
472 1112279 : int diagnostic_count (enum kind kind) const
473 : {
474 292073 : return m_diagnostic_counters.get_count (kind);
475 : }
476 :
477 : /* Option-related member functions. */
478 109200862 : inline bool option_enabled_p (option_id opt_id) const
479 : {
480 109200862 : if (!m_option_id_mgr)
481 : return true;
482 109200862 : return m_option_id_mgr->option_enabled_p (opt_id);
483 : }
484 :
485 1613570 : inline label_text get_option_name (option_id opt_id,
486 : enum kind orig_diag_kind,
487 : enum kind diag_kind) const
488 : {
489 1613570 : if (!m_option_id_mgr)
490 196 : return label_text ();
491 1613374 : return m_option_id_mgr->get_option_name (opt_id,
492 : orig_diag_kind,
493 1613374 : diag_kind);
494 : }
495 :
496 123 : inline label_text get_option_url (option_id opt_id) const
497 : {
498 123 : if (!m_option_id_mgr)
499 0 : return label_text ();
500 123 : return m_option_id_mgr->get_option_url (opt_id);
501 : }
502 :
503 : void
504 : set_option_id_manager (std::unique_ptr<option_id_manager> option_id_mgr,
505 : unsigned lang_mask);
506 :
507 277837 : unsigned get_lang_mask () const
508 : {
509 277837 : return m_lang_mask;
510 : }
511 :
512 : bool diagnostic_impl (rich_location *, const metadata *,
513 : option_id, const char *,
514 : va_list *, enum kind) ATTRIBUTE_GCC_DIAG(5,0);
515 : bool diagnostic_n_impl (rich_location *, const metadata *,
516 : option_id, unsigned HOST_WIDE_INT,
517 : const char *, const char *, va_list *,
518 : enum kind) ATTRIBUTE_GCC_DIAG(7,0);
519 :
520 416454 : int get_diagnostic_nesting_level () const
521 : {
522 416454 : return m_diagnostic_groups.m_diagnostic_nesting_level;
523 : }
524 :
525 : char *build_indent_prefix () const;
526 :
527 : int
528 470 : pch_save (FILE *f)
529 : {
530 470 : return m_option_classifier.pch_save (f);
531 : }
532 :
533 : int
534 350 : pch_restore (FILE *f)
535 : {
536 350 : return m_option_classifier.pch_restore (f);
537 : }
538 :
539 :
540 : void set_diagnostic_buffer (buffer *);
541 1252803 : buffer *get_diagnostic_buffer () const
542 : {
543 1252803 : return m_diagnostic_buffer;
544 : }
545 : void clear_diagnostic_buffer (buffer &);
546 : void flush_diagnostic_buffer (buffer &);
547 :
548 1280117 : std::unique_ptr<pretty_printer> clone_printer () const
549 : {
550 1280054 : return m_reference_printer->clone ();
551 : }
552 :
553 3781570 : pretty_printer *get_reference_printer () const
554 : {
555 3779967 : return m_reference_printer;
556 : }
557 :
558 : void
559 : add_sink (std::unique_ptr<sink>);
560 :
561 : void remove_all_output_sinks ();
562 :
563 : bool supports_fnotice_on_stderr_p () const;
564 :
565 : /* Raise SIGABRT on any diagnostic of severity kind::error or higher. */
566 : void
567 13 : set_abort_on_error (bool val)
568 : {
569 13 : m_abort_on_error = val;
570 : }
571 :
572 : /* Accessor for use in serialization, e.g. by C++ modules. */
573 : auto &
574 25866 : get_classification_history ()
575 : {
576 54977 : return m_option_classifier.m_classification_history;
577 : }
578 :
579 : void set_main_input_filename (const char *filename);
580 :
581 : void
582 214069 : set_permissive_option (option_id opt_permissive)
583 : {
584 214069 : m_opt_permissive = opt_permissive;
585 : }
586 :
587 : void
588 8 : set_fatal_errors (bool fatal_errors)
589 : {
590 8 : m_fatal_errors = fatal_errors;
591 8 : }
592 :
593 : void
594 293852 : set_internal_error_callback (void (*cb) (context *,
595 : const char *,
596 : va_list *))
597 : {
598 293852 : m_internal_error = cb;
599 : }
600 :
601 : void
602 102234 : set_adjust_diagnostic_info_callback (void (*cb) (const context &,
603 : diagnostic_info *))
604 : {
605 102234 : m_adjust_diagnostic_info = cb;
606 : }
607 :
608 : void
609 632 : inhibit_notes () { m_inhibit_notes_p = true; }
610 :
611 : source_printing_options &
612 757878 : get_source_printing_options ()
613 : {
614 757878 : return m_source_printing;
615 : }
616 : const source_printing_options &
617 1616 : get_source_printing_options () const
618 : {
619 1616 : return m_source_printing;
620 : }
621 :
622 418 : column_options &get_column_options () { return m_column_options; }
623 2418049 : const column_options &get_column_options () const { return m_column_options; }
624 :
625 : void set_caret_max_width (int value);
626 :
627 : private:
628 : void error_recursion () ATTRIBUTE_NORETURN;
629 :
630 : bool diagnostic_enabled (diagnostic_info *diagnostic);
631 :
632 : void get_any_inlining_info (diagnostic_info *diagnostic);
633 :
634 : void check_max_errors (bool flush);
635 : void action_after_output (enum kind diag_kind);
636 :
637 : /* Data members.
638 : Ideally, all of these would be private. */
639 :
640 : private:
641 : /* A reference instance of pretty_printer created by the client
642 : and owned by the context. Used for cloning when creating/adding
643 : output formats.
644 : Owned by the context; this would be a std::unique_ptr if
645 : context had a proper ctor. */
646 : pretty_printer *m_reference_printer;
647 :
648 : /* Cache of source code.
649 : Owned by the context; this would be a std::unique_ptr if
650 : context had a proper ctor. */
651 : file_cache *m_file_cache;
652 :
653 : /* The number of times we have issued diagnostics. */
654 : counters m_diagnostic_counters;
655 :
656 : /* True if it has been requested that warnings be treated as errors. */
657 : bool m_warning_as_error_requested;
658 :
659 : /* The number of option indexes that can be passed to warning() et
660 : al. */
661 : int m_n_opts;
662 :
663 : /* The stack of sets of overridden diagnostic option severities. */
664 : option_classifier m_option_classifier;
665 :
666 : /* True if we should print any CWE identifiers associated with
667 : diagnostics. */
668 : bool m_show_cwe;
669 :
670 : /* True if we should print any rules associated with diagnostics. */
671 : bool m_show_rules;
672 :
673 : /* How should diagnostics::paths::path objects be printed. */
674 : enum diagnostic_path_format m_path_format;
675 :
676 : /* True if we should print stack depths when printing diagnostic paths. */
677 : bool m_show_path_depths;
678 :
679 : /* True if we should print the command line option which controls
680 : each diagnostic, if known. */
681 : bool m_show_option_requested;
682 :
683 : /* True if we should raise a SIGABRT on errors. */
684 : bool m_abort_on_error;
685 :
686 : public:
687 : /* True if we should show the column number on diagnostics. */
688 : bool m_show_column;
689 :
690 : /* True if pedwarns are errors. */
691 : bool m_pedantic_errors;
692 :
693 : /* True if permerrors are warnings. */
694 : bool m_permissive;
695 :
696 : private:
697 : /* The option to associate with turning permerrors into warnings,
698 : if any. */
699 : option_id m_opt_permissive;
700 :
701 : /* True if errors are fatal. */
702 : bool m_fatal_errors;
703 :
704 : public:
705 : /* True if all warnings should be disabled. */
706 : bool m_inhibit_warnings;
707 :
708 : /* True if warnings should be given in system headers. */
709 : bool m_warn_system_headers;
710 :
711 : private:
712 : /* Maximum number of errors to report. */
713 : int m_max_errors;
714 :
715 : /* Client-supplied callbacks for use in text output. */
716 : struct {
717 : /* This function is called before any message is printed out. It is
718 : responsible for preparing message prefix and such. For example, it
719 : might say:
720 : In file included from "/usr/local/include/curses.h:5:
721 : from "/home/gdr/src/nifty_printer.h:56:
722 : ...
723 : */
724 : text_starter_fn m_begin_diagnostic;
725 :
726 : /* This function is called by diagnostic_show_locus in between
727 : disjoint spans of source code, so that the context can print
728 : something to indicate that a new span of source code has begun. */
729 : start_span_fn<to_text> m_text_start_span;
730 : start_span_fn<to_html> m_html_start_span;
731 :
732 : /* This function is called after the diagnostic message is printed. */
733 : text_finalizer_fn m_end_diagnostic;
734 : } m_text_callbacks;
735 :
736 : /* Client hook to report an internal error. */
737 : void (*m_internal_error) (context *, const char *, va_list *);
738 :
739 : /* Client hook to adjust properties of the given diagnostic that we're
740 : about to issue, such as its kind. */
741 : void (*m_adjust_diagnostic_info)(const context &, diagnostic_info *);
742 :
743 : /* Owned by the context; this would be a std::unique_ptr if
744 : context had a proper ctor. */
745 : option_id_manager *m_option_id_mgr;
746 : unsigned m_lang_mask;
747 :
748 : /* A stack of optional hooks for adding URLs to quoted text strings in
749 : diagnostics. Only used for the main diagnostic message.
750 : Typically a single one owner by the context, but can be temporarily
751 : overridden by a borrowed urlifier (e.g. on-stack). */
752 : struct urlifier_stack_node
753 : {
754 : urlifier *m_urlifier;
755 : bool m_owned;
756 : };
757 : auto_vec<urlifier_stack_node> *m_urlifier_stack;
758 :
759 : public:
760 : /* Auxiliary data for client. */
761 : void *m_client_aux_data;
762 :
763 : /* Used to detect that the last caret was printed at the same location. */
764 : location_t m_last_location;
765 :
766 : private:
767 : int m_lock;
768 :
769 : bool m_inhibit_notes_p;
770 :
771 : source_printing_options m_source_printing;
772 : column_options m_column_options;
773 :
774 : /* True if -freport-bug option is used. */
775 : bool m_report_bug;
776 :
777 : /* Used to specify additional diagnostic output to be emitted after the
778 : rest of the diagnostic. This is for implementing
779 : -fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
780 : enum diagnostics_extra_output_kind m_extra_output_kind;
781 :
782 : /* How should non-ASCII/non-printable bytes be escaped when
783 : a diagnostic suggests escaping the source code on output. */
784 : enum diagnostics_escape_format m_escape_format;
785 :
786 : /* If non-NULL, a diagnostics::changes::change_set to which fix-it hints
787 : should be applied, for generating patches.
788 : Owned by the context; this would be a std::unique_ptr if
789 : context had a proper ctor. */
790 : changes::change_set *m_fixits_change_set;
791 :
792 : /* Fields relating to diagnostic groups. */
793 : struct {
794 : /* How many diagnostic_group instances are currently alive. */
795 : int m_group_nesting_depth;
796 :
797 : /* How many nesting levels have been pushed within this group. */
798 : int m_diagnostic_nesting_level;
799 :
800 : /* How many diagnostics have been emitted since the bottommost
801 : diagnostic_group was pushed. */
802 : int m_emission_count;
803 :
804 : /* The "group+diagnostic" nesting depth from which to inhibit notes. */
805 : int m_inhibiting_notes_from;
806 : } m_diagnostic_groups;
807 :
808 : void inhibit_notes_in_group (bool inhibit = true);
809 : bool notes_inhibited_in_group () const;
810 :
811 : /* The various sinks to which diagnostics are to be outputted
812 : (text vs structured formats such as SARIF).
813 : The sinks are owned by the context; this would be a
814 : std::vector<std::unique_ptr> if context had a
815 : proper ctor. */
816 : auto_vec<sink *> m_sinks;
817 :
818 : /* Callback to set the locations of call sites along the inlining
819 : stack corresponding to a diagnostic location. Needed to traverse
820 : the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
821 : of a diagnostic's location. */
822 : set_locations_callback_t m_set_locations_cb;
823 :
824 : /* A bundle of hooks for providing data to the context about its client
825 : e.g. version information, plugins, etc.
826 : Used by SARIF output to give metadata about the client that's
827 : producing diagnostics.
828 : Owned by the context; this would be a std::unique_ptr if
829 : context had a proper ctor. */
830 : client_data_hooks *m_client_data_hooks;
831 :
832 : /* Support for diagrams. */
833 : struct
834 : {
835 : /* Theme to use when generating diagrams.
836 : Can be NULL (if text art is disabled).
837 : Owned by the context; this would be a std::unique_ptr if
838 : context had a proper ctor. */
839 : text_art::theme *m_theme;
840 :
841 : } m_diagrams;
842 :
843 : /* Owned by the context. */
844 : char **m_original_argv;
845 :
846 : /* Borrowed pointer to the active diagnostics::buffer, if any.
847 : If null (the default), then diagnostics that are reported to the
848 : context are immediately issued to the output format.
849 : If non-null, then diagnostics that are reported to the context
850 : are buffered in the buffer, and may be issued to the output format
851 : later (if the buffer is flushed), moved to other buffers, or
852 : discarded (if the buffer is cleared). */
853 : buffer *m_diagnostic_buffer;
854 :
855 : /* Owned by the context.
856 : Debugging option: if non-NULL, report information to the logger
857 : on what the context is doing. */
858 : logging::logger *m_logger;
859 : };
860 :
861 : /* Client supplied function to announce a diagnostic
862 : (for text-based diagnostic output). */
863 : inline text_starter_fn &
864 : text_starter (context *dc)
865 : {
866 : return dc->m_text_callbacks.m_begin_diagnostic;
867 : }
868 :
869 : /* Client supplied function called between disjoint spans of source code,
870 : so that the context can print
871 : something to indicate that a new span of source code has begun. */
872 : inline start_span_fn<to_text> &
873 18813 : start_span (context *dc)
874 : {
875 18813 : return dc->m_text_callbacks.m_text_start_span;
876 : }
877 :
878 : /* Client supplied function called after a diagnostic message is
879 : displayed (for text-based diagnostic output). */
880 : inline text_finalizer_fn &
881 : text_finalizer (context *dc)
882 : {
883 : return dc->m_text_callbacks.m_end_diagnostic;
884 : }
885 :
886 : } // namespace diagnostics
887 :
888 : #endif /* ! GCC_DIAGNOSTICS_CONTEXT_H */
|