OSDN Git Service

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