1/* Various declarations for language-independent diagnostics subroutines.
2 Copyright (C) 2000-2023 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_DIAGNOSTIC_H
22#define GCC_DIAGNOSTIC_H
23
24#include "pretty-print.h"
25#include "diagnostic-core.h"
26
27namespace text_art
28{
29 class theme;
30} // namespace text_art
31
32/* An enum for controlling what units to use for the column number
33 when diagnostics are output, used by the -fdiagnostics-column-unit option.
34 Tabs will be expanded or not according to the value of -ftabstop. The origin
35 (default 1) is controlled by -fdiagnostics-column-origin. */
36
37enum diagnostics_column_unit
38{
39 /* The default from GCC 11 onwards: display columns. */
40 DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
41
42 /* The behavior in GCC 10 and earlier: simple bytes. */
43 DIAGNOSTICS_COLUMN_UNIT_BYTE
44};
45
46/* An enum for controlling how to print non-ASCII characters/bytes when
47 a diagnostic suggests escaping the source code on output. */
48
49enum diagnostics_escape_format
50{
51 /* Escape non-ASCII Unicode characters in the form <U+XXXX> and
52 non-UTF-8 bytes in the form <XX>. */
53 DIAGNOSTICS_ESCAPE_FORMAT_UNICODE,
54
55 /* Escape non-ASCII bytes in the form <XX> (thus showing the underlying
56 encoding of non-ASCII Unicode characters). */
57 DIAGNOSTICS_ESCAPE_FORMAT_BYTES
58};
59
60/* Enum for overriding the standard output format. */
61
62enum diagnostics_output_format
63{
64 /* The default: textual output. */
65 DIAGNOSTICS_OUTPUT_FORMAT_TEXT,
66
67 /* JSON-based output, to stderr. */
68 DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR,
69
70 /* JSON-based output, to a file. */
71 DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE,
72
73 /* SARIF-based output, to stderr. */
74 DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR,
75
76 /* SARIF-based output, to a file. */
77 DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE
78};
79
80/* An enum for controlling how diagnostic_paths should be printed. */
81enum diagnostic_path_format
82{
83 /* Don't print diagnostic_paths. */
84 DPF_NONE,
85
86 /* Print diagnostic_paths by emitting a separate "note" for every event
87 in the path. */
88 DPF_SEPARATE_EVENTS,
89
90 /* Print diagnostic_paths by consolidating events together where they
91 are close enough, and printing such runs of events with multiple
92 calls to diagnostic_show_locus, showing the individual events in
93 each run via labels in the source. */
94 DPF_INLINE_EVENTS
95};
96
97/* An enum for capturing values of GCC_EXTRA_DIAGNOSTIC_OUTPUT,
98 and for -fdiagnostics-parseable-fixits. */
99
100enum diagnostics_extra_output_kind
101{
102 /* No extra output, or an unrecognized value. */
103 EXTRA_DIAGNOSTIC_OUTPUT_none,
104
105 /* Emit fix-it hints using the "fixits-v1" format, equivalent to
106 -fdiagnostics-parseable-fixits. */
107 EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1,
108
109 /* Emit fix-it hints using the "fixits-v2" format. */
110 EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2
111};
112
113/* Values for -fdiagnostics-text-art-charset=. */
114
115enum diagnostic_text_art_charset
116{
117 /* No text art diagrams shall be emitted. */
118 DIAGNOSTICS_TEXT_ART_CHARSET_NONE,
119
120 /* Use pure ASCII for text art diagrams. */
121 DIAGNOSTICS_TEXT_ART_CHARSET_ASCII,
122
123 /* Use ASCII + conservative use of other unicode characters
124 in text art diagrams. */
125 DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE,
126
127 /* Use Emoji. */
128 DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI
129};
130
131/* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
132 its context and its KIND (ice, error, warning, note, ...) See complete
133 list in diagnostic.def. */
134struct diagnostic_info
135{
136 diagnostic_info ()
137 : message (), richloc (), metadata (), x_data (), kind (), option_index (),
138 m_iinfo ()
139 { }
140
141 /* Text to be formatted. */
142 text_info message;
143
144 /* The location at which the diagnostic is to be reported. */
145 rich_location *richloc;
146
147 /* An optional bundle of metadata associated with the diagnostic
148 (or NULL). */
149 const diagnostic_metadata *metadata;
150
151 /* Auxiliary data for client. */
152 void *x_data;
153 /* The kind of diagnostic it is about. */
154 diagnostic_t kind;
155 /* Which OPT_* directly controls this diagnostic. */
156 int option_index;
157
158 /* Inlining context containing locations for each call site along
159 the inlining stack. */
160 struct inlining_info
161 {
162 /* Locations along the inlining stack. */
163 auto_vec<location_t, 8> m_ilocs;
164 /* The abstract origin of the location. */
165 void *m_ao;
166 /* Set if every M_ILOCS element is in a system header. */
167 bool m_allsyslocs;
168 } m_iinfo;
169};
170
171/* Forward declarations. */
172typedef void (*diagnostic_starter_fn) (diagnostic_context *,
173 diagnostic_info *);
174
175typedef void (*diagnostic_start_span_fn) (diagnostic_context *,
176 expanded_location);
177
178typedef void (*diagnostic_finalizer_fn) (diagnostic_context *,
179 diagnostic_info *,
180 diagnostic_t);
181
182class edit_context;
183namespace json { class value; }
184class diagnostic_client_data_hooks;
185class logical_location;
186class diagnostic_diagram;
187
188/* Abstract base class for a particular output format for diagnostics;
189 each value of -fdiagnostics-output-format= will have its own
190 implementation. */
191
192class diagnostic_output_format
193{
194public:
195 virtual ~diagnostic_output_format () {}
196
197 virtual void on_begin_group () = 0;
198 virtual void on_end_group () = 0;
199 virtual void on_begin_diagnostic (diagnostic_info *) = 0;
200 virtual void on_end_diagnostic (diagnostic_info *,
201 diagnostic_t orig_diag_kind) = 0;
202 virtual void on_diagram (const diagnostic_diagram &diagram) = 0;
203
204protected:
205 diagnostic_output_format (diagnostic_context &context)
206 : m_context (context)
207 {}
208
209 diagnostic_context &m_context;
210};
211
212/* Subclass of diagnostic_output_format for classic text-based output
213 to stderr.
214
215 Uses diagnostic_context.m_text_callbacks to provide client-specific
216 textual output (e.g. include paths, macro expansions, etc). */
217
218class diagnostic_text_output_format : public diagnostic_output_format
219{
220public:
221 diagnostic_text_output_format (diagnostic_context &context)
222 : diagnostic_output_format (context)
223 {}
224 ~diagnostic_text_output_format ();
225 void on_begin_group () override {}
226 void on_end_group () override {}
227 void on_begin_diagnostic (diagnostic_info *) override;
228 void on_end_diagnostic (diagnostic_info *,
229 diagnostic_t orig_diag_kind) override;
230 void on_diagram (const diagnostic_diagram &diagram) override;
231};
232
233/* A stack of sets of classifications: each entry in the stack is
234 a mapping from option index to diagnostic severity that can be changed
235 via pragmas. The stack can be pushed and popped. */
236
237class diagnostic_option_classifier
238{
239public:
240 void init (int n_opts);
241 void fini ();
242
243 /* Save all diagnostic classifications in a stack. */
244 void push ();
245
246 /* Restore the topmost classification set off the stack. If the stack
247 is empty, revert to the state based on command line parameters. */
248 void pop (location_t where);
249
250 bool option_unspecified_p (int opt) const
251 {
252 return get_current_override (opt) == DK_UNSPECIFIED;
253 }
254
255 diagnostic_t get_current_override (int opt) const
256 {
257 gcc_assert (opt < m_n_opts);
258 return m_classify_diagnostic[opt];
259 }
260
261 diagnostic_t
262 classify_diagnostic (const diagnostic_context *context,
263 int option_index,
264 diagnostic_t new_kind,
265 location_t where);
266
267 diagnostic_t
268 update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
269
270private:
271 /* Each time a diagnostic's classification is changed with a pragma,
272 we record the change and the location of the change in an array of
273 these structs. */
274 struct diagnostic_classification_change_t
275 {
276 location_t location;
277 int option;
278 diagnostic_t kind;
279 };
280
281 int m_n_opts;
282
283 /* For each option index that can be passed to warning() et al
284 (OPT_* from options.h when using this code with the core GCC
285 options), this array may contain a new kind that the diagnostic
286 should be changed to before reporting, or DK_UNSPECIFIED to leave
287 it as the reported kind, or DK_IGNORED to not report it at
288 all. */
289 diagnostic_t *m_classify_diagnostic;
290
291 /* History of all changes to the classifications above. This list
292 is stored in location-order, so we can search it, either
293 binary-wise or end-to-front, to find the most recent
294 classification for a given diagnostic, given the location of the
295 diagnostic. */
296 diagnostic_classification_change_t *m_classification_history;
297
298 /* The size of the above array. */
299 int m_n_classification_history;
300
301 /* For pragma push/pop. */
302 int *m_push_list;
303 int m_n_push;
304};
305
306/* A bundle of options relating to printing the user's source code
307 (potentially with a margin, underlining, labels, etc). */
308
309struct diagnostic_source_printing_options
310{
311 /* True if we should print the source line with a caret indicating
312 the location.
313 Corresponds to -fdiagnostics-show-caret. */
314 bool enabled;
315
316 /* Maximum width of the source line printed. */
317 int max_width;
318
319 /* Character used at the caret when printing source locations. */
320 char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
321
322 /* When printing source code, should the characters at carets and ranges
323 be colorized? (assuming colorization is on at all).
324 This should be true for frontends that generate range information
325 (so that the ranges of code are colorized),
326 and false for frontends that merely specify points within the
327 source code (to avoid e.g. colorizing just the first character in
328 a token, which would look strange). */
329 bool colorize_source_p;
330
331 /* When printing source code, should labelled ranges be printed?
332 Corresponds to -fdiagnostics-show-labels. */
333 bool show_labels_p;
334
335 /* When printing source code, should there be a left-hand margin
336 showing line numbers?
337 Corresponds to -fdiagnostics-show-line-numbers. */
338 bool show_line_numbers_p;
339
340 /* If printing source code, what should the minimum width of the margin
341 be? Line numbers will be right-aligned, and padded to this width.
342 Corresponds to -fdiagnostics-minimum-margin-width=VALUE. */
343 int min_margin_width;
344
345 /* Usable by plugins; if true, print a debugging ruler above the
346 source output. */
347 bool show_ruler_p;
348};
349
350/* This data structure bundles altogether any information relevant to
351 the context of a diagnostic message. */
352class diagnostic_context
353{
354public:
355 typedef void (*ice_handler_callback_t) (diagnostic_context *);
356 typedef void (*set_locations_callback_t) (diagnostic_context *,
357 diagnostic_info *);
358
359 void initialize (int n_opts);
360 void color_init (int value);
361 void urls_init (int value);
362
363 void file_cache_init ();
364
365 void finish ();
366
367 void set_set_locations_callback (set_locations_callback_t cb)
368 {
369 m_set_locations_cb = cb;
370 }
371
372 void
373 initialize_input_context (diagnostic_input_charset_callback ccb,
374 bool should_skip_bom);
375
376 void begin_group ();
377 void end_group ();
378
379 bool warning_enabled_at (location_t loc, int opt);
380
381 bool option_unspecified_p (int opt) const
382 {
383 return m_option_classifier.option_unspecified_p (opt);
384 }
385
386 bool report_diagnostic (diagnostic_info *);
387
388 void report_current_module (location_t where);
389
390 void check_max_errors (bool flush);
391 void action_after_output (diagnostic_t diag_kind);
392
393 diagnostic_t
394 classify_diagnostic (int option_index,
395 diagnostic_t new_kind,
396 location_t where)
397 {
398 return m_option_classifier.classify_diagnostic (context: this,
399 option_index,
400 new_kind,
401 where);
402 }
403
404 void push_diagnostics (location_t where ATTRIBUTE_UNUSED)
405 {
406 m_option_classifier.push ();
407 }
408 void pop_diagnostics (location_t where)
409 {
410 m_option_classifier.pop (where);
411 }
412
413 void maybe_show_locus (const rich_location &richloc,
414 diagnostic_t diagnostic_kind,
415 pretty_printer *pp);
416
417 void emit_diagram (const diagnostic_diagram &diagram);
418
419 /* Various setters for use by option-handling logic. */
420 void set_output_format (diagnostic_output_format *output_format);
421 void set_text_art_charset (enum diagnostic_text_art_charset charset);
422 void set_client_data_hooks (diagnostic_client_data_hooks *hooks);
423 void set_urlifier (urlifier *);
424 void create_edit_context ();
425 void set_warning_as_error_requested (bool val)
426 {
427 m_warning_as_error_requested = val;
428 }
429 void set_report_bug (bool val) { m_report_bug = val; }
430 void set_extra_output_kind (enum diagnostics_extra_output_kind kind)
431 {
432 m_extra_output_kind = kind;
433 }
434 void set_show_cwe (bool val) { m_show_cwe = val; }
435 void set_show_rules (bool val) { m_show_rules = val; }
436 void set_path_format (enum diagnostic_path_format val)
437 {
438 m_path_format = val;
439 }
440 void set_show_path_depths (bool val) { m_show_path_depths = val; }
441 void set_show_option_requested (bool val) { m_show_option_requested = val; }
442 void set_max_errors (int val) { m_max_errors = val; }
443 void set_escape_format (enum diagnostics_escape_format val)
444 {
445 m_escape_format = val;
446 }
447 void set_ice_handler_callback (ice_handler_callback_t cb)
448 {
449 m_ice_handler_cb = cb;
450 }
451
452 /* Various accessors. */
453 bool warning_as_error_requested_p () const
454 {
455 return m_warning_as_error_requested;
456 }
457 bool show_path_depths_p () const { return m_show_path_depths; }
458 enum diagnostic_path_format get_path_format () const { return m_path_format; }
459 enum diagnostics_escape_format get_escape_format () const
460 {
461 return m_escape_format;
462 }
463
464 file_cache *
465 get_file_cache () const
466 {
467 return m_file_cache;
468 }
469
470 edit_context *get_edit_context () const
471 {
472 return m_edit_context_ptr;
473 }
474 const diagnostic_client_data_hooks *get_client_data_hooks ()
475 {
476 return m_client_data_hooks;
477 }
478 text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
479
480 int converted_column (expanded_location s) const;
481
482 int &diagnostic_count (diagnostic_t kind)
483 {
484 return m_diagnostic_count[kind];
485 }
486
487private:
488 bool includes_seen_p (const line_map_ordinary *map);
489
490 void print_any_cwe (const diagnostic_info &diagnostic);
491 void print_any_rules (const diagnostic_info &diagnostic);
492 void print_option_information (const diagnostic_info &diagnostic,
493 diagnostic_t orig_diag_kind);
494
495 void show_any_path (const diagnostic_info &diagnostic);
496
497 void error_recursion () ATTRIBUTE_NORETURN;
498
499 bool diagnostic_enabled (diagnostic_info *diagnostic);
500
501 void get_any_inlining_info (diagnostic_info *diagnostic);
502
503 void show_locus (const rich_location &richloc,
504 diagnostic_t diagnostic_kind,
505 pretty_printer *pp);
506
507 /* Data members.
508 Ideally, all of these would be private and have "m_" prefixes. */
509
510public:
511 /* Where most of the diagnostic formatting work is done. */
512 pretty_printer *printer;
513
514private:
515 /* Cache of source code. */
516 file_cache *m_file_cache;
517
518 /* The number of times we have issued diagnostics. */
519 int m_diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
520
521 /* True if it has been requested that warnings be treated as errors. */
522 bool m_warning_as_error_requested;
523
524 /* The number of option indexes that can be passed to warning() et
525 al. */
526 int m_n_opts;
527
528 /* The stack of sets of overridden diagnostic option severities. */
529 diagnostic_option_classifier m_option_classifier;
530
531 /* True if we should print any CWE identifiers associated with
532 diagnostics. */
533 bool m_show_cwe;
534
535 /* True if we should print any rules associated with diagnostics. */
536 bool m_show_rules;
537
538 /* How should diagnostic_path objects be printed. */
539 enum diagnostic_path_format m_path_format;
540
541 /* True if we should print stack depths when printing diagnostic paths. */
542 bool m_show_path_depths;
543
544 /* True if we should print the command line option which controls
545 each diagnostic, if known. */
546 bool m_show_option_requested;
547
548public:
549 /* True if we should raise a SIGABRT on errors. */
550 bool m_abort_on_error;
551
552 /* True if we should show the column number on diagnostics. */
553 bool m_show_column;
554
555 /* True if pedwarns are errors. */
556 bool m_pedantic_errors;
557
558 /* True if permerrors are warnings. */
559 bool m_permissive;
560
561 /* The index of the option to associate with turning permerrors into
562 warnings. */
563 int m_opt_permissive;
564
565 /* True if errors are fatal. */
566 bool m_fatal_errors;
567
568 /* True if all warnings should be disabled. */
569 bool m_inhibit_warnings;
570
571 /* True if warnings should be given in system headers. */
572 bool m_warn_system_headers;
573
574private:
575 /* Maximum number of errors to report. */
576 int m_max_errors;
577
578public:
579 /* Client-supplied callbacks for use in text output. */
580 struct {
581 /* This function is called before any message is printed out. It is
582 responsible for preparing message prefix and such. For example, it
583 might say:
584 In file included from "/usr/local/include/curses.h:5:
585 from "/home/gdr/src/nifty_printer.h:56:
586 ...
587 */
588 diagnostic_starter_fn begin_diagnostic;
589
590 /* This function is called by diagnostic_show_locus in between
591 disjoint spans of source code, so that the context can print
592 something to indicate that a new span of source code has begun. */
593 diagnostic_start_span_fn start_span;
594
595 /* This function is called after the diagnostic message is printed. */
596 diagnostic_finalizer_fn end_diagnostic;
597 } m_text_callbacks;
598
599 /* Client hook to report an internal error. */
600 void (*m_internal_error) (diagnostic_context *, const char *, va_list *);
601
602 /* Client hook to say whether the option controlling a diagnostic is
603 enabled. Returns nonzero if enabled, zero if disabled. */
604 int (*m_option_enabled) (int, unsigned, void *);
605
606 /* Client information to pass as second argument to
607 option_enabled. */
608 void *m_option_state;
609
610 /* Client hook to return the name of an option that controls a
611 diagnostic. Returns malloced memory. The first diagnostic_t
612 argument is the kind of diagnostic before any reclassification
613 (of warnings as errors, etc.); the second is the kind after any
614 reclassification. May return NULL if no name is to be printed.
615 May be passed 0 as well as the index of a particular option. */
616 char *(*m_option_name) (diagnostic_context *,
617 int,
618 diagnostic_t,
619 diagnostic_t);
620
621 /* Client hook to return a URL describing the option that controls
622 a diagnostic. Returns malloced memory. May return NULL if no URL
623 is available. May be passed 0 as well as the index of a
624 particular option. */
625 char *(*m_get_option_url) (diagnostic_context *, int);
626
627private:
628 /* An optional hook for adding URLs to quoted text strings in
629 diagnostics. Only used for the main diagnostic message. */
630 urlifier *m_urlifier;
631
632public:
633 void (*m_print_path) (diagnostic_context *, const diagnostic_path *);
634 json::value *(*m_make_json_for_path) (diagnostic_context *,
635 const diagnostic_path *);
636
637 /* Auxiliary data for client. */
638 void *m_client_aux_data;
639
640 /* Used to detect that the last caret was printed at the same location. */
641 location_t m_last_location;
642
643private:
644 /* Used to detect when the input file stack has changed since last
645 described. */
646 const line_map_ordinary *m_last_module;
647
648 int m_lock;
649
650public:
651 /* A copy of lang_hooks.option_lang_mask (). */
652 unsigned m_lang_mask;
653
654 bool m_inhibit_notes_p;
655
656 diagnostic_source_printing_options m_source_printing;
657
658private:
659 /* True if -freport-bug option is used. */
660 bool m_report_bug;
661
662 /* Used to specify additional diagnostic output to be emitted after the
663 rest of the diagnostic. This is for implementing
664 -fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
665 enum diagnostics_extra_output_kind m_extra_output_kind;
666
667public:
668 /* What units to use when outputting the column number. */
669 enum diagnostics_column_unit m_column_unit;
670
671 /* The origin for the column number (1-based or 0-based typically). */
672 int m_column_origin;
673
674 /* The size of the tabstop for tab expansion. */
675 int m_tabstop;
676
677private:
678 /* How should non-ASCII/non-printable bytes be escaped when
679 a diagnostic suggests escaping the source code on output. */
680 enum diagnostics_escape_format m_escape_format;
681
682 /* If non-NULL, an edit_context to which fix-it hints should be
683 applied, for generating patches. */
684 edit_context *m_edit_context_ptr;
685
686 /* Fields relating to diagnostic groups. */
687 struct {
688 /* How many diagnostic_group instances are currently alive. */
689 int m_nesting_depth;
690
691 /* How many diagnostics have been emitted since the bottommost
692 diagnostic_group was pushed. */
693 int m_emission_count;
694 } m_diagnostic_groups;
695
696 /* How to output diagnostics (text vs a structured format such as JSON).
697 Must be non-NULL; owned by context. */
698 diagnostic_output_format *m_output_format;
699
700 /* Callback to set the locations of call sites along the inlining
701 stack corresponding to a diagnostic location. Needed to traverse
702 the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
703 of a diagnostic's location. */
704 set_locations_callback_t m_set_locations_cb;
705
706 /* Optional callback for attempting to handle ICEs gracefully. */
707 ice_handler_callback_t m_ice_handler_cb;
708
709 /* Include files that diagnostic_report_current_module has already listed the
710 include path for. */
711 hash_set<location_t, false, location_hash> *m_includes_seen;
712
713 /* A bundle of hooks for providing data to the context about its client
714 e.g. version information, plugins, etc.
715 Used by SARIF output to give metadata about the client that's
716 producing diagnostics. */
717 diagnostic_client_data_hooks *m_client_data_hooks;
718
719 /* Support for diagrams. */
720 struct
721 {
722 /* Theme to use when generating diagrams.
723 Can be NULL (if text art is disabled). */
724 text_art::theme *m_theme;
725
726 } m_diagrams;
727};
728
729inline void
730diagnostic_inhibit_notes (diagnostic_context * context)
731{
732 context->m_inhibit_notes_p = true;
733}
734
735
736/* Client supplied function to announce a diagnostic
737 (for text-based diagnostic output). */
738#define diagnostic_starter(DC) (DC)->m_text_callbacks.begin_diagnostic
739
740/* Client supplied function called after a diagnostic message is
741 displayed (for text-based diagnostic output). */
742#define diagnostic_finalizer(DC) (DC)->m_text_callbacks.end_diagnostic
743
744/* Extension hooks for client. */
745#define diagnostic_context_auxiliary_data(DC) (DC)->m_client_aux_data
746#define diagnostic_info_auxiliary_data(DI) (DI)->x_data
747
748/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */
749#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
750
751/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
752#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
753
754/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
755inline void
756diagnostic_abort_on_error (diagnostic_context *context)
757{
758 context->m_abort_on_error = true;
759}
760
761/* This diagnostic_context is used by front-ends that directly output
762 diagnostic messages without going through `error', `warning',
763 and similar functions. */
764extern diagnostic_context *global_dc;
765
766/* Returns whether the diagnostic framework has been intialized already and is
767 ready for use. */
768#define diagnostic_ready_p() (global_dc->printer != NULL)
769
770/* The number of errors that have been issued so far. Ideally, these
771 would take a diagnostic_context as an argument. */
772#define errorcount global_dc->diagnostic_count (DK_ERROR)
773/* Similarly, but for warnings. */
774#define warningcount global_dc->diagnostic_count (DK_WARNING)
775/* Similarly, but for warnings promoted to errors. */
776#define werrorcount global_dc->diagnostic_count (DK_WERROR)
777/* Similarly, but for sorrys. */
778#define sorrycount global_dc->diagnostic_count (DK_SORRY)
779
780/* Returns nonzero if warnings should be emitted. */
781#define diagnostic_report_warnings_p(DC, LOC) \
782 (!(DC)->m_inhibit_warnings \
783 && !(in_system_header_at (LOC) && !(DC)->m_warn_system_headers))
784
785/* Override the option index to be used for reporting a
786 diagnostic. */
787
788inline void
789diagnostic_override_option_index (diagnostic_info *info, int optidx)
790{
791 info->option_index = optidx;
792}
793
794/* Diagnostic related functions. */
795
796inline void
797diagnostic_initialize (diagnostic_context *context, int n_opts)
798{
799 context->initialize (n_opts);
800}
801
802inline void
803diagnostic_color_init (diagnostic_context *context, int value = -1)
804{
805 context->color_init (value);
806}
807
808inline void
809diagnostic_urls_init (diagnostic_context *context, int value = -1)
810{
811 context->urls_init (value);
812}
813
814inline void
815diagnostic_finish (diagnostic_context *context)
816{
817 context->finish ();
818}
819
820inline void
821diagnostic_report_current_module (diagnostic_context *context,
822 location_t where)
823{
824 context->report_current_module (where);
825}
826
827inline void
828diagnostic_show_locus (diagnostic_context *context,
829 rich_location *richloc,
830 diagnostic_t diagnostic_kind,
831 pretty_printer *pp = nullptr)
832{
833 gcc_assert (richloc);
834 context->maybe_show_locus (richloc: *richloc, diagnostic_kind, pp);
835}
836
837/* Because we read source files a second time after the frontend did it the
838 first time, we need to know how the frontend handled things like character
839 set conversion and UTF-8 BOM stripping, in order to make everything
840 consistent. This function needs to be called by each frontend that requires
841 non-default behavior, to inform the diagnostics infrastructure how input is
842 to be processed. The default behavior is to do no conversion and not to
843 strip a UTF-8 BOM.
844
845 The callback should return the input charset to be used to convert the given
846 file's contents to UTF-8, or it should return NULL if no conversion is needed
847 for this file. SHOULD_SKIP_BOM only applies in case no conversion was
848 performed, and if true, it will cause a UTF-8 BOM to be skipped at the
849 beginning of the file. (In case a conversion was performed, the BOM is
850 rather skipped as part of the conversion process.) */
851
852inline void
853diagnostic_initialize_input_context (diagnostic_context *context,
854 diagnostic_input_charset_callback ccb,
855 bool should_skip_bom)
856{
857 context->initialize_input_context (ccb, should_skip_bom);
858}
859
860/* Force diagnostics controlled by OPTIDX to be kind KIND. */
861inline diagnostic_t
862diagnostic_classify_diagnostic (diagnostic_context *context,
863 int optidx,
864 diagnostic_t kind,
865 location_t where)
866{
867 return context->classify_diagnostic (option_index: optidx, new_kind: kind, where);
868}
869
870inline void
871diagnostic_push_diagnostics (diagnostic_context *context,
872 location_t where)
873{
874 context->push_diagnostics (where);
875}
876inline void
877diagnostic_pop_diagnostics (diagnostic_context *context,
878 location_t where)
879{
880 context->pop_diagnostics (where);
881}
882
883/* Report a diagnostic message (an error or a warning) as specified by
884 DC. This function is *the* subroutine in terms of which front-ends
885 should implement their specific diagnostic handling modules. The
886 front-end independent format specifiers are exactly those described
887 in the documentation of output_format.
888 Return true if a diagnostic was printed, false otherwise. */
889
890inline bool
891diagnostic_report_diagnostic (diagnostic_context *context,
892 diagnostic_info *diagnostic)
893{
894 return context->report_diagnostic (diagnostic);
895}
896
897#ifdef ATTRIBUTE_GCC_DIAG
898extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
899 rich_location *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
900extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
901 va_list *, rich_location *,
902 diagnostic_t)
903 ATTRIBUTE_GCC_DIAG(2,0);
904extern void diagnostic_append_note (diagnostic_context *, location_t,
905 const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
906#endif
907extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *);
908void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
909void default_diagnostic_start_span_fn (diagnostic_context *,
910 expanded_location);
911void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *,
912 diagnostic_t);
913void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
914
915inline void
916diagnostic_action_after_output (diagnostic_context *context,
917 diagnostic_t diag_kind)
918{
919 context->action_after_output (diag_kind);
920}
921
922inline void
923diagnostic_check_max_errors (diagnostic_context *context, bool flush = false)
924{
925 context->check_max_errors (flush);
926}
927
928int get_terminal_width (void);
929
930/* Return the location associated to this diagnostic. Parameter WHICH
931 specifies which location. By default, expand the first one. */
932
933inline location_t
934diagnostic_location (const diagnostic_info * diagnostic, int which = 0)
935{
936 return diagnostic->message.get_location (index_of_location: which);
937}
938
939/* Return the number of locations to be printed in DIAGNOSTIC. */
940
941inline unsigned int
942diagnostic_num_locations (const diagnostic_info * diagnostic)
943{
944 return diagnostic->message.m_richloc->get_num_locations ();
945}
946
947/* Expand the location of this diagnostic. Use this function for
948 consistency. Parameter WHICH specifies which location. By default,
949 expand the first one. */
950
951inline expanded_location
952diagnostic_expand_location (const diagnostic_info * diagnostic, int which = 0)
953{
954 return diagnostic->richloc->get_expanded_location (idx: which);
955}
956
957/* This is somehow the right-side margin of a caret line, that is, we
958 print at least these many characters after the position pointed at
959 by the caret. */
960const int CARET_LINE_MARGIN = 10;
961
962/* Return true if the two locations can be represented within the same
963 caret line. This is used to build a prefix and also to determine
964 whether to print one or two caret lines. */
965
966inline bool
967diagnostic_same_line (const diagnostic_context *context,
968 expanded_location s1, expanded_location s2)
969{
970 return (s2.column && s1.line == s2.line
971 && (context->m_source_printing.max_width - CARET_LINE_MARGIN
972 > abs (x: s1.column - s2.column)));
973}
974
975extern const char *diagnostic_get_color_for_kind (diagnostic_t kind);
976
977/* Pure text formatting support functions. */
978extern char *file_name_as_prefix (diagnostic_context *, const char *);
979
980extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
981
982extern void diagnostic_output_format_init (diagnostic_context *,
983 const char *base_file_name,
984 enum diagnostics_output_format);
985extern void diagnostic_output_format_init_json_stderr (diagnostic_context *context);
986extern void diagnostic_output_format_init_json_file (diagnostic_context *context,
987 const char *base_file_name);
988extern void diagnostic_output_format_init_sarif_stderr (diagnostic_context *context);
989extern void diagnostic_output_format_init_sarif_file (diagnostic_context *context,
990 const char *base_file_name);
991extern void diagnostic_output_format_init_sarif_stream (diagnostic_context *context,
992 FILE *stream);
993
994/* Compute the number of digits in the decimal representation of an integer. */
995extern int num_digits (int);
996
997extern json::value *json_from_expanded_location (diagnostic_context *context,
998 location_t loc);
999
1000inline bool
1001warning_enabled_at (location_t loc, int opt)
1002{
1003 return global_dc->warning_enabled_at (loc, opt);
1004}
1005
1006inline bool
1007option_unspecified_p (int opt)
1008{
1009 return global_dc->option_unspecified_p (opt);
1010}
1011
1012extern char *get_cwe_url (int cwe);
1013
1014#endif /* ! GCC_DIAGNOSTIC_H */
1015

source code of gcc/diagnostic.h