1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999, 2000, 2001, 2002 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 2, 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 COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22
23 /* This file implements the language independent aspect of diagnostic
24 message module. */
25
26 #include "config.h"
27 #undef FLOAT /* This is for hpux. They should change hpux. */
28 #undef FFS /* Some systems define this in param.h. */
29 #include "system.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "flags.h"
33 #include "input.h"
34 #include "toplev.h"
35 #include "intl.h"
36 #include "diagnostic.h"
37 #include "langhooks.h"
38 #include "langhooks-def.h"
39
40 #define output_text_length(BUFFER) (BUFFER)->line_length
41 #define is_starting_newline(BUFFER) (output_text_length (BUFFER) == 0)
42 #define line_wrap_cutoff(BUFFER) (BUFFER)->state.maximum_length
43 #define prefix_was_emitted_for(BUFFER) (BUFFER)->state.emitted_prefix_p
44
45 /* Prototypes. */
46 static void output_flush PARAMS ((output_buffer *));
47 static void output_do_verbatim PARAMS ((output_buffer *, text_info *));
48 static void output_buffer_to_stream PARAMS ((output_buffer *));
49 static void output_format PARAMS ((output_buffer *, text_info *));
50 static void output_indent PARAMS ((output_buffer *));
51
52 static char *vbuild_message_string PARAMS ((const char *, va_list))
53 ATTRIBUTE_PRINTF (1, 0);
54 static char *build_message_string PARAMS ((const char *, ...))
55 ATTRIBUTE_PRINTF_1;
56 static void format_with_decl PARAMS ((output_buffer *, text_info *, tree));
57 static void diagnostic_for_decl PARAMS ((diagnostic_info *, tree));
58 static void set_real_maximum_length PARAMS ((output_buffer *));
59
60 static void output_unsigned_decimal PARAMS ((output_buffer *, unsigned int));
61 static void output_long_decimal PARAMS ((output_buffer *, long int));
62 static void output_long_unsigned_decimal PARAMS ((output_buffer *,
63 long unsigned int));
64 static void output_octal PARAMS ((output_buffer *, unsigned int));
65 static void output_long_octal PARAMS ((output_buffer *, unsigned long int));
66 static void output_hexadecimal PARAMS ((output_buffer *, unsigned int));
67 static void output_long_hexadecimal PARAMS ((output_buffer *,
68 unsigned long int));
69 static void output_pointer PARAMS ((output_buffer *, void *));
70 static void output_append_r PARAMS ((output_buffer *, const char *, int));
71 static void wrap_text PARAMS ((output_buffer *, const char *, const char *));
72 static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
73 const char *));
74 static void output_clear_data PARAMS ((output_buffer *));
75
76 static void default_diagnostic_starter PARAMS ((diagnostic_context *,
77 diagnostic_info *));
78 static void default_diagnostic_finalizer PARAMS ((diagnostic_context *,
79 diagnostic_info *));
80
81 static void error_recursion PARAMS ((diagnostic_context *)) ATTRIBUTE_NORETURN;
82 static bool text_specifies_location PARAMS ((text_info *, location_t *));
83
84 extern int rtl_dump_and_exit;
85 extern int warnings_are_errors;
86
87 /* A diagnostic_context surrogate for stderr. */
88 static diagnostic_context global_diagnostic_context;
89 diagnostic_context *global_dc = &global_diagnostic_context;
90
91
92 /* Subroutine of output_set_maximum_length. Set up BUFFER's
93 internal maximum characters per line. */
94 static void
set_real_maximum_length(buffer)95 set_real_maximum_length (buffer)
96 output_buffer *buffer;
97 {
98 /* If we're told not to wrap lines then do the obvious thing. In case
99 we'll emit prefix only once per diagnostic message, it is appropriate
100 not to increase unnecessarily the line-length cut-off. */
101 if (!output_is_line_wrapping (buffer)
102 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
103 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
104 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
105 else
106 {
107 int prefix_length = buffer->state.prefix ?
108 strlen (buffer->state.prefix) : 0;
109 /* If the prefix is ridiculously too long, output at least
110 32 characters. */
111 if (output_line_cutoff (buffer) - prefix_length < 32)
112 line_wrap_cutoff (buffer) = output_line_cutoff (buffer) + 32;
113 else
114 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
115 }
116 }
117
118 /* Sets the number of maximum characters per line BUFFER can output
119 in line-wrapping mode. A LENGTH value 0 suppresses line-wrapping. */
120 void
output_set_maximum_length(buffer,length)121 output_set_maximum_length (buffer, length)
122 output_buffer *buffer;
123 int length;
124 {
125 output_line_cutoff (buffer) = length;
126 set_real_maximum_length (buffer);
127 }
128
129 /* Sets BUFFER's PREFIX. */
130 void
output_set_prefix(buffer,prefix)131 output_set_prefix (buffer, prefix)
132 output_buffer *buffer;
133 const char *prefix;
134 {
135 buffer->state.prefix = prefix;
136 set_real_maximum_length (buffer);
137 prefix_was_emitted_for (buffer) = false;
138 output_indentation (buffer) = 0;
139 }
140
141 /* Return a pointer to the last character emitted in the output
142 BUFFER area. A NULL pointer means no character available. */
143 const char *
output_last_position(buffer)144 output_last_position (buffer)
145 const output_buffer *buffer;
146 {
147 const char *p = NULL;
148
149 if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
150 p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
151 return p;
152 }
153
154 /* Free BUFFER's prefix, a previously malloc'd string. */
155 void
output_destroy_prefix(buffer)156 output_destroy_prefix (buffer)
157 output_buffer *buffer;
158 {
159 if (buffer->state.prefix != NULL)
160 {
161 free ((char *) buffer->state.prefix);
162 buffer->state.prefix = NULL;
163 }
164 }
165
166 /* Zero out any text output so far in BUFFER. */
167 void
output_clear_message_text(buffer)168 output_clear_message_text (buffer)
169 output_buffer *buffer;
170 {
171 obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
172 output_text_length (buffer) = 0;
173 }
174
175 /* Zero out any formatting data used so far by BUFFER. */
176 static void
output_clear_data(buffer)177 output_clear_data (buffer)
178 output_buffer *buffer;
179 {
180 prefix_was_emitted_for (buffer) = false;
181 output_indentation (buffer) = 0;
182 }
183
184 /* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
185 characters per line. */
186 void
init_output_buffer(buffer,prefix,maximum_length)187 init_output_buffer (buffer, prefix, maximum_length)
188 output_buffer *buffer;
189 const char *prefix;
190 int maximum_length;
191 {
192 memset (buffer, 0, sizeof (output_buffer));
193 obstack_init (&buffer->obstack);
194 output_buffer_attached_stream (buffer) = stderr;
195 output_line_cutoff (buffer) = maximum_length;
196 output_prefixing_rule (buffer) = diagnostic_prefixing_rule (global_dc);
197 output_set_prefix (buffer, prefix);
198 output_text_length (buffer) = 0;
199 output_clear_data (buffer);
200 }
201
202 /* Reinitialize BUFFER. */
203 void
output_clear(buffer)204 output_clear (buffer)
205 output_buffer *buffer;
206 {
207 output_clear_message_text (buffer);
208 output_clear_data (buffer);
209 }
210
211 /* Finishes constructing a NULL-terminated character string representing
212 the BUFFERed message. */
213 const char *
output_finalize_message(buffer)214 output_finalize_message (buffer)
215 output_buffer *buffer;
216 {
217 obstack_1grow (&buffer->obstack, '\0');
218 return output_message_text (buffer);
219 }
220
221 /* Return the amount of characters BUFFER can accept to
222 make a full line. */
223 int
output_space_left(buffer)224 output_space_left (buffer)
225 const output_buffer *buffer;
226 {
227 return line_wrap_cutoff (buffer) - output_text_length (buffer);
228 }
229
230 /* Write out BUFFER's prefix. */
231 void
output_emit_prefix(buffer)232 output_emit_prefix (buffer)
233 output_buffer *buffer;
234 {
235 if (buffer->state.prefix != NULL)
236 {
237 switch (output_prefixing_rule (buffer))
238 {
239 default:
240 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
241 break;
242
243 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
244 if (prefix_was_emitted_for (buffer))
245 {
246 output_indent (buffer);
247 break;
248 }
249 output_indentation (buffer) += 3;
250 /* Fall through. */
251
252 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
253 {
254 int prefix_length = strlen (buffer->state.prefix);
255 output_append_r (buffer, buffer->state.prefix, prefix_length);
256 prefix_was_emitted_for (buffer) = true;
257 }
258 break;
259 }
260 }
261 }
262
263 /* Have BUFFER start a new line. */
264 void
output_add_newline(buffer)265 output_add_newline (buffer)
266 output_buffer *buffer;
267 {
268 obstack_1grow (&buffer->obstack, '\n');
269 output_text_length (buffer) = 0;
270 }
271
272 /* Appends a character to BUFFER. */
273 void
output_add_character(buffer,c)274 output_add_character (buffer, c)
275 output_buffer *buffer;
276 int c;
277 {
278 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
279 output_add_newline (buffer);
280 obstack_1grow (&buffer->obstack, c);
281 ++output_text_length (buffer);
282 }
283
284 /* Adds a space to BUFFER. */
285 void
output_add_space(buffer)286 output_add_space (buffer)
287 output_buffer *buffer;
288 {
289 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
290 {
291 output_add_newline (buffer);
292 return;
293 }
294 obstack_1grow (&buffer->obstack, ' ');
295 ++output_text_length (buffer);
296 }
297
298 /* These functions format an INTEGER into BUFFER as suggested by their
299 names. */
300 void
output_decimal(buffer,i)301 output_decimal (buffer, i)
302 output_buffer *buffer;
303 int i;
304 {
305 output_formatted_scalar (buffer, "%d", i);
306 }
307
308 static void
output_long_decimal(buffer,i)309 output_long_decimal (buffer, i)
310 output_buffer *buffer;
311 long int i;
312 {
313 output_formatted_scalar (buffer, "%ld", i);
314 }
315
316 static void
output_unsigned_decimal(buffer,i)317 output_unsigned_decimal (buffer, i)
318 output_buffer *buffer;
319 unsigned int i;
320 {
321 output_formatted_scalar (buffer, "%u", i);
322 }
323
324 static void
output_long_unsigned_decimal(buffer,i)325 output_long_unsigned_decimal (buffer, i)
326 output_buffer *buffer;
327 long unsigned int i;
328 {
329 output_formatted_scalar (buffer, "%lu", i);
330 }
331
332 static void
output_octal(buffer,i)333 output_octal (buffer, i)
334 output_buffer *buffer;
335 unsigned int i;
336 {
337 output_formatted_scalar (buffer, "%o", i);
338 }
339
340 static void
output_long_octal(buffer,i)341 output_long_octal (buffer, i)
342 output_buffer *buffer;
343 unsigned long int i;
344 {
345 output_formatted_scalar (buffer, "%lo", i);
346 }
347
348 static void
output_hexadecimal(buffer,i)349 output_hexadecimal (buffer, i)
350 output_buffer *buffer;
351 unsigned int i;
352 {
353 output_formatted_scalar (buffer, "%x", i);
354 }
355
356 static void
output_long_hexadecimal(buffer,i)357 output_long_hexadecimal (buffer, i)
358 output_buffer *buffer;
359 unsigned long int i;
360 {
361 output_formatted_scalar (buffer, "%lx", i);
362 }
363
364 static void
output_pointer(buffer,p)365 output_pointer (buffer, p)
366 output_buffer *buffer;
367 void *p;
368 {
369 output_formatted_scalar (buffer, HOST_PTR_PRINTF, p);
370 }
371
372 /* Append to BUFFER a string specified by its STARTING character
373 and LENGTH. */
374 static void
output_append_r(buffer,start,length)375 output_append_r (buffer, start, length)
376 output_buffer *buffer;
377 const char *start;
378 int length;
379 {
380 obstack_grow (&buffer->obstack, start, length);
381 output_text_length (buffer) += length;
382 }
383
384 /* Append a string deliminated by START and END to BUFFER. No wrapping is
385 done. However, if beginning a new line then emit BUFFER->state.prefix
386 and skip any leading whitespace if appropriate. The caller must ensure
387 that it is safe to do so. */
388 void
output_append(buffer,start,end)389 output_append (buffer, start, end)
390 output_buffer *buffer;
391 const char *start;
392 const char *end;
393 {
394 /* Emit prefix and skip whitespace if we're starting a new line. */
395 if (is_starting_newline (buffer))
396 {
397 output_emit_prefix (buffer);
398 if (output_is_line_wrapping (buffer))
399 while (start != end && *start == ' ')
400 ++start;
401 }
402 output_append_r (buffer, start, end - start);
403 }
404
405 static void
output_indent(buffer)406 output_indent (buffer)
407 output_buffer *buffer;
408 {
409 int n = output_indentation (buffer);
410 int i;
411
412 for (i = 0; i < n; ++i)
413 output_add_character (buffer, ' ');
414 }
415
416 /* Wrap a text delimited by START and END into BUFFER. */
417 static void
wrap_text(buffer,start,end)418 wrap_text (buffer, start, end)
419 output_buffer *buffer;
420 const char *start;
421 const char *end;
422 {
423 bool is_wrapping = output_is_line_wrapping (buffer);
424
425 while (start != end)
426 {
427 /* Dump anything bordered by whitespaces. */
428 {
429 const char *p = start;
430 while (p != end && *p != ' ' && *p != '\n')
431 ++p;
432 if (is_wrapping && p - start >= output_space_left (buffer))
433 output_add_newline (buffer);
434 output_append (buffer, start, p);
435 start = p;
436 }
437
438 if (start != end && *start == ' ')
439 {
440 output_add_space (buffer);
441 ++start;
442 }
443 if (start != end && *start == '\n')
444 {
445 output_add_newline (buffer);
446 ++start;
447 }
448 }
449 }
450
451 /* Same as wrap_text but wrap text only when in line-wrapping mode. */
452 static void
maybe_wrap_text(buffer,start,end)453 maybe_wrap_text (buffer, start, end)
454 output_buffer *buffer;
455 const char *start;
456 const char *end;
457 {
458 if (output_is_line_wrapping (buffer))
459 wrap_text (buffer, start, end);
460 else
461 output_append (buffer, start, end);
462 }
463
464
465 /* Append a STRING to BUFFER; the STRING might be line-wrapped if in
466 appropriate mode. */
467 void
output_add_string(buffer,str)468 output_add_string (buffer, str)
469 output_buffer *buffer;
470 const char *str;
471 {
472 maybe_wrap_text (buffer, str, str + (str ? strlen (str) : 0));
473 }
474
475 /* Append an identifier ID to BUFFER. */
476 void
output_add_identifier(buffer,id)477 output_add_identifier (buffer, id)
478 output_buffer *buffer;
479 tree id;
480 {
481 output_append (buffer, IDENTIFIER_POINTER (id),
482 IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id));
483 }
484
485 /* Flush the content of BUFFER onto the attached stream,
486 and reinitialize. */
487
488 static void
output_buffer_to_stream(buffer)489 output_buffer_to_stream (buffer)
490 output_buffer *buffer;
491 {
492 const char *text = output_finalize_message (buffer);
493 fputs (text, output_buffer_attached_stream (buffer));
494 output_clear_message_text (buffer);
495 }
496
497 /* Format a message pointed to by TEXT. The following format specifiers are
498 recognized as being language independent:
499 %d, %i: (signed) integer in base ten.
500 %u: unsigned integer in base ten.
501 %o: unsigned integer in base eight.
502 %x: unsigned integer in base sixteen.
503 %ld, %li, %lo, %lu, %lx: long versions of the above.
504 %c: character.
505 %s: string.
506 %p: pointer.
507 %%: `%'.
508 %*.s: a substring the length of which is specified by an integer.
509 %H: location_t. */
510 static void
output_format(buffer,text)511 output_format (buffer, text)
512 output_buffer *buffer;
513 text_info *text;
514 {
515 for (; *text->format_spec; ++text->format_spec)
516 {
517 bool long_integer = 0;
518
519 /* Ignore text. */
520 {
521 const char *p = text->format_spec;
522 while (*p && *p != '%')
523 ++p;
524 wrap_text (buffer, text->format_spec, p);
525 text->format_spec = p;
526 }
527
528 if (*text->format_spec == '\0')
529 break;
530
531 /* We got a '%'. Let's see what happens. Record whether we're
532 parsing a long integer format specifier. */
533 if (*++text->format_spec == 'l')
534 {
535 long_integer = true;
536 ++text->format_spec;
537 }
538
539 /* Handle %c, %d, %i, %ld, %li, %lo, %lu, %lx, %o, %s, %u,
540 %x, %.*s; %%. And nothing else. Front-ends should install
541 printers to grok language specific format specifiers. */
542 switch (*text->format_spec)
543 {
544 case 'c':
545 output_add_character (buffer, va_arg (*text->args_ptr, int));
546 break;
547
548 case 'd':
549 case 'i':
550 if (long_integer)
551 output_long_decimal (buffer, va_arg (*text->args_ptr, long int));
552 else
553 output_decimal (buffer, va_arg (*text->args_ptr, int));
554 break;
555
556 case 'o':
557 if (long_integer)
558 output_long_octal (buffer,
559 va_arg (*text->args_ptr, unsigned long int));
560 else
561 output_octal (buffer, va_arg (*text->args_ptr, unsigned int));
562 break;
563
564 case 's':
565 output_add_string (buffer, va_arg (*text->args_ptr, const char *));
566 break;
567
568 case 'p':
569 output_pointer (buffer, va_arg (*text->args_ptr, void *));
570 break;
571
572 case 'u':
573 if (long_integer)
574 output_long_unsigned_decimal
575 (buffer, va_arg (*text->args_ptr, long unsigned int));
576 else
577 output_unsigned_decimal
578 (buffer, va_arg (*text->args_ptr, unsigned int));
579 break;
580
581 case 'x':
582 if (long_integer)
583 output_long_hexadecimal
584 (buffer, va_arg (*text->args_ptr, unsigned long int));
585 else
586 output_hexadecimal
587 (buffer, va_arg (*text->args_ptr, unsigned int));
588 break;
589
590 case '%':
591 output_add_character (buffer, '%');
592 break;
593
594 case 'H':
595 {
596 const location_t *locus = va_arg (*text->args_ptr, location_t *);
597 output_add_string (buffer, "file '");
598 output_add_string (buffer, locus->file);
599 output_add_string (buffer, "', line ");
600 output_decimal (buffer, locus->line);
601 }
602 break;
603
604 case '.':
605 {
606 int n;
607 const char *s;
608 /* We handle no precision specifier but `%.*s'. */
609 if (*++text->format_spec != '*')
610 abort ();
611 else if (*++text->format_spec != 's')
612 abort ();
613 n = va_arg (*text->args_ptr, int);
614 s = va_arg (*text->args_ptr, const char *);
615 output_append (buffer, s, s + n);
616 }
617 break;
618
619 default:
620 if (!buffer->format_decoder
621 || !(*buffer->format_decoder) (buffer, text))
622 {
623 /* Hmmm. The front-end failed to install a format translator
624 but called us with an unrecognized format. Sorry. */
625 abort ();
626 }
627 }
628 }
629 }
630
631 static char *
vbuild_message_string(msg,ap)632 vbuild_message_string (msg, ap)
633 const char *msg;
634 va_list ap;
635 {
636 char *str;
637
638 vasprintf (&str, msg, ap);
639 return str;
640 }
641
642 /* Return a malloc'd string containing MSG formatted a la
643 printf. The caller is responsible for freeing the memory. */
644 static char *
build_message_string(const char * msg,...)645 build_message_string VPARAMS ((const char *msg, ...))
646 {
647 char *str;
648
649 VA_OPEN (ap, msg);
650 VA_FIXEDARG (ap, const char *, msg);
651
652 str = vbuild_message_string (msg, ap);
653
654 VA_CLOSE (ap);
655
656 return str;
657 }
658
659 /* Same as diagnsotic_build_prefix, but only the source FILE is given. */
660 char *
file_name_as_prefix(f)661 file_name_as_prefix (f)
662 const char *f;
663 {
664 return build_message_string ("%s: ", f);
665 }
666
667 /* Format a message into BUFFER a la printf. */
668 void
output_printf(struct output_buffer * buffer,const char * msgid,...)669 output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
670 {
671 text_info text;
672 VA_OPEN (ap, msgid);
673 VA_FIXEDARG (ap, output_buffer *, buffer);
674 VA_FIXEDARG (ap, const char *, msgid);
675
676 text.args_ptr = ≈
677 text.format_spec = _(msgid);
678 output_format (buffer, &text);
679 VA_CLOSE (ap);
680 }
681
682 /* Print a message relevant to the given DECL. */
683 static void
format_with_decl(buffer,text,decl)684 format_with_decl (buffer, text, decl)
685 output_buffer *buffer;
686 text_info *text;
687 tree decl;
688 {
689 const char *p;
690
691 /* Do magic to get around lack of varargs support for insertion
692 of arguments into existing list. We know that the decl is first;
693 we ass_u_me that it will be printed with "%s". */
694 for (p = text->format_spec; *p; ++p)
695 {
696 if (*p == '%')
697 {
698 if (*(p + 1) == '%')
699 ++p;
700 else if (*(p + 1) != 's')
701 abort ();
702 else
703 break;
704 }
705 }
706
707 /* Print the left-hand substring. */
708 maybe_wrap_text (buffer, text->format_spec, p);
709
710 if (*p == '%') /* Print the name. */
711 {
712 const char *const n = (DECL_NAME (decl)
713 ? (*lang_hooks.decl_printable_name) (decl, 2)
714 : _("((anonymous))"));
715 output_add_string (buffer, n);
716 while (*p)
717 {
718 ++p;
719 if (ISALPHA (*(p - 1) & 0xFF))
720 break;
721 }
722 }
723
724 if (*p) /* Print the rest of the message. */
725 {
726 text->format_spec = p;
727 output_format (buffer, text);
728 }
729 }
730
731 /* Flush the content of BUFFER onto the attached stream. */
732 static void
output_flush(buffer)733 output_flush (buffer)
734 output_buffer *buffer;
735 {
736 output_buffer_to_stream (buffer);
737 output_clear_data (buffer);
738 fputc ('\n', output_buffer_attached_stream (buffer));
739 fflush (output_buffer_attached_stream (buffer));
740 }
741
742 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
743 settings needed by BUFFER for a verbatim formatting. */
744 static void
output_do_verbatim(buffer,text)745 output_do_verbatim (buffer, text)
746 output_buffer *buffer;
747 text_info *text;
748 {
749 diagnostic_prefixing_rule_t rule = output_prefixing_rule (buffer);
750 int line_cutoff = output_line_cutoff (buffer);
751
752 /* Set verbatim mode. */
753 output_prefixing_rule (buffer) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
754 output_line_cutoff (buffer) = 0;
755 /* Do the actual formatting. */
756 output_format (buffer, text);
757 /* Restore previous settings. */
758 output_prefixing_rule (buffer) = rule;
759 output_line_cutoff (buffer) = line_cutoff;
760 }
761
762 /* Output MESSAGE verbatim into BUFFER. */
763 void
output_verbatim(output_buffer * buffer,const char * msgid,...)764 output_verbatim VPARAMS ((output_buffer *buffer, const char *msgid, ...))
765 {
766 text_info text;
767 VA_OPEN (ap, msgid);
768 VA_FIXEDARG (ap, output_buffer *, buffer);
769 VA_FIXEDARG (ap, const char *, msgid);
770
771 text.format_spec = msgid;
772 text.args_ptr = ≈
773 output_do_verbatim (buffer, &text);
774 VA_CLOSE (ap);
775 }
776
777
778 /* Initialize the diagnostic message outputting machinery. */
779 void
diagnostic_initialize(context)780 diagnostic_initialize (context)
781 diagnostic_context *context;
782 {
783 memset (context, 0, sizeof *context);
784 obstack_init (&context->buffer.obstack);
785
786 /* By default, diagnostics are sent to stderr. */
787 output_buffer_attached_stream (&context->buffer) = stderr;
788
789 /* By default, we emit prefixes once per message. */
790 diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
791
792 diagnostic_starter (context) = default_diagnostic_starter;
793 diagnostic_finalizer (context) = default_diagnostic_finalizer;
794 context->warnings_are_errors_message = warnings_are_errors;
795 }
796
797 /* Returns true if the next format specifier in TEXT is a format specifier
798 for a location_t. If so, update the object pointed by LOCUS to reflect
799 the specified location in *TEXT->args_ptr. */
800 static bool
text_specifies_location(text,locus)801 text_specifies_location (text, locus)
802 text_info *text;
803 location_t *locus;
804 {
805 const char *p;
806 /* Skip any leading text. */
807 for (p = text->format_spec; *p && *p != '%'; ++p)
808 ;
809
810 /* Extract the location information if any. */
811 if (*p == '%' && *++p == 'H')
812 {
813 *locus = *va_arg (*text->args_ptr, location_t *);
814 text->format_spec = p + 1;
815 return true;
816 }
817
818 return false;
819 }
820
821 void
diagnostic_set_info(diagnostic,msgid,args,file,line,kind)822 diagnostic_set_info (diagnostic, msgid, args, file, line, kind)
823 diagnostic_info *diagnostic;
824 const char *msgid;
825 va_list *args;
826 const char *file;
827 int line;
828 diagnostic_t kind;
829 {
830 diagnostic->message.format_spec = msgid;
831 diagnostic->message.args_ptr = args;
832 /* If the diagnostic message doesn't specify a loccation,
833 use FILE and LINE. */
834 if (!text_specifies_location (&diagnostic->message, &diagnostic->location))
835 {
836 diagnostic->location.file = file;
837 diagnostic->location.line = line;
838 }
839 diagnostic->kind = kind;
840 }
841
842 /* Return a malloc'd string describing a location. The caller is
843 responsible for freeing the memory. */
844 char *
diagnostic_build_prefix(diagnostic)845 diagnostic_build_prefix (diagnostic)
846 diagnostic_info *diagnostic;
847 {
848 static const char *const diagnostic_kind_text[] = {
849 #define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
850 #include "diagnostic.def"
851 #undef DEFINE_DIAGNOSTIC_KIND
852 "must-not-happen"
853 };
854 if (diagnostic->kind >= DK_LAST_DIAGNOSTIC_KIND)
855 abort();
856
857 return diagnostic->location.file
858 ? build_message_string ("%s:%d: %s",
859 diagnostic->location.file,
860 diagnostic->location.line,
861 _(diagnostic_kind_text[diagnostic->kind]))
862 : build_message_string ("%s: %s", progname,
863 _(diagnostic_kind_text[diagnostic->kind]));
864 }
865
866 /* Report a diagnostic MESSAGE at the declaration DECL.
867 MSG is a format string which uses %s to substitute the declaration
868 name; subsequent substitutions are a la output_format. */
869 static void
diagnostic_for_decl(diagnostic,decl)870 diagnostic_for_decl (diagnostic, decl)
871 diagnostic_info *diagnostic;
872 tree decl;
873 {
874 if (global_dc->lock++)
875 error_recursion (global_dc);
876
877 if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
878 {
879 diagnostic_report_current_function (global_dc);
880 output_set_prefix
881 (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
882 format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
883 output_flush (&global_dc->buffer);
884 output_destroy_prefix (&global_dc->buffer);
885 }
886 global_dc->lock--;
887 }
888
889 void
diagnostic_flush_buffer(context)890 diagnostic_flush_buffer (context)
891 diagnostic_context *context;
892 {
893 output_buffer_to_stream (&context->buffer);
894 fflush (output_buffer_attached_stream (&context->buffer));
895 }
896
897 /* Count a diagnostic. Return true if the message should be printed. */
898 bool
diagnostic_count_diagnostic(context,kind)899 diagnostic_count_diagnostic (context, kind)
900 diagnostic_context *context;
901 diagnostic_t kind;
902 {
903 switch (kind)
904 {
905 default:
906 abort();
907 break;
908
909 case DK_FATAL: case DK_ICE: case DK_SORRY:
910 case DK_ANACHRONISM: case DK_NOTE:
911 ++diagnostic_kind_count (context, kind);
912 break;
913
914 case DK_WARNING:
915 if (!diagnostic_report_warnings_p ())
916 return false;
917 else if (!warnings_are_errors)
918 {
919 ++diagnostic_kind_count (context, DK_WARNING);
920 break;
921 }
922 /* else fall through. */
923
924 case DK_ERROR:
925 if (kind == DK_WARNING && context->warnings_are_errors_message)
926 {
927 output_verbatim (&context->buffer,
928 "%s: warnings being treated as errors\n", progname);
929 context->warnings_are_errors_message = false;
930 }
931 ++diagnostic_kind_count (context, DK_ERROR);
932 break;
933 }
934
935 return true;
936 }
937
938 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
939 runs its second argument through gettext. */
940 void
fnotice(FILE * file,const char * msgid,...)941 fnotice VPARAMS ((FILE *file, const char *msgid, ...))
942 {
943 VA_OPEN (ap, msgid);
944 VA_FIXEDARG (ap, FILE *, file);
945 VA_FIXEDARG (ap, const char *, msgid);
946
947 vfprintf (file, _(msgid), ap);
948 VA_CLOSE (ap);
949 }
950
951
952 /* Print a fatal I/O error message. Argument are like printf.
953 Also include a system error message based on `errno'. */
954 void
fatal_io_error(const char * msgid,...)955 fatal_io_error VPARAMS ((const char *msgid, ...))
956 {
957 text_info text;
958 VA_OPEN (ap, msgid);
959 VA_FIXEDARG (ap, const char *, msgid);
960
961 text.format_spec = _(msgid);
962 text.args_ptr = ≈
963 output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
964 output_format (&global_dc->buffer, &text);
965 output_flush (&global_dc->buffer);
966 VA_CLOSE (ap);
967 exit (FATAL_EXIT_CODE);
968 }
969
970 /* Issue a pedantic warning MSGID. */
971 void
pedwarn(const char * msgid,...)972 pedwarn VPARAMS ((const char *msgid, ...))
973 {
974 diagnostic_info diagnostic;
975 VA_OPEN (ap, msgid);
976 VA_FIXEDARG (ap, const char *, msgid);
977
978 diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, lineno,
979 pedantic_error_kind ());
980 report_diagnostic (&diagnostic);
981 VA_CLOSE (ap);
982 }
983
984 /* Issue a pedantic warning about DECL. */
985 void
pedwarn_with_decl(tree decl,const char * msgid,...)986 pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
987 {
988 diagnostic_info diagnostic;
989 VA_OPEN (ap, msgid);
990 VA_FIXEDARG (ap, tree, decl);
991 VA_FIXEDARG (ap, const char *, msgid);
992
993 diagnostic_set_info (&diagnostic, _(msgid), &ap,
994 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
995 pedantic_error_kind ());
996
997 /* We don't want -pedantic-errors to cause the compilation to fail from
998 "errors" in system header files. Sometimes fixincludes can't fix what's
999 broken (eg: unsigned char bitfields - fixing it may change the alignment
1000 which will cause programs to mysteriously fail because the C library
1001 or kernel uses the original layout). There's no point in issuing a
1002 warning either, it's just unnecessary noise. */
1003 if (!DECL_IN_SYSTEM_HEADER (decl))
1004 diagnostic_for_decl (&diagnostic, decl);
1005 VA_CLOSE (ap);
1006 }
1007
1008 /* Same as above but within the context FILE and LINE. */
1009 void
pedwarn_with_file_and_line(const char * file,int line,const char * msgid,...)1010 pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
1011 const char *msgid, ...))
1012 {
1013 diagnostic_info diagnostic;
1014 VA_OPEN (ap, msgid);
1015 VA_FIXEDARG (ap, const char *, file);
1016 VA_FIXEDARG (ap, int, line);
1017 VA_FIXEDARG (ap, const char *, msgid);
1018
1019 diagnostic_set_info (&diagnostic, _(msgid), &ap, file, line,
1020 pedantic_error_kind ());
1021 report_diagnostic (&diagnostic);
1022 VA_CLOSE (ap);
1023 }
1024
1025 /* Just apologize with MSGID. */
1026 void
sorry(const char * msgid,...)1027 sorry VPARAMS ((const char *msgid, ...))
1028 {
1029 diagnostic_info diagnostic;
1030
1031 VA_OPEN (ap, msgid);
1032 VA_FIXEDARG (ap, const char *, msgid);
1033
1034 ++sorrycount;
1035 diagnostic_set_info (&diagnostic, _(msgid), &ap,
1036 input_filename, lineno, DK_SORRY);
1037
1038 output_set_prefix
1039 (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
1040 output_format (&global_dc->buffer, &diagnostic.message);
1041 output_flush (&global_dc->buffer);
1042 VA_CLOSE (ap);
1043 }
1044
1045 /* Called when the start of a function definition is parsed,
1046 this function prints on stderr the name of the function. */
1047 void
announce_function(decl)1048 announce_function (decl)
1049 tree decl;
1050 {
1051 if (!quiet_flag)
1052 {
1053 if (rtl_dump_and_exit)
1054 verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
1055 else
1056 verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
1057 fflush (stderr);
1058 output_needs_newline (&global_dc->buffer) = true;
1059 diagnostic_set_last_function (global_dc);
1060 }
1061 }
1062
1063 /* The default function to print out name of current function that caused
1064 an error. */
1065 void
lhd_print_error_function(context,file)1066 lhd_print_error_function (context, file)
1067 diagnostic_context *context;
1068 const char *file;
1069 {
1070 if (diagnostic_last_function_changed (context))
1071 {
1072 const char *old_prefix = output_prefix (&context->buffer);
1073 char *new_prefix = file ? build_message_string ("%s: ", file) : NULL;
1074
1075 output_set_prefix (&context->buffer, new_prefix);
1076
1077 if (current_function_decl == NULL)
1078 output_add_string (&context->buffer, _("At top level:"));
1079 else
1080 {
1081 if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
1082 output_printf
1083 (&context->buffer, "In member function `%s':",
1084 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
1085 else
1086 output_printf
1087 (&context->buffer, "In function `%s':",
1088 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
1089 }
1090 output_add_newline (&context->buffer);
1091
1092 diagnostic_set_last_function (context);
1093 output_buffer_to_stream (&context->buffer);
1094 context->buffer.state.prefix = old_prefix;
1095 free ((char*) new_prefix);
1096 }
1097 }
1098
1099 /* Prints out, if necessary, the name of the current function
1100 that caused an error. Called from all error and warning functions.
1101 We ignore the FILE parameter, as it cannot be relied upon. */
1102
1103 void
diagnostic_report_current_function(context)1104 diagnostic_report_current_function (context)
1105 diagnostic_context *context;
1106 {
1107 diagnostic_report_current_module (context);
1108 (*lang_hooks.print_error_function) (context, input_filename);
1109 }
1110
1111 void
error_with_file_and_line(const char * file,int line,const char * msgid,...)1112 error_with_file_and_line VPARAMS ((const char *file, int line,
1113 const char *msgid, ...))
1114 {
1115 diagnostic_info diagnostic;
1116
1117 VA_OPEN (ap, msgid);
1118 VA_FIXEDARG (ap, const char *, file);
1119 VA_FIXEDARG (ap, int, line);
1120 VA_FIXEDARG (ap, const char *, msgid);
1121
1122 diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_ERROR);
1123 report_diagnostic (&diagnostic);
1124 VA_CLOSE (ap);
1125 }
1126
1127 void
error_with_decl(tree decl,const char * msgid,...)1128 error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1129 {
1130 diagnostic_info diagnostic;
1131 VA_OPEN (ap, msgid);
1132 VA_FIXEDARG (ap, tree, decl);
1133 VA_FIXEDARG (ap, const char *, msgid);
1134
1135 diagnostic_set_info (&diagnostic, msgid, &ap,
1136 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
1137 DK_ERROR);
1138 diagnostic_for_decl (&diagnostic, decl);
1139 VA_CLOSE (ap);
1140 }
1141
1142
1143 /* Report an error message. The arguments are like that of printf. */
1144
1145 void
error(const char * msgid,...)1146 error VPARAMS ((const char *msgid, ...))
1147 {
1148 diagnostic_info diagnostic;
1149
1150 VA_OPEN (ap, msgid);
1151 VA_FIXEDARG (ap, const char *, msgid);
1152
1153 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
1154 DK_ERROR);
1155 report_diagnostic (&diagnostic);
1156 VA_CLOSE (ap);
1157 }
1158
1159 /* Likewise, except that the compilation is terminated after printing the
1160 error message. */
1161
1162 void
fatal_error(const char * msgid,...)1163 fatal_error VPARAMS ((const char *msgid, ...))
1164 {
1165 diagnostic_info diagnostic;
1166
1167 VA_OPEN (ap, msgid);
1168 VA_FIXEDARG (ap, const char *, msgid);
1169
1170 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
1171 DK_FATAL);
1172 report_diagnostic (&diagnostic);
1173 VA_CLOSE (ap);
1174
1175 fnotice (stderr, "compilation terminated.\n");
1176 exit (FATAL_EXIT_CODE);
1177 }
1178
1179 void
internal_error(const char * msgid,...)1180 internal_error VPARAMS ((const char *msgid, ...))
1181 {
1182 diagnostic_info diagnostic;
1183
1184 VA_OPEN (ap, msgid);
1185 VA_FIXEDARG (ap, const char *, msgid);
1186
1187 if (global_dc->lock)
1188 error_recursion (global_dc);
1189
1190 #ifndef ENABLE_CHECKING
1191 if (errorcount > 0 || sorrycount > 0)
1192 {
1193 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1194 input_filename, lineno);
1195 exit (FATAL_EXIT_CODE);
1196 }
1197 #endif
1198
1199 if (global_dc->internal_error != 0)
1200 (*global_dc->internal_error) (_(msgid), &ap);
1201
1202 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
1203 DK_ICE);
1204 report_diagnostic (&diagnostic);
1205 VA_CLOSE (ap);
1206
1207 fnotice (stderr,
1208 "Please submit a full bug report,\n\
1209 with preprocessed source if appropriate.\n\
1210 See %s for instructions.\n", bug_report_url);
1211 exit (FATAL_EXIT_CODE);
1212 }
1213
1214 void
warning_with_file_and_line(const char * file,int line,const char * msgid,...)1215 warning_with_file_and_line VPARAMS ((const char *file, int line,
1216 const char *msgid, ...))
1217 {
1218 diagnostic_info diagnostic;
1219
1220 VA_OPEN (ap, msgid);
1221 VA_FIXEDARG (ap, const char *, file);
1222 VA_FIXEDARG (ap, int, line);
1223 VA_FIXEDARG (ap, const char *, msgid);
1224
1225 diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_WARNING);
1226 report_diagnostic (&diagnostic);
1227 VA_CLOSE (ap);
1228 }
1229
1230 void
warning_with_decl(tree decl,const char * msgid,...)1231 warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1232 {
1233 diagnostic_info diagnostic;
1234 VA_OPEN (ap, msgid);
1235 VA_FIXEDARG (ap, tree, decl);
1236 VA_FIXEDARG (ap, const char *, msgid);
1237
1238 diagnostic_set_info (&diagnostic, msgid, &ap,
1239 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
1240 DK_WARNING);
1241 diagnostic_for_decl (&diagnostic, decl);
1242 VA_CLOSE (ap);
1243 }
1244
1245 void
warning(const char * msgid,...)1246 warning VPARAMS ((const char *msgid, ...))
1247 {
1248 diagnostic_info diagnostic;
1249
1250 VA_OPEN (ap, msgid);
1251 VA_FIXEDARG (ap, const char *, msgid);
1252
1253 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
1254 DK_WARNING);
1255 report_diagnostic (&diagnostic);
1256 VA_CLOSE (ap);
1257 }
1258
1259
1260 /* Same as above but use diagnostic_buffer. */
1261
1262 void
verbatim(const char * msgid,...)1263 verbatim VPARAMS ((const char *msgid, ...))
1264 {
1265 text_info text;
1266 VA_OPEN (ap, msgid);
1267 VA_FIXEDARG (ap, const char *, msgid);
1268
1269 text.format_spec = _(msgid);
1270 text.args_ptr = ≈
1271 output_do_verbatim (&global_dc->buffer, &text);
1272 output_buffer_to_stream (&global_dc->buffer);
1273 VA_CLOSE (ap);
1274 }
1275
1276 /* Report a diagnostic message (an error or a warning) as specified by
1277 DC. This function is *the* subroutine in terms of which front-ends
1278 should implement their specific diagnostic handling modules. The
1279 front-end independent format specifiers are exactly those described
1280 in the documentation of output_format. */
1281
1282 void
diagnostic_report_diagnostic(context,diagnostic)1283 diagnostic_report_diagnostic (context, diagnostic)
1284 diagnostic_context *context;
1285 diagnostic_info *diagnostic;
1286 {
1287 if (context->lock++)
1288 error_recursion (context);
1289
1290 if (diagnostic_count_diagnostic (context, diagnostic->kind))
1291 {
1292 (*diagnostic_starter (context)) (context, diagnostic);
1293 output_format (&context->buffer, &diagnostic->message);
1294 (*diagnostic_finalizer (context)) (context, diagnostic);
1295 output_flush (&context->buffer);
1296 }
1297
1298 --context->lock;
1299 }
1300
1301 /* Inform the user that an error occurred while trying to report some
1302 other error. This indicates catastrophic internal inconsistencies,
1303 so give up now. But do try to flush out the previous error.
1304 This mustn't use internal_error, that will cause infinite recursion. */
1305
1306 static void
error_recursion(context)1307 error_recursion (context)
1308 diagnostic_context *context;
1309 {
1310 if (context->lock < 3)
1311 output_flush (&context->buffer);
1312
1313 fnotice (stderr,
1314 "Internal compiler error: Error reporting routines re-entered.\n");
1315 fnotice (stderr,
1316 "Please submit a full bug report,\n\
1317 with preprocessed source if appropriate.\n\
1318 See %s for instructions.\n", bug_report_url);
1319 exit (FATAL_EXIT_CODE);
1320 }
1321
1322 /* Given a partial pathname as input, return another pathname that
1323 shares no directory elements with the pathname of __FILE__. This
1324 is used by fancy_abort() to print `Internal compiler error in expr.c'
1325 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1326
1327 const char *
trim_filename(name)1328 trim_filename (name)
1329 const char *name;
1330 {
1331 static const char this_file[] = __FILE__;
1332 const char *p = name, *q = this_file;
1333
1334 /* First skip any "../" in each filename. This allows us to give a proper
1335 reference to a file in a subdirectory. */
1336 while (p[0] == '.' && p[1] == '.'
1337 && (p[2] == DIR_SEPARATOR
1338 #ifdef DIR_SEPARATOR_2
1339 || p[2] == DIR_SEPARATOR_2
1340 #endif
1341 ))
1342 p += 3;
1343
1344 while (q[0] == '.' && q[1] == '.'
1345 && (q[2] == DIR_SEPARATOR
1346 #ifdef DIR_SEPARATOR_2
1347 || p[2] == DIR_SEPARATOR_2
1348 #endif
1349 ))
1350 q += 3;
1351
1352 /* Now skip any parts the two filenames have in common. */
1353 while (*p == *q && *p != 0 && *q != 0)
1354 p++, q++;
1355
1356 /* Now go backwards until the previous directory separator. */
1357 while (p > name && p[-1] != DIR_SEPARATOR
1358 #ifdef DIR_SEPARATOR_2
1359 && p[-1] != DIR_SEPARATOR_2
1360 #endif
1361 )
1362 p--;
1363
1364 return p;
1365 }
1366
1367 /* Report an internal compiler error in a friendly manner and without
1368 dumping core. */
1369
1370 void
fancy_abort(file,line,function)1371 fancy_abort (file, line, function)
1372 const char *file;
1373 int line;
1374 const char *function;
1375 {
1376 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
1377 }
1378
1379 void
diagnostic_report_current_module(context)1380 diagnostic_report_current_module (context)
1381 diagnostic_context *context;
1382 {
1383 struct file_stack *p;
1384
1385 if (output_needs_newline (&context->buffer))
1386 {
1387 output_add_newline (&context->buffer);
1388 output_needs_newline (&context->buffer) = false;
1389 }
1390
1391 if (input_file_stack && input_file_stack->next != 0
1392 && diagnostic_last_module_changed (context))
1393 {
1394 for (p = input_file_stack->next; p; p = p->next)
1395 if (p == input_file_stack->next)
1396 output_verbatim (&context->buffer,
1397 "In file included from %s:%d", p->name, p->line);
1398 else
1399 output_verbatim (&context->buffer,
1400 ",\n from %s:%d", p->name, p->line);
1401 output_verbatim (&context->buffer, ":\n");
1402 diagnostic_set_last_module (context);
1403 }
1404 }
1405
1406 static void
default_diagnostic_starter(context,diagnostic)1407 default_diagnostic_starter (context, diagnostic)
1408 diagnostic_context *context;
1409 diagnostic_info *diagnostic;
1410 {
1411 diagnostic_report_current_function (context);
1412 output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
1413 }
1414
1415 static void
default_diagnostic_finalizer(context,diagnostic)1416 default_diagnostic_finalizer (context, diagnostic)
1417 diagnostic_context *context;
1418 diagnostic_info *diagnostic __attribute__((unused));
1419 {
1420 output_destroy_prefix (&context->buffer);
1421 }
1422
1423 void
inform(const char * msgid,...)1424 inform VPARAMS ((const char *msgid, ...))
1425 {
1426 diagnostic_info diagnostic;
1427
1428 VA_OPEN (ap, msgid);
1429 VA_FIXEDARG (ap, const char *, msgid);
1430
1431 diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
1432 DK_NOTE);
1433 report_diagnostic (&diagnostic);
1434 VA_CLOSE (ap);
1435 }
1436
1437 void
warn_deprecated_use(node)1438 warn_deprecated_use (node)
1439 tree node;
1440 {
1441 if (node == 0 || !warn_deprecated_decl)
1442 return;
1443
1444 if (DECL_P (node))
1445 warning ("`%s' is deprecated (declared at %s:%d)",
1446 IDENTIFIER_POINTER (DECL_NAME (node)),
1447 DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
1448 else if (TYPE_P (node))
1449 {
1450 const char *what = NULL;
1451 tree decl = TYPE_STUB_DECL (node);
1452
1453 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
1454 what = IDENTIFIER_POINTER (TYPE_NAME (node));
1455 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
1456 && DECL_NAME (TYPE_NAME (node)))
1457 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
1458
1459 if (what)
1460 {
1461 if (decl)
1462 warning ("`%s' is deprecated (declared at %s:%d)", what,
1463 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1464 else
1465 warning ("`%s' is deprecated", what);
1466 }
1467 else if (decl)
1468 warning ("type is deprecated (declared at %s:%d)",
1469 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1470 else
1471 warning ("type is deprecated");
1472 }
1473 }
1474