OSDN Git Service

* diagnostic.c: Reorder functions for clarity, putting all the
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 11 May 2003 02:06:12 +0000 (02:06 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 11 May 2003 02:06:12 +0000 (02:06 +0000)
functions in the "error" family next to each other, and
likewise all the functions in the "error_with_decl" family.
Some other routines were moved too.  Add comments.
(vbuild_message_string): Fold into sole caller.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66676 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/diagnostic.c

index cbc986a..2cdd153 100644 (file)
@@ -1,3 +1,12 @@
+2003-05-10  Zack Weinberg  <zack@codesourcery.com>
+
+       * diagnostic.c: Reorder functions for clarity, putting all the
+       functions in the "error" family next to each other, and
+       likewise all the functions in the "error_with_decl" family.
+       Some other routines were moved too.  Add comments.
+       (vbuild_message_string): Fold into sole caller.
+
+
 2003-05-11  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * except.c (EH_RETURN_STACKADJ_RTX): Do not define.
 
 2003-05-10  Richard Earnshaw  <rearnsha@arm.com>
 
-       * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New 
+       * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New
        constants.
        (ior_scc_scc, and_scc_scc): New insn_and_split patterns.
-       * arm.c (arm_select_dominance_cc_mode): Renamed from 
+       * arm.c (arm_select_dominance_cc_mode): Renamed from
        select_dominance_cc_mode, no-longer static.  Use DOM_CC... constants.
        Callers updated.
        * arm-protos.h (arm_select_dominance_cc_mode): Add prototype.
        (if_stmt_file): Remove.
        (if_stmt_line): Likewise.
        * jump.c: include "diagnostic.h"
-       (never_reached_warning): Don't use warning_with_file_and_line. 
+       (never_reached_warning): Don't use warning_with_file_and_line.
        * Makefile.in (jump.o): Add dependce on diagnostic.h
 
 2003-05-09  Alan Modra  <amodra@bigpond.net.au>
 
 2003-05-08  Aldy Hernandez  <aldyh@redhat.com>
 
-        * mklibgcc.in: Use mkinstalldirs when installing multilib
-        directories.
+       * mklibgcc.in: Use mkinstalldirs when installing multilib
+       directories.
 
 2003-05-08  J"orn Rennecke <joern.rennecke@superh.com>
 
 2003-05-08  Gabriel Dos Reis <gdr@integrable-solutions.net>
 
        * objc/objc-act.c (error_with_ivar): Don't use
-       error_with_file_and_line. 
+       error_with_file_and_line.
        (warn_with_method): Don't use warning_with_file_and_line.
 
 2003-05-08  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
 2003-05-07  David Mosberger <davidm@hpl.hp.com>
 
-        * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
+       * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
 
 2003-05-07  Richard Henderson  <rth@redhat.com>
 
 
 2003-05-07  David Mosberger <davidm@hpl.hp.com>
 
-        * config/ia64/crtbegin.asm (__do_jv_register_classes): Don't
+       * config/ia64/crtbegin.asm (__do_jv_register_classes): Don't
        forget to preserve gp.
-        * config/ia64/crtend.asm (__do_global_ctors_au): Ditto.
-
-        * config/ia64/crtbegin.asm (__do_jv_register_classes): Add missing
-        .prologue directive.
-        Use .skip instead of data8 for .bss section to make Intel
-        Assembler (ias) happy.  Minor whitespace fixups.  Make "nop 0"
-        explicit in the .mib bundles and remove the unnecessary stop
-        bits.  Replace local labels with normal labels, to make ias
-        happy.  Don't register __do_global_ctors_aux here, do it in
-        crtend.asm instead.
-
-        * config/ia64/crtend.asm [HAVE_INIT_FINI_ARRAY]: Register
-        __do_global_ctors_aux in .init_array section instead of
-        declaring it as a hidden global.  Replace local labels with
-        ordinary labels to make ias happy.
+       * config/ia64/crtend.asm (__do_global_ctors_au): Ditto.
+
+       * config/ia64/crtbegin.asm (__do_jv_register_classes): Add missing
+       .prologue directive.
+       Use .skip instead of data8 for .bss section to make Intel
+       Assembler (ias) happy.  Minor whitespace fixups.  Make "nop 0"
+       explicit in the .mib bundles and remove the unnecessary stop
+       bits.  Replace local labels with normal labels, to make ias
+       happy.  Don't register __do_global_ctors_aux here, do it in
+       crtend.asm instead.
+
+       * config/ia64/crtend.asm [HAVE_INIT_FINI_ARRAY]: Register
+       __do_global_ctors_aux in .init_array section instead of
+       declaring it as a hidden global.  Replace local labels with
+       ordinary labels to make ias happy.
 
 2003-05-07  Richard Henderson  <rth@redhat.com>
 
-        PR c++/10570
-        * except.c: Revert 04-01 and 04-02 forced-unwind changes.
-        * flags.h, toplev.c, doc/invoke.texi: Likewise.
+       PR c++/10570
+       * except.c: Revert 04-01 and 04-02 forced-unwind changes.
+       * flags.h, toplev.c, doc/invoke.texi: Likewise.
 
-        * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning.
-        * unwind.inc (_Unwind_DeleteException): Check for null
-        exception_cleanup.
+       * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning.
+       * unwind.inc (_Unwind_DeleteException): Check for null
+       exception_cleanup.
 
-        * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New.
-        * unwind.inc (_Unwind_Resume_or_Rethrow): New.
-        * unwind.h: Declare them.
-        * libgcc-std.ver (GCC_3.3): Export them.
+       * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New.
+       * unwind.inc (_Unwind_Resume_or_Rethrow): New.
+       * unwind.h: Declare them.
+       * libgcc-std.ver (GCC_3.3): Export them.
 
 2003-05-07  Richard Henderson  <rth@redhat.com>
 
index e7e39ba..ce6c8bc 100644 (file)
@@ -51,8 +51,6 @@ static void output_buffer_to_stream PARAMS ((output_buffer *));
 static void output_format PARAMS ((output_buffer *, text_info *));
 static void output_indent PARAMS ((output_buffer *));
 
-static char *vbuild_message_string PARAMS ((const char *, va_list))
-     ATTRIBUTE_PRINTF (1, 0);
 static char *build_message_string PARAMS ((const char *, ...))
      ATTRIBUTE_PRINTF_1;
 static void format_with_decl PARAMS ((output_buffer *, text_info *, tree));
@@ -388,6 +386,9 @@ output_append (buffer, start, end)
   output_append_r (buffer, start, end - start);
 }
 
+/* Insert enough spaces into BUFFER to bring the column position to
+   the current indentation level, assuming that a newline has just
+   been written to the buffer.  */
 static void
 output_indent (buffer)
      output_buffer *buffer;
@@ -616,19 +617,8 @@ output_format (buffer, text)
     }
 }
 
-static char *
-vbuild_message_string (msg, ap)
-     const char *msg;
-     va_list ap;
-{
-  char *str;
-
-  vasprintf (&str, msg, ap);
-  return str;
-}
-
-/*  Return a malloc'd string containing MSG formatted a la
-    printf.  The caller is responsible for freeing the memory.  */
+/* Return a malloc'd string containing MSG formatted a la printf.  The
+   caller is responsible for freeing the memory.  */
 static char *
 build_message_string VPARAMS ((const char *msg, ...))
 {
@@ -637,7 +627,7 @@ build_message_string VPARAMS ((const char *msg, ...))
   VA_OPEN (ap, msg);
   VA_FIXEDARG (ap, const char *, msg);
 
-  str = vbuild_message_string (msg, ap);
+  vasprintf (&str, msg, ap);
 
   VA_CLOSE (ap);
 
@@ -851,29 +841,6 @@ diagnostic_build_prefix (diagnostic)
                             _(diagnostic_kind_text[diagnostic->kind]));
 }
 
-/* Report a diagnostic MESSAGE at the declaration DECL.
-   MSG is a format string which uses %s to substitute the declaration
-   name; subsequent substitutions are a la output_format.  */
-static void
-diagnostic_for_decl (diagnostic, decl)
-     diagnostic_info *diagnostic;
-     tree decl;
-{
-  if (global_dc->lock++)
-    error_recursion (global_dc);
-
-  if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
-    {
-      diagnostic_report_current_function (global_dc);
-      output_set_prefix
-       (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
-      format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
-      output_flush (&global_dc->buffer);
-      output_destroy_prefix (&global_dc->buffer);
-    }
-  global_dc->lock--;
-}
-
 void
 diagnostic_flush_buffer (context)
      diagnostic_context *context;
@@ -923,96 +890,6 @@ diagnostic_count_diagnostic (context, kind)
   return true;
 }
 
-/* Print a diagnostic MSGID on FILE.  This is just fprintf, except it
-   runs its second argument through gettext.  */
-void
-fnotice VPARAMS ((FILE *file, const char *msgid, ...))
-{
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, FILE *, file);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  vfprintf (file, _(msgid), ap);
-  VA_CLOSE (ap);
-}
-
-
-/* Print a fatal I/O error message.  Argument are like printf.
-   Also include a system error message based on `errno'.  */
-void
-fatal_io_error VPARAMS ((const char *msgid, ...))
-{
-  text_info text;
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  text.format_spec = _(msgid);
-  text.args_ptr = &ap;
-  output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
-  output_format (&global_dc->buffer, &text);
-  output_flush (&global_dc->buffer);
-  VA_CLOSE (ap);
-  exit (FATAL_EXIT_CODE);
-}
-
-/* Issue a pedantic warning MSGID.  */
-void
-pedwarn VPARAMS ((const char *msgid, ...))
-{
-  diagnostic_info diagnostic;
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, input_line,
-                       pedantic_error_kind ());
-  report_diagnostic (&diagnostic);
-  VA_CLOSE (ap);
-}
-
-/* Issue a pedantic warning about DECL.  */
-void
-pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
-{
-  diagnostic_info diagnostic;
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, tree, decl);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  diagnostic_set_info (&diagnostic, _(msgid), &ap,
-                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
-                       pedantic_error_kind ());
-
-  /* We don't want -pedantic-errors to cause the compilation to fail from
-     "errors" in system header files.  Sometimes fixincludes can't fix what's
-     broken (eg: unsigned char bitfields - fixing it may change the alignment
-     which will cause programs to mysteriously fail because the C library
-     or kernel uses the original layout).  There's no point in issuing a
-     warning either, it's just unnecessary noise.  */
-  if (!DECL_IN_SYSTEM_HEADER (decl))
-    diagnostic_for_decl (&diagnostic, decl);
-  VA_CLOSE (ap);
-}
-
-/* Just apologize with MSGID.  */
-void
-sorry VPARAMS ((const char *msgid, ...))
-{
-  diagnostic_info diagnostic;
-
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  ++sorrycount;
-  diagnostic_set_info (&diagnostic, _(msgid), &ap,
-                       input_filename, input_line, DK_SORRY);
-
-  output_set_prefix
-    (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
-  output_format (&global_dc->buffer, &diagnostic.message);
-  output_flush (&global_dc->buffer);
-  VA_CLOSE (ap);
-}
-
 /* Called when the start of a function definition is parsed,
    this function prints on stderr the name of the function.  */
 void
@@ -1080,107 +957,183 @@ diagnostic_report_current_function (context)
 }
 
 void
-error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
+diagnostic_report_current_module (context)
+     diagnostic_context *context;
 {
-  diagnostic_info diagnostic;
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, tree, decl);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  diagnostic_set_info (&diagnostic, msgid, &ap,
-                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
-                       DK_ERROR);
-  diagnostic_for_decl (&diagnostic, decl);
-  VA_CLOSE (ap);
-}
+  struct file_stack *p;
 
+  if (output_needs_newline (&context->buffer))
+    {
+      output_add_newline (&context->buffer);
+      output_needs_newline (&context->buffer) = false;
+    }
 
-/* Report an error message.  The arguments are like that of printf.  */
+  if (input_file_stack && input_file_stack->next != 0
+      && diagnostic_last_module_changed (context))
+    {
+      for (p = input_file_stack->next; p; p = p->next)
+       if (p == input_file_stack->next)
+         output_verbatim (&context->buffer,
+                           "In file included from %s:%d",
+                          p->location.file, p->location.line);
+       else
+         output_verbatim (&context->buffer,
+                           ",\n                 from %s:%d",
+                          p->location.file, p->location.line);
+      output_verbatim (&context->buffer, ":\n");
+      diagnostic_set_last_module (context);
+    }
+}
 
-void
-error VPARAMS ((const char *msgid, ...))
+static void
+default_diagnostic_starter (context, diagnostic)
+     diagnostic_context *context;
+     diagnostic_info *diagnostic;
 {
-  diagnostic_info diagnostic;
-
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  diagnostic_report_current_function (context);
+  output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
+}
 
-  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
-                       DK_ERROR);
-  report_diagnostic (&diagnostic);
-  VA_CLOSE (ap);
+static void
+default_diagnostic_finalizer (context, diagnostic)
+     diagnostic_context *context;
+     diagnostic_info *diagnostic __attribute__((unused));
+{
+  output_destroy_prefix (&context->buffer);
 }
 
-/* Likewise, except that the compilation is terminated after printing the
-   error message.  */
+/* Report a diagnostic message (an error or a warning) as specified by
+   DC.  This function is *the* subroutine in terms of which front-ends
+   should implement their specific diagnostic handling modules.  The
+   front-end independent format specifiers are exactly those described
+   in the documentation of output_format.  */
 
 void
-fatal_error VPARAMS ((const char *msgid, ...))
+diagnostic_report_diagnostic (context, diagnostic)
+     diagnostic_context *context;
+     diagnostic_info *diagnostic;
 {
-  diagnostic_info diagnostic;
-
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  if (context->lock++)
+    error_recursion (context);
 
-  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
-                       DK_FATAL);
-  report_diagnostic (&diagnostic);
-  VA_CLOSE (ap);
+  if (diagnostic_count_diagnostic (context, diagnostic->kind))
+    {
+      (*diagnostic_starter (context)) (context, diagnostic);
+      output_format (&context->buffer, &diagnostic->message);
+      (*diagnostic_finalizer (context)) (context, diagnostic);
+      output_flush (&context->buffer);
+    }
 
-  fnotice (stderr, "compilation terminated.\n");
-  exit (FATAL_EXIT_CODE);
+  if (context->abort_on_error && diagnostic->kind <= DK_ERROR)
+    real_abort();
+  --context->lock;
 }
 
-void
-internal_error VPARAMS ((const char *msgid, ...))
+/* Report a diagnostic MESSAGE at the declaration DECL.
+   MSG is a format string which uses %s to substitute the declaration
+   name; subsequent substitutions are a la output_format.  */
+static void
+diagnostic_for_decl (diagnostic, decl)
+     diagnostic_info *diagnostic;
+     tree decl;
 {
-  diagnostic_info diagnostic;
-
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
-
-  if (global_dc->lock)
+  if (global_dc->lock++)
     error_recursion (global_dc);
 
-#ifndef ENABLE_CHECKING
-  if (errorcount > 0 || sorrycount > 0)
+  if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
     {
-      fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
-              input_filename, input_line);
-      exit (FATAL_EXIT_CODE);
+      diagnostic_report_current_function (global_dc);
+      output_set_prefix
+       (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
+      format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
+      output_flush (&global_dc->buffer);
+      output_destroy_prefix (&global_dc->buffer);
     }
-#endif
+  global_dc->lock--;
+}
 
-  if (global_dc->internal_error != 0)
-    (*global_dc->internal_error) (_(msgid), &ap);
+/* Given a partial pathname as input, return another pathname that
+   shares no directory elements with the pathname of __FILE__.  This
+   is used by fancy_abort() to print `Internal compiler error in expr.c'
+   instead of `Internal compiler error in ../../GCC/gcc/expr.c'.  */
 
-  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
-                       DK_ICE);
-  report_diagnostic (&diagnostic);
-  VA_CLOSE (ap);
+const char *
+trim_filename (name)
+     const char *name;
+{
+  static const char this_file[] = __FILE__;
+  const char *p = name, *q = this_file;
 
-  fnotice (stderr,
-"Please submit a full bug report,\n\
-with preprocessed source if appropriate.\n\
-See %s for instructions.\n", bug_report_url);
-  exit (FATAL_EXIT_CODE);
+  /* First skip any "../" in each filename.  This allows us to give a proper
+     reference to a file in a subdirectory.  */
+  while (p[0] == '.' && p[1] == '.'
+        && (p[2] == DIR_SEPARATOR
+#ifdef DIR_SEPARATOR_2
+            || p[2] == DIR_SEPARATOR_2
+#endif
+            ))
+    p += 3;
+
+  while (q[0] == '.' && q[1] == '.'
+        && (q[2] == DIR_SEPARATOR
+#ifdef DIR_SEPARATOR_2
+            || p[2] == DIR_SEPARATOR_2
+#endif
+            ))
+    q += 3;
+
+  /* Now skip any parts the two filenames have in common.  */
+  while (*p == *q && *p != 0 && *q != 0)
+    p++, q++;
+
+  /* Now go backwards until the previous directory separator.  */
+  while (p > name && p[-1] != DIR_SEPARATOR
+#ifdef DIR_SEPARATOR_2
+        && p[-1] != DIR_SEPARATOR_2
+#endif
+        )
+    p--;
+
+  return p;
 }
+\f
+/* Standard error reporting routines in increasing order of severity.
+   All of these take arguments like printf.  */
 
+/* Text to be emitted verbatim to the error message stream; this
+   produces no prefix and disables line-wrapping.  Use rarely.  */
 void
-warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
+verbatim VPARAMS ((const char *msgid, ...))
+{
+  text_info text;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+
+  text.format_spec = _(msgid);
+  text.args_ptr = &ap;
+  output_do_verbatim (&global_dc->buffer, &text);
+  output_buffer_to_stream (&global_dc->buffer);
+  VA_CLOSE (ap);
+}
+
+/* An informative note.  Use this for additional details on an error
+   message.  */
+void
+inform VPARAMS ((const char *msgid, ...))
 {
   diagnostic_info diagnostic;
+
   VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, tree, decl);
   VA_FIXEDARG (ap, const char *, msgid);
 
-  diagnostic_set_info (&diagnostic, msgid, &ap,
-                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
-                       DK_WARNING);
-  diagnostic_for_decl (&diagnostic, decl);
+  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
+                       DK_NOTE);
+  report_diagnostic (&diagnostic);
   VA_CLOSE (ap);
 }
 
+/* A warning.  Use this for code which is correct according to the
+   relevant language specification but is likely to be buggy anyway.  */
 void
 warning VPARAMS ((const char *msgid, ...))
 {
@@ -1195,188 +1148,198 @@ warning VPARAMS ((const char *msgid, ...))
   VA_CLOSE (ap);
 }
 
+/* A "pedantic" warning.  Use this for code which triggers a
+   diagnostic which is required by the relevant language
+   specification, but which is considered unhelpful (i.e. there isn't
+   anything *really* wrong with the construct in the language as she
+   is spoke).  It is a normal warning unless -pedantic-errors is
+   applied, which turns it into an error.  Note that pedwarn-s still
+   happen if -pedantic is not given; you must write
+   "if (pedantic) pedwarn (...)" to get a warning enabled only under
+   -pedantic.  All such warnings should, however, use pedwarn.  */
+void
+pedwarn VPARAMS ((const char *msgid, ...))
+{
+  diagnostic_info diagnostic;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-/* Same as above but use diagnostic_buffer.  */
+  diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, input_line,
+                       pedantic_error_kind ());
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
+}
 
+/* A hard error: the code is definitely ill-formed, and an object file
+   will not be produced.  */
 void
-verbatim VPARAMS ((const char *msgid, ...))
+error VPARAMS ((const char *msgid, ...))
 {
-  text_info text;
+  diagnostic_info diagnostic;
+
   VA_OPEN (ap, msgid);
   VA_FIXEDARG (ap, const char *, msgid);
 
-  text.format_spec = _(msgid);
-  text.args_ptr = &ap;
-  output_do_verbatim (&global_dc->buffer, &text);
-  output_buffer_to_stream (&global_dc->buffer);
+  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
+                       DK_ERROR);
+  report_diagnostic (&diagnostic);
   VA_CLOSE (ap);
 }
 
-/* Report a diagnostic message (an error or a warning) as specified by
-   DC.  This function is *the* subroutine in terms of which front-ends
-   should implement their specific diagnostic handling modules.  The
-   front-end independent format specifiers are exactly those described
-   in the documentation of output_format.  */
-
+/* "Sorry, not implemented."  Use for a language feature which is
+   required by the relevant specification but not implemented by GCC.
+   An object file will not be produced.  */
 void
-diagnostic_report_diagnostic (context, diagnostic)
-     diagnostic_context *context;
-     diagnostic_info *diagnostic;
+sorry VPARAMS ((const char *msgid, ...))
 {
-  if (context->lock++)
-    error_recursion (context);
+  diagnostic_info diagnostic;
 
-  if (diagnostic_count_diagnostic (context, diagnostic->kind))
-    {
-      (*diagnostic_starter (context)) (context, diagnostic);
-      output_format (&context->buffer, &diagnostic->message);
-      (*diagnostic_finalizer (context)) (context, diagnostic);
-      output_flush (&context->buffer);
-    }
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-  if (context->abort_on_error && diagnostic->kind <= DK_ERROR)
-    real_abort();
-  --context->lock;
-}
+  ++sorrycount;
+  diagnostic_set_info (&diagnostic, _(msgid), &ap,
+                       input_filename, input_line, DK_SORRY);
 
-/* Inform the user that an error occurred while trying to report some
-   other error.  This indicates catastrophic internal inconsistencies,
-   so give up now.  But do try to flush out the previous error.
-   This mustn't use internal_error, that will cause infinite recursion.  */
+  output_set_prefix
+    (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
+  output_format (&global_dc->buffer, &diagnostic.message);
+  output_flush (&global_dc->buffer);
+  VA_CLOSE (ap);
+}
 
-static void
-error_recursion (context)
-     diagnostic_context *context;
+/* An error which is severe enough that we make no attempt to
+   continue.  Do not use this for internal consistency checks; that's
+   internal_error.  Use of this function should be rare.  */
+void
+fatal_error VPARAMS ((const char *msgid, ...))
 {
-  if (context->lock < 3)
-    output_flush (&context->buffer);
+  diagnostic_info diagnostic;
 
-  fnotice (stderr,
-          "Internal compiler error: Error reporting routines re-entered.\n");
-  fnotice (stderr,
-"Please submit a full bug report,\n\
-with preprocessed source if appropriate.\n\
-See %s for instructions.\n", bug_report_url);
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+
+  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
+                       DK_FATAL);
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
+
+  fnotice (stderr, "compilation terminated.\n");
   exit (FATAL_EXIT_CODE);
 }
 
-/* Given a partial pathname as input, return another pathname that
-   shares no directory elements with the pathname of __FILE__.  This
-   is used by fancy_abort() to print `Internal compiler error in expr.c'
-   instead of `Internal compiler error in ../../GCC/gcc/expr.c'.  */
-
-const char *
-trim_filename (name)
-     const char *name;
+/* An internal consistency check has failed.  We make no attempt to
+   continue.  Note that unless there is debugging value to be had from
+   a more specific message, or some other good reason, you should use
+   abort () instead of calling this function directly.  */
+void
+internal_error VPARAMS ((const char *msgid, ...))
 {
-  static const char this_file[] = __FILE__;
-  const char *p = name, *q = this_file;
+  diagnostic_info diagnostic;
 
-  /* First skip any "../" in each filename.  This allows us to give a proper
-     reference to a file in a subdirectory.  */
-  while (p[0] == '.' && p[1] == '.'
-        && (p[2] == DIR_SEPARATOR
-#ifdef DIR_SEPARATOR_2
-            || p[2] == DIR_SEPARATOR_2
-#endif
-            ))
-    p += 3;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-  while (q[0] == '.' && q[1] == '.'
-        && (q[2] == DIR_SEPARATOR
-#ifdef DIR_SEPARATOR_2
-            || p[2] == DIR_SEPARATOR_2
+  if (global_dc->lock)
+    error_recursion (global_dc);
+
+#ifndef ENABLE_CHECKING
+  if (errorcount > 0 || sorrycount > 0)
+    {
+      fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
+              input_filename, input_line);
+      exit (FATAL_EXIT_CODE);
+    }
 #endif
-            ))
-    q += 3;
 
-  /* Now skip any parts the two filenames have in common.  */
-  while (*p == *q && *p != 0 && *q != 0)
-    p++, q++;
+  if (global_dc->internal_error != 0)
+    (*global_dc->internal_error) (_(msgid), &ap);
 
-  /* Now go backwards until the previous directory separator.  */
-  while (p > name && p[-1] != DIR_SEPARATOR
-#ifdef DIR_SEPARATOR_2
-        && p[-1] != DIR_SEPARATOR_2
-#endif
-        )
-    p--;
+  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
+                       DK_ICE);
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
 
-  return p;
+  fnotice (stderr,
+"Please submit a full bug report,\n\
+with preprocessed source if appropriate.\n\
+See %s for instructions.\n", bug_report_url);
+  exit (FATAL_EXIT_CODE);
 }
-
-/* Report an internal compiler error in a friendly manner and without
-   dumping core.  */
+\f
+/* Variants of some of the above, which make reference to a particular
+   DECL node.  These are deprecated.  */
 
 void
-fancy_abort (file, line, function)
-     const char *file;
-     int line;
-     const char *function;
+warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
-  internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
+  diagnostic_info diagnostic;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, tree, decl);
+  VA_FIXEDARG (ap, const char *, msgid);
+
+  diagnostic_set_info (&diagnostic, msgid, &ap,
+                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
+                       DK_WARNING);
+  diagnostic_for_decl (&diagnostic, decl);
+  VA_CLOSE (ap);
 }
 
 void
-diagnostic_report_current_module (context)
-     diagnostic_context *context;
+pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
-  struct file_stack *p;
+  diagnostic_info diagnostic;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, tree, decl);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-  if (output_needs_newline (&context->buffer))
-    {
-      output_add_newline (&context->buffer);
-      output_needs_newline (&context->buffer) = false;
-    }
+  diagnostic_set_info (&diagnostic, _(msgid), &ap,
+                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
+                       pedantic_error_kind ());
 
-  if (input_file_stack && input_file_stack->next != 0
-      && diagnostic_last_module_changed (context))
-    {
-      for (p = input_file_stack->next; p; p = p->next)
-       if (p == input_file_stack->next)
-         output_verbatim (&context->buffer,
-                           "In file included from %s:%d",
-                          p->location.file, p->location.line);
-       else
-         output_verbatim (&context->buffer,
-                           ",\n                 from %s:%d",
-                          p->location.file, p->location.line);
-      output_verbatim (&context->buffer, ":\n");
-      diagnostic_set_last_module (context);
-    }
+  /* We don't want -pedantic-errors to cause the compilation to fail from
+     "errors" in system header files.  Sometimes fixincludes can't fix what's
+     broken (eg: unsigned char bitfields - fixing it may change the alignment
+     which will cause programs to mysteriously fail because the C library
+     or kernel uses the original layout).  There's no point in issuing a
+     warning either, it's just unnecessary noise.  */
+  if (!DECL_IN_SYSTEM_HEADER (decl))
+    diagnostic_for_decl (&diagnostic, decl);
+  VA_CLOSE (ap);
 }
 
-static void
-default_diagnostic_starter (context, diagnostic)
-     diagnostic_context *context;
-     diagnostic_info *diagnostic;
+void
+error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
 {
-  diagnostic_report_current_function (context);
-  output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
-}
+  diagnostic_info diagnostic;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, tree, decl);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-static void
-default_diagnostic_finalizer (context, diagnostic)
-     diagnostic_context *context;
-     diagnostic_info *diagnostic __attribute__((unused));
-{
-  output_destroy_prefix (&context->buffer);
+  diagnostic_set_info (&diagnostic, msgid, &ap,
+                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
+                       DK_ERROR);
+  diagnostic_for_decl (&diagnostic, decl);
+  VA_CLOSE (ap);
 }
+\f
+/* Special case error functions.  Most are implemented in terms of the
+   above, or should be.  */
 
+/* Print a diagnostic MSGID on FILE.  This is just fprintf, except it
+   runs its second argument through gettext.  */
 void
-inform VPARAMS ((const char *msgid, ...))
+fnotice VPARAMS ((FILE *file, const char *msgid, ...))
 {
-  diagnostic_info diagnostic;
-
   VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, FILE *, file);
   VA_FIXEDARG (ap, const char *, msgid);
 
-  diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, input_line,
-                       DK_NOTE);
-  report_diagnostic (&diagnostic);
+  vfprintf (file, _(msgid), ap);
   VA_CLOSE (ap);
 }
 
+/* Warn about a use of an identifier which was marked deprecated.  */
 void
 warn_deprecated_use (node)
      tree node;
@@ -1415,6 +1378,58 @@ warn_deprecated_use (node)
     }
 }
 
+/* Print a fatal I/O error message.  Argument are like printf.
+   Also include a system error message based on `errno'.  */
+void
+fatal_io_error VPARAMS ((const char *msgid, ...))
+{
+  text_info text;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+
+  text.format_spec = _(msgid);
+  text.args_ptr = &ap;
+  output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
+  output_format (&global_dc->buffer, &text);
+  output_flush (&global_dc->buffer);
+  VA_CLOSE (ap);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Inform the user that an error occurred while trying to report some
+   other error.  This indicates catastrophic internal inconsistencies,
+   so give up now.  But do try to flush out the previous error.
+   This mustn't use internal_error, that will cause infinite recursion.  */
+
+static void
+error_recursion (context)
+     diagnostic_context *context;
+{
+  if (context->lock < 3)
+    output_flush (&context->buffer);
+
+  fnotice (stderr,
+          "Internal compiler error: Error reporting routines re-entered.\n");
+  fnotice (stderr,
+"Please submit a full bug report,\n\
+with preprocessed source if appropriate.\n\
+See %s for instructions.\n", bug_report_url);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Report an internal compiler error in a friendly manner.  This is
+   the function that gets called upon use of abort() in the source
+   code generally, thanks to a special macro.  */
+
+void
+fancy_abort (file, line, function)
+     const char *file;
+     int line;
+     const char *function;
+{
+  internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
+}
+
 /* Really call the system 'abort'.  This has to go right at the end of
    this file, so that there are no functions after it that call abort
    and get the system abort instead of our macro.  */