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