OSDN Git Service

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