OSDN Git Service

2000-09-25 Branko Cibej <branko.cibej@hermes.si>
[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_text_info PARAMS ((output_buffer *));
97 static void clear_diagnostic_info PARAMS ((output_buffer *));
98
99 static void default_diagnostic_starter PARAMS ((output_buffer *,
100                                                 diagnostic_context *));
101 static void default_diagnostic_finalizer PARAMS ((output_buffer *,
102                                                   diagnostic_context *));
103
104 static void error_recursion PARAMS ((void)) ATTRIBUTE_NORETURN;
105 static const char *trim_filename PARAMS ((const char *));
106
107 extern int rtl_dump_and_exit;
108 extern int inhibit_warnings;
109 extern int warnings_are_errors;
110 extern int warningcount;
111 extern int errorcount;
112
113 /* Front-end specific tree formatter, if non-NULL.  */
114 printer_fn lang_printer = NULL;
115
116 /* This must be large enough to hold any printed integer or
117    floating-point value.  */
118 static char digit_buffer[128];
119
120 /* An output_buffer surrogate for stderr.  */
121 static output_buffer global_output_buffer;
122 output_buffer *diagnostic_buffer = &global_output_buffer;
123
124 /* Function of last error message;
125    more generally, function such that if next error message is in it
126    then we don't have to mention the function name.  */
127 static tree last_error_function = NULL;
128
129 /* Used to detect when input_file_stack has changed since last described.  */
130 static int last_error_tick;
131
132 /* Called by report_error_function to print out function name.
133    Default may be overridden by language front-ends.  */
134
135 void (*print_error_function) PARAMS ((const char *)) =
136   default_print_error_function;
137
138 /* Hooks for language specific diagnostic messages pager and finalizer.  */
139 diagnostic_starter_fn lang_diagnostic_starter;
140 diagnostic_finalizer_fn lang_diagnostic_finalizer;
141
142 /* Maximum characters per line in automatic line wrapping mode.
143    Zero means don't wrap lines. */
144
145 int diagnostic_message_length_per_line;
146
147 /* Used to control every diagnostic message formatting.  Front-ends should
148    call set_message_prefixing_rule to set up their politics.  */
149 static int current_prefixing_rule;
150
151 /* Prevent recursion into the error handler.  */
152 static int diagnostic_lock;
153
154 \f
155 /* Return truthvalue if current input file is different from the most recent
156    file involved in a diagnostic message.  */
157 int
158 error_module_changed ()
159 {
160   return last_error_tick != input_file_stack_tick;
161 }
162
163 /* Remember current file as being the most recent file involved in a
164    diagnostic message.  */
165 void
166 record_last_error_module ()
167 {
168   last_error_tick = input_file_stack_tick;
169 }
170
171 /* Same as error_module_changed, but for function.  */
172 int
173 error_function_changed ()
174 {
175   return last_error_function != current_function_decl;
176 }
177
178 /* Same as record_last_error_module, but for function.  */
179 void
180 record_last_error_function ()
181 {
182   last_error_function = current_function_decl;
183 }
184
185 /* Initialize the diagnostic message outputting machinery.  */
186
187 void
188 initialize_diagnostics ()
189 {
190   /* By default, we don't line-wrap messages.  */
191   diagnostic_message_length_per_line = 0;
192   set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
193
194   /* Proceed to actual initialization.  */
195   default_initialize_buffer (diagnostic_buffer);
196
197   lang_diagnostic_starter = default_diagnostic_starter;
198   lang_diagnostic_finalizer = default_diagnostic_finalizer;
199 }
200
201 void
202 set_message_prefixing_rule (rule)
203      int rule;
204 {
205   current_prefixing_rule = rule;
206 }
207
208 /* Returns true if BUFFER is in line-wrappind mode.  */
209
210 int
211 output_is_line_wrapping (buffer)
212      output_buffer *buffer;
213 {
214   return ideal_line_wrap_cutoff (buffer) > 0;
215 }
216
217 /* Return BUFFER's prefix.  */
218
219 const char *
220 output_get_prefix (buffer)
221      const output_buffer *buffer;
222 {
223   return output_prefix (buffer);
224 }
225
226 /* Subroutine of output_set_maximum_length.  Set up BUFFER's
227    internal maximum characters per line.  */
228
229 static void
230 set_real_maximum_length (buffer)
231      output_buffer *buffer;
232 {
233   /* If we're told not to wrap lines then do the obvious thing.  In case
234    we'll emit prefix only once per diagnostic message, it is appropriate
235   not to increase unncessarily the line-length cut-off.  */
236   if (! output_is_line_wrapping (buffer)
237       || prefixing_policy (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
238       || prefixing_policy (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
239     line_wrap_cutoff (buffer) = ideal_line_wrap_cutoff (buffer);
240   else
241     {
242       int prefix_length =
243         output_prefix (buffer) ? strlen (output_prefix (buffer)) : 0;
244       /* If the prefix is ridiculously too long, output at least
245          32 characters.  */
246       if (ideal_line_wrap_cutoff (buffer) - prefix_length < 32)
247         line_wrap_cutoff (buffer) = ideal_line_wrap_cutoff (buffer) + 32;
248       else
249         line_wrap_cutoff (buffer) = ideal_line_wrap_cutoff (buffer);
250     }
251 }
252
253 /* Sets the number of maximum characters per line BUFFER can output
254    in line-wrapping mode.  A LENGTH value 0 suppresses line-wrapping.  */
255
256 void
257 output_set_maximum_length (buffer, length)
258      output_buffer *buffer;
259      int length;
260 {
261  ideal_line_wrap_cutoff (buffer) = length;
262   set_real_maximum_length (buffer);
263 }
264
265 /* Sets BUFFER's PREFIX.  */
266
267 void
268 output_set_prefix (buffer, prefix)
269      output_buffer *buffer;
270      const char *prefix;
271 {
272   output_prefix (buffer) = prefix;
273   set_real_maximum_length (buffer);
274   prefix_was_emitted_for (buffer) = 0;
275   output_indentation (buffer) = 0;
276 }
277
278 /*  Return a pointer to the last character emitted in the output
279     BUFFER area.  A NULL pointer means no character available.  */
280 const char *
281 output_last_position (buffer)
282      const output_buffer *buffer;
283 {
284   const char *p = NULL;
285   
286   if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
287     p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
288   return p;
289 }
290
291 /* Free BUFFER's prefix, a previously malloc'd string.  */
292
293 void
294 output_destroy_prefix (buffer)
295      output_buffer *buffer;
296 {
297   if (output_prefix (buffer) != NULL)
298     {
299       free ((char *) output_prefix (buffer));
300       output_prefix (buffer) = NULL;
301     }
302 }
303
304 /* Zero out any text output so far in BUFFER.  */
305
306 static void
307 clear_text_info (buffer)
308      output_buffer *buffer;
309 {
310   obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
311   output_text_length (buffer) = 0;
312 }
313
314 /* Zero out any diagnostic data used so far by BUFFER.  */
315
316 static void
317 clear_diagnostic_info (buffer)
318      output_buffer *buffer;
319 {
320   output_buffer_text_cursor (buffer) = NULL;
321   output_buffer_ptr_to_format_args (buffer) = NULL;
322   prefix_was_emitted_for (buffer) = 0;
323   output_indentation (buffer) = 0;
324 }
325
326 /* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
327    characters per line.  */
328
329 void
330 init_output_buffer (buffer, prefix, maximum_length)
331      output_buffer *buffer;
332      const char *prefix;
333      int maximum_length;
334 {
335   bzero (buffer, sizeof (output_buffer));
336   obstack_init (&buffer->obstack);
337   ideal_line_wrap_cutoff (buffer) = maximum_length;
338   prefixing_policy (buffer) = current_prefixing_rule;
339   output_set_prefix (buffer, prefix);
340   output_text_length (buffer) = 0;
341   clear_diagnostic_info (buffer);  
342 }
343
344 /* Initialize BUFFER with a NULL prefix and current diagnostic message
345    length cutoff.  */
346 void
347 default_initialize_buffer (buffer)
348      output_buffer *buffer;
349 {
350   init_output_buffer (buffer, NULL, diagnostic_message_length_per_line);
351 }
352
353 /* Recompute diagnostic_buffer's attributes to reflect any change
354    in diagnostic formatting global options.  */
355
356 void
357 reshape_diagnostic_buffer ()
358 {
359   ideal_line_wrap_cutoff (diagnostic_buffer) =
360     diagnostic_message_length_per_line;
361   prefixing_policy (diagnostic_buffer) = current_prefixing_rule;
362   set_real_maximum_length (diagnostic_buffer);
363 }
364
365 /* Reinitialize BUFFER.  */
366 void
367 output_clear (buffer)
368      output_buffer *buffer;
369 {
370   clear_text_info (buffer);
371   clear_diagnostic_info (buffer);
372 }
373
374 /* Finishes to construct a NULL-terminated character string representing
375    the BUFFERed message.  */
376
377 const char *
378 output_finish (buffer)
379      output_buffer *buffer;
380 {
381   obstack_1grow (&buffer->obstack, '\0');
382   return (const char *) obstack_finish (&buffer->obstack);
383 }
384
385 void
386 flush_diagnostic_buffer ()
387 {
388   output_to_stream (diagnostic_buffer, stderr);
389   fflush (stderr);
390 }
391
392 /* Return the amount of characters BUFFER can accept to
393    make a full line.  */
394
395 int
396 output_space_left (buffer)
397      const output_buffer *buffer;
398 {
399   return line_wrap_cutoff (buffer) - output_text_length (buffer);
400 }
401
402 /* Write out BUFFER's prefix.  */
403
404 void
405 output_emit_prefix (buffer)
406      output_buffer *buffer;
407 {
408   if (output_prefix (buffer) != NULL)
409     {
410       switch (prefixing_policy (buffer))
411         {
412         default:
413         case DIAGNOSTICS_SHOW_PREFIX_NEVER:
414           break;
415
416         case DIAGNOSTICS_SHOW_PREFIX_ONCE:
417           if (prefix_was_emitted_for (buffer))
418             {
419               output_indent (buffer);
420               break;
421             }
422           output_indentation (buffer) += 3;          
423           /* Fall through.  */
424
425         case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
426           {
427             int prefix_length = strlen (output_prefix (buffer));
428             output_append_r (buffer, output_prefix (buffer), prefix_length);
429             prefix_was_emitted_for (buffer) = 1;
430           }
431           break;
432         }
433     }
434 }
435
436 /* Have BUFFER start a new line.  */
437
438 void
439 output_add_newline (buffer)
440      output_buffer *buffer;
441 {
442   obstack_1grow (&buffer->obstack, '\n');
443   output_text_length (buffer) = 0;
444 }
445
446 /* Appends a character to BUFFER.  */
447
448 void
449 output_add_character (buffer, c)
450      output_buffer *buffer;
451      int c;
452 {
453   if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
454     output_add_newline (buffer);
455   obstack_1grow (&buffer->obstack, c);
456   ++output_text_length (buffer);
457 }
458
459 /* Adds a space to BUFFER.  */
460
461 void
462 output_add_space (buffer)
463      output_buffer *buffer;
464 {
465   if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
466     {
467       output_add_newline (buffer);
468       return;
469     }
470   obstack_1grow (&buffer->obstack, ' ');
471   ++output_text_length (buffer);
472 }
473
474 /* These functions format an INTEGER into BUFFER as suggested by their
475    names.  */
476
477 void
478 output_decimal (buffer, i)
479      output_buffer *buffer;
480      int i;
481 {
482   output_formatted_integer (buffer, "%d", i);
483 }
484
485 static void
486 output_long_decimal (buffer, i)
487      output_buffer *buffer;
488      long int i;
489 {
490   output_formatted_integer (buffer, "%ld", i);
491 }
492
493 static void
494 output_unsigned_decimal (buffer, i)
495      output_buffer *buffer;
496      unsigned int i;
497 {
498   output_formatted_integer (buffer, "%u", i);
499 }
500
501 static void
502 output_long_unsigned_decimal (buffer, i)
503      output_buffer *buffer;
504      long unsigned int i;
505 {
506   output_formatted_integer (buffer, "%lu", i);
507 }
508
509 static void
510 output_octal (buffer, i)
511      output_buffer *buffer;
512      unsigned int i;
513 {
514   output_formatted_integer (buffer, "%o", i);
515 }
516
517 static void
518 output_long_octal (buffer, i)
519      output_buffer *buffer;
520      unsigned long int i;
521 {
522   output_formatted_integer (buffer, "%lo", i);
523 }
524
525 static void
526 output_hexadecimal (buffer, i)
527      output_buffer *buffer;
528      unsigned int i;
529 {
530   output_formatted_integer (buffer, "%x", i);
531 }
532
533 static void
534 output_long_hexadecimal (buffer, i)
535      output_buffer *buffer;
536      unsigned long int i;
537 {
538   output_formatted_integer (buffer, "%lx", i);
539 }
540
541 /* Append to BUFFER a string specified by its STARTING character
542    and LENGTH.  */
543
544 static void
545 output_append_r (buffer, start, length)
546      output_buffer *buffer;
547      const char *start;
548      int length;
549 {
550   obstack_grow (&buffer->obstack, start, length);
551   output_text_length (buffer) += length;
552 }
553
554 /* Append a string deliminated by START and END to BUFFER.  No wrapping is
555    done.  However, if beginning a new line then emit output_prefix (BUFFER)
556    and skip any leading whitespace if appropriate.  The caller must ensure
557    that it is safe to do so.  */
558
559 void
560 output_append (buffer, start, end)
561      output_buffer *buffer;
562      const char *start;
563      const char *end;
564 {
565   /* Emit prefix and skip whitespace if we're starting a new line.  */
566   if (is_starting_newline (buffer))
567     {
568       output_emit_prefix (buffer);
569       if (output_is_line_wrapping (buffer))
570         while (start != end && *start == ' ')
571           ++start;
572     }
573   output_append_r (buffer, start, end - start);
574 }
575
576 static void
577 output_indent (buffer)
578      output_buffer *buffer;
579 {
580   int n = output_indentation (buffer);
581   int i;
582
583   for (i = 0; i < n; ++i)
584     output_add_character (buffer, ' ');
585 }
586
587 /* Wrap a text delimited by START and END into BUFFER.  */
588
589 static void
590 wrap_text (buffer, start, end)
591      output_buffer *buffer;
592      const char *start;
593      const char *end;
594 {
595   int is_wrapping = output_is_line_wrapping (buffer);
596   
597   while (start != end)
598     {
599       /* Dump anything bodered by whitespaces.  */ 
600       {
601         const char *p = start;
602         while (p != end && *p != ' ' && *p != '\n')
603           ++p;
604         if (is_wrapping && p - start >= output_space_left (buffer))
605           output_add_newline (buffer);
606         output_append (buffer, start, p);
607         start = p;
608       }
609
610       if (start != end && *start == ' ')
611         {
612           output_add_space (buffer);
613           ++start;
614         }
615       if (start != end && *start == '\n')
616         {
617           output_add_newline (buffer);
618           ++start;
619         }
620     }
621 }
622
623 /* Same as wrap_text but wrap text only when in line-wrapping mode.  */
624 static void
625 maybe_wrap_text (buffer, start, end)
626      output_buffer *buffer;
627      const char *start;
628      const char *end;
629 {
630   if (output_is_line_wrapping (buffer))
631     wrap_text (buffer, start, end);
632   else
633     output_append (buffer, start, end);
634 }
635
636
637 /* Append a STRING to BUFFER; the STRING maybe be line-wrapped if in
638    appropriate mode.  */
639
640 void
641 output_add_string (buffer, str)
642      output_buffer *buffer;
643      const char *str;
644 {
645   maybe_wrap_text (buffer, str, str + (str ? strlen (str) : 0));
646 }
647
648 /* Flush the content of BUFFER onto FILE and reinitialize BUFFER.  */
649
650 static void
651 output_to_stream (buffer, file)
652      output_buffer *buffer;
653      FILE *file;
654 {
655   const char *text = output_finish (buffer);
656   fputs (text, file);
657   clear_text_info (buffer);
658 }
659
660 /* Format a message pointed to by output_buffer_text_cursor (BUFFER) using
661    output_buffer_format_args (BUFFER) as appropriate.  The following format
662    specifiers are recognized as  being language independent:
663    %d, %i: (signed) integer in base ten.
664    %u: unsigned integer in base ten.
665    %o: unsigned integer in base eight.
666    %x: unsigned integer in base sixteen.
667    %ld, %li, %lo, %lu, %lx: long versions of the above.
668    %c: character.
669    %s: string.
670    %%: `%'.
671    %*.s: a substring the length of which is specified by an integer.  */
672
673 static void
674 output_format (buffer)
675      output_buffer *buffer;
676 {
677   for (; *output_buffer_text_cursor (buffer);
678        ++output_buffer_text_cursor (buffer))
679     {
680       int long_integer = 0;
681
682       /* Ignore text.  */
683       {
684         const char *p = output_buffer_text_cursor (buffer);
685         while (*p && *p != '%')
686           ++p;
687         wrap_text (buffer, output_buffer_text_cursor (buffer), p);
688         output_buffer_text_cursor (buffer) = p;
689       }
690
691       if (!*output_buffer_text_cursor (buffer))
692         break;
693
694       /* We got a '%'.  Let's see what happens. Record whether we're
695          parsing a long integer format specifier.  */
696       if (*++output_buffer_text_cursor (buffer) == 'l')
697         {
698           long_integer = 1;
699           ++output_buffer_text_cursor (buffer);
700         }
701
702       /* Handle %c, %d, %i, %ld, %li, %lo, %lu, %lx, %o, %s, %u,
703          %x, %.*s; %%.  And nothing else.  Front-ends should install
704          printers to grok language specific format specifiers.  */
705       switch (*output_buffer_text_cursor (buffer))
706         {
707         case 'c':
708           output_add_character
709             (buffer, va_arg (output_buffer_format_args (buffer), int));
710           break;
711           
712         case 'd':
713         case 'i':
714           if (long_integer)
715             output_long_decimal
716               (buffer, va_arg (output_buffer_format_args (buffer), long int));
717           else
718             output_decimal
719               (buffer, va_arg (output_buffer_format_args (buffer), int));
720           break;
721
722         case 'o':
723           if (long_integer)
724             output_long_octal (buffer,
725                                va_arg (output_buffer_format_args (buffer),
726                                        unsigned long int));
727           else
728             output_octal (buffer,
729                           va_arg (output_buffer_format_args (buffer),
730                                   unsigned int));
731           break;
732
733         case 's':
734           output_add_string (buffer,
735                              va_arg (output_buffer_format_args (buffer),
736                                      const char *));
737           break;
738
739         case 'u':
740           if (long_integer)
741             output_long_unsigned_decimal
742               (buffer, va_arg (output_buffer_format_args (buffer),
743                                long unsigned int));
744           else
745             output_unsigned_decimal
746               (buffer, va_arg (output_buffer_format_args (buffer),
747                                unsigned int));
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 }