This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

diagnostic.c reorganization


I'm trying to do some work which should touch diagnostic.c only
peripherally, but there are internal inconsistencies in there which
require me to do some cleanup first.  This is patch one of two, which
primarily sorts the functions in the file by category.
inform/warning/pedwarn/error/sorry/fatal_error/internal_error are all
right next to each other now, as are the _with_decl variants.  I also
added some comments, and folded vbuild_message_string into its sole
caller.

zw

        * 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.

===================================================================
Index: diagnostic.c
--- diagnostic.c	9 May 2003 10:08:19 -0000	1.110
+++ diagnostic.c	11 May 2003 02:03:26 -0000
@@ -51,8 +51,6 @@ static void output_buffer_to_stream PARA
 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 cha
   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, ki
   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 = ≈
-  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 (cont
 }
 
 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;
 }
+
+/* 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.  */
+
+/* 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);
 }
+
+/* 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;
@@ -1413,6 +1376,58 @@ warn_deprecated_use (node)
       else
 	warning ("type is deprecated");
     }
+}
+
+/* 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]