OSDN Git Service

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