]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/diagnostic.c
Add diagnostic paths
[thirdparty/gcc.git] / gcc / diagnostic.c
CommitLineData
47b69537 1/* Language-independent diagnostic subroutines for the GNU Compiler Collection
8d9254fc 2 Copyright (C) 1999-2020 Free Software Foundation, Inc.
406a65d0 3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
6ed551b4 4
1322177d 5This file is part of GCC.
6ed551b4 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
1322177d 10version.
6ed551b4 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
6ed551b4
GDR
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
6ed551b4
GDR
20
21
4eb00163 22/* This file implements the language independent aspect of diagnostic
6ed551b4
GDR
23 message module. */
24
25#include "config.h"
6ed551b4 26#include "system.h"
4977bab6 27#include "coretypes.h"
a757585a 28#include "version.h"
d83697f4 29#include "demangle.h"
6ed551b4 30#include "intl.h"
d83697f4 31#include "backtrace.h"
345ed1fe 32#include "diagnostic.h"
4b84d650 33#include "diagnostic-color.h"
d2608235 34#include "diagnostic-url.h"
6d4a35ca 35#include "diagnostic-metadata.h"
4bc1899b 36#include "diagnostic-path.h"
717ebe91 37#include "edit-context.h"
a93eac6a 38#include "selftest.h"
ace72598 39#include "selftest-diagnostic.h"
fa5baeed 40#include "opts.h"
6ed551b4 41
c9db45aa
TB
42#ifdef HAVE_TERMIOS_H
43# include <termios.h>
44#endif
45
46#ifdef GWINSZ_IN_SYS_IOCTL
47# include <sys/ioctl.h>
48#endif
49
0ecf545c
MS
50/* Disable warnings about quoting issues in the pp_xxx calls below
51 that (intentionally) don't follow GCC diagnostic conventions. */
52#if __GNUC__ >= 10
53# pragma GCC diagnostic push
54# pragma GCC diagnostic ignored "-Wformat-diag"
55#endif
56
243fbddd
JM
57#define pedantic_warning_kind(DC) \
58 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
59#define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
5f0f4a3b 60#define permissive_error_option(DC) ((DC)->opt_permissive)
c707a408 61
30f7a378 62/* Prototypes. */
6d4a35ca
DM
63static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
64 int, const char *,
65 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
66static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
67 int, unsigned HOST_WIDE_INT,
1c89478a 68 const char *, const char *, va_list *,
6d4a35ca 69 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
a5fb7ad2 70
79a490a9 71static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
79a490a9 72static void real_abort (void) ATTRIBUTE_NORETURN;
fbfc1192 73
1da2ed5f
JM
74/* Name of program invoked, sans directories. */
75
76const char *progname;
77
f68fc4db
GDR
78/* A diagnostic_context surrogate for stderr. */
79static diagnostic_context global_diagnostic_context;
80diagnostic_context *global_dc = &global_diagnostic_context;
6ed551b4 81\f
59650e48
ZW
82/* Return a malloc'd string containing MSG formatted a la printf. The
83 caller is responsible for freeing the memory. */
8e54f6d3 84char *
e34d07f2 85build_message_string (const char *msg, ...)
b903d81e 86{
36244024 87 char *str;
e34d07f2 88 va_list ap;
b903d81e 89
e34d07f2 90 va_start (ap, msg);
582f770b 91 str = xvasprintf (msg, ap);
e34d07f2 92 va_end (ap);
b903d81e
GDR
93
94 return str;
95}
96
95bd1dd7 97/* Same as diagnostic_build_prefix, but only the source FILE is given. */
24805e80 98char *
e78e8a0b 99file_name_as_prefix (diagnostic_context *context, const char *f)
24805e80 100{
e78e8a0b
JJ
101 const char *locus_cs
102 = colorize_start (pp_show_color (context->printer), "locus");
103 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
104 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
24805e80
GDR
105}
106
47b69537 107
6ed551b4 108\f
9fec0042 109/* Return the value of the getenv("COLUMNS") as an integer. If the
c9db45aa
TB
110 value is not set to a positive integer, use ioctl to get the
111 terminal width. If it fails, return INT_MAX. */
112int
113get_terminal_width (void)
9fec0042
MLI
114{
115 const char * s = getenv ("COLUMNS");
116 if (s != NULL) {
117 int n = atoi (s);
118 if (n > 0)
119 return n;
120 }
c9db45aa
TB
121
122#ifdef TIOCGWINSZ
123 struct winsize w;
124 w.ws_col = 0;
125 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
126 return w.ws_col;
127#endif
128
9fec0042
MLI
129 return INT_MAX;
130}
131
132/* Set caret_max_width to value. */
133void
134diagnostic_set_caret_max_width (diagnostic_context *context, int value)
135{
136 /* One minus to account for the leading empty space. */
137 value = value ? value - 1
025311c4 138 : (isatty (fileno (pp_buffer (context->printer)->stream))
c9db45aa 139 ? get_terminal_width () - 1: INT_MAX);
9fec0042
MLI
140
141 if (value <= 0)
142 value = INT_MAX;
143
144 context->caret_max_width = value;
145}
146
478dd60d
DM
147/* Default implementation of final_cb. */
148
149static void
150default_diagnostic_final_cb (diagnostic_context *context)
151{
152 /* Some of the errors may actually have been warnings. */
153 if (diagnostic_kind_count (context, DK_WERROR))
154 {
155 /* -Werror was given. */
156 if (context->warning_as_error_requested)
157 pp_verbatim (context->printer,
158 _("%s: all warnings being treated as errors"),
159 progname);
160 /* At least one -Werror= was given. */
161 else
162 pp_verbatim (context->printer,
163 _("%s: some warnings being treated as errors"),
164 progname);
165 pp_newline_and_flush (context->printer);
166 }
167}
168
47b69537
GDR
169/* Initialize the diagnostic message outputting machinery. */
170void
5f0f4a3b 171diagnostic_initialize (diagnostic_context *context, int n_opts)
47b69537 172{
5f0f4a3b
JM
173 int i;
174
b6fe0bb8
GDR
175 /* Allocate a basic pretty-printer. Clients will replace this a
176 much more elaborated pretty-printer if they wish. */
5ed6ace5 177 context->printer = XNEW (pretty_printer);
da6ca2b5 178 new (context->printer) pretty_printer ();
47b69537 179
b6fe0bb8 180 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
7783b402 181 context->warning_as_error_requested = false;
5f0f4a3b
JM
182 context->n_opts = n_opts;
183 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
184 for (i = 0; i < n_opts; i++)
185 context->classify_diagnostic[i] = DK_UNSPECIFIED;
9fec0042
MLI
186 context->show_caret = false;
187 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
b816477a 188 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
2a2703a2 189 context->caret_chars[i] = '^';
6d4a35ca 190 context->show_cwe = false;
4bc1899b
DM
191 context->path_format = DPF_NONE;
192 context->show_path_depths = false;
2098fe9e 193 context->show_option_requested = false;
b6fe0bb8 194 context->abort_on_error = false;
5f0f4a3b
JM
195 context->show_column = false;
196 context->pedantic_errors = false;
197 context->permissive = false;
198 context->opt_permissive = 0;
199 context->fatal_errors = false;
e3339d0f
JM
200 context->dc_inhibit_warnings = false;
201 context->dc_warn_system_headers = false;
3a789837 202 context->max_errors = 0;
b6fe0bb8 203 context->internal_error = NULL;
47b69537 204 diagnostic_starter (context) = default_diagnostic_starter;
876217ae 205 context->start_span = default_diagnostic_start_span_fn;
47b69537 206 diagnostic_finalizer (context) = default_diagnostic_finalizer;
5f0f4a3b 207 context->option_enabled = NULL;
46625112 208 context->option_state = NULL;
5f0f4a3b 209 context->option_name = NULL;
b4c7ca2e 210 context->get_option_url = NULL;
1b8b126f 211 context->last_location = UNKNOWN_LOCATION;
b6fe0bb8 212 context->last_module = 0;
cf835838 213 context->x_data = NULL;
b6fe0bb8 214 context->lock = 0;
0e94b750 215 context->inhibit_notes_p = false;
cc015f3a 216 context->colorize_source_p = false;
96e6ae57 217 context->show_labels_p = false;
56b61d7f 218 context->show_line_numbers_p = false;
0141ab44 219 context->min_margin_width = 0;
cc015f3a
DM
220 context->show_ruler_p = false;
221 context->parseable_fixits_p = false;
717ebe91 222 context->edit_context_ptr = NULL;
097f82ec
DM
223 context->diagnostic_group_nesting_depth = 0;
224 context->diagnostic_group_emission_count = 0;
225 context->begin_group_cb = NULL;
226 context->end_group_cb = NULL;
478dd60d 227 context->final_cb = default_diagnostic_final_cb;
47b69537
GDR
228}
229
97aa8bb6
MLI
230/* Maybe initialize the color support. We require clients to do this
231 explicitly, since most clients don't want color. When called
232 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
233
234void
235diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
236{
237 /* value == -1 is the default value. */
238 if (value < 0)
239 {
240 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
241 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
242 otherwise default to -fdiagnostics-color=never, for other
243 values default to that
244 -fdiagnostics-color={never,auto,always}. */
245 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
246 {
247 if (!getenv ("GCC_COLORS"))
248 return;
249 value = DIAGNOSTICS_COLOR_AUTO;
250 }
251 else
252 value = DIAGNOSTICS_COLOR_DEFAULT;
253 }
254 pp_show_color (context->printer)
255 = colorize_init ((diagnostic_color_rule_t) value);
256}
257
d2608235
DM
258/* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
259
260void
261diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
262{
263 if (value < 0)
264 value = DIAGNOSTICS_COLOR_DEFAULT;
265
266 context->printer->show_urls
267 = diagnostic_urls_enabled_p ((diagnostic_url_rule_t) value);
268}
269
d0b8780d
MLI
270/* Do any cleaning up required after the last diagnostic is emitted. */
271
272void
273diagnostic_finish (diagnostic_context *context)
274{
478dd60d
DM
275 if (context->final_cb)
276 context->final_cb (context);
7ecc3eb9
DS
277
278 diagnostic_file_cache_fini ();
3edf64aa
DM
279
280 XDELETEVEC (context->classify_diagnostic);
281 context->classify_diagnostic = NULL;
282
283 /* diagnostic_initialize allocates context->printer using XNEW
284 and placement-new. */
285 context->printer->~pretty_printer ();
286 XDELETE (context->printer);
287 context->printer = NULL;
717ebe91
DM
288
289 if (context->edit_context_ptr)
290 {
291 delete context->edit_context_ptr;
292 context->edit_context_ptr = NULL;
293 }
d0b8780d
MLI
294}
295
178b58b5
JM
296/* Initialize DIAGNOSTIC, where the message MSG has already been
297 translated. */
47b69537 298void
178b58b5 299diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
8a645150 300 va_list *args, rich_location *richloc,
178b58b5 301 diagnostic_t kind)
47b69537 302{
8a645150 303 gcc_assert (richloc);
fa6ef813 304 diagnostic->message.err_no = errno;
47b69537 305 diagnostic->message.args_ptr = args;
178b58b5 306 diagnostic->message.format_spec = msg;
8a645150
DM
307 diagnostic->message.m_richloc = richloc;
308 diagnostic->richloc = richloc;
6d4a35ca 309 diagnostic->metadata = NULL;
47b69537 310 diagnostic->kind = kind;
ccf08a6e 311 diagnostic->option_index = 0;
47b69537
GDR
312}
313
178b58b5
JM
314/* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
315 translated. */
316void
317diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
8a645150 318 va_list *args, rich_location *richloc,
178b58b5
JM
319 diagnostic_t kind)
320{
8a645150
DM
321 gcc_assert (richloc);
322 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
323}
324
325static const char *const diagnostic_kind_color[] = {
326#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
327#include "diagnostic.def"
328#undef DEFINE_DIAGNOSTIC_KIND
329 NULL
330};
331
332/* Get a color name for diagnostics of type KIND
333 Result could be NULL. */
334
335const char *
336diagnostic_get_color_for_kind (diagnostic_t kind)
337{
338 return diagnostic_kind_color[kind];
178b58b5
JM
339}
340
101e910b
NS
341/* Return a formatted line and column ':%line:%column'. Elided if
342 zero. The result is a statically allocated buffer. */
343
344static const char *
345maybe_line_and_column (int line, int col)
346{
347 static char result[32];
348
349 if (line)
350 {
351 size_t l = snprintf (result, sizeof (result),
352 col ? ":%d:%d" : ":%d", line, col);
353 gcc_checking_assert (l < sizeof (result));
354 }
355 else
356 result[0] = 0;
357 return result;
358}
359
876217ae
DM
360/* Return a malloc'd string describing a location e.g. "foo.c:42:10".
361 The caller is responsible for freeing the memory. */
362
363static char *
364diagnostic_get_location_text (diagnostic_context *context,
365 expanded_location s)
366{
367 pretty_printer *pp = context->printer;
368 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
369 const char *locus_ce = colorize_stop (pp_show_color (pp));
101e910b
NS
370 const char *file = s.file ? s.file : progname;
371 int line = strcmp (file, N_("<built-in>")) ? s.line : 0;
372 int col = context->show_column ? s.column : 0;
876217ae 373
101e910b
NS
374 const char *line_col = maybe_line_and_column (line, col);
375 return build_message_string ("%s%s%s:%s", locus_cs, file,
376 line_col, locus_ce);
876217ae
DM
377}
378
379/* Return a malloc'd string describing a location and the severity of the
380 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
381 freeing the memory. */
47b69537 382char *
243fbddd 383diagnostic_build_prefix (diagnostic_context *context,
dfa32261 384 const diagnostic_info *diagnostic)
47b69537 385{
ef9772c8 386 static const char *const diagnostic_kind_text[] = {
4b84d650 387#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
4b1d52c7
GDR
388#include "diagnostic.def"
389#undef DEFINE_DIAGNOSTIC_KIND
390 "must-not-happen"
391 };
99abe958
MLI
392 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
393
255508dd 394 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
4b84d650 395 const char *text_cs = "", *text_ce = "";
4b84d650
JJ
396 pretty_printer *pp = context->printer;
397
398 if (diagnostic_kind_color[diagnostic->kind])
399 {
400 text_cs = colorize_start (pp_show_color (pp),
401 diagnostic_kind_color[diagnostic->kind]);
402 text_ce = colorize_stop (pp_show_color (pp));
403 }
4b84d650 404
99abe958 405 expanded_location s = diagnostic_expand_location (diagnostic);
876217ae
DM
406 char *location_text = diagnostic_get_location_text (context, s);
407
408 char *result = build_message_string ("%s %s%s%s", location_text,
409 text_cs, text, text_ce);
410 free (location_text);
411 return result;
47b69537
GDR
412}
413
d83697f4
ILT
414/* Functions at which to stop the backtrace print. It's not
415 particularly helpful to print the callers of these functions. */
416
417static const char * const bt_stop[] =
418{
419 "main",
3edf64aa 420 "toplev::main",
d83697f4
ILT
421 "execute_one_pass",
422 "compile_file",
423};
424
425/* A callback function passed to the backtrace_full function. */
426
427static int
428bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
429 const char *function)
430{
431 int *pcount = (int *) data;
432
433 /* If we don't have any useful information, don't print
434 anything. */
435 if (filename == NULL && function == NULL)
436 return 0;
437
438 /* Skip functions in diagnostic.c. */
439 if (*pcount == 0
440 && filename != NULL
c3284718 441 && strcmp (lbasename (filename), "diagnostic.c") == 0)
d83697f4
ILT
442 return 0;
443
444 /* Print up to 20 functions. We could make this a --param, but
445 since this is only for debugging just use a constant for now. */
446 if (*pcount >= 20)
447 {
448 /* Returning a non-zero value stops the backtrace. */
449 return 1;
450 }
451 ++*pcount;
452
453 char *alc = NULL;
454 if (function != NULL)
455 {
456 char *str = cplus_demangle_v3 (function,
457 (DMGL_VERBOSE | DMGL_ANSI
458 | DMGL_GNU_V3 | DMGL_PARAMS));
459 if (str != NULL)
460 {
461 alc = str;
462 function = str;
463 }
464
465 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
466 {
467 size_t len = strlen (bt_stop[i]);
468 if (strncmp (function, bt_stop[i], len) == 0
469 && (function[len] == '\0' || function[len] == '('))
470 {
471 if (alc != NULL)
472 free (alc);
473 /* Returning a non-zero value stops the backtrace. */
474 return 1;
475 }
476 }
477 }
478
479 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
a67a73fd 480 (unsigned long) pc,
d83697f4
ILT
481 function == NULL ? "???" : function,
482 filename == NULL ? "???" : filename,
483 lineno);
484
485 if (alc != NULL)
486 free (alc);
487
488 return 0;
489}
490
491/* A callback function passed to the backtrace_full function. This is
492 called if backtrace_full has an error. */
493
494static void
495bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
496{
497 if (errnum < 0)
498 {
499 /* This means that no debug info was available. Just quietly
500 skip printing backtrace info. */
501 return;
502 }
503 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
504 errnum == 0 ? "" : xstrerror (errnum));
505}
506
d0ea9f0a
NS
507/* Check if we've met the maximum error limit, and if so fatally exit
508 with a message. CONTEXT is the context to check, and FLUSH
509 indicates whether a diagnostic_finish call is needed. */
510
511void
512diagnostic_check_max_errors (diagnostic_context *context, bool flush)
513{
514 if (!context->max_errors)
515 return;
516
517 int count = (diagnostic_kind_count (context, DK_ERROR)
518 + diagnostic_kind_count (context, DK_SORRY)
519 + diagnostic_kind_count (context, DK_WERROR));
520
521 if (count >= context->max_errors)
522 {
523 fnotice (stderr,
524 "compilation terminated due to -fmax-errors=%u.\n",
525 context->max_errors);
526 if (flush)
527 diagnostic_finish (context);
528 exit (FATAL_EXIT_CODE);
529 }
530}
531
9804f5fb
ZW
532/* Take any action which is expected to happen after the diagnostic
533 is written out. This function does not always return. */
c4100eae 534void
79a490a9 535diagnostic_action_after_output (diagnostic_context *context,
c4100eae 536 diagnostic_t diag_kind)
9804f5fb 537{
c4100eae 538 switch (diag_kind)
9804f5fb
ZW
539 {
540 case DK_DEBUG:
541 case DK_NOTE:
542 case DK_ANACHRONISM:
543 case DK_WARNING:
544 break;
545
546 case DK_ERROR:
547 case DK_SORRY:
548 if (context->abort_on_error)
549 real_abort ();
243fbddd 550 if (context->fatal_errors)
c65a01af
RG
551 {
552 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
d0b8780d 553 diagnostic_finish (context);
c65a01af
RG
554 exit (FATAL_EXIT_CODE);
555 }
9804f5fb
ZW
556 break;
557
558 case DK_ICE:
b55f40c1 559 case DK_ICE_NOBT:
d83697f4 560 {
b55f40c1
JJ
561 struct backtrace_state *state = NULL;
562 if (diag_kind == DK_ICE)
563 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
d83697f4
ILT
564 int count = 0;
565 if (state != NULL)
566 backtrace_full (state, 2, bt_callback, bt_err_callback,
567 (void *) &count);
568
569 if (context->abort_on_error)
570 real_abort ();
571
572 fnotice (stderr, "Please submit a full bug report,\n"
573 "with preprocessed source if appropriate.\n");
574 if (count > 0)
575 fnotice (stderr,
576 ("Please include the complete backtrace "
577 "with any bug report.\n"));
578 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
9804f5fb 579
d83697f4
ILT
580 exit (ICE_EXIT_CODE);
581 }
9804f5fb
ZW
582
583 case DK_FATAL:
584 if (context->abort_on_error)
585 real_abort ();
d0b8780d 586 diagnostic_finish (context);
9804f5fb
ZW
587 fnotice (stderr, "compilation terminated.\n");
588 exit (FATAL_EXIT_CODE);
589
590 default:
d5706a1e 591 gcc_unreachable ();
9804f5fb
ZW
592 }
593}
594
26d5ed6c
DM
595/* True if the last module or file in which a diagnostic was reported is
596 different from the current one. */
597
598static bool
599last_module_changed_p (diagnostic_context *context,
600 const line_map_ordinary *map)
601{
602 return context->last_module != map;
603}
604
605/* Remember the current module or file as being the last one in which we
606 report a diagnostic. */
607
608static void
609set_last_module (diagnostic_context *context, const line_map_ordinary *map)
610{
611 context->last_module = map;
612}
613
6ed551b4 614void
07a0b324 615diagnostic_report_current_module (diagnostic_context *context, location_t where)
6ed551b4 616{
0e50b624 617 const line_map_ordinary *map = NULL;
6ed551b4 618
b6fe0bb8 619 if (pp_needs_newline (context->printer))
59650e48 620 {
b6fe0bb8
GDR
621 pp_newline (context->printer);
622 pp_needs_newline (context->printer) = false;
59650e48 623 }
6ed551b4 624
07a0b324 625 if (where <= BUILTINS_LOCATION)
966e8f4d
TT
626 return;
627
07a0b324
TT
628 linemap_resolve_location (line_table, where,
629 LRK_MACRO_DEFINITION_LOCATION,
630 &map);
631
26d5ed6c 632 if (map && last_module_changed_p (context, map))
59650e48 633 {
26d5ed6c 634 set_last_module (context, map);
966e8f4d 635 if (! MAIN_FILE_P (map))
6773e15f 636 {
9e525f08
NS
637 bool first = true;
638 do
966e8f4d 639 {
f10a9135
NS
640 where = linemap_included_from (map);
641 map = linemap_included_from_linemap (line_table, map);
9e525f08 642 const char *line_col
f10a9135 643 = maybe_line_and_column (SOURCE_LINE (map, where),
9e525f08
NS
644 first && context->show_column
645 ? SOURCE_COLUMN (map, where) : 0);
646 static const char *const msgs[] =
647 {
648 N_("In file included from"),
649 N_(" from"),
650 };
651 unsigned index = !first;
652 pp_verbatim (context->printer, "%s%s %r%s%s%R",
653 first ? "" : ",\n", _(msgs[index]),
654 "locus", LINEMAP_FILE (map), line_col);
655 first = false;
966e8f4d 656 }
9e525f08 657 while (! MAIN_FILE_P (map));
966e8f4d
TT
658 pp_verbatim (context->printer, ":");
659 pp_newline (context->printer);
6773e15f 660 }
59650e48
ZW
661 }
662}
400500c4 663
4bc1899b
DM
664/* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
665 print the path. */
666
667void
668diagnostic_show_any_path (diagnostic_context *context,
669 diagnostic_info *diagnostic)
670{
671 const diagnostic_path *path = diagnostic->richloc->get_path ();
672 if (!path)
673 return;
674
675 if (context->print_path)
676 context->print_path (context, path);
677}
678
679/* Return true if the events in this path involve more than one
680 function, or false if it is purely intraprocedural. */
681
682bool
683diagnostic_path::interprocedural_p () const
684{
685 const unsigned num = num_events ();
686 for (unsigned i = 0; i < num; i++)
687 {
688 if (get_event (i).get_fndecl () != get_event (0).get_fndecl ())
689 return true;
690 if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ())
691 return true;
692 }
693 return false;
694}
695
4537ec0c 696void
79a490a9
AJ
697default_diagnostic_starter (diagnostic_context *context,
698 diagnostic_info *diagnostic)
6ed551b4 699{
2a2703a2 700 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
243fbddd
JM
701 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
702 diagnostic));
59650e48 703}
6ed551b4 704
876217ae
DM
705void
706default_diagnostic_start_span_fn (diagnostic_context *context,
707 expanded_location exploc)
708{
5c6a2bf2
DM
709 char *text = diagnostic_get_location_text (context, exploc);
710 pp_string (context->printer, text);
711 free (text);
876217ae
DM
712 pp_newline (context->printer);
713}
714
4537ec0c 715void
18767f65 716default_diagnostic_finalizer (diagnostic_context *context,
478dd60d
DM
717 diagnostic_info *diagnostic,
718 diagnostic_t)
59650e48 719{
e9c9a142
DM
720 char *saved_prefix = pp_take_prefix (context->printer);
721 pp_set_prefix (context->printer, NULL);
d3e28653 722 pp_newline (context->printer);
cc015f3a 723 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
e9c9a142 724 pp_set_prefix (context->printer, saved_prefix);
01e1dea3 725 pp_flush (context->printer);
6ed551b4
GDR
726}
727
79cf5994
DD
728/* Interface to specify diagnostic kind overrides. Returns the
729 previous setting, or DK_UNSPECIFIED if the parameters are out of
3c8ca1ab
EB
730 range. If OPTION_INDEX is zero, the new setting is for all the
731 diagnostics. */
79cf5994
DD
732diagnostic_t
733diagnostic_classify_diagnostic (diagnostic_context *context,
734 int option_index,
cd7fe53b
DD
735 diagnostic_t new_kind,
736 location_t where)
79cf5994
DD
737{
738 diagnostic_t old_kind;
739
3c8ca1ab 740 if (option_index < 0
5f0f4a3b 741 || option_index >= context->n_opts
79cf5994
DD
742 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
743 return DK_UNSPECIFIED;
744
745 old_kind = context->classify_diagnostic[option_index];
cd7fe53b
DD
746
747 /* Handle pragmas separately, since we need to keep track of *where*
748 the pragmas were. */
749 if (where != UNKNOWN_LOCATION)
750 {
751 int i;
752
3ba421e8
MLI
753 /* Record the command-line status, so we can reset it back on DK_POP. */
754 if (old_kind == DK_UNSPECIFIED)
755 {
b32bc1ac 756 old_kind = !context->option_enabled (option_index,
fa5baeed 757 context->lang_mask,
b32bc1ac
MLI
758 context->option_state)
759 ? DK_IGNORED : (context->warning_as_error_requested
760 ? DK_ERROR : DK_WARNING);
3ba421e8
MLI
761 context->classify_diagnostic[option_index] = old_kind;
762 }
763
cd7fe53b
DD
764 for (i = context->n_classification_history - 1; i >= 0; i --)
765 if (context->classification_history[i].option == option_index)
766 {
767 old_kind = context->classification_history[i].kind;
768 break;
769 }
770
771 i = context->n_classification_history;
772 context->classification_history =
773 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
774 * sizeof (diagnostic_classification_change_t));
775 context->classification_history[i].location = where;
776 context->classification_history[i].option = option_index;
777 context->classification_history[i].kind = new_kind;
778 context->n_classification_history ++;
779 }
780 else
781 context->classify_diagnostic[option_index] = new_kind;
782
79cf5994
DD
783 return old_kind;
784}
785
cd7fe53b
DD
786/* Save all diagnostic classifications in a stack. */
787void
788diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
789{
790 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
791 context->push_list[context->n_push ++] = context->n_classification_history;
792}
793
794/* Restore the topmost classification set off the stack. If the stack
795 is empty, revert to the state based on command line parameters. */
796void
797diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
798{
799 int jump_to;
800 int i;
801
802 if (context->n_push)
803 jump_to = context->push_list [-- context->n_push];
804 else
805 jump_to = 0;
806
807 i = context->n_classification_history;
808 context->classification_history =
809 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
810 * sizeof (diagnostic_classification_change_t));
811 context->classification_history[i].location = where;
812 context->classification_history[i].option = jump_to;
813 context->classification_history[i].kind = DK_POP;
814 context->n_classification_history ++;
815}
816
a93eac6a
DM
817/* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
818 escaping rules for -fdiagnostics-parseable-fixits. */
819
820static void
821print_escaped_string (pretty_printer *pp, const char *text)
822{
823 gcc_assert (pp);
824 gcc_assert (text);
825
826 pp_character (pp, '"');
827 for (const char *ch = text; *ch; ch++)
828 {
829 switch (*ch)
830 {
831 case '\\':
832 /* Escape backslash as two backslashes. */
833 pp_string (pp, "\\\\");
834 break;
835 case '\t':
836 /* Escape tab as "\t". */
837 pp_string (pp, "\\t");
838 break;
839 case '\n':
840 /* Escape newline as "\n". */
841 pp_string (pp, "\\n");
842 break;
843 case '"':
844 /* Escape doublequotes as \". */
845 pp_string (pp, "\\\"");
846 break;
847 default:
848 if (ISPRINT (*ch))
849 pp_character (pp, *ch);
850 else
851 /* Use octal for non-printable chars. */
852 {
853 unsigned char c = (*ch & 0xff);
854 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
855 }
856 break;
857 }
858 }
859 pp_character (pp, '"');
860}
861
862/* Implementation of -fdiagnostics-parseable-fixits. Print a
863 machine-parseable version of all fixits in RICHLOC to PP. */
864
865static void
866print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
867{
868 gcc_assert (pp);
869 gcc_assert (richloc);
870
e9c9a142
DM
871 char *saved_prefix = pp_take_prefix (pp);
872 pp_set_prefix (pp, NULL);
873
a93eac6a
DM
874 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
875 {
876 const fixit_hint *hint = richloc->get_fixit_hint (i);
620e594b 877 location_t start_loc = hint->get_start_loc ();
a93eac6a
DM
878 expanded_location start_exploc = expand_location (start_loc);
879 pp_string (pp, "fix-it:");
880 print_escaped_string (pp, start_exploc.file);
a93eac6a 881 /* For compatibility with clang, print as a half-open range. */
620e594b 882 location_t next_loc = hint->get_next_loc ();
338035aa
DM
883 expanded_location next_exploc = expand_location (next_loc);
884 pp_printf (pp, ":{%i:%i-%i:%i}:",
885 start_exploc.line, start_exploc.column,
886 next_exploc.line, next_exploc.column);
887 print_escaped_string (pp, hint->get_string ());
a93eac6a
DM
888 pp_newline (pp);
889 }
e9c9a142
DM
890
891 pp_set_prefix (pp, saved_prefix);
a93eac6a
DM
892}
893
dc41c9b0
DM
894/* Update the diag_class of DIAGNOSTIC based on its location
895 relative to any
896 #pragma GCC diagnostic
897 directives recorded within CONTEXT.
898
899 Return the new diag_class of DIAGNOSTIC if it was updated, or
900 DK_UNSPECIFIED otherwise. */
901
902static diagnostic_t
903update_effective_level_from_pragmas (diagnostic_context *context,
904 diagnostic_info *diagnostic)
905{
906 diagnostic_t diag_class = DK_UNSPECIFIED;
907
908 if (context->n_classification_history > 0)
909 {
910 location_t location = diagnostic_location (diagnostic);
911
912 /* FIXME: Stupid search. Optimize later. */
913 for (int i = context->n_classification_history - 1; i >= 0; i --)
914 {
915 if (linemap_location_before_p
916 (line_table,
917 context->classification_history[i].location,
918 location))
919 {
920 if (context->classification_history[i].kind == (int) DK_POP)
921 {
922 i = context->classification_history[i].option;
923 continue;
924 }
925 int option = context->classification_history[i].option;
926 /* The option 0 is for all the diagnostics. */
927 if (option == 0 || option == diagnostic->option_index)
928 {
929 diag_class = context->classification_history[i].kind;
930 if (diag_class != DK_UNSPECIFIED)
931 diagnostic->kind = diag_class;
932 break;
933 }
934 }
935 }
936 }
937
938 return diag_class;
939}
940
6d4a35ca
DM
941/* Generate a URL string describing CWE. The caller is responsible for
942 freeing the string. */
943
944static char *
945get_cwe_url (int cwe)
946{
947 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
948}
949
950/* If DIAGNOSTIC has a CWE identifier, print it.
951
952 For example, if the diagnostic metadata associates it with CWE-119,
953 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
954 description of the security issue. */
955
956static void
957print_any_cwe (diagnostic_context *context,
958 const diagnostic_info *diagnostic)
959{
960 if (diagnostic->metadata == NULL)
961 return;
962
963 int cwe = diagnostic->metadata->get_cwe ();
964 if (cwe)
965 {
966 pretty_printer *pp = context->printer;
967 char *saved_prefix = pp_take_prefix (context->printer);
968 pp_string (pp, " [");
969 pp_string (pp, colorize_start (pp_show_color (pp),
970 diagnostic_kind_color[diagnostic->kind]));
971 char *cwe_url = get_cwe_url (cwe);
972 pp_begin_url (pp, cwe_url);
973 free (cwe_url);
974 pp_printf (pp, "CWE-%i", cwe);
975 pp_set_prefix (context->printer, saved_prefix);
976 pp_end_url (pp);
977 pp_string (pp, colorize_stop (pp_show_color (pp)));
978 pp_character (pp, ']');
979 }
980}
981
80ceac09
DM
982/* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
983 printer, e.g. " [-Werror=uninitialized]".
984 Subroutine of diagnostic_report_diagnostic. */
985
986static void
987print_option_information (diagnostic_context *context,
988 const diagnostic_info *diagnostic,
989 diagnostic_t orig_diag_kind)
990{
991 char *option_text;
992
993 option_text = context->option_name (context, diagnostic->option_index,
994 orig_diag_kind, diagnostic->kind);
995
996 if (option_text)
997 {
b4c7ca2e
DM
998 char *option_url = NULL;
999 if (context->get_option_url)
1000 option_url = context->get_option_url (context,
1001 diagnostic->option_index);
80ceac09
DM
1002 pretty_printer *pp = context->printer;
1003 pp_string (pp, " [");
1004 pp_string (pp, colorize_start (pp_show_color (pp),
1005 diagnostic_kind_color[diagnostic->kind]));
b4c7ca2e
DM
1006 if (option_url)
1007 pp_begin_url (pp, option_url);
80ceac09 1008 pp_string (pp, option_text);
b4c7ca2e
DM
1009 if (option_url)
1010 {
1011 pp_end_url (pp);
1012 free (option_url);
1013 }
80ceac09
DM
1014 pp_string (pp, colorize_stop (pp_show_color (pp)));
1015 pp_character (pp, ']');
1016 free (option_text);
1017 }
1018}
dc41c9b0 1019
59650e48
ZW
1020/* Report a diagnostic message (an error or a warning) as specified by
1021 DC. This function is *the* subroutine in terms of which front-ends
1022 should implement their specific diagnostic handling modules. The
1023 front-end independent format specifiers are exactly those described
b8698a0f 1024 in the documentation of output_format.
71205d17 1025 Return true if a diagnostic was printed, false otherwise. */
400500c4 1026
71205d17 1027bool
79a490a9
AJ
1028diagnostic_report_diagnostic (diagnostic_context *context,
1029 diagnostic_info *diagnostic)
400500c4 1030{
2a2703a2 1031 location_t location = diagnostic_location (diagnostic);
d0b8780d 1032 diagnostic_t orig_diag_kind = diagnostic->kind;
4e2bae26
MLI
1033
1034 /* Give preference to being able to inhibit warnings, before they
1035 get reclassified to something else. */
71205d17 1036 if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
5f0f4a3b 1037 && !diagnostic_report_warnings_p (context, location))
71205d17
MLI
1038 return false;
1039
b8698a0f 1040 if (diagnostic->kind == DK_PEDWARN)
d0b8780d 1041 {
243fbddd 1042 diagnostic->kind = pedantic_warning_kind (context);
d0b8780d
MLI
1043 /* We do this to avoid giving the message for -pedantic-errors. */
1044 orig_diag_kind = diagnostic->kind;
1045 }
0e94b750
MLI
1046
1047 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
1048 return false;
b8698a0f 1049
d5706a1e
ZW
1050 if (context->lock > 0)
1051 {
1052 /* If we're reporting an ICE in the middle of some other error,
1053 try to flush out the previous error, then let this one
1054 through. Don't do this more than once. */
b55f40c1
JJ
1055 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1056 && context->lock == 1)
f8923f7e 1057 pp_newline_and_flush (context->printer);
d5706a1e
ZW
1058 else
1059 error_recursion (context);
1060 }
1061
4e2bae26
MLI
1062 /* If the user requested that warnings be treated as errors, so be
1063 it. Note that we do this before the next block so that
1064 individual warnings can be overridden back to warnings with
1065 -Wno-error=*. */
1066 if (context->warning_as_error_requested
1067 && diagnostic->kind == DK_WARNING)
03fd1ef6 1068 diagnostic->kind = DK_ERROR;
b8698a0f 1069
0c3641b0
MLI
1070 if (diagnostic->option_index
1071 && diagnostic->option_index != permissive_error_option (context))
79cf5994
DD
1072 {
1073 /* This tests if the user provided the appropriate -Wfoo or
1074 -Wno-foo option. */
46625112 1075 if (! context->option_enabled (diagnostic->option_index,
fa5baeed 1076 context->lang_mask,
46625112 1077 context->option_state))
71205d17 1078 return false;
cd7fe53b
DD
1079
1080 /* This tests for #pragma diagnostic changes. */
dc41c9b0
DM
1081 diagnostic_t diag_class
1082 = update_effective_level_from_pragmas (context, diagnostic);
d5e7854c 1083
79cf5994
DD
1084 /* This tests if the user provided the appropriate -Werror=foo
1085 option. */
cd7fe53b 1086 if (diag_class == DK_UNSPECIFIED
d5e7854c
NS
1087 && (context->classify_diagnostic[diagnostic->option_index]
1088 != DK_UNSPECIFIED))
1089 diagnostic->kind
1090 = context->classify_diagnostic[diagnostic->option_index];
1091
c0220ea4 1092 /* This allows for future extensions, like temporarily disabling
79cf5994
DD
1093 warnings for ranges of source code. */
1094 if (diagnostic->kind == DK_IGNORED)
71205d17 1095 return false;
79cf5994 1096 }
2098fe9e 1097
d0ea9f0a
NS
1098 if (diagnostic->kind != DK_NOTE)
1099 diagnostic_check_max_errors (context);
1100
d5706a1e 1101 context->lock++;
400500c4 1102
b55f40c1 1103 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
59650e48 1104 {
52249a2e
MLI
1105 /* When not checking, ICEs are converted to fatal errors when an
1106 error has already occurred. This is counteracted by
1107 abort_on_error. */
b2b29377
MM
1108 if (!CHECKING_P
1109 && (diagnostic_kind_count (context, DK_ERROR) > 0
1110 || diagnostic_kind_count (context, DK_SORRY) > 0)
52249a2e
MLI
1111 && !context->abort_on_error)
1112 {
2a2703a2
MLI
1113 expanded_location s
1114 = expand_location (diagnostic_location (diagnostic));
52249a2e
MLI
1115 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1116 s.file, s.line);
1117 exit (ICE_EXIT_CODE);
1118 }
52249a2e 1119 if (context->internal_error)
a13812e2
JM
1120 (*context->internal_error) (context,
1121 diagnostic->message.format_spec,
52249a2e 1122 diagnostic->message.args_ptr);
43db5b3c 1123 }
37e99116
JJ
1124 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
1125 ++diagnostic_kind_count (context, DK_WERROR);
1126 else
1127 ++diagnostic_kind_count (context, diagnostic->kind);
b8698a0f 1128
097f82ec
DM
1129 /* Is this the initial diagnostic within the stack of groups? */
1130 if (context->diagnostic_group_emission_count == 0)
1131 {
1132 if (context->begin_group_cb)
1133 context->begin_group_cb (context);
1134 }
1135 context->diagnostic_group_emission_count++;
1136
cf835838
JM
1137 diagnostic->message.x_data = &diagnostic->x_data;
1138 diagnostic->x_data = NULL;
52249a2e
MLI
1139 pp_format (context->printer, &diagnostic->message);
1140 (*diagnostic_starter (context)) (context, diagnostic);
1141 pp_output_formatted_text (context->printer);
6d4a35ca
DM
1142 if (context->show_cwe)
1143 print_any_cwe (context, diagnostic);
80ceac09
DM
1144 if (context->show_option_requested)
1145 print_option_information (context, diagnostic, orig_diag_kind);
478dd60d 1146 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
a93eac6a
DM
1147 if (context->parseable_fixits_p)
1148 {
1149 print_parseable_fixits (context->printer, diagnostic->richloc);
1150 pp_flush (context->printer);
1151 }
c4100eae 1152 diagnostic_action_after_output (context, diagnostic->kind);
cf835838 1153 diagnostic->x_data = NULL;
9804f5fb 1154
717ebe91 1155 if (context->edit_context_ptr)
b09649fd
DM
1156 if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
1157 context->edit_context_ptr->add_fixits (diagnostic->richloc);
717ebe91 1158
9804f5fb 1159 context->lock--;
71205d17 1160
4bc1899b
DM
1161 diagnostic_show_any_path (context, diagnostic);
1162
71205d17 1163 return true;
59650e48 1164}
43db5b3c 1165
bc65bad2
MG
1166/* Get the number of digits in the decimal representation of VALUE. */
1167
1168int
1169num_digits (int value)
1170{
1171 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1172 using floating point. */
1173 gcc_assert (value >= 0);
1174
1175 if (value == 0)
1176 return 1;
1177
1178 int digits = 0;
1179 while (value > 0)
1180 {
1181 digits++;
1182 value /= 10;
1183 }
1184 return digits;
1185}
1186
59650e48
ZW
1187/* Given a partial pathname as input, return another pathname that
1188 shares no directory elements with the pathname of __FILE__. This
1189 is used by fancy_abort() to print `Internal compiler error in expr.c'
1190 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
3a538a66 1191
59650e48 1192const char *
79a490a9 1193trim_filename (const char *name)
59650e48
ZW
1194{
1195 static const char this_file[] = __FILE__;
1196 const char *p = name, *q = this_file;
43db5b3c 1197
59650e48
ZW
1198 /* First skip any "../" in each filename. This allows us to give a proper
1199 reference to a file in a subdirectory. */
d5706a1e 1200 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
59650e48
ZW
1201 p += 3;
1202
d5706a1e 1203 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
59650e48
ZW
1204 q += 3;
1205
1206 /* Now skip any parts the two filenames have in common. */
1207 while (*p == *q && *p != 0 && *q != 0)
1208 p++, q++;
1209
1210 /* Now go backwards until the previous directory separator. */
ef9af077 1211 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
59650e48
ZW
1212 p--;
1213
1214 return p;
6ed551b4 1215}
59650e48
ZW
1216\f
1217/* Standard error reporting routines in increasing order of severity.
1218 All of these take arguments like printf. */
6ed551b4 1219
59650e48
ZW
1220/* Text to be emitted verbatim to the error message stream; this
1221 produces no prefix and disables line-wrapping. Use rarely. */
6ed551b4 1222void
4b794eaf 1223verbatim (const char *gmsgid, ...)
59650e48
ZW
1224{
1225 text_info text;
e34d07f2 1226 va_list ap;
59650e48 1227
4b794eaf 1228 va_start (ap, gmsgid);
fa6ef813 1229 text.err_no = errno;
59650e48 1230 text.args_ptr = &ap;
4b794eaf 1231 text.format_spec = _(gmsgid);
cf835838 1232 text.x_data = NULL;
b6fe0bb8 1233 pp_format_verbatim (global_dc->printer, &text);
f8923f7e 1234 pp_newline_and_flush (global_dc->printer);
e34d07f2 1235 va_end (ap);
59650e48
ZW
1236}
1237
dfa32261
MLI
1238/* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1239void
1240diagnostic_append_note (diagnostic_context *context,
1241 location_t location,
1242 const char * gmsgid, ...)
1243{
1244 diagnostic_info diagnostic;
1245 va_list ap;
ebedc9a3 1246 rich_location richloc (line_table, location);
dfa32261
MLI
1247
1248 va_start (ap, gmsgid);
8a645150
DM
1249 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1250 if (context->inhibit_notes_p)
1251 {
1252 va_end (ap);
1253 return;
1254 }
653fee19 1255 char *saved_prefix = pp_take_prefix (context->printer);
8a645150
DM
1256 pp_set_prefix (context->printer,
1257 diagnostic_build_prefix (context, &diagnostic));
dfa32261
MLI
1258 pp_format (context->printer, &diagnostic.message);
1259 pp_output_formatted_text (context->printer);
1260 pp_destroy_prefix (context->printer);
4432aa6c 1261 pp_set_prefix (context->printer, saved_prefix);
d3e28653 1262 pp_newline (context->printer);
cc015f3a 1263 diagnostic_show_locus (context, &richloc, DK_NOTE);
c3284718 1264 va_end (ap);
dfa32261
MLI
1265}
1266
64a5912c
DM
1267/* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1268 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1269 and internal_error_no_backtrace, as documented and defined below. */
c3811744 1270static bool
6d4a35ca
DM
1271diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1272 int opt, const char *gmsgid,
c3811744 1273 va_list *ap, diagnostic_t kind)
6ed551b4 1274{
47b69537 1275 diagnostic_info diagnostic;
71205d17
MLI
1276 if (kind == DK_PERMERROR)
1277 {
c3811744 1278 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
243fbddd 1279 permissive_error_kind (global_dc));
5f0f4a3b 1280 diagnostic.option_index = permissive_error_option (global_dc);
71205d17 1281 }
c3811744
PC
1282 else
1283 {
1284 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
71205d17
MLI
1285 if (kind == DK_WARNING || kind == DK_PEDWARN)
1286 diagnostic.option_index = opt;
c3811744 1287 }
6d4a35ca 1288 diagnostic.metadata = metadata;
56d35585 1289 return diagnostic_report_diagnostic (global_dc, &diagnostic);
c3811744
PC
1290}
1291
64a5912c
DM
1292/* Implement inform_n, warning_n, and error_n, as documented and
1293 defined below. */
a5fb7ad2 1294static bool
6d4a35ca
DM
1295diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1296 int opt, unsigned HOST_WIDE_INT n,
64a5912c
DM
1297 const char *singular_gmsgid,
1298 const char *plural_gmsgid,
1299 va_list *ap, diagnostic_t kind)
a5fb7ad2
PK
1300{
1301 diagnostic_info diagnostic;
1c89478a
MS
1302 unsigned long gtn;
1303
1304 if (sizeof n <= sizeof gtn)
1305 gtn = n;
1306 else
1307 /* Use the largest number ngettext can handle, otherwise
1308 preserve the six least significant decimal digits for
1309 languages where the plural form depends on them. */
1310 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;
1311
1312 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
1313 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
a5fb7ad2
PK
1314 if (kind == DK_WARNING)
1315 diagnostic.option_index = opt;
6d4a35ca 1316 diagnostic.metadata = metadata;
56d35585 1317 return diagnostic_report_diagnostic (global_dc, &diagnostic);
c3811744 1318}
71205d17 1319
296c53ac
MP
1320/* Wrapper around diagnostic_impl taking a variable argument list. */
1321
c3811744
PC
1322bool
1323emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1324 const char *gmsgid, ...)
1325{
097f82ec 1326 auto_diagnostic_group d;
c3811744
PC
1327 va_list ap;
1328 va_start (ap, gmsgid);
1329 rich_location richloc (line_table, location);
6d4a35ca 1330 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
80f24351
MM
1331 va_end (ap);
1332 return ret;
6ed551b4
GDR
1333}
1334
8ba109ce
DM
1335/* As above, but for rich_location *. */
1336
1337bool
1338emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
1339 const char *gmsgid, ...)
1340{
1341 auto_diagnostic_group d;
1342 va_list ap;
1343 va_start (ap, gmsgid);
6d4a35ca 1344 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
8ba109ce
DM
1345 va_end (ap);
1346 return ret;
1347}
1348
296c53ac
MP
1349/* Wrapper around diagnostic_impl taking a va_list parameter. */
1350
1351bool
1352emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
1353 const char *gmsgid, va_list *ap)
1354{
1355 rich_location richloc (line_table, location);
6d4a35ca
DM
1356 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
1357}
1358
1359/* Wrapper around diagnostic_impl taking a va_list parameter. */
1360
1361bool
1362emit_diagnostic_valist (diagnostic_t kind, rich_location *richloc,
1363 const diagnostic_metadata *metadata,
1364 int opt,
1365 const char *gmsgid, va_list *ap)
1366{
1367 return diagnostic_impl (richloc, metadata, opt, gmsgid, ap, kind);
296c53ac
MP
1368}
1369
1f5b3869 1370/* An informative note at LOCATION. Use this for additional details on an error
71205d17 1371 message. */
6ed551b4 1372void
1f5b3869 1373inform (location_t location, const char *gmsgid, ...)
8a645150 1374{
097f82ec 1375 auto_diagnostic_group d;
8a645150 1376 va_list ap;
8a645150 1377 va_start (ap, gmsgid);
c3811744 1378 rich_location richloc (line_table, location);
6d4a35ca 1379 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
8a645150
DM
1380 va_end (ap);
1381}
1382
64a5912c 1383/* Same as "inform" above, but at RICHLOC. */
8a645150 1384void
64a5912c 1385inform (rich_location *richloc, const char *gmsgid, ...)
d4ee4d25 1386{
64a5912c
DM
1387 gcc_assert (richloc);
1388
097f82ec 1389 auto_diagnostic_group d;
d4ee4d25 1390 va_list ap;
4b794eaf 1391 va_start (ap, gmsgid);
6d4a35ca 1392 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
d4ee4d25
DD
1393 va_end (ap);
1394}
1395
894e2652
SZ
1396/* An informative note at LOCATION. Use this for additional details on an
1397 error message. */
1398void
1c89478a
MS
1399inform_n (location_t location, unsigned HOST_WIDE_INT n,
1400 const char *singular_gmsgid, const char *plural_gmsgid, ...)
894e2652 1401{
894e2652 1402 va_list ap;
894e2652 1403 va_start (ap, plural_gmsgid);
097f82ec 1404 auto_diagnostic_group d;
64a5912c 1405 rich_location richloc (line_table, location);
6d4a35ca 1406 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
c3811744 1407 &ap, DK_NOTE);
894e2652
SZ
1408 va_end (ap);
1409}
1410
71205d17 1411/* A warning at INPUT_LOCATION. Use this for code which is correct according
b8698a0f 1412 to the relevant language specification but is likely to be buggy anyway.
71205d17
MLI
1413 Returns true if the warning was printed, false if it was inhibited. */
1414bool
1415warning (int opt, const char *gmsgid, ...)
6ed551b4 1416{
097f82ec 1417 auto_diagnostic_group d;
e34d07f2 1418 va_list ap;
4b794eaf 1419 va_start (ap, gmsgid);
c3811744 1420 rich_location richloc (line_table, input_location);
6d4a35ca 1421 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
e34d07f2 1422 va_end (ap);
80f24351 1423 return ret;
6ed551b4
GDR
1424}
1425
aa14403d 1426/* A warning at LOCATION. Use this for code which is correct according to the
71205d17
MLI
1427 relevant language specification but is likely to be buggy anyway.
1428 Returns true if the warning was printed, false if it was inhibited. */
1429
1430bool
aa14403d 1431warning_at (location_t location, int opt, const char *gmsgid, ...)
8a645150 1432{
097f82ec 1433 auto_diagnostic_group d;
8a645150 1434 va_list ap;
8a645150 1435 va_start (ap, gmsgid);
c3811744 1436 rich_location richloc (line_table, location);
6d4a35ca 1437 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
8a645150
DM
1438 va_end (ap);
1439 return ret;
1440}
1441
64a5912c 1442/* Same as "warning at" above, but using RICHLOC. */
8a645150
DM
1443
1444bool
64a5912c 1445warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
aa14403d 1446{
64a5912c
DM
1447 gcc_assert (richloc);
1448
097f82ec 1449 auto_diagnostic_group d;
aa14403d 1450 va_list ap;
aa14403d 1451 va_start (ap, gmsgid);
6d4a35ca
DM
1452 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1453 va_end (ap);
1454 return ret;
1455}
1456
1457/* Same as "warning at" above, but using METADATA. */
1458
1459bool
1460warning_at (rich_location *richloc, const diagnostic_metadata &metadata,
1461 int opt, const char *gmsgid, ...)
1462{
1463 gcc_assert (richloc);
1464
1465 auto_diagnostic_group d;
1466 va_list ap;
1467 va_start (ap, gmsgid);
1468 bool ret
1469 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
1470 DK_WARNING);
aa14403d 1471 va_end (ap);
80f24351 1472 return ret;
aa14403d
RAE
1473}
1474
64a5912c 1475/* Same as warning_n plural variant below, but using RICHLOC. */
a5fb7ad2
PK
1476
1477bool
1c89478a 1478warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
64a5912c 1479 const char *singular_gmsgid, const char *plural_gmsgid, ...)
a5fb7ad2 1480{
64a5912c
DM
1481 gcc_assert (richloc);
1482
097f82ec 1483 auto_diagnostic_group d;
a5fb7ad2
PK
1484 va_list ap;
1485 va_start (ap, plural_gmsgid);
6d4a35ca 1486 bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
64a5912c
DM
1487 singular_gmsgid, plural_gmsgid,
1488 &ap, DK_WARNING);
a5fb7ad2
PK
1489 va_end (ap);
1490 return ret;
1491}
1492
26e82579
JH
1493/* A warning at LOCATION. Use this for code which is correct according to the
1494 relevant language specification but is likely to be buggy anyway.
1495 Returns true if the warning was printed, false if it was inhibited. */
1496
1497bool
1c89478a
MS
1498warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
1499 const char *singular_gmsgid, const char *plural_gmsgid, ...)
26e82579 1500{
097f82ec 1501 auto_diagnostic_group d;
26e82579 1502 va_list ap;
26e82579 1503 va_start (ap, plural_gmsgid);
64a5912c 1504 rich_location richloc (line_table, location);
6d4a35ca 1505 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
c3811744
PC
1506 singular_gmsgid, plural_gmsgid,
1507 &ap, DK_WARNING);
26e82579
JH
1508 va_end (ap);
1509 return ret;
1510}
1511
85790e66
MLI
1512/* A "pedantic" warning at LOCATION: issues a warning unless
1513 -pedantic-errors was given on the command line, in which case it
1514 issues an error. Use this for diagnostics required by the relevant
1515 language standard, if you have chosen not to make them errors.
9804f5fb
ZW
1516
1517 Note that these diagnostics are issued independent of the setting
c1771a20 1518 of the -Wpedantic command-line switch. To get a warning enabled
fcf73884 1519 only with that switch, use either "if (pedantic) pedwarn
c1771a20
MLI
1520 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1521 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
fcf73884 1522
71205d17
MLI
1523 Returns true if the warning was printed, false if it was inhibited. */
1524
85790e66 1525bool
509c9d60 1526pedwarn (location_t location, int opt, const char *gmsgid, ...)
85790e66 1527{
097f82ec 1528 auto_diagnostic_group d;
85790e66 1529 va_list ap;
85790e66 1530 va_start (ap, gmsgid);
c3811744 1531 rich_location richloc (line_table, location);
6d4a35ca 1532 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
85790e66 1533 va_end (ap);
80f24351 1534 return ret;
85790e66
MLI
1535}
1536
64a5912c 1537/* Same as pedwarn above, but using RICHLOC. */
1a4f11c8
DM
1538
1539bool
64a5912c 1540pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
1a4f11c8 1541{
64a5912c
DM
1542 gcc_assert (richloc);
1543
097f82ec 1544 auto_diagnostic_group d;
1a4f11c8
DM
1545 va_list ap;
1546 va_start (ap, gmsgid);
6d4a35ca 1547 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1a4f11c8
DM
1548 va_end (ap);
1549 return ret;
1550}
1551
7e99f74b
MLI
1552/* A "permissive" error at LOCATION: issues an error unless
1553 -fpermissive was given on the command line, in which case it issues
1554 a warning. Use this for things that really should be errors but we
71205d17 1555 want to support legacy code.
7e99f74b 1556
71205d17
MLI
1557 Returns true if the warning was printed, false if it was inhibited. */
1558
1559bool
cbe5f3b3 1560permerror (location_t location, const char *gmsgid, ...)
7e99f74b 1561{
097f82ec 1562 auto_diagnostic_group d;
7e99f74b 1563 va_list ap;
7e99f74b 1564 va_start (ap, gmsgid);
c3811744 1565 rich_location richloc (line_table, location);
6d4a35ca 1566 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
8a645150
DM
1567 va_end (ap);
1568 return ret;
1569}
1570
64a5912c 1571/* Same as "permerror" above, but at RICHLOC. */
8a645150
DM
1572
1573bool
64a5912c 1574permerror (rich_location *richloc, const char *gmsgid, ...)
8a645150 1575{
64a5912c
DM
1576 gcc_assert (richloc);
1577
097f82ec 1578 auto_diagnostic_group d;
8a645150 1579 va_list ap;
8a645150 1580 va_start (ap, gmsgid);
6d4a35ca 1581 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
7e99f74b 1582 va_end (ap);
80f24351 1583 return ret;
7e99f74b
MLI
1584}
1585
59650e48
ZW
1586/* A hard error: the code is definitely ill-formed, and an object file
1587 will not be produced. */
8514e318 1588void
4b794eaf 1589error (const char *gmsgid, ...)
8514e318 1590{
097f82ec 1591 auto_diagnostic_group d;
e34d07f2 1592 va_list ap;
4b794eaf 1593 va_start (ap, gmsgid);
c3811744 1594 rich_location richloc (line_table, input_location);
6d4a35ca 1595 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
e34d07f2 1596 va_end (ap);
93d87cb1
GDR
1597}
1598
894e2652
SZ
1599/* A hard error: the code is definitely ill-formed, and an object file
1600 will not be produced. */
1601void
1c89478a
MS
1602error_n (location_t location, unsigned HOST_WIDE_INT n,
1603 const char *singular_gmsgid, const char *plural_gmsgid, ...)
894e2652 1604{
097f82ec 1605 auto_diagnostic_group d;
894e2652 1606 va_list ap;
894e2652 1607 va_start (ap, plural_gmsgid);
64a5912c 1608 rich_location richloc (line_table, location);
6d4a35ca 1609 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
c3811744 1610 &ap, DK_ERROR);
894e2652
SZ
1611 va_end (ap);
1612}
1613
c3811744 1614/* Same as above, but use location LOC instead of input_location. */
a63068b6
AH
1615void
1616error_at (location_t loc, const char *gmsgid, ...)
1617{
097f82ec 1618 auto_diagnostic_group d;
a63068b6 1619 va_list ap;
a63068b6 1620 va_start (ap, gmsgid);
c3811744 1621 rich_location richloc (line_table, loc);
6d4a35ca 1622 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
8a645150
DM
1623 va_end (ap);
1624}
1625
1626/* Same as above, but use RICH_LOC. */
1627
1628void
64a5912c 1629error_at (rich_location *richloc, const char *gmsgid, ...)
8a645150 1630{
64a5912c
DM
1631 gcc_assert (richloc);
1632
097f82ec 1633 auto_diagnostic_group d;
8a645150 1634 va_list ap;
8a645150 1635 va_start (ap, gmsgid);
6d4a35ca 1636 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
a63068b6
AH
1637 va_end (ap);
1638}
1639
59650e48
ZW
1640/* "Sorry, not implemented." Use for a language feature which is
1641 required by the relevant specification but not implemented by GCC.
1642 An object file will not be produced. */
93d87cb1 1643void
4b794eaf 1644sorry (const char *gmsgid, ...)
93d87cb1 1645{
097f82ec 1646 auto_diagnostic_group d;
e34d07f2 1647 va_list ap;
4b794eaf 1648 va_start (ap, gmsgid);
c3811744 1649 rich_location richloc (line_table, input_location);
6d4a35ca 1650 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
e34d07f2 1651 va_end (ap);
59650e48 1652}
43db5b3c 1653
ad172f72
AS
1654/* Same as above, but use location LOC instead of input_location. */
1655void
1656sorry_at (location_t loc, const char *gmsgid, ...)
1657{
1658 auto_diagnostic_group d;
1659 va_list ap;
1660 va_start (ap, gmsgid);
1661 rich_location richloc (line_table, loc);
6d4a35ca 1662 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
ad172f72
AS
1663 va_end (ap);
1664}
1665
1da2ed5f
JM
1666/* Return true if an error or a "sorry" has been seen. Various
1667 processing is disabled after errors. */
1668bool
1669seen_error (void)
1670{
1671 return errorcount || sorrycount;
1672}
1673
3d00119c
AB
1674/* An error which is severe enough that we make no attempt to
1675 continue. Do not use this for internal consistency checks; that's
1676 internal_error. Use of this function should be rare. */
1677void
1678fatal_error (location_t loc, const char *gmsgid, ...)
1679{
097f82ec 1680 auto_diagnostic_group d;
3d00119c 1681 va_list ap;
3d00119c 1682 va_start (ap, gmsgid);
c3811744 1683 rich_location richloc (line_table, loc);
6d4a35ca 1684 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
3d00119c
AB
1685 va_end (ap);
1686
1687 gcc_unreachable ();
1688}
1689
59650e48
ZW
1690/* An internal consistency check has failed. We make no attempt to
1691 continue. Note that unless there is debugging value to be had from
1692 a more specific message, or some other good reason, you should use
1693 abort () instead of calling this function directly. */
1694void
4b794eaf 1695internal_error (const char *gmsgid, ...)
fbfc1192 1696{
097f82ec 1697 auto_diagnostic_group d;
e34d07f2 1698 va_list ap;
4b794eaf 1699 va_start (ap, gmsgid);
c3811744 1700 rich_location richloc (line_table, input_location);
6d4a35ca 1701 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
e34d07f2 1702 va_end (ap);
fbfc1192 1703
d5706a1e 1704 gcc_unreachable ();
fbfc1192 1705}
b55f40c1
JJ
1706
1707/* Like internal_error, but no backtrace will be printed. Used when
1708 the internal error does not happen at the current location, but happened
1709 somewhere else. */
1710void
1711internal_error_no_backtrace (const char *gmsgid, ...)
1712{
097f82ec 1713 auto_diagnostic_group d;
b55f40c1 1714 va_list ap;
b55f40c1 1715 va_start (ap, gmsgid);
c3811744 1716 rich_location richloc (line_table, input_location);
6d4a35ca 1717 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
b55f40c1
JJ
1718 va_end (ap);
1719
1720 gcc_unreachable ();
1721}
59650e48 1722\f
59650e48
ZW
1723/* Special case error functions. Most are implemented in terms of the
1724 above, or should be. */
e23bd218 1725
59650e48
ZW
1726/* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1727 runs its second argument through gettext. */
04c1334c 1728void
4b794eaf 1729fnotice (FILE *file, const char *cmsgid, ...)
04c1334c 1730{
e34d07f2 1731 va_list ap;
04c1334c 1732
4b794eaf
JJ
1733 va_start (ap, cmsgid);
1734 vfprintf (file, _(cmsgid), ap);
e34d07f2 1735 va_end (ap);
04c1334c
GDR
1736}
1737
59650e48
ZW
1738/* Inform the user that an error occurred while trying to report some
1739 other error. This indicates catastrophic internal inconsistencies,
1740 so give up now. But do try to flush out the previous error.
1741 This mustn't use internal_error, that will cause infinite recursion. */
1742
1743static void
79a490a9 1744error_recursion (diagnostic_context *context)
59650e48
ZW
1745{
1746 if (context->lock < 3)
f8923f7e 1747 pp_newline_and_flush (context->printer);
59650e48
ZW
1748
1749 fnotice (stderr,
1750 "Internal compiler error: Error reporting routines re-entered.\n");
d5706a1e
ZW
1751
1752 /* Call diagnostic_action_after_output to get the "please submit a bug
c4100eae
MLI
1753 report" message. */
1754 diagnostic_action_after_output (context, DK_ICE);
d5706a1e
ZW
1755
1756 /* Do not use gcc_unreachable here; that goes through internal_error
1757 and therefore would cause infinite recursion. */
1758 real_abort ();
59650e48
ZW
1759}
1760
1761/* Report an internal compiler error in a friendly manner. This is
1762 the function that gets called upon use of abort() in the source
1763 code generally, thanks to a special macro. */
1764
1765void
79a490a9 1766fancy_abort (const char *file, int line, const char *function)
59650e48
ZW
1767{
1768 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
1769}
1770
097f82ec
DM
1771/* class auto_diagnostic_group. */
1772
1773/* Constructor: "push" this group into global_dc. */
1774
1775auto_diagnostic_group::auto_diagnostic_group ()
1776{
1777 global_dc->diagnostic_group_nesting_depth++;
1778}
1779
1780/* Destructor: "pop" this group from global_dc. */
1781
1782auto_diagnostic_group::~auto_diagnostic_group ()
1783{
1784 if (--global_dc->diagnostic_group_nesting_depth == 0)
1785 {
1786 /* Handle the case where we've popped the final diagnostic group.
1787 If any diagnostics were emitted, give the context a chance
1788 to do something. */
1789 if (global_dc->diagnostic_group_emission_count > 0)
1790 {
1791 if (global_dc->end_group_cb)
1792 global_dc->end_group_cb (global_dc);
1793 }
1794 global_dc->diagnostic_group_emission_count = 0;
1795 }
1796}
1797
4bc1899b
DM
1798/* Implementation of diagnostic_path::num_events vfunc for
1799 simple_diagnostic_path: simply get the number of events in the vec. */
1800
1801unsigned
1802simple_diagnostic_path::num_events () const
1803{
1804 return m_events.length ();
1805}
1806
1807/* Implementation of diagnostic_path::get_event vfunc for
1808 simple_diagnostic_path: simply return the event in the vec. */
1809
1810const diagnostic_event &
1811simple_diagnostic_path::get_event (int idx) const
1812{
1813 return *m_events[idx];
1814}
1815
1816/* Add an event to this path at LOC within function FNDECL at
1817 stack depth DEPTH.
1818
1819 Use m_context's printer to format FMT, as the text of the new
1820 event.
1821
1822 Return the id of the new event. */
1823
1824diagnostic_event_id_t
1825simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
1826 const char *fmt, ...)
1827{
1828 pretty_printer *pp = m_event_pp;
1829 pp_clear_output_area (pp);
1830
1831 text_info ti;
1832 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
1833
1834 va_list ap;
1835
1836 va_start (ap, fmt);
1837
1838 ti.format_spec = _(fmt);
1839 ti.args_ptr = &ap;
1840 ti.err_no = 0;
1841 ti.x_data = NULL;
1842 ti.m_richloc = &rich_loc;
1843
1844 pp_format (pp, &ti);
1845 pp_output_formatted_text (pp);
1846
1847 va_end (ap);
1848
1849 simple_diagnostic_event *new_event
1850 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
1851 m_events.safe_push (new_event);
1852
1853 pp_clear_output_area (pp);
1854
1855 return diagnostic_event_id_t (m_events.length () - 1);
1856}
1857
1858/* struct simple_diagnostic_event. */
1859
1860/* simple_diagnostic_event's ctor. */
1861
1862simple_diagnostic_event::simple_diagnostic_event (location_t loc,
1863 tree fndecl,
1864 int depth,
1865 const char *desc)
1866: m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc))
1867{
1868}
1869
1870/* simple_diagnostic_event's dtor. */
1871
1872simple_diagnostic_event::~simple_diagnostic_event ()
1873{
1874 free (m_desc);
1875}
1876
1877/* Print PATH by emitting a dummy "note" associated with it. */
1878
1879DEBUG_FUNCTION
1880void debug (diagnostic_path *path)
1881{
1882 rich_location richloc (line_table, UNKNOWN_LOCATION);
1883 richloc.set_path (path);
1884 inform (&richloc, "debug path");
1885}
1886
886e0865
GK
1887/* Really call the system 'abort'. This has to go right at the end of
1888 this file, so that there are no functions after it that call abort
1889 and get the system abort instead of our macro. */
1890#undef abort
79a490a9
AJ
1891static void
1892real_abort (void)
886e0865
GK
1893{
1894 abort ();
1895}
a93eac6a
DM
1896
1897#if CHECKING_P
1898
1899namespace selftest {
1900
1901/* Helper function for test_print_escaped_string. */
1902
1903static void
1904assert_print_escaped_string (const location &loc, const char *expected_output,
1905 const char *input)
1906{
1907 pretty_printer pp;
1908 print_escaped_string (&pp, input);
1909 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
1910}
1911
1912#define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
1913 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
1914
1915/* Tests of print_escaped_string. */
1916
1917static void
1918test_print_escaped_string ()
1919{
1920 /* Empty string. */
1921 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
1922
1923 /* Non-empty string. */
1924 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
1925
1926 /* Various things that need to be escaped: */
1927 /* Backslash. */
1928 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
1929 "before\\after");
1930 /* Tab. */
1931 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
1932 "before\tafter");
1933 /* Newline. */
1934 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
1935 "before\nafter");
1936 /* Double quote. */
1937 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
1938 "before\"after");
1939
1940 /* Non-printable characters: BEL: '\a': 0x07 */
1941 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
1942 "before\aafter");
1943 /* Non-printable characters: vertical tab: '\v': 0x0b */
1944 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
1945 "before\vafter");
1946}
1947
1948/* Tests of print_parseable_fixits. */
1949
1950/* Verify that print_parseable_fixits emits the empty string if there
1951 are no fixits. */
1952
1953static void
1954test_print_parseable_fixits_none ()
1955{
1956 pretty_printer pp;
1957 rich_location richloc (line_table, UNKNOWN_LOCATION);
1958
1959 print_parseable_fixits (&pp, &richloc);
1960 ASSERT_STREQ ("", pp_formatted_text (&pp));
1961}
1962
1963/* Verify that print_parseable_fixits does the right thing if there
1964 is an insertion fixit hint. */
1965
1966static void
1967test_print_parseable_fixits_insert ()
1968{
1969 pretty_printer pp;
1970 rich_location richloc (line_table, UNKNOWN_LOCATION);
1971
1972 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1973 linemap_line_start (line_table, 5, 100);
1974 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1975 location_t where = linemap_position_for_column (line_table, 10);
254830ba 1976 richloc.add_fixit_insert_before (where, "added content");
a93eac6a
DM
1977
1978 print_parseable_fixits (&pp, &richloc);
1979 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
1980 pp_formatted_text (&pp));
1981}
1982
1983/* Verify that print_parseable_fixits does the right thing if there
1984 is an removal fixit hint. */
1985
1986static void
1987test_print_parseable_fixits_remove ()
1988{
1989 pretty_printer pp;
1990 rich_location richloc (line_table, UNKNOWN_LOCATION);
1991
1992 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1993 linemap_line_start (line_table, 5, 100);
1994 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1995 source_range where;
1996 where.m_start = linemap_position_for_column (line_table, 10);
1997 where.m_finish = linemap_position_for_column (line_table, 20);
1998 richloc.add_fixit_remove (where);
1999
2000 print_parseable_fixits (&pp, &richloc);
2001 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
2002 pp_formatted_text (&pp));
2003}
2004
2005/* Verify that print_parseable_fixits does the right thing if there
2006 is an replacement fixit hint. */
2007
2008static void
2009test_print_parseable_fixits_replace ()
2010{
2011 pretty_printer pp;
2012 rich_location richloc (line_table, UNKNOWN_LOCATION);
2013
2014 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2015 linemap_line_start (line_table, 5, 100);
2016 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2017 source_range where;
2018 where.m_start = linemap_position_for_column (line_table, 10);
2019 where.m_finish = linemap_position_for_column (line_table, 20);
2020 richloc.add_fixit_replace (where, "replacement");
2021
2022 print_parseable_fixits (&pp, &richloc);
2023 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
2024 pp_formatted_text (&pp));
2025}
2026
ace72598
DM
2027/* Verify that
2028 diagnostic_get_location_text (..., SHOW_COLUMN)
2029 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
2030 colorization disabled. */
2031
2032static void
2033assert_location_text (const char *expected_loc_text,
2034 const char *filename, int line, int column,
2035 bool show_column)
2036{
2037 test_diagnostic_context dc;
2038 dc.show_column = show_column;
2039
2040 expanded_location xloc;
2041 xloc.file = filename;
2042 xloc.line = line;
2043 xloc.column = column;
2044 xloc.data = NULL;
2045 xloc.sysp = false;
2046
2047 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
2048 ASSERT_STREQ (expected_loc_text, actual_loc_text);
2049 free (actual_loc_text);
2050}
2051
2052/* Verify that diagnostic_get_location_text works as expected. */
2053
2054static void
2055test_diagnostic_get_location_text ()
2056{
2057 const char *old_progname = progname;
2058 progname = "PROGNAME";
2059 assert_location_text ("PROGNAME:", NULL, 0, 0, true);
2060 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
2061 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
101e910b
NS
2062 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true);
2063 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
ace72598 2064 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
101e910b
NS
2065 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
2066
2067 maybe_line_and_column (INT_MAX, INT_MAX);
2068 maybe_line_and_column (INT_MIN, INT_MIN);
2069
ace72598
DM
2070 progname = old_progname;
2071}
2072
bc65bad2
MG
2073/* Selftest for num_digits. */
2074
2075static void
2076test_num_digits ()
2077{
2078 ASSERT_EQ (1, num_digits (0));
2079 ASSERT_EQ (1, num_digits (9));
2080 ASSERT_EQ (2, num_digits (10));
2081 ASSERT_EQ (2, num_digits (99));
2082 ASSERT_EQ (3, num_digits (100));
2083 ASSERT_EQ (3, num_digits (999));
2084 ASSERT_EQ (4, num_digits (1000));
2085 ASSERT_EQ (4, num_digits (9999));
2086 ASSERT_EQ (5, num_digits (10000));
2087 ASSERT_EQ (5, num_digits (99999));
2088 ASSERT_EQ (6, num_digits (100000));
2089 ASSERT_EQ (6, num_digits (999999));
2090 ASSERT_EQ (7, num_digits (1000000));
2091 ASSERT_EQ (7, num_digits (9999999));
2092 ASSERT_EQ (8, num_digits (10000000));
2093 ASSERT_EQ (8, num_digits (99999999));
2094}
2095
a93eac6a
DM
2096/* Run all of the selftests within this file. */
2097
2098void
2099diagnostic_c_tests ()
2100{
2101 test_print_escaped_string ();
2102 test_print_parseable_fixits_none ();
2103 test_print_parseable_fixits_insert ();
2104 test_print_parseable_fixits_remove ();
2105 test_print_parseable_fixits_replace ();
ace72598 2106 test_diagnostic_get_location_text ();
bc65bad2
MG
2107 test_num_digits ();
2108
a93eac6a
DM
2109}
2110
2111} // namespace selftest
2112
2113#endif /* #if CHECKING_P */
0ecf545c
MS
2114
2115#if __GNUC__ >= 10
2116# pragma GCC diagnostic pop
2117#endif