OSDN Git Service

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