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