OSDN Git Service

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