Branch data Line data Source code
1 : : /* Various declarations for language-independent diagnostics subroutines.
2 : : Copyright (C) 2000-2025 Free Software Foundation, Inc.
3 : : Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along 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 "unique-argv.h"
25 : : #include "rich-location.h"
26 : : #include "pretty-print.h"
27 : : #include "diagnostic-core.h"
28 : :
29 : : namespace text_art
30 : : {
31 : : class theme;
32 : : } // namespace text_art
33 : :
34 : : namespace xml
35 : : {
36 : : class printer;
37 : : } // namespace xml
38 : :
39 : : /* An enum for controlling what units to use for the column number
40 : : when diagnostics are output, used by the -fdiagnostics-column-unit option.
41 : : Tabs will be expanded or not according to the value of -ftabstop. The origin
42 : : (default 1) is controlled by -fdiagnostics-column-origin. */
43 : :
44 : : enum diagnostics_column_unit
45 : : {
46 : : /* The default from GCC 11 onwards: display columns. */
47 : : DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
48 : :
49 : : /* The behavior in GCC 10 and earlier: simple bytes. */
50 : : DIAGNOSTICS_COLUMN_UNIT_BYTE
51 : : };
52 : :
53 : : /* An enum for controlling how to print non-ASCII characters/bytes when
54 : : a diagnostic suggests escaping the source code on output. */
55 : :
56 : : enum diagnostics_escape_format
57 : : {
58 : : /* Escape non-ASCII Unicode characters in the form <U+XXXX> and
59 : : non-UTF-8 bytes in the form <XX>. */
60 : : DIAGNOSTICS_ESCAPE_FORMAT_UNICODE,
61 : :
62 : : /* Escape non-ASCII bytes in the form <XX> (thus showing the underlying
63 : : encoding of non-ASCII Unicode characters). */
64 : : DIAGNOSTICS_ESCAPE_FORMAT_BYTES
65 : : };
66 : :
67 : : /* Enum for overriding the standard output format. */
68 : :
69 : : enum diagnostics_output_format
70 : : {
71 : : /* The default: textual output. */
72 : : DIAGNOSTICS_OUTPUT_FORMAT_TEXT,
73 : :
74 : : /* SARIF-based output, as JSON to stderr. */
75 : : DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR,
76 : :
77 : : /* SARIF-based output, to a JSON file. */
78 : : DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE
79 : : };
80 : :
81 : : /* An enum for controlling how diagnostic_paths should be printed. */
82 : : enum diagnostic_path_format
83 : : {
84 : : /* Don't print diagnostic_paths. */
85 : : DPF_NONE,
86 : :
87 : : /* Print diagnostic_paths by emitting a separate "note" for every event
88 : : in the path. */
89 : : DPF_SEPARATE_EVENTS,
90 : :
91 : : /* Print diagnostic_paths by consolidating events together where they
92 : : are close enough, and printing such runs of events with multiple
93 : : calls to diagnostic_show_locus, showing the individual events in
94 : : each run via labels in the source. */
95 : : DPF_INLINE_EVENTS
96 : : };
97 : :
98 : : /* An enum for capturing values of GCC_EXTRA_DIAGNOSTIC_OUTPUT,
99 : : and for -fdiagnostics-parseable-fixits. */
100 : :
101 : : enum diagnostics_extra_output_kind
102 : : {
103 : : /* No extra output, or an unrecognized value. */
104 : : EXTRA_DIAGNOSTIC_OUTPUT_none,
105 : :
106 : : /* Emit fix-it hints using the "fixits-v1" format, equivalent to
107 : : -fdiagnostics-parseable-fixits. */
108 : : EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1,
109 : :
110 : : /* Emit fix-it hints using the "fixits-v2" format. */
111 : : EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2
112 : : };
113 : :
114 : : /* Values for -fdiagnostics-text-art-charset=. */
115 : :
116 : : enum diagnostic_text_art_charset
117 : : {
118 : : /* No text art diagrams shall be emitted. */
119 : : DIAGNOSTICS_TEXT_ART_CHARSET_NONE,
120 : :
121 : : /* Use pure ASCII for text art diagrams. */
122 : : DIAGNOSTICS_TEXT_ART_CHARSET_ASCII,
123 : :
124 : : /* Use ASCII + conservative use of other unicode characters
125 : : in text art diagrams. */
126 : : DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE,
127 : :
128 : : /* Use Emoji. */
129 : : DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI
130 : : };
131 : :
132 : : /* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
133 : : its context and its KIND (ice, error, warning, note, ...) See complete
134 : : list in diagnostic.def. */
135 : 198622352 : struct diagnostic_info
136 : : {
137 : 99311885 : diagnostic_info ()
138 : 99311885 : : message (), richloc (), metadata (), x_data (), kind (), option_id (),
139 : 99311885 : m_iinfo ()
140 : 99311885 : { }
141 : :
142 : : /* Text to be formatted. */
143 : : text_info message;
144 : :
145 : : /* The location at which the diagnostic is to be reported. */
146 : : rich_location *richloc;
147 : :
148 : : /* An optional bundle of metadata associated with the diagnostic
149 : : (or NULL). */
150 : : const diagnostic_metadata *metadata;
151 : :
152 : : /* Auxiliary data for client. */
153 : : void *x_data;
154 : : /* The kind of diagnostic it is about. */
155 : : diagnostic_t kind;
156 : : /* Which OPT_* directly controls this diagnostic. */
157 : : diagnostic_option_id option_id;
158 : :
159 : : /* Inlining context containing locations for each call site along
160 : : the inlining stack. */
161 : 99311176 : struct inlining_info
162 : : {
163 : : /* Locations along the inlining stack. */
164 : : auto_vec<location_t, 8> m_ilocs;
165 : : /* The abstract origin of the location. */
166 : : void *m_ao;
167 : : /* Set if every M_ILOCS element is in a system header. */
168 : : bool m_allsyslocs;
169 : : } m_iinfo;
170 : : };
171 : :
172 : : /* Forward declarations. */
173 : : class diagnostic_location_print_policy;
174 : : class diagnostic_source_print_policy;
175 : :
176 : : typedef void (*diagnostic_text_starter_fn) (diagnostic_text_output_format &,
177 : : const diagnostic_info *);
178 : :
179 : : struct to_text;
180 : : struct to_html;
181 : :
182 : : extern pretty_printer *get_printer (to_text &);
183 : :
184 : : template <typename Sink>
185 : : using diagnostic_start_span_fn = void (*) (const diagnostic_location_print_policy &,
186 : : Sink &sink,
187 : : expanded_location);
188 : :
189 : : typedef void (*diagnostic_text_finalizer_fn) (diagnostic_text_output_format &,
190 : : const diagnostic_info *,
191 : : diagnostic_t);
192 : :
193 : : /* Abstract base class for the diagnostic subsystem to make queries
194 : : about command-line options. */
195 : :
196 : 299632 : class diagnostic_option_manager
197 : : {
198 : : public:
199 : : virtual ~diagnostic_option_manager () {}
200 : :
201 : : /* Return 1 if option OPTION_ID is enabled, 0 if it is disabled,
202 : : or -1 if it isn't a simple on-off switch
203 : : (or if the value is unknown, typically set later in target). */
204 : : virtual int option_enabled_p (diagnostic_option_id option_id) const = 0;
205 : :
206 : : /* Return malloced memory for the name of the option OPTION_ID
207 : : which enabled a diagnostic, originally of type ORIG_DIAG_KIND but
208 : : possibly converted to DIAG_KIND by options such as -Werror.
209 : : May return NULL if no name is to be printed.
210 : : May be passed 0 as well as the index of a particular option. */
211 : : virtual char *make_option_name (diagnostic_option_id option_id,
212 : : diagnostic_t orig_diag_kind,
213 : : diagnostic_t diag_kind) const = 0;
214 : :
215 : : /* Return malloced memory for a URL describing the option that controls
216 : : a diagnostic.
217 : : May return NULL if no URL is available.
218 : : May be passed 0 as well as the index of a particular option. */
219 : : virtual char *make_option_url (diagnostic_option_id option_id) const = 0;
220 : : };
221 : :
222 : : class edit_context;
223 : : class diagnostic_client_data_hooks;
224 : : class logical_location_manager;
225 : : class diagnostic_diagram;
226 : : class diagnostic_source_effect_info;
227 : : class diagnostic_output_format;
228 : : class diagnostic_text_output_format;
229 : : class diagnostic_buffer;
230 : :
231 : : /* A stack of sets of classifications: each entry in the stack is
232 : : a mapping from option index to diagnostic severity that can be changed
233 : : via pragmas. The stack can be pushed and popped. */
234 : :
235 : : class diagnostic_option_classifier
236 : : {
237 : : public:
238 : : void init (int n_opts);
239 : : void fini ();
240 : :
241 : : /* Save all diagnostic classifications in a stack. */
242 : : void push ();
243 : :
244 : : /* Restore the topmost classification set off the stack. If the stack
245 : : is empty, revert to the state based on command line parameters. */
246 : : void pop (location_t where);
247 : :
248 : 1063582 : bool option_unspecified_p (diagnostic_option_id option_id) const
249 : : {
250 : 1655474 : return get_current_override (option_id) == DK_UNSPECIFIED;
251 : : }
252 : :
253 : 1073437 : diagnostic_t get_current_override (diagnostic_option_id option_id) const
254 : : {
255 : 1073437 : gcc_assert (option_id.m_idx < m_n_opts);
256 : 1073437 : return m_classify_diagnostic[option_id.m_idx];
257 : : }
258 : :
259 : : diagnostic_t
260 : : classify_diagnostic (const diagnostic_context *context,
261 : : diagnostic_option_id option_id,
262 : : diagnostic_t new_kind,
263 : : location_t where);
264 : :
265 : : diagnostic_t
266 : : update_effective_level_from_pragmas (diagnostic_info *diagnostic) const;
267 : :
268 : : int pch_save (FILE *);
269 : : int pch_restore (FILE *);
270 : :
271 : : private:
272 : : /* Each time a diagnostic's classification is changed with a pragma,
273 : : we record the change and the location of the change in an array of
274 : : these structs. */
275 : : struct diagnostic_classification_change_t
276 : : {
277 : : location_t location;
278 : :
279 : : /* For DK_POP, this is the index of the corresponding push (as stored
280 : : in m_push_list).
281 : : Otherwise, this is an option index. */
282 : : int option;
283 : :
284 : : diagnostic_t kind;
285 : : };
286 : :
287 : : int m_n_opts;
288 : :
289 : : /* For each option index that can be passed to warning() et al
290 : : (OPT_* from options.h when using this code with the core GCC
291 : : options), this array may contain a new kind that the diagnostic
292 : : should be changed to before reporting, or DK_UNSPECIFIED to leave
293 : : it as the reported kind, or DK_IGNORED to not report it at
294 : : all. */
295 : : diagnostic_t *m_classify_diagnostic;
296 : :
297 : : /* History of all changes to the classifications above. This list
298 : : is stored in location-order, so we can search it, either
299 : : binary-wise or end-to-front, to find the most recent
300 : : classification for a given diagnostic, given the location of the
301 : : diagnostic. */
302 : : vec<diagnostic_classification_change_t> m_classification_history;
303 : :
304 : : /* For diagnostic_context::get_classification_history, declared later. */
305 : : friend class diagnostic_context;
306 : :
307 : : /* For pragma push/pop. */
308 : : vec<int> m_push_list;
309 : : };
310 : :
311 : : /* A bundle of options relating to printing the user's source code
312 : : (potentially with a margin, underlining, labels, etc). */
313 : :
314 : : struct diagnostic_source_printing_options
315 : : {
316 : : /* True if we should print the source line with a caret indicating
317 : : the location.
318 : : Corresponds to -fdiagnostics-show-caret. */
319 : : bool enabled;
320 : :
321 : : /* Maximum width of the source line printed. */
322 : : int max_width;
323 : :
324 : : /* Character used at the caret when printing source locations. */
325 : : char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
326 : :
327 : : /* When printing source code, should the characters at carets and ranges
328 : : be colorized? (assuming colorization is on at all).
329 : : This should be true for frontends that generate range information
330 : : (so that the ranges of code are colorized),
331 : : and false for frontends that merely specify points within the
332 : : source code (to avoid e.g. colorizing just the first character in
333 : : a token, which would look strange). */
334 : : bool colorize_source_p;
335 : :
336 : : /* When printing source code, should labelled ranges be printed?
337 : : Corresponds to -fdiagnostics-show-labels. */
338 : : bool show_labels_p;
339 : :
340 : : /* When printing source code, should there be a left-hand margin
341 : : showing line numbers?
342 : : Corresponds to -fdiagnostics-show-line-numbers. */
343 : : bool show_line_numbers_p;
344 : :
345 : : /* If printing source code, what should the minimum width of the margin
346 : : be? Line numbers will be right-aligned, and padded to this width.
347 : : Corresponds to -fdiagnostics-minimum-margin-width=VALUE. */
348 : : int min_margin_width;
349 : :
350 : : /* Usable by plugins; if true, print a debugging ruler above the
351 : : source output. */
352 : : bool show_ruler_p;
353 : :
354 : : /* When printing events in an inline path, should we print lines
355 : : visualizing links between related events (e.g. for CFG paths)?
356 : : Corresponds to -fdiagnostics-show-event-links. */
357 : : bool show_event_links_p;
358 : : };
359 : :
360 : : /* A bundle of state for determining column numbers in diagnostics
361 : : (tab stops, whether to start at 0 or 1, etc).
362 : : Uses a file_cache to handle tabs. */
363 : :
364 : : class diagnostic_column_policy
365 : : {
366 : : public:
367 : : diagnostic_column_policy (const diagnostic_context &dc);
368 : :
369 : : int converted_column (expanded_location s) const;
370 : :
371 : : label_text get_location_text (const expanded_location &s,
372 : : bool show_column,
373 : : bool colorize) const;
374 : :
375 : 49236 : int get_tabstop () const { return m_tabstop; }
376 : :
377 : : private:
378 : : file_cache &m_file_cache;
379 : : enum diagnostics_column_unit m_column_unit;
380 : : int m_column_origin;
381 : : int m_tabstop;
382 : : };
383 : :
384 : : /* A bundle of state for printing locations within diagnostics
385 : : (e.g. "FILENAME:LINE:COLUMN"), to isolate the interactions between
386 : : diagnostic_context and the start_span callbacks. */
387 : :
388 : : class diagnostic_location_print_policy
389 : : {
390 : : public:
391 : : diagnostic_location_print_policy (const diagnostic_context &dc);
392 : : diagnostic_location_print_policy (const diagnostic_text_output_format &);
393 : :
394 : 1197099 : bool show_column_p () const { return m_show_column; }
395 : :
396 : : const diagnostic_column_policy &
397 : 1793 : get_column_policy () const { return m_column_policy; }
398 : :
399 : : void
400 : : print_text_span_start (const diagnostic_context &dc,
401 : : pretty_printer &pp,
402 : : const expanded_location &exploc);
403 : :
404 : : void
405 : : print_html_span_start (const diagnostic_context &dc,
406 : : xml::printer &xp,
407 : : const expanded_location &exploc);
408 : :
409 : : private:
410 : : diagnostic_column_policy m_column_policy;
411 : : bool m_show_column;
412 : : };
413 : :
414 : : /* Abstract base class for optionally supplying extra tags when writing
415 : : out annotation labels in HTML output. */
416 : :
417 : 3 : class html_label_writer
418 : : {
419 : : public:
420 : 3 : virtual ~html_label_writer () {}
421 : : virtual void begin_label () = 0;
422 : : virtual void end_label () = 0;
423 : : };
424 : :
425 : : /* A bundle of state for printing source within a diagnostic,
426 : : to isolate the interactions between diagnostic_context and the
427 : : implementation of diagnostic_show_locus. */
428 : :
429 : : class diagnostic_source_print_policy
430 : : {
431 : : public:
432 : : diagnostic_source_print_policy (const diagnostic_context &);
433 : : diagnostic_source_print_policy (const diagnostic_context &,
434 : : const diagnostic_source_printing_options &);
435 : :
436 : : void
437 : : print (pretty_printer &pp,
438 : : const rich_location &richloc,
439 : : diagnostic_t diagnostic_kind,
440 : : diagnostic_source_effect_info *effect_info) const;
441 : :
442 : : void
443 : : print_as_html (xml::printer &xp,
444 : : const rich_location &richloc,
445 : : diagnostic_t diagnostic_kind,
446 : : diagnostic_source_effect_info *effect_info,
447 : : html_label_writer *label_writer) const;
448 : :
449 : : const diagnostic_source_printing_options &
450 : 49051 : get_options () const { return m_options; }
451 : :
452 : : diagnostic_start_span_fn<to_text>
453 : 1793 : get_text_start_span_fn () const { return m_text_start_span_cb; }
454 : :
455 : : diagnostic_start_span_fn<to_html>
456 : 1 : get_html_start_span_fn () const { return m_html_start_span_cb; }
457 : :
458 : : file_cache &
459 : 49048 : get_file_cache () const { return m_file_cache; }
460 : :
461 : : enum diagnostics_escape_format
462 : 554 : get_escape_format () const
463 : : {
464 : 554 : return m_escape_format;
465 : : }
466 : :
467 : : text_art::theme *
468 : 51684 : get_diagram_theme () const { return m_diagram_theme; }
469 : :
470 : : const diagnostic_column_policy &get_column_policy () const
471 : : {
472 : 49236 : return m_location_policy.get_column_policy ();
473 : : }
474 : :
475 : 463 : const diagnostic_location_print_policy &get_location_policy () const
476 : : {
477 : 463 : return m_location_policy;
478 : : }
479 : :
480 : : private:
481 : : const diagnostic_source_printing_options &m_options;
482 : : class diagnostic_location_print_policy m_location_policy;
483 : : diagnostic_start_span_fn<to_text> m_text_start_span_cb;
484 : : diagnostic_start_span_fn<to_html> m_html_start_span_cb;
485 : : file_cache &m_file_cache;
486 : :
487 : : /* Other data copied from diagnostic_context. */
488 : : text_art::theme *m_diagram_theme;
489 : : enum diagnostics_escape_format m_escape_format;
490 : : };
491 : :
492 : : /* A collection of counters of diagnostics, per-kind
493 : : (e.g. "3 errors and 1 warning"), for use by both diagnostic_context
494 : : and by diagnostic_buffer. */
495 : :
496 : : struct diagnostic_counters
497 : : {
498 : : diagnostic_counters ();
499 : :
500 : : void dump (FILE *out, int indent) const;
501 : 0 : void DEBUG_FUNCTION dump () const { dump (stderr, 0); }
502 : :
503 : 801331 : int get_count (diagnostic_t kind) const { return m_count_for_kind[kind]; }
504 : :
505 : : void move_to (diagnostic_counters &dest);
506 : : void clear ();
507 : :
508 : : int m_count_for_kind[DK_LAST_DIAGNOSTIC_KIND];
509 : : };
510 : :
511 : : /* This class encapsulates the state of the diagnostics subsystem
512 : : as a whole (either directly, or via owned objects of other classes, to
513 : : avoid global variables).
514 : :
515 : : It has responsibility for:
516 : : - being a central place for clients to report diagnostics
517 : : - reporting those diagnostics to zero or more output sinks
518 : : (e.g. text vs SARIF)
519 : : - providing a "dump" member function for a debug dump of the state of
520 : : the diagnostics subsytem
521 : : - direct vs buffered diagnostics (see class diagnostic_buffer)
522 : : - tracking the original argv of the program (for SARIF output)
523 : : - crash-handling
524 : :
525 : : It delegates responsibility to various other classes:
526 : : - the various output sinks (instances of diagnostic_output_format
527 : : subclasses)
528 : : - formatting of messages (class pretty_printer)
529 : : - an optional urlifier to inject URLs into formatted messages
530 : : - counting the number of diagnostics reported of each kind
531 : : (class diagnostic_counters)
532 : : - calling out to a diagnostic_option_manager to determine if
533 : : a particular warning is enabled or disabled
534 : : - tracking pragmas that enable/disable warnings in a range of
535 : : source code
536 : : - a cache for use when quoting the user's source code (class file_cache)
537 : : - a text_art::theme
538 : : - an edit_context for generating patches from fix-it hints
539 : : - diagnostic_client_data_hooks for metadata.
540 : :
541 : : Try to avoid adding new responsibilities to this class itself, to avoid
542 : : the "blob" anti-pattern. */
543 : :
544 : 38588 : class diagnostic_context
545 : : {
546 : : public:
547 : : /* Give access to m_text_callbacks. */
548 : : friend diagnostic_text_starter_fn &
549 : : diagnostic_text_starter (diagnostic_context *context);
550 : : friend diagnostic_start_span_fn<to_text> &
551 : : diagnostic_start_span (diagnostic_context *context);
552 : : friend diagnostic_text_finalizer_fn &
553 : : diagnostic_text_finalizer (diagnostic_context *context);
554 : :
555 : : friend class diagnostic_source_print_policy;
556 : : friend class diagnostic_text_output_format;
557 : : friend class diagnostic_buffer;
558 : :
559 : : typedef void (*set_locations_callback_t) (diagnostic_context *,
560 : : diagnostic_info *);
561 : :
562 : : void initialize (int n_opts);
563 : : void color_init (int value);
564 : : void urls_init (int value);
565 : : void set_pretty_printer (std::unique_ptr<pretty_printer> pp);
566 : : void refresh_output_sinks ();
567 : :
568 : : void finish ();
569 : :
570 : : void dump (FILE *out) const;
571 : 0 : void DEBUG_FUNCTION dump () const { dump (stderr); }
572 : :
573 : : bool execution_failed_p () const;
574 : :
575 : : void set_original_argv (unique_argv original_argv);
576 : 401 : const char * const *get_original_argv ()
577 : : {
578 : 401 : return const_cast<const char * const *> (m_original_argv);
579 : : }
580 : :
581 : 341166 : void set_set_locations_callback (set_locations_callback_t cb)
582 : : {
583 : 341166 : m_set_locations_cb = cb;
584 : : }
585 : :
586 : : void
587 : : initialize_input_context (diagnostic_input_charset_callback ccb,
588 : : bool should_skip_bom);
589 : :
590 : : void begin_group ();
591 : : void end_group ();
592 : :
593 : : void push_nesting_level ();
594 : : void pop_nesting_level ();
595 : :
596 : : bool warning_enabled_at (location_t loc, diagnostic_option_id option_id);
597 : :
598 : 1063582 : bool option_unspecified_p (diagnostic_option_id option_id) const
599 : : {
600 : 1655474 : return m_option_classifier.option_unspecified_p (option_id);
601 : : }
602 : :
603 : : bool emit_diagnostic_with_group (diagnostic_t kind,
604 : : rich_location &richloc,
605 : : const diagnostic_metadata *metadata,
606 : : diagnostic_option_id option_id,
607 : : const char *gmsgid, ...)
608 : : ATTRIBUTE_GCC_DIAG(6,7);
609 : : bool emit_diagnostic_with_group_va (diagnostic_t kind,
610 : : rich_location &richloc,
611 : : const diagnostic_metadata *metadata,
612 : : diagnostic_option_id option_id,
613 : : const char *gmsgid, va_list *ap)
614 : : ATTRIBUTE_GCC_DIAG(6,0);
615 : :
616 : : bool report_diagnostic (diagnostic_info *);
617 : : void report_verbatim (text_info &);
618 : :
619 : : diagnostic_t
620 : 4485219 : classify_diagnostic (diagnostic_option_id option_id,
621 : : diagnostic_t new_kind,
622 : : location_t where)
623 : : {
624 : 4485219 : return m_option_classifier.classify_diagnostic (this,
625 : : option_id,
626 : : new_kind,
627 : : where);
628 : : }
629 : :
630 : 3807494 : void push_diagnostics (location_t where ATTRIBUTE_UNUSED)
631 : : {
632 : 3807494 : m_option_classifier.push ();
633 : : }
634 : 3806943 : void pop_diagnostics (location_t where)
635 : : {
636 : 3806943 : m_option_classifier.pop (where);
637 : : }
638 : :
639 : : void maybe_show_locus (const rich_location &richloc,
640 : : const diagnostic_source_printing_options &opts,
641 : : diagnostic_t diagnostic_kind,
642 : : pretty_printer &pp,
643 : : diagnostic_source_effect_info *effect_info);
644 : : void maybe_show_locus_as_html (const rich_location &richloc,
645 : : const diagnostic_source_printing_options &opts,
646 : : diagnostic_t diagnostic_kind,
647 : : xml::printer &xp,
648 : : diagnostic_source_effect_info *effect_info,
649 : : html_label_writer *label_writer);
650 : :
651 : : void emit_diagram (const diagnostic_diagram &diagram);
652 : :
653 : : /* Various setters for use by option-handling logic. */
654 : : void set_output_format (std::unique_ptr<diagnostic_output_format> output_format);
655 : : void set_text_art_charset (enum diagnostic_text_art_charset charset);
656 : : void set_client_data_hooks (std::unique_ptr<diagnostic_client_data_hooks> hooks);
657 : :
658 : : void push_owned_urlifier (std::unique_ptr<urlifier>);
659 : : void push_borrowed_urlifier (const urlifier &);
660 : : void pop_urlifier ();
661 : :
662 : : void create_edit_context ();
663 : 4364 : void set_warning_as_error_requested (bool val)
664 : : {
665 : 4364 : m_warning_as_error_requested = val;
666 : 4364 : }
667 : 12 : void set_report_bug (bool val) { m_report_bug = val; }
668 : 4 : void set_extra_output_kind (enum diagnostics_extra_output_kind kind)
669 : : {
670 : 4 : m_extra_output_kind = kind;
671 : 4 : }
672 : 286682 : void set_show_cwe (bool val) { m_show_cwe = val; }
673 : 286682 : void set_show_rules (bool val) { m_show_rules = val; }
674 : : void set_show_highlight_colors (bool val);
675 : 583969 : void set_path_format (enum diagnostic_path_format val)
676 : : {
677 : 583969 : m_path_format = val;
678 : 297283 : }
679 : 286758 : void set_show_path_depths (bool val) { m_show_path_depths = val; }
680 : 286736 : void set_show_option_requested (bool val) { m_show_option_requested = val; }
681 : 44 : void set_max_errors (int val) { m_max_errors = val; }
682 : 532 : void set_escape_format (enum diagnostics_escape_format val)
683 : : {
684 : 532 : m_escape_format = val;
685 : 4 : }
686 : :
687 : : void set_format_decoder (printer_fn format_decoder);
688 : : void set_prefixing_rule (diagnostic_prefixing_rule_t rule);
689 : :
690 : : /* Various accessors. */
691 : 29644 : bool warning_as_error_requested_p () const
692 : : {
693 : 29644 : return m_warning_as_error_requested;
694 : : }
695 : 15587 : bool show_path_depths_p () const { return m_show_path_depths; }
696 : : diagnostic_output_format &get_output_format (size_t idx) const;
697 : 3917 : enum diagnostic_path_format get_path_format () const { return m_path_format; }
698 : 50496 : enum diagnostics_escape_format get_escape_format () const
699 : : {
700 : 50496 : return m_escape_format;
701 : : }
702 : :
703 : : file_cache &
704 : 2894040 : get_file_cache () const
705 : : {
706 : 2894040 : gcc_assert (m_file_cache);
707 : 2894040 : return *m_file_cache;
708 : : }
709 : :
710 : 284720 : edit_context *get_edit_context () const
711 : : {
712 : 284720 : return m_edit_context_ptr;
713 : : }
714 : 2178 : const diagnostic_client_data_hooks *get_client_data_hooks () const
715 : : {
716 : 2178 : return m_client_data_hooks;
717 : : }
718 : :
719 : : const logical_location_manager *
720 : : get_logical_location_manager () const;
721 : :
722 : : const urlifier *get_urlifier () const;
723 : :
724 : 53342 : text_art::theme *get_diagram_theme () const { return m_diagrams.m_theme; }
725 : :
726 : 308500 : int &diagnostic_count (diagnostic_t kind)
727 : : {
728 : 308500 : return m_diagnostic_counters.m_count_for_kind[kind];
729 : : }
730 : 801235 : int diagnostic_count (diagnostic_t kind) const
731 : : {
732 : 285013 : return m_diagnostic_counters.get_count (kind);
733 : : }
734 : :
735 : : /* Option-related member functions. */
736 : 90872736 : inline bool option_enabled_p (diagnostic_option_id option_id) const
737 : : {
738 : 90872736 : if (!m_option_mgr)
739 : : return true;
740 : 90872736 : return m_option_mgr->option_enabled_p (option_id);
741 : : }
742 : :
743 : 1512468 : inline char *make_option_name (diagnostic_option_id option_id,
744 : : diagnostic_t orig_diag_kind,
745 : : diagnostic_t diag_kind) const
746 : : {
747 : 1512468 : if (!m_option_mgr)
748 : : return nullptr;
749 : 1512272 : return m_option_mgr->make_option_name (option_id,
750 : : orig_diag_kind,
751 : 1512272 : diag_kind);
752 : : }
753 : :
754 : 118 : inline char *make_option_url (diagnostic_option_id option_id) const
755 : : {
756 : 118 : if (!m_option_mgr)
757 : : return nullptr;
758 : 118 : return m_option_mgr->make_option_url (option_id);
759 : : }
760 : :
761 : : void
762 : : set_option_manager (std::unique_ptr<diagnostic_option_manager> mgr,
763 : : unsigned lang_mask);
764 : :
765 : 271302 : unsigned get_lang_mask () const
766 : : {
767 : 271302 : return m_lang_mask;
768 : : }
769 : :
770 : : bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
771 : : diagnostic_option_id, const char *,
772 : : va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0);
773 : : bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
774 : : diagnostic_option_id, unsigned HOST_WIDE_INT,
775 : : const char *, const char *, va_list *,
776 : : diagnostic_t) ATTRIBUTE_GCC_DIAG(7,0);
777 : :
778 : 331418 : int get_diagnostic_nesting_level () const
779 : : {
780 : 331418 : return m_diagnostic_groups.m_diagnostic_nesting_level;
781 : : }
782 : :
783 : : char *build_indent_prefix () const;
784 : :
785 : : int
786 : 465 : pch_save (FILE *f)
787 : : {
788 : 465 : return m_option_classifier.pch_save (f);
789 : : }
790 : :
791 : : int
792 : 347 : pch_restore (FILE *f)
793 : : {
794 : 347 : return m_option_classifier.pch_restore (f);
795 : : }
796 : :
797 : :
798 : : void set_diagnostic_buffer (diagnostic_buffer *);
799 : 1192427 : diagnostic_buffer *get_diagnostic_buffer () const
800 : : {
801 : 1192427 : return m_diagnostic_buffer;
802 : : }
803 : : void clear_diagnostic_buffer (diagnostic_buffer &);
804 : : void flush_diagnostic_buffer (diagnostic_buffer &);
805 : :
806 : 1250954 : std::unique_ptr<pretty_printer> clone_printer () const
807 : : {
808 : 1250888 : return m_reference_printer->clone ();
809 : : }
810 : :
811 : 3633775 : pretty_printer *get_reference_printer () const
812 : : {
813 : 3632175 : return m_reference_printer;
814 : : }
815 : :
816 : : void
817 : : add_sink (std::unique_ptr<diagnostic_output_format>);
818 : :
819 : : void remove_all_output_sinks ();
820 : :
821 : : bool supports_fnotice_on_stderr_p () const;
822 : :
823 : : /* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
824 : : void
825 : 13 : set_abort_on_error (bool val)
826 : : {
827 : 13 : m_abort_on_error = val;
828 : : }
829 : :
830 : : /* Accessor for use in serialization, e.g. by C++ modules. */
831 : : auto &
832 : 2547 : get_classification_history ()
833 : : {
834 : 7247 : return m_option_classifier.m_classification_history;
835 : : }
836 : :
837 : : void set_main_input_filename (const char *filename);
838 : :
839 : : void
840 : 206885 : set_permissive_option (diagnostic_option_id opt_permissive)
841 : : {
842 : 206885 : m_opt_permissive = opt_permissive;
843 : : }
844 : :
845 : : void
846 : 8 : set_fatal_errors (bool fatal_errors)
847 : : {
848 : 8 : m_fatal_errors = fatal_errors;
849 : 8 : }
850 : :
851 : : void
852 : 286705 : set_internal_error_callback (void (*cb) (diagnostic_context *,
853 : : const char *,
854 : : va_list *))
855 : : {
856 : 286705 : m_internal_error = cb;
857 : : }
858 : :
859 : : void
860 : 95377 : set_adjust_diagnostic_info_callback (void (*cb) (diagnostic_context *,
861 : : diagnostic_info *))
862 : : {
863 : 95377 : m_adjust_diagnostic_info = cb;
864 : : }
865 : :
866 : : void
867 : 619 : inhibit_notes () { m_inhibit_notes_p = true; }
868 : :
869 : : private:
870 : : void error_recursion () ATTRIBUTE_NORETURN;
871 : :
872 : : bool diagnostic_enabled (diagnostic_info *diagnostic);
873 : :
874 : : void get_any_inlining_info (diagnostic_info *diagnostic);
875 : :
876 : : void check_max_errors (bool flush);
877 : : void action_after_output (diagnostic_t diag_kind);
878 : :
879 : : /* Data members.
880 : : Ideally, all of these would be private. */
881 : :
882 : : private:
883 : : /* A reference instance of pretty_printer created by the client
884 : : and owned by the context. Used for cloning when creating/adding
885 : : output formats.
886 : : Owned by the context; this would be a std::unique_ptr if
887 : : diagnostic_context had a proper ctor. */
888 : : pretty_printer *m_reference_printer;
889 : :
890 : : /* Cache of source code.
891 : : Owned by the context; this would be a std::unique_ptr if
892 : : diagnostic_context had a proper ctor. */
893 : : file_cache *m_file_cache;
894 : :
895 : : /* The number of times we have issued diagnostics. */
896 : : diagnostic_counters m_diagnostic_counters;
897 : :
898 : : /* True if it has been requested that warnings be treated as errors. */
899 : : bool m_warning_as_error_requested;
900 : :
901 : : /* The number of option indexes that can be passed to warning() et
902 : : al. */
903 : : int m_n_opts;
904 : :
905 : : /* The stack of sets of overridden diagnostic option severities. */
906 : : diagnostic_option_classifier m_option_classifier;
907 : :
908 : : /* True if we should print any CWE identifiers associated with
909 : : diagnostics. */
910 : : bool m_show_cwe;
911 : :
912 : : /* True if we should print any rules associated with diagnostics. */
913 : : bool m_show_rules;
914 : :
915 : : /* How should diagnostic_path objects be printed. */
916 : : enum diagnostic_path_format m_path_format;
917 : :
918 : : /* True if we should print stack depths when printing diagnostic paths. */
919 : : bool m_show_path_depths;
920 : :
921 : : /* True if we should print the command line option which controls
922 : : each diagnostic, if known. */
923 : : bool m_show_option_requested;
924 : :
925 : : /* True if we should raise a SIGABRT on errors. */
926 : : bool m_abort_on_error;
927 : :
928 : : public:
929 : : /* True if we should show the column number on diagnostics. */
930 : : bool m_show_column;
931 : :
932 : : /* True if pedwarns are errors. */
933 : : bool m_pedantic_errors;
934 : :
935 : : /* True if permerrors are warnings. */
936 : : bool m_permissive;
937 : :
938 : : private:
939 : : /* The option to associate with turning permerrors into warnings,
940 : : if any. */
941 : : diagnostic_option_id m_opt_permissive;
942 : :
943 : : /* True if errors are fatal. */
944 : : bool m_fatal_errors;
945 : :
946 : : public:
947 : : /* True if all warnings should be disabled. */
948 : : bool m_inhibit_warnings;
949 : :
950 : : /* True if warnings should be given in system headers. */
951 : : bool m_warn_system_headers;
952 : :
953 : : private:
954 : : /* Maximum number of errors to report. */
955 : : int m_max_errors;
956 : :
957 : : /* Client-supplied callbacks for use in text output. */
958 : : struct {
959 : : /* This function is called before any message is printed out. It is
960 : : responsible for preparing message prefix and such. For example, it
961 : : might say:
962 : : In file included from "/usr/local/include/curses.h:5:
963 : : from "/home/gdr/src/nifty_printer.h:56:
964 : : ...
965 : : */
966 : : diagnostic_text_starter_fn m_begin_diagnostic;
967 : :
968 : : /* This function is called by diagnostic_show_locus in between
969 : : disjoint spans of source code, so that the context can print
970 : : something to indicate that a new span of source code has begun. */
971 : : diagnostic_start_span_fn<to_text> m_text_start_span;
972 : : diagnostic_start_span_fn<to_html> m_html_start_span;
973 : :
974 : : /* This function is called after the diagnostic message is printed. */
975 : : diagnostic_text_finalizer_fn m_end_diagnostic;
976 : : } m_text_callbacks;
977 : :
978 : : /* Client hook to report an internal error. */
979 : : void (*m_internal_error) (diagnostic_context *, const char *, va_list *);
980 : :
981 : : /* Client hook to adjust properties of the given diagnostic that we're
982 : : about to issue, such as its kind. */
983 : : void (*m_adjust_diagnostic_info)(diagnostic_context *, diagnostic_info *);
984 : :
985 : : /* Owned by the context; this would be a std::unique_ptr if
986 : : diagnostic_context had a proper ctor. */
987 : : diagnostic_option_manager *m_option_mgr;
988 : : unsigned m_lang_mask;
989 : :
990 : : /* A stack of optional hooks for adding URLs to quoted text strings in
991 : : diagnostics. Only used for the main diagnostic message.
992 : : Typically a single one owner by the context, but can be temporarily
993 : : overridden by a borrowed urlifier (e.g. on-stack). */
994 : : struct urlifier_stack_node
995 : : {
996 : : urlifier *m_urlifier;
997 : : bool m_owned;
998 : : };
999 : : auto_vec<urlifier_stack_node> *m_urlifier_stack;
1000 : :
1001 : : public:
1002 : : /* Auxiliary data for client. */
1003 : : void *m_client_aux_data;
1004 : :
1005 : : /* Used to detect that the last caret was printed at the same location. */
1006 : : location_t m_last_location;
1007 : :
1008 : : private:
1009 : : int m_lock;
1010 : :
1011 : : bool m_inhibit_notes_p;
1012 : :
1013 : : public:
1014 : : diagnostic_source_printing_options m_source_printing;
1015 : :
1016 : : private:
1017 : : /* True if -freport-bug option is used. */
1018 : : bool m_report_bug;
1019 : :
1020 : : /* Used to specify additional diagnostic output to be emitted after the
1021 : : rest of the diagnostic. This is for implementing
1022 : : -fdiagnostics-parseable-fixits and GCC_EXTRA_DIAGNOSTIC_OUTPUT. */
1023 : : enum diagnostics_extra_output_kind m_extra_output_kind;
1024 : :
1025 : : public:
1026 : : /* What units to use when outputting the column number. */
1027 : : enum diagnostics_column_unit m_column_unit;
1028 : :
1029 : : /* The origin for the column number (1-based or 0-based typically). */
1030 : : int m_column_origin;
1031 : :
1032 : : /* The size of the tabstop for tab expansion. */
1033 : : int m_tabstop;
1034 : :
1035 : : private:
1036 : : /* How should non-ASCII/non-printable bytes be escaped when
1037 : : a diagnostic suggests escaping the source code on output. */
1038 : : enum diagnostics_escape_format m_escape_format;
1039 : :
1040 : : /* If non-NULL, an edit_context to which fix-it hints should be
1041 : : applied, for generating patches.
1042 : : Owned by the context; this would be a std::unique_ptr if
1043 : : diagnostic_context had a proper ctor. */
1044 : : edit_context *m_edit_context_ptr;
1045 : :
1046 : : /* Fields relating to diagnostic groups. */
1047 : : struct {
1048 : : /* How many diagnostic_group instances are currently alive. */
1049 : : int m_group_nesting_depth;
1050 : :
1051 : : /* How many nesting levels have been pushed within this group. */
1052 : : int m_diagnostic_nesting_level;
1053 : :
1054 : : /* How many diagnostics have been emitted since the bottommost
1055 : : diagnostic_group was pushed. */
1056 : : int m_emission_count;
1057 : :
1058 : : /* The "group+diagnostic" nesting depth from which to inhibit notes. */
1059 : : int m_inhibiting_notes_from;
1060 : : } m_diagnostic_groups;
1061 : :
1062 : : void inhibit_notes_in_group (bool inhibit = true);
1063 : : bool notes_inhibited_in_group () const;
1064 : :
1065 : : /* The various sinks to which diagnostics are to be outputted
1066 : : (text vs structured formats such as SARIF).
1067 : : The sinks are owned by the context; this would be a
1068 : : std::vector<std::unique_ptr> if diagnostic_context had a
1069 : : proper ctor. */
1070 : : auto_vec<diagnostic_output_format *> m_output_sinks;
1071 : :
1072 : : /* Callback to set the locations of call sites along the inlining
1073 : : stack corresponding to a diagnostic location. Needed to traverse
1074 : : the BLOCK_SUPERCONTEXT() chain hanging off the LOCATION_BLOCK()
1075 : : of a diagnostic's location. */
1076 : : set_locations_callback_t m_set_locations_cb;
1077 : :
1078 : : /* A bundle of hooks for providing data to the context about its client
1079 : : e.g. version information, plugins, etc.
1080 : : Used by SARIF output to give metadata about the client that's
1081 : : producing diagnostics.
1082 : : Owned by the context; this would be a std::unique_ptr if
1083 : : diagnostic_context had a proper ctor. */
1084 : : diagnostic_client_data_hooks *m_client_data_hooks;
1085 : :
1086 : : /* Support for diagrams. */
1087 : : struct
1088 : : {
1089 : : /* Theme to use when generating diagrams.
1090 : : Can be NULL (if text art is disabled).
1091 : : Owned by the context; this would be a std::unique_ptr if
1092 : : diagnostic_context had a proper ctor. */
1093 : : text_art::theme *m_theme;
1094 : :
1095 : : } m_diagrams;
1096 : :
1097 : : /* Owned by the context. */
1098 : : char **m_original_argv;
1099 : :
1100 : : /* Borrowed pointer to the active diagnostic_buffer, if any.
1101 : : If null (the default), then diagnostics that are reported to the
1102 : : context are immediately issued to the output format.
1103 : : If non-null, then diagnostics that are reported to the context
1104 : : are buffered in the buffer, and may be issued to the output format
1105 : : later (if the buffer is flushed), moved to other buffers, or
1106 : : discarded (if the buffer is cleared). */
1107 : : diagnostic_buffer *m_diagnostic_buffer;
1108 : : };
1109 : :
1110 : : /* Client supplied function to announce a diagnostic
1111 : : (for text-based diagnostic output). */
1112 : : inline diagnostic_text_starter_fn &
1113 : : diagnostic_text_starter (diagnostic_context *context)
1114 : : {
1115 : : return context->m_text_callbacks.m_begin_diagnostic;
1116 : : }
1117 : :
1118 : : /* Client supplied function called between disjoint spans of source code,
1119 : : so that the context can print
1120 : : something to indicate that a new span of source code has begun. */
1121 : : inline diagnostic_start_span_fn<to_text> &
1122 : 18809 : diagnostic_start_span (diagnostic_context *context)
1123 : : {
1124 : 18809 : return context->m_text_callbacks.m_text_start_span;
1125 : : }
1126 : :
1127 : : /* Client supplied function called after a diagnostic message is
1128 : : displayed (for text-based diagnostic output). */
1129 : : inline diagnostic_text_finalizer_fn &
1130 : : diagnostic_text_finalizer (diagnostic_context *context)
1131 : : {
1132 : : return context->m_text_callbacks.m_end_diagnostic;
1133 : : }
1134 : :
1135 : : /* Extension hooks for client. */
1136 : : #define diagnostic_context_auxiliary_data(DC) (DC)->m_client_aux_data
1137 : : #define diagnostic_info_auxiliary_data(DI) (DI)->x_data
1138 : :
1139 : : /* This diagnostic_context is used by front-ends that directly output
1140 : : diagnostic messages without going through `error', `warning',
1141 : : and similar functions. */
1142 : : extern diagnostic_context *global_dc;
1143 : :
1144 : : /* The number of errors that have been issued so far. Ideally, these
1145 : : would take a diagnostic_context as an argument. */
1146 : : #define errorcount global_dc->diagnostic_count (DK_ERROR)
1147 : : /* Similarly, but for warnings. */
1148 : : #define warningcount global_dc->diagnostic_count (DK_WARNING)
1149 : : /* Similarly, but for warnings promoted to errors. */
1150 : : #define werrorcount global_dc->diagnostic_count (DK_WERROR)
1151 : : /* Similarly, but for sorrys. */
1152 : : #define sorrycount global_dc->diagnostic_count (DK_SORRY)
1153 : :
1154 : : /* Returns nonzero if warnings should be emitted. */
1155 : : #define diagnostic_report_warnings_p(DC, LOC) \
1156 : : (!(DC)->m_inhibit_warnings \
1157 : : && !(in_system_header_at (LOC) && !(DC)->m_warn_system_headers))
1158 : :
1159 : : /* Override the option index to be used for reporting a
1160 : : diagnostic. */
1161 : :
1162 : : inline void
1163 : 142806 : diagnostic_set_option_id (diagnostic_info *info,
1164 : : diagnostic_option_id option_id)
1165 : : {
1166 : 142806 : info->option_id = option_id;
1167 : : }
1168 : :
1169 : : /* Diagnostic related functions. */
1170 : :
1171 : : inline void
1172 : 712877 : diagnostic_initialize (diagnostic_context *context, int n_opts)
1173 : : {
1174 : 712877 : context->initialize (n_opts);
1175 : : }
1176 : :
1177 : : inline void
1178 : 1420574 : diagnostic_color_init (diagnostic_context *context, int value = -1)
1179 : : {
1180 : 1420574 : context->color_init (value);
1181 : 549875 : }
1182 : :
1183 : : inline void
1184 : 1404249 : diagnostic_urls_init (diagnostic_context *context, int value = -1)
1185 : : {
1186 : 1404249 : context->urls_init (value);
1187 : 541309 : }
1188 : :
1189 : : inline void
1190 : 305108 : diagnostic_finish (diagnostic_context *context)
1191 : : {
1192 : 305108 : context->finish ();
1193 : : }
1194 : :
1195 : : inline void
1196 : 356165 : diagnostic_show_locus (diagnostic_context *context,
1197 : : const diagnostic_source_printing_options &opts,
1198 : : rich_location *richloc,
1199 : : diagnostic_t diagnostic_kind,
1200 : : pretty_printer *pp,
1201 : : diagnostic_source_effect_info *effect_info = nullptr)
1202 : : {
1203 : 356165 : gcc_assert (context);
1204 : 356165 : gcc_assert (richloc);
1205 : 356165 : gcc_assert (pp);
1206 : 356165 : context->maybe_show_locus (*richloc, opts, diagnostic_kind, *pp, effect_info);
1207 : 356165 : }
1208 : :
1209 : : inline void
1210 : 6 : diagnostic_show_locus_as_html (diagnostic_context *context,
1211 : : const diagnostic_source_printing_options &opts,
1212 : : rich_location *richloc,
1213 : : diagnostic_t diagnostic_kind,
1214 : : xml::printer &xp,
1215 : : diagnostic_source_effect_info *effect_info = nullptr,
1216 : : html_label_writer *label_writer = nullptr)
1217 : : {
1218 : 6 : gcc_assert (context);
1219 : 6 : gcc_assert (richloc);
1220 : 6 : context->maybe_show_locus_as_html (*richloc, opts, diagnostic_kind, xp,
1221 : : effect_info, label_writer);
1222 : 6 : }
1223 : :
1224 : : /* Because we read source files a second time after the frontend did it the
1225 : : first time, we need to know how the frontend handled things like character
1226 : : set conversion and UTF-8 BOM stripping, in order to make everything
1227 : : consistent. This function needs to be called by each frontend that requires
1228 : : non-default behavior, to inform the diagnostics infrastructure how input is
1229 : : to be processed. The default behavior is to do no conversion and not to
1230 : : strip a UTF-8 BOM.
1231 : :
1232 : : The callback should return the input charset to be used to convert the given
1233 : : file's contents to UTF-8, or it should return NULL if no conversion is needed
1234 : : for this file. SHOULD_SKIP_BOM only applies in case no conversion was
1235 : : performed, and if true, it will cause a UTF-8 BOM to be skipped at the
1236 : : beginning of the file. (In case a conversion was performed, the BOM is
1237 : : rather skipped as part of the conversion process.) */
1238 : :
1239 : : inline void
1240 : 207923 : diagnostic_initialize_input_context (diagnostic_context *context,
1241 : : diagnostic_input_charset_callback ccb,
1242 : : bool should_skip_bom)
1243 : : {
1244 : 207923 : context->initialize_input_context (ccb, should_skip_bom);
1245 : : }
1246 : :
1247 : : /* Force diagnostics controlled by OPTIDX to be kind KIND. */
1248 : : inline diagnostic_t
1249 : 4485219 : diagnostic_classify_diagnostic (diagnostic_context *context,
1250 : : diagnostic_option_id option_id,
1251 : : diagnostic_t kind,
1252 : : location_t where)
1253 : : {
1254 : 4485219 : return context->classify_diagnostic (option_id, kind, where);
1255 : : }
1256 : :
1257 : : inline void
1258 : 3807494 : diagnostic_push_diagnostics (diagnostic_context *context,
1259 : : location_t where)
1260 : : {
1261 : 3807494 : context->push_diagnostics (where);
1262 : 3742034 : }
1263 : : inline void
1264 : 3806943 : diagnostic_pop_diagnostics (diagnostic_context *context,
1265 : : location_t where)
1266 : : {
1267 : 3806943 : context->pop_diagnostics (where);
1268 : 3741483 : }
1269 : :
1270 : : /* Report a diagnostic message (an error or a warning) as specified by
1271 : : DC. This function is *the* subroutine in terms of which front-ends
1272 : : should implement their specific diagnostic handling modules. The
1273 : : front-end independent format specifiers are exactly those described
1274 : : in the documentation of output_format.
1275 : : Return true if a diagnostic was printed, false otherwise. */
1276 : :
1277 : : inline bool
1278 : 4406481 : diagnostic_report_diagnostic (diagnostic_context *context,
1279 : : diagnostic_info *diagnostic)
1280 : : {
1281 : 4406481 : context->begin_group ();
1282 : 4406481 : bool warned = context->report_diagnostic (diagnostic);
1283 : 4406113 : context->end_group ();
1284 : 4406113 : return warned;
1285 : : }
1286 : :
1287 : : #ifdef ATTRIBUTE_GCC_DIAG
1288 : : extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
1289 : : rich_location *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
1290 : : extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
1291 : : va_list *, rich_location *,
1292 : : diagnostic_t)
1293 : : ATTRIBUTE_GCC_DIAG(2,0);
1294 : : #endif
1295 : : void default_diagnostic_text_starter (diagnostic_text_output_format &,
1296 : : const diagnostic_info *);
1297 : : template <typename Sink>
1298 : : void default_diagnostic_start_span_fn (const diagnostic_location_print_policy &,
1299 : : Sink &sink,
1300 : : expanded_location);
1301 : : void default_diagnostic_text_finalizer (diagnostic_text_output_format &,
1302 : : const diagnostic_info *,
1303 : : diagnostic_t);
1304 : : void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
1305 : :
1306 : : int get_terminal_width (void);
1307 : :
1308 : : /* Return the location associated to this diagnostic. Parameter WHICH
1309 : : specifies which location. By default, expand the first one. */
1310 : :
1311 : : inline location_t
1312 : 92669661 : diagnostic_location (const diagnostic_info * diagnostic, int which = 0)
1313 : : {
1314 : 92669661 : return diagnostic->message.get_location (which);
1315 : : }
1316 : :
1317 : : /* Return the number of locations to be printed in DIAGNOSTIC. */
1318 : :
1319 : : inline unsigned int
1320 : : diagnostic_num_locations (const diagnostic_info * diagnostic)
1321 : : {
1322 : : return diagnostic->message.m_richloc->get_num_locations ();
1323 : : }
1324 : :
1325 : : /* Expand the location of this diagnostic. Use this function for
1326 : : consistency. Parameter WHICH specifies which location. By default,
1327 : : expand the first one. */
1328 : :
1329 : : inline expanded_location
1330 : 1526263 : diagnostic_expand_location (const diagnostic_info * diagnostic, int which = 0)
1331 : : {
1332 : 1526263 : return diagnostic->richloc->get_expanded_location (which);
1333 : : }
1334 : :
1335 : : /* This is somehow the right-side margin of a caret line, that is, we
1336 : : print at least these many characters after the position pointed at
1337 : : by the caret. */
1338 : : const int CARET_LINE_MARGIN = 10;
1339 : :
1340 : : /* Return true if the two locations can be represented within the same
1341 : : caret line. This is used to build a prefix and also to determine
1342 : : whether to print one or two caret lines. */
1343 : :
1344 : : inline bool
1345 : 506 : diagnostic_same_line (const diagnostic_context *context,
1346 : : expanded_location s1, expanded_location s2)
1347 : : {
1348 : 500 : return (s2.column && s1.line == s2.line
1349 : 506 : && (context->m_source_printing.max_width - CARET_LINE_MARGIN
1350 : 173 : > abs (s1.column - s2.column)));
1351 : : }
1352 : :
1353 : : extern const char *diagnostic_get_color_for_kind (diagnostic_t kind);
1354 : :
1355 : : /* Pure text formatting support functions. */
1356 : :
1357 : : extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
1358 : :
1359 : : /* Compute the number of digits in the decimal representation of an integer. */
1360 : : extern int num_digits (int);
1361 : :
1362 : : inline bool
1363 : 281686 : warning_enabled_at (location_t loc, diagnostic_option_id option_id)
1364 : : {
1365 : 281686 : return global_dc->warning_enabled_at (loc, option_id);
1366 : : }
1367 : :
1368 : : inline bool
1369 : 591892 : option_unspecified_p (diagnostic_option_id option_id)
1370 : : {
1371 : 591892 : return global_dc->option_unspecified_p (option_id);
1372 : : }
1373 : :
1374 : : extern char *get_cwe_url (int cwe);
1375 : :
1376 : : extern const char *get_diagnostic_kind_text (diagnostic_t kind);
1377 : :
1378 : : const char *maybe_line_and_column (int line, int col);
1379 : :
1380 : : #endif /* ! GCC_DIAGNOSTIC_H */
|