X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdiagnostic.c;h=eee97cecd33c1b60f5de487fc3ebe3e3c96da319;hb=ee28dfbdcee05409dd607d27fbbd5dd781b09a48;hp=dbe94a89958288e583e8251733cf2c886fe6d2c2;hpb=5bcc316e1b642640cf09a651605077c8f44e2bc7;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index dbe94a89958..eee97cecd33 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -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 - Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009, 2010 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -24,22 +24,16 @@ 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" #define pedantic_warning_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING) #define permissive_error_kind() (flag_permissive ? DK_WARNING : DK_ERROR) @@ -47,11 +41,6 @@ along with GCC; see the file COPYING3. If not see /* Prototypes. */ static char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1; -static void default_diagnostic_starter (diagnostic_context *, - diagnostic_info *); -static void default_diagnostic_finalizer (diagnostic_context *, - diagnostic_info *); - static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; static void diagnostic_action_after_output (diagnostic_context *, @@ -101,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); @@ -111,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 @@ -126,6 +138,7 @@ diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, diagnostic->message.args_ptr = args; diagnostic->message.format_spec = msg; diagnostic->location = location; + diagnostic->override_column = 0; diagnostic->kind = kind; diagnostic->option_index = 0; } @@ -153,12 +166,14 @@ diagnostic_build_prefix (diagnostic_info *diagnostic) }; const char *text = _(diagnostic_kind_text[diagnostic->kind]); expanded_location s = expand_location (diagnostic->location); + if (diagnostic->override_column) + s.column = diagnostic->override_column; gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); return (s.file == NULL ? build_message_string ("%s: %s", progname, text) - : flag_show_column && s.column != 0 + : flag_show_column ? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text) : build_message_string ("%s:%d: %s", s.file, s.line, text)); } @@ -184,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; @@ -200,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); @@ -209,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) { @@ -240,9 +246,15 @@ diagnostic_report_current_module (diagnostic_context *context) if (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); - pp_verbatim (context->printer, - "In file included from %s:%d", - map->to_file, LAST_SOURCE_LINE (map)); + if (flag_show_column) + pp_verbatim (context->printer, + "In file included from %s:%d:%d", + map->to_file, + LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map)); + else + pp_verbatim (context->printer, + "In file included from %s:%d", + map->to_file, LAST_SOURCE_LINE (map)); while (! MAIN_FILE_P (map)) { map = INCLUDED_FROM (line_table, map); @@ -256,15 +268,15 @@ diagnostic_report_current_module (diagnostic_context *context) } } -static void +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)); } -static void +void default_diagnostic_finalizer (diagnostic_context *context, diagnostic_info *diagnostic ATTRIBUTE_UNUSED) { @@ -295,7 +307,7 @@ diagnostic_classify_diagnostic (diagnostic_context *context, 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. + in the documentation of output_format. Return true if a diagnostic was printed, false otherwise. */ bool @@ -303,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 @@ -312,9 +324,16 @@ diagnostic_report_diagnostic (diagnostic_context *context, && !diagnostic_report_warnings_p (location)) return false; - if (diagnostic->kind == DK_PEDWARN) - diagnostic->kind = pedantic_warning_kind (); - + if (diagnostic->kind == DK_PEDWARN) + { + 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) { /* If we're reporting an ICE in the middle of some other error, @@ -334,9 +353,8 @@ 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) { /* This tests if the user provided the appropriate -Wfoo or @@ -348,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. */ @@ -356,19 +373,20 @@ 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++; - if (diagnostic->kind == DK_ICE) + if (diagnostic->kind == DK_ICE && plugins_active_p ()) + { + fnotice (stderr, "*** WARNING *** there are active plugins, do not report" + " this as a bug unless you can reproduce it without enabling" + " any plugins.\n"); + dump_active_plugins (stderr); + } + + if (diagnostic->kind == DK_ICE) { #ifndef ENABLE_CHECKING /* When not checking, ICEs are converted to fatal errors when an @@ -389,16 +407,46 @@ diagnostic_report_diagnostic (diagnostic_context *context, diagnostic->message.args_ptr); } ++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); @@ -406,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--; @@ -459,14 +507,14 @@ verbatim (const char *gmsgid, ...) text.args_ptr = ≈ 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); } bool -emit_diagnostic (diagnostic_t kind, location_t location, int opt, +emit_diagnostic (diagnostic_t kind, location_t location, int opt, const char *gmsgid, ...) { diagnostic_info diagnostic; @@ -503,8 +551,25 @@ 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. + to the relevant language specification but is likely to be buggy anyway. Returns true if the warning was printed, false if it was inhibited. */ bool warning (int opt, const char *gmsgid, ...) @@ -551,7 +616,7 @@ warning_at (location_t location, int opt, const char *gmsgid, ...) Returns true if the warning was printed, false if it was inhibited. */ bool -pedwarn_at (location_t location, int opt, const char *gmsgid, ...) +pedwarn (location_t location, int opt, const char *gmsgid, ...) { diagnostic_info diagnostic; va_list ap; @@ -563,21 +628,6 @@ pedwarn_at (location_t location, int opt, const char *gmsgid, ...) return report_diagnostic (&diagnostic); } -/* Equivalent to pedwarn_at using INPUT_LOCATION. */ - -bool -pedwarn (int opt, const char *gmsgid, ...) -{ - diagnostic_info diagnostic; - va_list ap; - - va_start (ap, gmsgid); - diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_PEDWARN); - diagnostic.option_index = opt; - va_end (ap); - return report_diagnostic (&diagnostic); -} - /* A "permissive" error at LOCATION: issues an error unless -fpermissive was given on the command line, in which case it issues a warning. Use this for things that really should be errors but we @@ -613,6 +663,36 @@ 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, ...) +{ + diagnostic_info diagnostic; + va_list ap; + + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, loc, DK_ERROR); + report_diagnostic (&diagnostic); + va_end (ap); +} + /* "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. */