OSDN Git Service

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