OSDN Git Service

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