From afe4375b43ca2a4b57c992ab6dc6f242ddd5e124 Mon Sep 17 00:00:00 2001
From: Ed Schonberg <schonberg@adacore.com>
Date: Fri, 6 Apr 2007 11:20:23 +0200
Subject: [PATCH] exp_ch7.ads, [...] (Find_Final_List): If the access type is
 anonymous, use finalization list of enclosing dynamic scope.

2007-04-06  Ed Schonberg  <schonberg@adacore.com>
	    Bob Duff  <duff@adacore.com>
	    Cyrille Comar  <comar@adacore.com>

	* exp_ch7.ads, exp_ch7.adb (Find_Final_List): If the access type is
	anonymous, use finalization list of enclosing dynamic scope.
	(Expand_N_Package_Declaration): For a library package declaration
	without a corresponding body, generate RACW subprogram bodies in the
	spec (just as we do for the task activation call).
	(Convert_View): Split Is_Abstract flag into Is_Abstract_Subprogram and
	Is_Abstract_Type. Make sure these are called only when appropriate.
	Remove all code for DSP option
	(CW_Or_Controlled_Type): new subprogram.

From-SVN: r123563
---
 gcc/ada/exp_ch7.adb | 130 ++++++++++++++++++++++++++++++++-----------
 gcc/ada/exp_ch7.ads | 132 +++++++++++++++++++++++---------------------
 2 files changed, 167 insertions(+), 95 deletions(-)

diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 0a4a52714e5..144d20b6f21 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -35,9 +35,11 @@ with Errout;   use Errout;
 with Exp_Ch9;  use Exp_Ch9;
 with Exp_Ch11; use Exp_Ch11;
 with Exp_Dbug; use Exp_Dbug;
+with Exp_Dist; use Exp_Dist;
 with Exp_Tss;  use Exp_Tss;
 with Exp_Util; use Exp_Util;
 with Freeze;   use Freeze;
+with Lib;      use Lib;
 with Hostparm; use Hostparm;
 with Nlists;   use Nlists;
 with Nmake;    use Nmake;
@@ -46,7 +48,6 @@ with Output;   use Output;
 with Restrict; use Restrict;
 with Rident;   use Rident;
 with Rtsfind;  use Rtsfind;
-with Targparm; use Targparm;
 with Sinfo;    use Sinfo;
 with Sem;      use Sem;
 with Sem_Ch3;  use Sem_Ch3;
@@ -900,6 +901,15 @@ package body Exp_Ch7 is
                    and then Controlled_Type (Corresponding_Record_Type (T)));
    end Controlled_Type;
 
+   ---------------------------
+   -- CW_Or_Controlled_Type --
+   ---------------------------
+
+   function CW_Or_Controlled_Type (T : Entity_Id) return Boolean is
+   begin
+      return Is_Class_Wide_Type (T) or else Controlled_Type (T);
+   end CW_Or_Controlled_Type;
+
    --------------------------
    -- Controller_Component --
    --------------------------
@@ -977,7 +987,7 @@ package body Exp_Ch7 is
          Atyp := Etype (Arg);
       end if;
 
-      if Is_Abstract (Proc) and then Is_Tagged_Type (Ftyp) then
+      if Is_Abstract_Subprogram (Proc) and then Is_Tagged_Type (Ftyp) then
          return Unchecked_Convert_To (Class_Wide_Type (Ftyp), Arg);
 
       elsif Ftyp /= Atyp
@@ -1020,17 +1030,12 @@ package body Exp_Ch7 is
       Loc       : constant Source_Ptr := Sloc (N);
       Wrap_Node : Node_Id;
 
-      Sec_Stk : constant Boolean :=
-                  Sec_Stack and not Functions_Return_By_DSP_On_Target;
-      --  We never need a secondary stack if functions return by DSP
-
    begin
       --  Do not create a transient scope if we are already inside one
 
       for S in reverse Scope_Stack.First .. Scope_Stack.Last loop
-
          if Scope_Stack.Table (S).Is_Transient then
-            if Sec_Stk then
+            if Sec_Stack then
                Set_Uses_Sec_Stack (Scope_Stack.Table (S).Entity);
             end if;
 
@@ -1064,7 +1069,7 @@ package body Exp_Ch7 is
          New_Scope (New_Internal_Entity (E_Block, Current_Scope, Loc, 'B'));
          Set_Scope_Is_Transient;
 
-         if Sec_Stk then
+         if Sec_Stack then
             Set_Uses_Sec_Stack (Current_Scope);
             Check_Restriction (No_Secondary_Stack, N);
          end if;
@@ -1546,12 +1551,12 @@ package body Exp_Ch7 is
    -- Expand_N_Package_Body --
    ---------------------------
 
-   --  Add call to Activate_Tasks if body is an activator (actual
-   --  processing is in chapter 9).
+   --  Add call to Activate_Tasks if body is an activator (actual processing
+   --  is in chapter 9).
 
    --  Generate subprogram descriptor for elaboration routine
 
-   --  ENcode entity names in package body
+   --  Encode entity names in package body
 
    procedure Expand_N_Package_Body (N : Node_Id) is
       Ent : constant Entity_Id := Corresponding_Spec (N);
@@ -1583,14 +1588,76 @@ package body Exp_Ch7 is
    --  whether a body will eventually appear.
 
    procedure Expand_N_Package_Declaration (N : Node_Id) is
+      Spec    : constant Node_Id := Specification (N);
+      Decls   : List_Id;
+
+      No_Body : Boolean;
+      --  True in the case of a package declaration that is a compilation unit
+      --  and for which no associated body will be compiled in
+      --  this compilation.
    begin
-      if Nkind (Parent (N)) = N_Compilation_Unit
-        and then not Body_Required (Parent (N))
+
+      No_Body := False;
+
+      --  Case of a package declaration other than a compilation unit
+
+      if Nkind (Parent (N)) /= N_Compilation_Unit then
+         null;
+
+      --  Case of a compilation unit that does not require a body
+
+      elsif not Body_Required (Parent (N))
         and then not Unit_Requires_Body (Defining_Entity (N))
-        and then Present (Activation_Chain_Entity (N))
       then
+         No_Body := True;
+
+      --  Special case of generating calling stubs for a remote call interface
+      --  package: even though the package declaration requires one, the
+      --  body won't be processed in this compilation (so any stubs for RACWs
+      --  declared in the package must be generated here, along with the
+      --  spec).
+
+      elsif Parent (N) = Cunit (Main_Unit)
+        and then Is_Remote_Call_Interface (Defining_Entity (N))
+        and then Distribution_Stub_Mode = Generate_Caller_Stub_Body
+      then
+         No_Body := True;
+      end if;
+
+      --  For a package declaration that implies no associated body, generate
+      --  task activation call and RACW supporting bodies now (since we won't
+      --  have a specific separate compilation unit for that).
+
+      if No_Body then
+
          New_Scope (Defining_Entity (N));
-         Build_Task_Activation_Call (N);
+
+         if Has_RACW (Defining_Entity (N)) then
+
+            --  Generate RACW subprogram bodies
+
+            Decls := Private_Declarations (Spec);
+
+            if No (Decls) then
+               Decls := Visible_Declarations (Spec);
+            end if;
+
+            if No (Decls) then
+               Decls := New_List;
+               Set_Visible_Declarations (Spec, Decls);
+            end if;
+
+            Append_RACW_Bodies (Decls, Defining_Entity (N));
+            Analyze_List (Decls);
+         end if;
+
+         if Present (Activation_Chain_Entity (N)) then
+
+            --  Generate task activation call as last step of elaboration
+
+            Build_Task_Activation_Call (N);
+         end if;
+
          Pop_Scope;
       end if;
 
@@ -1652,12 +1719,18 @@ package body Exp_Ch7 is
              Selector_Name => Make_Identifier (Loc, Name_F));
 
       --  Case of a dynamically allocated object. The final list is the
-      --  corresponding list controller (The next entity in the scope of
-      --  the access type with the right type). If the type comes from a
-      --  With_Type clause, no controller was created, and we use the
-      --  global chain instead.
+      --  corresponding list controller (the next entity in the scope of the
+      --  access type with the right type). If the type comes from a With_Type
+      --  clause, no controller was created, we use the global chain instead.
 
-      elsif Is_Access_Type (E) then
+      --  An anonymous access type either has a list created for it when the
+      --  allocator is a for an access parameter or an access discriminant,
+      --  or else it uses the list of the enclosing dynamic scope, when the
+      --  context is a declaration or an assignment.
+
+      elsif Is_Access_Type (E)
+        and then Ekind (E) /= E_Anonymous_Access_Type
+      then
          if not From_With_Type (E) then
             return
               Make_Selected_Component (Loc,
@@ -2589,7 +2662,7 @@ package body Exp_Ch7 is
 
       if Prim = Finalize_Case or else Prim = Adjust_Case then
          Handler := New_List (
-           Make_Exception_Handler (Loc,
+           Make_Implicit_Exception_Handler (Loc,
              Exception_Choices => New_List (Make_Others_Choice (Loc)),
              Statements        => New_List (
                Make_Raise_Program_Error (Loc,
@@ -3025,10 +3098,8 @@ package body Exp_Ch7 is
                   Set_Uses_Sec_Stack (Current_Scope, False);
 
                   if not Requires_Transient_Scope (Etype (S)) then
-                     if not Functions_Return_By_DSP_On_Target then
-                        Set_Uses_Sec_Stack (S, True);
-                        Check_Restriction (No_Secondary_Stack, Action);
-                     end if;
+                     Set_Uses_Sec_Stack (S, True);
+                     Check_Restriction (No_Secondary_Stack, Action);
                   end if;
 
                   exit;
@@ -3046,11 +3117,8 @@ package body Exp_Ch7 is
                elsif K = E_Procedure
                  or else K = E_Block
                then
-                  if not Functions_Return_By_DSP_On_Target then
-                     Set_Uses_Sec_Stack (S, True);
-                     Check_Restriction (No_Secondary_Stack, Action);
-                  end if;
-
+                  Set_Uses_Sec_Stack (S, True);
+                  Check_Restriction (No_Secondary_Stack, Action);
                   Set_Uses_Sec_Stack (Current_Scope, False);
                   exit;
 
diff --git a/gcc/ada/exp_ch7.ads b/gcc/ada/exp_ch7.ads
index 02c38063407..a062fef3921 100644
--- a/gcc/ada/exp_ch7.ads
+++ b/gcc/ada/exp_ch7.ads
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2005, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2006, 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- --
@@ -60,15 +60,21 @@ package Exp_Ch7 is
    function Controlled_Type (T : Entity_Id) return Boolean;
    --  True if T potentially needs finalization actions
 
+   function CW_Or_Controlled_Type (T : Entity_Id) return Boolean;
+   --  True if T is either a potentially controlled type or a class-wide type.
+   --  Note that in normal mode, class-wide types are potentially controlled so
+   --  this function is different from Controlled_Type only under restrictions
+   --  No_Finalization.
+
    function Find_Final_List
      (E   : Entity_Id;
       Ref : Node_Id := Empty) return Node_Id;
-   --  E is an entity representing a controlled object, a controlled type
-   --  or a scope. If Ref is not empty, it is a reference to a controlled
-   --  record, the closest Final list is in the controller component of
-   --  the record containing Ref otherwise this function returns a
-   --  reference to the final list attached to the closest dynamic scope
-   --  (that can be E itself) creating this final list if necessary.
+   --  E is an entity representing a controlled object, a controlled type or a
+   --  scope. If Ref is not empty, it is a reference to a controlled record,
+   --  the closest Final list is in the controller component of the record
+   --  containing Ref otherwise this function returns a reference to the final
+   --  list attached to the closest dynamic scope (that can be E itself)
+   --  creating this final list if necessary.
 
    function Has_New_Controlled_Component (E : Entity_Id) return Boolean;
    --  E is a type entity. Give the same resul as Has_Controlled_Component
@@ -79,30 +85,28 @@ package Exp_Ch7 is
      (Obj_Ref     : Node_Id;
       Flist_Ref   : Node_Id;
       With_Attach : Node_Id) return Node_Id;
-   --  Attach the referenced object to the referenced Final Chain
-   --  'Flist_Ref' With_Attach is an expression of type Short_Short_Integer
-   --  which can be either '0' to signify no attachment, '1' for
-   --  attachement to a simply linked list or '2' for attachement to a
-   --  doubly linked list.
+   --  Attach the referenced object to the referenced Final Chain 'Flist_Ref'
+   --  With_Attach is an expression of type Short_Short_Integer which can be
+   --  either '0' to signify no attachment, '1' for attachement to a simply
+   --  linked list or '2' for attachement to a doubly linked list.
 
    function Make_Init_Call
      (Ref         : Node_Id;
       Typ         : Entity_Id;
       Flist_Ref   : Node_Id;
       With_Attach : Node_Id) return List_Id;
-   --  Ref is an expression (with no-side effect and is not required to
-   --  have been previously analyzed) that references the object to be
-   --  initialized. Typ is the expected type of Ref, which is a controlled
-   --  type (Is_Controlled) or a type with controlled components
-   --  (Has_Controlled). With_Attach is an integer expression representing
-   --  the level of attachment, see Attach_To_Final_List's Nb_Link param
-   --  documentation in s-finimp.ads.
+   --  Ref is an expression (with no-side effect and is not required to have
+   --  been previously analyzed) that references the object to be initialized.
+   --  Typ is the expected type of Ref, which is either a controlled type
+   --  (Is_Controlled) or a type with controlled components (Has_Controlled).
+   --  With_Attach is an integer expression which is the attchment level,
+   --  see System.Finalization_Implementation.Attach_To_Final_List for the
+   --  documentation of Nb_Link.
    --
-   --  This function will generate the appropriate calls to make
-   --  sure that the objects referenced by Ref are initialized. The
-   --  generate code is quite different depending on the fact the type
-   --  IS_Controlled or HAS_Controlled but this is not the problem of the
-   --  caller, the details are in the body.
+   --  This function will generate the appropriate calls to make sure that the
+   --  objects referenced by Ref are initialized. The generated code is quite
+   --  different for an IS_Controlled type or a HAS_Controlled type, but this
+   --  is not the problem for the caller, the details are in the body.
 
    function Make_Adjust_Call
      (Ref         : Node_Id;
@@ -110,23 +114,23 @@ package Exp_Ch7 is
       Flist_Ref   : Node_Id;
       With_Attach : Node_Id;
       Allocator   : Boolean := False) return List_Id;
-   --  Ref is an expression (with no-side effect and is not required to
-   --  have been previously analyzed) that references the object to be
-   --  adjusted. Typ is the expected type of Ref, which is a controlled
-   --  type (Is_Controlled) or a type with controlled components
-   --  (Has_Controlled).  With_Attach is an integer expression representing
-   --  the level of attachment, see Attach_To_Final_List's Nb_Link param
-   --  documentation in s-finimp.ads. Note: if Typ is Finalize_Storage_Only
-   --  and the object is at library level, then With_Attach will be ignored,
-   --  and a zero link level will be passed to Attach_To_Final_List.
+   --  Ref is an expression (with no-side effect and is not required to have
+   --  been previously analyzed) that references the object to be adjusted. Typ
+   --  is the expected type of Ref, which is a controlled type (Is_Controlled)
+   --  or a type with controlled components (Has_Controlled). With_Attach is an
+   --  integer expression giving the attachment level (see documentation of
+   --  Attach_To_Final_List.Nb_Link param documentation in s-finimp.ads.
+   --  Note: if Typ is Finalize_Storage_Only and the object is at library
+   --  level, then With_Attach will be ignored, and a zero link level will be
+   --  passed to Attach_To_Final_List.
    --
-   --  This function will generate the appropriate calls to make
-   --  sure that the objects referenced by Ref are adjusted. The generated
-   --  code is quite different depending on the fact the type IS_Controlled
-   --  or HAS_Controlled but this is not the problem of the caller, the
-   --  details are in the body. The objects must be attached when the adjust
-   --  takes place after an initialization expression but not when it takes
-   --  place after a regular assignment.
+   --  This function will generate the appropriate calls to make sure that the
+   --  objects referenced by Ref are adjusted. The generated code is quite
+   --  different depending on the fact the type IS_Controlled or HAS_Controlled
+   --  but this is not the problem of the caller, the details are in the body.
+   --  The objects must be attached when the adjust takes place after an
+   --  initialization expression but not when it takes place after a regular
+   --  assignment.
    --
    --  If Allocator is True, we are adjusting a newly-created object. The
    --  existing chaining pointers should not be left unchanged, because they
@@ -138,21 +142,21 @@ package Exp_Ch7 is
      (Ref         : Node_Id;
       Typ         : Entity_Id;
       With_Detach : Node_Id) return List_Id;
-   --  Ref is an expression (with no-side effect and is not required
-   --  to have been previously analyzed) that references the object to
-   --  be Finalized. Typ is the expected type of Ref, which is a
-   --  controlled type (Is_Controlled) or a type with controlled
-   --  components (Has_Controlled). With_Detach is a boolean expression
-   --  indicating whether to detach the controlled object from whatever
-   --  finalization list it is currently attached to.
+   --  Ref is an expression (with no-side effect and is not required to have
+   --  been previously analyzed) that references the object to be Finalized.
+   --  Typ is the expected type of Ref, which is a controlled type
+   --  (Is_Controlled) or a type with controlled components (Has_Controlled).
+   --  With_Detach is a boolean expression indicating whether to detach the
+   --  controlled object from whatever finalization list it is currently
+   --  attached to.
    --
-   --  This function will generate the appropriate calls to make
-   --  sure that the objects referenced by Ref are finalized. The generated
-   --  code is quite different depending on the fact the type IS_Controlled
-   --  or HAS_Controlled but this is not the problem of the caller, the
-   --  details are in the body. The objects must be detached when finalizing
-   --  an unchecked deallocated object but not when finalizing the target of
-   --  an assignment, it is not necessary either on scope exit.
+   --  This function will generate the appropriate calls to make sure that the
+   --  objects referenced by Ref are finalized. The generated code is quite
+   --  different depending on the fact the type IS_Controlled or HAS_Controlled
+   --  but this is not the problem of the caller, the details are in the body.
+   --  The objects must be detached when finalizing an unchecked deallocated
+   --  object but not when finalizing the target of an assignment, it is not
+   --  necessary either on scope exit.
 
    procedure Expand_Ctrl_Function_Call (N : Node_Id);
    --  Expand a call to a function returning a controlled value. That is to
@@ -167,8 +171,8 @@ package Exp_Ch7 is
      (N   : Node_Id;
       Obj : Node_Id;
       Typ : Entity_Id) return List_Id;
-   --  Generate loops to finalize any tasks or simple protected objects
-   --  that are subcomponents of an array.
+   --  Generate loops to finalize any tasks or simple protected objects that
+   --  are subcomponents of an array.
 
    function Cleanup_Protected_Object
      (N   : Node_Id;
@@ -191,10 +195,10 @@ package Exp_Ch7 is
    --  Check whether composite type contains a simple protected component
 
    function Is_Simple_Protected_Type (T : Entity_Id) return Boolean;
-   --  Check whether argument is a protected type without entries.
-   --  Protected types with entries are controlled, and their cleanup
-   --  is handled by the standard finalization machinery. For simple
-   --  protected types we generate inline code to release their locks.
+   --  Check whether argument is a protected type without entries. Protected
+   --  types with entries are controlled, and their cleanup is handled by the
+   --  standard finalization machinery. For simple protected types we generate
+   --  inline code to release their locks.
 
    --------------------------------
    -- Transient Scope Management --
@@ -215,12 +219,12 @@ package Exp_Ch7 is
    --  return the node to be wrapped if the current scope is transient
 
    procedure Store_Before_Actions_In_Scope (L : List_Id);
-   --  Append the list L of actions to the end of the before-actions store
-   --  in the top of the scope stack
+   --  Append the list L of actions to the end of the before-actions store in
+   --  the top of the scope stack
 
    procedure Store_After_Actions_In_Scope (L : List_Id);
-   --  Append the list L of actions to the beginning of the after-actions
-   --  store in the top of the scope stack
+   --  Append the list L of actions to the beginning of the after-actions store
+   --  in the top of the scope stack
 
    procedure Wrap_Transient_Declaration (N : Node_Id);
    --  N is an object declaration. Expand the finalization calls after the