OSDN Git Service

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