ada-tree.h (DECL_TAFT_TYPE_P): New flag.
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 2 Apr 2011 08:36:32 +0000 (08:36 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 2 Apr 2011 08:36:32 +0000 (08:36 +0000)
* 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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/ada-tree.h
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c

index 4e109b48f1759148d7b068ba8c477845c104aed6..ac3d0131713e8603b512bdc20861ed548c0414e2 100644 (file)
@@ -1,3 +1,15 @@
+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.
index 9002fa1c7b9704c6804f7acf91339b0fc73c04cb..de47afcebc0cbaa85389027920b5919c952bc45b 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              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- *
@@ -336,6 +336,10 @@ do {                                                  \
    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)
index 1afa06c7ade26710b65113f9274f2f910b1dc560..9c79d65530ab9aa1889793e660b5bdb590ceb55d 100644 (file)
@@ -4469,6 +4469,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
           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;
       }
index cca9523e760c6069a073763c2e7b6bfcf4a94d88..9622625a7ec2cca05dfa333c281b7334831ed7a5 100644 (file)
@@ -6609,11 +6609,17 @@ process_freeze_entity (Node_Id gnat_node)
       && 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.
@@ -7456,7 +7462,11 @@ process_type (Entity_Id gnat_entity)
          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;
@@ -7478,11 +7488,17 @@ process_type (Entity_Id gnat_entity)
   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
index 78d5506259dfc784f04811f5724663a8ae210c7f..31172723b4f8ffcd1bdbbf66609dba8c9bdde8ea 100644 (file)
@@ -4736,9 +4736,28 @@ smaller_form_type_p (tree type, tree orig_type)
 
 /* 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 ();