OSDN Git Service

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