OSDN Git Service

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