OSDN Git Service

2000-07-09 Gabriel Dos Reis <gdr@codesourcery.com>
[pf3gnuchains/gcc-fork.git] / gcc / diagnostic.c
1 /* Language-independent diagnostic subroutines for the GNU C compiler
2    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21
22 /* This file implements the language independant aspect of diagnostic
23    message module.  */
24
25 #include "config.h"
26 #undef FLOAT /* This is for hpux. They should change hpux.  */
27 #undef FFS  /* Some systems define this in param.h.  */
28 #include "system.h"
29
30 #include "tree.h"
31 #include "rtl.h"
32 #include "tm_p.h"
33 #include "flags.h"
34 #include "input.h"
35 #include "insn-attr.h"
36 #include "insn-codes.h"
37 #include "insn-config.h"
38 #include "toplev.h"
39 #include "intl.h"
40 #include "diagnostic.h"
41
42 #define obstack_chunk_alloc xmalloc
43 #define obstack_chunk_free  free
44
45 #define diagnostic_args diagnostic_buffer->format_args
46 #define diagnostic_msg diagnostic_buffer->cursor
47
48 #define output_formatted_integer(BUFFER, FORMAT, INTEGER) \
49   do {                                                    \
50     sprintf (digit_buffer, FORMAT, INTEGER);              \
51     output_add_string (BUFFER, digit_buffer);             \
52   } while (0)
53
54 /* This data structure serves to save/restore an output_buffer state.  */
55 typedef struct
56 {
57   const char *prefix;
58   int maximum_length;
59   int ideal_maximum_length;
60   int emitted_prefix_p;
61   int prefixing_rule;
62   const char *cursor;
63   va_list format_args;
64 } output_state;
65
66
67 /* Prototypes. */
68 static int doing_line_wrapping PARAMS ((void));
69
70 static void output_do_verbatim PARAMS ((output_buffer *));
71 static void output_to_stream PARAMS ((output_buffer *, FILE *));
72 static void output_format PARAMS ((output_buffer *));
73
74 static char *vbuild_message_string PARAMS ((const char *, va_list));
75 static char *build_message_string PARAMS ((const char *, ...))
76      ATTRIBUTE_PRINTF_1;
77 static char *context_as_prefix PARAMS ((const char *, int, int));
78 static void output_do_printf PARAMS ((output_buffer *, const char *));
79 static void line_wrapper_printf PARAMS ((FILE *, const char *, ...))
80      ATTRIBUTE_PRINTF_2;
81 static void vline_wrapper_message_with_location PARAMS ((const char *, int,
82                                                          int, const char *,
83                                                          va_list));
84 static void notice PARAMS ((const char *s, ...)) ATTRIBUTE_PRINTF_1;
85 static void v_message_with_file_and_line PARAMS ((const char *, int, int,
86                                                   const char *, va_list));
87 static void v_message_with_decl PARAMS ((tree, int, const char *, va_list));
88 static void file_and_line_for_asm PARAMS ((rtx, const char **, int *));
89 static void v_error_with_file_and_line PARAMS ((const char *, int,
90                                                 const char *, va_list));
91 static void v_error_with_decl PARAMS ((tree, const char *, va_list));
92 static void v_error_for_asm PARAMS ((rtx, const char *, va_list));
93 static void vfatal PARAMS ((const char *, va_list)) ATTRIBUTE_NORETURN;
94 static void v_warning_with_file_and_line PARAMS ((const char *, int,
95                                                   const char *, va_list));
96 static void v_warning_with_decl PARAMS ((tree, const char *, va_list));
97 static void v_warning_for_asm PARAMS ((rtx, const char *, va_list));
98 static void v_pedwarn_with_decl PARAMS ((tree, const char *, va_list));
99 static void v_pedwarn_with_file_and_line PARAMS ((const char *, int,
100                                                   const char *, va_list));
101 static void vsorry PARAMS ((const char *, va_list));
102 static void report_file_and_line PARAMS ((const char *, int, int));
103 static void vnotice PARAMS ((FILE *, const char *, va_list));
104 static void set_real_maximum_length PARAMS ((output_buffer *));
105
106 static void save_output_state PARAMS ((const output_buffer *, output_state *));
107 static void restore_output_state PARAMS ((const output_state *,
108                                           output_buffer *));
109                                           
110 static void output_unsigned_decimal PARAMS ((output_buffer *, unsigned int));
111 static void output_long_decimal PARAMS ((output_buffer *, long int));
112 static void output_long_unsigned_decimal PARAMS ((output_buffer *,
113                                                   long unsigned int));
114 static void output_octal PARAMS ((output_buffer *, int));
115 static void output_long_octal PARAMS ((output_buffer *, long int));
116 static void output_hexadecimal PARAMS ((output_buffer *, int));
117 static void output_long_hexadecimal PARAMS ((output_buffer *, long int));
118 static void output_append_r PARAMS ((output_buffer *, const char *, int));
119
120 extern int rtl_dump_and_exit;
121 extern int inhibit_warnings;
122 extern int warnings_are_errors;
123 extern int warningcount;
124 extern int errorcount;
125
126 /* Front-end specific tree formatter, if non-NULL.  */
127 printer_fn lang_printer = NULL;
128
129 /* This must be large enough to hold any printed integer or
130    floating-point value.  */
131 static char digit_buffer[128];
132
133 /* An output_buffer surrogate for stderr.  */
134 static output_buffer global_output_buffer;
135 output_buffer *diagnostic_buffer = &global_output_buffer;
136
137 static int need_error_newline;
138
139 /* Function of last error message;
140    more generally, function such that if next error message is in it
141    then we don't have to mention the function name.  */
142 static tree last_error_function = NULL;
143
144 /* Used to detect when input_file_stack has changed since last described.  */
145 static int last_error_tick;
146
147 /* Called by report_error_function to print out function name.
148  * Default may be overridden by language front-ends.  */
149
150 void (*print_error_function) PARAMS ((const char *)) =
151   default_print_error_function;
152
153 /* Maximum characters per line in automatic line wrapping mode.
154    Zero means don't wrap lines. */
155
156 int diagnostic_message_length_per_line;
157
158 /* Used to control every diagnostic message formatting.  Front-ends should
159    call set_message_prefixing_rule to set up their politics.  */
160 static int current_prefixing_rule;
161 \f
162 /* Initialize the diagnostic message outputting machinery.  */
163
164 void
165 initialize_diagnostics ()
166 {
167   /* By default, we don't line-wrap messages.  */
168   diagnostic_message_length_per_line = 0;
169   set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
170   /* Proceed to actual initialization.  */
171   default_initialize_buffer (diagnostic_buffer);
172 }
173
174 /* Predicate. Return 1 if we're in automatic line wrapping mode.  */
175
176 static int
177 doing_line_wrapping ()
178 {
179   return diagnostic_message_length_per_line > 0;
180 }
181
182 void
183 set_message_prefixing_rule (rule)
184      int rule;
185 {
186   current_prefixing_rule = rule;
187 }
188
189 /* Returns true if BUFFER is in line-wrappind mode.  */
190 int
191 output_is_line_wrapping (buffer)
192      output_buffer *buffer;
193 {
194   return buffer->ideal_maximum_length > 0;
195 }
196
197 /* Return BUFFER's prefix.  */
198 const char *
199 output_get_prefix (buffer)
200      const output_buffer *buffer;
201 {
202   return buffer->prefix;
203 }
204
205 /* Subroutine of output_set_maximum_length.  Set up BUFFER's
206    internal maximum characters per line.  */
207 static void
208 set_real_maximum_length (buffer)
209      output_buffer *buffer;
210 {
211   /* If we're told not to wrap lines then do the obvious thing.  */
212   if (! output_is_line_wrapping (buffer))
213     buffer->maximum_length = buffer->ideal_maximum_length;
214   else
215     {
216       int prefix_length = buffer->prefix ? strlen (buffer->prefix) : 0;
217       /* If the prefix is ridiculously too long, output at least
218          32 characters.  */
219       if (buffer->ideal_maximum_length - prefix_length < 32)
220         buffer->maximum_length = buffer->ideal_maximum_length + 32;
221       else
222         buffer->maximum_length = buffer->ideal_maximum_length;
223     }
224 }
225
226 /* Sets the number of maximum characters per line BUFFER can output
227    in line-wrapping mode.  A LENGTH value 0 suppresses line-wrapping.  */
228 void
229 output_set_maximum_length (buffer, length)
230      output_buffer *buffer;
231      int length;
232 {
233   buffer->ideal_maximum_length = length;
234   set_real_maximum_length (buffer);
235 }
236
237 /* Sets BUFFER's PREFIX.  */
238 void
239 output_set_prefix (buffer, prefix)
240      output_buffer *buffer;
241      const char *prefix;
242 {
243   buffer->prefix = prefix;
244   set_real_maximum_length (buffer);
245   buffer->emitted_prefix_p = 0;
246 }
247
248 /* Free BUFFER's prefix, a previously malloc()'d string.  */
249
250 void
251 output_destroy_prefix (buffer)
252      output_buffer *buffer;
253 {
254   if (buffer->prefix)
255     {
256       free ((char *) buffer->prefix);
257       buffer->prefix = NULL;
258     }
259 }
260
261 /* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
262    characters per line.  */
263 void
264 init_output_buffer (buffer, prefix, maximum_length)
265      output_buffer *buffer;
266      const char *prefix;
267      int maximum_length;
268 {
269   obstack_init (&buffer->obstack);
270   buffer->ideal_maximum_length = maximum_length;
271   buffer->line_length = 0;
272   output_set_prefix (buffer, prefix);
273   buffer->emitted_prefix_p = 0;
274   buffer->prefixing_rule = current_prefixing_rule;
275   
276   buffer->cursor = NULL;
277 }
278
279 /* Initialize BUFFER with a NULL prefix and current diagnostic message
280    length cutoff.  */
281 void
282 default_initialize_buffer (buffer)
283      output_buffer *buffer;
284 {
285   init_output_buffer (buffer, NULL, diagnostic_message_length_per_line);
286 }
287
288 /* Recompute diagnostic_buffer's attributes to reflect any change
289    in diagnostic formatting global options.  */
290 void
291 reshape_diagnostic_buffer ()
292 {
293   diagnostic_buffer->ideal_maximum_length = diagnostic_message_length_per_line;
294   diagnostic_buffer->prefixing_rule = current_prefixing_rule;
295   set_real_maximum_length (diagnostic_buffer);
296 }
297
298 /* Reinitialize BUFFER.  */
299 void
300 output_clear (buffer)
301      output_buffer *buffer;
302 {
303   obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
304   buffer->line_length = 0;
305   buffer->cursor = NULL;
306   buffer->emitted_prefix_p = 0;
307 }
308
309 /* Finishes to construct a NULL-terminated character string representing
310    the BUFFERed message.  */
311 const char *
312 output_finish (buffer)
313      output_buffer *buffer;
314 {
315   obstack_1grow (&buffer->obstack, '\0');
316   return (const char *) obstack_finish (&buffer->obstack);
317 }
318
319 /* Return the amount of characters BUFFER can accept to
320    make a full line.  */
321 int
322 output_space_left (buffer)
323      const output_buffer *buffer;
324 {
325   return buffer->maximum_length - buffer->line_length;
326 }
327
328 /* Write out BUFFER's prefix.  */
329 void
330 output_emit_prefix (buffer)
331      output_buffer *buffer;
332 {
333   if (buffer->prefix)
334     {
335       switch (buffer->prefixing_rule)
336         {
337         default:
338         case DIAGNOSTICS_SHOW_PREFIX_NEVER:
339           break;
340
341         case DIAGNOSTICS_SHOW_PREFIX_ONCE:
342           if (buffer->emitted_prefix_p)
343             break;
344           else
345             buffer->emitted_prefix_p = 1;
346           /* Fall through.  */
347
348         case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
349           buffer->line_length += strlen (buffer->prefix);
350           obstack_grow
351             (&buffer->obstack, buffer->prefix, buffer->line_length);
352           break;
353         }
354     }
355 }
356
357 /* Have BUFFER start a new line.  */
358 void
359 output_add_newline (buffer)
360      output_buffer *buffer;
361 {
362   obstack_1grow (&buffer->obstack, '\n');
363   buffer->line_length = 0;
364 }
365
366 /* Appends a character to BUFFER.  */
367 void
368 output_add_character (buffer, c)
369      output_buffer *buffer;
370      int c;
371 {
372   if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
373     output_add_newline (buffer);
374   obstack_1grow (&buffer->obstack, c);
375   ++buffer->line_length;
376 }
377
378 /* Adds a space to BUFFER.  */
379 void
380 output_add_space (buffer)
381      output_buffer *buffer;
382 {
383   if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
384     {
385       output_add_newline (buffer);
386       return;
387     }
388   obstack_1grow (&buffer->obstack, ' ');
389   ++buffer->line_length;
390 }
391
392 /* These functions format an INTEGER into BUFFER as suggested by their
393    names.  */
394 void
395 output_decimal (buffer, i)
396      output_buffer *buffer;
397      int i;
398 {
399   output_formatted_integer (buffer, "%d", i);
400 }
401
402 static void
403 output_long_decimal (buffer, i)
404      output_buffer *buffer;
405      long int i;
406 {
407   output_formatted_integer (buffer, "%ld", i);
408 }
409
410 static void
411 output_unsigned_decimal (buffer, i)
412      output_buffer *buffer;
413      unsigned int i;
414 {
415   output_formatted_integer (buffer, "%u", i);
416 }
417
418 static void
419 output_long_unsigned_decimal (buffer, i)
420      output_buffer *buffer;
421      long unsigned int i;
422 {
423   output_formatted_integer (buffer, "%lu", i);
424 }
425
426 static void
427 output_octal (buffer, i)
428      output_buffer *buffer;
429      int i;
430 {
431   output_formatted_integer (buffer, "%o", i);
432 }
433
434 static void
435 output_long_octal (buffer, i)
436      output_buffer *buffer;
437      long int i;
438 {
439   output_formatted_integer (buffer, "%lo", i);
440 }
441
442 static void
443 output_hexadecimal (buffer, i)
444      output_buffer *buffer;
445      int i;
446 {
447   output_formatted_integer (buffer, "%x", i);
448 }
449
450 static void
451 output_long_hexadecimal (buffer, i)
452      output_buffer *buffer;
453      long int i;
454 {
455   output_formatted_integer (buffer, "%lx", i);
456 }
457
458 /* Append to BUFFER a string specified by its STARTING character
459    and LENGTH.  */
460 static void
461 output_append_r (buffer, start, length)
462      output_buffer *buffer;
463      const char *start;
464      int length;
465 {
466   obstack_grow (&buffer->obstack, start, length);
467   buffer->line_length += length;
468 }
469
470 /* Append a string deliminated by START and END to BUFFER.  No wrapping is
471    done.  However, if beginning a new line then emit BUFFER->PREFIX and
472    skip any leading whitespace if appropriate.  The caller must ensure
473    that it is safe to do so.  */
474 void
475 output_append (buffer, start, end)
476      output_buffer *buffer;
477      const char *start;
478      const char *end;
479 {
480   /* Emit prefix and skip whitespace if we're starting a new line.  */
481   if (buffer->line_length == 0)
482     {
483       output_emit_prefix (buffer);
484       if (output_is_line_wrapping (buffer))
485         while (start != end && *start == ' ')
486           ++start;
487     }
488   output_append_r (buffer, start, end - start);
489 }
490
491 /* Wrap a STRing into BUFFER.  */
492
493 void
494 output_add_string (buffer, str)
495      output_buffer *buffer;
496      const char *str;
497 {
498   const char *p = str;
499
500   if (!output_is_line_wrapping (buffer))
501     output_append (buffer, str, str + strlen (str));
502   else while (*str)
503     {
504       while (*p && *p != ' ' && *p != '\n')
505         ++p;
506       
507       if (p - str < output_space_left (buffer))
508         output_append (buffer, str, p);
509       else
510         {
511           output_add_newline (buffer);
512           output_append (buffer, str, p);
513         }
514       
515       while (*p && *p == '\n')
516         {
517           output_add_newline (buffer);
518           ++p;
519         }
520
521       str = p++;
522     }
523 }
524
525 /* Flush the content of BUFFER onto FILE and reinitialize BUFFER.  */
526
527 static void
528 output_to_stream (buffer, file)
529      output_buffer *buffer;
530      FILE *file;
531 {
532   const char *text = output_finish (buffer);
533   fputs (text, file);
534   output_clear (buffer);
535 }
536
537 /* Format a message pointed to by BUFFER->CURSOR using BUFFER->CURSOR
538    as appropriate.  The following format specifiers are recognized as
539    being language independent:
540    %d, %i: (signed) integer in base ten.
541    %u: unsigned integer in base ten.
542    %o: (signed) integer in base eight.
543    %x: (signged) integer in base sixteen.
544    %ld, %li, %lo, %lu, %lx: long versions of the above.
545    %c: character.
546    %s: string.
547    %%: `%'.
548    %*.s: a substring the length of which is specified by an integer.  */
549 static void
550 output_format (buffer)
551      output_buffer *buffer;
552 {
553   const char *msg = buffer->cursor;
554   for (; *buffer->cursor; ++buffer->cursor)
555     {
556       int long_integer = 0;
557       /* Ignore text.  */
558       if (*buffer->cursor != '%')
559         {
560           output_add_character (buffer, *buffer->cursor);
561           continue;
562         }
563
564       /* We got a '%'.  Let's see what happens. Record whether we're
565          parsing a long integer format specifier.  */
566       if (*++buffer->cursor == 'l')
567         {
568           long_integer = 1;
569           ++buffer->cursor;
570         }
571
572       /* Handle %c, %d, %i, %ld, %li, %lo, %lu, %lx, %o, %s, %u,
573          %x, %.*s; %%.  And nothing else.  Front-ends should install
574          printers to grok language specific format specifiers.  */
575       switch (*buffer->cursor)
576         {
577         case 'c':
578           output_add_character
579             (buffer, va_arg (buffer->format_args, int));
580           break;
581           
582         case 'd':
583         case 'i':
584           if (long_integer)
585             output_long_decimal
586               (buffer, va_arg (buffer->format_args, long int));
587           else
588             output_decimal (buffer, va_arg (buffer->format_args, int));
589           break;
590
591         case 'o':
592           if (long_integer)
593             output_long_octal
594               (buffer, va_arg (buffer->format_args, long int));
595           else
596             output_octal (buffer, va_arg (buffer->format_args, int));
597           break;
598
599         case 's':
600           output_add_string
601             (buffer, va_arg (buffer->format_args, const char *));
602           break;
603
604         case 'u':
605           if (long_integer)
606             output_long_unsigned_decimal
607               (buffer, va_arg (buffer->format_args, long unsigned int));
608           else
609             output_unsigned_decimal
610               (buffer, va_arg (buffer->format_args, unsigned int));
611           
612         case 'x':
613           if (long_integer)
614             output_long_hexadecimal
615               (buffer, va_arg (buffer->format_args, long int));
616           else
617             output_hexadecimal (buffer, va_arg (buffer->format_args, int));
618           break;
619
620         case '%':
621           output_add_character (buffer, '%');
622           break;
623
624         case '.':
625           {
626             int n;
627             /* We handle no precision specifier but `%.*s'.  */
628             if (*++buffer->cursor != '*')
629               abort ();
630             else if (*++buffer->cursor != 's')
631               abort();
632             n = va_arg (buffer->format_args, int);
633             output_append (buffer, msg, msg + n);
634           }
635           break;
636
637         default:
638           if (!lang_printer || !(*lang_printer) (buffer))
639             {
640               /* Hmmm.  The front-end failed to install a format translator
641                  but called us with an unrecognized format.  Sorry.  */
642               abort();
643             }
644         }
645     }
646   output_finish (buffer);
647 }
648
649 static char *
650 vbuild_message_string (msgid, ap)
651      const char *msgid;
652      va_list ap;
653 {
654   char *str;
655
656   vasprintf (&str, msgid, ap);
657   return str;
658 }
659
660 /*  Return a malloc'd string containing MSGID formatted a la
661     printf.  The caller is reponsible for freeing the memory.  */
662
663 static char *
664 build_message_string VPARAMS ((const char *msgid, ...))
665 {
666 #ifndef ANSI_PROTOTYPES
667   const char *msgid;
668 #endif
669   va_list ap;
670   char *str;
671
672   VA_START (ap, msgid);
673
674 #ifndef ANSI_PROTOTYPES
675   msgid = va_arg (ap, const char *);
676 #endif
677
678   str = vbuild_message_string (msgid, ap);
679
680   va_end (ap);
681
682   return str;
683 }
684
685
686 /* Return a malloc'd string describing a location.  The caller is
687    responsible for freeing the memory.  */
688
689 static char *
690 context_as_prefix (file, line, warn)
691      const char *file;
692      int line;
693      int warn;
694 {
695   if (file)
696     {
697       if (warn)
698         return build_message_string ("%s:%d: warning: ", file, line);
699       else
700         return build_message_string ("%s:%d: ", file, line);
701     }
702   else
703     {
704       if (warn)
705         return build_message_string ("%s: warning: ", progname);
706       else
707         return build_message_string ("%s: ", progname);
708     }
709 }
710
711 /* Format a MESSAGE into BUFFER.  Automatically wrap lines.  */
712
713 static void
714 output_do_printf (buffer, msgid)
715      output_buffer *buffer;
716      const char *msgid;
717 {
718   char *message = vbuild_message_string (msgid, buffer->format_args);
719
720   output_add_string (buffer, message);
721   free (message);
722 }
723
724
725 /* Format a message into BUFFER a la printf.  */
726
727 void
728 output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
729 {
730 #ifndef ANSI_PROTOTYPES
731   struct output_buffer *buffer;
732   const char *msgid;
733 #endif
734   va_list ap;
735   va_list old_args;
736
737   VA_START (ap, msgid);
738 #ifndef ANSI_PROTOTYPES
739   buffer = va_arg (ap, struct output_buffer *);
740   msgid = va_arg (ap, const char *);
741 #endif
742   va_copy (old_args, buffer->format_args);
743
744   va_copy (buffer->format_args, ap);
745   output_do_printf (buffer, msgid);
746   va_end (buffer->format_args);
747
748   va_copy (buffer->format_args, old_args);
749 }
750
751
752 /* Format a MESSAGE into FILE.  Do line wrapping, starting new lines
753    with PREFIX.  */
754
755 static void
756 line_wrapper_printf VPARAMS ((FILE *file, const char *msgid, ...))
757 {
758 #ifndef ANSI_PROTOTYPES
759   FILE *file;
760   const char *msgid;
761 #endif
762   output_buffer buffer;
763   
764   default_initialize_buffer (&buffer);
765   VA_START (buffer.format_args, msgid);
766
767 #ifndef ANSI_PROTOTYPES
768   file = va_arg (buffer.format_args, FILE *);
769   msgid = va_arg (buffer.format_args, const char *);
770 #endif  
771
772   output_do_printf (&buffer, msgid);
773   output_to_stream (&buffer, file);
774
775   va_end (buffer.format_args);
776 }
777
778
779 static void
780 vline_wrapper_message_with_location (file, line, warn, msgid, ap)
781      const char *file;
782      int line;
783      int warn;
784      const char *msgid;
785      va_list ap;
786 {
787   output_buffer buffer;
788   
789   init_output_buffer (&buffer, context_as_prefix (file, line, warn),
790                       diagnostic_message_length_per_line);
791   va_copy (buffer.format_args, ap);
792   output_do_printf (&buffer, msgid);
793   output_to_stream (&buffer, stderr);
794
795   output_destroy_prefix (&buffer);
796   fputc ('\n', stderr);
797 }
798
799
800 /* Print the message MSGID in FILE.  */
801
802 static void
803 vnotice (file, msgid, ap)
804      FILE *file;
805      const char *msgid;
806      va_list ap;
807 {
808   vfprintf (file, _(msgid), ap);
809 }
810
811 /* Print MSGID on stderr.  */
812
813 static void
814 notice VPARAMS ((const char *msgid, ...))
815 {
816 #ifndef ANSI_PROTOTYPES
817   char *msgid;
818 #endif
819   va_list ap;
820
821   VA_START (ap, msgid);
822
823 #ifndef ANSI_PROTOTYPES
824   msgid = va_arg (ap, char *);
825 #endif
826
827   vnotice (stderr, msgid, ap);
828   va_end (ap);
829 }
830
831 /* Report FILE and LINE (or program name), and optionally just WARN.  */
832
833 static void
834 report_file_and_line (file, line, warn)
835      const char *file;
836      int line;
837      int warn;
838 {
839   if (file)
840     fprintf (stderr, "%s:%d: ", file, line);
841   else
842     fprintf (stderr, "%s: ", progname);
843
844   if (warn)
845     notice ("warning: ");
846 }
847
848 /* Print a message relevant to line LINE of file FILE.  */
849
850 static void
851 v_message_with_file_and_line (file, line, warn, msgid, ap)
852      const char *file;
853      int line;
854      int warn;
855      const char *msgid;
856      va_list ap;
857 {
858   report_file_and_line (file, line, warn);
859   vnotice (stderr, msgid, ap);
860   fputc ('\n', stderr);
861 }
862
863 /* Print a message relevant to the given DECL.  */
864
865 static void
866 v_message_with_decl (decl, warn, msgid, ap)
867      tree decl;
868      int warn;
869      const char *msgid;
870      va_list ap;
871 {
872   const char *p;
873   output_buffer buffer;
874
875   if (doing_line_wrapping ())
876     {
877       init_output_buffer
878         (&buffer, context_as_prefix
879          (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn),
880          diagnostic_message_length_per_line);
881     }
882   else
883     report_file_and_line (DECL_SOURCE_FILE (decl),
884                           DECL_SOURCE_LINE (decl), warn);
885
886   /* Do magic to get around lack of varargs support for insertion
887      of arguments into existing list.  We know that the decl is first;
888      we ass_u_me that it will be printed with "%s".  */
889
890   for (p = _(msgid); *p; ++p)
891     {
892       if (*p == '%')
893         {
894           if (*(p + 1) == '%')
895             ++p;
896           else if (*(p + 1) != 's')
897             abort ();
898           else
899             break;
900         }
901     }
902
903   if (p > _(msgid))                     /* Print the left-hand substring.  */
904     {
905       if (doing_line_wrapping ())
906         output_printf (&buffer, "%.*s", (int)(p - _(msgid)), _(msgid));
907       else
908         fprintf (stderr, "%.*s", (int)(p - _(msgid)), _(msgid));
909     }
910
911   if (*p == '%')                /* Print the name.  */
912     {
913       const char *n = (DECL_NAME (decl)
914                  ? (*decl_printable_name) (decl, 2)
915                  : _("((anonymous))"));
916       if (doing_line_wrapping ())
917         output_add_string (&buffer, n);
918       else
919         fputs (n, stderr);
920       while (*p)
921         {
922           ++p;
923           if (ISALPHA (*(p - 1) & 0xFF))
924             break;
925         }
926     }
927
928   if (*p)                       /* Print the rest of the message.  */
929     {
930       if (doing_line_wrapping ())
931         {
932           va_copy (buffer.format_args, ap);
933           output_do_printf (&buffer, p);
934           va_copy (ap, buffer.format_args);
935         }
936       else
937         vfprintf (stderr, p, ap);
938     }
939
940   if (doing_line_wrapping())
941     {
942       output_to_stream (&buffer, stderr);
943       output_destroy_prefix (&buffer);
944     }
945   
946   fputc ('\n', stderr);
947 }
948
949 /* Figure file and line of the given INSN.  */
950
951 static void
952 file_and_line_for_asm (insn, pfile, pline)
953      rtx insn;
954      const char **pfile;
955      int *pline;
956 {
957   rtx body = PATTERN (insn);
958   rtx asmop;
959
960   /* Find the (or one of the) ASM_OPERANDS in the insn.  */
961   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
962     asmop = SET_SRC (body);
963   else if (GET_CODE (body) == ASM_OPERANDS)
964     asmop = body;
965   else if (GET_CODE (body) == PARALLEL
966            && GET_CODE (XVECEXP (body, 0, 0)) == SET)
967     asmop = SET_SRC (XVECEXP (body, 0, 0));
968   else if (GET_CODE (body) == PARALLEL
969            && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
970     asmop = XVECEXP (body, 0, 0);
971   else
972     asmop = NULL;
973
974   if (asmop)
975     {
976       *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
977       *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
978     }
979   else
980     {
981       *pfile = input_filename;
982       *pline = lineno;
983     }
984 }
985
986 /* Report an error at line LINE of file FILE.  */
987
988 static void
989 v_error_with_file_and_line (file, line, msgid, ap)
990      const char *file;
991      int line;
992      const char *msgid;
993      va_list ap;
994 {
995   count_error (0);
996   report_error_function (file);
997   if (doing_line_wrapping ())
998     vline_wrapper_message_with_location (file, line, 0, msgid, ap);
999   else
1000     v_message_with_file_and_line (file, line, 0, msgid, ap);
1001 }
1002
1003 /* Report an error at the declaration DECL.
1004    MSGID is a format string which uses %s to substitute the declaration
1005    name; subsequent substitutions are a la printf.  */
1006
1007 static void
1008 v_error_with_decl (decl, msgid, ap)
1009      tree decl;
1010      const char *msgid;
1011      va_list ap;
1012 {
1013   count_error (0);
1014   report_error_function (DECL_SOURCE_FILE (decl));
1015   v_message_with_decl (decl, 0, msgid, ap);
1016 }
1017
1018
1019 /* Report an error at the line number of the insn INSN.
1020    This is used only when INSN is an `asm' with operands,
1021    and each ASM_OPERANDS records its own source file and line.  */
1022
1023 static void
1024 v_error_for_asm (insn, msgid, ap)
1025      rtx insn;
1026      const char *msgid;
1027      va_list ap;
1028 {
1029   const char *file;
1030   int line;
1031
1032   count_error (0);
1033   file_and_line_for_asm (insn, &file, &line);
1034   report_error_function (file);
1035   v_message_with_file_and_line (file, line, 0, msgid, ap);
1036 }
1037
1038
1039 /* Report an error at the current line number.  */
1040
1041 void
1042 verror (msgid, ap)
1043      const char *msgid;
1044      va_list ap;
1045 {
1046   v_error_with_file_and_line (input_filename, lineno, msgid, ap);
1047 }
1048
1049
1050 /* Report a fatal error at the current line number.  Allow a front end to
1051    intercept the message.  */
1052
1053 static void (*fatal_function) PARAMS ((const char *, va_list));
1054
1055 static void
1056 vfatal (msgid, ap)
1057      const char *msgid;
1058      va_list ap;
1059 {
1060    if (fatal_function != 0)
1061      (*fatal_function) (_(msgid), ap);
1062
1063   verror (msgid, ap);
1064   exit (FATAL_EXIT_CODE);
1065 }
1066
1067 /* Report a warning at line LINE of file FILE.  */
1068
1069 static void
1070 v_warning_with_file_and_line (file, line, msgid, ap)
1071      const char *file;
1072      int line;
1073      const char *msgid;
1074      va_list ap;
1075 {
1076   if (count_error (1))
1077     {
1078       report_error_function (file);
1079       if (doing_line_wrapping ())
1080         vline_wrapper_message_with_location (file, line, 1, msgid, ap);
1081       else
1082         v_message_with_file_and_line (file, line, 1, msgid, ap);
1083     }
1084 }
1085
1086
1087 /* Report a warning at the declaration DECL.
1088    MSGID is a format string which uses %s to substitute the declaration
1089    name; subsequent substitutions are a la printf.  */
1090
1091 static void
1092 v_warning_with_decl (decl, msgid, ap)
1093      tree decl;
1094      const char *msgid;
1095      va_list ap;
1096 {
1097   if (count_error (1))
1098     {
1099       report_error_function (DECL_SOURCE_FILE (decl));
1100       v_message_with_decl (decl, 1, msgid, ap);
1101     }
1102 }
1103
1104
1105 /* Report a warning at the line number of the insn INSN.
1106    This is used only when INSN is an `asm' with operands,
1107    and each ASM_OPERANDS records its own source file and line.  */
1108
1109 static void
1110 v_warning_for_asm (insn, msgid, ap)
1111      rtx insn;
1112      const char *msgid;
1113      va_list ap;
1114 {
1115   if (count_error (1))
1116     {
1117       const char *file;
1118       int line;
1119
1120       file_and_line_for_asm (insn, &file, &line);
1121       report_error_function (file);
1122       v_message_with_file_and_line (file, line, 1, msgid, ap);
1123     }
1124 }
1125
1126
1127 /* Report a warning at the current line number.  */
1128
1129 void
1130 vwarning (msgid, ap)
1131      const char *msgid;
1132      va_list ap;
1133 {
1134   v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
1135 }
1136
1137 /* These functions issue either warnings or errors depending on
1138    -pedantic-errors.  */
1139
1140 void
1141 vpedwarn (msgid, ap)
1142      const char *msgid;
1143      va_list ap;
1144 {
1145   if (flag_pedantic_errors)
1146     verror (msgid, ap);
1147   else
1148     vwarning (msgid, ap);
1149 }
1150
1151
1152 static void
1153 v_pedwarn_with_decl (decl, msgid, ap)
1154      tree decl;
1155      const char *msgid;
1156      va_list ap;
1157 {
1158   /* We don't want -pedantic-errors to cause the compilation to fail from
1159      "errors" in system header files.  Sometimes fixincludes can't fix what's
1160      broken (eg: unsigned char bitfields - fixing it may change the alignment
1161      which will cause programs to mysteriously fail because the C library
1162      or kernel uses the original layout).  There's no point in issuing a
1163      warning either, it's just unnecessary noise.  */
1164
1165   if (! DECL_IN_SYSTEM_HEADER (decl))
1166     {
1167       if (flag_pedantic_errors)
1168         v_error_with_decl (decl, msgid, ap);
1169       else
1170         v_warning_with_decl (decl, msgid, ap);
1171     }
1172 }
1173
1174
1175 static void
1176 v_pedwarn_with_file_and_line (file, line, msgid, ap)
1177      const char *file;
1178      int line;
1179      const char *msgid;
1180      va_list ap;
1181 {
1182   if (flag_pedantic_errors)
1183     v_error_with_file_and_line (file, line, msgid, ap);
1184   else
1185     v_warning_with_file_and_line (file, line, msgid, ap);
1186 }
1187
1188
1189 /* Apologize for not implementing some feature.  */
1190
1191 static void
1192 vsorry (msgid, ap)
1193      const char *msgid;
1194      va_list ap;
1195 {
1196   sorrycount++;
1197   if (input_filename)
1198     fprintf (stderr, "%s:%d: ", input_filename, lineno);
1199   else
1200     fprintf (stderr, "%s: ", progname);
1201   notice ("sorry, not implemented: ");
1202   vnotice (stderr, msgid, ap);
1203   fputc ('\n', stderr);
1204 }
1205
1206 \f
1207 /* Count an error or warning.  Return 1 if the message should be printed.  */
1208
1209 int
1210 count_error (warningp)
1211      int warningp;
1212 {
1213   if (warningp && inhibit_warnings)
1214     return 0;
1215
1216   if (warningp && !warnings_are_errors)
1217     warningcount++;
1218   else
1219     {
1220       static int warning_message = 0;
1221
1222       if (warningp && !warning_message)
1223         {
1224           notice ("%s: warnings being treated as errors\n", progname);
1225           warning_message = 1;
1226         }
1227       errorcount++;
1228     }
1229
1230   return 1;
1231 }
1232
1233 /* Print a diagnistic MSGID on FILE.  */
1234 void
1235 fnotice VPARAMS ((FILE *file, const char *msgid, ...))
1236 {
1237 #ifndef ANSI_PROTOTYPES
1238   FILE *file;
1239   const char *msgid;
1240 #endif
1241   va_list ap;
1242
1243   VA_START (ap, msgid);
1244
1245 #ifndef ANSI_PROTOTYPES
1246   file = va_arg (ap, FILE *);
1247   msgid = va_arg (ap, const char *);
1248 #endif
1249
1250   vnotice (file, msgid, ap);
1251   va_end (ap);
1252 }
1253
1254
1255 /* Print a fatal error message.  NAME is the text.
1256    Also include a system error message based on `errno'.  */
1257
1258 void
1259 pfatal_with_name (name)
1260   const char *name;
1261 {
1262   fprintf (stderr, "%s: ", progname);
1263   perror (name);
1264   exit (FATAL_EXIT_CODE);
1265 }
1266
1267 void
1268 fatal_io_error (name)
1269   const char *name;
1270 {
1271   notice ("%s: %s: I/O error\n", progname, name);
1272   exit (FATAL_EXIT_CODE);
1273 }
1274
1275 /* Issue a pedantic warning MSGID.  */
1276 void
1277 pedwarn VPARAMS ((const char *msgid, ...))
1278 {
1279 #ifndef ANSI_PROTOTYPES
1280   const char *msgid;
1281 #endif
1282   va_list ap;
1283
1284   VA_START (ap, msgid);
1285
1286 #ifndef ANSI_PROTOTYPES
1287   msgid = va_arg (ap, const char *);
1288 #endif
1289
1290   vpedwarn (msgid, ap);
1291   va_end (ap);
1292 }
1293
1294 /* Issue a pedantic waring about DECL.  */
1295 void
1296 pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1297 {
1298 #ifndef ANSI_PROTOTYPES
1299   tree decl;
1300   const char *msgid;
1301 #endif
1302   va_list ap;
1303
1304   VA_START (ap, msgid);
1305
1306 #ifndef ANSI_PROTOTYPES
1307   decl = va_arg (ap, tree);
1308   msgid = va_arg (ap, const char *);
1309 #endif
1310
1311   v_pedwarn_with_decl (decl, msgid, ap);
1312   va_end (ap);
1313 }
1314
1315 /* Same as above but within the context FILE and LINE. */
1316 void
1317 pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
1318                                      const char *msgid, ...))
1319 {
1320 #ifndef ANSI_PROTOTYPES
1321   const char *file;
1322   int line;
1323   const char *msgid;
1324 #endif
1325   va_list ap;
1326
1327   VA_START (ap, msgid);
1328
1329 #ifndef ANSI_PROTOTYPES
1330   file = va_arg (ap, const char *);
1331   line = va_arg (ap, int);
1332   msgid = va_arg (ap, const char *);
1333 #endif
1334
1335   v_pedwarn_with_file_and_line (file, line, msgid, ap);
1336   va_end (ap);
1337 }
1338
1339 /* Just apologize with MSGID.  */
1340 void
1341 sorry VPARAMS ((const char *msgid, ...))
1342 {
1343 #ifndef ANSI_PROTOTYPES
1344   const char *msgid;
1345 #endif
1346   va_list ap;
1347
1348   VA_START (ap, msgid);
1349
1350 #ifndef ANSI_PROTOTYPES
1351   msgid = va_arg (ap, const char *);
1352 #endif
1353
1354   vsorry (msgid, ap);
1355   va_end (ap);
1356 }
1357
1358 /* Called when the start of a function definition is parsed,
1359    this function prints on stderr the name of the function.  */
1360
1361 void
1362 announce_function (decl)
1363      tree decl;
1364 {
1365   if (! quiet_flag)
1366     {
1367       if (rtl_dump_and_exit)
1368         fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
1369       else
1370         {
1371           if (doing_line_wrapping ())
1372             line_wrapper_printf
1373               (stderr, " %s", (*decl_printable_name) (decl, 2));
1374           else
1375             fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
1376         }
1377       fflush (stderr);
1378       need_error_newline = 1;
1379       last_error_function = current_function_decl;
1380     }
1381 }
1382
1383 /* The default function to print out name of current function that caused
1384    an error.  */
1385
1386 void
1387 default_print_error_function (file)
1388   const char *file;
1389 {
1390   if (last_error_function != current_function_decl)
1391     {
1392       char *prefix = NULL;
1393       output_buffer buffer;
1394       
1395       if (file)
1396         prefix = build_message_string ("%s: ", file);
1397
1398       if (doing_line_wrapping ())
1399         init_output_buffer
1400           (&buffer, prefix, diagnostic_message_length_per_line);
1401       else
1402         {
1403           if (file)
1404             fprintf (stderr, "%s: ", file);
1405         }
1406       
1407       if (current_function_decl == NULL)
1408         {
1409           if (doing_line_wrapping ())
1410             output_printf (&buffer, "At top level:\n");
1411           else
1412             notice ("At top level:\n");
1413         }
1414       else
1415         {
1416           if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
1417             {
1418               if (doing_line_wrapping ())
1419                 output_printf
1420                   (&buffer, "In method `%s':\n",
1421                    (*decl_printable_name) (current_function_decl, 2));
1422               else
1423                 notice ("In method `%s':\n",
1424                         (*decl_printable_name) (current_function_decl, 2));
1425             }
1426           else
1427             {
1428               if (doing_line_wrapping ())
1429                 output_printf
1430                   (&buffer, "In function `%s':\n",
1431                    (*decl_printable_name) (current_function_decl, 2));
1432               else
1433                 notice ("In function `%s':\n",
1434                         (*decl_printable_name) (current_function_decl, 2));
1435             }
1436         }
1437
1438       last_error_function = current_function_decl;
1439
1440       if (doing_line_wrapping ())
1441         output_to_stream (&buffer, stderr);
1442       
1443       free ((char*) prefix);
1444     }
1445 }
1446
1447 /* Prints out, if necessary, the name of the current function
1448   that caused an error.  Called from all error and warning functions.
1449   We ignore the FILE parameter, as it cannot be relied upon.  */
1450
1451 void
1452 report_error_function (file)
1453   const char *file ATTRIBUTE_UNUSED;
1454 {
1455   struct file_stack *p;
1456
1457   if (need_error_newline)
1458     {
1459       fprintf (stderr, "\n");
1460       need_error_newline = 0;
1461     }
1462
1463   if (input_file_stack && input_file_stack->next != 0
1464       && input_file_stack_tick != last_error_tick)
1465     {
1466       for (p = input_file_stack->next; p; p = p->next)
1467         if (p == input_file_stack->next)
1468           notice ("In file included from %s:%d", p->name, p->line);
1469         else
1470           notice (",\n                 from %s:%d", p->name, p->line);
1471       fprintf (stderr, ":\n");
1472       last_error_tick = input_file_stack_tick;
1473     }
1474
1475   (*print_error_function) (input_filename);
1476 }
1477
1478 void
1479 error_with_file_and_line VPARAMS ((const char *file, int line,
1480                                    const char *msgid, ...))
1481 {
1482 #ifndef ANSI_PROTOTYPES
1483   const char *file;
1484   int line;
1485   const char *msgid;
1486 #endif
1487   va_list ap;
1488
1489   VA_START (ap, msgid);
1490
1491 #ifndef ANSI_PROTOTYPES
1492   file = va_arg (ap, const char *);
1493   line = va_arg (ap, int);
1494   msgid = va_arg (ap, const char *);
1495 #endif
1496
1497   v_error_with_file_and_line (file, line, msgid, ap);
1498   va_end (ap);
1499 }
1500
1501 void
1502 error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1503 {
1504 #ifndef ANSI_PROTOTYPES
1505   tree decl;
1506   const char *msgid;
1507 #endif
1508   va_list ap;
1509
1510   VA_START (ap, msgid);
1511
1512 #ifndef ANSI_PROTOTYPES
1513   decl = va_arg (ap, tree);
1514   msgid = va_arg (ap, const char *);
1515 #endif
1516
1517   v_error_with_decl (decl, msgid, ap);
1518   va_end (ap);
1519 }
1520
1521 void
1522 error_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
1523 {
1524 #ifndef ANSI_PROTOTYPES
1525   rtx insn;
1526   const char *msgid;
1527 #endif
1528   va_list ap;
1529
1530   VA_START (ap, msgid);
1531
1532 #ifndef ANSI_PROTOTYPES
1533   insn = va_arg (ap, rtx);
1534   msgid = va_arg (ap, const char *);
1535 #endif
1536
1537   v_error_for_asm (insn, msgid, ap);
1538   va_end (ap);
1539 }
1540
1541 void
1542 error VPARAMS ((const char *msgid, ...))
1543 {
1544 #ifndef ANSI_PROTOTYPES
1545   const char *msgid;
1546 #endif
1547   va_list ap;
1548
1549   VA_START (ap, msgid);
1550
1551 #ifndef ANSI_PROTOTYPES
1552   msgid = va_arg (ap, const char *);
1553 #endif
1554
1555   verror (msgid, ap);
1556   va_end (ap);
1557 }
1558
1559 /* Set the function to call when a fatal error occurs.  */
1560
1561 void
1562 set_fatal_function (f)
1563      void (*f) PARAMS ((const char *, va_list));
1564 {
1565   fatal_function = f;
1566 }
1567
1568 void
1569 fatal VPARAMS ((const char *msgid, ...))
1570 {
1571 #ifndef ANSI_PROTOTYPES
1572   const char *msgid;
1573 #endif
1574   va_list ap;
1575
1576   VA_START (ap, msgid);
1577
1578 #ifndef ANSI_PROTOTYPES
1579   msgid = va_arg (ap, const char *);
1580 #endif
1581
1582   vfatal (msgid, ap);
1583   va_end (ap);
1584 }
1585
1586 void
1587 _fatal_insn (msgid, insn, file, line, function)
1588      const char *msgid;
1589      rtx insn;
1590      const char *file;
1591      int line;
1592      const char *function;
1593 {
1594   error ("%s", msgid);
1595   debug_rtx (insn);
1596   fancy_abort (file, line, function);
1597 }
1598
1599 void
1600 _fatal_insn_not_found (insn, file, line, function)
1601      rtx insn;
1602      const char *file;
1603      int line;
1604      const char *function;
1605 {
1606   if (INSN_CODE (insn) < 0)
1607     _fatal_insn ("Unrecognizable insn:", insn, file, line, function);
1608   else
1609     _fatal_insn ("Insn does not satisfy its constraints:",
1610                 insn, file, line, function);
1611 }
1612
1613 void
1614 warning_with_file_and_line VPARAMS ((const char *file, int line,
1615                                      const char *msgid, ...))
1616 {
1617 #ifndef ANSI_PROTOTYPES
1618   const char *file;
1619   int line;
1620   const char *msgid;
1621 #endif
1622   va_list ap;
1623
1624   VA_START (ap, msgid);
1625
1626 #ifndef ANSI_PROTOTYPES
1627   file = va_arg (ap, const char *);
1628   line = va_arg (ap, int);
1629   msgid = va_arg (ap, const char *);
1630 #endif
1631
1632   v_warning_with_file_and_line (file, line, msgid, ap);
1633   va_end (ap);
1634 }
1635
1636 void
1637 warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1638 {
1639 #ifndef ANSI_PROTOTYPES
1640   tree decl;
1641   const char *msgid;
1642 #endif
1643   va_list ap;
1644
1645   VA_START (ap, msgid);
1646
1647 #ifndef ANSI_PROTOTYPES
1648   decl = va_arg (ap, tree);
1649   msgid = va_arg (ap, const char *);
1650 #endif
1651
1652   v_warning_with_decl (decl, msgid, ap);
1653   va_end (ap);
1654 }
1655
1656 void
1657 warning_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
1658 {
1659 #ifndef ANSI_PROTOTYPES
1660   rtx insn;
1661   const char *msgid;
1662 #endif
1663   va_list ap;
1664
1665   VA_START (ap, msgid);
1666
1667 #ifndef ANSI_PROTOTYPES
1668   insn = va_arg (ap, rtx);
1669   msgid = va_arg (ap, const char *);
1670 #endif
1671
1672   v_warning_for_asm (insn, msgid, ap);
1673   va_end (ap);
1674 }
1675
1676 void
1677 warning VPARAMS ((const char *msgid, ...))
1678 {
1679 #ifndef ANSI_PROTOTYPES
1680   const char *msgid;
1681 #endif
1682   va_list ap;
1683
1684   VA_START (ap, msgid);
1685
1686 #ifndef ANSI_PROTOTYPES
1687   msgid = va_arg (ap, const char *);
1688 #endif
1689
1690   vwarning (msgid, ap);
1691   va_end (ap);
1692 }
1693
1694 /* Save BUFFER's STATE.  */
1695 static void
1696 save_output_state (buffer, state)
1697      const output_buffer *buffer;
1698      output_state *state;
1699 {
1700   state->prefix = buffer->prefix;
1701   state->maximum_length = buffer->maximum_length;
1702   state->ideal_maximum_length = buffer->ideal_maximum_length;
1703   state->emitted_prefix_p = buffer->emitted_prefix_p;
1704   state->prefixing_rule = buffer->prefixing_rule;
1705   state->cursor = buffer->cursor;
1706   va_copy (state->format_args, buffer->format_args);
1707 }
1708
1709 /* Restore BUFFER's previously saved STATE.  */
1710 static void
1711 restore_output_state (state, buffer)
1712      const output_state *state;
1713      output_buffer *buffer;
1714 {
1715   buffer->prefix = state->prefix;
1716   buffer->maximum_length = state->maximum_length;
1717   buffer->ideal_maximum_length = state->ideal_maximum_length;
1718   buffer->emitted_prefix_p = state->emitted_prefix_p;
1719   buffer->prefixing_rule = state->prefixing_rule;
1720   buffer->cursor = state->cursor;
1721   va_copy (buffer->format_args, state->format_args);
1722 }
1723
1724 /* Helper subroutine of output_verbatim and verbatim. Do the approriate
1725    settings needed by BUFFER for a verbatim formatting.  */
1726 static void
1727 output_do_verbatim (buffer)
1728      output_buffer *buffer;
1729 {
1730   buffer->prefix = NULL;
1731   buffer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_NEVER;
1732   output_set_maximum_length (buffer, 0);
1733   output_format (buffer);
1734 }
1735
1736 /* Output MESSAGE verbatim into BUFFER.  */
1737 void
1738 output_verbatim VPARAMS ((output_buffer *buffer, const char *msg, ...))
1739 {
1740 #ifndef ANSI_PROTOTYPES
1741   output_buffer *buffer;
1742   const char *msg;
1743 #endif
1744   output_state previous_state;
1745   va_list ap;
1746
1747   VA_START (ap, msg);
1748 #ifndef ANSI_PROTOTYPES
1749   buffer = va_arg (ap, output_buffer *);
1750   msg = va_arg (ap, const char *);
1751 #endif
1752   save_output_state (buffer, &previous_state);
1753   buffer->cursor = msg;
1754   va_copy (buffer->format_args, ap);
1755   output_do_verbatim(buffer);
1756   va_end (buffer->format_args);
1757   restore_output_state (&previous_state, buffer);
1758 }
1759
1760 /* Same as above but use diagnostic_buffer.  */
1761 void
1762 verbatim VPARAMS ((const char *msg, ...))
1763 {
1764 #ifndef ANSI_PROTOTYPES
1765   const char *msg;
1766 #endif
1767   output_state previous_state;
1768   save_output_state (diagnostic_buffer, &previous_state);
1769   VA_START (diagnostic_args, msg);
1770 #ifndef ANSI_PROTOTYPES
1771   msg = va_arg (diagnostic_args, const char *);
1772 #endif
1773   diagnostic_msg = msg;
1774   output_do_verbatim (diagnostic_buffer);
1775   output_to_stream (diagnostic_buffer, stderr);
1776   va_end (diagnostic_args);
1777   restore_output_state (&previous_state, diagnostic_buffer);
1778 }