diff options
author | David Malcolm <dmalcolm@redhat.com> | 2024-07-13 10:34:51 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2024-07-13 10:34:51 -0400 |
commit | 7d73c01ce6d1ab28157a7dadcd3be14f96a7c8f3 (patch) | |
tree | 19ff9b197aa6635ad127839f17933febd9503132 /gcc/cp | |
parent | abf3964711f05b6858d9775c3595ec2b45483e14 (diff) | |
download | gcc-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.cc | 75 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 13 | ||||
-rw-r--r-- | gcc/cp/error.cc | 107 | ||||
-rw-r--r-- | gcc/cp/typeck.cc | 20 |
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) |