aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2024-07-13 10:34:51 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2024-07-13 10:34:51 -0400
commit7d73c01ce6d1ab28157a7dadcd3be14f96a7c8f3 (patch)
tree19ff9b197aa6635ad127839f17933febd9503132 /gcc/cp
parentabf3964711f05b6858d9775c3595ec2b45483e14 (diff)
downloadgcc-7d73c01ce6d1ab28157a7dadcd3be14f96a7c8f3.zip
gcc-7d73c01ce6d1ab28157a7dadcd3be14f96a7c8f3.tar.gz
gcc-7d73c01ce6d1ab28157a7dadcd3be14f96a7c8f3.tar.bz2
diagnostics: add highlight-a vs highlight-b in colorization and pp_markup
Since r6-4582-g8a64515099e645 (which added class rich_location), ranges of quoted source code have been colorized using the following rules: - the primary range used the same color of the kind of the diagnostic i.e. "error" vs "warning" etc (defaulting to bold red and bold magenta respectively) - secondary ranges alternate between "range1" and "range2" (defaulting to green and blue respectively) This works for cases with large numbers of highlighted ranges, but is suboptimal for common cases. The following patch adds a pair of color names: "highlight-a" and "highlight-b", and uses them whenever it makes sense to highlight and contrast two different things in the source code (e.g. a type mismatch). These are used by diagnostic-show-locus.cc for highlighting quoted source. In addition the patch adds colorization to fragments within the corresponding diagnostic messages themselves, using consistent colorization between the message and the quoted source code for the two different things being contrasted. For example, consider: demo.c: In function ‘test_bad_format_string_args’: ../../src/demo.c:25:18: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘const char *’ [-Wformat=] 25 | printf("hello %i", msg); | ~^ ~~~ | | | | int const char * | %s Previously, the types within the message in quotes would be in bold but not colorized, and the labelled ranges of quoted source code would use bold magenta for the "int" and non-bold green for the "const char *". With this patch: - the "%i" and "int" in the message and the "int" in the quoted source are all colored bold green - the "const char *" in the message and in the quoted source are both colored bold blue so that the consistent use of contrasting color draws the reader's eyes to the relationships between the diagnostic message and the source. I've tried this with gnome-terminal with many themes, including a variety of light versus dark backgrounds, solarized versus non-solarized themes, etc, and it was readable in all. My initial version of the patch used the existing %r and %R facilities within pretty-print.cc for the messages, but this turned out to be very uncomfortable, leading to error-prone format strings such as: error_at (richloc, "invalid operands to binary %s (have %<%r%T%R%> and %<%r%T%R%>)", opname, "highlight-a", type0, "highlight-b", type1); To avoid requiring monstrosities such as the above, the patch adds a new "%e" format code to pretty-print.cc, which expects a pp_element *, where pp_element is a new abstract base class (actually a pp_markup::element), along with various useful subclasses. This lets the above be written as: pp_markup::element_quoted_type element_0 (type0, highlight_colors::lhs); pp_markup::element_quoted_type element_1 (type1, highlight_colors::rhs); error_at (richloc, "invalid operands to binary %s (have %e and %e)", opname, &element_0, &element_1); which I feel is maintainable and clear to translators; the use of %e and pp_element * captures the type-unsafe part of the variadic call, and the subclasses allow for type-safety (so e.g. an element_quoted_type expects a type and a highlighting color). This approach allows for some nice simplifications within c-format.cc. The patch also extends -Wformat to "teach" it about the new %e and pp_element *. Doing so requires c-format.cc to be able to determine if a T * is a pp_element * (i.e. if T is a subclass). To do so I added a new comp_types callback for comparing types, where the C++ frontend supplies a suitable implementation (and %e will always be wrong for C). I've manually tested this on many diagnostics with both C and C++ and it seems a subtle but significant improvement in readability. I've added a new option -fno-diagnostics-show-highlight-colors in case people prefer the old behavior. gcc/c-family/ChangeLog: * c-common.cc: Include "tree-pretty-print-markup.h". (binary_op_error): Use pp_markup::element_quoted_type and %e. (check_function_arguments): Add "comp_types" param and pass it to check_function_format. * c-common.h (check_function_arguments): Add "comp_types" param. (check_function_format): Likewise. * c-format.cc: Include "tree-pretty-print-markup.h". (local_pp_element_ptr_node): New. (PP_FORMAT_CHAR_TABLE): Add entry for %e. (struct format_check_context): Add "m_comp_types" field. (check_function_format): Add "comp_types" param and pass it to check_format_info. (check_format_info): Likewise, passing it to format_ctx's ctor. (check_format_arg): Extract m_comp_types from format_ctx and pass it to check_format_info_main. (check_format_info_main): Add "comp_types" param and pass it to arg_parser's ctor. (class argument_parser): Add "m_comp_types" field. (argument_parser::check_argument_type): Pass m_comp_types to check_format_types. (handle_subclass_of_pp_element_p): New. (check_format_types): Add "comp_types" param, and use it to call handle_subclass_of_pp_element_p. (class element_format_substring): New. (class element_expected_type_with_indirection): New. (format_type_warning): Use element_expected_type_with_indirection to unify the if (wanted_type_name) branches, reducing from four emit_warning calls to two. Simplify these further using %e. Doing so also gives suitable colorization of the text within the diagnostics. (init_dynamic_diag_info): Initialize local_pp_element_ptr_node. (selftest::test_type_mismatch_range_labels): Add nullptr for new param of gcc_rich_location label overload. * c-format.h (T_PP_ELEMENT_PTR): New. * c-type-mismatch.cc: Include "diagnostic-highlight-colors.h". (binary_op_rich_location::binary_op_rich_location): Use highlight_colors::lhs and highlight_colors::rhs for the ranges. * c-type-mismatch.h (class binary_op_rich_location): Add comment about highlight_colors. gcc/c/ChangeLog: * c-objc-common.cc: Include "tree-pretty-print-markup.h". (print_type): Add optional "highlight_color" param and use it to show highlight colors in "aka" text. (pp_markup::element_quoted_type::print_type): New. * c-typeck.cc: Include "tree-pretty-print-markup.h". (comp_parm_types): New. (build_function_call_vec): Pass it to check_function_arguments. (inform_for_arg): Use %e and highlight colors to contrast actual versus expected. (convert_for_assignment): Use highlight_colors::actual for the rhs_label. (build_binary_op): Use highlight_colors::lhs and highlight_colors::rhs for the ranges. gcc/ChangeLog: * common.opt (fdiagnostics-show-highlight-colors): New option. * common.opt.urls: Regenerate. * coretypes.h (pp_markup::element): New forward decl. (pp_element): New typedef. * diagnostic-color.cc (gcc_color_defaults): Add "highlight-a" and "highlight-b". * diagnostic-format-json.cc (diagnostic_output_format_init_json): Disable highlight colors. * diagnostic-format-sarif.cc (diagnostic_output_format_init_sarif): Likewise. * diagnostic-highlight-colors.h: New file. * diagnostic-path.cc (struct event_range): Pass nullptr for highlight color of m_rich_loc. * diagnostic-show-locus.cc (colorizer::set_range): Handle ranges with m_highlight_color. (colorizer::STATE_NAMED_COLOR): New. (colorizer::m_richloc): New field. (colorizer::colorizer): Add richloc param for initializing m_richloc. (colorizer::set_named_color): New. (colorizer::begin_state): Add case STATE_NAMED_COLOR. (layout::layout): Pass richloc to m_colorizer's ctor. (selftest::test_one_liner_labels): Pass nullptr for new param of gcc_rich_location ctor for labels. (selftest::test_one_liner_labels_utf8): Likewise. * diagnostic.h (diagnostic_context::set_show_highlight_colors): New. * doc/invoke.texi: Add option -fdiagnostics-show-highlight-colors and highlight-a and highlight-b color caps. * doc/ux.texi (Use color consistently when highlighting mismatches): New subsection. * gcc-rich-location.cc (gcc_rich_location::add_expr): Add "highlight_color" param. (gcc_rich_location::maybe_add_expr): Likewise. * gcc-rich-location.h (gcc_rich_location::gcc_rich_location): Split out into a pair of ctors, where if a range_label is supplied the caller must also supply a highlight color. (gcc_rich_location::add_expr): Add "highlight_color" param. (gcc_rich_location::maybe_add_expr): Likewise. * gcc.cc (driver_handle_option): Handle OPT_fdiagnostics_show_highlight_colors. * lto-wrapper.cc (merge_and_complain): Likewise. (append_compiler_options): Likewise. (append_diag_options): Likewise. (run_gcc): Likewise. * opts-common.cc (decode_cmdline_options_to_array): Add comment about -fno-diagnostics-show-highlight-colors. * opts-global.cc (init_options_once): Preserve pp_show_highlight_colors in case the global_dc's printer is recreated. * opts.cc (common_handle_option): Handle OPT_fdiagnostics_show_highlight_colors. (gen_command_line_string): Likewise. * pretty-print-markup.h: New file. * pretty-print.cc: Include "pretty-print-markup.h" and "diagnostic-highlight-colors.h". (pretty_printer::format): Handle %e. (pretty_printer::pretty_printer): Handle new field m_show_highlight_colors. (pp_string_n): New. (pp_markup::context::begin_quote): New. (pp_markup::context::end_quote): New. (pp_markup::context::begin_color): New. (pp_markup::context::end_color): New. (highlight_colors::expected): New. (highlight_colors::actual): New. (highlight_colors::lhs): New. (highlight_colors::rhs): New. (class selftest::test_element): New. (selftest::test_pp_format): Add tests of %e. (selftest::test_urlification): Likewise. * pretty-print.h (pp_markup::context): New forward decl. (class chunk_info): Add friend class pp_markup::context. (class pretty_printer): Add friend pp_show_highlight_colors. (pretty_printer::m_show_highlight_colors): New field. (pp_show_highlight_colors): New inline function. (pp_string_n): New decl. * substring-locations.cc: Include "diagnostic-highlight-colors.h". (format_string_diagnostic_t::highlight_color_format_string): New. (format_string_diagnostic_t::highlight_color_param): New. (format_string_diagnostic_t::emit_warning_n_va): Use highlight colors. * substring-locations.h (format_string_diagnostic_t::highlight_color_format_string): New. (format_string_diagnostic_t::highlight_color_param): New. * toplev.cc (general_init): Initialize global_dc's show_highlight_colors. * tree-pretty-print-markup.h: New file. gcc/cp/ChangeLog: * call.cc: Include "tree-pretty-print-markup.h". (implicit_conversion_error): Use highlight_colors::percent_h for the labelled range. (op_error_string): Split out into... (concat_op_error_string): ...this. (binop_error_string): New. (op_error): Use %e, binop_error_string, highlight_colors::lhs, and highlight_colors::rhs. (maybe_inform_about_fndecl_for_bogus_argument_init): Add "highlight_color" param; use it for the richloc. (convert_like_internal): Use highlight_colors::percent_h for the labelled_range, and highlight_colors::percent_i for the call to maybe_inform_about_fndecl_for_bogus_argument_init. (build_over_call): Pass cp_comp_parm_types for new "comp_types" param of check_function_arguments. (complain_about_bad_argument): Use highlight_colors::percent_h for the labelled_range, and highlight_colors::percent_i for the call to maybe_inform_about_fndecl_for_bogus_argument_init. * cp-tree.h (maybe_inform_about_fndecl_for_bogus_argument_init): Add optional highlight_color param. (cp_comp_parm_types): New decl. (highlight_colors::const percent_h): New decl. (highlight_colors::const percent_i): New decl. * error.cc: Include "tree-pretty-print-markup.h". (highlight_colors::const percent_h): New defn. (highlight_colors::const percent_i): New defn. (type_to_string): Add param "highlight_color" and use it. (print_nonequal_arg): Likewise. (print_template_differences): Add params "highlight_color_a" and "highlight_color_b". (type_to_string_with_compare): Add params "this_highlight_color" and "peer_highlight_color". (print_template_tree_comparison): Add params "highlight_color_a" and "highlight_color_b". (cxx_format_postprocessor::handle): Use highlight_colors::percent_h and highlight_colors::percent_i. (pp_markup::element_quoted_type::print_type): New. (range_label_for_type_mismatch::get_text): Pass nullptr for new params of type_to_string_with_compare. * typeck.cc (cp_comp_parm_types): New. (cp_build_function_call_vec): Pass it to check_function_arguments. (convert_for_assignment): Use highlight_colors::percent_h for the labelled_range. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/bad-binary-ops-highlight-colors.C: New test. * g++.dg/diagnostic/bad-binary-ops-no-highlight-colors.C: New test. * g++.dg/plugin/plugin.exp (plugin_test_list): Add show-template-tree-color-no-highlight-colors.C to show_template_tree_color_plugin.c. * g++.dg/plugin/show-template-tree-color-labels.C: Update expected output to reflect use of highlight-a and highlight-b to contrast mismatches. * g++.dg/plugin/show-template-tree-color-no-elide-type.C: Likewise. * g++.dg/plugin/show-template-tree-color-no-highlight-colors.C: New test. * g++.dg/plugin/show-template-tree-color.C: Update expected output to reflect use of highlight-a and highlight-b to contrast mismatches. * g++.dg/warn/Wformat-gcc_diag-1.C: New test. * g++.dg/warn/Wformat-gcc_diag-2.C: New test. * g++.dg/warn/Wformat-gcc_diag-3.C: New test. * gcc.dg/bad-binary-ops-highlight-colors.c: New test. * gcc.dg/format/colors.c: New test. * gcc.dg/plugin/diagnostic_plugin_show_trees.c (show_tree): Pass nullptr for new param of gcc_rich_location::add_expr. libcpp/ChangeLog: * include/rich-location.h (location_range::m_highlight_color): New field. (rich_location::rich_location): Add optional label_highlight_color param. (rich_location::set_highlight_color): New decl. (rich_location::add_range): Add optional label_highlight_color param. (rich_location::set_range): Likewise. * line-map.cc (rich_location::rich_location): Add "label_highlight_color" param and pass it to add_range. (rich_location::set_highlight_color): New. (rich_location::add_range): Add "label_highlight_color" param. (rich_location::set_range): Add "highlight_color" param. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/call.cc75
-rw-r--r--gcc/cp/cp-tree.h13
-rw-r--r--gcc/cp/error.cc107
-rw-r--r--gcc/cp/typeck.cc20
4 files changed, 164 insertions, 51 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 83070b2..a5d3426 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "decl.h"
#include "c-family/c-type-mismatch.h"
#include "tristate.h"
+#include "tree-pretty-print-markup.h"
/* The various kinds of conversion. */
@@ -4760,7 +4761,8 @@ implicit_conversion_error (location_t loc, tree type, tree expr)
else
{
range_label_for_type_mismatch label (TREE_TYPE (expr), type);
- gcc_rich_location rich_loc (loc, &label);
+ gcc_rich_location rich_loc (loc, &label,
+ highlight_colors::percent_h);
error_at (&rich_loc, "could not convert %qE from %qH to %qI",
expr, TREE_TYPE (expr), type);
}
@@ -5446,6 +5448,19 @@ build_op_call (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
return result;
}
+/* Subroutine for preparing format strings suitable for the error
+ function. It concatenates a prefix (controlled by MATCH), ERRMSG,
+ and SUFFIX. */
+
+static const char *
+concat_op_error_string (bool match, const char *errmsg, const char *suffix)
+{
+ return concat (match
+ ? G_("ambiguous overload for ")
+ : G_("no match for "),
+ errmsg, suffix, nullptr);
+}
+
/* Called by op_error to prepare format strings suitable for the error
function. It concatenates a prefix (controlled by MATCH), ERRMSG,
and a suffix (controlled by NTYPES). */
@@ -5453,19 +5468,24 @@ build_op_call (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
static const char *
op_error_string (const char *errmsg, int ntypes, bool match)
{
- const char *msg;
-
- const char *msgp = concat (match ? G_("ambiguous overload for ")
- : G_("no match for "), errmsg, NULL);
-
+ const char *suffix;
if (ntypes == 3)
- msg = concat (msgp, G_(" (operand types are %qT, %qT, and %qT)"), NULL);
+ suffix = G_(" (operand types are %qT, %qT, and %qT)");
else if (ntypes == 2)
- msg = concat (msgp, G_(" (operand types are %qT and %qT)"), NULL);
+ suffix = G_(" (operand types are %qT and %qT)");
else
- msg = concat (msgp, G_(" (operand type is %qT)"), NULL);
+ suffix = G_(" (operand type is %qT)");
+ return concat_op_error_string (match, errmsg, suffix);
+}
- return msg;
+/* Similar to op_error_string, but a special-case for binary ops that
+ use %e for the args, rather than %qT. */
+
+static const char *
+binop_error_string (const char *errmsg, bool match)
+{
+ return concat_op_error_string (match, errmsg,
+ G_(" (operand types are %e and %e)"));
}
static void
@@ -5536,9 +5556,13 @@ op_error (const op_location_t &loc,
if (flag_diagnostics_show_caret)
{
binary_op_rich_location richloc (loc, arg1, arg2, true);
+ pp_markup::element_quoted_type element_0
+ (TREE_TYPE (arg1), highlight_colors::lhs);
+ pp_markup::element_quoted_type element_1
+ (TREE_TYPE (arg2), highlight_colors::rhs);
error_at (&richloc,
- op_error_string (G_("%<operator%s%>"), 2, match),
- opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+ binop_error_string (G_("%<operator%s%>"), match),
+ opname, &element_0, &element_1);
}
else
error_at (loc, op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
@@ -8370,11 +8394,16 @@ get_fndecl_argument_location (tree fndecl, int argnum)
wrong). */
void
-maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum)
+maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum,
+ const char *highlight_color)
{
if (fn)
- inform (get_fndecl_argument_location (fn, argnum),
- " initializing argument %P of %qD", argnum, fn);
+ {
+ gcc_rich_location richloc (get_fndecl_argument_location (fn, argnum));
+ richloc.set_highlight_color (highlight_color);
+ inform (&richloc,
+ " initializing argument %P of %qD", argnum, fn);
+ }
}
/* Maybe warn about C++20 Conversions to arrays of unknown bound. C is
@@ -8523,7 +8552,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
if (!complained && expr != error_mark_node)
{
range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
- gcc_rich_location richloc (loc, &label);
+ gcc_rich_location richloc (loc, &label, highlight_colors::percent_h);
complained = permerror (&richloc,
"invalid conversion from %qH to %qI",
TREE_TYPE (expr), totype);
@@ -8535,7 +8564,8 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
else
expr = cp_convert (totype, expr, complain);
if (complained == 1)
- maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+ maybe_inform_about_fndecl_for_bogus_argument_init
+ (fn, argnum, highlight_colors::percent_i);
return expr;
}
@@ -10380,7 +10410,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
}
warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
- nargs, fargs, NULL);
+ nargs, fargs, NULL,
+ cp_comp_parm_types);
}
if (DECL_INHERITED_CTOR (fn))
@@ -11460,12 +11491,14 @@ complain_about_bad_argument (location_t arg_loc,
arg_loc = input_location;
label = NULL;
}
- gcc_rich_location richloc (arg_loc, label);
+ gcc_rich_location richloc (arg_loc, label, highlight_colors::percent_h);
error_at (&richloc,
"cannot convert %qH to %qI",
from_type, to_type);
- maybe_inform_about_fndecl_for_bogus_argument_init (fndecl,
- parmnum);
+ maybe_inform_about_fndecl_for_bogus_argument_init
+ (fndecl,
+ parmnum,
+ highlight_colors::percent_i);
}
/* Subroutine of build_new_method_call_1, for where there are no viable
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 208947c..c1a371bc 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6773,7 +6773,8 @@ extern location_t get_fndecl_argument_location (tree, int);
extern void complain_about_bad_argument (location_t arg_loc,
tree from_type, tree to_type,
tree fndecl, int parmnum);
-extern void maybe_inform_about_fndecl_for_bogus_argument_init (tree, int);
+extern void maybe_inform_about_fndecl_for_bogus_argument_init (tree, int,
+ const char * = nullptr);
extern tree perform_dguide_overload_resolution (tree, const vec<tree, va_gc> *,
tsubst_flags_t);
@@ -8183,6 +8184,7 @@ extern bool comp_except_specs (const_tree, const_tree, int);
extern bool comptypes (tree, tree, int);
extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
extern bool similar_type_p (tree, tree);
+extern bool cp_comp_parm_types (tree, tree);
extern bool next_common_initial_sequence (tree &, tree &);
extern bool layout_compatible_type_p (tree, tree);
extern bool compparms (const_tree, const_tree);
@@ -9057,6 +9059,15 @@ name_independent_decl_p (tree decl)
&& !DECL_EXTERNAL (decl));
}
+namespace highlight_colors {
+
+/* Color names for highlighting "%qH" vs "%qI" values,
+ and ranges corresponding to them. */
+extern const char *const percent_h;
+extern const char *const percent_i;
+
+} // namespace highlight_colors
+
#if CHECKING_P
namespace selftest {
extern void run_cp_tests (void);
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 1f36563a..e35448f 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "cxx-pretty-print.h"
#include "tree-pretty-print.h"
+#include "tree-pretty-print-markup.h"
#include "gimple-pretty-print.h"
#include "c-family/c-objc.h"
#include "ubsan.h"
@@ -62,7 +63,8 @@ static const char *decl_to_string (tree, int, bool);
static const char *fndecl_to_string (tree, int);
static const char *op_to_string (bool, enum tree_code);
static const char *parm_to_string (int);
-static const char *type_to_string (tree, int, bool, bool *, bool);
+static const char *type_to_string (tree, int, bool, bool *, bool,
+ const char * = nullptr);
static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
static void dump_type (cxx_pretty_printer *, tree, int);
@@ -109,6 +111,11 @@ static void cp_print_error_function (diagnostic_context *,
static bool cp_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool, bool *, const char **);
+/* Color names for highlighting "%qH" vs "%qI" values,
+ and ranges corresponding to them. */
+const char *const highlight_colors::percent_h = "highlight-a";
+const char *const highlight_colors::percent_i = "highlight-b";
+
/* Struct for handling %H or %I, which require delaying printing the
type until a postprocessing stage. */
@@ -3405,12 +3412,12 @@ op_to_string (bool assop, enum tree_code p)
pp_format, or is not needed due to QUOTE being NULL (for template arguments
within %H and %I).
- SHOW_COLOR is used to determine the colorization of any quotes that
- are added. */
+ SHOW_COLOR and HIGHLIGHT_COLOR are used to determine the colorization of
+ any quotes that are added. */
static const char *
type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
- bool show_color)
+ bool show_color, const char *highlight_color)
{
int flags = 0;
if (verbose)
@@ -3421,7 +3428,11 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
pp_show_color (cxx_pp) = show_color;
if (postprocessed && quote && *quote)
- pp_begin_quote (cxx_pp, show_color);
+ {
+ pp_begin_quote (cxx_pp, show_color);
+ if (show_color && highlight_color)
+ pp_string (cxx_pp, colorize_start (show_color, highlight_color));
+ }
struct obstack *ob = pp_buffer (cxx_pp)->obstack;
int type_start, type_len;
@@ -3447,6 +3458,8 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
pp_cxx_whitespace (cxx_pp);
if (quote && *quote)
pp_begin_quote (cxx_pp, show_color);
+ if (highlight_color)
+ pp_string (cxx_pp, colorize_start (show_color, highlight_color));
/* And remember the start of the aka dump. */
aka_start = obstack_object_size (ob);
dump_type (cxx_pp, aka, flags);
@@ -3476,6 +3489,8 @@ type_to_string (tree typ, int verbose, bool postprocessed, bool *quote,
if (quote && *quote)
{
+ if (show_color && highlight_color)
+ pp_string (cxx_pp, colorize_stop (show_color));
pp_end_quote (cxx_pp, show_color);
*quote = false;
}
@@ -4100,13 +4115,17 @@ arg_to_string (tree arg, bool verbose)
print_template_tree_comparison.
Print a representation of ARG (an expression or type) to PP,
- colorizing it as "type-diff" if PP->show_color. */
+ colorizing it if PP->show_color, using HIGHLIGHT_COLOR,
+ or "type-diff" if the latter is NULL. */
static void
-print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose)
+print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose,
+ const char *highlight_color)
{
+ if (!highlight_color)
+ highlight_color = "type-diff";
pp_printf (pp, "%r%s%R",
- "type-diff",
+ highlight_color,
(arg
? arg_to_string (arg, verbose)
: G_("(no argument)")));
@@ -4158,7 +4177,9 @@ print_nonequal_arg (pretty_printer *pp, tree arg, bool verbose)
static void
print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
- bool verbose, int indent)
+ bool verbose, int indent,
+ const char *highlight_color_a,
+ const char *highlight_color_b)
{
if (indent)
newline_and_indent (pp, indent);
@@ -4209,19 +4230,20 @@ print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
{
int new_indent = indent ? indent + 2 : 0;
if (comparable_template_types_p (arg_a, arg_b))
- print_template_differences (pp, arg_a, arg_b, verbose, new_indent);
+ print_template_differences (pp, arg_a, arg_b, verbose, new_indent,
+ highlight_color_a, highlight_color_b);
else
if (indent)
{
newline_and_indent (pp, indent + 2);
pp_character (pp, '[');
- print_nonequal_arg (pp, arg_a, verbose);
+ print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
pp_string (pp, " != ");
- print_nonequal_arg (pp, arg_b, verbose);
+ print_nonequal_arg (pp, arg_b, verbose, highlight_color_b);
pp_character (pp, ']');
}
else
- print_nonequal_arg (pp, arg_a, verbose);
+ print_nonequal_arg (pp, arg_a, verbose, highlight_color_a);
}
}
pp_printf (pp, ">");
@@ -4247,13 +4269,16 @@ print_template_differences (pretty_printer *pp, tree type_a, tree type_b,
static const char *
type_to_string_with_compare (tree type, tree peer, bool verbose,
- bool show_color)
+ bool show_color,
+ const char *this_highlight_color,
+ const char *peer_highlight_color)
{
pretty_printer inner_pp;
pretty_printer *pp = &inner_pp;
pp_show_color (pp) = show_color;
- print_template_differences (pp, type, peer, verbose, 0);
+ print_template_differences (pp, type, peer, verbose, 0,
+ this_highlight_color, peer_highlight_color);
return pp_ggc_formatted_text (pp);
}
@@ -4291,9 +4316,13 @@ type_to_string_with_compare (tree type, tree peer, bool verbose,
static void
print_template_tree_comparison (pretty_printer *pp, tree type_a, tree type_b,
- bool verbose, int indent)
+ bool verbose, int indent,
+ const char *highlight_color_a,
+ const char *highlight_color_b)
{
- print_template_differences (pp, type_a, type_b, verbose, indent);
+ print_template_differences (pp, type_a, type_b, verbose, indent,
+ highlight_color_a,
+ highlight_color_b);
}
/* Subroutine for use in a format_postprocessor::handle
@@ -4345,6 +4374,11 @@ cxx_format_postprocessor::handle (pretty_printer *pp)
been present. */
if (m_type_a.m_tree || m_type_b.m_tree)
{
+ const bool show_highlight_colors = pp_show_highlight_colors (pp);
+ const char *percent_h
+ = show_highlight_colors ? highlight_colors::percent_h : nullptr;
+ const char *percent_i
+ = show_highlight_colors ? highlight_colors::percent_i : nullptr;
/* Avoid reentrancy issues by working with a copy of
m_type_a and m_type_b, resetting them now. */
deferred_printed_type type_a = m_type_a;
@@ -4362,19 +4396,22 @@ cxx_format_postprocessor::handle (pretty_printer *pp)
if (comparable_template_types_p (type_a.m_tree, type_b.m_tree))
{
- type_a_text
- = type_to_string_with_compare (type_a.m_tree, type_b.m_tree,
- type_a.m_verbose, show_color);
- type_b_text
- = type_to_string_with_compare (type_b.m_tree, type_a.m_tree,
- type_b.m_verbose, show_color);
+ type_a_text = type_to_string_with_compare
+ (type_a.m_tree, type_b.m_tree,
+ type_a.m_verbose, show_color,
+ percent_h, percent_i);
+ type_b_text = type_to_string_with_compare
+ (type_b.m_tree, type_a.m_tree,
+ type_b.m_verbose, show_color,
+ percent_i, percent_h);
if (flag_diagnostics_show_template_tree)
{
pretty_printer inner_pp;
pp_show_color (&inner_pp) = pp_show_color (pp);
print_template_tree_comparison
- (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2);
+ (&inner_pp, type_a.m_tree, type_b.m_tree, type_a.m_verbose, 2,
+ percent_h, percent_i);
append_formatted_chunk (pp, pp_ggc_formatted_text (&inner_pp));
}
}
@@ -4384,9 +4421,11 @@ cxx_format_postprocessor::handle (pretty_printer *pp)
provided), they are printed normally, and no difference tree
is printed. */
type_a_text = type_to_string (type_a.m_tree, type_a.m_verbose,
- true, &type_a.m_quote, show_color);
+ true, &type_a.m_quote, show_color,
+ percent_h);
type_b_text = type_to_string (type_b.m_tree, type_b.m_verbose,
- true, &type_b.m_quote, show_color);
+ true, &type_b.m_quote, show_color,
+ percent_i);
}
if (type_a.m_quote)
@@ -4438,6 +4477,19 @@ defer_phase_2_of_type_diff (deferred_printed_type *deferred,
*deferred = deferred_printed_type (type, buffer_ptr, verbose, quote);
}
+/* Implementation of pp_markup::element_quoted_type::print_type
+ for C++/ObjC++. */
+
+void
+pp_markup::element_quoted_type::print_type (pp_markup::context &ctxt)
+{
+ const char *highlight_color
+ = pp_show_highlight_colors (&ctxt.m_pp) ? m_highlight_color : nullptr;
+ const char *result
+ = type_to_string (m_type, false, false, &ctxt.m_quoted,
+ pp_show_color (&ctxt.m_pp), highlight_color);
+ pp_string (&ctxt.m_pp, result);
+}
/* Called from output_format -- during diagnostic message processing --
to handle C++ specific format specifier with the following meanings:
@@ -4748,7 +4800,8 @@ range_label_for_type_mismatch::get_text (unsigned /*range_idx*/) const
if (m_other_type
&& comparable_template_types_p (m_labelled_type, m_other_type))
result = type_to_string_with_compare (m_labelled_type, m_other_type,
- verbose, show_color);
+ verbose, show_color,
+ nullptr, nullptr);
else
result = type_to_string (m_labelled_type, verbose, true, NULL, show_color);
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 5519d77..5041a70 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4346,6 +4346,18 @@ cp_build_function_call_nary (tree function, tsubst_flags_t complain, ...)
return ret;
}
+/* C++ implementation of callback for use when checking param types. */
+
+bool
+cp_comp_parm_types (tree wanted_type, tree actual_type)
+{
+ if (TREE_CODE (wanted_type) == POINTER_TYPE
+ && TREE_CODE (actual_type) == POINTER_TYPE)
+ return same_or_base_type_p (TREE_TYPE (wanted_type),
+ TREE_TYPE (actual_type));
+ return false;
+}
+
/* Build a function call using a vector of arguments.
If FUNCTION is the result of resolving an overloaded target built-in,
ORIG_FNDECL is the original function decl, otherwise it is null.
@@ -4457,7 +4469,8 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
/* Check for errors in format strings and inappropriately
null parameters. */
bool warned_p = check_function_arguments (input_location, fndecl, fntype,
- nargs, argarray, NULL);
+ nargs, argarray, NULL,
+ cp_comp_parm_types);
ret = build_cxx_call (function, nargs, argarray, complain, orig_fndecl);
@@ -10380,7 +10393,10 @@ convert_for_assignment (tree type, tree rhs,
else
{
range_label_for_type_mismatch label (rhstype, type);
- gcc_rich_location richloc (rhs_loc, has_loc ? &label : NULL);
+ gcc_rich_location richloc
+ (rhs_loc,
+ has_loc ? &label : NULL,
+ has_loc ? highlight_colors::percent_h : NULL);
auto_diagnostic_group d;
switch (errtype)