OSDN Git Service

PR debug/43516
[pf3gnuchains/gcc-fork.git] / gcc / diagnostic.c
index 28217a7..eee97ce 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009 Free Software Foundation, Inc.
+   2009, 2010 Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
 
 This file is part of GCC.
@@ -24,21 +24,14 @@ along with GCC; see the file COPYING3.  If not see
    message module.  */
 
 #include "config.h"
-#undef FLOAT /* This is for hpux. They should change hpux.  */
-#undef FFS  /* Some systems define this in param.h.  */
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
 #include "version.h"
-#include "tm_p.h"
 #include "flags.h"
 #include "input.h"
 #include "toplev.h"
 #include "intl.h"
 #include "diagnostic.h"
-#include "langhooks.h"
-#include "langhooks-def.h"
 #include "opts.h"
 #include "plugin.h"
 
@@ -97,7 +90,7 @@ diagnostic_initialize (diagnostic_context *context)
   context->printer->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
 
   memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
-  context->issue_warnings_are_errors_message = true;
+  context->some_warnings_are_errors = false;
   context->warning_as_error_requested = false;
   memset (context->classify_diagnostic, DK_UNSPECIFIED,
          sizeof context->classify_diagnostic);
@@ -107,8 +100,31 @@ diagnostic_initialize (diagnostic_context *context)
   diagnostic_starter (context) = default_diagnostic_starter;
   diagnostic_finalizer (context) = default_diagnostic_finalizer;
   context->last_module = 0;
-  context->last_function = NULL;
+  context->x_data = NULL;
   context->lock = 0;
+  context->inhibit_notes_p = false;
+}
+
+/* Do any cleaning up required after the last diagnostic is emitted.  */
+
+void
+diagnostic_finish (diagnostic_context *context)
+{
+  /* Some of the errors may actually have been warnings.  */
+  if (context->some_warnings_are_errors)
+    {
+      /* -Werror was given.  */
+      if (context->warning_as_error_requested)
+       pp_verbatim (context->printer,
+                    _("%s: all warnings being treated as errors\n"),
+                    progname);
+      /* At least one -Werror= was given.  */
+      else
+       pp_verbatim (context->printer,
+                    _("%s: some warnings being treated as errors\n"),
+                    progname);
+      pp_flush (context->printer);
+    }
 }
 
 /* Initialize DIAGNOSTIC, where the message MSG has already been
@@ -183,6 +199,7 @@ diagnostic_action_after_output (diagnostic_context *context,
       if (flag_fatal_errors)
        {
          fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
+         diagnostic_finish (context);
          exit (FATAL_EXIT_CODE);
        }
       break;
@@ -199,7 +216,7 @@ diagnostic_action_after_output (diagnostic_context *context,
     case DK_FATAL:
       if (context->abort_on_error)
        real_abort ();
-
+      diagnostic_finish (context);
       fnotice (stderr, "compilation terminated.\n");
       exit (FATAL_EXIT_CODE);
 
@@ -208,16 +225,6 @@ diagnostic_action_after_output (diagnostic_context *context,
     }
 }
 
-/* Prints out, if necessary, the name of the current function
-   that caused an error.  Called from all error and warning functions.  */
-void
-diagnostic_report_current_function (diagnostic_context *context,
-                                   diagnostic_info *diagnostic)
-{
-  diagnostic_report_current_module (context);
-  lang_hooks.print_error_function (context, input_filename, diagnostic);
-}
-
 void
 diagnostic_report_current_module (diagnostic_context *context)
 {
@@ -265,7 +272,7 @@ void
 default_diagnostic_starter (diagnostic_context *context,
                            diagnostic_info *diagnostic)
 {
-  diagnostic_report_current_function (context, diagnostic);
+  diagnostic_report_current_module (context);
   pp_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
 }
 
@@ -308,7 +315,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
                              diagnostic_info *diagnostic)
 {
   location_t location = diagnostic->location;
-  bool maybe_print_warnings_as_errors_message = false;
+  diagnostic_t orig_diag_kind = diagnostic->kind;
   const char *saved_format_spec;
 
   /* Give preference to being able to inhibit warnings, before they
@@ -317,11 +324,15 @@ diagnostic_report_diagnostic (diagnostic_context *context,
       && !diagnostic_report_warnings_p (location))
     return false;
 
-  if (diagnostic->kind == DK_NOTE && flag_compare_debug)
-    return false;
-
   if (diagnostic->kind == DK_PEDWARN)
-    diagnostic->kind = pedantic_warning_kind ();
+    {
+      diagnostic->kind = pedantic_warning_kind ();
+      /* We do this to avoid giving the message for -pedantic-errors.  */
+      orig_diag_kind = diagnostic->kind;
+    }
+  if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
+    return false;
 
   if (context->lock > 0)
     {
@@ -342,7 +353,6 @@ diagnostic_report_diagnostic (diagnostic_context *context,
       && diagnostic->kind == DK_WARNING)
     {
       diagnostic->kind = DK_ERROR;
-      maybe_print_warnings_as_errors_message = true;
     }
 
   if (diagnostic->option_index)
@@ -356,7 +366,6 @@ diagnostic_report_diagnostic (diagnostic_context *context,
       if (context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED)
        {
          diagnostic->kind = context->classify_diagnostic[diagnostic->option_index];
-         maybe_print_warnings_as_errors_message = false;
        }
       /* This allows for future extensions, like temporarily disabling
         warnings for ranges of source code.  */
@@ -364,15 +373,8 @@ diagnostic_report_diagnostic (diagnostic_context *context,
        return false;
     }
 
-  /* If we changed the kind due to -Werror, and didn't override it, we
-     need to print this message.  */
-  if (context->issue_warnings_are_errors_message
-      && maybe_print_warnings_as_errors_message)
-    {
-      pp_verbatim (context->printer,
-                  "%s: warnings being treated as errors\n", progname);
-      context->issue_warnings_are_errors_message = false;
-    }
+  if (orig_diag_kind == DK_WARNING && diagnostic->kind == DK_ERROR)
+    context->some_warnings_are_errors = true;
 
   context->lock++;
 
@@ -407,14 +409,44 @@ diagnostic_report_diagnostic (diagnostic_context *context,
   ++diagnostic_kind_count (context, diagnostic->kind);
 
   saved_format_spec = diagnostic->message.format_spec;
-  if (context->show_option_requested && diagnostic->option_index)
-    diagnostic->message.format_spec
-      = ACONCAT ((diagnostic->message.format_spec,
-                  " [", cl_options[diagnostic->option_index].opt_text, "]", NULL));
+  if (context->show_option_requested)
+    {
+      const char * option_text = NULL;
 
+      if (diagnostic->option_index)
+       {
+         /* A warning classified as an error.  */
+         if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
+             && diagnostic->kind == DK_ERROR)
+           option_text 
+             = ACONCAT ((cl_options[OPT_Werror_].opt_text,
+                         /* Skip over "-W".  */
+                         cl_options[diagnostic->option_index].opt_text + 2,
+                         NULL));
+         /* A warning with option.  */
+         else
+           option_text = cl_options[diagnostic->option_index].opt_text;
+       }
+      /* A warning without option classified as an error.  */
+      else if (orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
+              || diagnostic->kind == DK_WARNING)
+       {
+         if (context->warning_as_error_requested)
+           option_text = cl_options[OPT_Werror].opt_text;
+         else
+           option_text = _("enabled by default");
+       }
+
+      if (option_text)
+       diagnostic->message.format_spec
+         = ACONCAT ((diagnostic->message.format_spec,
+                     " ", 
+                     "[", option_text, "]",
+                     NULL));
+    }
   diagnostic->message.locus = &diagnostic->location;
-  diagnostic->message.abstract_origin = &diagnostic->abstract_origin;
-  diagnostic->abstract_origin = NULL;
+  diagnostic->message.x_data = &diagnostic->x_data;
+  diagnostic->x_data = NULL;
   pp_format (context->printer, &diagnostic->message);
   (*diagnostic_starter (context)) (context, diagnostic);
   pp_output_formatted_text (context->printer);
@@ -422,7 +454,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
   pp_flush (context->printer);
   diagnostic_action_after_output (context, diagnostic);
   diagnostic->message.format_spec = saved_format_spec;
-  diagnostic->abstract_origin = NULL;
+  diagnostic->x_data = NULL;
 
   context->lock--;
 
@@ -475,7 +507,7 @@ verbatim (const char *gmsgid, ...)
   text.args_ptr = &ap;
   text.format_spec = _(gmsgid);
   text.locus = NULL;
-  text.abstract_origin = NULL;
+  text.x_data = NULL;
   pp_format_verbatim (global_dc->printer, &text);
   pp_flush (global_dc->printer);
   va_end (ap);
@@ -519,6 +551,23 @@ inform (location_t location, const char *gmsgid, ...)
   va_end (ap);
 }
 
+/* An informative note at LOCATION.  Use this for additional details on an
+   error message.  */
+void
+inform_n (location_t location, int n, const char *singular_gmsgid,
+          const char *plural_gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, plural_gmsgid);
+  diagnostic_set_info_translated (&diagnostic,
+                                  ngettext (singular_gmsgid, plural_gmsgid, n),
+                                  &ap, location, DK_NOTE);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 /* A warning at INPUT_LOCATION.  Use this for code which is correct according
    to the relevant language specification but is likely to be buggy anyway.
    Returns true if the warning was printed, false if it was inhibited.  */
@@ -614,6 +663,23 @@ error (const char *gmsgid, ...)
   va_end (ap);
 }
 
+/* A hard error: the code is definitely ill-formed, and an object file
+   will not be produced.  */
+void
+error_n (location_t location, int n, const char *singular_gmsgid,
+         const char *plural_gmsgid, ...)
+{
+  diagnostic_info diagnostic;
+  va_list ap;
+
+  va_start (ap, plural_gmsgid);
+  diagnostic_set_info_translated (&diagnostic,
+                                  ngettext (singular_gmsgid, plural_gmsgid, n),
+                                  &ap, location, DK_ERROR);
+  report_diagnostic (&diagnostic);
+  va_end (ap);
+}
+
 /* Same as ebove, but use location LOC instead of input_location.  */
 void
 error_at (location_t loc, const char *gmsgid, ...)