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