c++: tweak colorization of incompatible declspecs

Introduce a helper function for complaining about "signed unsigned"
and "short long".  Add colorization there so that e.g. the 'signed'
and 'unsigned' are given consistent contrasting colors in both the
message and the quoted source.

gcc/cp/ChangeLog:
	* decl.cc: Add #include "diagnostic-highlight-colors.h"
	and #include "pretty-print-markup.h".
	(complain_about_incompatible_declspecs): New.
	(grokdeclarator): Use it when complaining about both 'signed' and
	'unsigned', and both 'long' and 'short'.

gcc/ChangeLog:
	* diagnostic-highlight-colors.h: Tweak comment.
	* pretty-print-markup.h (class pp_element_quoted_string): New,
	based on pretty-print.cc's selftest::test_element, adding an
	optional highlight color.
	* pretty-print.cc (class test_element): Drop.
	(selftest::test_pp_format): Use pp_element_quoted_string.
	(selftest::test_urlification): Likewise.

gcc/testsuite/ChangeLog:
	* g++.dg/diagnostic/long-short-colorization.C: New test.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
David Malcolm 2024-12-11 10:32:14 -05:00
parent 7435d1dbae
commit 4b4023d529
5 changed files with 75 additions and 31 deletions

View file

@ -61,6 +61,8 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks-def.h" /* For lhd_simulate_record_decl */
#include "coroutines.h"
#include "gcc-urlifier.h"
#include "diagnostic-highlight-colors.h"
#include "pretty-print-markup.h"
/* Possible cases of bad specifiers type used by bad_specifiers. */
enum bad_spec_place {
@ -12437,6 +12439,23 @@ check_decltype_auto (location_t loc, tree type)
return false;
}
/* Issue an error about two mutually incompatible declspecs
with the given names and locations
e.g. "error: `signed' and `unsigned' specified together" */
static void
complain_about_incompatible_declspecs (const char *name_a, location_t loc_a,
const char *name_b, location_t loc_b)
{
gcc_rich_location richloc (loc_a, nullptr, highlight_colors::lhs);
richloc.add_range (loc_b, SHOW_RANGE_WITHOUT_CARET,
nullptr, highlight_colors::rhs);
pp_element_quoted_string e_name_a (name_a, highlight_colors::lhs);
pp_element_quoted_string e_name_b (name_b, highlight_colors::rhs);
error_at (&richloc, "%e and %e specified together",
&e_name_a, &e_name_b);
}
/* Given declspecs and a declarator (abstract or otherwise), determine
the name and type of the object declared and construct a DECL node
for it.
@ -13070,18 +13089,13 @@ grokdeclarator (const cp_declarator *declarator,
int ok = 0;
if (signed_p && unsigned_p)
{
gcc_rich_location richloc (declspecs->locations[ds_signed]);
richloc.add_range (declspecs->locations[ds_unsigned]);
error_at (&richloc,
"%<signed%> and %<unsigned%> specified together");
}
complain_about_incompatible_declspecs
("signed", declspecs->locations[ds_signed],
"unsigned", declspecs->locations[ds_unsigned]);
else if (long_p && short_p)
{
gcc_rich_location richloc (declspecs->locations[ds_long]);
richloc.add_range (declspecs->locations[ds_short]);
error_at (&richloc, "%<long%> and %<short%> specified together");
}
complain_about_incompatible_declspecs
("long", declspecs->locations[ds_long],
"short", declspecs->locations[ds_short]);
else if (TREE_CODE (type) != INTEGER_TYPE
|| type == char8_type_node
|| type == char16_type_node

View file

@ -47,7 +47,8 @@ namespace highlight_colors {
extern const char *const expected;
extern const char *const actual;
/* Color names for expressing "LHS" vs "RHS" values in a binary operation. */
/* Color names for expressing "LHS" vs "RHS" values in a binary operation
or when we are listing two different things. */
extern const char *const lhs;
extern const char *const rhs;

View file

@ -89,4 +89,29 @@ private:
} // namespace pp_markup
class pp_element_quoted_string : public pp_element
{
public:
pp_element_quoted_string (const char *text,
const char *highlight_color = nullptr)
: m_text (text),
m_highlight_color (highlight_color)
{}
void add_to_phase_2 (pp_markup::context &ctxt) final override
{
ctxt.begin_quote ();
if (m_highlight_color)
ctxt.begin_highlight_color (m_highlight_color);
pp_string (&ctxt.m_pp, m_text);
if (m_highlight_color)
ctxt.end_highlight_color ();
ctxt.end_quote ();
}
private:
const char *m_text;
const char *m_highlight_color;
};
#endif /* GCC_PRETTY_PRINT_MARKUP_H */

View file

@ -3314,22 +3314,6 @@ assert_pp_format_colored (const location &loc, const char *expected,
(ARG1), (ARG2), (ARG3)); \
SELFTEST_END_STMT
class test_element : public pp_element
{
public:
test_element (const char *text) : m_text (text) {}
void add_to_phase_2 (pp_markup::context &ctxt) final override
{
ctxt.begin_quote ();
pp_string (&ctxt.m_pp, m_text);
ctxt.end_quote ();
}
private:
const char *m_text;
};
/* Verify that pp_format works, for various format codes. */
static void
@ -3444,8 +3428,8 @@ test_pp_format ()
/* Verify %e. */
{
test_element foo ("foo");
test_element bar ("bar");
pp_element_quoted_string foo ("foo");
pp_element_quoted_string bar ("bar");
ASSERT_PP_FORMAT_2 ("before `foo' `bar' after",
"before %e %e after",
&foo, &bar);
@ -4204,7 +4188,7 @@ test_urlification ()
{
pretty_printer pp;
pp.set_url_format (URL_FORMAT_ST);
test_element elem ("-foption");
pp_element_quoted_string elem ("-foption");
pp_printf_with_urlifier (&pp, &urlifier,
"foo %e bar",
&elem);

View file

@ -0,0 +1,20 @@
// Verify colorization of printing of declspec mismatches
// Use dg-*-multiline-output to avoid regexp interpretation.
// { dg-options "-fdiagnostics-color=always -fdiagnostics-show-caret" }
long short int a;
/* { dg-begin-multiline-output "" }
'long' and 'short' specified together
long short int a;
^~~~ ~~~~~
{ dg-end-multiline-output "" } */
short long int b;
/* { dg-begin-multiline-output "" }
'long' and 'short' specified together
short long int b;
~~~~~ ^~~~
{ dg-end-multiline-output "" } */
// Discard the remaining colorized output that confuses dejagnu.
// { dg-prune-output diagnostic/long-short-colorization.C }