* gcc-interface/ada-tree.h (DECL_TAFT_TYPE_P): New flag.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Incomplete_Type>: Set it
if this is a Taft amendment type and the full declaration is available.
* gcc-interface/trans.c (process_type): Likewise.
If there is an old type, mark the new one as used if DECL_TAFT_TYPE_P.
(process_freeze_entity): Likewise.
* gcc-interface/utils.c (dummy_global): New static variable.
(gnat_write_global_declarations): If there are types declared as used
at the global level, insert them in the global hash table.
From-SVN: r171881
+2011-04-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/ada-tree.h (DECL_TAFT_TYPE_P): New flag.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Incomplete_Type>: Set it
+ if this is a Taft amendment type and the full declaration is available.
+ * gcc-interface/trans.c (process_type): Likewise.
+ If there is an old type, mark the new one as used if DECL_TAFT_TYPE_P.
+ (process_freeze_entity): Likewise.
+ * gcc-interface/utils.c (dummy_global): New static variable.
+ (gnat_write_global_declarations): If there are types declared as used
+ at the global level, insert them in the global hash table.
+
2011-04-02 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/gigi.h (record_builtin_type): Add ARTIFICIAL_P param.
* *
* C Header File *
* *
- * Copyright (C) 1992-2010, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2011, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
pair of INDIRECT_REFs is needed to access the object. */
#define DECL_BY_DOUBLE_REF_P(NODE) DECL_LANG_FLAG_0 (PARM_DECL_CHECK (NODE))
+/* Nonzero in a TYPE_DECL if this is the declaration of a Taft amendment type
+ in the main unit, i.e. the full declaration is available. */
+#define DECL_TAFT_TYPE_P(NODE) DECL_LANG_FLAG_0 (TYPE_DECL_CHECK (NODE))
+
/* Nonzero in a DECL if it is always used by reference, i.e. an INDIRECT_REF
is needed to access the object. */
#define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE)
we can do any needed updates when we see it. */
gnu_type = make_dummy_type (gnat_entity);
gnu_decl = TYPE_STUB_DECL (gnu_type);
+ if (Has_Completion_In_Body (gnat_entity))
+ DECL_TAFT_TYPE_P (gnu_decl) = 1;
save_gnu_tree (full_view, gnu_decl, 0);
break;
}
&& Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
- /* If we've made any pointers to the old version of this type, we
- have to update them. */
+ /* If we have an old type and we've made pointers to this type, update those
+ pointers. If this is a Taft amendment type in the main unit, we need to
+ mark the type as used since other units referencing it don't see the full
+ declaration and, therefore, cannot mark it as used themselves. */
if (gnu_old)
- update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
- TREE_TYPE (gnu_new));
+ {
+ update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
+ TREE_TYPE (gnu_new));
+ if (DECL_TAFT_TYPE_P (gnu_old))
+ used_types_insert (TREE_TYPE (gnu_new));
+ }
}
\f
/* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
save_gnu_tree (gnat_entity, gnu_decl, false);
if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
&& Present (Full_View (gnat_entity)))
- save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
+ {
+ if (Has_Completion_In_Body (gnat_entity))
+ DECL_TAFT_TYPE_P (gnu_decl) = 1;
+ save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
+ }
}
return;
gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 1);
gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);
- /* If we have an old type and we've made pointers to this type,
- update those pointers. */
+ /* If we have an old type and we've made pointers to this type, update those
+ pointers. If this is a Taft amendment type in the main unit, we need to
+ mark the type as used since other units referencing it don't see the full
+ declaration and, therefore, cannot mark it as used themselves. */
if (gnu_old)
- update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
- TREE_TYPE (gnu_new));
+ {
+ update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
+ TREE_TYPE (gnu_new));
+ if (DECL_TAFT_TYPE_P (gnu_old))
+ used_types_insert (TREE_TYPE (gnu_new));
+ }
/* If this is a record type corresponding to a task or protected type
that is a completion of an incomplete type, perform a similar update
/* Perform final processing on global variables. */
+static GTY (()) tree dummy_global;
+
void
gnat_write_global_declarations (void)
{
+ /* If we have declared types as used at the global level, insert them in
+ the global hash table. We use a dummy variable for this purpose. */
+ if (!VEC_empty (tree, types_used_by_cur_var_decl))
+ {
+ dummy_global
+ = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, void_type_node);
+ TREE_STATIC (dummy_global) = 1;
+ TREE_ASM_WRITTEN (dummy_global) = 1;
+ varpool_mark_needed_node (varpool_node (dummy_global));
+
+ while (!VEC_empty (tree, types_used_by_cur_var_decl))
+ {
+ tree t = VEC_pop (tree, types_used_by_cur_var_decl);
+ types_used_by_var_decl_insert (t, dummy_global);
+ }
+ }
+
/* Proceed to optimize and emit assembly.
FIXME: shouldn't be the front end's responsibility to call this. */
cgraph_finalize_compilation_unit ();