mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 09:20:27 +08:00
dump_printf: add "%C" for dumping cgraph_node *
This patch implements support for %C in dump_printf for dumping cgraph_node *. (I would have preferred to have a code for printing symtab_node * and both subclasses, but there doesn't seem to be a good way for -Wformat to handle inheritance, so, failing that, I went with this approach). gcc/c-family/ChangeLog: * c-format.c (local_cgraph_node_ptr_node): New variable. (gcc_dump_printf_char_table): Add entry for %C. (get_pointer_to_named_type): New function, taken from the handling code for "gimple *" from... (init_dynamic_diag_info): ...here. Add handling for "cgraph_node *". * c-format.h (T_CGRAPH_NODE): New. gcc/ChangeLog: * dump-context.h (ASSERT_IS_CGRAPH_NODE): New macro. * dumpfile.c (make_item_for_dump_cgraph_node): Move to before... (dump_pretty_printer::decode_format): Implement "%C" for cgraph_node *. (selftest::test_capture_of_dump_calls): Rename "where" to "stmt_loc". Convert test_decl to a function decl and set its location. Add a symbol_table_test RAII instance and a cgraph_node, using it to test "%C" and dump_symtab_node. gcc/testsuite/ChangeLog: * gcc.dg/format/gcc_diag-10.c (cgraph_node): New typedef. (test_dump): Add testing of %C. From-SVN: r265918
This commit is contained in:
parent
0d8f74b4cf
commit
d8010ee456
@ -1,3 +1,14 @@
|
||||
2018-11-08 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* dump-context.h (ASSERT_IS_CGRAPH_NODE): New macro.
|
||||
* dumpfile.c (make_item_for_dump_cgraph_node): Move to before...
|
||||
(dump_pretty_printer::decode_format): Implement "%C" for
|
||||
cgraph_node *.
|
||||
(selftest::test_capture_of_dump_calls): Rename "where" to
|
||||
"stmt_loc". Convert test_decl to a function decl and set its
|
||||
location. Add a symbol_table_test RAII instance and a
|
||||
cgraph_node, using it to test "%C" and dump_symtab_node.
|
||||
|
||||
2018-11-08 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR middle-end/87916
|
||||
|
@ -1,3 +1,13 @@
|
||||
2018-11-08 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* c-format.c (local_cgraph_node_ptr_node): New variable.
|
||||
(gcc_dump_printf_char_table): Add entry for %C.
|
||||
(get_pointer_to_named_type): New function, taken from the handling
|
||||
code for "gimple *" from...
|
||||
(init_dynamic_diag_info): ...here. Add handling for
|
||||
"cgraph_node *".
|
||||
* c-format.h (T_CGRAPH_NODE): New.
|
||||
|
||||
2018-10-19 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* c-cppbuiltin.c (c_cpp_builtins): Add
|
||||
|
@ -60,6 +60,7 @@ struct function_format_info
|
||||
/* Initialized in init_dynamic_diag_info. */
|
||||
static GTY(()) tree local_tree_type_node;
|
||||
static GTY(()) tree local_gimple_ptr_node;
|
||||
static GTY(()) tree local_cgraph_node_ptr_node;
|
||||
static GTY(()) tree locus;
|
||||
|
||||
static bool decode_format_attr (tree, function_format_info *, int);
|
||||
@ -803,6 +804,9 @@ static const format_char_info gcc_dump_printf_char_table[] =
|
||||
/* E and G require a "gimple *" argument at runtime. */
|
||||
{ "EG", 1, STD_C89, { T89_G, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
|
||||
|
||||
/* C requires a "cgraph_node *" argument at runtime. */
|
||||
{ "C", 1, STD_C89, { T_CGRAPH_NODE, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
|
||||
|
||||
/* T requires a "tree" at runtime. */
|
||||
{ "T", 1, STD_C89, { T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL },
|
||||
|
||||
@ -3882,6 +3886,33 @@ init_dynamic_gfc_info (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Lookup the type named NAME and return a pointer-to-NAME type if found.
|
||||
Otherwise, return void_type_node if NAME has not been used yet, or NULL_TREE if
|
||||
NAME is not a type (issuing an error). */
|
||||
|
||||
static tree
|
||||
get_pointer_to_named_type (const char *name)
|
||||
{
|
||||
tree result;
|
||||
if ((result = maybe_get_identifier (name)))
|
||||
{
|
||||
result = identifier_global_value (result);
|
||||
if (result)
|
||||
{
|
||||
if (TREE_CODE (result) != TYPE_DECL)
|
||||
{
|
||||
error ("%qs is not defined as a type", name);
|
||||
result = NULL_TREE;
|
||||
}
|
||||
else
|
||||
result = TREE_TYPE (result);
|
||||
}
|
||||
}
|
||||
else
|
||||
result = void_type_node;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Determine the types of "tree" and "location_t" in the code being
|
||||
compiled for use in GCC's diagnostic custom format attributes. You
|
||||
must have set dynamic_format_types before calling this function. */
|
||||
@ -3935,25 +3966,12 @@ init_dynamic_diag_info (void)
|
||||
/* Similar to the above but for gimple*. */
|
||||
if (!local_gimple_ptr_node
|
||||
|| local_gimple_ptr_node == void_type_node)
|
||||
{
|
||||
if ((local_gimple_ptr_node = maybe_get_identifier ("gimple")))
|
||||
{
|
||||
local_gimple_ptr_node
|
||||
= identifier_global_value (local_gimple_ptr_node);
|
||||
if (local_gimple_ptr_node)
|
||||
{
|
||||
if (TREE_CODE (local_gimple_ptr_node) != TYPE_DECL)
|
||||
{
|
||||
error ("%<gimple%> is not defined as a type");
|
||||
local_gimple_ptr_node = 0;
|
||||
}
|
||||
else
|
||||
local_gimple_ptr_node = TREE_TYPE (local_gimple_ptr_node);
|
||||
}
|
||||
}
|
||||
else
|
||||
local_gimple_ptr_node = void_type_node;
|
||||
}
|
||||
local_gimple_ptr_node = get_pointer_to_named_type ("gimple");
|
||||
|
||||
/* Similar to the above but for cgraph_node*. */
|
||||
if (!local_cgraph_node_ptr_node
|
||||
|| local_cgraph_node_ptr_node == void_type_node)
|
||||
local_cgraph_node_ptr_node = get_pointer_to_named_type ("cgraph_node");
|
||||
|
||||
static tree hwi;
|
||||
|
||||
|
@ -299,6 +299,7 @@ struct format_kind_info
|
||||
#define T99_UC { STD_C99, NULL, T_UC }
|
||||
#define T_V &void_type_node
|
||||
#define T89_G { STD_C89, NULL, &local_gimple_ptr_node }
|
||||
#define T_CGRAPH_NODE { STD_C89, NULL, &local_cgraph_node_ptr_node }
|
||||
#define T89_T { STD_C89, NULL, &local_tree_type_node }
|
||||
#define T89_V { STD_C89, NULL, T_V }
|
||||
#define T_W &wchar_type_node
|
||||
|
@ -251,6 +251,14 @@ verify_item (const location &loc,
|
||||
(EXPECTED_LOCATION), (EXPECTED_TEXT)); \
|
||||
SELFTEST_END_STMT
|
||||
|
||||
/* Verify that ITEM is a symtab node, with the expected values. */
|
||||
|
||||
#define ASSERT_IS_SYMTAB_NODE(ITEM, EXPECTED_LOCATION, EXPECTED_TEXT) \
|
||||
SELFTEST_BEGIN_STMT \
|
||||
verify_item (SELFTEST_LOCATION, (ITEM), OPTINFO_ITEM_KIND_SYMTAB_NODE, \
|
||||
(EXPECTED_LOCATION), (EXPECTED_TEXT)); \
|
||||
SELFTEST_END_STMT
|
||||
|
||||
} // namespace selftest
|
||||
|
||||
#endif /* CHECKING_P */
|
||||
|
115
gcc/dumpfile.c
115
gcc/dumpfile.c
@ -748,6 +748,18 @@ dump_context::dump_generic_expr_loc (dump_flags_t dump_kind,
|
||||
dump_generic_expr (dump_kind, extra_dump_flags, t);
|
||||
}
|
||||
|
||||
/* Make an item for the given dump call. */
|
||||
|
||||
static optinfo_item *
|
||||
make_item_for_dump_symtab_node (symtab_node *node)
|
||||
{
|
||||
location_t loc = DECL_SOURCE_LOCATION (node->decl);
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
|
||||
xstrdup (node->dump_name ()));
|
||||
return item;
|
||||
}
|
||||
|
||||
/* dump_pretty_printer's ctor. */
|
||||
|
||||
dump_pretty_printer::dump_pretty_printer (dump_context *context,
|
||||
@ -881,6 +893,8 @@ dump_pretty_printer::format_decoder_cb (pretty_printer *pp, text_info *text,
|
||||
Supported format codes (in addition to the standard pretty_printer ones)
|
||||
are:
|
||||
|
||||
%C: cgraph_node *:
|
||||
Equivalent to: dump_symtab_node (MSG_*, node)
|
||||
%E: gimple *:
|
||||
Equivalent to: dump_gimple_expr (MSG_*, TDF_SLIM, stmt, 0)
|
||||
%G: gimple *:
|
||||
@ -888,7 +902,9 @@ dump_pretty_printer::format_decoder_cb (pretty_printer *pp, text_info *text,
|
||||
%T: tree:
|
||||
Equivalent to: dump_generic_expr (MSG_*, arg, TDF_SLIM).
|
||||
|
||||
FIXME: add symtab_node?
|
||||
TODO: add a format code that can handle (symtab_node*) *and* both
|
||||
subclasses (presumably means teaching -Wformat about non-virtual
|
||||
subclasses).
|
||||
|
||||
These format codes build optinfo_item instances, thus capturing metadata
|
||||
about the arguments being dumped, as well as the textual output. */
|
||||
@ -901,6 +917,16 @@ dump_pretty_printer::decode_format (text_info *text, const char *spec,
|
||||
for later use (to capture metadata, rather than plain text). */
|
||||
switch (*spec)
|
||||
{
|
||||
case 'C':
|
||||
{
|
||||
cgraph_node *node = va_arg (*text->args_ptr, cgraph_node *);
|
||||
|
||||
/* Make an item for the node, and stash it. */
|
||||
optinfo_item *item = make_item_for_dump_symtab_node (node);
|
||||
stash_item (buffer_ptr, item);
|
||||
return true;
|
||||
}
|
||||
|
||||
case 'E':
|
||||
{
|
||||
gimple *stmt = va_arg (*text->args_ptr, gimple *);
|
||||
@ -1023,18 +1049,6 @@ dump_context::dump_dec (dump_flags_t dump_kind, const poly_int<N, C> &value)
|
||||
delete item;
|
||||
}
|
||||
|
||||
/* Make an item for the given dump call. */
|
||||
|
||||
static optinfo_item *
|
||||
make_item_for_dump_symtab_node (symtab_node *node)
|
||||
{
|
||||
location_t loc = DECL_SOURCE_LOCATION (node->decl);
|
||||
optinfo_item *item
|
||||
= new optinfo_item (OPTINFO_ITEM_KIND_SYMTAB_NODE, loc,
|
||||
xstrdup (node->dump_name ()));
|
||||
return item;
|
||||
}
|
||||
|
||||
/* Output the name of NODE on appropriate dump streams. */
|
||||
|
||||
void
|
||||
@ -2067,18 +2081,26 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
linemap_add (line_table, LC_ENTER, false, "test.txt", 0);
|
||||
linemap_line_start (line_table, 5, 100);
|
||||
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
|
||||
location_t where = linemap_position_for_column (line_table, 10);
|
||||
if (where > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
location_t decl_loc = linemap_position_for_column (line_table, 8);
|
||||
location_t stmt_loc = linemap_position_for_column (line_table, 10);
|
||||
if (stmt_loc > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
return;
|
||||
|
||||
dump_location_t loc = dump_location_t::from_location_t (where);
|
||||
dump_location_t loc = dump_location_t::from_location_t (stmt_loc);
|
||||
|
||||
gimple *stmt = gimple_build_return (NULL);
|
||||
gimple_set_location (stmt, where);
|
||||
gimple_set_location (stmt, stmt_loc);
|
||||
|
||||
tree test_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
|
||||
tree test_decl = build_decl (decl_loc, FUNCTION_DECL,
|
||||
get_identifier ("test_decl"),
|
||||
integer_type_node);
|
||||
build_function_type_list (void_type_node,
|
||||
NULL_TREE));
|
||||
|
||||
symbol_table_test tmp_symtab;
|
||||
|
||||
cgraph_node *node = cgraph_node::get_create (test_decl);
|
||||
gcc_assert (node);
|
||||
|
||||
/* Run all tests twice, with and then without optinfo enabled, to ensure
|
||||
that immediate destinations vs optinfo-based destinations both
|
||||
work, independently of each other, with no leaks. */
|
||||
@ -2135,7 +2157,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 2);
|
||||
ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
|
||||
ASSERT_IS_GIMPLE (info->get_item (1), where, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2153,7 +2175,25 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 2);
|
||||
ASSERT_IS_TEXT (info->get_item (0), "gimple: ");
|
||||
ASSERT_IS_GIMPLE (info->get_item (1), where, "return;\n");
|
||||
ASSERT_IS_GIMPLE (info->get_item (1), stmt_loc, "return;\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Test of dump_printf with %C. */
|
||||
{
|
||||
temp_dump_context tmp (with_optinfo, true,
|
||||
MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
|
||||
dump_printf (MSG_NOTE, "node: %C", node);
|
||||
|
||||
ASSERT_DUMPED_TEXT_EQ (tmp, "node: test_decl/0");
|
||||
if (with_optinfo)
|
||||
{
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 2);
|
||||
ASSERT_IS_TEXT (info->get_item (0), "node: ");
|
||||
ASSERT_IS_SYMTAB_NODE (info->get_item (1), decl_loc, "test_decl/0");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2184,8 +2224,8 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
ASSERT_IS_TEXT (info->get_item (2), " and ");
|
||||
ASSERT_IS_TREE (info->get_item (3), UNKNOWN_LOCATION, "test_decl");
|
||||
ASSERT_IS_TEXT (info->get_item (4), " 42 consecutive ");
|
||||
ASSERT_IS_GIMPLE (info->get_item (5), where, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (6), where, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (5), stmt_loc, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (6), stmt_loc, "return;");
|
||||
ASSERT_IS_TEXT (info->get_item (7), " after\n");
|
||||
}
|
||||
}
|
||||
@ -2202,7 +2242,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
{
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->get_location_t (), where);
|
||||
ASSERT_EQ (info->get_location_t (), stmt_loc);
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 2);
|
||||
ASSERT_IS_TEXT (info->get_item (0), "test of tree: ");
|
||||
@ -2221,7 +2261,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
{
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->get_location_t (), where);
|
||||
ASSERT_EQ (info->get_location_t (), stmt_loc);
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_TREE (info->get_item (0), UNKNOWN_LOCATION, "1");
|
||||
@ -2242,7 +2282,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2258,7 +2298,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), where, "return;\n");
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2274,7 +2314,7 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2290,11 +2330,28 @@ test_capture_of_dump_calls (const line_table_case &case_)
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), where, "return;");
|
||||
ASSERT_IS_GIMPLE (info->get_item (0), stmt_loc, "return;");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* symtab_node. */
|
||||
{
|
||||
temp_dump_context tmp (with_optinfo, true,
|
||||
MSG_ALL_KINDS | MSG_PRIORITY_USER_FACING);
|
||||
dump_symtab_node (MSG_NOTE, node);
|
||||
|
||||
ASSERT_DUMPED_TEXT_EQ (tmp, "test_decl/0");
|
||||
if (with_optinfo)
|
||||
{
|
||||
optinfo *info = tmp.get_pending_optinfo ();
|
||||
ASSERT_TRUE (info != NULL);
|
||||
ASSERT_EQ (info->get_kind (), OPTINFO_KIND_NOTE);
|
||||
ASSERT_EQ (info->num_items (), 1);
|
||||
ASSERT_IS_SYMTAB_NODE (info->get_item (0), decl_loc, "test_decl/0");
|
||||
}
|
||||
}
|
||||
|
||||
/* poly_int. */
|
||||
{
|
||||
temp_dump_context tmp (with_optinfo, true,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2018-11-08 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* gcc.dg/format/gcc_diag-10.c (cgraph_node): New typedef.
|
||||
(test_dump): Add testing of %C.
|
||||
|
||||
2018-11-08 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* g++.dg/other/pr87916.C: New test.
|
||||
|
@ -20,7 +20,7 @@ typedef union tree_node *tree;
|
||||
typedef struct gimple gimple;
|
||||
|
||||
/* Likewise for gimple. */
|
||||
typedef struct gimple gimple;
|
||||
typedef struct cgraph_node cgraph_node;
|
||||
|
||||
#define FORMAT(kind) __attribute__ ((format (__gcc_## kind ##__, 1, 2)))
|
||||
|
||||
@ -162,7 +162,7 @@ void test_cxxdiag (tree t, gimple *gc)
|
||||
cxxdiag ("%<%X%>", t);
|
||||
}
|
||||
|
||||
void test_dump (tree t, gimple *stmt)
|
||||
void test_dump (tree t, gimple *stmt, cgraph_node *node)
|
||||
{
|
||||
dump ("%<"); /* { dg-warning "unterminated quoting directive" } */
|
||||
dump ("%>"); /* { dg-warning "unmatched quoting directive " } */
|
||||
@ -182,4 +182,5 @@ void test_dump (tree t, gimple *stmt)
|
||||
dump ("%E", stmt);
|
||||
dump ("%T", t);
|
||||
dump ("%G", stmt);
|
||||
dump ("%C", node);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user