OSDN Git Service

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