OSDN Git Service

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