decl.c (gnat_to_gnu_entity): Remove useless 'else' statements and tidy up.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 6 Jun 2016 09:26:07 +0000 (09:26 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 6 Jun 2016 09:26:07 +0000 (09:26 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Component>: Remove
useless 'else' statements and tidy up.
<E_Array_Subtype>: Fully deal with the declaration here.
<E_Incomplete_Type>: Use properly-typed constant.
Assert that we don't apply the special type treatment to dummy types.
Separate this treatment from the final back-annotation and simplify
the condition for the RM size.
(gnat_to_gnu_param): Add GNU_PARAM_TYPE parameter and adjust.
(gnat_to_gnu_subprog_type): Ajust call to gnat_to_gnu_param.
* gcc-interface/trans.c (gnat_to_gnu) <N_Subprogram_Declaration>: Add
comment.
(process_freeze_entity): Remove obsolete code.
(process_type): Minor tweaks.

From-SVN: r237122

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/trans.c

index 8c1b90457d0e9c860809bec2b442a0d4244c598b..0370cd112ee8af9863065ddf9ffad9e9ec4eb8cb 100644 (file)
@@ -1,3 +1,19 @@
+2016-06-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Component>: Remove
+       useless 'else' statements and tidy up.
+       <E_Array_Subtype>: Fully deal with the declaration here.
+       <E_Incomplete_Type>: Use properly-typed constant.
+       Assert that we don't apply the special type treatment to dummy types.
+       Separate this treatment from the final back-annotation and simplify
+       the condition for the RM size.
+       (gnat_to_gnu_param): Add GNU_PARAM_TYPE parameter and adjust.
+       (gnat_to_gnu_subprog_type): Ajust call to gnat_to_gnu_param.
+       * gcc-interface/trans.c (gnat_to_gnu) <N_Subprogram_Declaration>: Add
+       comment.
+       (process_freeze_entity): Remove obsolete code.
+       (process_type): Minor tweaks.
+
 2016-06-06  Eric Botcazou  <ebotcazou@adacore.com>
 
        * einfo.ads (Returns_Limited_View): Remove.
index c0100addd26fde89d79dfb22dc12300a69da861a..c3aee4829a3ba292c5f2f86744522654d33892f2 100644 (file)
@@ -496,8 +496,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
           be a FIELD_DECL.  Likewise for discriminants.  If the entity is a
           non-girder discriminant (in the case of derived untagged record
           types), return the stored discriminant it renames.  */
-       else if (Present (Original_Record_Component (gnat_entity))
-                && Original_Record_Component (gnat_entity) != gnat_entity)
+       if (Present (Original_Record_Component (gnat_entity))
+           && Original_Record_Component (gnat_entity) != gnat_entity)
          {
            gnu_decl
              = gnat_to_gnu_entity (Original_Record_Component (gnat_entity),
@@ -509,7 +509,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
        /* Otherwise, if we are not defining this and we have no GCC type
           for the containing record, make one for it.  Then we should
           have made our own equivalent.  */
-       else if (!definition && !present_gnu_tree (gnat_record))
+       if (!definition && !present_gnu_tree (gnat_record))
          {
            /* ??? If this is in a record whose scope is a protected
               type and we have an Original_Record_Component, use it.
@@ -523,21 +523,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                  = gnat_to_gnu_entity (Original_Record_Component
                                        (gnat_entity),
                                        gnu_expr, false);
-               saved = true;
-               break;
+             }
+           else
+             {
+               gnat_to_gnu_entity (Scope (gnat_entity), NULL_TREE, false);
+               gnu_decl = get_gnu_tree (gnat_entity);
              }
 
-           gnat_to_gnu_entity (Scope (gnat_entity), NULL_TREE, false);
-           gnu_decl = get_gnu_tree (gnat_entity);
            saved = true;
            break;
          }
 
-       else
-         /* Here we have no GCC type and this is a reference rather than a
-            definition.  This should never happen.  Most likely the cause is
-            reference before declaration in the GNAT tree for gnat_entity.  */
-         gcc_unreachable ();
+       /* Here we have no GCC type and this is a reference rather than a
+          definition.  This should never happen.  Most likely the cause is
+          reference before declaration in the GNAT tree for gnat_entity.  */
+       gcc_unreachable ();
       }
 
     case E_Constant:
@@ -1064,6 +1064,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                    gcc_assert (ralign >= align);
                  }
 
+               /* The expression might not be a DECL so save it manually.  */
                save_gnu_tree (gnat_entity, gnu_decl, true);
                saved = true;
                annotate_object (gnat_entity, gnu_type, NULL_TREE, false);
@@ -2828,8 +2829,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                                      NULL_TREE, false);
              this_made_decl = true;
              gnu_type = TREE_TYPE (gnu_decl);
-
              save_gnu_tree (gnat_entity, NULL_TREE, false);
+             save_gnu_tree (gnat_entity, gnu_decl, false);
+             saved = true;
 
              gnu_inner = gnu_type;
              while (TREE_CODE (gnu_inner) == RECORD_TYPE
@@ -4356,7 +4358,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
            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);
+           save_gnu_tree (full_view, gnu_decl, false);
          }
       }
       break;
@@ -4455,6 +4457,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
      handling alignment and possible padding.  */
   if (is_type && (!gnu_decl || this_made_decl))
     {
+      gcc_assert (!TYPE_IS_DUMMY_P (gnu_type));
+
       /* Process the attributes, if not already done.  Note that the type is
         already defined so we cannot pass true for IN_PLACE here.  */
       process_attributes (&gnu_type, &attr_list, false, gnat_entity);
@@ -4703,21 +4707,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
            }
        }
 
-      if (!gnu_decl)
-       gnu_decl = create_type_decl (gnu_entity_name, gnu_type,
-                                    artificial_p, debug_info_p,
-                                    gnat_entity);
-      else
-       {
-         TREE_TYPE (gnu_decl) = gnu_type;
-         TYPE_STUB_DECL (gnu_type) = gnu_decl;
-       }
-    }
-
-  if (is_type && !TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl)))
-    {
-      gnu_type = TREE_TYPE (gnu_decl);
-
       /* If this is a derived type, relate its alias set to that of its parent
         to avoid troubles when a call to an inherited primitive is inlined in
         a context where a derived object is accessed.  The inlined code works
@@ -4796,8 +4785,23 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
                             ? ALIAS_SET_COPY : ALIAS_SET_SUPERSET);
        }
 
-      /* Back-annotate the Alignment of the type if not already in the
-        tree.  Likewise for sizes.  */
+      if (!gnu_decl)
+       gnu_decl = create_type_decl (gnu_entity_name, gnu_type,
+                                    artificial_p, debug_info_p,
+                                    gnat_entity);
+      else
+       {
+         TREE_TYPE (gnu_decl) = gnu_type;
+         TYPE_STUB_DECL (gnu_type) = gnu_decl;
+       }
+    }
+
+  /* If we got a type that is not dummy, back-annotate the alignment of the
+     type if not already in the tree.  Likewise for the size, if any.  */
+  if (is_type && !TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl)))
+    {
+      gnu_type = TREE_TYPE (gnu_decl);
+
       if (Unknown_Alignment (gnat_entity))
        {
          unsigned int double_align, align;
@@ -4883,7 +4887,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
            Set_Esize (gnat_entity, annotate_value (gnu_size));
        }
 
-      if (Unknown_RM_Size (gnat_entity) && rm_size (gnu_type))
+      if (Unknown_RM_Size (gnat_entity) && TYPE_SIZE (gnu_type))
        Set_RM_Size (gnat_entity, annotate_value (rm_size (gnu_type)));
     }
 
@@ -5266,22 +5270,22 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
 }
 
 /* Return a GCC tree for a parameter corresponding to GNAT_PARAM, to be placed
-   in the parameter list built for GNAT_SUBPROG.  FIRST is true if GNAT_PARAM
-   is the first parameter in the list.  Also set CICO to true if the parameter
-   must use the copy-in copy-out implementation mechanism.
+   in the parameter list of GNAT_SUBPROG.  GNU_PARAM_TYPE is the GCC tree for
+   the type of the parameter.  FIRST is true if this is the first parameter in
+   the list of GNAT_SUBPROG.  Also set CICO to true if the parameter must use
+   the copy-in copy-out implementation mechanism.
 
-   The returned tree is a PARM_DECL, except for those cases where no
-   parameter needs to be actually passed to the subprogram; the type
-   of this "shadow" parameter is then returned instead.  */
+   The returned tree is a PARM_DECL, except for the cases where no parameter
+   needs to be actually passed to the subprogram; the type of this "shadow"
+   parameter is then returned instead.  */
 
 static tree
-gnat_to_gnu_param (Entity_Id gnat_param, bool first, Entity_Id gnat_subprog,
-                  bool *cico)
+gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first,
+                  Entity_Id gnat_subprog, bool *cico)
 {
   Entity_Id gnat_param_type = Etype (gnat_param);
   Mechanism_Type mech = Mechanism (gnat_param);
   tree gnu_param_name = get_entity_name (gnat_param);
-  tree gnu_param_type = gnat_to_gnu_type (gnat_param_type);
   bool foreign = Has_Foreign_Convention (gnat_subprog);
   bool in_param = (Ekind (gnat_param) == E_In_Parameter);
   /* The parameter can be indirectly modified if its address is taken.  */
@@ -5482,14 +5486,14 @@ gnat_to_gnu_param (Entity_Id gnat_param, bool first, Entity_Id gnat_subprog,
 }
 
 /* Associate GNAT_SUBPROG with GNU_TYPE, which must be a dummy type, so that
-   GNAT_SUBPROG is updated when TYPE is completed.
+   GNAT_SUBPROG is updated when GNU_TYPE is completed.
 
    Ada 2012 (AI05-019) says that freezing a subprogram does not always freeze
    the corresponding profile, which means that, by the time the freeze node
    of the subprogram is encountered, types involved in its profile may still
-   be not frozen yet.  That's why we do not update GNAT_SUBPROG when we see
-   its freeze node but only when we see the freeze node of types involved in
-   its profile, either types of formal parameters or the return type.  */
+   be not yet frozen.  That's why we need to update GNAT_SUBPROG when we see
+   the freeze node of types involved in its profile, either types of formal
+   parameters or the return type.  */
 
 static void
 associate_subprog_with_dummy_type (Entity_Id gnat_subprog, tree gnu_type)
@@ -5648,7 +5652,9 @@ gnat_to_gnu_profile_type (Entity_Id gnat_type)
           && ((!in_main_unit
                && !present_gnu_tree (gnat_equiv)
                && Present (gnat_full)
-               && (Is_Record_Type (gnat_full) || Is_Array_Type (gnat_full)))
+               && (Is_Record_Type (gnat_full)
+                   || Is_Array_Type (gnat_full)
+                   || Is_Access_Type (gnat_full)))
               || (in_main_unit && Present (Freeze_Node (gnat_rep)))))
     {
       gnu_type = make_dummy_type (gnat_equiv);
@@ -5959,8 +5965,8 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition,
          else
            {
              gnu_param
-               = gnat_to_gnu_param (gnat_param, num == 0, gnat_subprog,
-                                    &cico);
+               = gnat_to_gnu_param (gnat_param, gnu_param_type, num == 0,
+                                    gnat_subprog, &cico);
 
              /* We are returned either a PARM_DECL or a type if no parameter
                 needs to be passed; in either case, adjust the type.  */
index 8cf4cea564cda98e7ad341695512a9eee81020dd..c8f125b554724004e0f9c71ddeb2c94bc9c5727b 100644 (file)
@@ -7137,11 +7137,19 @@ gnat_to_gnu (Node_Id gnat_node)
     /***************************/
 
     case N_Subprogram_Declaration:
-      /* Unless there is a freeze node, declare the subprogram.  We consider
-        this a "definition" even though we're not generating code for
-        the subprogram because we will be making the corresponding GCC
-        node here.  */
-
+      /* Unless there is a freeze node, declare the entity.  We consider
+        this a definition even though we're not generating code for the
+        subprogram because we will be making the corresponding GCC node.
+        When there is a freeze node, it is considered the definition of
+        the subprogram and we do nothing until after it is encountered.
+        That's an efficiency issue: the types involved in the profile
+        are far more likely to be frozen between the declaration and
+        the freeze node than before the declaration, so we save some
+        updates of the GCC node by waiting until the freeze node.
+        The counterpart is that we assume that there is no reference
+        to the subprogram between the declaration and the freeze node
+        in the expanded code; otherwise, it will be interpreted as an
+        external reference and very likely give rise to a link failure.  */
       if (No (Freeze_Node (Defining_Entity (Specification (gnat_node)))))
        gnat_to_gnu_entity (Defining_Entity (Specification (gnat_node)),
                            NULL_TREE, true);
@@ -7572,7 +7580,6 @@ gnat_to_gnu (Node_Id gnat_node)
     case N_Itype_Reference:
       if (!present_gnu_tree (Itype (gnat_node)))
        process_type (Itype (gnat_node));
-
       gnu_result = alloc_stmt_list ();
       break;
 
@@ -8571,9 +8578,8 @@ process_freeze_entity (Node_Id gnat_node)
              && kind == E_Subprogram_Type)))
     return;
 
-  /* If we have a non-dummy type old tree, we have nothing to do, except
-     aborting if this is the public view of a private type whose full view was
-     not delayed, as this node was never delayed as it should have been.  We
+  /* If we have a non-dummy type old tree, we have nothing to do, except for
+     aborting, since this node was never delayed as it should have been.  We
      let this happen for concurrent types and their Corresponding_Record_Type,
      however, because each might legitimately be elaborated before its own
      freeze node, e.g. while processing the other.  */
@@ -8581,10 +8587,7 @@ process_freeze_entity (Node_Id gnat_node)
       && !(TREE_CODE (gnu_old) == TYPE_DECL
           && TYPE_IS_DUMMY_P (TREE_TYPE (gnu_old))))
     {
-      gcc_assert ((IN (kind, Incomplete_Or_Private_Kind)
-                  && Present (Full_View (gnat_entity))
-                  && No (Freeze_Node (Full_View (gnat_entity))))
-                 || Is_Concurrent_Type (gnat_entity)
+      gcc_assert (Is_Concurrent_Type (gnat_entity)
                  || (IN (kind, Record_Kind)
                      && Is_Concurrent_Record_Type (gnat_entity)));
       return;
@@ -9456,28 +9459,22 @@ addressable_p (tree gnu_expr, tree gnu_type)
     }
 }
 \f
-/* Do the processing for the declaration of a GNAT_ENTITY, a type.  If
-   a separate Freeze node exists, delay the bulk of the processing.  Otherwise
-   make a GCC type for GNAT_ENTITY and set up the correspondence.  */
+/* Do the processing for the declaration of a GNAT_ENTITY, a type or subtype.
+   If a Freeze node exists for the entity, delay the bulk of the processing.
+   Otherwise make a GCC type for GNAT_ENTITY and set up the correspondence.  */
 
 void
 process_type (Entity_Id gnat_entity)
 {
   tree gnu_old
-    = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : 0;
-  tree gnu_new;
-
-  /* If we are to delay elaboration of this type, just do any
-     elaborations needed for expressions within the declaration and
-     make a dummy type entry for this node and its Full_View (if
-     any) in case something points to it.  Don't do this if it
-     has already been done (the only way that can happen is if
-     the private completion is also delayed).  */
-  if (Present (Freeze_Node (gnat_entity))
-      || (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
-         && Present (Full_View (gnat_entity))
-         && Present (Freeze_Node (Full_View (gnat_entity)))
-         && !present_gnu_tree (Full_View (gnat_entity))))
+    = present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity) : NULL_TREE;
+
+  /* If we are to delay elaboration of this type, just do any elaboration
+     needed for expressions within the declaration and make a dummy node
+     for it and its Full_View (if any), in case something points to it.
+     Do not do this if it has already been done (the only way that can
+     happen is if the private completion is also delayed).  */
+  if (Present (Freeze_Node (gnat_entity)))
     {
       elaborate_entity (gnat_entity);
 
@@ -9497,10 +9494,9 @@ process_type (Entity_Id gnat_entity)
       return;
     }
 
-  /* If we saved away a dummy type for this node it means that this
-     made the type that corresponds to the full type of an incomplete
-     type.  Clear that type for now and then update the type in the
-     pointers.  */
+  /* If we saved away a dummy type for this node, it means that this made the
+     type that corresponds to the full type of an incomplete type.  Clear that
+     type for now and then update the type in the pointers below.  */
   if (gnu_old)
     {
       gcc_assert (TREE_CODE (gnu_old) == TYPE_DECL
@@ -9510,7 +9506,7 @@ process_type (Entity_Id gnat_entity)
     }
 
   /* Now fully elaborate the type.  */
-  gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, true);
+  tree gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, true);
   gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);
 
   /* If we have an old type and we've made pointers to this type, update those