@@ -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_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_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 ");
- 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);
}