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