home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / exp_ch9.adb < prev    next >
Text File  |  1996-09-28  |  218KB  |  6,178 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                              E X P _ C H 9                               --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.219 $                            --
  10. --                                                                          --
  11. --        Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved        --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
  22. --                                                                          --
  23. ------------------------------------------------------------------------------
  24.  
  25. with Atree;    use Atree;
  26. with Einfo;    use Einfo;
  27. with Elists;   use Elists;
  28. with Expander; use Expander;
  29. with Exp_Ch3;  use Exp_Ch3;
  30. with Exp_Ch6;  use Exp_Ch6;
  31. with Exp_TSS;  use Exp_TSS;
  32. with Exp_Util; use Exp_Util;
  33. with Freeze;   use Freeze;
  34. with Namet;    use Namet;
  35. with Nlists;   use Nlists;
  36. with Nmake;    use Nmake;
  37. with Rtsfind;  use Rtsfind;
  38. with Sem;      use Sem;
  39. with Sem_Ch5;
  40. with Sem_Ch6;
  41. with Sem_Ch11; use Sem_Ch11;
  42. with Sem_Ch13; use Sem_Ch13;
  43. with Sem_Util; use Sem_Util;
  44. with Sinfo;    use Sinfo;
  45. with Snames;   use Snames;
  46. with Stand;    use Stand;
  47. with Tbuild;   use Tbuild;
  48. with Types;    use Types;
  49. with Uintp;    use Uintp;
  50.  
  51. package body Exp_Ch9 is
  52.  
  53.    -----------------------
  54.    -- Local Subprograms --
  55.    -----------------------
  56.  
  57.    procedure Add_Object_Pointer
  58.      (Decls : List_Id;
  59.       Pid : Entity_Id;
  60.       Loc : Source_Ptr);
  61.    --  Prepend an object pointer declaration to the declaration list
  62.    --  Decls.  This object pointer is initialized to a type conversion
  63.    --  of the System.Address pointer passed to entry barrier functions
  64.    --  and entry body procedures.
  65.  
  66.    function Array_Type (E : Entity_Id; Trec : Node_Id) return Entity_Id;
  67.    --  Find the array type associated with an entry family in the
  68.    --  associated record for the task type.
  69.  
  70.    function Build_Accept_Body
  71.      (Stats : Node_Id;
  72.       Loc   : Source_Ptr)
  73.       return  Node_Id;
  74.    --  Transform accept statement into a block with added exception handler.
  75.    --  Cused both for simple accept statements and for accept alternatives in
  76.    --  select statements.
  77.  
  78.    function Build_Barrier_Function
  79.      (N         : Node_Id;
  80.       Pid       : Node_Id)
  81.       return Node_Id;
  82.    --  Build the function body returning the value of the barrier expression
  83.    --  for the specified entry body.
  84.  
  85.    function Build_Barrier_Function_Specification
  86.      (Def_Id : Entity_Id;
  87.       Loc    : Source_Ptr)
  88.       return Node_Id;
  89.    --  Build a specification for a function implementing
  90.    --  the protected entry barrier of the specified entry body.
  91.  
  92.    function Build_Corresponding_Record
  93.      (N    : Node_Id;
  94.       Ctyp : Node_Id;
  95.       Loc  : Source_Ptr)
  96.       return Node_Id;
  97.    --  Common to tasks and protected types. Copy discriminant specifications,
  98.    --  build record declaration.
  99.  
  100.    function Build_Entry_Count_Expression
  101.      (Concurrent_Type : Node_Id;
  102.       Component_List  : List_Id;
  103.       Loc             : Source_Ptr)
  104.       return            Node_Id;
  105.    --  Compute number of entries for concurrent object. This is a count of
  106.    --  simple entries, followed by an expression that computes the length
  107.    --  of the range of each entry family.
  108.  
  109.    function Build_Protected_Entry
  110.      (N         : Node_Id;
  111.       Pid       : Node_Id)
  112.       return Node_Id;
  113.    --  Build the procedure implementing the statement sequence of
  114.    --  the specified entry body.
  115.  
  116.    function Build_Protected_Entry_Specification
  117.      (Def_Id : Entity_Id;
  118.       Ent_Id : Entity_Id;
  119.       Loc    : Source_Ptr)
  120.       return Node_Id;
  121.    --  Build a specification for a procedure implementing
  122.    --  the statement sequence of the specified entry body.
  123.    --  Add attributes associating it with the entry defining identifier
  124.    --  Ent_Id.
  125.  
  126.    function Build_Protected_Sub_Specification
  127.      (N           : Node_Id;
  128.       Prottyp     : Entity_Id;
  129.       Unprotected : Boolean := False)
  130.       return        Node_Id;
  131.    --  Build specification for protected subprogram.
  132.  
  133.    function Build_Protected_Subprogram_Body
  134.      (N         : Node_Id;
  135.       Pid       : Node_Id;
  136.       N_Op_Spec : Node_Id)
  137.       return      Node_Id;
  138.    --  This function is used to construct the protected version of a protected
  139.    --  subprogram. It locks the associated protected object, then calls the
  140.    --  unprotected version of the subprogram (for further details, see
  141.    --  Build_Unprotected_Subprogram_Body).
  142.  
  143.    function Build_Selected_Name
  144.      (Prefix, Selector : Name_Id;
  145.       Append_Char      : Character := ' ')
  146.       return Name_Id;
  147.    --  Build a name in the form of Prefix__Selector, with an optional
  148.    --  character appended.
  149.  
  150.    procedure Build_Simple_Entry_Call
  151.      (N       : Node_Id;
  152.       Concval : Node_Id;
  153.       Ename   : Node_Id;
  154.       Index   : Node_Id);
  155.  
  156.    function Build_Standard_Exception_Handlers
  157.      (Sub  : Entity_Id;
  158.       Loc  : Source_Ptr)
  159.       return List_Id;
  160.    --  This routine constructs a list of exception handlers, one for
  161.    --  each of the standard exceptions and one for others.  It calls
  162.    --  the subprogram referenced by Sub in each of these handlers with
  163.    --  the ID of the corresponding exception, and with Current_Exception
  164.    --  for the others case.  This is an interim implementation of the
  165.    --  mechanism for raising exceptions in other tasks (e.g. raising
  166.    --  an exception that completes an accept statement in the caller) so
  167.    --  that at least the standard exceptions work.  Full implementation will
  168.    --  require Ada.Exceptions.
  169.  
  170.    function Build_Task_Proc_Specification (T : Entity_Id) return Node_Id;
  171.    --  This routine constructs a specification for the procedure that we will
  172.    --  build for the task body for task type T. The spec has the form:
  173.    --
  174.    --    procedure tnameB (_Task : access tnameV);
  175.    --
  176.    --  where name is the character name taken from the task type entity that
  177.    --  is passed as the argument to the procedure, and tnameV is the task
  178.    --  value type that is associated with the task type.
  179.  
  180.    function Build_Unprotected_Subprogram_Body
  181.      (N    : Node_Id;
  182.       Pid  : Node_Id)
  183.       return Node_Id;
  184.    --  This routine constructs the unprotected version of a protected
  185.    --  subprogram body, which is contains all of the code in the
  186.    --  original, unexpanded body. This is the version of the protected
  187.    --  subprogram that is called from all protected operations on the same
  188.    --  object, including the protected version of the same subprogram.
  189.  
  190.    procedure Collect_Entry_Families
  191.      (Loc          : Source_Ptr;
  192.       Cdecls       : List_Id;
  193.       Current_Node : in out Node_Id;
  194.       Conctyp      : Entity_Id);
  195.    --  For each entry family in a concurrent type, create an anonymous array
  196.    --  type of the right size, and add a component to the corresponding_record.
  197.  
  198.    function Entry_Range_Expression
  199.      (Sloc  : Source_Ptr;
  200.       Ent   : Entity_Id;
  201.       Ttyp  : Entity_Id)
  202.       return  Node_Id;
  203.    --  Returns the entry index range allocated to an entry family.
  204.    --  Ttyp is the concurrent type.
  205.  
  206.    procedure Extract_Entry
  207.      (N       : Node_Id;
  208.       Concval : out Node_Id;
  209.       Ename   : out Node_Id;
  210.       Index   : out Node_Id);
  211.    --  Given an entry call, returns the associated concurrent object,
  212.    --  the entry name, and the entry family index.
  213.  
  214.    function Find_Task_Pragma (T : Node_Id; P : Name_Id) return Node_Id;
  215.    --  Searches the task definition T for the first occurrence of the pragma
  216.    --  whose name is given by P. The caller has ensured that the pragma is
  217.    --  present in the task definition.
  218.  
  219.    function Concurrent_Ref (N : Node_Id) return Node_Id;
  220.    --  Given the name of a concurrent object (task or protected object),
  221.    --  or the name of an access to a concurrent object, this
  222.    --  function returns an expression referencing the associated Task_Id
  223.    --  or Protection object, respectively.
  224.    --  Note that a special case is when the name is a reference to a task
  225.    --  type name. This can only happen within a task body, and the meaning
  226.    --  is to get the Task_Id for the currently executing task.
  227.  
  228.    ----------------------------------
  229.    -- Add_Discriminal_Declarations --
  230.    ----------------------------------
  231.  
  232.    procedure Add_Discriminal_Declarations
  233.      (Decls : List_Id;
  234.       Typ   : Entity_Id;
  235.       Name  : Name_Id;
  236.       Loc   : Source_Ptr)
  237.    is
  238.       D     : Entity_Id;
  239.  
  240.    begin
  241.       if Has_Discriminants (Typ) then
  242.          D := First_Discriminant (Typ);
  243.  
  244.          while Present (D) loop
  245.  
  246.             Prepend_To (Decls,
  247.               Make_Object_Renaming_Declaration (Loc,
  248.                 Defining_Identifier => Discriminal (D),
  249.                 Subtype_Mark => New_Reference_To (Etype (D), Loc),
  250.                 Name =>
  251.                   Make_Selected_Component (Loc,
  252.                     Prefix        => Make_Identifier (Loc, Name),
  253.                     Selector_Name => Make_Identifier (Loc, Chars (D)))));
  254.  
  255.             D := Next_Discriminant (D);
  256.          end loop;
  257.       end if;
  258.    end Add_Discriminal_Declarations;
  259.  
  260.    ------------------------
  261.    -- Add_Object_Pointer --
  262.    ------------------------
  263.  
  264.    procedure Add_Object_Pointer
  265.      (Decls : List_Id;
  266.       Pid : Entity_Id;
  267.       Loc : Source_Ptr)
  268.    is
  269.       Obj_Ptr : Node_Id;
  270.  
  271.    begin
  272.       --  Prepend the declaration of _object. This must be first in the
  273.       --  declaration list, since it is used by the discriminal and
  274.       --  prival declarations.
  275.       --  ??? An attempt to make this a renaming was unsuccessful.
  276.       --
  277.       --     type poVP is access poV;
  278.       --     _object : poVP := poVP!O;
  279.  
  280.       Obj_Ptr := Make_Defining_Identifier (Loc,
  281.         Chars =>
  282.           New_External_Name
  283.             (Chars (Corresponding_Record_Type (Pid)), 'P'));
  284.  
  285.       Prepend_To (Decls,
  286.         Make_Object_Declaration (Loc,
  287.           Defining_Identifier =>
  288.             Make_Defining_Identifier (Loc, Name_uObject),
  289.           Object_Definition => New_Reference_To (Obj_Ptr, Loc),
  290.           Expression =>
  291.             Make_Unchecked_Type_Conversion (Loc,
  292.               Subtype_Mark => New_Reference_To (Obj_Ptr, Loc),
  293.               Expression => Make_Identifier (Loc, Name_uO))));
  294.  
  295.       Prepend_To (Decls,
  296.         Make_Full_Type_Declaration (Loc,
  297.           Defining_Identifier => Obj_Ptr,
  298.           Type_Definition => Make_Access_To_Object_Definition (Loc,
  299.             Subtype_Indication =>
  300.               New_Reference_To (Corresponding_Record_Type (Pid), Loc))));
  301.  
  302.    end Add_Object_Pointer;
  303.  
  304.    ------------------------------
  305.    -- Add_Private_Declarations --
  306.    ------------------------------
  307.  
  308.    procedure Add_Private_Declarations
  309.      (Decls : List_Id;
  310.       Typ   : Entity_Id;
  311.       Name  : Name_Id;
  312.       Loc   : Source_Ptr)
  313.    is
  314.       P        : Node_Id;
  315.       Pdef     : Entity_Id;
  316.       Def      : Node_Id := Protected_Definition (Parent (Typ));
  317.       Body_Ent : constant Entity_Id := Corresponding_Body (Parent (Typ));
  318.  
  319.    begin
  320.       pragma Assert (Nkind (Def) = N_Protected_Definition);
  321.  
  322.       if Present (Private_Declarations (Def)) then
  323.          P := First (Private_Declarations (Def));
  324.  
  325.          while Present (P) loop
  326.             if Nkind (P) = N_Component_Declaration then
  327.                Pdef := Defining_Identifier (P);
  328.                Prepend_To (Decls,
  329.                  Make_Object_Renaming_Declaration (Loc,
  330.                    Defining_Identifier => Prival (Pdef),
  331.                    Subtype_Mark => New_Reference_To (Etype (Pdef), Loc),
  332.                    Name =>
  333.                      Make_Selected_Component (Loc,
  334.                        Prefix        => Make_Identifier (Loc, Name),
  335.                        Selector_Name => Make_Identifier (Loc, Chars (Pdef)))));
  336.             end if;
  337.             P := Next (P);
  338.          end loop;
  339.       end if;
  340.  
  341.       --  One more "prival" for the object itself.
  342.  
  343.       Prepend_To (Decls,
  344.         Make_Object_Renaming_Declaration (Loc,
  345.           Defining_Identifier => Object_Ref (Body_Ent),
  346.           Subtype_Mark => New_Reference_To (RTE (RE_Protection), Loc),
  347.           Name =>
  348.             Make_Selected_Component (Loc,
  349.               Prefix        => Make_Identifier (Loc, Name),
  350.               Selector_Name => Make_Identifier (Loc, Name_uObject))));
  351.  
  352.    end Add_Private_Declarations;
  353.  
  354.    ----------------
  355.    -- Array_Type --
  356.    ----------------
  357.  
  358.    function Array_Type (E : Entity_Id; Trec : Node_Id) return Entity_Id is
  359.       Arr : Entity_Id := First_Component (Trec);
  360.  
  361.    begin
  362.       while Present (Arr) loop
  363.          exit when Ekind (Arr) = E_Component
  364.            and then Is_Array_Type (Etype (Arr))
  365.            and then Chars (Arr) = Chars (E);
  366.  
  367.          Arr := Next_Component (Arr);
  368.       end loop;
  369.  
  370.       --  This used to return Arr itself, but this caused problems
  371.       --  when used in expanding a protected type, possibly because
  372.       --  the record of which it is a component is not frozen yet.
  373.       --  I am going to try the type instead.  This may pose visibility
  374.       --  problems. ???
  375.  
  376.       return Etype (Arr);
  377.    end Array_Type;
  378.  
  379.    -----------------------
  380.    -- Build_Accept_Body --
  381.    -----------------------
  382.  
  383.    function Build_Accept_Body
  384.      (Stats : Node_Id;
  385.       Loc   : Source_Ptr)
  386.       return  Node_Id
  387.    is
  388.       Block : Node_Id;
  389.       New_S : Node_Id;
  390.       Hand  : Node_Id;
  391.       Call  : Node_Id;
  392.  
  393.    begin
  394.       --  Add the end of the statement sequence, Complete_Rendezvous is called.
  395.       --  A label skipping the Complete_Rendezvous, and all other
  396.       --  accept processing, has already been added for the expansion
  397.       --  of requeue statements.
  398.  
  399.       Call := Build_Runtime_Call (Loc, RE_Complete_Rendezvous);
  400.       Insert_Before (Last (Statements (Stats)), Call);
  401.       Analyze (Call);
  402.  
  403.       --  If exception handlers are present, then append Complete_Rendezvous
  404.       --  calls to the handlers, and construct the required outer block.
  405.  
  406.       if Present (Exception_Handlers (Stats)) then
  407.          Hand := First (Exception_Handlers (Stats));
  408.  
  409.          while Present (Hand) loop
  410.             Call := Build_Runtime_Call (Loc, RE_Complete_Rendezvous);
  411.             Append (Call, Statements (Hand));
  412.             Analyze (Call);
  413.             Hand := Next (Hand);
  414.          end loop;
  415.  
  416.          New_S :=
  417.            Make_Handled_Sequence_Of_Statements (Loc,
  418.              Statements => New_List (
  419.                Make_Block_Statement (Loc,
  420.                Handled_Statement_Sequence => Stats)));
  421.  
  422.       else
  423.          New_S := Stats;
  424.       end if;
  425.  
  426.       --  At this stage we know that the new statement sequence does not
  427.       --  have an exception handler part, so we supply one to call
  428.       --  Exceptional_Complete_Rendezvous.
  429.  
  430.       Set_Exception_Handlers (New_S,
  431.         Build_Standard_Exception_Handlers (
  432.           RTE (RE_Exceptional_Complete_Rendezvous), Loc));
  433.       Analyze_Exception_Handlers (Exception_Handlers (New_S));
  434.  
  435.       return New_S;
  436.  
  437.    end Build_Accept_Body;
  438.  
  439.    -----------------------------------
  440.    -- Build_Activation_Chain_Entity --
  441.    -----------------------------------
  442.  
  443.    procedure Build_Activation_Chain_Entity (N : Node_Id) is
  444.       P     : Node_Id;
  445.       B     : Node_Id;
  446.       Decls : List_Id;
  447.  
  448.    begin
  449.       --  Loop to find enclosing construct containing activation chain variable
  450.  
  451.       P := Parent (N);
  452.  
  453.       while Nkind (P) /= N_Subprogram_Body
  454.         and then Nkind (P) /= N_Package_Declaration
  455.         and then Nkind (P) /= N_Package_Body
  456.         and then Nkind (P) /= N_Block_Statement
  457.         and then Nkind (P) /= N_Task_Body
  458.       loop
  459.          P := Parent (P);
  460.       end loop;
  461.  
  462.       --  If we are in a package body, the activation chain variable is
  463.       --  allocated in the corresponding spec. First, we save the package
  464.       --  body node because we enter the new entity in its Declarations list.
  465.  
  466.       B := P;
  467.  
  468.       if Nkind (P) = N_Package_Body then
  469.          P := Get_Declaration_Node (Corresponding_Spec (P));
  470.          Decls := Declarations (B);
  471.  
  472.       elsif Nkind (P) = N_Package_Declaration then
  473.          Decls := Visible_Declarations (Specification (B));
  474.  
  475.       else
  476.          Decls := Declarations (B);
  477.       end if;
  478.  
  479.       --  If activation chain entity not already declared, declare it
  480.  
  481.       if No (Activation_Chain_Entity (P)) then
  482.          Set_Activation_Chain_Entity
  483.            (P, Make_Defining_Identifier (Sloc (P), Name_uChain));
  484.  
  485.          Prepend_To (Decls,
  486.            Make_Object_Declaration (Sloc (P),
  487.              Defining_Identifier => Activation_Chain_Entity (P),
  488.              Aliased_Present => True,
  489.              Object_Definition   =>
  490.                New_Reference_To (RTE (RE_Activation_Chain), Sloc (P))));
  491.  
  492.          Analyze (First (Decls));
  493.       end if;
  494.  
  495.    end Build_Activation_Chain_Entity;
  496.  
  497.    ----------------------------
  498.    -- Build_Barrier_Function --
  499.    ----------------------------
  500.  
  501.    function Build_Barrier_Function
  502.      (N         : Node_Id;
  503.       Pid       : Node_Id)
  504.       return Node_Id
  505.    is
  506.       Loc         : constant Source_Ptr := Sloc (N);
  507.       Ent_Name    : constant Name_Id    := Chars (Defining_Identifier (N));
  508.       Ent_Formals : constant Node_Id    := Entry_Body_Formal_Part (N);
  509.       Bdef        : Entity_Id;
  510.       Bspec       : Node_Id;
  511.       Op_Decls    : List_Id := New_List;
  512.  
  513.    begin
  514.       Bdef := Make_Defining_Identifier (Loc,
  515.         Build_Selected_Name (Chars (Pid), Ent_Name, 'B'));
  516.       Bspec := Build_Barrier_Function_Specification (Bdef, Loc);
  517.  
  518.       --  <object pointer declaration>
  519.       --  <discriminant renamings>
  520.       --  <private object renamings>
  521.       --  Add discriminal and private renamings. These names have
  522.       --  already been used to expand references to discriminants
  523.       --  and private data.
  524.  
  525.       Add_Discriminal_Declarations (Op_Decls, Pid, Name_uObject, Loc);
  526.       Add_Private_Declarations (Op_Decls, Pid, Name_uObject, Loc);
  527.       Add_Object_Pointer (Op_Decls, Pid, Loc);
  528.  
  529.       return
  530.         Make_Subprogram_Body (Loc,
  531.           Specification => Bspec,
  532.           Declarations => Op_Decls,
  533.           Handled_Statement_Sequence =>
  534.             Make_Handled_Sequence_Of_Statements (Loc,
  535.               Statements => New_List (
  536.                 Make_Return_Statement (Loc,
  537.                   Expression => Condition (Ent_Formals)))));
  538.    end Build_Barrier_Function;
  539.  
  540.    ------------------------------------------
  541.    -- Build_Barrier_Function_Specification --
  542.    ------------------------------------------
  543.  
  544.    function Build_Barrier_Function_Specification
  545.      (Def_Id : Entity_Id;
  546.       Loc    : Source_Ptr)
  547.       return   Node_Id
  548.    is
  549.    begin
  550.       return Make_Function_Specification (Loc,
  551.         Defining_Unit_Name => Def_Id,
  552.         Parameter_Specifications => New_List (
  553.           Make_Parameter_Specification (Loc,
  554.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
  555.             Parameter_Type =>
  556.               New_Reference_To (RTE (RE_Address), Loc)),
  557.  
  558.           Make_Parameter_Specification (Loc,
  559.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uE),
  560.             Parameter_Type =>
  561.               New_Reference_To (RTE (RE_Protected_Entry_Index), Loc))),
  562.  
  563.         Subtype_Mark => New_Reference_To (Standard_Boolean, Loc));
  564.    end Build_Barrier_Function_Specification;
  565.  
  566.    --------------------------
  567.    -- Build_Call_With_Task --
  568.    --------------------------
  569.  
  570.    function Build_Call_With_Task
  571.      (N    : Node_Id;
  572.       E    : Entity_Id)
  573.       return Node_Id
  574.    is
  575.       Loc : constant Source_Ptr := Sloc (N);
  576.  
  577.    begin
  578.       return
  579.         Make_Function_Call (Loc,
  580.           Name => New_Reference_To (E, Loc),
  581.           Parameter_Associations => New_List (Concurrent_Ref (N)));
  582.    end Build_Call_With_Task;
  583.  
  584.    --------------------------------
  585.    -- Build_Corresponding_Record --
  586.    --------------------------------
  587.  
  588.    function Build_Corresponding_Record
  589.     (N    : Node_Id;
  590.      Ctyp : Entity_Id;
  591.      Loc  : Source_Ptr)
  592.      return Node_Id
  593.    is
  594.       Disc     : Entity_Id;
  595.       Dlist    : List_Id;
  596.       Rec_Ent  : constant Entity_Id :=
  597.                    Make_Defining_Identifier
  598.                      (Loc, New_External_Name (Chars (Ctyp), 'V'));
  599.       Rec_Decl : Node_Id;
  600.       Cdecls   : List_Id;
  601.  
  602.    begin
  603.       Set_Corresponding_Record_Type (Ctyp, Rec_Ent);
  604.       Set_Ekind (Rec_Ent, E_Record_Type);
  605.       Set_Is_Concurrent_Record_Type (Rec_Ent, True);
  606.       Set_Corresponding_Concurrent_Type (Rec_Ent, Ctyp);
  607.  
  608.       Cdecls := New_List;
  609.  
  610.       --  Make a copy of the discriminant specifications
  611.  
  612.       if Present (Discriminant_Specifications (N)) then
  613.          Dlist := New_List;
  614.          Disc := First (Discriminant_Specifications (N));
  615.  
  616.          while Present (Disc) loop
  617.             Append_To (Dlist,
  618.               Make_Discriminant_Specification (Loc,
  619.                 Defining_Identifier =>
  620.                   New_Copy (Defining_Identifier (Disc)),
  621.                 Discriminant_Type =>
  622.                   New_Occurrence_Of (Etype (Defining_Identifier (Disc)), Loc),
  623.                 Expression =>
  624.                   New_Copy (Expression (Disc))));
  625.             Disc := Next (Disc);
  626.          end loop;
  627.  
  628.       else
  629.          Dlist := No_List;
  630.       end if;
  631.  
  632.       --  Now we can construct the record type declaration
  633.  
  634.       Rec_Decl :=
  635.         Make_Full_Type_Declaration (Loc,
  636.           Defining_Identifier => Rec_Ent,
  637.           Discriminant_Specifications => Dlist,
  638.           Type_Definition =>
  639.             Make_Record_Definition (Loc,
  640.               Component_List =>
  641.                 Make_Component_List (Loc,
  642.                   Component_Items => Cdecls)));
  643.  
  644.       return Rec_Decl;
  645.    end Build_Corresponding_Record;
  646.  
  647.    ----------------------------------
  648.    -- Build_Entry_Count_Expression --
  649.    ----------------------------------
  650.  
  651.    function Build_Entry_Count_Expression
  652.      (Concurrent_Type : Node_Id;
  653.       Component_List  : List_Id;
  654.       Loc             : Source_Ptr)
  655.       return            Node_Id
  656.    is
  657.       Eindx  : Nat;
  658.       Ent    : Entity_Id;
  659.       Ecount : Node_Id;
  660.       Comp   : Node_Id;
  661.  
  662.    begin
  663.       Ent := First_Entity (Concurrent_Type);
  664.       Eindx := 0;
  665.  
  666.       --  Count number of non-family entries
  667.  
  668.       while Present (Ent) loop
  669.          if Ekind (Ent) = E_Entry then
  670.             Eindx := Eindx + 1;
  671.          end if;
  672.  
  673.          Ent := Next_Entity (Ent);
  674.       end loop;
  675.  
  676.       Ecount := Make_Integer_Literal (Loc, UI_From_Int (Eindx));
  677.  
  678.       --  Loop through entry families building the addition nodes
  679.  
  680.       Ent := First_Entity (Concurrent_Type);
  681.       Comp := First (Component_List);
  682.       while Present (Ent) loop
  683.          if Ekind (Ent) = E_Entry_Family then
  684.             while Chars (Ent) /= Chars (Defining_Identifier (Comp)) loop
  685.                Comp := Next (Comp);
  686.             end loop;
  687.  
  688.             Ecount :=
  689.               Make_Op_Add (Loc,
  690.                 Left_Opnd  => Ecount,
  691.                 Right_Opnd =>
  692.                   Make_Attribute_Reference (Loc,
  693.                     Prefix => New_Reference_To (
  694.                       Etype (Subtype_Indication (Comp)),
  695.                       Loc),
  696.                     Attribute_Name => Name_Length));
  697.          end if;
  698.  
  699.          Ent := Next_Entity (Ent);
  700.       end loop;
  701.       return Ecount;
  702.    end Build_Entry_Count_Expression;
  703.  
  704.    -------------------------
  705.    -- Build_Master_Entity --
  706.    -------------------------
  707.  
  708.    procedure Build_Master_Entity (E : Entity_Id) is
  709.       Loc  : constant Source_Ptr := Sloc (E);
  710.       P    : Node_Id;
  711.       Decl : Node_Id;
  712.  
  713.    begin
  714.       --  Nothing to do if we already built a master entity for this scope
  715.  
  716.       if Has_Master_Entity (Scope (E)) then
  717.          return;
  718.       end if;
  719.  
  720.       --  Otherwise first build the master entity
  721.       --    _Master : constant Master_Id := Current_Master;
  722.       --  and insert it just before the current declaration
  723.  
  724.       Decl :=
  725.         Make_Object_Declaration (Loc,
  726.           Defining_Identifier =>
  727.             Make_Defining_Identifier (Loc, Name_uMaster),
  728.           Constant_Present => True,
  729.           Object_Definition => New_Reference_To (RTE (RE_Master_Id), Loc),
  730.           Expression => New_Reference_To (RTE (RE_Current_Master), Loc));
  731.  
  732.       P := Parent (E);
  733.       Insert_Before (P, Decl);
  734.       Analyze (Decl);
  735.       Set_Has_Master_Entity (Scope (E));
  736.  
  737.       --  Now mark the containing scope as a task master
  738.  
  739.       while Nkind (P) /= N_Compilation_Unit loop
  740.          P := Parent (P);
  741.  
  742.          --  If we fall off the top, we are at the outer level, and the
  743.          --  environment task is our effective master, so nothing to mark.
  744.  
  745.          if Nkind (P) = N_Task_Body
  746.            or else Nkind (P) = N_Block_Statement
  747.            or else Nkind (P) = N_Subprogram_Body
  748.          then
  749.             Set_Is_Task_Master (P, True);
  750.             return;
  751.          end if;
  752.       end loop;
  753.    end Build_Master_Entity;
  754.  
  755.    ---------------------------
  756.    -- Build_Protected_Entry --
  757.    ---------------------------
  758.  
  759.    function Build_Protected_Entry
  760.      (N         : Node_Id;
  761.       Pid       : Node_Id)
  762.       return Node_Id
  763.    is
  764.       Loc         : constant Source_Ptr := Sloc (N);
  765.       Ent_Name    : constant Name_Id    :=
  766.         Chars (Defining_Identifier (N));
  767.       Edef        : Entity_Id;
  768.       Espec       : Node_Id;
  769.       Op_Decls    : List_Id := New_List;
  770.       Op_Stats    : List_Id;
  771.  
  772.    begin
  773.       Edef := Make_Defining_Identifier (Loc,
  774.         Build_Selected_Name (Chars (Pid), Ent_Name, 'E'));
  775.       Espec := Build_Protected_Entry_Specification (Edef, Empty, Loc);
  776.  
  777.       --  <object pointer declaration>
  778.       --  Add object pointer declaration.  This is needed by the
  779.       --  discriminal and prival renamings, which should already
  780.       --  have been inserted into the declaration list.
  781.  
  782.       Add_Object_Pointer (Op_Decls, Pid, Loc);
  783.  
  784.       Op_Stats := New_List (
  785.          Make_Block_Statement (Loc,
  786.            Declarations => Declarations (N),
  787.            Handled_Statement_Sequence =>
  788.              Handled_Statement_Sequence (N)),
  789.  
  790.          Make_Procedure_Call_Statement (Loc,
  791.            Name =>
  792.              New_Reference_To (
  793.                RTE (RE_Complete_Entry_Body), Loc),
  794.  
  795.            Parameter_Associations => New_List (
  796.              Make_Attribute_Reference (Loc,
  797.                Prefix =>
  798.                  Make_Selected_Component (Loc,
  799.                    Prefix =>
  800.                      Make_Identifier (Loc, Name_uObject),
  801.  
  802.                    Selector_Name =>
  803.                      Make_Identifier (Loc, Name_uObject)),
  804.                  Attribute_Name => Name_Unchecked_Access))));
  805.  
  806.       return
  807.         Make_Subprogram_Body (Loc,
  808.           Specification => Espec,
  809.           Declarations => Op_Decls,
  810.           Handled_Statement_Sequence =>
  811.             Make_Handled_Sequence_Of_Statements (Loc,
  812.               Statements => Op_Stats,
  813.               Exception_Handlers => New_List (
  814.                 Make_Exception_Handler (Loc,
  815.                   Exception_Choices =>
  816.                     New_List (Make_Others_Choice (Loc)),
  817.  
  818.                   Statements =>  New_List (
  819.                     Make_Procedure_Call_Statement (Loc,
  820.                       Name => New_Reference_To (
  821.                         RTE (RE_Exceptional_Complete_Entry_Body), Loc),
  822.  
  823.                       Parameter_Associations => New_List (
  824.                         Make_Attribute_Reference (Loc,
  825.                           Prefix =>
  826.                             Make_Selected_Component (Loc,
  827.                               Prefix =>
  828.                                 Make_Identifier (Loc, Name_uObject),
  829.                               Selector_Name =>
  830.                                 Make_Identifier (Loc, Name_uObject)),
  831.                             Attribute_Name => Name_Unchecked_Access),
  832.  
  833.                         Make_Function_Call (Loc,
  834.                           Name => New_Reference_To (
  835.                             RTE (RE_Current_Exception), Loc)))))))));
  836.    end Build_Protected_Entry;
  837.  
  838.    -----------------------------------------
  839.    -- Build_Protected_Entry_Specification --
  840.    -----------------------------------------
  841.  
  842.    function Build_Protected_Entry_Specification
  843.      (Def_Id : Entity_Id;
  844.       Ent_Id : Entity_Id;
  845.       Loc    : Source_Ptr)
  846.       return Node_Id
  847.    is
  848.       P : Entity_Id;
  849.  
  850.    begin
  851.       P := Make_Defining_Identifier (Loc, Name_uP);
  852.  
  853.       if Present (Ent_Id) then
  854.          Append_Elmt (P, Accept_Address (Ent_Id));
  855.       end if;
  856.  
  857.       return Make_Procedure_Specification (Loc,
  858.         Defining_Unit_Name => Def_Id,
  859.         Parameter_Specifications => New_List (
  860.           Make_Parameter_Specification (Loc,
  861.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uO),
  862.             Parameter_Type =>
  863.               New_Reference_To (RTE (RE_Address), Loc)),
  864.  
  865.           Make_Parameter_Specification (Loc,
  866.             Defining_Identifier => P,
  867.             Parameter_Type =>
  868.               New_Reference_To (RTE (RE_Address), Loc)),
  869.  
  870.           Make_Parameter_Specification (Loc,
  871.             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uE),
  872.             Parameter_Type =>
  873.               New_Reference_To (RTE (RE_Protected_Entry_Index), Loc))));
  874.    end Build_Protected_Entry_Specification;
  875.  
  876.    -------------------------------------
  877.    -- Build_Protected_Subprogram_Body --
  878.    -------------------------------------
  879.  
  880.    function Build_Protected_Subprogram_Body
  881.      (N         : Node_Id;
  882.       Pid       : Node_Id;
  883.       N_Op_Spec : Node_Id)
  884.       return      Node_Id
  885.    is
  886.       Loc         : constant Source_Ptr := Sloc (N);
  887.       Op_Spec     : Node_Id;
  888.       Op_Def      : Entity_Id;
  889.       Sub_Name    : Name_Id;
  890.       P_Op_Spec   : Node_Id;
  891.       Op_Decls    : List_Id;
  892.       Uactuals    : List_Id;
  893.       Pformal     : Node_Id;
  894.       Return_Var  : Node_Id;
  895.       Unprot_Call : Node_Id;
  896.       Sub_Return  : Node_Id;
  897.       Final_Sub   : Node_Id;
  898.       Final_Stats : List_Id;
  899.       Final_Decls : List_Id;
  900.  
  901.    begin
  902.       Op_Spec := Specification (N);
  903.       Op_Def := Defining_Unit_Name (Op_Spec);
  904.  
  905.       --  Make an unprotected version of the subprogram for use
  906.       --  within the same object, with a new name and an additional
  907.       --  parameter representing the object.
  908.  
  909.       Sub_Name := Chars (Defining_Unit_Name (Specification (N)));
  910.  
  911.       P_Op_Spec :=
  912.         Build_Protected_Sub_Specification (N,
  913.           Pid, Unprotected => False);
  914.  
  915.       --  Build a list of the formal parameters of the protected
  916.       --  version of the subprogram to use as the actual parameters
  917.       --  of the unprotected version.
  918.  
  919.       Uactuals := New_List;
  920.       Pformal := First (Parameter_Specifications (P_Op_Spec));
  921.  
  922.       while Present (Pformal) loop
  923.          Append (
  924.            Make_Identifier (Loc, Chars (Defining_Identifier (Pformal))),
  925.            Uactuals);
  926.          Pformal := Next (Pformal);
  927.       end loop;
  928.  
  929.       --  Make a call to the unprotected version of the subprogram
  930.       --  built above for use by the protected version built below.
  931.  
  932.       if Nkind (Op_Spec) = N_Function_Specification then
  933.          Return_Var := Make_Defining_Identifier (Loc,
  934.            New_External_Name (Name_Return, 'P'));
  935.  
  936.          Op_Decls := New_List (
  937.            Make_Object_Declaration (Loc,
  938.              Defining_Identifier => Return_Var,
  939.              Object_Definition => New_Copy (Subtype_Mark (Op_Spec))));
  940.  
  941.          Unprot_Call := Make_Assignment_Statement (Loc,
  942.            Name => New_Reference_To (Return_Var, Loc),
  943.            Expression => Make_Function_Call (Loc,
  944.              Name =>
  945.                Make_Identifier (Loc,
  946.                  Chars (Defining_Unit_Name (N_Op_Spec))),
  947.              Parameter_Associations => Uactuals));
  948.  
  949.          Sub_Return := Make_Return_Statement (Loc,
  950.            Expression => New_Reference_To (Return_Var, Loc));
  951.  
  952.       else
  953.          Op_Decls := Empty_List;
  954.  
  955.          Unprot_Call := Make_Procedure_Call_Statement (Loc,
  956.            Name =>
  957.              Make_Identifier (Loc,
  958.                Chars (Defining_Unit_Name (N_Op_Spec))),
  959.            Parameter_Associations => Uactuals);
  960.  
  961.          Sub_Return := Make_Return_Statement (Loc);
  962.       end if;
  963.  
  964.       --  Make a subprogram to perform finalization for the
  965.       --  protected subprogram, unlocking the protected object
  966.       --  parameter and undeferring abortion.
  967.       --  If this is a protected procedure, and the object contains
  968.       --  entries, this also calls the entry service routine.
  969.  
  970.       Final_Stats := New_List (
  971.         Make_Procedure_Call_Statement (Loc,
  972.           Name =>
  973.             New_Reference_To (
  974.               RTE (RE_Unlock), Loc),
  975.  
  976.           Parameter_Associations => New_List (
  977.             Make_Attribute_Reference (Loc,
  978.               Prefix =>
  979.                 Make_Selected_Component (Loc,
  980.                   Prefix =>
  981.                     Make_Identifier (Loc, Name_uObject),
  982.                   Selector_Name =>
  983.                     Make_Identifier (Loc, Name_uObject)),
  984.               Attribute_Name => Name_Unchecked_Access))),
  985.  
  986.         Make_Procedure_Call_Statement (Loc,
  987.           Name =>
  988.             New_Reference_To (
  989.               RTE (RE_Abort_Undefer), Loc),
  990.           Parameter_Associations => Empty_List));
  991.  
  992.       if Nkind (Op_Spec) = N_Procedure_Specification
  993.         and then Has_Entries (Pid)
  994.       then
  995.          Prepend_To (Final_Stats,
  996.            Make_Procedure_Call_Statement (Loc,
  997.              Name => New_Reference_To (RTE (RE_Service_Entries), Loc),
  998.              Parameter_Associations => New_List (
  999.                Make_Attribute_Reference (Loc,
  1000.                  Prefix =>
  1001.                    Make_Selected_Component (Loc,
  1002.                      Prefix =>
  1003.                        Make_Identifier (Loc, Name_uObject),
  1004.                      Selector_Name =>
  1005.                        Make_Identifier (Loc, Name_uObject)),
  1006.                  Attribute_Name => Name_Unchecked_Access))));
  1007.       end if;
  1008.  
  1009.       Final_Sub :=
  1010.         Make_Subprogram_Body (Loc,
  1011.           Specification =>
  1012.             Make_Procedure_Specification (Loc,
  1013.               Defining_Unit_Name =>
  1014.                 Make_Defining_Identifier (Loc,
  1015.                   Chars => New_External_Name (Sub_Name, 'F'))),
  1016.  
  1017.           Declarations => Empty_List,
  1018.  
  1019.           Handled_Statement_Sequence =>
  1020.             Make_Handled_Sequence_Of_Statements (Loc,
  1021.               Statements => Final_Stats));
  1022.  
  1023.       --  Make the protected subprogram body. This locks the protected
  1024.       --  object and calls the unprotected version of the subprogram.
  1025.  
  1026.       return
  1027.         Make_Subprogram_Body (Loc,
  1028.           Specification => P_Op_Spec,
  1029.           Declarations => Op_Decls,
  1030.  
  1031.           Handled_Statement_Sequence =>
  1032.             Make_Handled_Sequence_Of_Statements (Loc,
  1033.               Statements => New_List (
  1034.                 Make_Block_Statement (Loc,
  1035.                   Declarations => New_List (Final_Sub),
  1036.                   Handled_Statement_Sequence =>
  1037.                     Make_Handled_Sequence_Of_Statements (Loc,
  1038.  
  1039.                       Statements => New_List (
  1040.                         Make_Procedure_Call_Statement (Loc,
  1041.                           Name =>
  1042.                             New_Reference_To (RTE (RE_Abort_Defer), Loc),
  1043.                           Parameter_Associations => Empty_List),
  1044.  
  1045.                         Make_Procedure_Call_Statement (Loc,
  1046.                           Name =>
  1047.                             New_Reference_To (RTE (RE_Lock), Loc),
  1048.                           Parameter_Associations => New_List (
  1049.                             Make_Attribute_Reference (Loc,
  1050.                               Prefix =>
  1051.                                 Make_Selected_Component (Loc,
  1052.                                   Prefix =>
  1053.                                     Make_Identifier (Loc, Name_uObject),
  1054.                                 Selector_Name =>
  1055.                                     Make_Identifier (Loc, Name_uObject)),
  1056.                               Attribute_Name => Name_Unchecked_Access))),
  1057.                         Unprot_Call),
  1058.  
  1059.                       Identifier => New_Occurrence_Of (
  1060.                         Defining_Unit_Name (Specification (Final_Sub)),
  1061.                         Loc))),
  1062.                 Sub_Return)));
  1063.  
  1064.    end Build_Protected_Subprogram_Body;
  1065.  
  1066.    -------------------------------------
  1067.    -- Build_Protected_Subprogram_Call --
  1068.    -------------------------------------
  1069.  
  1070.    function Build_Protected_Subprogram_Call
  1071.      (N        : Node_Id;
  1072.       Name     : Node_Id;
  1073.       Rec      : Node_Id;
  1074.       External : Boolean := True)
  1075.       return     Node_Id
  1076.    is
  1077.       Loc     : constant Source_Ptr := Sloc (N);
  1078.       Sub     : Entity_Id := Entity (Name);
  1079.       New_Sub : Node_Id;
  1080.       Params  : List_Id;
  1081.       Append  : Character;
  1082.  
  1083.    begin
  1084.       --  The following assumes that the protected version of the
  1085.       --  subprogram immediately follows the unprotected one in the entity
  1086.       --  chain for their common scope. There is currently no attribute to
  1087.       --  retrieve the protected version. Should there be one???
  1088.  
  1089.       if External then
  1090.          New_Sub := New_Occurrence_Of (
  1091.            Next_Entity (Protected_Body_Subprogram (Sub)), Loc);
  1092.       else
  1093.          New_Sub :=
  1094.            New_Occurrence_Of (Protected_Body_Subprogram (Sub), Loc);
  1095.       end if;
  1096.  
  1097.       if Present (Parameter_Associations (N)) then
  1098.          Params := New_List_Copy (Parameter_Associations (N));
  1099.       else
  1100.          Params := New_List;
  1101.       end if;
  1102.  
  1103.       Prepend (Rec, Params);
  1104.  
  1105.       if Ekind (Sub) = E_Procedure then
  1106.          return Make_Procedure_Call_Statement (Loc,
  1107.            Name => New_Sub,
  1108.            Parameter_Associations => Params);
  1109.  
  1110.       else
  1111.          pragma Assert (Ekind (Sub) = E_Function);
  1112.          return Make_Function_Call (Loc,
  1113.            Name => New_Sub,
  1114.            Parameter_Associations => Params);
  1115.       end if;
  1116.    end Build_Protected_Subprogram_Call;
  1117.  
  1118.    ---------------------------------------
  1119.    -- Build_Protected_Sub_Specification --
  1120.    ---------------------------------------
  1121.  
  1122.    function Build_Protected_Sub_Specification
  1123.      (N           : Node_Id;
  1124.       Prottyp     : Entity_Id;
  1125.       Unprotected : Boolean := False)
  1126.       return        Node_Id
  1127.    is
  1128.       Loc         : constant Source_Ptr := Sloc (N);
  1129.       Spec        : constant Node_Id    := Specification (N);
  1130.       Ident       : constant Entity_Id  := Defining_Unit_Name (Spec);
  1131.       Nam         : constant Name_Id    := Chars (Ident);
  1132.       Formal      : Entity_Id;
  1133.       New_Plist   : List_Id;
  1134.       Append_Char : Character;
  1135.       New_Spec    : Node_Id;
  1136.       New_Param   : Node_Id;
  1137.  
  1138.    begin
  1139.       if Unprotected then
  1140.          Append_Char := 'N';
  1141.       else
  1142.          Append_Char := 'P';
  1143.       end if;
  1144.  
  1145.       New_Plist := New_List;
  1146.       Formal := First_Formal (Ident);
  1147.  
  1148.       while Present (Formal) loop
  1149.          New_Param :=
  1150.            Make_Parameter_Specification (Loc,
  1151.              Defining_Identifier =>
  1152.                Make_Defining_Identifier (Loc, Chars (Formal)),
  1153.              In_Present => In_Present (Parent (Formal)),
  1154.              Out_Present => Out_Present (Parent (Formal)),
  1155.              Parameter_Type =>
  1156.                New_Reference_To (Etype (Formal), Loc));
  1157.  
  1158.          if Unprotected then
  1159.             Set_Protected_Formal (Formal, Defining_Identifier (New_Param));
  1160.          end if;
  1161.  
  1162.          Append (New_Param, New_Plist);
  1163.          Formal := Next_Formal (Formal);
  1164.       end loop;
  1165.  
  1166.       Prepend_To (New_Plist,
  1167.         Make_Parameter_Specification (Loc,
  1168.           Defining_Identifier =>
  1169.             Make_Defining_Identifier (Loc, Name_uObject),
  1170.           In_Present => True,
  1171.           Out_Present => Nkind (Spec) = N_Procedure_Specification,
  1172.           Parameter_Type =>
  1173.             New_Reference_To
  1174.               (Corresponding_Record_Type (Prottyp), Loc)));
  1175.  
  1176.       if Nkind (Spec) = N_Procedure_Specification then
  1177.          return
  1178.            Make_Procedure_Specification (Loc,
  1179.              Defining_Unit_Name =>
  1180.                Make_Defining_Identifier (Loc,
  1181.                  Chars => New_External_Name (Nam, Append_Char)),
  1182.              Parameter_Specifications => New_Plist);
  1183.  
  1184.       else
  1185.          New_Spec :=
  1186.            Make_Function_Specification (Loc,
  1187.              Defining_Unit_Name =>
  1188.                Make_Defining_Identifier (Loc,
  1189.                  Chars => New_External_Name (Nam, Append_Char)),
  1190.              Parameter_Specifications => New_Plist,
  1191.              Subtype_Mark => New_Copy (Subtype_Mark (Spec)));
  1192.          Set_Return_Present (Defining_Unit_Name (New_Spec));
  1193.          return New_Spec;
  1194.       end if;
  1195.  
  1196.    end Build_Protected_Sub_Specification;
  1197.  
  1198.    -------------------------
  1199.    -- Build_Selected_Name --
  1200.    -------------------------
  1201.  
  1202.    function Build_Selected_Name
  1203.      (Prefix, Selector : Name_Id;
  1204.       Append_Char      : Character := ' ')
  1205.       return Name_Id
  1206.    is
  1207.       Select_Buffer : String (1 .. System.Parameters.Max_Name_Length);
  1208.       Select_Len    : Natural;
  1209.  
  1210.    begin
  1211.       Get_Name_String (Selector);
  1212.       Select_Len := Name_Len;
  1213.       Select_Buffer (1 .. Select_Len) := Name_Buffer (1 .. Name_Len);
  1214.       Get_Name_String (Prefix);
  1215.       Name_Buffer (Name_Len + 1) := '_';
  1216.       Name_Buffer (Name_Len + 2) := '_';
  1217.  
  1218.       Name_Len := Name_Len + 2;
  1219.       for J in 1 .. Select_Len loop
  1220.          Name_Len := Name_Len + 1;
  1221.          Name_Buffer (Name_Len) := Select_Buffer (J);
  1222.       end loop;
  1223.  
  1224.       if Append_Char /= ' ' then
  1225.          Name_Len := Name_Len + 1;
  1226.          Name_Buffer (Name_Len) := Append_Char;
  1227.       end if;
  1228.  
  1229.       return Name_Find;
  1230.    end Build_Selected_Name;
  1231.  
  1232.    -----------------------------
  1233.    -- Build_Simple_Entry_Call --
  1234.    -----------------------------
  1235.  
  1236.    --  A task entry call is converted to a call to Call_Simple
  1237.  
  1238.    --    declare
  1239.    --       P : parms := (parm, parm, parm);
  1240.    --    begin
  1241.    --       Call_Simple (acceptor-task, entry-index, P'Address);
  1242.    --       parm := P.param;
  1243.    --       parm := P.param;
  1244.    --       ...
  1245.    --    end;
  1246.  
  1247.    --  Here Pnn is an aggregate of the type constructed for the entry to hold
  1248.    --  the parameters, and the constructed aggregate value contains either the
  1249.    --  parameters or, in the case of non-elementary types, references to these
  1250.    --  parameters. Then the address of this aggregate is passed to the runtime
  1251.    --  routine, along with the task id value and the task entry index value.
  1252.    --  Pnn is only required if parameters are present.
  1253.  
  1254.    --  The assignments after the call are present only in the case of in-out
  1255.    --  or out parameters for elementary types, and are used to assign back the
  1256.    --  resulting values of such parameters.
  1257.  
  1258.    --  Note: the reason that we insert a block here is that in the context
  1259.    --  of selects, conditional entry calls etc. the entry call statement
  1260.    --  appears on its own, not as an element of a list.
  1261.  
  1262.    --  A protected entry call is converted to a Protected_Entry_Call:
  1263.  
  1264.    --  declare
  1265.    --     P   : E1_Params := (param, param, param);
  1266.    --     Pnn : Boolean;
  1267.    --     Bnn : Communications_Block;
  1268.  
  1269.    --  declare
  1270.    --     P   : E1_Params := (param, param, param);
  1271.    --     Bnn : Communications_Block;
  1272.  
  1273.    --  begin
  1274.    --     Protected_Entry_Call (
  1275.    --       Object => po._object'Access,
  1276.    --       E => <entry index>;
  1277.    --       Uninterpreted_Data => P'Address;
  1278.    --       Mode => Simple_Call;
  1279.    --       Block => Bnn);
  1280.    --     parm := P.param;
  1281.    --     parm := P.param;
  1282.    --       ...
  1283.    --  end;
  1284.  
  1285.    procedure Build_Simple_Entry_Call
  1286.      (N       : Node_Id;
  1287.       Concval : Node_Id;
  1288.       Ename   : Node_Id;
  1289.       Index   : Node_Id)
  1290.    is
  1291.    begin
  1292.       Expand_Call (N);
  1293.  
  1294.       --  Convert entry call to Call_Simple call
  1295.  
  1296.       declare
  1297.          Loc       : constant Source_Ptr := Sloc (N);
  1298.          Parms     : constant List_Id    := Parameter_Associations (N);
  1299.          Pdecl     : Node_Id;
  1300.          Xdecl     : Node_Id;
  1301.          Decls     : List_Id;
  1302.          Conctyp   : Node_Id;
  1303.          Ent       : Entity_Id;
  1304.          Ent_Acc   : Entity_Id;
  1305.          P         : Entity_Id;
  1306.          X         : Entity_Id;
  1307.          Plist     : List_Id;
  1308.          Parm1     : Node_Id;
  1309.          Parm2     : Node_Id;
  1310.          Parm3     : Node_Id;
  1311.          Call      : Node_Id;
  1312.          Actual    : Node_Id;
  1313.          Formal    : Node_Id;
  1314.          N_Node    : Node_Id;
  1315.          N_Var     : Node_Id;
  1316.          Stats     : List_Id := New_List;
  1317.          Comm_Name : Entity_Id;
  1318.  
  1319.       begin
  1320.          --  Simple entry and entry family cases merge here
  1321.  
  1322.          Ent     := Entity (Ename);
  1323.          Ent_Acc := Entry_Parameters_Type (Ent);
  1324.          Conctyp := Etype (Concval);
  1325.  
  1326.          --  If prefix is an access type, dereference to obtain the task type
  1327.  
  1328.          if Is_Access_Type (Conctyp) then
  1329.             Conctyp := Designated_Type (Conctyp);
  1330.          end if;
  1331.  
  1332.          --  Special case for protected subprogram calls.
  1333.  
  1334.          if Is_Protected_Type (Conctyp)
  1335.            and then Is_Subprogram (Entity (Ename))
  1336.          then
  1337.             Rewrite_Substitute_Tree (N,
  1338.               Build_Protected_Subprogram_Call
  1339.                 (N, Ename, Convert_Concurrent (Concval, Conctyp)));
  1340.             Analyze (N);
  1341.             return;
  1342.          end if;
  1343.  
  1344.          --  First parameter is the Task_Id value from the task value or the
  1345.          --  Object from the protected object value, obtained by selecting
  1346.          --  the _Task_Id or _Object from the result of doing an unchecked
  1347.          --  conversion to convert the value to the corresponding record type.
  1348.  
  1349.          Parm1 := Concurrent_Ref (Concval);
  1350.  
  1351.          --  Second parameter is the entry index, computed by the routine
  1352.          --  provided for this purpose. The value of this expression is
  1353.          --  assigned to an intermediate variable to assure that any entry
  1354.          --  family index expressions are evaluated before the entry
  1355.          --  parameters.
  1356.  
  1357.          X := Make_Defining_Identifier (Loc, Name_uX);
  1358.  
  1359.          Xdecl :=
  1360.            Make_Object_Declaration (Loc,
  1361.              Defining_Identifier => X,
  1362.              Object_Definition =>
  1363.                New_Reference_To (RTE (RE_Task_Entry_Index), Loc),
  1364.              Expression =>
  1365.                Entry_Index_Expression (Loc, Entity (Ename), Index, Conctyp));
  1366.  
  1367.          Decls := New_List (Xdecl);
  1368.          Parm2 := New_Reference_To (X, Loc);
  1369.  
  1370.          --  The third parameter is the packaged parameters. If there are
  1371.          --  none, then it is just the null address, since nothing is passed
  1372.  
  1373.          if No (Parms) then
  1374.             Parm3 := New_Reference_To (RTE (RE_Null_Address), Loc);
  1375.  
  1376.          --  Case of parameters present, where third argument is the address
  1377.          --  of a packaged record containing the required parameter values.
  1378.  
  1379.          else
  1380.             --  First build a list of parameter values, which are
  1381.             --  references to objects of the parameter types.
  1382.  
  1383.             Plist := New_List;
  1384.  
  1385.             Actual := First_Actual (N);
  1386.             Formal := First_Formal (Ent);
  1387.  
  1388.             while Present (Actual) loop
  1389.  
  1390.                --  If it is a by_copy_type, copy it to a new variable.
  1391.                --  Then, the packaged parameter should have a field pointing to
  1392.                --  this variable.
  1393.  
  1394.                if Is_By_Copy_Type (Etype (Actual)) then
  1395.                   N_Node :=
  1396.                     Make_Object_Declaration (Loc,
  1397.                       Defining_Identifier => Make_Defining_Identifier
  1398.                         (Loc, New_Internal_Name ('I')),
  1399.                       Aliased_Present => True,
  1400.                       Object_Definition =>
  1401.                         New_Reference_To (Etype (Actual), Loc));
  1402.  
  1403.                   --  We have to make an assignment statement separate for
  1404.                   --  the case of limited type. We can not assign it unless
  1405.                   --  the Assignment_OK flag is set first.
  1406.  
  1407.                   if Ekind (Formal) /= E_Out_Parameter then
  1408.                      N_Var :=
  1409.                        New_Reference_To (Defining_Identifier (N_Node), Loc);
  1410.                      Set_Assignment_OK (N_Var);
  1411.                      Append_To (Stats,
  1412.                        Make_Assignment_Statement (Loc,
  1413.                          Name => N_Var,
  1414.                          Expression => New_Copy (Actual)));
  1415.                   end if;
  1416.  
  1417.                   Append (N_Node, Decls);
  1418.  
  1419.                   Append_To (Plist,
  1420.                     Make_Attribute_Reference (Loc,
  1421.                       Attribute_Name => Name_Unchecked_Access,
  1422.                     Prefix =>
  1423.                       New_Reference_To (Defining_Identifier (N_Node), Loc)));
  1424.                else
  1425.                   Append_To (Plist,
  1426.                     Make_Reference (Loc, Prefix => New_Copy (Actual)));
  1427.                end if;
  1428.  
  1429.                Actual := Next_Actual (Actual);
  1430.                Formal := Next_Formal (Formal);
  1431.             end loop;
  1432.  
  1433.             --  Now build the declaration of parameters initialized with the
  1434.             --  aggregate containing this constructed parameter list.
  1435.  
  1436.             P := Make_Defining_Identifier (Loc, Name_uP);
  1437.  
  1438.             Pdecl :=
  1439.               Make_Object_Declaration (Loc,
  1440.                 Defining_Identifier => P,
  1441.                 Object_Definition =>
  1442.                   New_Reference_To (Designated_Type (Ent_Acc), Loc),
  1443.                 Expression =>
  1444.                   Make_Aggregate (Loc, Expressions => Plist));
  1445.  
  1446.             Parm3 :=
  1447.               Make_Attribute_Reference (Loc,
  1448.                 Attribute_Name => Name_Address,
  1449.                 Prefix => New_Reference_To (P, Loc));
  1450.  
  1451.             Append (Pdecl, Decls);
  1452.          end if;
  1453.  
  1454.          --  Now we can create the call
  1455.  
  1456.          if Is_Protected_Type (Conctyp) then
  1457.  
  1458.             --  Change they type of the index declaration.
  1459.  
  1460.             Set_Object_Definition (Xdecl,
  1461.               New_Reference_To (RTE (RE_Protected_Entry_Index), Loc));
  1462.  
  1463.             --  Some additional declarations for protected entry calls.
  1464.  
  1465.             if No (Decls) then
  1466.                Decls := New_List;
  1467.             end if;
  1468.  
  1469.             --  Bnn : Communications_Block;
  1470.  
  1471.             Comm_Name :=
  1472.               Make_Defining_Identifier (Loc, New_Internal_Name ('B'));
  1473.  
  1474.             Append_To (Decls,
  1475.               Make_Object_Declaration (Loc,
  1476.                 Defining_Identifier => Comm_Name,
  1477.                 Object_Definition =>
  1478.                   New_Reference_To (RTE (RE_Communication_Block), Loc)));
  1479.  
  1480.             --  Some additional statements for protected entry calls.
  1481.  
  1482.             --     Protected_Entry_Call (
  1483.             --       Object => po._object'Access,
  1484.             --       E => <entry index>;
  1485.             --       Uninterpreted_Data => P'Address;
  1486.             --       Mode => Simple_Call;
  1487.             --       Block => Bnn);
  1488.  
  1489.             Call :=
  1490.               Make_Procedure_Call_Statement (Loc,
  1491.                 Name =>
  1492.                   New_Reference_To (RTE (RE_Protected_Entry_Call), Loc),
  1493.  
  1494.                 Parameter_Associations => New_List (
  1495.                   Make_Attribute_Reference (Loc,
  1496.                     Attribute_Name => Name_Unchecked_Access,
  1497.                     Prefix         => Parm1),
  1498.                   Parm2,
  1499.                   Parm3,
  1500.                   New_Reference_To (RTE (RE_Simple_Call), Loc),
  1501.                   New_Occurrence_Of (Comm_Name, Loc)));
  1502.  
  1503.          else
  1504.             Call :=
  1505.               Make_Procedure_Call_Statement (Loc,
  1506.                 Name => New_Reference_To (RTE (RE_Call_Simple), Loc),
  1507.                 Parameter_Associations => New_List (Parm1, Parm2, Parm3));
  1508.  
  1509.          end if;
  1510.  
  1511.          Append_To (Stats, Call);
  1512.  
  1513.          --  If there are out or in/out parameters by copy
  1514.          --  add assignment statements for the result values.
  1515.  
  1516.          if Present (Parms) then
  1517.             Actual := First_Actual (N);
  1518.             Formal := First_Formal (Ent);
  1519.  
  1520.             Set_Assignment_OK (Actual);
  1521.             while Present (Actual) loop
  1522.                if Is_By_Copy_Type (Etype (Actual))
  1523.                  and then Ekind (Formal) /= E_In_Parameter
  1524.                then
  1525.                   N_Node := New_Copy (Actual);
  1526.                   Set_Assignment_OK (N_Node);
  1527.  
  1528.                   --  In all cases (including limited private types) we
  1529.                   --  want the assignment to be valid.
  1530.  
  1531.                   Insert_After (Call,
  1532.                     Make_Assignment_Statement (Loc,
  1533.                       Name => N_Node,
  1534.                       Expression =>
  1535.                         Make_Explicit_Dereference (Loc,
  1536.                           Make_Selected_Component (Loc,
  1537.                             Prefix => New_Reference_To (P, Loc),
  1538.                             Selector_Name =>
  1539.                               Make_Identifier (Loc, Chars (Formal))))));
  1540.                end if;
  1541.  
  1542.                Actual := Next_Actual (Actual);
  1543.                Formal := Next_Formal (Formal);
  1544.             end loop;
  1545.          end if;
  1546.  
  1547.          --  Finally, create block and analyze it
  1548.  
  1549.          Rewrite_Substitute_Tree (N,
  1550.            Make_Block_Statement (Loc,
  1551.              Declarations => Decls,
  1552.              Handled_Statement_Sequence =>
  1553.                Make_Handled_Sequence_Of_Statements (Loc,
  1554.                  Statements => Stats)));
  1555.  
  1556.          Analyze (N);
  1557.       end;
  1558.  
  1559.    end Build_Simple_Entry_Call;
  1560.  
  1561.    ---------------------------------------
  1562.    -- Build_Standard_Exception_Handlers --
  1563.    ---------------------------------------
  1564.  
  1565.    function Build_Standard_Exception_Handlers
  1566.      (Sub  : Entity_Id;
  1567.       Loc  : Source_Ptr)
  1568.       return List_Id
  1569.    is
  1570.       type Ex_Id is
  1571.         array (S_Exceptions range S_Numeric_Error .. S_Tasking_Error)
  1572.           of Node_Id;
  1573.  
  1574.       Ids : constant Ex_Id := (RTE (RE_Numeric_Error_ID),
  1575.                                RTE (RE_Program_Error_ID),
  1576.                                RTE (RE_Storage_Error_ID),
  1577.                                RTE (RE_Tasking_Error_ID));
  1578.       Handlers : List_Id := New_List;
  1579.  
  1580.    begin
  1581.       for Id in Ids'Range loop
  1582.          Append_To (Handlers,
  1583.            Make_Exception_Handler (Loc,
  1584.              Exception_Choices => New_List (New_Reference_To (SE (Id), Loc)),
  1585.              Statements => New_List (
  1586.                Make_Procedure_Call_Statement (Loc,
  1587.                  Name => New_Reference_To (Sub, Loc),
  1588.                  Parameter_Associations => New_List (
  1589.                    New_Reference_To (Ids (Id), Loc))))));
  1590.       end loop;
  1591.  
  1592.       Append_To (Handlers,
  1593.         Make_Exception_Handler (Loc,
  1594.           Exception_Choices => New_List (Make_Others_Choice (Loc)),
  1595.           Statements => New_List (
  1596.             Make_Procedure_Call_Statement (Loc,
  1597.               Name => New_Reference_To (Sub, Loc),
  1598.               Parameter_Associations => New_List (
  1599.                 Make_Function_Call (Loc,
  1600.                   Name => New_Reference_To (
  1601.                     RTE (RE_Current_Exception), Loc)))))));
  1602.  
  1603.       return Handlers;
  1604.    end Build_Standard_Exception_Handlers;
  1605.  
  1606.    --------------------------------
  1607.    -- Build_Task_Activation_Call --
  1608.    --------------------------------
  1609.  
  1610.    procedure Build_Task_Activation_Call (N : Node_Id) is
  1611.       Loc   : constant Source_Ptr := Sloc (N);
  1612.       Chain : Entity_Id;
  1613.       Call  : Node_Id;
  1614.       P     : Node_Id;
  1615.  
  1616.    begin
  1617.       --  Get the activation chain entity. Except in the case of a package
  1618.       --  body, this is in the node that was passed. For a package body,we
  1619.       --  have to find the corresponding package declaration node.
  1620.  
  1621.       if Nkind (N) = N_Package_Body then
  1622.          P := Corresponding_Spec (N);
  1623.  
  1624.          loop
  1625.             P := Parent (P);
  1626.             exit when Nkind (P) = N_Package_Declaration;
  1627.          end loop;
  1628.  
  1629.          Chain := Activation_Chain_Entity (P);
  1630.  
  1631.       else
  1632.          Chain := Activation_Chain_Entity (N);
  1633.       end if;
  1634.  
  1635.       if Present (Chain) then
  1636.          Call :=
  1637.            Make_Procedure_Call_Statement (Loc,
  1638.              Name => New_Reference_To (RTE (RE_Activate_Tasks), Loc),
  1639.              Parameter_Associations =>
  1640.                New_List (Make_Attribute_Reference (Loc,
  1641.                  Prefix => New_Occurrence_Of (Chain, Loc),
  1642.                  Attribute_Name => Name_Unchecked_Access)));
  1643.  
  1644.          if Nkind (N) = N_Package_Declaration then
  1645.             if Present (Corresponding_Body (N)) then
  1646.                null;
  1647.  
  1648.             elsif Present (Private_Declarations (Specification (N))) then
  1649.                Append (Call, Private_Declarations (Specification (N)));
  1650.  
  1651.             else
  1652.                Append (Call, Visible_Declarations (Specification (N)));
  1653.             end if;
  1654.  
  1655.          elsif Present (Handled_Statement_Sequence (N)) then
  1656.             Prepend (Call, Statements (Handled_Statement_Sequence (N)));
  1657.  
  1658.          else
  1659.             Set_Handled_Statement_Sequence (N,
  1660.                Make_Handled_Sequence_Of_Statements (Loc,
  1661.                   Statements => New_List (Call)));
  1662.          end if;
  1663.  
  1664.          Analyze (Call);
  1665.       end if;
  1666.  
  1667.    end Build_Task_Activation_Call;
  1668.  
  1669.    -------------------------------
  1670.    -- Build_Task_Allocate_Block --
  1671.    -------------------------------
  1672.  
  1673.    procedure Build_Task_Allocate_Block
  1674.      (Actions : List_Id;
  1675.       N       : Node_Id;
  1676.       Args    : List_Id)
  1677.    is
  1678.       T      : constant Entity_Id  := Entity (Expression (N));
  1679.       Init   : constant Entity_Id  := Base_Init_Proc (T);
  1680.       Loc    : constant Source_Ptr := Sloc (N);
  1681.       Blkent : Entity_Id;
  1682.       Block  : Node_Id;
  1683.  
  1684.    begin
  1685.       Blkent := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  1686.  
  1687.       Block :=
  1688.         Make_Block_Statement (Loc,
  1689.           Identifier => New_Reference_To (Blkent, Loc),
  1690.           Declarations => New_List (
  1691.  
  1692.             --  _Chain  : Activation_Chain;
  1693.  
  1694.             Make_Object_Declaration (Loc,
  1695.               Defining_Identifier =>
  1696.                 Make_Defining_Identifier (Loc, Name_uChain),
  1697.               Aliased_Present => True,
  1698.               Object_Definition   =>
  1699.                 New_Reference_To (RTE (RE_Activation_Chain), Loc)),
  1700.  
  1701.             --  procedure _Expunge is
  1702.             --  begin
  1703.             --     Expunge_Unactivated_Tasks (_Chain);
  1704.             --  end;
  1705.  
  1706.             Make_Subprogram_Body (Loc,
  1707.               Specification =>
  1708.                 Make_Procedure_Specification (Loc,
  1709.                   Defining_Unit_Name =>
  1710.                     Make_Defining_Identifier (Loc, Name_uExpunge)),
  1711.  
  1712.               Declarations => Empty_List,
  1713.  
  1714.               Handled_Statement_Sequence =>
  1715.                 Make_Handled_Sequence_Of_Statements (Loc,
  1716.                   Statements => New_List (
  1717.                     Make_Procedure_Call_Statement (Loc,
  1718.                       Name =>
  1719.                         New_Reference_To (
  1720.                           RTE (RE_Expunge_Unactivated_Tasks), Loc),
  1721.                       Parameter_Associations => New_List (
  1722.                         Make_Identifier (Loc, Name_uChain))))))),
  1723.  
  1724.           Handled_Statement_Sequence =>
  1725.             Make_Handled_Sequence_Of_Statements (Loc,
  1726.  
  1727.               Statements => New_List (
  1728.  
  1729.                --  Init (Args);
  1730.  
  1731.                 Make_Procedure_Call_Statement (Loc,
  1732.                   Name => New_Reference_To (Init, Loc),
  1733.                   Parameter_Associations => Args),
  1734.  
  1735.                --  Activate_Tasks (_Chain);
  1736.  
  1737.                 Make_Procedure_Call_Statement (Loc,
  1738.                   Name => New_Reference_To (RTE (RE_Activate_Tasks), Loc),
  1739.                   Parameter_Associations => New_List (
  1740.                     Make_Attribute_Reference (Loc,
  1741.                       Prefix => Make_Identifier (Loc, Name_uChain),
  1742.                       Attribute_Name => Name_Unchecked_Access)))),
  1743.  
  1744.               Identifier => Make_Identifier (Loc, Name_uExpunge)),
  1745.  
  1746.           Has_Created_Identifier => True);
  1747.  
  1748.       Append_To (Actions,
  1749.         Make_Implicit_Label_Declaration (Loc,
  1750.           Defining_Identifier => Blkent,
  1751.           Label => Block));
  1752.  
  1753.       Append_To (Actions, Block);
  1754.  
  1755.    end Build_Task_Allocate_Block;
  1756.  
  1757.    -----------------------------------
  1758.    -- Build_Task_Proc_Specification --
  1759.    -----------------------------------
  1760.  
  1761.    function Build_Task_Proc_Specification (T : Entity_Id) return Node_Id is
  1762.       Loc : constant Source_Ptr := Sloc (T);
  1763.       Nam : constant Name_Id    := Chars (T);
  1764.       Ent : Entity_Id;
  1765.  
  1766.    begin
  1767.       Ent :=
  1768.         Make_Defining_Identifier (Loc,
  1769.           Chars => New_External_Name (Nam, 'B'));
  1770.       Set_Is_Internal (Ent);
  1771.       Set_Task_Body_Procedure (T, Ent);
  1772.  
  1773.       return
  1774.         Make_Procedure_Specification (Loc,
  1775.           Defining_Unit_Name       => Ent,
  1776.           Parameter_Specifications =>
  1777.             New_List (
  1778.               Make_Parameter_Specification (Loc,
  1779.                 Defining_Identifier =>
  1780.                   Make_Defining_Identifier (Loc, Name_uTask),
  1781.                 Parameter_Type =>
  1782.                   Make_Access_Definition (Loc,
  1783.                     Subtype_Mark =>
  1784.                       New_Reference_To
  1785.                         (Corresponding_Record_Type (T), Loc)))));
  1786.  
  1787.    end Build_Task_Proc_Specification;
  1788.  
  1789.    ---------------------------------------
  1790.    -- Build_Unprotected_Subprogram_Body --
  1791.    ---------------------------------------
  1792.  
  1793.    function Build_Unprotected_Subprogram_Body
  1794.      (N    : Node_Id;
  1795.       Pid  : Node_Id)
  1796.       return Node_Id
  1797.    is
  1798.       Loc       : constant Source_Ptr := Sloc (N);
  1799.       Sub_Name  : Name_Id;
  1800.       N_Op_Spec : Node_Id;
  1801.       Op_Decls  : List_Id;
  1802.  
  1803.    begin
  1804.       --  Make an unprotected version of the subprogram for use
  1805.       --  within the same object, with a new name and an additional
  1806.       --  parameter representing the object.
  1807.  
  1808.       Op_Decls := Declarations (N);
  1809.       Sub_Name := Chars (Defining_Unit_Name (Specification (N)));
  1810.  
  1811.       N_Op_Spec :=
  1812.         Build_Protected_Sub_Specification
  1813.           (N, Pid, Unprotected => True);
  1814.  
  1815.       return
  1816.         Make_Subprogram_Body (Loc,
  1817.           Specification => N_Op_Spec,
  1818.           Declarations => Op_Decls,
  1819.           Handled_Statement_Sequence =>
  1820.             Handled_Statement_Sequence (N));
  1821.  
  1822.    end Build_Unprotected_Subprogram_Body;
  1823.  
  1824.    ----------------------------
  1825.    -- Collect_Entry_Families --
  1826.    ----------------------------
  1827.  
  1828.    procedure Collect_Entry_Families
  1829.      (Loc          : Source_Ptr;
  1830.       Cdecls       : List_Id;
  1831.       Current_Node : in out Node_Id;
  1832.       Conctyp      : Entity_Id)
  1833.    is
  1834.       Efam      : Entity_Id;
  1835.       Efam_Decl : Node_Id;
  1836.       Efam_Type : Entity_Id;
  1837.  
  1838.    begin
  1839.       Efam := First_Entity (Conctyp);
  1840.  
  1841.       while Present (Efam) loop
  1842.  
  1843.          if Ekind (Efam) = E_Entry_Family then
  1844.             Efam_Type :=
  1845.               Make_Defining_Identifier (Loc,
  1846.                 Chars => New_Internal_Name ('F'));
  1847.  
  1848.             Efam_Decl :=
  1849.               Make_Full_Type_Declaration (Loc,
  1850.                 Defining_Identifier => Efam_Type,
  1851.                 Type_Definition =>
  1852.                   Make_Constrained_Array_Definition (Loc,
  1853.                     Discrete_Subtype_Definitions => (New_List (
  1854.                       New_Copy (Discrete_Subtype_Definition (Parent (Efam))))),
  1855.  
  1856.                     Subtype_Indication =>
  1857.                       New_Reference_To (Standard_Character, Loc)));
  1858.  
  1859.             Insert_After (Current_Node, Efam_Decl);
  1860.             Current_Node := Efam_Decl;
  1861.             Analyze (Efam_Decl);
  1862.  
  1863.             Append_To (Cdecls,
  1864.               Make_Component_Declaration (Loc,
  1865.                 Defining_Identifier =>
  1866.                   Make_Defining_Identifier (Loc, Chars (Efam)),
  1867.                 Subtype_Indication => New_Occurrence_Of (Efam_Type, Loc)));
  1868.          end if;
  1869.  
  1870.          Efam := Next_Entity (Efam);
  1871.       end loop;
  1872.    end Collect_Entry_Families;
  1873.  
  1874.    --------------------
  1875.    -- Concurrent_Ref --
  1876.    --------------------
  1877.  
  1878.    --  The expression returned for a reference to a concurrent
  1879.    --  object has the form:
  1880.  
  1881.    --    taskV!(name)._Task_Id
  1882.  
  1883.    --  for a task, and
  1884.  
  1885.    --    objectV!(name)._Object
  1886.  
  1887.    --  for a protected object.
  1888.  
  1889.    --  For the case of an access to a concurrent object,
  1890.    --  there is an extra explicit dereference:
  1891.  
  1892.    --    taskV!(name.all)._Task_Id
  1893.    --    objectV!(name.all)._Object
  1894.  
  1895.    --  here taskV and objectV are the types for the associated records, which
  1896.    --  contain the required _Task_Id and _Object fields for tasks and
  1897.    --  protected objects, respectively.
  1898.  
  1899.    --  For the case of a task type name, the expression is
  1900.  
  1901.    --    Self;
  1902.  
  1903.    --  i.e. a call to the Self function which returns precisely this Task_Id
  1904.  
  1905.    --  For the case of a protected type name, the expression is
  1906.  
  1907.    --    objectR
  1908.  
  1909.    --  which is a renaming of the _object field of the current object
  1910.    --  object record, passed into protected operations as a parameter.
  1911.  
  1912.    function Concurrent_Ref (N : Node_Id) return Node_Id is
  1913.       Loc  : constant Source_Ptr := Sloc (N);
  1914.       Ntyp : constant Entity_Id  := Etype (N);
  1915.       Dtyp : Entity_Id;
  1916.       Sel  : Name_Id;
  1917.  
  1918.    begin
  1919.       if Is_Access_Type (Ntyp) then
  1920.          Dtyp := Designated_Type (Ntyp);
  1921.  
  1922.          if Is_Protected_Type (Dtyp) then
  1923.             Sel := Name_uObject;
  1924.          else
  1925.             Sel := Name_uTask_Id;
  1926.          end if;
  1927.  
  1928.          return
  1929.            Make_Selected_Component (Loc,
  1930.              Prefix =>
  1931.                Make_Unchecked_Type_Conversion (Loc,
  1932.                  Subtype_Mark => New_Reference_To (
  1933.                    Corresponding_Record_Type (Dtyp), Loc),
  1934.                  Expression => Make_Explicit_Dereference (Loc, N)),
  1935.              Selector_Name => Make_Identifier (Loc, Sel));
  1936.  
  1937.       elsif Is_Entity_Name (N)
  1938.         and then Is_Concurrent_Type (Entity (N))
  1939.       then
  1940.          if Is_Task_Type (Entity (N)) then
  1941.             return
  1942.               Make_Function_Call (Loc,
  1943.                 Name => New_Reference_To (RTE (RE_Self), Loc));
  1944.          else
  1945.             pragma Assert (Is_Protected_Type (Entity (N)));
  1946.             return
  1947.               New_Reference_To (
  1948.                 Object_Ref (Corresponding_Body (Parent (Base_Type (Ntyp)))),
  1949.                 Loc);
  1950.          end if;
  1951.  
  1952.       else
  1953.          pragma Assert (Is_Concurrent_Type (Ntyp));
  1954.  
  1955.          if Is_Protected_Type (Ntyp) then
  1956.             Sel := Name_uObject;
  1957.          else
  1958.             Sel := Name_uTask_Id;
  1959.          end if;
  1960.  
  1961.          return
  1962.            Make_Selected_Component (Loc,
  1963.              Prefix =>
  1964.                Make_Unchecked_Type_Conversion (Loc,
  1965.                  Subtype_Mark =>
  1966.                    New_Reference_To (Corresponding_Record_Type (Ntyp), Loc),
  1967.                  Expression => New_Copy_Tree (N)),
  1968.              Selector_Name => Make_Identifier (Loc, Sel));
  1969.       end if;
  1970.    end Concurrent_Ref;
  1971.  
  1972.    ------------------------
  1973.    -- Convert_Concurrent --
  1974.    ------------------------
  1975.  
  1976.    function Convert_Concurrent
  1977.      (N    : Node_Id;
  1978.       Typ  : Entity_Id)
  1979.       return Node_Id
  1980.    is
  1981.       Loc : constant Source_Ptr := Sloc (N);
  1982.  
  1983.    begin
  1984.       if not Is_Concurrent_Type (Typ) then
  1985.          return N;
  1986.       else
  1987.          return
  1988.            Make_Unchecked_Type_Conversion (Loc,
  1989.              Subtype_Mark =>
  1990.                New_Reference_To (Corresponding_Record_Type (Typ), Loc),
  1991.                Expression => New_Copy (N));
  1992.       end if;
  1993.    end Convert_Concurrent;
  1994.  
  1995.    ----------------------------
  1996.    -- Entry_Index_Expression --
  1997.    ----------------------------
  1998.  
  1999.    function Entry_Index_Expression
  2000.      (Sloc  : Source_Ptr;
  2001.       Ent   : Entity_Id;
  2002.       Index : Node_Id;
  2003.       Ttyp  : Entity_Id)
  2004.       return  Node_Id
  2005.    is
  2006.       Expr : Node_Id;
  2007.       Num  : Node_Id;
  2008.       Prev : Entity_Id;
  2009.       S    : Node_Id;
  2010.       Trec : Node_Id := Corresponding_Record_Type (Ttyp);
  2011.  
  2012.    begin
  2013.       --  The queues of entries and entry families appear in  textual
  2014.       --  order in the associated record. The entry index is computed as
  2015.       --  the sum of the number of queues for all entries that precede the
  2016.       --  designated one, to which is added the index expression, if this
  2017.       --  expression denotes a member of a family.
  2018.  
  2019.       --  The following is a place holder for the count of simple entries.
  2020.  
  2021.       Num := Make_Integer_Literal (Sloc, Uint_1);
  2022.  
  2023.       --  We construct an expression which is a series of addition
  2024.       --  operations. The first operand is the number of single entries that
  2025.       --  precede this one, the second operand is the index value relative
  2026.       --  to the start of the referenced family, and the remaining operands
  2027.       --  are the lengths of the entry families that precede this entry, i.e.
  2028.       --  the constructed expression is:
  2029.  
  2030.       --    number_simple_entries +
  2031.       --      (s'pos (index-value) - s'pos (family'first)) + 1 +
  2032.       --      family'length + ...
  2033.  
  2034.       --  where index-value is the given index value, and s is the index
  2035.       --  subtype (we have to use pos because the subtype might be an
  2036.       --  enumeration type preventing direct subtraction).
  2037.       --  Note that the task entry array is one-indexed.
  2038.  
  2039.       if Present (Index) then
  2040.          S := Etype (Discrete_Subtype_Definition (Declaration_Node (Ent)));
  2041.  
  2042.          Expr :=
  2043.            Make_Op_Add (Sloc,
  2044.              Left_Opnd  => Num,
  2045.  
  2046.              Right_Opnd =>
  2047.                Make_Op_Subtract (Sloc,
  2048.                  Left_Opnd =>
  2049.                    Make_Attribute_Reference (Sloc,
  2050.                      Attribute_Name => Name_Pos,
  2051.                      Prefix => New_Reference_To (S, Sloc),
  2052.                      Expressions => New_List (New_Copy (Index))),
  2053.  
  2054.                  Right_Opnd =>
  2055.                    Make_Attribute_Reference (Sloc,
  2056.                      Attribute_Name => Name_Pos,
  2057.                      Prefix => New_Reference_To (S, Sloc),
  2058.                      Expressions => New_List (
  2059.                        Make_Attribute_Reference (Sloc,
  2060.                          Prefix => New_Reference_To (S, Sloc),
  2061.                          Attribute_Name => Name_First)))));
  2062.       else
  2063.          Expr := Num;
  2064.       end if;
  2065.  
  2066.       --  Now add lengths of preceding entries and entry families.
  2067.  
  2068.       Prev := First_Entity (Ttyp);
  2069.  
  2070.       while Chars (Prev) /= Chars (Ent)
  2071.         or else (Ekind (Prev) /= Ekind (Ent))
  2072.         or else not Sem_Ch6.Type_Conformant (Ent, Prev)
  2073.       loop
  2074.          if Ekind (Prev) = E_Entry then
  2075.             Set_Intval (Num, Intval (Num) + 1);
  2076.  
  2077.          elsif Ekind (Prev) = E_Entry_Family then
  2078.             Expr :=
  2079.               Make_Op_Add (Sloc,
  2080.               Left_Opnd  => Expr,
  2081.               Right_Opnd =>
  2082.                 Make_Attribute_Reference (Sloc,
  2083.                   Attribute_Name => Name_Length,
  2084.                   Prefix => New_Reference_To (Array_Type (Prev, Trec), Sloc)));
  2085.  
  2086.          --  Other components are anonymous types to be ignored.
  2087.  
  2088.          else
  2089.             null;
  2090.          end if;
  2091.  
  2092.          Prev := Next_Entity (Prev);
  2093.       end loop;
  2094.  
  2095.       return Expr;
  2096.    end Entry_Index_Expression;
  2097.  
  2098.    ----------------------------
  2099.    -- Entry_Range_Expression --
  2100.    ----------------------------
  2101.  
  2102.    function Entry_Range_Expression
  2103.      (Sloc  : Source_Ptr;
  2104.       Ent   : Entity_Id;
  2105.       Ttyp  : Entity_Id)
  2106.       return  Node_Id
  2107.    is
  2108.       Trec   : constant Node_Id := Corresponding_Record_Type (Ttyp);
  2109.       Right  : Node_Id;
  2110.       Left   : Node_Id;
  2111.       Scount : Node_Id;
  2112.       Fcount : Node_Id;
  2113.       Prev   : Entity_Id;
  2114.  
  2115.    begin
  2116.       --  The following is a place holder for the count of simple entries.
  2117.  
  2118.       Scount := Make_Integer_Literal (Sloc, Uint_1);
  2119.       Fcount := Make_Integer_Literal (Sloc, Uint_0);
  2120.  
  2121.       Prev := First_Entity (Ttyp);
  2122.  
  2123.       while Chars (Prev) /= Chars (Ent) loop
  2124.  
  2125.          if Ekind (Prev) = E_Entry then
  2126.             Set_Intval (Scount, Intval (Scount) + 1);
  2127.  
  2128.          elsif Ekind (Prev) = E_Entry_Family then
  2129.             Fcount :=
  2130.               Make_Op_Add (Sloc,
  2131.               Left_Opnd  => Fcount,
  2132.               Right_Opnd =>
  2133.                 Make_Attribute_Reference (Sloc,
  2134.                   Attribute_Name => Name_Length,
  2135.                   Prefix => New_Reference_To (Array_Type (Prev, Trec), Sloc)));
  2136.  
  2137.          --  Other components are anonymous types to be ignored.
  2138.  
  2139.          else
  2140.             null;
  2141.          end if;
  2142.  
  2143.          Prev := Next_Entity (Prev);
  2144.       end loop;
  2145.  
  2146.       Left :=
  2147.         Make_Op_Add (Sloc,
  2148.           Left_Opnd => Scount,
  2149.           Right_Opnd => Fcount);
  2150.  
  2151.       Right :=
  2152.         Make_Op_Add (Sloc,
  2153.           Left_Opnd => New_Copy_Tree (Left),
  2154.           Right_Opnd =>
  2155.             Make_Op_Subtract (Sloc,
  2156.               Left_Opnd => Make_Attribute_Reference (Sloc,
  2157.                 Attribute_Name => Name_Length,
  2158.                 Prefix => New_Reference_To (Array_Type (Prev, Trec), Sloc)),
  2159.               Right_Opnd => Make_Integer_Literal (Sloc, Uint_1)));
  2160.  
  2161.       return
  2162.         Make_Range (Sloc,
  2163.           Low_Bound => Left,
  2164.           High_Bound => Right);
  2165.  
  2166.    end Entry_Range_Expression;
  2167.  
  2168.    ---------------------------
  2169.    -- Establish_Task_Master --
  2170.    ---------------------------
  2171.  
  2172.    procedure Establish_Task_Master (N : Node_Id) is
  2173.       Call : Node_Id;
  2174.  
  2175.    begin
  2176.       Call := Build_Runtime_Call (Sloc (N), RE_Enter_Master);
  2177.       Prepend_To (Declarations (N), Call);
  2178.       Analyze (Call);
  2179.    end Establish_Task_Master;
  2180.  
  2181.    --------------------------------
  2182.    -- Expand_Accept_Declarations --
  2183.    --------------------------------
  2184.  
  2185.    --  Part of the expansion of an accept statement involves the creation of
  2186.    --  a declaration that can be referenced from the statement sequence of
  2187.    --  the accept:
  2188.  
  2189.    --    Ann : Address;
  2190.  
  2191.    --  This declaration is inserted immediately before the accept statement
  2192.    --  and it is important that it be inserted before the statements of the
  2193.    --  statement sequence are analyzed. Thus it would be too late to create
  2194.    --  this declaration in the Expand_N_Accept_Statement routine, which is
  2195.    --  why there is a separate procedure to be called directly from Sem_Ch9.
  2196.  
  2197.    --  It is used to hold the address of the record containing the parameters
  2198.    --  (see Expand_N_Entry_Call for more details on how this record is built).
  2199.    --  References to the parameters do an unchecked conversion of this address
  2200.    --  to a pointer to the required record type, and then access the field that
  2201.    --  holds the value of the required parameter. The entity for the address
  2202.    --  variable is held as the top stack element (i.e. the last element) of the
  2203.    --  Accept_Address stack in the corresponding entry entity, and this element
  2204.    --  must be set in place  before the statements are processed.
  2205.  
  2206.    --  The above description applies to the case of a stand alone accept
  2207.    --  statement, i.e. one not appearing as part of a select alternative.
  2208.  
  2209.    --  For the case of an accept that appears as part of a select alternative
  2210.    --  of a selective accept, we must still create the declaration right away,
  2211.    --  since Ann is needed immediately, but there is an important difference:
  2212.  
  2213.    --    The declaration is inserted before the selective accept, not before
  2214.    --    the accept statement (which is not part of a list anyway, and so would
  2215.    --    not accommodate inserted declarations)
  2216.  
  2217.    --    We only need one address variable for the entire selective accept. So
  2218.    --    the Ann declaration is created only for the first accept alternative,
  2219.    --    and subsequent accept alternatives reference the same Ann variable.
  2220.  
  2221.    --  We can distinguish the two cases by seeing whether the accept statement
  2222.    --  is part of a list. If not, then it must be in an accept alternative.
  2223.  
  2224.    --  To expand the requeue statement, a label is provided at the end of
  2225.    --  the accept statement or alternative of which it is a part, so that
  2226.    --  the statement can be skipped after the requeue is complete.
  2227.    --  This label is created here rather than during the expansion of the
  2228.    --  accept statement, because it will be needed by any requeue
  2229.    --  statements within the accept, which are expanded before the
  2230.    --  accept.
  2231.  
  2232.    procedure Expand_Accept_Declarations (N : Node_Id; Ent : Entity_Id) is
  2233.       Loc    : constant Source_Ptr := Sloc (N);
  2234.       Ttyp   : constant Entity_Id  := Scope (Ent);
  2235.       Ann    : Entity_Id;
  2236.       Adecl  : Node_Id;
  2237.       Lab_Id : Node_Id;
  2238.       Lab    : Node_Id;
  2239.       Ldecl  : Node_Id;
  2240.  
  2241.    begin
  2242.       if Expander_Active then
  2243.  
  2244.          --  Create and declare a label to be placed at the end of the
  2245.          --  accept statement. This is used to allow requeues to skip
  2246.          --  the remainder of entry processing.
  2247.  
  2248.          if Present (Handled_Statement_Sequence (N)) then
  2249.             Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L'));
  2250.             Set_Entity (Lab_Id,
  2251.               Make_Defining_Identifier (Loc, Chars (Lab_Id)));
  2252.             Lab := Make_Label (Loc, Lab_Id);
  2253.             Ldecl :=
  2254.               Make_Implicit_Label_Declaration (Loc,
  2255.                 Defining_Identifier  => Entity (Lab_Id),
  2256.                 Label => Lab);
  2257.             Append (Lab, Statements (Handled_Statement_Sequence (N)));
  2258.          end if;
  2259.  
  2260.          --  Case of stand alone accept statement
  2261.  
  2262.          if Is_List_Member (N) then
  2263.             Ann := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  2264.  
  2265.             Adecl :=
  2266.               Make_Object_Declaration (Loc,
  2267.                 Defining_Identifier => Ann,
  2268.                 Object_Definition => New_Reference_To (RTE (RE_Address), Loc));
  2269.  
  2270.             Insert_Before (N, Adecl);
  2271.             Analyze (Adecl);
  2272.  
  2273.             if Present (Handled_Statement_Sequence (N)) then
  2274.                Insert_Before (N, Ldecl);
  2275.                Analyze (Ldecl);
  2276.             end if;
  2277.  
  2278.          --  Case of accept statement which is in an accept alternative
  2279.  
  2280.          else
  2281.             declare
  2282.                Acc_Alt : constant Node_Id := Parent (N);
  2283.                Sel_Acc : constant Node_Id := Parent (Acc_Alt);
  2284.                Alt     : Node_Id;
  2285.  
  2286.             begin
  2287.                pragma Assert (Nkind (Acc_Alt) = N_Accept_Alternative);
  2288.                pragma Assert (Nkind (Sel_Acc) = N_Selective_Accept);
  2289.  
  2290.                --  ??? Consider a single label for select statements.
  2291.  
  2292.                if Present (Handled_Statement_Sequence (N)) then
  2293.                   Prepend (Ldecl,
  2294.                      Statements (Handled_Statement_Sequence (N)));
  2295.                   Analyze (Ldecl);
  2296.                end if;
  2297.  
  2298.                --  Find first accept alternative of the selective accept. A
  2299.                --  valid selective accept must have at least one accept in it.
  2300.  
  2301.                Alt := First (Select_Alternatives (Sel_Acc));
  2302.  
  2303.                while Nkind (Alt) /= N_Accept_Alternative loop
  2304.                   Alt := Next (Alt);
  2305.                end loop;
  2306.  
  2307.                --  If we are the first accept statement, then we have to
  2308.                --  create the Ann variable, as for the stand alone case,
  2309.                --  except that it is inserted before the selective accept.
  2310.                --  Similarly, a label for requeue expansion must be
  2311.                --  declared.
  2312.  
  2313.                if N = Accept_Statement (Alt) then
  2314.                   Ann :=
  2315.                     Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  2316.  
  2317.                   Adecl :=
  2318.                     Make_Object_Declaration (Loc,
  2319.                       Defining_Identifier => Ann,
  2320.                       Object_Definition =>
  2321.                         New_Reference_To (RTE (RE_Address), Loc));
  2322.  
  2323.                   Insert_Before (Sel_Acc, Adecl);
  2324.                   Analyze (Adecl);
  2325.  
  2326.                --  If we are not the first accept statement, then find the
  2327.                --  Ann variable allocated by the first accept and use it.
  2328.  
  2329.                else
  2330.                   Ann :=
  2331.                     Node (Last_Elmt (Accept_Address
  2332.                       (Entity (Entry_Direct_Name (Accept_Statement (Alt))))));
  2333.                end if;
  2334.             end;
  2335.          end if;
  2336.  
  2337.          --  Merge here with Ann either created or referenced, and Adecl
  2338.          --  pointing to the corresponding declaration. Remaining processing
  2339.          --  is the same for the two cases.
  2340.  
  2341.          Append_Elmt (Ann, Accept_Address (Ent));
  2342.       end if;
  2343.    end Expand_Accept_Declarations;
  2344.  
  2345.    ------------------------------
  2346.    -- Next_Protected_Operation --
  2347.    ------------------------------
  2348.  
  2349.    function Next_Protected_Operation (N : Node_Id) return Node_Id is
  2350.       Next_Op : Node_Id;
  2351.  
  2352.    begin
  2353.       Next_Op := Next (N);
  2354.  
  2355.       while Present (Next_Op)
  2356.         and then Nkind (Next_Op) /= N_Subprogram_Body
  2357.         and then Nkind (Next_Op) /= N_Entry_Body
  2358.       loop
  2359.          Next_Op := Next (Next_Op);
  2360.       end loop;
  2361.  
  2362.       return Next_Op;
  2363.    end Next_Protected_Operation;
  2364.  
  2365.    -------------------------------
  2366.    -- First_Protected_Operation --
  2367.    -------------------------------
  2368.  
  2369.    function First_Protected_Operation (D : List_Id) return Node_Id is
  2370.       First_Op : Node_Id;
  2371.  
  2372.    begin
  2373.       First_Op := First (D);
  2374.       while Present (First_Op)
  2375.         and then Nkind (First_Op) /= N_Subprogram_Body
  2376.         and then Nkind (First_Op) /= N_Entry_Body
  2377.       loop
  2378.          First_Op := Next (First_Op);
  2379.       end loop;
  2380.  
  2381.       return First_Op;
  2382.    end First_Protected_Operation;
  2383.  
  2384.    --------------------------
  2385.    -- Expand_Entry_Barrier --
  2386.    --------------------------
  2387.  
  2388.    procedure Expand_Entry_Barrier (N : Node_Id) is
  2389.       Loc  : constant Source_Ptr := Sloc (N);
  2390.       Func : Node_Id;
  2391.       Scop : constant Entity_Id  := Current_Scope;
  2392.       Dec  : Node_Id := Parent (Scop);
  2393.       Body_Dec : Node_Id := Parent (Corresponding_Body (Dec));
  2394.  
  2395.    begin
  2396.       if Expander_Active then
  2397.          Func := Build_Barrier_Function (N, Scop);
  2398.          Set_Barrier_Function (Defining_Identifier (N), Func);
  2399.          Set_Privals (Dec, N, Loc);
  2400.          Set_Discriminals (Dec, N, Loc);
  2401.       end if;
  2402.    end Expand_Entry_Barrier;
  2403.  
  2404.    ------------------------------------
  2405.    -- Expand_Entry_Body_Declarations --
  2406.    ------------------------------------
  2407.  
  2408.    procedure Expand_Entry_Body_Declarations (N : Node_Id) is
  2409.       Loc        : constant Source_Ptr := Sloc (N);
  2410.       Index_Spec : Node_Id;
  2411.  
  2412.    begin
  2413.       if Expander_Active then
  2414.  
  2415.          --  Expand entry bodies corresponding to entry families
  2416.          --  by assigning a placeholder for the constant that will
  2417.          --  be used to expand references to the entry index parameter.
  2418.  
  2419.          Index_Spec :=
  2420.            Entry_Index_Specification (Entry_Body_Formal_Part (N));
  2421.  
  2422.          if Present (Index_Spec) then
  2423.             Set_Entry_Index_Constant (
  2424.               Defining_Identifier (Index_Spec),
  2425.               Make_Defining_Identifier (Loc, New_Internal_Name ('I')));
  2426.          end if;
  2427.  
  2428.       end if;
  2429.    end Expand_Entry_Body_Declarations;
  2430.  
  2431.    -------------------------
  2432.    -- Expand_N_Entry_Body --
  2433.    -------------------------
  2434.  
  2435.    procedure Expand_N_Entry_Body (N : Node_Id) is
  2436.       Loc         : constant Source_Ptr := Sloc (N);
  2437.       Next_Op     : Node_Id;
  2438.       Dec         : Node_Id := Parent (Current_Scope);
  2439.       Ent_Formals : Node_Id := Entry_Body_Formal_Part (N);
  2440.       Index_Spec  : Node_Id := Entry_Index_Specification (Ent_Formals);
  2441.  
  2442.    begin
  2443.       --  If this is an entry family, declare the entry index specification.
  2444.       --  This is a declaration of the form
  2445.       --     I : Index_Type := Index_Type'Value (
  2446.       --       E - <<index of first family member>> +
  2447.       --       Protected_Entry_Index (Index_Type'Pos (Index_Type'First)));
  2448.  
  2449.       if Present (Index_Spec) then
  2450.          Prepend_To (Declarations (N),
  2451.            Make_Object_Declaration (Loc,
  2452.              Defining_Identifier => Entry_Index_Constant (
  2453.                Defining_Identifier (Index_Spec)),
  2454.  
  2455.              Constant_Present => True,
  2456.  
  2457.              Object_Definition => New_Reference_To (
  2458.                Etype (Defining_Identifier (Index_Spec)), Loc),
  2459.  
  2460.              Expression => Make_Attribute_Reference (Loc,
  2461.                Prefix => New_Reference_To (
  2462.                  Etype (Defining_Identifier (Index_Spec)), Loc),
  2463.  
  2464.                Attribute_Name => Name_Val,
  2465.                Expressions => New_List (
  2466.                  Make_Op_Add (Loc,
  2467.                    Left_Opnd => Make_Op_Subtract (Loc,
  2468.                      Left_Opnd => Make_Identifier (Loc, Name_uE),
  2469.                      Right_Opnd =>
  2470.                        Entry_Index_Expression (
  2471.                          Loc,
  2472.                          Defining_Identifier (N),
  2473.                          Empty,
  2474.                          Defining_Identifier (Dec))),
  2475.  
  2476.                    Right_Opnd =>
  2477.                      Make_Attribute_Reference (Loc,
  2478.                        Prefix => New_Reference_To (
  2479.                          Etype (Defining_Identifier (Index_Spec)), Loc),
  2480.                        Attribute_Name => Name_Pos,
  2481.                        Expressions => New_List (
  2482.                          Make_Attribute_Reference (Loc,
  2483.                            Prefix => New_Reference_To (
  2484.                              Etype (Defining_Identifier (Index_Spec)), Loc),
  2485.                            Attribute_Name => Name_First))))))));
  2486.       end if;
  2487.  
  2488.       --  Add the renamings for private declarations and discriminants.
  2489.  
  2490.       Add_Discriminal_Declarations
  2491.         (Declarations (N), Defining_Identifier (Dec), Name_uObject, Loc);
  2492.       Add_Private_Declarations
  2493.         (Declarations (N), Defining_Identifier (Dec), Name_uObject, Loc);
  2494.  
  2495.       --  Associate privals and discriminals with the next protected
  2496.       --  operation body to be expanded. These are used to expand
  2497.       --  references to private data objects and discriminants,
  2498.       --  respectively.
  2499.  
  2500.       Next_Op := Next_Protected_Operation (N);
  2501.  
  2502.       if Present (Next_Op) then
  2503.          Set_Privals (Dec, Next_Op, Loc);
  2504.          Set_Discriminals (Dec, Next_Op, Loc);
  2505.       end if;
  2506.  
  2507.    end Expand_N_Entry_Body;
  2508.  
  2509.    ----------------------------------------
  2510.    -- Expand_Protected_Body_Declarations --
  2511.    ----------------------------------------
  2512.  
  2513.    --  Part of the expansion of a protected body involves the creation of
  2514.    --  a declaration that can be referenced from the statement sequences of
  2515.    --  the entry bodies:
  2516.  
  2517.    --    A : Address;
  2518.  
  2519.    --  This declaration is inserted in the declarations of the service
  2520.    --  entries procedure for the protected body,
  2521.    --  and it is important that it be inserted before the statements of
  2522.    --  the entry body statement sequences are analyzed.
  2523.    --  Thus it would be too late to create
  2524.    --  this declaration in the Expand_N_Protected_Body routine, which is
  2525.    --  why there is a separate procedure to be called directly from Sem_Ch9.
  2526.  
  2527.    --  It is used to hold the address of the record containing the parameters
  2528.    --  (see Expand_N_Entry_Call for more details on how this record is built).
  2529.    --  References to the parameters do an unchecked conversion of this address
  2530.    --  to a pointer to the required record type, and then access the field that
  2531.    --  holds the value of the required parameter. The entity for the address
  2532.    --  variable is held as the top stack element (i.e. the last element) of the
  2533.    --  Accept_Address stack in the corresponding entry entity, and this element
  2534.    --  must be set in place  before the statements are processed.
  2535.  
  2536.    --  No stack is needed for entry bodies, since they cannot be nested, but
  2537.    --  it is kept for consistency between protected and task entries. The
  2538.    --  stack will never contain more than one element. There is also only one
  2539.    --  such variable for a given protected body, but this is placed on the
  2540.    --  Accept_Address stack of all of the entries, again for consistency.
  2541.  
  2542.    --  To expand the requeue statement, a label is provided at the end of
  2543.    --  the loop in the entry service routine created by the expander (see
  2544.    --  Expand_N_Protected_Body for details), so that the statement can be
  2545.    --  skipped after the requeue is complete. This label is created during the
  2546.    --  expansion of the entry body, which will take place after the expansion
  2547.    --  of the requeue statements that it contains, so a placeholder defining
  2548.    --  identifier is associated with the task type here.
  2549.  
  2550.    --  Another label is provided following case statement created by the
  2551.    --  expander. This label is need for implementing return statement from
  2552.    --  entry body so that a return can be expanded as a goto to this label.
  2553.    --  This label is created during the expansion of the entry body, which will
  2554.    --  take place after the expansion of the return statements that it
  2555.    --  contains. Therefore, just like the label for expanding requeues, we need
  2556.    --  another placeholder for the label.
  2557.  
  2558.    procedure Expand_Protected_Body_Declarations
  2559.      (N : Node_Id;
  2560.       Spec_Id : Entity_Id)
  2561.    is
  2562.       Loc        : constant Source_Ptr := Sloc (N);
  2563.       Body_Id    : constant Entity_Id := Corresponding_Body (Parent (Spec_Id));
  2564.  
  2565.       P          : Entity_Id;
  2566.       Op         : Node_Id;
  2567.       Lab_Id     : Node_Id;
  2568.       Lab        : Node_Id;
  2569.  
  2570.    begin
  2571.       if Expander_Active then
  2572.  
  2573.          --  Associate privals with the first subprogram or entry
  2574.          --  body to be expanded. These are used to expand references
  2575.          --  to private data objects.
  2576.  
  2577.          Op := First_Protected_Operation (Declarations (N));
  2578.  
  2579.          if Present (Op) then
  2580.             Set_Discriminals (Parent (Spec_Id), Op, Sloc (N));
  2581.             Set_Privals (Parent (Spec_Id), Op, Sloc (N));
  2582.          end if;
  2583.       end if;
  2584.    end Expand_Protected_Body_Declarations;
  2585.  
  2586.    ------------------------------
  2587.    -- Expand_N_Abort_Statement --
  2588.    ------------------------------
  2589.  
  2590.    --  Expand abort T1, T2, .. Tn; into:
  2591.    --    Abort_Tasks (Task_List'(1 => T1.Task_Id, 2 => T2.Task_Id ...))
  2592.  
  2593.    procedure Expand_N_Abort_Statement (N : Node_Id) is
  2594.       Loc    : constant Source_Ptr := Sloc (N);
  2595.       Tlist  : constant List_Id    := Names (N);
  2596.       Count  : Nat;
  2597.       Aggr   : Node_Id;
  2598.       Tasknm : Node_Id;
  2599.  
  2600.    begin
  2601.       Aggr := Make_Aggregate (Loc, Component_Associations => New_List);
  2602.       Count := 0;
  2603.  
  2604.       Tasknm := First (Tlist);
  2605.  
  2606.       while Present (Tasknm) loop
  2607.          Count := Count + 1;
  2608.          Append_To (Component_Associations (Aggr),
  2609.            Make_Component_Association (Loc,
  2610.              Choices => New_List (
  2611.                Make_Integer_Literal (Loc, UI_From_Int (Count))),
  2612.              Expression => Concurrent_Ref (Tasknm)));
  2613.          Tasknm := Next (Tasknm);
  2614.       end loop;
  2615.  
  2616.       Replace_Substitute_Tree (N,
  2617.         Make_Procedure_Call_Statement (Loc,
  2618.           Name => New_Reference_To (RTE (RE_Abort_Tasks), Loc),
  2619.           Parameter_Associations => New_List (
  2620.             Make_Qualified_Expression (Loc,
  2621.               Subtype_Mark => New_Reference_To (RTE (RE_Task_List), Loc),
  2622.               Expression => Aggr))));
  2623.  
  2624.       Analyze (N);
  2625.  
  2626.    end Expand_N_Abort_Statement;
  2627.  
  2628.    -------------------------------
  2629.    -- Expand_N_Accept_Statement --
  2630.    -------------------------------
  2631.  
  2632.    --  This procedure handles expansion of accept statements that stand
  2633.    --  alone, i.e. they are not part of an accept alternative. The expansion
  2634.    --  of accept statement in accept alternatives is handled by the routines
  2635.    --  Expand_N_Accept_Alternative and Expand_N_Selective_Accept. The
  2636.    --  following description applies only to stand alone accept statements.
  2637.  
  2638.    --  If there is no handled statement sequence, then this is called a
  2639.    --  trivial accept, and the expansion is:
  2640.  
  2641.    --    Accept_Trivial (entry-index)
  2642.  
  2643.    --  If there is a handled statement sequence, then the expansion is:
  2644.  
  2645.    --    Ann : Address;
  2646.    --    {Lnn : Label}
  2647.  
  2648.    --    begin
  2649.    --       begin
  2650.    --          Accept_Call (entry-index, Ann);
  2651.    --          <statement sequence from N_Accept_Statement node>
  2652.    --          Complete_Rendezvous;
  2653.    --          <<Lnn>>
  2654.    --
  2655.    --       exception
  2656.    --          when ... =>
  2657.    --             <exception handler from N_Accept_Statement node>
  2658.    --             Complete_Rendezvous;
  2659.    --          when ... =>
  2660.    --             <exception handler from N_Accept_Statement node>
  2661.    --             Complete_Rendezvous;
  2662.    --          ...
  2663.    --       end;
  2664.  
  2665.    --    exception
  2666.    --       when others =>
  2667.    --          Exceptional_Complete_Rendezvous (Current_Exception);
  2668.    --    end;
  2669.  
  2670.    --  The first three declarations were already inserted ahead of the
  2671.    --  accept statement by the Expand_Accept_Declarations procedure, which
  2672.    --  was called directly from the semantics during analysis of the accept.
  2673.    --  statement, before analyzing its contained statements.
  2674.  
  2675.    --  The declarations from the N_Accept_Statement, as noted in Sinfo, come
  2676.    --  from possible expansion activity (the original source of course does
  2677.    --  not have any declarations associated with the accept statement, since
  2678.    --  an accept statement has no declarative part). In particular, if the
  2679.    --  expander is active, the first such declaration is the declaration of
  2680.    --  the Accept_Params_Ptr entity (see Sem_Ch9.Analyze_Accept_Statement).
  2681.    --
  2682.    --  The two blocks are merged into a single block if the inner block has
  2683.    --  no exception handlers, but otherwise two blocks are required, since
  2684.    --  exceptions might be raised in the exception handlers of the inner
  2685.    --  block, and Exceptional_Complete_Rendezvous must be called.
  2686.  
  2687.    procedure Expand_N_Accept_Statement (N : Node_Id) is
  2688.       Loc     : constant Source_Ptr := Sloc (N);
  2689.       Stats   : constant Node_Id    := Handled_Statement_Sequence (N);
  2690.       Ename   : constant Node_Id    := Entry_Direct_Name (N);
  2691.       Eindx   : constant Node_Id    := Entry_Index (N);
  2692.       Eent    : constant Entity_Id  := Entity (Ename);
  2693.       Acstack : constant Elist_Id   := Accept_Address (Eent);
  2694.       Ann     : constant Entity_Id  := Node (Last_Elmt (Acstack));
  2695.       Ttyp    : constant Entity_Id  := Etype (Scope (Eent));
  2696.       Call    : Node_Id;
  2697.       Block   : Node_Id;
  2698.  
  2699.    begin
  2700.       --  If accept statement is not part of a list, then its parent must be
  2701.       --  an accept alternative, and, as described above, we do not do any
  2702.       --  expansion for such accept statements at this level.
  2703.  
  2704.       if not Is_List_Member (N) then
  2705.          pragma Assert (Nkind (Parent (N)) = N_Accept_Alternative);
  2706.          return;
  2707.  
  2708.       --  Trivial accept case (no statement sequence)
  2709.  
  2710.       elsif No (Stats) then
  2711.          Rewrite_Substitute_Tree (N,
  2712.            Make_Procedure_Call_Statement (Loc,
  2713.              Name => New_Reference_To (RTE (RE_Accept_Trivial), Loc),
  2714.              Parameter_Associations => New_List (
  2715.                Entry_Index_Expression (Loc, Entity (Ename), Eindx, Ttyp))));
  2716.  
  2717.          Analyze (N);
  2718.          return;
  2719.  
  2720.       --  Case of statement sequence present
  2721.  
  2722.       else
  2723.          --  Construct the block
  2724.  
  2725.          Block :=
  2726.            Make_Block_Statement (Loc,
  2727.              Handled_Statement_Sequence => Build_Accept_Body (Stats, Loc));
  2728.  
  2729.          --  Prepend call to Accept_Call to main statement sequence
  2730.  
  2731.          Call :=
  2732.            Make_Procedure_Call_Statement (Loc,
  2733.              Name => New_Reference_To (RTE (RE_Accept_Call), Loc),
  2734.              Parameter_Associations => New_List (
  2735.                Entry_Index_Expression (Loc, Entity (Ename), Eindx, Ttyp),
  2736.                New_Reference_To (Ann, Loc)));
  2737.  
  2738.          Prepend (Call, Statements (Stats));
  2739.          Analyze (Call);
  2740.  
  2741.          --  Replace the accept statement by the new block
  2742.  
  2743.          Rewrite_Substitute_Tree (N, Block);
  2744.          Analyze (N);
  2745.  
  2746.          --  Last step is to unstack the Accept_Address value
  2747.  
  2748.          Remove_Last_Elmt (Acstack);
  2749.          return;
  2750.       end if;
  2751.  
  2752.    end Expand_N_Accept_Statement;
  2753.  
  2754.    ----------------------------------
  2755.    -- Expand_N_Asynchronous_Select --
  2756.    ----------------------------------
  2757.  
  2758.    --  This procedure assumes that the trigger statement is an entry
  2759.    --  call. A delay alternative should already have been expanded
  2760.    --  into an entry call to the appropriate delay object Wait entry.
  2761.  
  2762.    --  If the trigger is a task entry call, the select is implemented
  2763.    --  with Task_Entry_Call:
  2764.  
  2765.    --    declare
  2766.    --       B : Boolean;
  2767.    --       C : Boolean;
  2768.    --       P : parms := (parm, parm, parm);
  2769.    --       procedure Fn is
  2770.    --       begin
  2771.    --          Cancel_Task_Entry_Call (C);
  2772.    --       end Fn;
  2773.    --    begin
  2774.    --       Abort_Defer;
  2775.    --       Task_Entry_Call
  2776.    --         (acceptor-task,
  2777.    --          entry-index,
  2778.    --          P'Address,
  2779.    --          Asynchronous_Call,
  2780.    --          B);
  2781.    --       begin
  2782.    --          begin
  2783.    --             Abort_Undefer;
  2784.    --             abortable-part
  2785.    --          at end
  2786.    --             _clean;
  2787.    --          end;
  2788.    --       exception
  2789.    --       when Abort_Signal => null;
  2790.    --       end;
  2791.    --       parm := P.param;
  2792.    --       parm := P.param;
  2793.    --       ...
  2794.    --       if not C then
  2795.    --          triggered-statements
  2796.    --       end if;
  2797.    --    end;
  2798.  
  2799.    --  Note that Build_Simple_Entry_Call is used to expand the entry
  2800.    --  of the asynchronous entry call (by the
  2801.    --  Expand_N_Entry_Call_Statement procedure) as follows:
  2802.  
  2803.    --    declare
  2804.    --       P : parms := (parm, parm, parm);
  2805.    --    begin
  2806.    --       Call_Simple (acceptor-task, entry-index, P'Address);
  2807.    --       parm := P.param;
  2808.    --       parm := P.param;
  2809.    --       ...
  2810.    --    end;
  2811.  
  2812.    --  so the task at hand is to convert the latter expansion into the former
  2813.  
  2814.  
  2815.    --  If the trigger is a protected entry call, the select is
  2816.    --  implemented with Protected_Entry_Call:
  2817.  
  2818.    --  declare
  2819.    --     P   : E1_Params := (param, param, param);
  2820.    --     Bnn : Communications_Block;
  2821.    --  begin
  2822.    --     declare
  2823.    --        procedure Fnn is
  2824.    --        begin
  2825.    --           if Enqueued (Bnn) then
  2826.    --              Cancel_Protected_Entry_Call (Bnn);
  2827.    --           end if;
  2828.    --        end Fnn;
  2829.    --     begin
  2830.    --        begin
  2831.    --           Protected_Entry_Call (
  2832.    --             Object => po._object'Access,
  2833.    --             E => <entry index>;
  2834.    --             Uninterpreted_Data => P'Address;
  2835.    --             Mode => Asynchronous_Call;
  2836.    --             Block => Bnn);
  2837.    --           if Enqueued (Bnn) then
  2838.    --              <abortable part>
  2839.    --           end if;
  2840.    --        at end
  2841.    --           Fnn;
  2842.    --        end;
  2843.    --     exception
  2844.    --     when Abort_Signal =>
  2845.    --        null;
  2846.    --     end;
  2847.    --     if not Cancelled (Bnn) then
  2848.    --        triggered statements
  2849.    --     end if;
  2850.    --  end;
  2851.  
  2852.    --  Build_Simple_Entry_Call is used to expand the all to a simple
  2853.    --  protected entry call:
  2854.  
  2855.    --  declare
  2856.    --     P   : E1_Params := (param, param, param);
  2857.    --     Bnn : Communications_Block;
  2858.  
  2859.    --  begin
  2860.    --     Protected_Entry_Call (
  2861.    --       Object => po._object'Access,
  2862.    --       E => <entry index>;
  2863.    --       Uninterpreted_Data => P'Address;
  2864.    --       Mode => Simple_Call;
  2865.    --       Block => Bnn);
  2866.    --     parm := P.param;
  2867.    --     parm := P.param;
  2868.    --       ...
  2869.    --  end;
  2870.  
  2871.    --  The job is to convert this to the asynchronous form.
  2872.  
  2873.    --  If the trigger is a delay statement, it will have been expanded
  2874.    --  into a call to one of the GNARL delay procedures. This routine
  2875.    --  will convert this into a protected entry call on a delay object
  2876.    --  and then continue processing as for a protected entry call trigger.
  2877.    --  This requires declaring a Delay_Block object and adding a pointer
  2878.    --  to this object to the parameter list of the delay procedure to form
  2879.    --  the parameter list of the entry call. This object is used by
  2880.    --  the runtime to queue the delay request.
  2881.  
  2882.    --  For a description of the use of P and the assignments after the
  2883.    --  call, see Expand_N_Entry_Call_Statement.
  2884.  
  2885.    procedure Expand_N_Asynchronous_Select (N : Node_Id) is
  2886.       Loc        : constant Source_Ptr := Sloc (N);
  2887.       Trig       : constant Node_Id    := Triggering_Alternative (N);
  2888.       Abrt       : constant Node_Id    := Abortable_Part (N);
  2889.       Ecall      : Node_Id             := Triggering_Statement (Trig);
  2890.       Tstats     : constant List_Id    := Statements (Trig);
  2891.       Astats     : List_Id             := Statements (Abrt);
  2892.       Concval    : Node_Id;
  2893.       Ename      : Node_Id;
  2894.       Index      : Node_Id;
  2895.       Ablk       : Node_Id;
  2896.       Hdle       : List_Id;
  2897.       Decls      : List_Id;
  2898.       Decl       : Node_Id;
  2899.       Parms      : List_Id;
  2900.       Parm       : Node_Id;
  2901.       Call       : Node_Id;
  2902.       Stmts      : List_Id;
  2903.       Stmt       : Node_Id;
  2904.       B          : Entity_Id;
  2905.       C          : Entity_Id;
  2906.       Pend       : Entity_Id;
  2907.       Comm       : Entity_Id;
  2908.       Final      : Entity_Id;
  2909.       Final_Body : Node_Id;
  2910.       Pdef       : Entity_Id;
  2911.       Odef       : Entity_Id;
  2912.       Dblock_Ent : Entity_Id;
  2913.       Dstat      : Node_Id;
  2914.       N_Orig     : Node_Id;
  2915.  
  2916.    begin
  2917.       --  If a delay was used as a trigger, it will have been expanded
  2918.       --  into a procedure call. Convert it to a protected entry call
  2919.       --  on the appropriate delay object, based on the type.
  2920.       --  ??? This currently supports only Duration, Real_Time.Time,
  2921.       --      and Calendar.Time.
  2922.  
  2923.       if Nkind (Ecall) = N_Procedure_Call_Statement then
  2924.  
  2925.          --  Add a Delay_Block object to the parameter list of the
  2926.          --  delay procedure to form the parameter list of the Wait
  2927.          --  entry call.
  2928.  
  2929.          Dblock_Ent := Make_Defining_Identifier (Loc, New_Internal_Name ('D'));
  2930.  
  2931.          N_Orig := Relocate_Node (N);
  2932.  
  2933.          --  Wrap the asynchronous select in a block declaring the
  2934.          --  Delay_Block object. Note that this is in addition to the
  2935.          --  block that will be used to implement the select statement
  2936.          --  proper. This is because the delay trigger is expanded in two
  2937.          --  stages: once to convert the procedure call into an entry
  2938.          --  call, and once by Build_Simple_Entry_Call (below) to convert
  2939.          --  the entry call into GNARLI code for a simple entry call.
  2940.  
  2941.          Rewrite_Substitute_Tree (N,
  2942.            Make_Block_Statement (Loc,
  2943.              Declarations => New_List (
  2944.                Make_Object_Declaration (Loc,
  2945.                  Defining_Identifier => Dblock_Ent,
  2946.                  Aliased_Present => True,
  2947.                  Object_Definition => New_Reference_To (
  2948.                    RTE (RE_Delay_Block), Loc))),
  2949.  
  2950.              Handled_Statement_Sequence =>
  2951.                Make_Handled_Sequence_Of_Statements (Loc,
  2952.                  Statements => New_List)));
  2953.  
  2954.          --  Note that the new block must be analyzed before the select
  2955.          --  statement is added to it, otherwise this procedure would be
  2956.          --  called recursively.
  2957.          --  ??? All of these machinations are the result of the
  2958.          --      questionable context-sensitive code in
  2959.          --      Expand_N_Entry_Call statement that delays expansion of
  2960.          --      an entry call trigger. This is not being fixed now,
  2961.          --      since there is some question as to whether the delay
  2962.          --      object interface will survive.
  2963.  
  2964.          Analyze (N);
  2965.  
  2966.          Pdef := Entity (Name (Ecall));
  2967.  
  2968.          if Pdef = RTE (RO_CA_Delay_For) then
  2969.             Odef := RTE (RO_CA_Delay_Object);
  2970.          elsif Pdef = RTE (RO_CA_Delay_Until) then
  2971.             Odef := RTE (RO_CA_Delay_Until_Object);
  2972.          elsif Pdef = RTE (RO_RT_Delay_Until) then
  2973.             Odef := RTE (RO_RT_Delay_Until_Object);
  2974.          else
  2975.             Unimplemented (N, "This kind of trigger");
  2976.          end if;
  2977.  
  2978.          Append_To (Parameter_Associations (Ecall),
  2979.            Make_Attribute_Reference (Loc,
  2980.              Prefix => New_Reference_To (Dblock_Ent, Loc),
  2981.              Attribute_Name => Name_Unchecked_Access));
  2982.  
  2983.          Decl :=
  2984.            First (Visible_Declarations (Protected_Definition (
  2985.              Parent (Etype (Odef)))));
  2986.          while Nkind (Decl) /= N_Entry_Declaration loop
  2987.             Decl := Next (Decl);
  2988.          end loop;
  2989.  
  2990.          Rewrite_Substitute_Tree (Ecall,
  2991.            Make_Procedure_Call_Statement (Loc,
  2992.              Name => Make_Selected_Component (Loc,
  2993.                Prefix => New_Reference_To (Odef, Loc),
  2994.                Selector_Name => New_Reference_To (
  2995.                  Defining_Identifier (Decl), Loc)),
  2996.              Parameter_Associations => Parameter_Associations (Ecall)));
  2997.  
  2998.          Append_To (Statements (Handled_Statement_Sequence (N)), N_Orig);
  2999.  
  3000.          Analyze (Ecall);
  3001.       else
  3002.          N_Orig := N;
  3003.       end if;
  3004.  
  3005.       Extract_Entry (Ecall, Concval, Ename, Index);
  3006.       Build_Simple_Entry_Call (Ecall, Concval, Ename, Index);
  3007.  
  3008.       Stmts := Statements (Handled_Statement_Sequence (Ecall));
  3009.       Decls := Declarations (Ecall);
  3010.  
  3011.       if Is_Protected_Type (Etype (Concval)) then
  3012.  
  3013.          --  Get the declarations of the block expanded from the entry
  3014.          --  call.
  3015.  
  3016.          Decl := First (Decls);
  3017.          while Present (Decl)
  3018.            and then (Nkind (Decl) /= N_Object_Declaration
  3019.              or else Etype (Object_Definition (Decl))
  3020.                                       /= RTE (RE_Communication_Block))
  3021.          loop
  3022.             Decl := Next (Decl);
  3023.          end loop;
  3024.  
  3025.          pragma Assert (Present (Decl));
  3026.          Comm := Defining_Identifier (Decl);
  3027.  
  3028.          --  Make the finalization procedure.
  3029.          --  procedure Fnn is
  3030.  
  3031.          Final := Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
  3032.  
  3033.          Final_Body :=
  3034.            Make_Subprogram_Body (Loc,
  3035.              Specification =>
  3036.                Make_Procedure_Specification (Loc, Defining_Unit_Name => Final),
  3037.  
  3038.              Declarations => Empty_List,
  3039.              Handled_Statement_Sequence =>
  3040.                Make_Handled_Sequence_Of_Statements (Loc,
  3041.                  Statements => New_List (
  3042.  
  3043.                --  if Enqueued (Bnn) then
  3044.  
  3045.                    Make_If_Statement (Loc,
  3046.                      Condition => Make_Function_Call (Loc,
  3047.                        Name => New_Reference_To (
  3048.                          RTE (RE_Enqueued), Loc),
  3049.                        Parameter_Associations => New_List (
  3050.                          New_Reference_To (Comm, Loc))),
  3051.                      Then_Statements => New_List (
  3052.  
  3053.                      --  Cancel_Protected_Entry_Call (Bnn);
  3054.  
  3055.                        Make_Procedure_Call_Statement (Loc,
  3056.                          Name => New_Reference_To (
  3057.                            RTE (RE_Cancel_Protected_Entry_Call), Loc),
  3058.                          Parameter_Associations => New_List (
  3059.                            New_Reference_To (Comm, Loc))))))));
  3060.  
  3061.  
  3062.          --  Change the mode of the Protected_Entry_Call call.
  3063.          --  Protected_Entry_Call (
  3064.          --    Object => po._object'Access,
  3065.          --    E => <entry index>;
  3066.          --    Uninterpreted_Data => P'Address;
  3067.          --    Mode => Asynchronous_Call;
  3068.          --    Block => Bnn);
  3069.  
  3070.          Stmt := First (Stmts);
  3071.  
  3072.          --  Skip assignments to temporaries created for in-out parameters.
  3073.          --  This makes unwarranted assumptions about the shape of the expanded
  3074.          --  tree for the call, and should be cleaned up ???
  3075.  
  3076.          while Nkind (Stmt) /= N_Procedure_Call_Statement loop
  3077.             Stmt := Next (Stmt);
  3078.          end loop;
  3079.  
  3080.          Call := Stmt;
  3081.  
  3082.          Parm := First (Parameter_Associations (Call));
  3083.          while Present (Parm)
  3084.            and then Etype (Parm) /= RTE (RE_Call_Modes)
  3085.          loop
  3086.             Parm := Next (Parm);
  3087.          end loop;
  3088.  
  3089.          pragma Assert (Present (Parm));
  3090.          Rewrite_Substitute_Tree (Parm,
  3091.            New_Reference_To (RTE (RE_Asynchronous_Call), Loc));
  3092.          Analyze (Parm);
  3093.  
  3094.          --  Append an if statement to execute the abortable part.
  3095.          --  if Enqueued (Bnn) then
  3096.  
  3097.          Append_To (Stmts,
  3098.            Make_If_Statement (Loc,
  3099.              Condition => Make_Function_Call (Loc,
  3100.                Name => New_Reference_To (
  3101.                  RTE (RE_Enqueued), Loc),
  3102.                Parameter_Associations => New_List (
  3103.                  New_Reference_To (Comm, Loc))),
  3104.              Then_Statements => Astats));
  3105.  
  3106.          Stmts := New_List (Make_Block_Statement (Loc,
  3107.            Handled_Statement_Sequence =>
  3108.              Make_Handled_Sequence_Of_Statements (Loc,
  3109.                Statements => Stmts,
  3110.                Identifier => New_Occurrence_Of (Final, Loc))));
  3111.  
  3112.          Stmts := New_List (
  3113.            Make_Block_Statement (Loc,
  3114.              Declarations => New_List (Final_Body),
  3115.              Handled_Statement_Sequence =>
  3116.                Make_Handled_Sequence_Of_Statements (Loc,
  3117.                  Statements => Stmts,
  3118.  
  3119.                   --  exception
  3120.  
  3121.                   Exception_Handlers => New_List (
  3122.                     Make_Exception_Handler (Loc,
  3123.  
  3124.                   --  when Abort_Signal =>
  3125.                   --     null;
  3126.  
  3127.                       Exception_Choices =>
  3128.                         New_List (New_Reference_To (Stand.Abort_Signal, Loc)),
  3129.                       Statements =>  New_List (Make_Null_Statement (Loc)))))),
  3130.  
  3131.             --  if not Cancelled (Bnn) then
  3132.             --     triggered statements
  3133.             --  end if;
  3134.  
  3135.             Make_If_Statement (Loc,
  3136.               Condition => Make_Op_Not (Loc,
  3137.                 Right_Opnd =>
  3138.                   Make_Function_Call (Loc,
  3139.                     Name => New_Occurrence_Of (RTE (RE_Cancelled), Loc),
  3140.                     Parameter_Associations => New_List (
  3141.                       New_Occurrence_Of (Comm, Loc)))),
  3142.               Then_Statements => Tstats));
  3143.  
  3144.       else
  3145.       --  Asynchronous task entry call.
  3146.  
  3147.          if No (Decls) then
  3148.             Decls := New_List;
  3149.          end if;
  3150.  
  3151.          B := Make_Defining_Identifier (Loc, Name_uB);
  3152.  
  3153.          --  Insert declaration of B in declarations of existing block
  3154.  
  3155.          Prepend_To (Decls,
  3156.            Make_Object_Declaration (Loc,
  3157.              Defining_Identifier => B,
  3158.              Object_Definition => New_Reference_To (Standard_Boolean, Loc)));
  3159.  
  3160.          C := Make_Defining_Identifier (Loc, Name_uC);
  3161.  
  3162.          --  Insert declaration of C in declarations of existing block
  3163.  
  3164.          Prepend_To (Decls,
  3165.            Make_Object_Declaration (Loc,
  3166.              Defining_Identifier => C,
  3167.              Object_Definition => New_Reference_To (Standard_Boolean, Loc)));
  3168.  
  3169.          --  Insert declaration of the cleanup routine in declarations.
  3170.  
  3171.          Final := Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
  3172.  
  3173.          Append_To (Decls,
  3174.            Make_Subprogram_Body (Loc,
  3175.              Specification =>
  3176.                Make_Procedure_Specification (Loc, Defining_Unit_Name => Final),
  3177.  
  3178.              Declarations => Empty_List,
  3179.              Handled_Statement_Sequence =>
  3180.                Make_Handled_Sequence_Of_Statements (Loc,
  3181.                  Statements => New_List (
  3182.                     Make_Procedure_Call_Statement (Loc,
  3183.                       Name => New_Reference_To (
  3184.                         RTE (RE_Cancel_Task_Entry_Call),
  3185.                         Loc),
  3186.                       Parameter_Associations => New_List (
  3187.                         New_Reference_To (C, Loc)))))));
  3188.  
  3189.          --  Remove and save the call to Call_Simple.
  3190.  
  3191.          Stmt := First (Stmts);
  3192.  
  3193.          --  Skip assignments to temporaries created for in-out parameters.
  3194.          --  This makes unwarranted assumptions about the shape of the expanded
  3195.          --  tree for the call, and should be cleaned up ???
  3196.  
  3197.          while Nkind (Stmt) /= N_Procedure_Call_Statement loop
  3198.             Stmt := Next (Stmt);
  3199.          end loop;
  3200.  
  3201.          Call := Stmt;
  3202.  
  3203.          --  Create the inner block to protect the abortable part.
  3204.  
  3205.          Hdle :=  New_List (
  3206.            Make_Exception_Handler (Loc,
  3207.              Exception_Choices => New_List (
  3208.                New_Reference_To (Stand.Abort_Signal, Loc)),
  3209.              Statements => New_List (Make_Null_Statement (Loc))));
  3210.  
  3211.          Prepend_To (Astats,
  3212.            Make_Procedure_Call_Statement (Loc,
  3213.              Name => New_Reference_To (RTE (RE_Abort_Undefer), Loc),
  3214.              Parameter_Associations => Empty_List));
  3215.  
  3216.          Ablk :=
  3217.            Make_Block_Statement (Loc,
  3218.              Handled_Statement_Sequence =>
  3219.                Make_Handled_Sequence_Of_Statements (Loc,
  3220.                  Statements => New_List (
  3221.                    Make_Block_Statement (Loc,
  3222.                      Handled_Statement_Sequence =>
  3223.                        Make_Handled_Sequence_Of_Statements (Loc,
  3224.                          Statements => Astats,
  3225.                          Identifier => New_Reference_To (Final, Loc)))),
  3226.                  Exception_Handlers => Hdle));
  3227.  
  3228.          Insert_After (Call, Ablk);
  3229.  
  3230.          --  Create new call statement
  3231.  
  3232.          Parms := Parameter_Associations (Call);
  3233.          Append_To (Parms, New_Reference_To (RTE (RE_Asynchronous_Call), Loc));
  3234.          Append_To (Parms, New_Reference_To (B, Loc));
  3235.          Rewrite_Substitute_Tree (Call,
  3236.            Make_Procedure_Call_Statement (Loc,
  3237.              Name => New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
  3238.              Parameter_Associations => Parms));
  3239.  
  3240.          --  Construct statement sequence for new block
  3241.  
  3242.          Append_To (Stmts,
  3243.            Make_If_Statement (Loc,
  3244.              Condition => Make_Op_Not (Loc, New_Reference_To (C, Loc)),
  3245.              Then_Statements => Tstats));
  3246.  
  3247.          --  Protected the call against abortion
  3248.  
  3249.          Prepend_To (Stmts,
  3250.            Make_Procedure_Call_Statement (Loc,
  3251.              Name => New_Reference_To (RTE (RE_Abort_Defer), Loc),
  3252.              Parameter_Associations => Empty_List));
  3253.  
  3254.       end if;
  3255.  
  3256.       --  The result is the new block
  3257.  
  3258.       Rewrite_Substitute_Tree (N_Orig,
  3259.         Make_Block_Statement (Loc,
  3260.           Declarations => Decls,
  3261.           Handled_Statement_Sequence =>
  3262.             Make_Handled_Sequence_Of_Statements (Loc, Stmts)));
  3263.  
  3264.       Analyze (N_Orig);
  3265.  
  3266.    end Expand_N_Asynchronous_Select;
  3267.  
  3268.    -------------------------------------
  3269.    -- Expand_N_Conditional_Entry_Call --
  3270.    -------------------------------------
  3271.  
  3272.    --  The conditional task entry call is converted to a call to
  3273.    --  Task_Entry_Call:
  3274.  
  3275.    --    declare
  3276.    --       B : Boolean;
  3277.    --       P : parms := (parm, parm, parm);
  3278.  
  3279.    --    begin
  3280.    --       Task_Entry_Call
  3281.    --         (acceptor-task,
  3282.    --          entry-index,
  3283.    --          P'Address,
  3284.    --          Conditional_Call,
  3285.    --          B);
  3286.    --       parm := P.param;
  3287.    --       parm := P.param;
  3288.    --       ...
  3289.    --       if B then
  3290.    --          normal-statements
  3291.    --       else
  3292.    --          else-statements
  3293.    --       end if;
  3294.    --    end;
  3295.  
  3296.    --  For a description of the use of P and the assignments after the
  3297.    --  call, see Expand_N_Entry_Call_Statement. Note that the entry call
  3298.    --  of the conditional entry call has already been expanded (by the
  3299.    --  Expand_N_Entry_Call_Statement procedure) as follows:
  3300.  
  3301.    --    declare
  3302.    --       P : parms := (parm, parm, parm);
  3303.    --    begin
  3304.    --       Call_Simple (acceptor-task, entry-index, P'Address);
  3305.    --       parm := P.param;
  3306.    --       parm := P.param;
  3307.    --       ...
  3308.    --    end;
  3309.  
  3310.    --  so the task at hand is to convert the latter expansion into the former
  3311.  
  3312.  
  3313.    --  The conditional protected entry call is converted to a call to
  3314.    --  Protected_Entry_Call:
  3315.  
  3316.    --    declare
  3317.    --       P : parms := (parm, parm, parm);
  3318.    --       Bnn : Communications_Block;
  3319.  
  3320.    --    begin
  3321.    --       Protected_Entry_Call (
  3322.    --         Object => po._object'Access,
  3323.    --         E => <entry index>;
  3324.    --         Uninterpreted_Data => P'Address;
  3325.    --         Mode => Conditional_Call;
  3326.    --         Block => Bnn);
  3327.    --       parm := P.param;
  3328.    --       parm := P.param;
  3329.    --       ...
  3330.    --       if Cancelled (Bnn) then
  3331.    --          else-statements
  3332.    --       else
  3333.    --          normal-statements
  3334.    --       end if;
  3335.    --    end;
  3336.  
  3337.    --  As for tasks, the entry call of the conditional entry call has
  3338.    --  already been expanded (by the Expand_N_Entry_Call_Statement procedure)
  3339.    --  as follows:
  3340.  
  3341.    --    declare
  3342.    --       P   : E1_Params := (param, param, param);
  3343.    --       Bnn : Communications_Block;
  3344.  
  3345.    --    begin
  3346.    --       Protected_Entry_Call (
  3347.    --         Object => po._object'Access,
  3348.    --         E => <entry index>;
  3349.    --         Uninterpreted_Data => P'Address;
  3350.    --         Mode => Simple_Call;
  3351.    --         Block => Bnn);
  3352.    --       parm := P.param;
  3353.    --       parm := P.param;
  3354.    --         ...
  3355.    --    end;
  3356.  
  3357.    procedure Expand_N_Conditional_Entry_Call (N : Node_Id) is
  3358.       Loc     : constant Source_Ptr := Sloc (N);
  3359.       Alt     : constant Node_Id    := Entry_Call_Alternative (N);
  3360.       Blk     : constant Node_Id    := Entry_Call_Statement (Alt);
  3361.       Parms   : List_Id;
  3362.       Parm    : Node_Id;
  3363.       Call    : Node_Id;
  3364.       Stmts   : List_Id;
  3365.       B       : Entity_Id;
  3366.       Decl    : Node_Id;
  3367.       Stmt    : Node_Id;
  3368.  
  3369.    begin
  3370.  
  3371.       Stmts := Statements (Handled_Statement_Sequence (Blk));
  3372.  
  3373.       Stmt := First (Stmts);
  3374.  
  3375.       --  Skip assignments to temporaries created for in-out parameters.
  3376.       --  This makes unwarranted assumptions about the shape of the expanded
  3377.       --  tree for the call, and should be cleaned up ???
  3378.  
  3379.       while Nkind (Stmt) /= N_Procedure_Call_Statement loop
  3380.          Stmt := Next (Stmt);
  3381.       end loop;
  3382.  
  3383.       Call := Stmt;
  3384.  
  3385.       Parms := Parameter_Associations (Call);
  3386.  
  3387.       if Entity (Name (Call)) = RTE (RE_Protected_Entry_Call) then
  3388.  
  3389.          --  Substitute Conditional_Entry_Call for Simple_Call
  3390.          --  parameter.
  3391.  
  3392.          Parm := First (Parms);
  3393.          while Present (Parm)
  3394.            and then Etype (Parm) /= RTE (RE_Call_Modes)
  3395.          loop
  3396.             Parm := Next (Parm);
  3397.          end loop;
  3398.          pragma Assert (Present (Parm));
  3399.          Rewrite_Substitute_Tree (Parm,
  3400.            New_Reference_To (RTE (RE_Conditional_Call), Loc));
  3401.  
  3402.          Analyze (Parm);
  3403.  
  3404.          --  Find the Communication_Block parameter for the call
  3405.          --  to the Cancelled function.
  3406.  
  3407.          Decl := First (Declarations (Blk));
  3408.          while Present (Decl)
  3409.            and then Etype (Object_Definition (Decl))
  3410.              /= RTE (RE_Communication_Block)
  3411.          loop
  3412.             Decl := Next (Decl);
  3413.          end loop;
  3414.  
  3415.          --  Add an if statement to execute the else part if the call
  3416.          --  does not succeed (as indicated by the Cancelled predicate).
  3417.  
  3418.          Append_To (Stmts,
  3419.            Make_If_Statement (Loc,
  3420.              Condition => Make_Function_Call (Loc,
  3421.                Name => New_Reference_To (RTE (RE_Cancelled), Loc),
  3422.                Parameter_Associations => New_List (
  3423.                  New_Reference_To (Defining_Identifier (Decl), Loc))),
  3424.              Then_Statements => Else_Statements (N),
  3425.              Else_Statements => Statements (Alt)));
  3426.  
  3427.       else
  3428.          B := Make_Defining_Identifier (Loc, Name_uB);
  3429.  
  3430.          --  Insert declaration of B in declarations of existing block
  3431.  
  3432.          if No (Declarations (Blk)) then
  3433.             Set_Declarations (Blk, New_List);
  3434.          end if;
  3435.  
  3436.          Prepend_To (Declarations (Blk),
  3437.          Make_Object_Declaration (Loc,
  3438.            Defining_Identifier => B,
  3439.            Object_Definition => New_Reference_To (Standard_Boolean, Loc)));
  3440.  
  3441.          --  Create new call statement
  3442.  
  3443.          Append_To (Parms, New_Reference_To (RTE (RE_Conditional_Call), Loc));
  3444.          Append_To (Parms, New_Reference_To (B, Loc));
  3445.  
  3446.          Rewrite_Substitute_Tree (Call,
  3447.            Make_Procedure_Call_Statement (Loc,
  3448.              Name => New_Reference_To (RTE (RE_Task_Entry_Call), Loc),
  3449.              Parameter_Associations => Parms));
  3450.  
  3451.          --  Construct statement sequence for new block
  3452.  
  3453.          Append_To (Stmts,
  3454.            Make_If_Statement (Loc,
  3455.              Condition => New_Reference_To (B, Loc),
  3456.              Then_Statements => Statements (Alt),
  3457.              Else_Statements => Else_Statements (N)));
  3458.  
  3459.       end if;
  3460.  
  3461.       --  The result is the new block
  3462.  
  3463.       Rewrite_Substitute_Tree (N,
  3464.         Make_Block_Statement (Loc,
  3465.           Declarations => Declarations (Blk),
  3466.           Handled_Statement_Sequence =>
  3467.             Make_Handled_Sequence_Of_Statements (Loc, Stmts)));
  3468.  
  3469.       Analyze (N);
  3470.  
  3471.    end Expand_N_Conditional_Entry_Call;
  3472.  
  3473.    ---------------------------------------
  3474.    -- Expand_N_Delay_Relative_Statement --
  3475.    ---------------------------------------
  3476.  
  3477.    --  Delay statement is implemented as a procedure call to Delay_For
  3478.    --  defined in Ada.Calendar.Delays in order to reduce the overhead of
  3479.    --  simple delays imposed by the use of Protected Objects.
  3480.  
  3481.    procedure Expand_N_Delay_Relative_Statement (N : Node_Id) is
  3482.       Loc : constant Source_Ptr := Sloc (N);
  3483.  
  3484.    begin
  3485.       Rewrite_Substitute_Tree (N,
  3486.         Make_Procedure_Call_Statement (Loc,
  3487.           Name => New_Reference_To (RTE (RO_CA_Delay_For), Loc),
  3488.           Parameter_Associations => New_List (Expression (N))));
  3489.       Analyze (N);
  3490.    end Expand_N_Delay_Relative_Statement;
  3491.  
  3492.    ------------------------------------
  3493.    -- Expand_N_Delay_Until_Statement --
  3494.    ------------------------------------
  3495.  
  3496.    --  Delay Until statement is implemented as a procedure call to
  3497.    --  Delay_Until defined in Ada.Calendar.Delays and Ada.Real_Time.Delays.
  3498.  
  3499.    procedure Expand_N_Delay_Until_Statement (N : Node_Id) is
  3500.       Loc : constant Source_Ptr := Sloc (N);
  3501.       Typ : Entity_Id;
  3502.  
  3503.    begin
  3504.       if Etype (Expression (N)) = Etype (RTE (RO_CA_Time)) then
  3505.          Typ := RTE (RO_CA_Delay_Until);
  3506.       else
  3507.          Typ := RTE (RO_RT_Delay_Until);
  3508.       end if;
  3509.  
  3510.       Rewrite_Substitute_Tree (N,
  3511.         Make_Procedure_Call_Statement (Loc,
  3512.           Name => New_Reference_To (Typ, Loc),
  3513.           Parameter_Associations => New_List (Expression (N))));
  3514.  
  3515.       Analyze (N);
  3516.    end Expand_N_Delay_Until_Statement;
  3517.  
  3518.    -----------------------------------
  3519.    -- Expand_N_Entry_Call_Statement --
  3520.    -----------------------------------
  3521.  
  3522.    --  An entry call is expanded into GNARLI calls to implement
  3523.    --  a simple entry call (see Build_Simple_Entry_Call).
  3524.  
  3525.    procedure Expand_N_Entry_Call_Statement (N : Node_Id) is
  3526.       Concval : Node_Id;
  3527.       Ename   : Node_Id;
  3528.       Index   : Node_Id;
  3529.  
  3530.    begin
  3531.       --  If this entry call is part of an asynchronous select, don't
  3532.       --  expand it here; it will be expanded with the select statement.
  3533.       --  Don't expand timed entry calls either, as they are translated
  3534.       --  into asynchronous entry calls.
  3535.  
  3536.       --  ??? This whole approach is questionable; it may be better
  3537.       --  to go back to allowing the expansion to take place and then
  3538.       --  attempting to fix it up in Expand_N_Asynchronous_Select.
  3539.       --  The tricky part is figuring out whether the expanded
  3540.       --  call is on a task or protected entry.
  3541.  
  3542.       if Nkind (Parent (N)) /= N_Triggering_Alternative
  3543.         and then (Nkind (Parent (N)) /= N_Entry_Call_Alternative
  3544.                     or else Nkind (Parent (Parent (N))) /= N_Timed_Entry_Call)
  3545.       then
  3546.          Extract_Entry (N, Concval, Ename, Index);
  3547.          Build_Simple_Entry_Call (N, Concval, Ename, Index);
  3548.       end if;
  3549.  
  3550.    end Expand_N_Entry_Call_Statement;
  3551.  
  3552.    --------------------------------
  3553.    -- Expand_N_Entry_Declaration --
  3554.    --------------------------------
  3555.  
  3556.    --  If there are parameters, then first, each of the formals is marked
  3557.    --  by setting Is_Entry_Formal. Next a record type is built which is
  3558.    --  used to hold the parameter values. The name of this record type is
  3559.    --  entryP where entry is the name of the entry, with an additional
  3560.    --  corresponding access type called entryPA. The record type has matching
  3561.    --  components for each formal (the component names are the same as the
  3562.    --  formal names). For elementary types, the component type matches the
  3563.    --  formal type. For composite types, an access type is declared (with
  3564.    --  the name formalA) which designates the formal type, and the type of
  3565.    --  the component is this access type. Finally the Entry_Component of
  3566.    --  each formal is set to reference the corresponding record component.
  3567.  
  3568.    procedure Expand_N_Entry_Declaration (N : Node_Id) is
  3569.       Loc         : constant Source_Ptr := Sloc (N);
  3570.       Entry_Ent   : constant Entity_Id  := Defining_Identifier (N);
  3571.       Components  : List_Id;
  3572.       Formal      : Node_Id;
  3573.       Ftype       : Entity_Id;
  3574.       Last_Decl   : Node_Id;
  3575.       Component   : Entity_Id;
  3576.       Ctype       : Entity_Id;
  3577.       Decl        : Node_Id;
  3578.       Rec_Ent     : Entity_Id;
  3579.       Acc_Ent     : Entity_Id;
  3580.  
  3581.    begin
  3582.       Formal := First_Formal (Entry_Ent);
  3583.       Last_Decl := N;
  3584.  
  3585.       --  Most processing is done only if parameters are present
  3586.  
  3587.       if Present (Formal) then
  3588.          Components := New_List;
  3589.  
  3590.          --  Loop through formals
  3591.  
  3592.          while Present (Formal) loop
  3593.             Set_Is_Entry_Formal (Formal);
  3594.             Component := Make_Defining_Identifier (Loc, Chars (Formal));
  3595.             Set_Entry_Component (Formal, Component);
  3596.             Ftype := Etype (Formal);
  3597.  
  3598.             --  Declare new access type and then append
  3599.  
  3600.             Ctype :=
  3601.               Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  3602.  
  3603.             Decl :=
  3604.               Make_Full_Type_Declaration (Loc,
  3605.                 Defining_Identifier => Ctype,
  3606.                 Type_Definition     =>
  3607.                   Make_Access_To_Object_Definition (Loc,
  3608.                     All_Present        => True,
  3609.                     Subtype_Indication => New_Reference_To (Ftype, Loc)));
  3610.  
  3611.             Insert_After (Last_Decl, Decl);
  3612.             Last_Decl := Decl;
  3613.  
  3614.             Append_To (Components,
  3615.               Make_Component_Declaration (Loc,
  3616.                 Defining_Identifier => Component,
  3617.                 Subtype_Indication  => New_Reference_To (Ctype, Loc)));
  3618.  
  3619.             Formal := Next_Formal (Formal);
  3620.          end loop;
  3621.  
  3622.          --  Create the Entry_Parameter_Record declaration
  3623.  
  3624.          Rec_Ent :=
  3625.            Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
  3626.  
  3627.          Decl :=
  3628.            Make_Full_Type_Declaration (Loc,
  3629.              Defining_Identifier => Rec_Ent,
  3630.              Type_Definition     =>
  3631.                Make_Record_Definition (Loc,
  3632.                  Component_List =>
  3633.                    Make_Component_List (Loc,
  3634.                      Component_Items => Components)));
  3635.  
  3636.          Insert_After (Last_Decl, Decl);
  3637.          Last_Decl := Decl;
  3638.  
  3639.          --  Construct and link in the corresponding access type
  3640.  
  3641.          Acc_Ent :=
  3642.            Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
  3643.  
  3644.          Set_Entry_Parameters_Type (Entry_Ent, Acc_Ent);
  3645.  
  3646.          Decl :=
  3647.            Make_Full_Type_Declaration (Loc,
  3648.              Defining_Identifier => Acc_Ent,
  3649.              Type_Definition     =>
  3650.                Make_Access_To_Object_Definition (Loc,
  3651.                  All_Present        => True,
  3652.                  Subtype_Indication => New_Reference_To (Rec_Ent, Loc)));
  3653.  
  3654.          Insert_After (Last_Decl, Decl);
  3655.          Last_Decl := Decl;
  3656.  
  3657.       end if;
  3658.  
  3659.    end Expand_N_Entry_Declaration;
  3660.  
  3661.    -----------------------------
  3662.    -- Expand_N_Protected_Body --
  3663.    -----------------------------
  3664.  
  3665.    --  Protected bodies are expanded to the completion of the subprograms
  3666.    --  created for the corresponding protected type. These are a protected
  3667.    --  and unprotected version of each protected subprogram in the object,
  3668.    --  a function to caluclate each entry barrier, and a procedure to
  3669.    --  execute the sequence of statements of each protected entry body.
  3670.    --  For example, for protected type ptype:
  3671.  
  3672.    --  function entB
  3673.    --    (O : System.Address;
  3674.    --     E : Protected_Entry_Index)
  3675.    --     return Boolean
  3676.    --  is
  3677.    --     <discriminant renamings>
  3678.    --     <private object renamings>
  3679.    --  begin
  3680.    --     return <barrier expression>;
  3681.    --  end entB;
  3682.  
  3683.    --  procedure pprocN (_object : in out poV;...) is
  3684.    --     <discriminant renamings>
  3685.    --     <private object renamings>
  3686.    --  begin
  3687.    --     <sequence of statements>
  3688.    --  end pprocN;
  3689.  
  3690.    --  procedure pproc (_object : in out poV;...) is
  3691.    --     procedure pprocF is
  3692.    --       Pn : Boolean;
  3693.    --     begin
  3694.    --       ptypeS (_object, Pn);
  3695.    --       System.Tasking.Protected_Objects.Unlock (_object._object'Access);
  3696.    --       System.Tasking.Abortion.Undefer_Abortion;
  3697.    --     end pprocF;
  3698.    --  begin
  3699.    --     System.Tasking.Abortion.Defer_Abortion;
  3700.    --     System.Tasking.Protected_Objects.Lock (_object._object'Access);
  3701.    --     pprocN (_object;...);
  3702.    --  at end
  3703.    --     pprocF (_object._object'Access);
  3704.    --  end pproc;
  3705.  
  3706.    --  function pfuncN (_object : poV;...) return Return_Type is
  3707.    --     <discriminant renamings>
  3708.    --     <private object renamings>
  3709.    --  begin
  3710.    --     <sequence of statements>
  3711.    --  end pfuncN;
  3712.  
  3713.    --  function pfunc (_object : poV) return Return_Type is
  3714.    --     procedure pfuncF is
  3715.    --     begin
  3716.    --       System.Tasking.Protected_Objects.Unlock (_object._object'Access);
  3717.    --       System.Tasking.Abortion.Undefer_Abortion;
  3718.    --     end pprocF;
  3719.    --  begin
  3720.    --     System.Tasking.Abortion.Defer_Abortion;
  3721.    --     System.Tasking.Protected_Objects.Lock (_object._object'Access);
  3722.    --     return pfuncN (_object);
  3723.    --  at end
  3724.    --     ptypeF (_object);
  3725.    --  end pfunc;
  3726.  
  3727.    --  procedure entE
  3728.    --    (O : System.Address;
  3729.    --     P : System.Address;
  3730.    --     E : Protected_Entry_Index)
  3731.    --  is
  3732.    --     <discriminant renamings>
  3733.    --     <private object renamings>
  3734.    --     type poVP is access poV;
  3735.    --     _Object : ptVP := ptVP!(O);
  3736.    --  begin
  3737.    --     begin
  3738.    --        <statement sequence>
  3739.    --        Complete_Entry_Body (_Object._Object);
  3740.    --     exception
  3741.    --        when others =>
  3742.    --           Exceptional_Complete_Entry_Body (
  3743.    --             _Object._Object, Current_Exception);
  3744.    --     end;
  3745.    --  end entE;
  3746.  
  3747.    --  The type poV is the record created for the protected type to hold
  3748.    --  the state of the protected object.
  3749.  
  3750.    procedure Expand_N_Protected_Body (N : Node_Id) is
  3751.       Loc          : constant Source_Ptr := Sloc (N);
  3752.       Pid          : constant Entity_Id  := Corresponding_Spec (N);
  3753.       Ptyp         : constant Node_Id    := Parent (Pid);
  3754.       Body_Id      : constant Entity_Id  := Corresponding_Body (Ptyp);
  3755.       Op_Body      : Node_Id;
  3756.       Op_Id        : Entity_Id;
  3757.       New_Op_Body  : Node_Id;
  3758.       Current_Node : Node_Id;
  3759.       Lab_Decl     : Node_Id;
  3760.  
  3761.    begin
  3762.  
  3763.       if Nkind (Parent (N)) = N_Subunit then
  3764.  
  3765.          --  This is the proper body corresponding to a stub. The declarations
  3766.          --  must be inserted at the point of the stub, which is in the decla-
  3767.          --  rative part of the parent unit.
  3768.  
  3769.          Current_Node := Corresponding_Stub (Parent (N));
  3770.       else
  3771.          Current_Node := N;
  3772.       end if;
  3773.  
  3774.       Op_Body := First (Declarations (N));
  3775.  
  3776.       --  The protected body is replaced with the bodies of its
  3777.       --  protected operations.
  3778.  
  3779.       Rewrite_Substitute_Tree (N, Make_Null_Statement (Sloc (N)));
  3780.       Analyze (N);
  3781.  
  3782.       while Present (Op_Body) loop
  3783.  
  3784.          if Nkind (Op_Body) = N_Subprogram_Body then
  3785.  
  3786.             New_Op_Body :=
  3787.               Build_Unprotected_Subprogram_Body (Op_Body, Pid);
  3788.  
  3789.             Insert_After (Current_Node, New_Op_Body);
  3790.             Current_Node := New_Op_Body;
  3791.             Analyze (New_Op_Body);
  3792.  
  3793.             New_Op_Body :=
  3794.                Build_Protected_Subprogram_Body (
  3795.                  Op_Body, Pid, Specification (New_Op_Body));
  3796.  
  3797.             Insert_After (Current_Node, New_Op_Body);
  3798.             Analyze (New_Op_Body);
  3799.  
  3800.  
  3801.          elsif Nkind (Op_Body) = N_Entry_Body then
  3802.  
  3803.             Op_Id := Defining_Identifier (Op_Body);
  3804.             Insert_After (Current_Node, Barrier_Function (Op_Id));
  3805.             Current_Node := Barrier_Function (Op_Id);
  3806.             Analyze (Barrier_Function (Op_Id));
  3807.  
  3808.             New_Op_Body :=
  3809.                Build_Protected_Entry (Op_Body, Pid);
  3810.  
  3811.             Insert_After (Current_Node, New_Op_Body);
  3812.             Current_Node := New_Op_Body;
  3813.             Analyze (New_Op_Body);
  3814.  
  3815.          elsif Nkind (Op_Body) = N_Implicit_Label_Declaration then
  3816.             Lab_Decl := Op_Body;
  3817.          end if;
  3818.  
  3819.          Op_Body := Next (Op_Body);
  3820.       end loop;
  3821.  
  3822.    end Expand_N_Protected_Body;
  3823.  
  3824.    -----------------------------------------
  3825.    -- Expand_N_Protected_Type_Declaration --
  3826.    -----------------------------------------
  3827.  
  3828.    --  First we create a corresponding record type declaration used to
  3829.    --  represent values of this protected type.
  3830.    --  The general form of this type declaration is
  3831.  
  3832.    --    type poV (discriminants) is record
  3833.    --      _Object       : aliased Protection(<entry count>);
  3834.    --      entry_family  : array (bounds) of Void;
  3835.    --      _Priority     : Integer   := priority_expression;
  3836.    --      <private data fields>
  3837.    --    end record;
  3838.  
  3839.    --  The discriminants are present only if the corresponding protected
  3840.    --  type has discriminants, and they exactly mirror the protected type
  3841.    --  discriminants. The private data fields similarly mirror the
  3842.    --  private declarations of the protected type.
  3843.  
  3844.    --  The Object field is always present. It contains RTS specific data
  3845.    --  used to control the protected object. It is declared as Aliased
  3846.    --  so that it can be passed as a pointer to the RTS. This allows the
  3847.    --  protected record to be referenced within RTS data structures.
  3848.  
  3849.    --  The Service field is present for protected objects with entries. It
  3850.    --  contains sufficient information to allow the entry service procedure
  3851.    --  for this object to be called when the object is not known till runtime.
  3852.  
  3853.    --  One entry_family component is present for each entry family in the
  3854.    --  task definition (see Expand_N_Task_Type_Declaration).
  3855.  
  3856.    --  The Priority field is present only if a Priority or Interrupt_Priority
  3857.    --  pragma appears in the protected definition. The expression captures the
  3858.    --  argument that was present in the pragma, and is used to provide
  3859.    --  the Ceiling_Priority parameter to the call to Initialize_Protection.
  3860.  
  3861.    --  When a protected object is declared, an instance of the protected type
  3862.    --  value record is created. The elaboration of this declaration creates
  3863.    --  the correct bounds for the entry families, and also evaluates the
  3864.    --  priority expression if needed. The initialization routine for
  3865.    --  the protected type itself then calls Initialize_Protection with
  3866.    --  appropriate parameters to initialize the value of the Task_Id field.
  3867.  
  3868.    --  Note: this record is passed to the subprograms created by the
  3869.    --  expansion of protected subprograms and entries. It is an in parameter
  3870.    --  to protected functions and an in out parameter to procedures and
  3871.    --  entry bodies. The Entity_Id for this created record type is placed
  3872.    --  in the Corresponding_Record_Type field of the associated protected
  3873.    --  type entity.
  3874.  
  3875.    --  Next we create a procedure specifications for protected subprograms
  3876.    --  and entry bodies. For each protected subprograms two subprograms are
  3877.    --  created, an unprotected and a protected version. The unprotected
  3878.    --  version is called from within other operations of the same protected
  3879.    --  object.
  3880.  
  3881.    --  A single subprogram is created to service all entry bodies; it has an
  3882.    --  additional boolean out parameter indicating that the previous entry
  3883.    --  call made by the current task was serviced immediately, i.e. not by
  3884.    --  proxy. The O parameter contains a pointer to a record object of the
  3885.    --  type described above. An untyped interface is used here to allow this
  3886.    --  procedure to be called in places where the type of the object to be
  3887.    --  serviced is not known. This must be done, for example, when a call
  3888.    --  that may have been requeued is cancelled; the corresponding object
  3889.    --  must be serviced, but which object that is is not known till runtime.
  3890.  
  3891.    --  procedure ptypeS
  3892.    --    (O : System.Address; P : out Boolean);
  3893.    --  procedure pprocN (_object : in out poV);
  3894.    --  procedure pproc (_object : in out poV);
  3895.    --  function pfuncN (_object : poV);
  3896.    --  function pfunc (_object : poV);
  3897.    --  ...
  3898.  
  3899.    --  Note that this must come after the record type declaration, since
  3900.    --  the specs refer to this type.
  3901.  
  3902.    procedure Expand_N_Protected_Type_Declaration (N : Node_Id) is
  3903.       Loc          : constant Source_Ptr := Sloc (N);
  3904.       Prottyp      : constant Entity_Id  := Defining_Identifier (N);
  3905.       Protnm       : constant Name_Id    := Chars (Prottyp);
  3906.  
  3907.       Pdef         : constant Node_Id    := Protected_Definition (N);
  3908.       --  This contains 2 lists; one for visible and one for private decls
  3909.  
  3910.       Rec_Decl     : Node_Id   := Build_Corresponding_Record (N, Prottyp, Loc);
  3911.       Rec_Ent      : Entity_Id := Defining_Identifier (Rec_Decl);
  3912.       Cdecls       : List_Id   := Component_Items (Component_List
  3913.                                     (Type_Definition (Rec_Decl)));
  3914.  
  3915.       Dent         : Entity_Id;
  3916.       Priv         : Node_Id;
  3917.       New_Priv     : Node_Id;
  3918.       Efam         : Entity_Id;
  3919.       Comp         : Node_Id;
  3920.       Comp_Id      : Entity_Id;
  3921.       Sub          : Node_Id;
  3922.       Component    : Node_Id;
  3923.       Current_Node : Node_Id := N;
  3924.       Efam_Type    : Node_Id;
  3925.       Nam          : Name_Id;
  3926.       Bdef         : Entity_Id;
  3927.       Edef         : Entity_Id;
  3928.       Body_List    : List_Id          := New_List;
  3929.       Body_Id      : Entity_Id;
  3930.       Body_Arr     : Node_Id;
  3931.       Body_Aggr    : Node_Id;
  3932.       Body_Assign  : Node_Id;
  3933.       Index_Exp    : Node_Id;
  3934.       Index_Range  : Node_Id;
  3935.  
  3936.    begin
  3937.       --  Fill in the component declarations.
  3938.  
  3939.       --  Add components for entry families. For each entry family,
  3940.       --  create an anoymous type declaration with the same size, and
  3941.       --  analyze the type.
  3942.  
  3943.       Collect_Entry_Families (Loc, Cdecls, Current_Node, Prottyp);
  3944.  
  3945.       --  Prepend the _Object field to the component list.  This
  3946.       --  needs the family components to computer the number of entries.
  3947.  
  3948.       Component :=
  3949.         Make_Component_Declaration (Loc,
  3950.           Defining_Identifier =>
  3951.             Make_Defining_Identifier (Loc, Name_uObject),
  3952.           Aliased_Present => True,
  3953.  
  3954.           Subtype_Indication =>
  3955.             Make_Subtype_Indication (
  3956.               Sloc => Loc,
  3957.               Subtype_Mark => New_Reference_To (RTE (RE_Protection), Loc),
  3958.  
  3959.               Constraint =>
  3960.                 Make_Index_Or_Discriminant_Constraint (
  3961.                   Sloc => Loc,
  3962.                   Constraints => New_List (
  3963.                     Build_Entry_Count_Expression (Prottyp, Cdecls, Loc)))));
  3964.  
  3965.       Prepend_To (Cdecls, Component);
  3966.  
  3967.       --  Add private field components.
  3968.  
  3969.       if Present (Private_Declarations (Pdef)) then
  3970.          Priv := First (Private_Declarations (Pdef));
  3971.  
  3972.          while Present (Priv) loop
  3973.             if Nkind (Priv) = N_Component_Declaration then
  3974.                New_Priv := Make_Component_Declaration (Loc,
  3975.                  Defining_Identifier => Make_Defining_Identifier (Loc,
  3976.                    Chars => Chars (Defining_Identifier (Priv))),
  3977.                  Subtype_Indication =>
  3978.                    New_Reference_To (Etype (Defining_Identifier (Priv)), Loc),
  3979.                  Expression => Expression (Priv));
  3980.  
  3981.                Append_To (Cdecls, New_Priv);
  3982.  
  3983.             elsif Nkind (Priv) = N_Subprogram_Declaration then
  3984.  
  3985.                --  Make the unprotected version of the subprogram available
  3986.                --  for expansion of intra object calls. There is no need for
  3987.                --  a protected version because this operation can only be
  3988.                --  be called from within the body.
  3989.  
  3990.                Sub :=
  3991.                  Make_Subprogram_Declaration (Loc,
  3992.                    Specification =>
  3993.                      Build_Protected_Sub_Specification
  3994.                        (Priv, Prottyp, Unprotected => True));
  3995.  
  3996.                Insert_After (Current_Node, Sub);
  3997.                Analyze (Sub);
  3998.  
  3999.                Set_Protected_Body_Subprogram (
  4000.                  Defining_Unit_Name (Specification (Priv)),
  4001.                  Defining_Unit_Name (Specification (Sub)));
  4002.  
  4003.             end if;
  4004.             Priv := Next (Priv);
  4005.          end loop;
  4006.       end if;
  4007.  
  4008.       --  Add the priority ceiling component if a priority pragma is present
  4009.       --  ??? Pure Cargo Cult; copied from Expand_N_Task_Type_Declaration.
  4010.       --      I don't know if all of this stuff has a analog in
  4011.       --      protected types or not.
  4012.  
  4013.       if Present (Pdef) and then Has_Priority_Pragma (Pdef) then
  4014.          Append_To (Cdecls,
  4015.            Make_Component_Declaration (Loc,
  4016.              Defining_Identifier =>
  4017.                Make_Defining_Identifier (Loc, Name_uPriority),
  4018.              Subtype_Indication => New_Reference_To (Standard_Integer, Loc),
  4019.              Expression => New_Copy (
  4020.                Expression (First (
  4021.                  Pragma_Argument_Associations (
  4022.                    Find_Task_Pragma (Pdef, Name_Priority)))))));
  4023.       end if;
  4024.  
  4025.       Insert_After (Current_Node, Rec_Decl);
  4026.       Current_Node := Rec_Decl;
  4027.  
  4028.       --  Analyze the record declaration immediately after construction,
  4029.       --  because the initialization procedure is needed for single object
  4030.       --  declarations before the next entity is analyzed (the freeze call
  4031.       --  that generates this initialization procedure is found below).
  4032.  
  4033.       Analyze (Rec_Decl);
  4034.  
  4035.       --  Declare the array of entry body and barrier function
  4036.       --  subprogram pointers.  It has to be initialized here, otherwise
  4037.       --  it will be initialized using _init_proc at the end of the
  4038.       --  declarations.  This would be too late, as code to initialize
  4039.       --  the array is intermixed with the declarations of the entry body
  4040.       --  subprograms.
  4041.       --  ??? There has to be some better way to prevent this late
  4042.       --      initialization; the following works, but it declares
  4043.       --      a whole new array, calls _init_proc to null it out,
  4044.       --      explicitly nulls it out, and then assigns it to the
  4045.       --      real entry body array.
  4046.  
  4047.       if Has_Entries (Prottyp) then
  4048.          Body_Id := Make_Defining_Identifier (Loc,
  4049.            New_External_Name (Chars (Prottyp), 'A'));
  4050.  
  4051.          Body_Arr := Make_Object_Declaration (Loc,
  4052.            Defining_Identifier => Body_Id,
  4053.            Aliased_Present => True,
  4054.            Object_Definition =>
  4055.              Make_Subtype_Indication (Loc,
  4056.                Subtype_Mark =>
  4057.                  New_Reference_To (RTE (RE_Protected_Entry_Body_Array), Loc),
  4058.                Constraint =>
  4059.                  Make_Index_Or_Discriminant_Constraint (Loc,
  4060.                    Constraints => New_List (
  4061.                       Make_Range (Loc,
  4062.                         Make_Integer_Literal (Loc, Uint_1),
  4063.                         Build_Entry_Count_Expression (
  4064.                           Prottyp,
  4065.                           Component_Items (Component_List (
  4066.                              Type_Definition (Parent (
  4067.                                Corresponding_Record_Type (Prottyp))))),
  4068.                           Loc))))),
  4069.            Expression => Make_Aggregate (Loc,
  4070.              Component_Associations => New_List (
  4071.                Make_Component_Association (Loc,
  4072.                  Choices => New_List (Make_Others_Choice (Loc)),
  4073.                  Expression => Make_Aggregate (Loc,
  4074.                    Expressions =>
  4075.                      New_List (Make_Null (Loc), Make_Null (Loc)))))));
  4076.  
  4077.          Insert_After (Current_Node, Body_Arr);
  4078.          Current_Node := Body_Arr;
  4079.  
  4080.          --  A pointer to this array will be placed in the corresponding
  4081.          --  record by its initialization procedure, so this needs to be
  4082.          --  analyzed here.
  4083.  
  4084.          Analyze (Body_Arr);
  4085.  
  4086.          Set_Entry_Bodies_Array (Prottyp, Body_Id);
  4087.  
  4088.       end if;
  4089.  
  4090.       --  Build two new procedure specifications for each protected
  4091.       --  subprogram; one to call from outside the object and one to
  4092.       --  call from inside.  Build a barrier function and an entry
  4093.       --  body action procedure specification for each protected entry.
  4094.       --  Initialize the entry body array.
  4095.  
  4096.       Comp := First (Visible_Declarations (Pdef));
  4097.       while Present (Comp) loop
  4098.          if Nkind (Comp) = N_Subprogram_Declaration then
  4099.             Sub :=
  4100.               Make_Subprogram_Declaration (Loc,
  4101.                 Specification =>
  4102.                   Build_Protected_Sub_Specification
  4103.                     (Comp, Prottyp, Unprotected => True));
  4104.  
  4105.             Insert_After (Current_Node, Sub);
  4106.             Analyze (Sub);
  4107.  
  4108.             Set_Protected_Body_Subprogram (
  4109.               Defining_Unit_Name (Specification (Comp)),
  4110.               Defining_Unit_Name (Specification (Sub)));
  4111.  
  4112.             --  Make the protected version of the subprogram available
  4113.             --  for expansion of external calls.
  4114.  
  4115.             Current_Node := Sub;
  4116.  
  4117.             Sub :=
  4118.               Make_Subprogram_Declaration (Loc,
  4119.                 Specification =>
  4120.                   Build_Protected_Sub_Specification
  4121.                     (Comp, Prottyp, Unprotected => False));
  4122.  
  4123.             Insert_After (Current_Node, Sub);
  4124.             Analyze (Sub);
  4125.             Current_Node := Sub;
  4126.  
  4127.          elsif Nkind (Comp) = N_Entry_Declaration then
  4128.             Comp_Id := Defining_Identifier (Comp);
  4129.             Nam := Chars (Comp_Id);
  4130.             Edef := Make_Defining_Identifier (Loc,
  4131.               Build_Selected_Name (Protnm, Nam, 'E'));
  4132.             Sub :=
  4133.               Make_Subprogram_Declaration (Loc,
  4134.                 Specification =>
  4135.                   Build_Protected_Entry_Specification (Edef, Comp_Id, Loc));
  4136.  
  4137.             Insert_After (Current_Node, Sub);
  4138.             Analyze (Sub);
  4139.  
  4140.             Set_Protected_Body_Subprogram (
  4141.               Defining_Identifier (Comp),
  4142.               Defining_Unit_Name (Specification (Sub)));
  4143.  
  4144.             Current_Node := Sub;
  4145.  
  4146.             Bdef := Make_Defining_Identifier (Loc,
  4147.               Build_Selected_Name (Protnm, Nam, 'B'));
  4148.             Sub :=
  4149.               Make_Subprogram_Declaration (Loc,
  4150.                 Specification =>
  4151.                   Build_Barrier_Function_Specification (Bdef, Loc));
  4152.  
  4153.             Insert_After (Current_Node, Sub);
  4154.             Analyze (Sub);
  4155.             Current_Node := Sub;
  4156.  
  4157.             --  Initialize the entry body array components corresponding
  4158.             --  to this entry or entry family to a record of pointers
  4159.             --  to the barrier function and action procedure.
  4160.  
  4161.             Body_Aggr :=
  4162.               Make_Aggregate (Loc,
  4163.                 Expressions => New_List (
  4164.                   Make_Attribute_Reference (Loc,
  4165.                     Prefix => New_Reference_To (Bdef, Loc),
  4166.                     Attribute_Name => Name_Unrestricted_Access),
  4167.                   Make_Attribute_Reference (Loc,
  4168.                     Prefix => New_Reference_To (Edef, Loc),
  4169.                     Attribute_Name => Name_Unrestricted_Access)));
  4170.  
  4171.             if Ekind (Comp_Id) = E_Entry_Family then
  4172.                Index_Range := Entry_Range_Expression (Loc, Comp_Id, Prottyp);
  4173.                Body_Assign :=
  4174.                  Make_Assignment_Statement (Loc,
  4175.                    Name =>
  4176.                      Make_Slice (Loc,
  4177.                        Prefix => New_Reference_To (Body_Id, Loc),
  4178.                        Discrete_Range => Index_Range),
  4179.  
  4180.                    Expression =>
  4181.                      Make_Aggregate (Loc,
  4182.                        Component_Associations => New_List (
  4183.                          Make_Component_Association (Loc,
  4184.                            Choices => New_List (Make_Others_Choice (Loc)),
  4185.                            Expression => Body_Aggr))));
  4186.             else
  4187.                Index_Exp :=
  4188.                  Entry_Index_Expression (Loc, Comp_Id, Empty, Prottyp);
  4189.  
  4190.                Body_Assign := Make_Assignment_Statement (Loc,
  4191.                   Name => Make_Indexed_Component (Loc,
  4192.                     Prefix => New_Reference_To (Body_Id, Loc),
  4193.                     Expressions => New_List (Index_Exp)),
  4194.                   Expression => Body_Aggr);
  4195.             end if;
  4196.  
  4197.             Insert_After (Current_Node, Body_Assign);
  4198.             Analyze (Body_Assign);
  4199.             Current_Node := Body_Assign;
  4200.  
  4201.          end if;
  4202.  
  4203.          Comp := Next (Comp);
  4204.       end loop;
  4205.  
  4206.       --  If there are some private entry declarations, expand it as if they
  4207.       --  were visible entries.
  4208.  
  4209.       if Present (Private_Declarations (Pdef)) then
  4210.          Comp := First (Private_Declarations (Pdef));
  4211.          while Present (Comp) loop
  4212.             if Nkind (Comp) = N_Entry_Declaration then
  4213.                Comp_Id := Defining_Identifier (Comp);
  4214.                Nam := Chars (Comp_Id);
  4215.                Edef := Make_Defining_Identifier (Loc,
  4216.                  Build_Selected_Name (Protnm, Nam, 'E'));
  4217.                Sub :=
  4218.                  Make_Subprogram_Declaration (Loc,
  4219.                    Specification =>
  4220.                      Build_Protected_Entry_Specification (Edef, Comp_Id, Loc));
  4221.  
  4222.                Insert_After (Current_Node, Sub);
  4223.                Analyze (Sub);
  4224.  
  4225.                Set_Protected_Body_Subprogram (
  4226.                  Defining_Identifier (Comp),
  4227.                  Defining_Unit_Name (Specification (Sub)));
  4228.  
  4229.                Current_Node := Sub;
  4230.  
  4231.                Bdef := Make_Defining_Identifier (Loc,
  4232.                  Build_Selected_Name (Protnm, Nam, 'B'));
  4233.                Sub :=
  4234.                  Make_Subprogram_Declaration (Loc,
  4235.                    Specification =>
  4236.                      Build_Barrier_Function_Specification (Bdef, Loc));
  4237.  
  4238.                Insert_After (Current_Node, Sub);
  4239.                Analyze (Sub);
  4240.                Current_Node := Sub;
  4241.  
  4242.                --  Initialize the entry body array components corresponding
  4243.                --  to this entry or entry family to a record of pointers
  4244.                --  to the barrier function and action proceddure.
  4245.  
  4246.                Body_Aggr :=
  4247.                  Make_Aggregate (Loc,
  4248.                    Expressions => New_List (
  4249.                      Make_Attribute_Reference (Loc,
  4250.                        Prefix => New_Reference_To (Bdef, Loc),
  4251.                        Attribute_Name => Name_Unrestricted_Access),
  4252.                      Make_Attribute_Reference (Loc,
  4253.                        Prefix => New_Reference_To (Edef, Loc),
  4254.                        Attribute_Name => Name_Unrestricted_Access)));
  4255.  
  4256.                if Ekind (Comp_Id) = E_Entry_Family then
  4257.                   Index_Range :=
  4258.                      Entry_Range_Expression (Loc, Comp_Id, Prottyp);
  4259.                   Body_Assign :=
  4260.                     Make_Assignment_Statement (Loc,
  4261.                       Name =>
  4262.                         Make_Slice (Loc,
  4263.                           Prefix => New_Reference_To (Body_Id, Loc),
  4264.                           Discrete_Range => Index_Range),
  4265.  
  4266.                       Expression =>
  4267.                         Make_Aggregate (Loc,
  4268.                           Component_Associations => New_List (
  4269.                             Make_Component_Association (Loc,
  4270.                               Choices => New_List (Make_Others_Choice (Loc)),
  4271.                               Expression => Body_Aggr))));
  4272.                else
  4273.                   Index_Exp :=
  4274.                     Entry_Index_Expression (Loc, Comp_Id, Empty, Prottyp);
  4275.  
  4276.                   Body_Assign := Make_Assignment_Statement (Loc,
  4277.                      Name => Make_Indexed_Component (Loc,
  4278.                        Prefix => New_Reference_To (Body_Id, Loc),
  4279.                        Expressions => New_List (Index_Exp)),
  4280.                      Expression => Body_Aggr);
  4281.                end if;
  4282.  
  4283.                Insert_After (Current_Node, Body_Assign);
  4284.                Analyze (Body_Assign);
  4285.                Current_Node := Body_Assign;
  4286.  
  4287.             end if;
  4288.  
  4289.             Comp := Next (Comp);
  4290.          end loop;
  4291.       end if;
  4292.  
  4293.       --  Now we can freeze the corresponding record. This needs manually
  4294.       --  freezing, since it is really part of the protected type, and
  4295.       --  the protected type is frozen at this stage. We of course need
  4296.       --  the initialization procedure for this corresponding record type
  4297.       --  and we won't get it in time if we don't freeze now.
  4298.  
  4299.       Insert_List_After (Current_Node, Freeze_Entity (Rec_Ent, Loc));
  4300.  
  4301.       --  Complete the expansion of access types to the current protected
  4302.       --  type, if any were declared.
  4303.       --  ??? Pure cargo cult, imitated from Expand_N_Task_Type_Declaration.
  4304.  
  4305.       Expand_Previous_Access_Type (N, Prottyp);
  4306.  
  4307.    end Expand_N_Protected_Type_Declaration;
  4308.  
  4309.    --------------------------------
  4310.    -- Expand_N_Requeue_Statement --
  4311.    --------------------------------
  4312.  
  4313.    --  A requeue statement is expanded into one of four GNARLI operations,
  4314.    --  depending on the source and destination (task or protected object).
  4315.    --  In addition, code must be generated to jump around the remainder of
  4316.    --  processing for the original entry and, if the destination is a
  4317.    --  (different) protected object, to attempt to service it.
  4318.    --  The following illustrates the various cases:
  4319.  
  4320.    --  procedure entE
  4321.    --    (O : System.Address;
  4322.    --     P : System.Address;
  4323.    --     E : Protected_Entry_Index)
  4324.    --  is
  4325.    --     <discriminant renamings>
  4326.    --     <private object renamings>
  4327.    --     type poVP is access poV;
  4328.    --     _Object : ptVP := ptVP!(O);
  4329.    --
  4330.    --  begin
  4331.    --     begin
  4332.    --        <start of statement sequence for entry>
  4333.    --
  4334.    --        -- Requeue from one protected entry body to another protected
  4335.    --        -- entry.
  4336.    --
  4337.    --        Requeue_Protected_Entry (
  4338.    --          _object._object'Access,
  4339.    --          new._object'Access,
  4340.    --          E,
  4341.    --          Abort_Present);
  4342.    --        return;
  4343.    --
  4344.    --        <some more of the statement sequence for entry>
  4345.    --
  4346.    --        --  Requeue from an entry body to a task entry.
  4347.    --
  4348.    --        Requeue_Protected_To_Task_Entry (
  4349.    --          New._task_id,
  4350.    --          E,
  4351.    --          Abort_Present);
  4352.    --        return;
  4353.    --
  4354.    --        <rest of statement sequence for entry>
  4355.    --        Complete_Entry_Body (_Object._Object);
  4356.    --
  4357.    --     exception
  4358.    --        when others =>
  4359.    --           Exceptional_Complete_Entry_Body (
  4360.    --             _Object._Object, Current_Exception);
  4361.    --     end;
  4362.    --  end entE;
  4363.  
  4364.    --  Requeue of a task entry call to a task entry.
  4365.    --
  4366.    --  Accept_Call (E, Ann);
  4367.    --     <start of statement sequence for accept statement>
  4368.    --     Requeue_Task_Entry (New._task_id, E, Abort_Present);
  4369.    --     goto Lnn;
  4370.    --     <rest of statement sequence for accept statement>
  4371.    --  Complete_Rendezvous;
  4372.    --  <<Lnn>>
  4373.  
  4374.    --  Requeue of a task entry call to a protected entry.
  4375.    --
  4376.    --  Accept_Call (E, Ann);
  4377.    --     <start of statement sequence for accept statement>
  4378.    --     Requeue_Task_To_Protected_Entry (
  4379.    --       new._object'Access,
  4380.    --       E,
  4381.    --       Abort_Present);
  4382.    --     newS (new, Pnn);
  4383.    --     goto Lnn;
  4384.    --     <rest of statement sequence for accept statement>
  4385.    --  Complete_Rendezvous;
  4386.    --  <<Lnn>>
  4387.  
  4388.    --  Further details on these expansions can be found in
  4389.    --  Expand_N_Protected_Body and Expand_N_Accept_Statement.
  4390.  
  4391.    procedure Expand_N_Requeue_Statement (N : Node_Id) is
  4392.       Loc        : constant Source_Ptr := Sloc (N);
  4393.       Acc_Stat   : Node_Id;
  4394.       Concval    : Node_Id;
  4395.       Ename      : Node_Id;
  4396.       Index      : Node_Id;
  4397.       Conctyp    : Entity_Id;
  4398.       Oldent     : constant Entity_Id := Current_Scope;
  4399.       Oldtyp     : constant Entity_Id := Scope (Oldent);
  4400.       Lab_Node   : Node_Id;
  4401.       Rcall      : Node_Id;
  4402.       Abortable  : Node_Id;
  4403.       Skip_Stat  : Node_Id;
  4404.       Curr_Stat  : Node_Id;
  4405.       Self_Param : Node_Id;
  4406.       New_Param  : Node_Id;
  4407.       Params     : List_Id;
  4408.       RTS_Call   : Entity_Id;
  4409.       Pend_Exp   : Node_Id;
  4410.  
  4411.    begin
  4412.       if Abort_Present (N) then
  4413.          Abortable := New_Occurrence_Of (Standard_True, Loc);
  4414.       else
  4415.          Abortable := New_Occurrence_Of (Standard_False, Loc);
  4416.       end if;
  4417.  
  4418.       --  Set up the target object.
  4419.  
  4420.       Extract_Entry (N, Concval, Ename, Index);
  4421.       Conctyp := Etype (Concval);
  4422.       New_Param := Concurrent_Ref (Concval);
  4423.  
  4424.       --  The target entry index and abortable flag are the same for all cases.
  4425.  
  4426.       Params := New_List (
  4427.         Entry_Index_Expression (Loc, Entity (Ename), Index, Conctyp),
  4428.         Abortable);
  4429.  
  4430.       --  Figure out which GNARLI call and what additional parameters are
  4431.       --  needed.
  4432.  
  4433.       if Is_Task_Type (Oldtyp) then
  4434.  
  4435.          if Is_Task_Type (Conctyp) then
  4436.             RTS_Call := RTE (RE_Requeue_Task_Entry);
  4437.          else
  4438.             pragma Assert (Is_Protected_Type (Conctyp));
  4439.             RTS_Call := RTE (RE_Requeue_Task_To_Protected_Entry);
  4440.             New_Param :=
  4441.               Make_Attribute_Reference (Loc,
  4442.                 Prefix => New_Param,
  4443.                 Attribute_Name => Name_Unchecked_Access);
  4444.          end if;
  4445.  
  4446.          Prepend (New_Param, Params);
  4447.  
  4448.       else
  4449.          pragma Assert (Is_Protected_Type (Oldtyp));
  4450.          Self_Param :=
  4451.            Make_Attribute_Reference (Loc,
  4452.              Prefix => Concurrent_Ref (New_Occurrence_Of (Oldtyp, Loc)),
  4453.              Attribute_Name => Name_Unchecked_Access);
  4454.  
  4455.          if Is_Task_Type (Conctyp) then
  4456.  
  4457.             RTS_Call := RTE (RE_Requeue_Protected_To_Task_Entry);
  4458.  
  4459.          else
  4460.             pragma Assert (Is_Protected_Type (Conctyp));
  4461.             RTS_Call := RTE (RE_Requeue_Protected_Entry);
  4462.             New_Param :=
  4463.               Make_Attribute_Reference (Loc,
  4464.                 Prefix => New_Param,
  4465.                 Attribute_Name => Name_Unchecked_Access);
  4466.          end if;
  4467.  
  4468.          Prepend (New_Param, Params);
  4469.          Prepend (Self_Param, Params);
  4470.       end if;
  4471.  
  4472.       --  Create the GNARLI call.
  4473.  
  4474.       Rcall := Make_Procedure_Call_Statement (Loc,
  4475.         Name =>
  4476.           New_Occurrence_Of (RTS_Call, Loc),
  4477.         Parameter_Associations => Params);
  4478.  
  4479.       Rewrite_Substitute_Tree (N, Rcall);
  4480.       Analyze (N);
  4481.  
  4482.       if Is_Protected_Type (Oldtyp) then
  4483.  
  4484.          --  Build the return statement to skip the rest of the entry
  4485.          --  body.
  4486.  
  4487.          Skip_Stat := Make_Return_Statement (Loc);
  4488.  
  4489.       else
  4490.          --  if the requeue is within a task, find the end label of the
  4491.          --  enclosing accept statement.
  4492.  
  4493.          Acc_Stat := Parent (N);
  4494.          while Nkind (Acc_Stat) /= N_Accept_Statement loop
  4495.             Acc_Stat := Parent (Acc_Stat);
  4496.          end loop;
  4497.  
  4498.          Lab_Node :=
  4499.             Last (Statements (Handled_Statement_Sequence (Acc_Stat)));
  4500.  
  4501.          --  Build the goto statement to skip the rest of the accept
  4502.          --  statement.
  4503.  
  4504.          Skip_Stat :=
  4505.            Make_Goto_Statement (Loc,
  4506.              Name => New_Occurrence_Of (Entity (Identifier (Lab_Node)), Loc));
  4507.       end if;
  4508.  
  4509.       Set_Analyzed (Skip_Stat);
  4510.  
  4511.       Insert_After (N, Skip_Stat);
  4512.  
  4513.    end Expand_N_Requeue_Statement;
  4514.  
  4515.    -------------------------------
  4516.    -- Expand_N_Selective_Accept --
  4517.    -------------------------------
  4518.  
  4519.    procedure Expand_N_Selective_Accept (N : Node_Id) is
  4520.       Accept_Case    : List_Id;
  4521.       Accept_List    : List_Id := New_List;
  4522.  
  4523.       Alt            : Node_Id;
  4524.       Alts           : constant List_Id := Select_Alternatives (N);
  4525.       Alt_List       : List_Id := New_List;
  4526.       Alt_Stats      : List_Id;
  4527.       Ann            : Entity_Id := Empty;
  4528.  
  4529.       Block          : Node_Id;
  4530.       Check_Guard    : Boolean := True;
  4531.       Decls          : List_Id := New_List;
  4532.       Stats          : List_Id := New_List;
  4533.  
  4534.       Body_List      : List_Id := New_List;
  4535.       Trailing_List  : List_Id := New_List;
  4536.  
  4537.       Choices        : List_Id;
  4538.       Else_Present   : Boolean := False;
  4539.       Terminate_Alt  : Node_Id := Empty;
  4540.       Select_Mode    : Node_Id;
  4541.  
  4542.       Delay_Case     : List_Id;
  4543.       Delay_Count    : Integer := 0;
  4544.       Delay_Val      : Entity_Id;
  4545.       Delay_Index    : Entity_Id;
  4546.       Delay_Min      : Entity_Id;
  4547.       Delay_Alt_List : List_Id := New_List;
  4548.       Delay_List     : List_Id := New_List;
  4549.  
  4550.       First_Delay    : Boolean := True;
  4551.       Guard_Open     : Entity_Id;
  4552.  
  4553.       End_Lab        : Node_Id;
  4554.       Index          : Int := 1;
  4555.       Lab            : Node_Id;
  4556.       Loc            : constant Source_Ptr := Sloc (N);
  4557.       Num_Alts       : Int;
  4558.       Num_Accept     : Nat := 0;
  4559.       Proc           : Node_Id;
  4560.       Q              : Node_Id;
  4561.       Qnam           : Entity_Id := Make_Defining_Identifier (Loc,
  4562.                                     New_External_Name ('S', 0));
  4563.       Time_Type      : Entity_Id;
  4564.       X              : Node_Id;
  4565.       Xnam           : Entity_Id := Make_Defining_Identifier (Loc,
  4566.                                     New_External_Name ('X', 1));
  4567.  
  4568.       -----------------------
  4569.       -- Local subprograms --
  4570.       -----------------------
  4571.  
  4572.       procedure Add_Accept (Alt : Node_Id);
  4573.       --  Process a single accept statement in a select alternative. Build
  4574.       --  procedure for body of accept, and add entry to dispatch table with
  4575.       --  expression for guard, in preparation for call to run time select.
  4576.  
  4577.       function Make_And_Declare_Label (Num : Int) return Node_Id;
  4578.       --  Manufacture a label using Num as a serial number and declare it.
  4579.       --  The declaration is appended to Decls. The label marks the trailing
  4580.       --  statements of an accept or delay alternative.
  4581.  
  4582.       function Make_Select_Call (Select_Mode : Entity_Id) return Node_Id;
  4583.       --  Build call to Selective_Wait runtime routine.
  4584.  
  4585.       procedure Process_Delay_Alternative (Alt : Node_Id; Index : Int);
  4586.       --  Add code to compare value of delay with previous values, and
  4587.       --  generate case entry for trailing statements.
  4588.  
  4589.       procedure Process_Accept_Alternative
  4590.         (Alt   : Node_Id;
  4591.          Index : Int;
  4592.          Proc  : Node_Id);
  4593.       --  Add code to call corresponding procedure, and branch to
  4594.       --  trailing statements, if any.
  4595.  
  4596.       ----------------
  4597.       -- Add_Accept --
  4598.       ----------------
  4599.  
  4600.       procedure Add_Accept (Alt : Node_Id) is
  4601.          Acc_Stm   : constant Node_Id    := Accept_Statement (Alt);
  4602.          Ename     : constant Node_Id    := Entry_Direct_Name (Acc_Stm);
  4603.          Eent      : constant Entity_Id  := Entity (Ename);
  4604.          Index     : constant Node_Id    := Entry_Index (Acc_Stm);
  4605.          Null_Body : Node_Id;
  4606.          Proc_Body : Node_Id;
  4607.          Expr      : Node_Id;
  4608.  
  4609.       begin
  4610.          if No (Ann) then
  4611.             Ann := Node (First_Elmt (Accept_Address (Eent)));
  4612.          end if;
  4613.  
  4614.          if Present (Condition (Alt)) then
  4615.             Expr := Make_Conditional_Expression (Loc,
  4616.               New_List (Condition (Alt),
  4617.                         Entry_Index_Expression
  4618.                           (Loc, Eent, Index, Scope (Eent)),
  4619.                         New_Reference_To (RTE (RE_Null_Task_Entry), Loc)));
  4620.          else
  4621.             Expr :=
  4622.               Entry_Index_Expression
  4623.                 (Loc, Eent, Index, Scope (Eent));
  4624.          end if;
  4625.  
  4626.          if Present (Handled_Statement_Sequence (Accept_Statement (Alt))) then
  4627.             Null_Body := New_Reference_To (Standard_False, Loc);
  4628.  
  4629.             Proc_Body :=
  4630.               Make_Subprogram_Body (Loc,
  4631.                 Specification =>
  4632.                   Make_Procedure_Specification (Loc,
  4633.                     Defining_Unit_Name =>
  4634.                       Make_Defining_Identifier (Loc,
  4635.                         New_External_Name (Chars (Ename), 'A', Num_Accept))),
  4636.  
  4637.                Declarations => New_List,
  4638.                Handled_Statement_Sequence =>
  4639.                  Build_Accept_Body
  4640.                    (Handled_Statement_Sequence (Accept_Statement (Alt)), Loc));
  4641.  
  4642.             Append (Proc_Body, Body_List);
  4643.  
  4644.          else
  4645.             Null_Body := New_Reference_To (Standard_True,  Loc);
  4646.          end if;
  4647.  
  4648.          Append_To (Accept_List,
  4649.            Make_Aggregate (Loc, Expressions => New_List (Null_Body, Expr)));
  4650.  
  4651.          Num_Accept := Num_Accept + 1;
  4652.  
  4653.       end Add_Accept;
  4654.  
  4655.       -------------------------------
  4656.       -- Process_Delay_Alternative --
  4657.       -------------------------------
  4658.  
  4659.       procedure Process_Delay_Alternative (Alt : Node_Id; Index : Int) is
  4660.          Choices   : List_Id;
  4661.          Cond      : Node_Id;
  4662.          Delay_Alt : List_Id;
  4663.  
  4664.       begin
  4665.          --  Determine the smallest specified delay.
  4666.          --  for each delay alternative generate:
  4667.  
  4668.          --    if guard-expression then
  4669.          --       Delay_Val  := delay-expression;
  4670.          --       Guard_Open := True;
  4671.          --       if Delay_Val < Delay_Min then
  4672.          --          Delay_Min   := Delay_Val;
  4673.          --          Delay_Index := Index;
  4674.          --       end if;
  4675.          --    end if;
  4676.  
  4677.          --  The enclosing if-statement is omitted if there is no guard.
  4678.  
  4679.          if Delay_Count = 1
  4680.            or else First_Delay
  4681.          then
  4682.             First_Delay := False;
  4683.  
  4684.             Delay_Alt := New_List (
  4685.               Make_Assignment_Statement (Loc,
  4686.                 Name => New_Reference_To (Delay_Min, Loc),
  4687.                 Expression => Expression (Delay_Statement (Alt))));
  4688.  
  4689.             if Delay_Count > 1 then
  4690.                Append_To (Delay_Alt,
  4691.                  Make_Assignment_Statement (Loc,
  4692.                    Name       => New_Reference_To (Delay_Index, Loc),
  4693.                    Expression => Make_Integer_Literal (Loc,
  4694.                      Intval   => UI_From_Int (Index))));
  4695.             end if;
  4696.  
  4697.          else
  4698.             Delay_Alt := New_List (
  4699.               Make_Assignment_Statement (Loc,
  4700.                 Name => New_Reference_To (Delay_Val, Loc),
  4701.                 Expression => Expression (Delay_Statement (Alt))));
  4702.  
  4703.             if Time_Type = Standard_Duration then
  4704.                Cond :=
  4705.                   Make_Op_Lt (Loc,
  4706.                     Left_Opnd  => New_Reference_To (Delay_Val, Loc),
  4707.                     Right_Opnd => New_Reference_To (Delay_Min, Loc));
  4708.  
  4709.             else
  4710.                --  The scope of the time type must define a comparison
  4711.                --  operator. The scope itself may not be visible, so we
  4712.                --  construct a node with entity information to insure that
  4713.                --  semantic analysis can find the proper operator.
  4714.  
  4715.                Cond :=
  4716.                  Make_Function_Call (Loc,
  4717.                    Name => Make_Selected_Component (Loc,
  4718.                      Prefix => New_Reference_To (Scope (Time_Type), Loc),
  4719.                      Selector_Name =>
  4720.                        Make_Operator_Symbol (Loc,
  4721.                          Chars => Name_Op_Lt,
  4722.                          Strval => No_String)),
  4723.                     Parameter_Associations =>
  4724.                       New_List (
  4725.                         New_Reference_To (Delay_Val, Loc),
  4726.                         New_Reference_To (Delay_Min, Loc)));
  4727.  
  4728.                Set_Entity (Prefix (Name (Cond)), Scope (Time_Type));
  4729.             end if;
  4730.  
  4731.             Append_To (Delay_Alt,
  4732.               Make_If_Statement (Loc,
  4733.                 Condition => Cond,
  4734.                 Then_Statements => New_List (
  4735.                   Make_Assignment_Statement (Loc,
  4736.                     Name       => New_Reference_To (Delay_Min, Loc),
  4737.                     Expression => New_Reference_To (Delay_Val, Loc)),
  4738.  
  4739.                   Make_Assignment_Statement (Loc,
  4740.                     Name       => New_Reference_To (Delay_Index, Loc),
  4741.                     Expression => Make_Integer_Literal (Loc,
  4742.                       Intval   => UI_From_Int (Index))))));
  4743.          end if;
  4744.  
  4745.          if Check_Guard then
  4746.             Append_To (Delay_Alt,
  4747.               Make_Assignment_Statement (Loc,
  4748.                 Name => New_Reference_To (Guard_Open, Loc),
  4749.                 Expression => New_Reference_To (Standard_True, Loc)));
  4750.          end if;
  4751.  
  4752.          if Present (Condition (Alt)) then
  4753.             Delay_Alt := New_List (
  4754.               Make_If_Statement (Loc,
  4755.                 Condition => Condition (Alt),
  4756.                 Then_Statements => Delay_Alt));
  4757.          end if;
  4758.  
  4759.          Append_List (Delay_Alt, Delay_List);
  4760.  
  4761.          --  If the delay alternative has a statement part, add a
  4762.          --  choice to the case statements for delays.
  4763.  
  4764.          if Present (Statements (Alt)) then
  4765.  
  4766.             if Delay_Count = 1 then
  4767.                Append_List (Statements (Alt), Delay_Alt_List);
  4768.  
  4769.             else
  4770.                Choices := New_List (
  4771.                  Make_Integer_Literal (Loc,
  4772.                    Intval => UI_From_Int (Index)));
  4773.  
  4774.                Append_To (Delay_Alt_List,
  4775.                  Make_Case_Statement_Alternative (Loc,
  4776.                    Discrete_Choices => Choices,
  4777.                    Statements => Statements (Alt)));
  4778.             end if;
  4779.  
  4780.          elsif Delay_Count = 1 then
  4781.  
  4782.             --  If the single delay has no trailing statements, add a branch
  4783.             --  to the exit label to the selective wait.
  4784.  
  4785.             Delay_Alt_List := New_List (
  4786.               Make_Goto_Statement (Loc,
  4787.                 Name => New_Copy (Identifier (End_Lab))));
  4788.  
  4789.          end if;
  4790.       end Process_Delay_Alternative;
  4791.  
  4792.       --------------------------------
  4793.       -- Process_Accept_Alternative --
  4794.       --------------------------------
  4795.  
  4796.       procedure Process_Accept_Alternative
  4797.         (Alt   : Node_Id;
  4798.          Index : Int;
  4799.          Proc  : Node_Id)
  4800.       is
  4801.          Choices   : List_Id;
  4802.          Alt_Stats : List_Id;
  4803.  
  4804.       begin
  4805.          Alt_Stats := No_List;
  4806.  
  4807.          if Present (Handled_Statement_Sequence (Accept_Statement (Alt))) then
  4808.             Choices := New_List (
  4809.               Make_Integer_Literal (Loc,
  4810.                 Intval => UI_From_Int (Index)));
  4811.  
  4812.             Alt_Stats := New_List (
  4813.               Make_Procedure_Call_Statement (Loc,
  4814.                 Name => New_Reference_To (
  4815.                   Defining_Unit_Name (Specification (Proc)), Loc)));
  4816.          end if;
  4817.  
  4818.          if Statements (Alt) /= Empty_List then
  4819.  
  4820.             if No (Alt_Stats) then
  4821.  
  4822.                --  Accept with no body, followed by trailing statements.
  4823.  
  4824.                Choices := New_List (
  4825.                  Make_Integer_Literal (Loc,
  4826.                    Intval => UI_From_Int (Index)));
  4827.  
  4828.                Alt_Stats := New_List;
  4829.             end if;
  4830.  
  4831.             --  After the call, if any, branch to to trailing statements.
  4832.             --  We create a label for each, as well as the corresponding
  4833.             --  label declaration.
  4834.  
  4835.             Lab := Make_And_Declare_Label (Index);
  4836.             Append_To (Alt_Stats,
  4837.               Make_Goto_Statement (Loc,
  4838.                 Name => New_Copy (Identifier (Lab))));
  4839.  
  4840.             Append (Lab, Trailing_List);
  4841.             Append_List (Statements (Alt), Trailing_List);
  4842.             Append_To (Trailing_List,
  4843.               Make_Goto_Statement (Loc,
  4844.                 Name => New_Copy (Identifier (End_Lab))));
  4845.          end if;
  4846.  
  4847.          if Present (Alt_Stats) then
  4848.  
  4849.             --  Procedure call. and/or trailing statements.
  4850.  
  4851.             Append_To (Alt_List,
  4852.               Make_Case_Statement_Alternative (Loc,
  4853.                 Discrete_Choices => Choices,
  4854.                 Statements => Alt_Stats));
  4855.          end if;
  4856.       end Process_Accept_Alternative;
  4857.  
  4858.       ----------------------
  4859.       -- Make_Select_Call --
  4860.       ----------------------
  4861.  
  4862.       function Make_Select_Call (Select_Mode : Entity_Id) return Node_Id is
  4863.          Params : List_Id := New_List;
  4864.  
  4865.       begin
  4866.          Append (New_Reference_To (Qnam, Loc), Params);
  4867.          Append (Select_Mode, Params);
  4868.          Append (New_Reference_To (Ann, Loc), Params);
  4869.          Append (New_Reference_To (Xnam, Loc), Params);
  4870.  
  4871.          return
  4872.            Make_Procedure_Call_Statement (Loc,
  4873.              Name => New_Reference_To (RTE (RE_Selective_Wait), Loc),
  4874.              Parameter_Associations => Params);
  4875.       end Make_Select_Call;
  4876.  
  4877.       -----------------------------
  4878.       --  Make_And_Declare_Label --
  4879.       -----------------------------
  4880.  
  4881.       function Make_And_Declare_Label (Num : Int) return Node_Id is
  4882.          Lab_Id : Node_Id;
  4883.  
  4884.       begin
  4885.          Lab_Id := Make_Identifier (Loc, New_External_Name ('L', Num));
  4886.          Lab := Make_Label (Loc, Lab_Id);
  4887.  
  4888.          Append_To (Decls,
  4889.            Make_Implicit_Label_Declaration (Loc,
  4890.              Defining_Identifier  =>
  4891.                Make_Defining_Identifier (Loc, Chars (Lab_Id)),
  4892.              Label => Lab));
  4893.  
  4894.          return Lab;
  4895.       end Make_And_Declare_Label;
  4896.  
  4897.    --  Start of processing for Expand_N_Selective_Accept
  4898.  
  4899.    begin
  4900.       --  First insert some declarations before the select. The first is:
  4901.  
  4902.       --    Ann : Address
  4903.  
  4904.       --  This variable holds the parameters passed to the accept body. This
  4905.       --  declaration has already been inserted by the time we get here by
  4906.       --  a call to Expand_Accept_Declarations made from the semantics when
  4907.       --  processing the first accept statement contained in the select. We
  4908.       --  can find this entity as Accept_Address (E), where E is any of the
  4909.       --  entries references by contained accept statements.
  4910.  
  4911.       --  The first step is to scan the list of Selective_Accept_Statements
  4912.       --  to find this entity, and also count the number of accepts, and
  4913.       --  determine if terminated, delay or else is present:
  4914.       Num_Alts := 0;
  4915.  
  4916.       Alt := First (Alts);
  4917.       while Present (Alt) loop
  4918.  
  4919.          if Nkind (Alt) = N_Accept_Alternative then
  4920.             Add_Accept (Alt);
  4921.  
  4922.          elsif Nkind (Alt) = N_Delay_Alternative then
  4923.             Delay_Count   := Delay_Count + 1;
  4924.  
  4925.             --   If the delays are relative delays, the delay expressions have
  4926.             --   type Standard_Duration. Otherwise they have some time type.
  4927.             --   This has been verified by the front-end.
  4928.  
  4929.             if Nkind (Delay_Statement (Alt)) = N_Delay_Relative_Statement then
  4930.                Time_Type := Standard_Duration;
  4931.             else
  4932.                Time_Type := Etype (Expression (Delay_Statement (Alt)));
  4933.             end if;
  4934.  
  4935.             if No (Condition (Alt)) then
  4936.  
  4937.                --  this guard will always be open.
  4938.  
  4939.                Check_Guard := False;
  4940.             end if;
  4941.  
  4942.          elsif Nkind (Alt) = N_Terminate_Alternative then
  4943.             Terminate_Alt := Alt;
  4944.          end if;
  4945.  
  4946.          Num_Alts := Num_Alts + 1;
  4947.          Alt := Next (Alt);
  4948.       end loop;
  4949.  
  4950.       Else_Present := Present (Else_Statements (N));
  4951.  
  4952.       --  At the same time (see procedure Add_Accept) we build the accept list:
  4953.  
  4954.       --    Qnn : Accept_List (1 .. num-select) := (
  4955.       --          (null-body, entry-index),
  4956.       --          (null-body, entry-index),
  4957.       --          ..
  4958.       --          (null_body, entry-index));
  4959.  
  4960.       --  In the above declaration, null-body is True if the corresponding
  4961.       --  accept has no body, and false otherwise. The entry is either the
  4962.       --  entry index expression if there is no guard, or if a guard is
  4963.       --  present, then a conditional expression of the form:
  4964.  
  4965.       --    (if guard then entry-index else Null_Task_Entry)
  4966.  
  4967.       --  If a guard is statically known to be false, the entry can simply
  4968.       --  be omitted from the accept list.
  4969.  
  4970.       Q :=
  4971.         Make_Object_Declaration (Loc,
  4972.           Defining_Identifier => Qnam,
  4973.           Object_Definition =>
  4974.             New_Reference_To (RTE (RE_Accept_List_Access), Loc),
  4975.  
  4976.           Expression =>
  4977.             Make_Allocator (Loc,
  4978.               Expression =>
  4979.                 Make_Qualified_Expression (Loc,
  4980.                   Subtype_Mark =>
  4981.                     New_Reference_To (RTE (RE_Accept_List), Loc),
  4982.                   Expression =>
  4983.                     Make_Aggregate (Loc, Expressions => Accept_List))));
  4984.  
  4985.       Append (Q, Decls);
  4986.  
  4987.       --  Then we declare the variable that holds the index for the accept
  4988.       --  that will be selected for service:
  4989.  
  4990.       --    Xnn : Select_Index;
  4991.  
  4992.       X :=
  4993.         Make_Object_Declaration (Loc,
  4994.           Defining_Identifier => Xnam,
  4995.           Object_Definition =>
  4996.             New_Reference_To (RTE (RE_Select_Index), Loc));
  4997.  
  4998.       Append (X, Decls);
  4999.  
  5000.       --  After this follow  procedure declarations for each accept body.
  5001.  
  5002.       --    procedure Pnn is
  5003.       --    begin
  5004.       --       ...
  5005.       --    end;
  5006.  
  5007.       --  where the ... are statements from the corresponding procedure body.
  5008.       --  No parameters are involved, since the parameters are passed via Ann
  5009.       --  and the parameter references have already been expanded to be direct
  5010.       --  references to Ann (see Exp_Ch2.Expand_Entry_Parameter). Furthermore,
  5011.       --  any embedded tasking statements (which would normally be illegal in
  5012.       --  procedures, have been converted to calls to the tasking runtime so
  5013.       --  there is no problem in putting them into procedures.
  5014.  
  5015.       --  The original accept statement has been expanded into a block in
  5016.       --  the same fashion as for simple accepts (see Build_Accept_Body).
  5017.  
  5018.       --  Note: we don't really need to build these procedures for the case
  5019.       --  where no delay statement is present, but is is just as easy to
  5020.       --  build them unconditionally, and not significantly inefficient,
  5021.       --  since if they are short they will be inlined anyway.
  5022.  
  5023.       --  The procedure declarations have been assembled in Body_List.
  5024.  
  5025.       --  If delays are present, we must compute the required delay.
  5026.       --  We first generate the declarations:
  5027.  
  5028.       --    Delay_Index : Boolean := 0;
  5029.       --    Delay_Min   : Some_Time_Type.Time;
  5030.       --    Delay_Val   : Some_Time_Type.Time;
  5031.  
  5032.       --  Delay_Index will be set to the index of the minimum delay, i.e. the
  5033.       --   active delay that is actually chosen as the basis for the possible
  5034.       --   delay if an immediate rendez-vous is not possible.
  5035.       --   In the most common case there is a single delay statement, and this
  5036.       --   is handled specially.
  5037.  
  5038.       if Delay_Count > 0 then
  5039.  
  5040.          --  Generate the required declarations
  5041.  
  5042.          Delay_Val   := Make_Defining_Identifier (Loc,
  5043.                                     New_External_Name ('D', 1));
  5044.          Delay_Index := Make_Defining_Identifier (Loc,
  5045.                                     New_External_Name ('D', 2));
  5046.          Delay_Min   := Make_Defining_Identifier (Loc,
  5047.                                     New_External_Name ('D', 3));
  5048.          Append_To (Decls,
  5049.            Make_Object_Declaration (Loc,
  5050.              Defining_Identifier => Delay_Val,
  5051.              Object_Definition => New_Reference_To (Time_Type, Loc)));
  5052.  
  5053.          Append_To (Decls,
  5054.            Make_Object_Declaration (Loc,
  5055.              Defining_Identifier => Delay_Index,
  5056.              Object_Definition => New_Reference_To (Standard_Integer, Loc)));
  5057.  
  5058.          Append_To (Decls,
  5059.            Make_Object_Declaration (Loc,
  5060.              Defining_Identifier => Delay_Min,
  5061.              Object_Definition => New_Reference_To (Time_Type, Loc)));
  5062.  
  5063.          if Check_Guard then
  5064.             Guard_Open := Make_Defining_Identifier (Loc,
  5065.                                     New_External_Name ('G', 1));
  5066.             Append_To (Decls,
  5067.               Make_Object_Declaration (Loc,
  5068.                  Defining_Identifier => Guard_Open,
  5069.                  Object_Definition => New_Reference_To (Standard_Boolean, Loc),
  5070.                  Expression        => New_Reference_To (Standard_False, Loc)));
  5071.          end if;
  5072.       end if;
  5073.  
  5074.       if Present (Terminate_Alt) then
  5075.  
  5076.          --  If the terminate alternative guard is False, use
  5077.          --  Simple_Mode; otherwise use Terminate_Mode.
  5078.  
  5079.          if Present (Condition (Terminate_Alt)) then
  5080.             Select_Mode := Make_Conditional_Expression (Loc,
  5081.               New_List (Condition (Terminate_Alt),
  5082.                         New_Reference_To (RTE (RE_Terminate_Mode), Loc),
  5083.                         New_Reference_To (RTE (RE_Simple_Mode), Loc)));
  5084.          else
  5085.             Select_Mode := New_Reference_To (RTE (RE_Terminate_Mode), Loc);
  5086.          end if;
  5087.  
  5088.       elsif Else_Present or Delay_Count > 0 then
  5089.          Select_Mode := New_Reference_To (RTE (RE_Else_Mode), Loc);
  5090.  
  5091.       else
  5092.          Select_Mode := New_Reference_To (RTE (RE_Simple_Mode), Loc);
  5093.       end if;
  5094.  
  5095.       Append (Make_Select_Call (Select_Mode), Stats);
  5096.  
  5097.       --  Now generate code to act on the result. There is an entry
  5098.       --  in this case for each accept statement with a non-null body,
  5099.       --  followed by a branch to the statements that follow the Accept.
  5100.       --  In the absence of delay alternatives, we generate:
  5101.  
  5102.       --    case X is
  5103.       --      when No_Rendezvous =>  --  omitted if simple mode
  5104.       --         goto Lab0;
  5105.  
  5106.       --      when 1 =>
  5107.       --         P1n;
  5108.       --         goto Lab1;
  5109.  
  5110.       --      when 2 =>
  5111.       --         P2n;
  5112.       --         goto Lab2;
  5113.  
  5114.       --      when others =>
  5115.       --         goto Exit;
  5116.       --    end case;
  5117.       --
  5118.       --    Lab0: Else_Statements;
  5119.       --    goto exit;
  5120.  
  5121.       --    Lab1:  Trailing_Statements1;
  5122.       --    goto Exit;
  5123.       --
  5124.       --    Lab2:  Trailing_Statements2;
  5125.       --    goto Exit;
  5126.       --    ...
  5127.       --    Exit:
  5128.  
  5129.       --  Generate label for common exit.
  5130.  
  5131.       End_Lab := Make_And_Declare_Label (Num_Alts + 1);
  5132.  
  5133.       --  First entry is the default case, when no rendezvous is possible.
  5134.  
  5135.       Choices := New_List (
  5136.         New_Reference_To (RTE (RE_No_Rendezvous), Loc));
  5137.  
  5138.       if Else_Present then
  5139.  
  5140.          --  If no rendezvous is possible, the else part is executed.
  5141.  
  5142.          Lab := Make_And_Declare_Label (0);
  5143.          Alt_Stats := New_List (
  5144.            Make_Goto_Statement (Loc,
  5145.              Name => New_Copy (Identifier (Lab))));
  5146.  
  5147.          Append (Lab, Trailing_List);
  5148.          Append_List (Else_Statements (N), Trailing_List);
  5149.          Append_To (Trailing_List,
  5150.            Make_Goto_Statement (Loc,
  5151.              Name => New_Copy (Identifier (End_Lab))));
  5152.       else
  5153.          Alt_Stats := New_List (
  5154.            Make_Goto_Statement (Loc,
  5155.              Name => New_Copy (Identifier (End_Lab))));
  5156.       end if;
  5157.  
  5158.       Append_To (Alt_List,
  5159.         Make_Case_Statement_Alternative (Loc,
  5160.           Discrete_Choices => Choices,
  5161.           Statements => Alt_Stats));
  5162.  
  5163.       --  We make use of the fact that Accept_Index is an integer type,
  5164.       --  and generate successive literals for entries for each accept.
  5165.       --  Only those for which there is a body or trailing statements are
  5166.       --  given a case entry.
  5167.  
  5168.       Alt := First (Select_Alternatives (N));
  5169.       Proc := First (Body_List);
  5170.  
  5171.       while Present (Alt) loop
  5172.  
  5173.          if Nkind (Alt) = N_Accept_Alternative then
  5174.             Process_Accept_Alternative (Alt, Index, Proc);
  5175.  
  5176.             if Present
  5177.               (Handled_Statement_Sequence (Accept_Statement (Alt)))
  5178.             then
  5179.                Proc := Next (Proc);
  5180.             end if;
  5181.  
  5182.          elsif Nkind (Alt) = N_Delay_Alternative then
  5183.             Process_Delay_Alternative (Alt, Index);
  5184.          end if;
  5185.  
  5186.          Index := Index + 1;
  5187.          Alt := Next (Alt);
  5188.       end loop;
  5189.  
  5190.       --  An others choice is always added to the main case, as well
  5191.       --  as the delay case (to satisfy the compiler).
  5192.  
  5193.       Append_To (Alt_List,
  5194.         Make_Case_Statement_Alternative (Loc,
  5195.           Discrete_Choices =>
  5196.             New_List (Make_Others_Choice (Loc)),
  5197.           Statements       =>
  5198.             New_List (Make_Goto_Statement (Loc,
  5199.               Name => New_Copy (Identifier (End_Lab))))));
  5200.  
  5201.       Accept_Case := New_List (
  5202.         Make_Case_Statement (Loc,
  5203.           Expression   => New_Reference_To (Xnam, Loc),
  5204.           Alternatives => Alt_List));
  5205.  
  5206.       Append_List (Trailing_List, Accept_Case);
  5207.       Append (End_Lab, Accept_Case);
  5208.       Append_List (Body_List, Decls);
  5209.  
  5210.       --  Construct case statement for trailing statements of delay
  5211.       --  alternatives, if there are several of them.
  5212.  
  5213.       if Delay_Count > 1 then
  5214.          Append_To (Delay_Alt_List,
  5215.            Make_Case_Statement_Alternative (Loc,
  5216.              Discrete_Choices =>
  5217.                New_List (Make_Others_Choice (Loc)),
  5218.              Statements       =>
  5219.                New_List (Make_Null_Statement (Loc))));
  5220.  
  5221.          Delay_Case := New_List (
  5222.            Make_Case_Statement (Loc,
  5223.              Expression   => New_Reference_To (Delay_Index, Loc),
  5224.              Alternatives => Delay_Alt_List));
  5225.       else
  5226.          Delay_Case := Delay_Alt_List;
  5227.       end if;
  5228.  
  5229.       --  If there are no delay alternatives, we append the case statement
  5230.       --  to the statement list.
  5231.  
  5232.       if Delay_Count = 0 then
  5233.          Append_List (Accept_Case, Stats);
  5234.  
  5235.       else
  5236.          --  If delay alternatives are present, we generate:
  5237.  
  5238.          --    find minimum delay.
  5239.          --    if X = No_Rendezvous then
  5240.          --      Select
  5241.          --         Delay Delay_Min;
  5242.          --      then Abort
  5243.          --         Selective_Wait (Q, Simple_mode, P, X'Access);
  5244.          --      end select;
  5245.          --    end if;
  5246.          --
  5247.          --    if X = No_Rendezvous then
  5248.          --      case statement for delay statements.
  5249.          --    else
  5250.          --      case statement for accept alternatives.
  5251.          --    end if;
  5252.  
  5253.          declare
  5254.             First_Try : Node_Id;
  5255.             Asynch    : Node_Id;
  5256.             Cases     : Node_Id;
  5257.             Trigger   : Node_Id;
  5258.  
  5259.          begin
  5260.             Append_List (Delay_List, Stats);
  5261.  
  5262.             if Time_Type = Standard_Duration then
  5263.                Trigger :=
  5264.                  Make_Delay_Relative_Statement (Loc,
  5265.                    Expression => New_Reference_To (Delay_Min, Loc));
  5266.             else
  5267.                Trigger :=
  5268.                  Make_Delay_Until_Statement (Loc,
  5269.                    Expression => New_Reference_To (Delay_Min, Loc));
  5270.             end if;
  5271.  
  5272.             Asynch :=
  5273.               Make_Asynchronous_Select (Loc,
  5274.                 Triggering_Alternative =>
  5275.                   Make_Triggering_Alternative (Loc,
  5276.                     Triggering_Statement => Trigger,
  5277.                     Statements => New_List),
  5278.  
  5279.                 Abortable_Part =>
  5280.                   Make_Abortable_Part (Loc,
  5281.                     Statements =>  New_List (
  5282.                       Make_Select_Call (
  5283.                         New_Reference_To (RTE (RE_Simple_Mode), Loc)))));
  5284.  
  5285.             if Check_Guard then
  5286.                Asynch :=
  5287.                  Make_If_Statement (Loc,
  5288.                    Condition => New_Reference_To (Guard_Open, Loc),
  5289.                    Then_Statements => New_List (Asynch),
  5290.                    Else_Statements => New_List (
  5291.                      Make_Raise_Statement (Loc,
  5292.                        Name =>
  5293.                          New_Reference_To (Standard_Program_Error, Loc))));
  5294.             end if;
  5295.  
  5296.             First_Try :=
  5297.               Make_If_Statement (Loc,
  5298.                 Condition => Make_Op_Eq (Loc,
  5299.                   Left_Opnd  => New_Reference_To (Xnam, Loc),
  5300.                   Right_Opnd =>
  5301.                     New_Reference_To (RTE (RE_No_Rendezvous), Loc)),
  5302.                 Then_Statements => New_List (Asynch));
  5303.  
  5304.             Append (First_Try, Stats);
  5305.  
  5306.             Cases :=
  5307.               Make_If_Statement (Loc,
  5308.                 Condition => Make_Op_Eq (Loc,
  5309.                   Left_Opnd  => New_Reference_To (Xnam, Loc),
  5310.                   Right_Opnd =>
  5311.                     New_Reference_To (RTE (RE_No_Rendezvous), Loc)),
  5312.  
  5313.                 Then_Statements => Delay_Case,
  5314.                 Else_Statements => Accept_Case);
  5315.  
  5316.             Append (Cases, Stats);
  5317.          end;
  5318.       end if;
  5319.  
  5320.       --  Replace accept statement with appropriate block
  5321.  
  5322.       Block :=
  5323.         Make_Block_Statement (Loc,
  5324.           Declarations => Decls,
  5325.           Handled_Statement_Sequence =>
  5326.             Make_Handled_Sequence_Of_Statements (Loc,
  5327.               Statements => Stats));
  5328.  
  5329.       Rewrite_Substitute_Tree (N, Block);
  5330.       Analyze (N);
  5331.  
  5332.       --  Note: have to worry more about abort deferral in above code ???
  5333.  
  5334.       --  Final step is to unstack the Accept_Address entries for all accept
  5335.       --  statements appearing in accept alternatives in the select statement
  5336.  
  5337.       Alt := First (Alts);
  5338.       while Present (Alt) loop
  5339.          if Nkind (Alt) = N_Accept_Alternative then
  5340.             Remove_Last_Elmt (Accept_Address
  5341.               (Entity (Entry_Direct_Name (Accept_Statement (Alt)))));
  5342.          end if;
  5343.  
  5344.          Alt := Next (Alt);
  5345.       end loop;
  5346.  
  5347.    end Expand_N_Selective_Accept;
  5348.  
  5349.    --------------------------------------
  5350.    -- Expand_N_Single_Task_Declaration --
  5351.    --------------------------------------
  5352.  
  5353.    --  Single task declarations should never be present after semantic
  5354.    --  analysis, since we expect them to be replaced by a declaration of
  5355.    --  an anonymous task type, followed by a declaration of the task
  5356.    --  object. We include this routine to make sure that is happening!
  5357.  
  5358.    procedure Expand_N_Single_Task_Declaration (N : Node_Id) is
  5359.    begin
  5360.       pragma Assert (False); null;
  5361.    end Expand_N_Single_Task_Declaration;
  5362.  
  5363.    ------------------------
  5364.    -- Expand_N_Task_Body --
  5365.    ------------------------
  5366.  
  5367.    --  Given a task body
  5368.  
  5369.    --    task body tname is
  5370.    --       declarations
  5371.    --    begin
  5372.    --       statements
  5373.    --    end x;
  5374.  
  5375.    --  This expansion routine converts it into a procedure and sets the
  5376.    --  elaboration flag for the procedure to true, to represent the fact
  5377.    --  that the task body is now elaborated:
  5378.  
  5379.    --    procedure tnameB (_Task : access tnameV) is
  5380.    --       discriminal : dtype renames _Task.discriminant;
  5381.  
  5382.    --    begin
  5383.    --       System.Task_Stages.Complete_Activation;
  5384.    --       statements
  5385.    --    at end
  5386.    --       System.Task_Stages.Complete_Task;
  5387.    --    end tnameB;
  5388.  
  5389.    --    tnameE := True;
  5390.  
  5391.    --  In addition, if the task body is an activator, then a call to
  5392.    --  activate tasks is added at the start of the statements, before
  5393.    --  the call to Complete_Activation, and if in addition the task is
  5394.    --  a master then it must be established as a master. These calls are
  5395.    --  inserted and analyzed in Expand_Cleanup_Actions, when the
  5396.    --  Handled_Sequence_Of_Statements is expanded.
  5397.  
  5398.    --  There is one discriminal declaration line generated for each
  5399.    --  discriminant that is present to provide an easy reference point
  5400.    --  for discriminant references inside the body (see Exp_Ch2.Expand_Name).
  5401.  
  5402.    --  Note on relationship to GNARLI definition. In the GNARLI definition,
  5403.    --  task body procedures have a profile (Arg : System.Address). That is
  5404.    --  needed because GNARLI has to use the same access-to-subprogram type
  5405.    --  for all task types. We depend here on knowing that in GNAT, passing
  5406.    --  an address argument by value is identical to passing a a record value
  5407.    --  by access (in either case a single pointer is passed), so even though
  5408.    --  this procedure has the wrong profile. In fact it's all OK, since the
  5409.    --  callings sequence is identical.
  5410.  
  5411.    procedure Expand_N_Task_Body (N : Node_Id) is
  5412.       Loc  : constant Source_Ptr := Sloc (N);
  5413.       Ttyp : constant Entity_Id  := Corresponding_Spec (N);
  5414.       Call : Node_Id;
  5415.       Pend : Node_Id;
  5416.  
  5417.    begin
  5418.       Add_Discriminal_Declarations (Declarations (N), Ttyp, Name_uTask, Loc);
  5419.  
  5420.       --  The statement part has already been protected with an at_end and
  5421.       --  cleanup actions. The call to Complete_Activation must be placed
  5422.       --  at the head of the sequence of statements of that block. The
  5423.       --  declarations have been merged in this sequence of statements but
  5424.       --  the first real statement is accessible from the First_Real_Statement
  5425.       --  field (which was set for exactly this purpose)
  5426.  
  5427.       Call := Build_Runtime_Call (Loc, RE_Complete_Activation);
  5428.       Insert_Before
  5429.         (First_Real_Statement (Handled_Statement_Sequence (N)), Call);
  5430.       Analyze (Call);
  5431.  
  5432.       Rewrite_Substitute_Tree (N,
  5433.         Make_Subprogram_Body (Loc,
  5434.           Specification => Build_Task_Proc_Specification (Ttyp),
  5435.           Declarations  => Declarations (N),
  5436.           Handled_Statement_Sequence => Handled_Statement_Sequence (N)));
  5437.  
  5438.       Analyze (N);
  5439.  
  5440.       --  Set elaboration flag immediately after task body. If the body
  5441.       --  is a subunit, the flag is set in  the declarative part that
  5442.       --  contains the stub.
  5443.  
  5444.       if Nkind (Parent (N)) /= N_Subunit then
  5445.          Insert_After (N,
  5446.            Make_Assignment_Statement (Loc,
  5447.              Name =>
  5448.                Make_Identifier (Loc, New_External_Name (Chars (Ttyp), 'E')),
  5449.              Expression => New_Reference_To (Standard_True, Loc)));
  5450.       end if;
  5451.  
  5452.    end Expand_N_Task_Body;
  5453.  
  5454.    ------------------------------------
  5455.    -- Expand_N_Task_Type_Declaration --
  5456.    ------------------------------------
  5457.  
  5458.    --  We have several things to do. First we must create a Boolean flag used
  5459.    --  to mark if the body is elaborated yet. This variable gets set to True
  5460.    --  when the body of the task is elaborated (we can't rely on the normal
  5461.    --  ABE mechanism for the task body, since we need to pass an access to
  5462.    --  this elaboration boolean to the runtime routines).
  5463.  
  5464.    --    taskE : aliased Boolean := False;
  5465.  
  5466.    --  Next a variable is declared to hold the task stack size (either
  5467.    --  the default, which is the initial value given here, or a value that
  5468.    --  is set by a pragma Storage_Size appearing later on.
  5469.  
  5470.    --    taskZ : Size_Type := Unspecified_Size;
  5471.  
  5472.    --  Next we create a corresponding record type declaration used to represent
  5473.    --  values of this task. The general form of this type declaration is
  5474.  
  5475.    --    type taskV (discriminants) is record
  5476.    --      _Task_Id     : Task_Id;
  5477.    --      entry_family : array (bounds) of Void;
  5478.    --      _Priority    : Integer   := priority_expression;
  5479.    --      _Size        : Size_Type := Size_Type (size_expression);
  5480.    --    end record;
  5481.  
  5482.    --  The discriminants are present only if the corresponding task type has
  5483.    --  discriminants, and they exactly mirror the task type discriminants.
  5484.  
  5485.    --  The Id field is always present. It contains the Task_Id value, as
  5486.    --  set by the call to Create_Task. Note that although the task is
  5487.    --  limited, the task value record type is not limited, so there is no
  5488.    --  problem in passing this field as an out parameter to Create_Task.
  5489.  
  5490.    --  One entry_family component is present for each entry family in the
  5491.    --  task definition. The bounds correspond to the bounds of the entry
  5492.    --  family (which may depend on discriminants). The element type is
  5493.    --  void, since we only need the bounds information for determining
  5494.    --  the entry index. Note that the use of an anonymous array would
  5495.    --  normally be illegal in this context, but this is a parser check,
  5496.    --  and the semantics is quite prepared to handle such a case.
  5497.  
  5498.    --  The Size field is present only if a Storage_Size pragma appears in
  5499.    --  the task definition. The expression captures the argument that was
  5500.    --  present in the pragma, and is used to override the task stack size
  5501.    --  otherwise associated with the task type.
  5502.  
  5503.    --  The Priority field is present only if a Priority or Interrupt_Priority
  5504.    --  pragma appears in the task definition. The expression captures the
  5505.    --  argument that was present in the pragma, and is used to provide
  5506.    --  the Size parameter to the call to Create_Task.
  5507.  
  5508.    --  When a task is declared, an instance of the task value record is
  5509.    --  created. The elaboration of this declaration creates the correct
  5510.    --  bounds for the entry families, and also evaluates the size and
  5511.    --  priority expressions if needed. The initialization routine for
  5512.    --  the task type itself then calls Create_Task with appropriate
  5513.    --  parameters to initialize the value of the Task_Id field.
  5514.  
  5515.    --  Note: the address of this record is passed as the "Discriminants"
  5516.    --  parameter for Create_Task. Since Create_Task merely passes this onto
  5517.    --  the body procedure, it does not matter that it does not quite match
  5518.    --  the GNARLI model of what is being passed (the record contains more
  5519.    --  than just the discriminants, but the discriminants can be found from
  5520.    --  the record value).
  5521.  
  5522.    --  The Entity_Id for this created record type is placed in the
  5523.    --  Corresponding_Record_Type field of the associated task type entity.
  5524.  
  5525.    --  Next we create a procedure specification for the task body procedure:
  5526.  
  5527.    --    procedure taskB (_Task : access taskV);
  5528.  
  5529.    --  Note that this must come after the record type declaration, since
  5530.    --  the spec refers to this type. It turns out that the initialization
  5531.    --  procedure for the value type references the task body spec, but that's
  5532.    --  fine, since it won't be generated till the freeze point for the type,
  5533.    --  which is certainly after the task body spec declaration.
  5534.  
  5535.    --  Finally, we set the task index value field of the entry attribute in
  5536.    --  the case of a simple entry.
  5537.  
  5538.    procedure Expand_N_Task_Type_Declaration (N : Node_Id) is
  5539.       Loc       : constant Source_Ptr := Sloc (N);
  5540.       Tasktyp   : constant Entity_Id  := Etype (Defining_Identifier (N));
  5541.       Tasknm    : constant Name_Id    := Chars (Tasktyp);
  5542.       Taskdef   : constant Node_Id    := Task_Definition (N);
  5543.       Proc_Spec : Node_Id;
  5544.  
  5545.       Rec_Decl  : Node_Id   := Build_Corresponding_Record (N, Tasktyp, Loc);
  5546.       Rec_Ent   : Entity_Id := Defining_Identifier (Rec_Decl);
  5547.       Cdecls    : List_Id   := Component_Items (Component_List
  5548.                                  (Type_Definition (Rec_Decl)));
  5549.  
  5550.       Efam      : Entity_Id;
  5551.       Elab_Decl : Node_Id;
  5552.       Size_Decl : Node_Id;
  5553.       Body_Decl : Node_Id;
  5554.  
  5555.    begin
  5556.       --  First create the elaboration variable
  5557.  
  5558.       Elab_Decl :=
  5559.         Make_Object_Declaration (Loc,
  5560.           Defining_Identifier =>
  5561.             Make_Defining_Identifier (Loc, New_External_Name (Tasknm, 'E')),
  5562.           Aliased_Present      => True,
  5563.           Object_Definition    => New_Reference_To (Standard_Boolean, Loc),
  5564.           Expression           => New_Reference_To (Standard_False, Loc));
  5565.       Insert_After (N, Elab_Decl);
  5566.  
  5567.       --  Next create the declaration of the size variable (tasknmZ)
  5568.  
  5569.       Set_Storage_Size_Variable (Tasktyp,
  5570.         Make_Defining_Identifier (Loc, New_External_Name (Tasknm, 'Z')));
  5571.  
  5572.       Size_Decl :=
  5573.         Make_Object_Declaration (Loc,
  5574.           Defining_Identifier => Storage_Size_Variable (Tasktyp),
  5575.           Object_Definition => New_Reference_To (RTE (RE_Size_Type), Loc),
  5576.           Expression => New_Reference_To (RTE (RE_Unspecified_Size), Loc));
  5577.  
  5578.       Insert_After (Elab_Decl, Size_Decl);
  5579.  
  5580.       --  Next build the rest of the corresponding record declaration.
  5581.       --  This is done last, since the corresponding record initialization
  5582.       --  procedure will reference the previously created entities.
  5583.  
  5584.       --  Fill in the component declarations. First the _Task_Id field:
  5585.  
  5586.       Append_To (Cdecls,
  5587.         Make_Component_Declaration (Loc,
  5588.           Defining_Identifier =>
  5589.             Make_Defining_Identifier (Loc, Name_uTask_Id),
  5590.           Subtype_Indication => New_Reference_To (RTE (RE_Task_ID), Loc)));
  5591.  
  5592.       --  Add components for entry families
  5593.  
  5594.       Collect_Entry_Families (Loc, Cdecls, Size_Decl, Tasktyp);
  5595.  
  5596.       --  Add the priority component if a Priority pragma is present
  5597.  
  5598.       if Present (Taskdef) and then Has_Priority_Pragma (Taskdef) then
  5599.          Append_To (Cdecls,
  5600.            Make_Component_Declaration (Loc,
  5601.              Defining_Identifier =>
  5602.                Make_Defining_Identifier (Loc, Name_uPriority),
  5603.              Subtype_Indication => New_Reference_To (Standard_Integer, Loc),
  5604.              Expression => New_Copy (
  5605.                Expression (First (
  5606.                  Pragma_Argument_Associations (
  5607.                    Find_Task_Pragma (Taskdef, Name_Priority)))))));
  5608.       end if;
  5609.  
  5610.       --  Add the task_size component if a Storage_Size pragma is present
  5611.  
  5612.       if Present (Taskdef)
  5613.         and then Has_Storage_Size_Pragma (Taskdef)
  5614.       then
  5615.          Append_To (Cdecls,
  5616.            Make_Component_Declaration (Loc,
  5617.              Defining_Identifier =>
  5618.                Make_Defining_Identifier (Loc, Name_uSize),
  5619.  
  5620.              Subtype_Indication => New_Reference_To (RTE (RE_Size_Type), Loc),
  5621.  
  5622.              Expression =>
  5623.                Make_Type_Conversion (Loc,
  5624.                  Subtype_Mark => New_Reference_To (RTE (RE_Size_Type), Loc),
  5625.                  Expression => Relocate_Node (
  5626.                    Expression (First (
  5627.                      Pragma_Argument_Associations (
  5628.                        Find_Task_Pragma (Taskdef, Name_Storage_Size))))))));
  5629.       end if;
  5630.  
  5631.       Insert_After (Size_Decl, Rec_Decl);
  5632.  
  5633.       --  Analyze the record declaration immediately after construction,
  5634.       --  because the initialization procedure is needed for single task
  5635.       --  declarations before the next entity is analyzed.
  5636.  
  5637.       Analyze (Rec_Decl);
  5638.  
  5639.       --  Create the declaration of the task body procedure
  5640.  
  5641.       Proc_Spec := Build_Task_Proc_Specification (Tasktyp);
  5642.       Body_Decl :=
  5643.         Make_Subprogram_Declaration (Loc,
  5644.           Specification => Proc_Spec);
  5645.  
  5646.       Insert_After (Rec_Decl, Body_Decl);
  5647.  
  5648.       --  Now we can freeze the corresponding record. This needs manually
  5649.       --  freezing, since it is really part of the task type, and the task
  5650.       --  type is frozen at this stage. We of course need the initialization
  5651.       --  procedure for this corresponding record type and we won't get it
  5652.       --  in time if we don't freeze now.
  5653.  
  5654.       Insert_List_After (Body_Decl, Freeze_Entity (Rec_Ent, Loc));
  5655.  
  5656.       --  Complete the expansion of access types to the current task
  5657.       --  type, if any were declared.
  5658.  
  5659.       Expand_Previous_Access_Type (N, Tasktyp);
  5660.  
  5661.    end Expand_N_Task_Type_Declaration;
  5662.  
  5663.    -------------------------------
  5664.    -- Expand_N_Timed_Entry_Call --
  5665.    -------------------------------
  5666.  
  5667.    --  The timed entry call:
  5668.  
  5669.    --     select
  5670.    --        T.E;
  5671.    --        S1;
  5672.    --     or
  5673.    --        Delay D;
  5674.    --        S2;
  5675.    --     end select;
  5676.  
  5677.    --  is expanded into an asynchronous select:
  5678.  
  5679.    --    declare
  5680.    --       Timed_Out : Boolean := True;
  5681.    --    begin
  5682.    --       select
  5683.    --          T.E;
  5684.    --          Timed_Out := False;
  5685.    --          S1;
  5686.    --       then abort
  5687.    --          Delay D;
  5688.    --          S2;
  5689.    --       end select;
  5690.    --       if Timed_Out then
  5691.    --          S2;
  5692.    --       end if;
  5693.    --    end
  5694.  
  5695.    procedure Expand_N_Timed_Entry_Call (N : Node_Id) is
  5696.       Loc     : constant Source_Ptr := Sloc (N);
  5697.       E_Call  : constant Node_Id    := Entry_Call_Statement
  5698.                                            (Entry_Call_Alternative (N));
  5699.       E_Stats : constant List_Id    := Statements (Entry_Call_Alternative (N));
  5700.       D_Stat  : constant Node_Id    := Delay_Statement (Delay_Alternative (N));
  5701.       Stats   : constant List_Id    := Statements (Delay_Alternative (N));
  5702.  
  5703.       Asynch  : Node_Id;
  5704.       Blk     : Node_Id;
  5705.       T_Out   : Entity_Id := Make_Defining_Identifier
  5706.                                             (Loc, New_Internal_Name ('T'));
  5707.  
  5708.    begin
  5709.       Asynch :=
  5710.          Make_Asynchronous_Select (Loc,
  5711.            Triggering_Alternative =>
  5712.              Make_Triggering_Alternative (Loc,
  5713.                Triggering_Statement => E_Call,
  5714.                Statements => New_List (
  5715.                  Make_Assignment_Statement (Loc,
  5716.                    Name => New_Reference_To (T_Out, Loc),
  5717.                    Expression => New_Reference_To (Standard_False, Loc)))),
  5718.  
  5719.            Abortable_Part =>
  5720.              Make_Abortable_Part (Loc,
  5721.                Statements =>  New_List (D_Stat)));
  5722.  
  5723.       Append_List (E_Stats, Statements (Triggering_Alternative (Asynch)));
  5724.  
  5725.       Blk :=
  5726.         Make_Block_Statement (Loc,
  5727.           Declarations => New_List (
  5728.               Make_Object_Declaration (Loc,
  5729.                 Defining_Identifier => T_Out,
  5730.                 Object_Definition => New_Reference_To (Standard_Boolean, Loc),
  5731.                 Expression => New_Reference_To (Standard_True, Loc))),
  5732.  
  5733.            Handled_Statement_Sequence =>
  5734.              Make_Handled_Sequence_Of_Statements (Loc,
  5735.              Statements => New_List (
  5736.                  Asynch,
  5737.                  Make_If_Statement (Loc,
  5738.                    Condition => New_Reference_To (T_Out, Loc),
  5739.                    Then_Statements => Stats))));
  5740.  
  5741.       Rewrite_Substitute_Tree (N, Blk);
  5742.       Analyze (N);
  5743.  
  5744.    end Expand_N_Timed_Entry_Call;
  5745.  
  5746.    -------------------
  5747.    -- Extract_Entry --
  5748.    -------------------
  5749.  
  5750.    procedure Extract_Entry
  5751.      (N       : Node_Id;
  5752.       Concval : out Node_Id;
  5753.       Ename   : out Node_Id;
  5754.       Index   : out Node_Id)
  5755.    is
  5756.       Nam : constant Node_Id := Name (N);
  5757.  
  5758.    begin
  5759.       --  For a simple entry, the name is a selected component, with the
  5760.       --  prefix being the task value, and the selector being the entry.
  5761.  
  5762.       if Nkind (Nam) = N_Selected_Component then
  5763.          Concval := Prefix (Nam);
  5764.          Ename   := Selector_Name (Nam);
  5765.          Index   := Empty;
  5766.  
  5767.          --  For a member of an entry family, the name is an indexed
  5768.          --  component where the prefix is a selected component,
  5769.          --  whose prefix in turn is the task value, and whose
  5770.          --  selector is the entry family. The single expression in
  5771.          --  the expressions list of the indexed component is the
  5772.          --  subscript for the family.
  5773.  
  5774.       else
  5775.          pragma Assert (Nkind (Nam) = N_Indexed_Component);
  5776.          Concval := Prefix (Prefix (Nam));
  5777.          Ename   := Selector_Name (Prefix (Nam));
  5778.          Index   := First (Expressions (Nam));
  5779.       end if;
  5780.  
  5781.    end Extract_Entry;
  5782.  
  5783.    ----------------------
  5784.    -- Find_Task_Pragma --
  5785.    ----------------------
  5786.  
  5787.    function Find_Task_Pragma (T : Node_Id; P : Name_Id) return Node_Id is
  5788.       N : Node_Id;
  5789.  
  5790.    begin
  5791.       N := First (Visible_Declarations (T));
  5792.  
  5793.       while Present (N) loop
  5794.          if Nkind (N) = N_Pragma and then Chars (N) = P then
  5795.             return N;
  5796.          else
  5797.             N := Next (N);
  5798.          end if;
  5799.       end loop;
  5800.  
  5801.       N := First (Private_Declarations (T));
  5802.  
  5803.       while Present (N) loop
  5804.          if Nkind (N) = N_Pragma and then Chars (N) = P then
  5805.             return N;
  5806.          else
  5807.             N := Next (N);
  5808.          end if;
  5809.       end loop;
  5810.  
  5811.       pragma Assert (False);
  5812.    end Find_Task_Pragma;
  5813.  
  5814.    -------------------------------------
  5815.    -- Make_Initialize_Protection_Call --
  5816.    -------------------------------------
  5817.  
  5818.    function Make_Initialize_Protection_Call
  5819.      (Protect_Rec : Entity_Id)
  5820.       return        Node_Id
  5821.    is
  5822.       Loc    : constant Source_Ptr := Sloc (Protect_Rec);
  5823.       Pdef   : Node_Id;
  5824.       Pdec   : Node_Id;
  5825.       Ptyp   : Node_Id;
  5826.       Pnam   : Name_Id;
  5827.       Args   : List_Id;
  5828.  
  5829.    begin
  5830.       Ptyp := Corresponding_Concurrent_Type (Protect_Rec);
  5831.       Pnam := Chars (Ptyp);
  5832.  
  5833.       --  Get protected declaration. In the case of a task type declaration,
  5834.       --  this is simply the parent of the protected type entity.
  5835.       --  In the single protected object
  5836.       --  declaration, this parent will be the implicit type, and we can find
  5837.       --  the corresponding single protected object declaration by
  5838.       --  searching forward in the declaration list in the tree.
  5839.       --  ??? I am not sure that the test for N_Single_Protected_Declaration
  5840.       --      is needed here. Nodes of this type should have been removed
  5841.       --      during semantic analysis.
  5842.  
  5843.       Pdec := Parent (Ptyp);
  5844.  
  5845.       while Nkind (Pdec) /= N_Protected_Type_Declaration
  5846.         and then Nkind (Pdec) /= N_Single_Protected_Declaration
  5847.       loop
  5848.          Pdec := Next (Pdec);
  5849.       end loop;
  5850.  
  5851.       --  Now we can find the object definition from this declaration
  5852.  
  5853.       Pdef := Protected_Definition (Pdec);
  5854.  
  5855.       --  Build the parameter list for the call. Note that _Init is the name
  5856.       --  of the formal for the object to be initialized, which is the task
  5857.       --  value record itself.
  5858.  
  5859.       Args := New_List;
  5860.  
  5861.       --  Object parameter. This is a pointer to the object of type
  5862.       --  Protection used by the GNARL to control the protected object.
  5863.  
  5864.       Append_To (Args,
  5865.         Make_Attribute_Reference (Loc,
  5866.           Prefix =>
  5867.             Make_Selected_Component (Loc,
  5868.               Prefix => Make_Identifier (Loc, Name_uInit),
  5869.               Selector_Name => Make_Identifier (Loc, Name_uObject)),
  5870.           Attribute_Name => Name_Unchecked_Access));
  5871.  
  5872.       --  Priority parameter. Set to Unspecified_Priority unless there is a
  5873.       --  priority pragma, in which case we take the value from the pragma.
  5874.  
  5875.       if Present (Pdef)
  5876.         and then Has_Priority_Pragma (Pdef)
  5877.       then
  5878.          Append_To (Args,
  5879.            Make_Selected_Component (Loc,
  5880.              Prefix => Make_Identifier (Loc, Name_uInit),
  5881.              Selector_Name => Make_Identifier (Loc, Name_uPriority)));
  5882.  
  5883.       else
  5884.          Append_To (Args,
  5885.            New_Reference_To (RTE (RE_Unspecified_Priority), Loc));
  5886.       end if;
  5887.  
  5888.       --  Compiler_Info parameter. This parameter allows entry body
  5889.       --  procedures and barrier functions to be called from the runtime.
  5890.       --  It is a pointer to the record generated by the compiler to
  5891.       --  represent the protected object.
  5892.  
  5893.       Append_To (Args,
  5894.          Make_Attribute_Reference (Loc,
  5895.            Prefix => Make_Identifier (Loc, Name_uInit),
  5896.            Attribute_Name => Name_Address));
  5897.  
  5898.       --  Entry_Bodies parameter.  This is a pointer to an array of
  5899.       --  pointers to the entry body procedures and barrier functions
  5900.       --  of the object.  If the protected type has no entries this
  5901.       --  object will not exist; in this case, pass a null.
  5902.  
  5903.       if Has_Entries (Ptyp) then
  5904.          Append_To (Args,
  5905.            Make_Attribute_Reference (Loc,
  5906.              Prefix => New_Reference_To (Entry_Bodies_Array (Ptyp), Loc),
  5907.              Attribute_Name => Name_Unchecked_Access));
  5908.       else
  5909.          Append_To (Args, Make_Null (Loc));
  5910.       end if;
  5911.  
  5912.       return
  5913.         Make_Procedure_Call_Statement (Loc,
  5914.           Name => New_Reference_To (RTE (RE_Initialize_Protection), Loc),
  5915.           Parameter_Associations => Args);
  5916.  
  5917.    end Make_Initialize_Protection_Call;
  5918.  
  5919.    ---------------------------
  5920.    -- Make_Task_Create_Call --
  5921.    ---------------------------
  5922.  
  5923.    function Make_Task_Create_Call (Task_Rec : Entity_Id) return Node_Id is
  5924.       Loc    : constant Source_Ptr := Sloc (Task_Rec);
  5925.       Tdef   : Node_Id;
  5926.       Tdec   : Node_Id;
  5927.       Ttyp   : Node_Id;
  5928.       Tnam   : Name_Id;
  5929.       Args   : List_Id;
  5930.       Ecount : Node_Id;
  5931.  
  5932.    begin
  5933.       Ttyp := Corresponding_Concurrent_Type (Task_Rec);
  5934.       Tnam := Chars (Ttyp);
  5935.  
  5936.       --  Get task declaration. In the case of a task type declaration, this
  5937.       --  is simply the parent of the task type entity. In the single task
  5938.       --  declaration, this parent will be the implicit type, and we can find
  5939.       --  the corresponding single task declaration by searching forward in
  5940.       --  the declaration list in the tree.
  5941.       --  ??? I am not sure that the test for N_Single_Task_Declaration
  5942.       --      is needed here. Nodes of this type should have been removed
  5943.       --      during semantic analysis.
  5944.  
  5945.       Tdec := Parent (Ttyp);
  5946.  
  5947.       while Nkind (Tdec) /= N_Task_Type_Declaration
  5948.         and then Nkind (Tdec) /= N_Single_Task_Declaration
  5949.       loop
  5950.          Tdec := Next (Tdec);
  5951.       end loop;
  5952.  
  5953.       --  Now we can find the task definition from this declaration
  5954.  
  5955.       Tdef := Task_Definition (Tdec);
  5956.  
  5957.       --  Build the parameter list for the call. Note that _Init is the name
  5958.       --  of the formal for the object to be initialized, which is the task
  5959.       --  value record itself.
  5960.  
  5961.       Args := New_List;
  5962.  
  5963.       --  Size parameter. If no Storage_Size pragma is present, then
  5964.       --  the size is taken from the taskZ variable for the type, which
  5965.       --  is either Unspecified_Size, or has been reset by the use of
  5966.       --  a Storage_Size attribute definition clause. If a pragma is
  5967.       --  present, then the size is taken from the _Size field of the
  5968.       --  task value record, which was set from the pragma value.
  5969.  
  5970.       if Present (Tdef)
  5971.         and then Has_Storage_Size_Pragma (Tdef)
  5972.       then
  5973.          Append_To (Args,
  5974.            Make_Selected_Component (Loc,
  5975.              Prefix => Make_Identifier (Loc, Name_uInit),
  5976.              Selector_Name => Make_Identifier (Loc, Name_uSize)));
  5977.  
  5978.       else
  5979.          Append_To (Args,
  5980.            New_Reference_To (Storage_Size_Variable (Ttyp), Loc));
  5981.       end if;
  5982.  
  5983.       --  Priority parameter. Set to Unspecified_Priority unless there is a
  5984.       --  priority pragma, in which case we take the value from the pragma.
  5985.  
  5986.       if Present (Tdef)
  5987.         and then Has_Priority_Pragma (Tdef)
  5988.       then
  5989.          Append_To (Args,
  5990.            Make_Selected_Component (Loc,
  5991.              Prefix => Make_Identifier (Loc, Name_uInit),
  5992.              Selector_Name => Make_Identifier (Loc, Name_uPriority)));
  5993.  
  5994.       else
  5995.          Append_To (Args,
  5996.            New_Reference_To (RTE (RE_Unspecified_Priority), Loc));
  5997.       end if;
  5998.  
  5999.       --  Number of entries. This is an expression of the form:
  6000.       --
  6001.       --    n + _Init.a'Length + _Init.a'B'Length + ...
  6002.       --
  6003.       --  where a,b... are the entry family names for the task definition
  6004.  
  6005.       Ecount := Build_Entry_Count_Expression (
  6006.         Ttyp,
  6007.         Component_Items (Component_List (
  6008.           Type_Definition (Parent (
  6009.             Corresponding_Record_Type (Ttyp))))),
  6010.         Loc);
  6011.       Append_To (Args, Ecount);
  6012.  
  6013.       --  Master parameter. This is a reference to the _Master parameter of
  6014.       --  the initialization procedure.
  6015.  
  6016.       Append_To (Args, Make_Identifier (Loc, Name_uMaster));
  6017.  
  6018.       --  State parameter. This is a pointer to the task body procedure. The
  6019.       --  required value is obtained by taking the address of the task body
  6020.       --  procedure and converting it (with an unchecked conversion) to the
  6021.       --  type required by the task kernel. For further details, see the
  6022.       --  description of Expand_Task_Body
  6023.  
  6024.       Append_To (Args,
  6025.         Make_Unchecked_Type_Conversion (Loc,
  6026.           Subtype_Mark =>
  6027.             New_Reference_To (RTE (RE_Task_Procedure_Access), Loc),
  6028.  
  6029.           Expression =>
  6030.             Make_Attribute_Reference (Loc,
  6031.               Prefix => New_Occurrence_Of (Task_Body_Procedure (Ttyp), Loc),
  6032.               Attribute_Name => Name_Address)));
  6033.  
  6034.       --  Discriminants parameter. This is just the address of the task
  6035.       --  value record itself (which contains the discriminant values
  6036.  
  6037.       Append_To (Args,
  6038.         Make_Attribute_Reference (Loc,
  6039.           Prefix => Make_Identifier (Loc, Name_uInit),
  6040.           Attribute_Name => Name_Address));
  6041.  
  6042.       --  Elaborated parameter. This is an access to the elaboration Boolean
  6043.  
  6044.       Append_To (Args,
  6045.         Make_Attribute_Reference (Loc,
  6046.           Prefix => Make_Identifier (Loc, New_External_Name (Tnam, 'E')),
  6047.           Attribute_Name => Name_Unchecked_Access));
  6048.  
  6049.       --  Chain parameter. This is a reference to the _Chain parameter of
  6050.       --  the initialization procedure.
  6051.  
  6052.       Append_To (Args, Make_Identifier (Loc, Name_uChain));
  6053.  
  6054.       --  Created_Task parameter. This is the _Task_Id field of the task
  6055.       --  record value
  6056.  
  6057.       Append_To (Args,
  6058.         Make_Selected_Component (Loc,
  6059.           Prefix => Make_Identifier (Loc, Name_uInit),
  6060.           Selector_Name => Make_Identifier (Loc, Name_uTask_Id)));
  6061.  
  6062.       return
  6063.         Make_Procedure_Call_Statement (Loc,
  6064.           Name => New_Reference_To (RTE (RE_Create_Task), Loc),
  6065.           Parameter_Associations => Args);
  6066.  
  6067.    end Make_Task_Create_Call;
  6068.  
  6069.    ----------------------
  6070.    -- Set_Discriminals --
  6071.    ----------------------
  6072.  
  6073.    procedure Set_Discriminals
  6074.      (Dec : Node_Id;
  6075.       Op  : Node_Id;
  6076.       Loc : Source_Ptr)
  6077.    is
  6078.       D       : Entity_Id;
  6079.       Pdef    : Entity_Id;
  6080.       D_Minal : Entity_Id;
  6081.  
  6082.    begin
  6083.       pragma Assert (Nkind (Dec) = N_Protected_Type_Declaration);
  6084.       Pdef := Defining_Identifier (Dec);
  6085.  
  6086.       if Has_Discriminants (Pdef) then
  6087.          D := First_Discriminant (Pdef);
  6088.  
  6089.          while Present (D) loop
  6090.             D_Minal :=
  6091.               Make_Defining_Identifier (Loc,
  6092.                 Chars => New_External_Name (Chars (D), 'D'));
  6093.  
  6094.             Set_Ekind (D_Minal, E_Constant);
  6095.             Set_Etype (D_Minal, Etype (D));
  6096.             Set_Discriminal (D, D_Minal);
  6097.  
  6098.             D := Next_Discriminant (D);
  6099.          end loop;
  6100.       end if;
  6101.    end Set_Discriminals;
  6102.  
  6103.    -----------------
  6104.    -- Set_Privals --
  6105.    -----------------
  6106.  
  6107.    procedure Set_Privals
  6108.       (Dec : Node_Id;
  6109.        Op : Node_Id;
  6110.        Loc : Source_Ptr)
  6111.    is
  6112.       P         : Entity_Id;
  6113.       Priv      : Entity_Id;
  6114.       Def       : Node_Id;
  6115.       Body_Ent  : Entity_Id;
  6116.       Prec_Decl : constant Node_Id :=
  6117.                     Parent (Corresponding_Record_Type
  6118.                              (Defining_Identifier (Dec)));
  6119.       Prec_Def  : constant Entity_Id := Type_Definition (Prec_Decl);
  6120.       Obj_Decl  : Node_Id;
  6121.       P_Subtype : Entity_Id;
  6122.  
  6123.    begin
  6124.       pragma Assert (Nkind (Dec) = N_Protected_Type_Declaration);
  6125.       pragma Assert
  6126.         (Nkind (Op) = N_Subprogram_Body or else Nkind (Op) = N_Entry_Body);
  6127.       Def := Protected_Definition (Dec);
  6128.  
  6129.       if Present (Private_Declarations (Def)) then
  6130.  
  6131.          P := First (Private_Declarations (Def));
  6132.          while Present (P) loop
  6133.             if Nkind (P) = N_Component_Declaration then
  6134.                Priv :=
  6135.                  Make_Defining_Identifier (Loc,
  6136.                    New_External_Name
  6137.                      (Chars (Defining_Identifier (P)), 'P'));
  6138.  
  6139.                Set_Ekind (Priv, E_Variable);
  6140.                Set_Etype (Priv, Etype (Defining_Identifier (P)));
  6141.                Set_Protected_Operation (Defining_Identifier (P), Op);
  6142.                Set_Prival (Defining_Identifier (P), Priv);
  6143.             end if;
  6144.  
  6145.             P := Next (P);
  6146.          end loop;
  6147.       end if;
  6148.  
  6149.       --  There is one more implicit private declaration: the object
  6150.       --  itself. A "prival" for this is attached to the protected
  6151.       --  body defining identifier.
  6152.  
  6153.       Body_Ent := Corresponding_Body (Dec);
  6154.  
  6155.       Priv :=
  6156.         Make_Defining_Identifier (Loc,
  6157.           New_External_Name (Chars (Body_Ent), 'R'));
  6158.  
  6159.       --  Set the Etype to the implicit subtype of Protection created when
  6160.       --  the protected type declaration was expanded. This node will not
  6161.       --  be analyzed until it is used as the defining identifier for the
  6162.       --  renaming declaration in the protected operation body, and it will
  6163.       --  be needed in the references expanded before that body is expanded.
  6164.       --  Since the Protection field is aliased, set Is_Aliased as well.
  6165.  
  6166.       Obj_Decl := First (Component_Items (Component_List (Prec_Def)));
  6167.       while Chars (Defining_Identifier (Obj_Decl)) /= Name_uObject loop
  6168.          Obj_Decl := Next (Obj_Decl);
  6169.       end loop;
  6170.       P_Subtype  := Etype (Defining_Identifier (Obj_Decl));
  6171.       Set_Etype (Priv, P_Subtype);
  6172.       Set_Is_Aliased (Priv);
  6173.       Set_Object_Ref (Body_Ent, Priv);
  6174.  
  6175.    end Set_Privals;
  6176.  
  6177. end Exp_Ch9;
  6178.