This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 05/22] diagnostic.c/h: add support for external tools
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Fri, 4 Aug 2017 18:04:36 -0400
- Subject: [PATCH 05/22] diagnostic.c/h: add support for external tools
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=dmalcolm at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 13548C0587ED
- References: <1501884293-9047-1-git-send-email-dmalcolm@redhat.com>
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