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