Fix duplicates for anonymous structures with -fdump-ada-spec
This fixes a weakness in the way -fdump-ada-spec builds names for anonymous structures in the C/C++ code, resulting in duplicate identifiers under specific circumstances. c-family/ * c-ada-spec.c: Include bitmap.h. (dump_ada_double_name): Rename into... (dump_anonymous_type_name): ...this. Always use the TYPE_UID. (dump_ada_array_type): Adjust to above renaming. Robustify. (dump_nested_types_1): New function copied from... Add dumped_types parameter and pass it down to dump_nested_type. (dump_nested_types): ...this. Remove parent parameter. Just call dump_nested_types_1 on an automatic bitmap. (dump_nested_type): Add dumped_types parameter. <ARRAY_TYPE>: Do not dump it if already present in dumped_types. Adjust recursive calls and adjust to above renaming. (dump_ada_declaration): Adjust call to dump_nested_types. Tidy up and adjust to above renaming. (dump_ada_specs): Initialize and release bitmap obstack.
This commit is contained in:
parent
c26007ab17
commit
1d757b0950
2 changed files with 88 additions and 67 deletions
|
@ -1,3 +1,20 @@
|
|||
2020-02-14 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* c-ada-spec.c: Include bitmap.h.
|
||||
(dump_ada_double_name): Rename into...
|
||||
(dump_anonymous_type_name): ...this. Always use the TYPE_UID.
|
||||
(dump_ada_array_type): Adjust to above renaming. Robustify.
|
||||
(dump_nested_types_1): New function copied from... Add dumped_types
|
||||
parameter and pass it down to dump_nested_type.
|
||||
(dump_nested_types): ...this. Remove parent parameter. Just call
|
||||
dump_nested_types_1 on an automatic bitmap.
|
||||
(dump_nested_type): Add dumped_types parameter.
|
||||
<ARRAY_TYPE>: Do not dump it if already present in dumped_types.
|
||||
Adjust recursive calls and adjust to above renaming.
|
||||
(dump_ada_declaration): Adjust call to dump_nested_types.
|
||||
Tidy up and adjust to above renaming.
|
||||
(dump_ada_specs): Initialize and release bitmap obstack.
|
||||
|
||||
2020-02-10 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/93640
|
||||
|
|
|
@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "diagnostic.h"
|
||||
#include "stringpool.h"
|
||||
#include "attribs.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
/* Local functions, macros and variables. */
|
||||
static int dump_ada_node (pretty_printer *, tree, tree, int, bool, bool);
|
||||
|
@ -1475,30 +1476,21 @@ dump_ada_decl_name (pretty_printer *buffer, tree decl, bool limited_access)
|
|||
}
|
||||
}
|
||||
|
||||
/* Dump in BUFFER a name based on both T1 and T2 followed by a suffix. */
|
||||
/* Dump in BUFFER a name for the type T, which is a _TYPE without TYPE_NAME.
|
||||
PARENT is the parent node of T. */
|
||||
|
||||
static void
|
||||
dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2)
|
||||
dump_anonymous_type_name (pretty_printer *buffer, tree t, tree parent)
|
||||
{
|
||||
if (DECL_NAME (t1))
|
||||
pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false);
|
||||
if (DECL_NAME (parent))
|
||||
pp_ada_tree_identifier (buffer, DECL_NAME (parent), parent, false);
|
||||
else
|
||||
{
|
||||
pp_string (buffer, "anon");
|
||||
pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
|
||||
pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (parent)));
|
||||
}
|
||||
|
||||
pp_underscore (buffer);
|
||||
|
||||
if (DECL_NAME (t2))
|
||||
pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false);
|
||||
else
|
||||
{
|
||||
pp_string (buffer, "anon");
|
||||
pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2)));
|
||||
}
|
||||
|
||||
switch (TREE_CODE (TREE_TYPE (t2)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case ARRAY_TYPE:
|
||||
pp_string (buffer, "_array");
|
||||
|
@ -1516,6 +1508,8 @@ dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2)
|
|||
pp_string (buffer, "_unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
pp_scalar (buffer, "%d", TYPE_UID (t));
|
||||
}
|
||||
|
||||
/* Dump in BUFFER aspect Import on a given node T. SPC is the current
|
||||
|
@ -1816,10 +1810,9 @@ dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc)
|
|||
/* Print the dimensions. */
|
||||
dump_ada_array_domains (buffer, node, spc);
|
||||
|
||||
/* Print array's type. */
|
||||
/* Print the component type. */
|
||||
if (!char_array)
|
||||
{
|
||||
/* Retrieve the element type. */
|
||||
tree tmp = node;
|
||||
while (TREE_CODE (tmp) == ARRAY_TYPE)
|
||||
tmp = TREE_TYPE (tmp);
|
||||
|
@ -1829,10 +1822,12 @@ dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc)
|
|||
if (TREE_CODE (tmp) != POINTER_TYPE)
|
||||
pp_string (buffer, "aliased ");
|
||||
|
||||
if (TYPE_NAME (tmp) || !RECORD_OR_UNION_TYPE_P (tmp))
|
||||
if (TYPE_NAME (tmp)
|
||||
|| (!RECORD_OR_UNION_TYPE_P (tmp)
|
||||
&& TREE_CODE (tmp) != ENUMERAL_TYPE))
|
||||
dump_ada_node (buffer, tmp, node, spc, false, true);
|
||||
else
|
||||
dump_ada_double_name (buffer, type, get_underlying_decl (tmp));
|
||||
else if (type)
|
||||
dump_anonymous_type_name (buffer, tmp, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2469,10 +2464,11 @@ dump_forward_type (pretty_printer *buffer, tree type, tree t, int spc)
|
|||
TREE_VISITED (decl) = 1;
|
||||
}
|
||||
|
||||
static void dump_nested_type (pretty_printer *, tree, tree, tree, int);
|
||||
static void dump_nested_type (pretty_printer *, tree, tree, tree, bitmap, int);
|
||||
|
||||
/* Dump in BUFFER anonymous types nested inside T's definition.
|
||||
PARENT is the parent node of T. SPC is the indentation level.
|
||||
/* Dump in BUFFER anonymous types nested inside T's definition. PARENT is the
|
||||
parent node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC
|
||||
is the indentation level.
|
||||
|
||||
In C anonymous nested tagged types have no name whereas in C++ they have
|
||||
one. In C their TYPE_DECL is at top level whereas in C++ it is nested.
|
||||
|
@ -2484,13 +2480,14 @@ static void dump_nested_type (pretty_printer *, tree, tree, tree, int);
|
|||
pass on the nested TYPE_DECLs and a second pass on the unnamed types. */
|
||||
|
||||
static void
|
||||
dump_nested_types (pretty_printer *buffer, tree t, tree parent, int spc)
|
||||
dump_nested_types_1 (pretty_printer *buffer, tree t, tree parent,
|
||||
bitmap dumped_types, int spc)
|
||||
{
|
||||
tree type, field;
|
||||
|
||||
/* Find possible anonymous pointers/arrays/structs/unions recursively. */
|
||||
type = TREE_TYPE (t);
|
||||
if (type == NULL_TREE)
|
||||
if (!type)
|
||||
return;
|
||||
|
||||
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
|
||||
|
@ -2498,19 +2495,31 @@ dump_nested_types (pretty_printer *buffer, tree t, tree parent, int spc)
|
|||
&& DECL_NAME (field) != DECL_NAME (t)
|
||||
&& !DECL_ORIGINAL_TYPE (field)
|
||||
&& TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (type))
|
||||
dump_nested_type (buffer, field, t, parent, spc);
|
||||
dump_nested_type (buffer, field, t, parent, dumped_types, spc);
|
||||
|
||||
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
|
||||
if (TREE_CODE (field) == FIELD_DECL && !TYPE_NAME (TREE_TYPE (field)))
|
||||
dump_nested_type (buffer, field, t, parent, spc);
|
||||
dump_nested_type (buffer, field, t, parent, dumped_types, spc);
|
||||
}
|
||||
|
||||
/* Dump in BUFFER the anonymous type of FIELD inside T.
|
||||
PARENT is the parent node of T. SPC is the indentation level. */
|
||||
/* Likewise, but to be invoked only at top level. We dump each anonymous type
|
||||
nested inside T's definition exactly once, even if it is referenced several
|
||||
times in it (typically an array type), with a name prefixed by that of T. */
|
||||
|
||||
static void
|
||||
dump_nested_types (pretty_printer *buffer, tree t, int spc)
|
||||
{
|
||||
auto_bitmap dumped_types;
|
||||
dump_nested_types_1 (buffer, t, t, dumped_types, spc);
|
||||
}
|
||||
|
||||
/* Dump in BUFFER the anonymous type of FIELD inside T. PARENT is the parent
|
||||
node of T. DUMPED_TYPES is the bitmap of already dumped types. SPC is the
|
||||
indentation level. */
|
||||
|
||||
static void
|
||||
dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
||||
int spc)
|
||||
bitmap dumped_types, int spc)
|
||||
{
|
||||
tree field_type = TREE_TYPE (field);
|
||||
tree decl, tmp;
|
||||
|
@ -2523,6 +2532,11 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
|||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
/* Anonymous array types are shared. */
|
||||
if (!bitmap_set_bit (dumped_types, TYPE_UID (field_type)))
|
||||
return;
|
||||
|
||||
/* Recurse on the element type if need be. */
|
||||
tmp = TREE_TYPE (field_type);
|
||||
while (TREE_CODE (tmp) == ARRAY_TYPE)
|
||||
tmp = TREE_TYPE (tmp);
|
||||
|
@ -2533,7 +2547,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
|||
&& !TREE_VISITED (decl))
|
||||
{
|
||||
/* Generate full declaration. */
|
||||
dump_nested_type (buffer, decl, t, parent, spc);
|
||||
dump_nested_type (buffer, decl, t, parent, dumped_types, spc);
|
||||
TREE_VISITED (decl) = 1;
|
||||
}
|
||||
else if (!decl && TREE_CODE (tmp) == POINTER_TYPE)
|
||||
|
@ -2545,7 +2559,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
|||
else
|
||||
pp_string (buffer, "type ");
|
||||
|
||||
dump_ada_double_name (buffer, parent, field);
|
||||
dump_anonymous_type_name (buffer, field_type, parent);
|
||||
pp_string (buffer, " is ");
|
||||
dump_ada_array_type (buffer, field_type, parent, spc);
|
||||
pp_semicolon (buffer);
|
||||
|
@ -2561,7 +2575,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
|||
if (TYPE_NAME (field_type))
|
||||
dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
|
||||
else
|
||||
dump_ada_double_name (buffer, parent, field);
|
||||
dump_anonymous_type_name (buffer, field_type, parent);
|
||||
pp_string (buffer, " is ");
|
||||
dump_ada_enum_type (buffer, field_type, spc);
|
||||
pp_semicolon (buffer);
|
||||
|
@ -2570,14 +2584,14 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
|
|||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
dump_nested_types (buffer, field, t, spc);
|
||||
dump_nested_types_1 (buffer, field, parent, dumped_types, spc);
|
||||
|
||||
pp_string (buffer, "type ");
|
||||
|
||||
if (TYPE_NAME (field_type))
|
||||
dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
|
||||
else
|
||||
dump_ada_double_name (buffer, parent, field);
|
||||
dump_anonymous_type_name (buffer, field_type, parent);
|
||||
|
||||
if (TREE_CODE (field_type) == UNION_TYPE)
|
||||
pp_string (buffer, " (discr : unsigned := 0)");
|
||||
|
@ -2843,7 +2857,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
|
|||
pp_string (buffer, "subtype ");
|
||||
else
|
||||
{
|
||||
dump_nested_types (buffer, t, t, spc);
|
||||
dump_nested_types (buffer, t, spc);
|
||||
|
||||
if (separate_class_package (t))
|
||||
{
|
||||
|
@ -2920,8 +2934,6 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
|
|||
}
|
||||
else
|
||||
{
|
||||
tree tmp = TYPE_NAME (TREE_TYPE (t));
|
||||
|
||||
if (spc == INDENT_INCR || TREE_STATIC (t))
|
||||
is_var = true;
|
||||
|
||||
|
@ -2930,10 +2942,10 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
|
|||
if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE)
|
||||
pp_string (buffer, "aliased ");
|
||||
|
||||
if (tmp)
|
||||
dump_ada_node (buffer, tmp, type, spc, false, true);
|
||||
if (TYPE_NAME (TREE_TYPE (t)))
|
||||
dump_ada_node (buffer, TREE_TYPE (t), type, spc, false, true);
|
||||
else if (type)
|
||||
dump_ada_double_name (buffer, type, t);
|
||||
dump_anonymous_type_name (buffer, TREE_TYPE (t), type);
|
||||
else
|
||||
dump_ada_array_type (buffer, TREE_TYPE (t), type, spc);
|
||||
}
|
||||
|
@ -3152,33 +3164,21 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
|
|||
|
||||
pp_string (buffer, " : ");
|
||||
|
||||
if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
|
||||
|| TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
|
||||
{
|
||||
if (TYPE_NAME (TREE_TYPE (t))
|
||||
|| TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)
|
||||
pp_string (buffer, "aliased ");
|
||||
if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
|
||||
&& (TYPE_NAME (TREE_TYPE (t))
|
||||
|| (TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)))
|
||||
pp_string (buffer, "aliased ");
|
||||
|
||||
if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
|
||||
pp_string (buffer, "constant ");
|
||||
if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
|
||||
pp_string (buffer, "constant ");
|
||||
|
||||
if (TYPE_NAME (TREE_TYPE (t)))
|
||||
dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
|
||||
else if (type)
|
||||
dump_ada_double_name (buffer, type, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
|
||||
&& (TYPE_NAME (TREE_TYPE (t))
|
||||
|| TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE))
|
||||
pp_string (buffer, "aliased ");
|
||||
|
||||
if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
|
||||
pp_string (buffer, "constant ");
|
||||
|
||||
dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
|
||||
}
|
||||
if (TYPE_NAME (TREE_TYPE (t))
|
||||
|| (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
|
||||
&& TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE))
|
||||
dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
|
||||
else if (type)
|
||||
dump_anonymous_type_name (buffer, TREE_TYPE (t), type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3474,6 +3474,8 @@ void
|
|||
dump_ada_specs (void (*collect_all_refs)(const char *),
|
||||
int (*check)(tree, cpp_operation))
|
||||
{
|
||||
bitmap_obstack_initialize (NULL);
|
||||
|
||||
/* Iterate over the list of files to dump specs for. */
|
||||
for (int i = 0; i < source_refs_used; i++)
|
||||
dump_ads (source_refs[i], collect_all_refs, check);
|
||||
|
@ -3481,4 +3483,6 @@ dump_ada_specs (void (*collect_all_refs)(const char *),
|
|||
/* Free various tables. */
|
||||
free (source_refs);
|
||||
delete overloaded_names;
|
||||
|
||||
bitmap_obstack_release (NULL);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue