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