This patch adds fields "external_tool" and "external_test_id" to diagnostic_info, allowing for diagnostics to be marked as coming from a 3rd-party tool.
Instead of printing the pertinent warning flag e.g.: foo.c:10:1: something is wrong [-Wpointer-arith] the tool "ID" and (optionally) test ID is printed e.g.: foo.c:10:1: something is wrong [cppcheck:memleak] gcc/ChangeLog: * diagnostic-show-locus.c: Include "selftest-diagnostic.h". (class selftest::test_diagnostic_context): Move to selftest-diagnostic.h. * diagnostic.c: Include "selftest-diagnostic.h". (diagnostic_info::diagnostic_info): New ctor. (print_option_information): Handle external_tool and external_test_id fields of diagnostic_info. (diagnostic_report_diagnostic): Assert that diagnostic->kind is not DK_UNSPECIFIED. (selftest::dummy_option_name_cb): New function. (selftest::assert_option_information): New function. (selftest::test_print_option_information): New function. (selftest::diagnostic_c_tests): Call selftest::test_print_option_information. * diagnostic.h (struct diagnostic_info): Add default ctor, along with new fields "external_tool" and "external_test_id". * selftest-diagnostic.h: New file. --- gcc/diagnostic-show-locus.c | 29 +--------------- gcc/diagnostic.c | 85 ++++++++++++++++++++++++++++++++++++++++++--- gcc/diagnostic.h | 5 +++ gcc/selftest-diagnostic.h | 62 +++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 32 deletions(-) create mode 100644 gcc/selftest-diagnostic.h diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c index b0e72e7..08b2e56 100644 --- a/gcc/diagnostic-show-locus.c +++ b/gcc/diagnostic-show-locus.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-color.h" #include "gcc-rich-location.h" #include "selftest.h" +#include "selftest-diagnostic.h" #ifdef HAVE_TERMIOS_H # include <termios.h> @@ -1988,34 +1989,6 @@ namespace selftest { /* Selftests for diagnostic_show_locus. */ -/* Convenience subclass of diagnostic_context for testing - diagnostic_show_locus. */ - -class test_diagnostic_context : public diagnostic_context -{ - public: - test_diagnostic_context () - { - diagnostic_initialize (this, 0); - show_caret = true; - show_column = true; - start_span = start_span_cb; - } - ~test_diagnostic_context () - { - diagnostic_finish (this); - } - - /* Implementation of diagnostic_start_span_fn, hiding the - real filename (to avoid printing the names of tempfiles). */ - static void - start_span_cb (diagnostic_context *context, expanded_location exploc) - { - exploc.file = "FILENAME"; - default_diagnostic_start_span_fn (context, exploc); - } -}; - /* Verify that diagnostic_show_locus works sanely on UNKNOWN_LOCATION. */ static void diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index bbf5f5c..570f8c2 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-color.h" #include "edit-context.h" #include "selftest.h" +#include "selftest-diagnostic.h" #ifdef HAVE_TERMIOS_H # include <termios.h> @@ -67,7 +68,17 @@ const char *progname; /* A diagnostic_context surrogate for stderr. */ static diagnostic_context global_diagnostic_context; diagnostic_context *global_dc = &global_diagnostic_context; + + +/* diagnostic_info's ctor. */ + +diagnostic_info::diagnostic_info () +: message (), richloc (NULL), x_data (NULL), kind (DK_UNSPECIFIED), + option_index (0), external_tool (NULL), external_test_id (NULL) +{ +} + /* Return a malloc'd string containing MSG formatted a la printf. The caller is responsible for freeing the memory. */ char * @@ -843,6 +854,28 @@ print_option_information (diagnostic_context *context, const diagnostic_info *diagnostic, diagnostic_t orig_diag_kind) { + pretty_printer *pp = context->printer; + const char *cs = colorize_start (pp_show_color (pp), + diagnostic_kind_color[diagnostic->kind]); + const char *ce = colorize_stop (pp_show_color (pp)); + + if (diagnostic->external_tool) + { + pp_string (pp, " ["); + pp_string (pp, cs); + pp_string (pp, diagnostic->external_tool); + pp_string (pp, ce); + if (diagnostic->external_test_id) + { + pp_character (pp, ':'); + pp_string (pp, cs); + pp_string (pp, diagnostic->external_test_id); + pp_string (pp, ce); + } + pp_character (pp, ']'); + return; + } + char *option_text; option_text = context->option_name (context, diagnostic->option_index, @@ -850,12 +883,10 @@ print_option_information (diagnostic_context *context, if (option_text) { - pretty_printer *pp = context->printer; pp_string (pp, " ["); - pp_string (pp, colorize_start (pp_show_color (pp), - diagnostic_kind_color[diagnostic->kind])); + pp_string (pp, cs); pp_string (pp, option_text); - pp_string (pp, colorize_stop (pp_show_color (pp))); + pp_string (pp, ce); pp_character (pp, ']'); free (option_text); } @@ -875,6 +906,8 @@ diagnostic_report_diagnostic (diagnostic_context *context, location_t location = diagnostic_location (diagnostic); diagnostic_t orig_diag_kind = diagnostic->kind; + gcc_assert (diagnostic->kind != DK_UNSPECIFIED); + /* Give preference to being able to inhibit warnings, before they get reclassified to something else. */ if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) @@ -1490,6 +1523,49 @@ real_abort (void) namespace selftest { +/* A dummy diagnostic_context::option_name callback that always + returns a copy of "-Woption-name-goes-here". */ + +char * +dummy_option_name_cb (diagnostic_context *, int, diagnostic_t, diagnostic_t) +{ + return xstrdup ("-Woption-name-goes-here"); +} + +/* Verify that print_option_information on DIAGNOSTIC prints + EXPECTED. */ + +static void +assert_option_information (diagnostic_info *diagnostic, + const char *expected) +{ + test_diagnostic_context dc; + dc.option_name = dummy_option_name_cb; + print_option_information (&dc, diagnostic, DK_WARNING); + ASSERT_STREQ (expected, pp_formatted_text (dc.printer)); +} + +/* Verify that print_option_information does the right thing. */ + +static void +test_print_option_information () +{ + diagnostic_info diagnostic; + diagnostic.kind = DK_WARNING; + + /* A built-in warning. */ + assert_option_information (&diagnostic, " [-Woption-name-goes-here]"); + + /* An external tool, without a test ID. */ + diagnostic.external_tool = "external-tool-name"; + assert_option_information (&diagnostic, " [external-tool-name]"); + + /* An external tool, with a test ID. */ + diagnostic.external_test_id = "external-test-id"; + assert_option_information (&diagnostic, + " [external-tool-name:external-test-id]"); +} + /* Helper function for test_print_escaped_string. */ static void @@ -1621,6 +1697,7 @@ test_print_parseable_fixits_replace () void diagnostic_c_tests () { + test_print_option_information (); test_print_escaped_string (); test_print_parseable_fixits_none (); test_print_parseable_fixits_insert (); diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index dbd1703..0127a6c 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -29,6 +29,8 @@ along with GCC; see the file COPYING3. If not see list in diagnostic.def. */ struct diagnostic_info { + diagnostic_info (); + /* Text to be formatted. */ text_info message; @@ -41,6 +43,9 @@ struct diagnostic_info diagnostic_t kind; /* Which OPT_* directly controls this diagnostic. */ int option_index; + + const char *external_tool; + const char *external_test_id; }; /* Each time a diagnostic's classification is changed with a pragma, diff --git a/gcc/selftest-diagnostic.h b/gcc/selftest-diagnostic.h new file mode 100644 index 0000000..78bc5cf --- /dev/null +++ b/gcc/selftest-diagnostic.h @@ -0,0 +1,62 @@ +/* Support for selftests of diagnostics. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_SELFTEST_DIAGNOSTIC_H +#define GCC_SELFTEST_DIAGNOSTIC_H + +/* The selftest code should entirely disappear in a production + configuration, hence we guard all of it with #if CHECKING_P. */ + +#if CHECKING_P + +namespace selftest { + +/* Convenience subclass of diagnostic_context for testing + diagnostic_show_locus etc. */ + +class test_diagnostic_context : public diagnostic_context +{ + public: + test_diagnostic_context () + { + diagnostic_initialize (this, 0); + show_caret = true; + show_column = true; + start_span = start_span_cb; + } + ~test_diagnostic_context () + { + diagnostic_finish (this); + } + + /* Implementation of diagnostic_start_span_fn, hiding the + real filename (to avoid printing the names of tempfiles). */ + static void + start_span_cb (diagnostic_context *context, expanded_location exploc) + { + exploc.file = "FILENAME"; + default_diagnostic_start_span_fn (context, exploc); + } +}; + +} /* end of namespace selftest. */ + +#endif /* #if CHECKING_P */ + +#endif /* GCC_SELFTEST_DIAGNOSTIC_H */ -- 1.8.5.3