------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              E X P _ C H 6                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2003, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
with Checks;   use Checks;
with Debug;    use Debug;
with Einfo;    use Einfo;
with Errout;   use Errout;
with Elists;   use Elists;
with Exp_Ch2;  use Exp_Ch2;
with Exp_Ch3;  use Exp_Ch3;
with Exp_Ch7;  use Exp_Ch7;
with Exp_Ch9;  use Exp_Ch9;
with Exp_Ch11; use Exp_Ch11;
with Exp_Dbug; use Exp_Dbug;
with Exp_Disp; use Exp_Disp;
with Exp_Dist; use Exp_Dist;
with Exp_Intr; use Exp_Intr;
with Exp_Pakd; use Exp_Pakd;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Fname;    use Fname;
with Freeze;   use Freeze;
with Hostparm; use Hostparm;
with Inline;   use Inline;
with Lib;      use Lib;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Restrict; use Restrict;
with Rtsfind;  use Rtsfind;
with Sem;      use Sem;
with Sem_Ch6;  use Sem_Ch6;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Stand;    use Stand;
with Tbuild;   use Tbuild;
with Ttypes;   use Ttypes;
with Uintp;    use Uintp;
with Validsw;  use Validsw;

package body Exp_Ch6 is

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Check_Overriding_Operation (Subp : Entity_Id);
   --  Subp is a dispatching operation. Check whether it may override an
   --  inherited private operation, in which case its DT entry is that of
   --  the hidden operation, not the one it may have received earlier.
   --  This must be done before emitting the code to set the corresponding
   --  DT to the address of the subprogram. The actual placement of Subp in
   --  the proper place in the list of primitive operations is done in
   --  Declare_Inherited_Private_Subprograms, which also has to deal with
   --  implicit operations. This duplication is unavoidable for now???

   procedure Detect_Infinite_Recursion (N : Node_Id; Spec : Entity_Id);
   --  This procedure is called only if the subprogram body N, whose spec
   --  has the given entity Spec, contains a parameterless recursive call.
   --  It attempts to generate runtime code to detect if this a case of
   --  infinite recursion.
   --
   --  The body is scanned to determine dependencies. If the only external
   --  dependencies are on a small set of scalar variables, then the values
   --  of these variables are captured on entry to the subprogram, and if
   --  the values are not changed for the call, we know immediately that
   --  we have an infinite recursion.

   procedure Expand_Actuals (N : Node_Id; Subp : Entity_Id);
   --  For each actual of an in-out parameter which is a numeric conversion
   --  of the form T(A), where A denotes a variable, we insert the declaration:
   --
   --    Temp : T := T (A);
   --
   --  prior to the call. Then we replace the actual with a reference to Temp,
   --  and append the assignment:
   --
   --    A := TypeA (Temp);
   --
   --  after the call. Here TypeA is the actual type of variable A.
   --  For out parameters, the initial declaration has no expression.
   --  If A is not an entity name, we generate instead:
   --
   --    Var  : TypeA renames A;
   --    Temp : T := Var;       --  omitting expression for out parameter.
   --    ...
   --    Var := TypeA (Temp);
   --
   --  For other in-out parameters, we emit the required constraint checks
   --  before and/or after the call.
   --
   --  For all parameter modes, actuals that denote components and slices
   --  of packed arrays are expanded into suitable temporaries.

   procedure Expand_Inlined_Call
    (N         : Node_Id;
     Subp      : Entity_Id;
     Orig_Subp : Entity_Id);
   --  If called subprogram can be inlined by the front-end, retrieve the
   --  analyzed body, replace formals with actuals and expand call in place.
   --  Generate thunks for actuals that are expressions, and insert the
   --  corresponding constant declarations before the call. If the original
   --  call is to a derived operation, the return type is the one of the
   --  derived operation, but the body is that of the original, so return
   --  expressions in the body must be converted to the desired type (which
   --  is simply not noted in the tree without inline expansion).

   function Expand_Protected_Object_Reference
     (N    : Node_Id;
      Scop : Entity_Id)
      return Node_Id;

   procedure Expand_Protected_Subprogram_Call
     (N    : Node_Id;
      Subp : Entity_Id;
      Scop : Entity_Id);
   --  A call to a protected subprogram within the protected object may appear
   --  as a regular call. The list of actuals must be expanded to contain a
   --  reference to the object itself, and the call becomes a call to the
   --  corresponding protected subprogram.

   --------------------------------
   -- Check_Overriding_Operation --
   --------------------------------

   procedure Check_Overriding_Operation (Subp : Entity_Id) is
      Typ     : constant Entity_Id := Find_Dispatching_Type (Subp);
      Op_List : constant Elist_Id  := Primitive_Operations (Typ);
      Op_Elmt : Elmt_Id;
      Prim_Op : Entity_Id;
      Par_Op  : Entity_Id;

   begin
      if Is_Derived_Type (Typ)
        and then not Is_Private_Type (Typ)
        and then In_Open_Scopes (Scope (Etype (Typ)))
        and then Typ = Base_Type (Typ)
      then
         --  Subp overrides an inherited private operation if there is
         --  an inherited operation with a different name than Subp (see
         --  Derive_Subprogram) whose Alias is a hidden  subprogram with
         --  the same name as Subp.

         Op_Elmt := First_Elmt (Op_List);
         while Present (Op_Elmt) loop
            Prim_Op := Node (Op_Elmt);
            Par_Op  := Alias (Prim_Op);

            if Present (Par_Op)
              and then not Comes_From_Source (Prim_Op)
              and then Chars (Prim_Op) /= Chars (Par_Op)
              and then Chars (Par_Op) = Chars (Subp)
              and then Is_Hidden (Par_Op)
              and then Type_Conformant (Prim_Op, Subp)
            then
               Set_DT_Position (Subp, DT_Position (Prim_Op));
            end if;

            Next_Elmt (Op_Elmt);
         end loop;
      end if;
   end Check_Overriding_Operation;

   -------------------------------
   -- Detect_Infinite_Recursion --
   -------------------------------

   procedure Detect_Infinite_Recursion (N : Node_Id; Spec : Entity_Id) is
      Loc : constant Source_Ptr := Sloc (N);

      Var_List : constant Elist_Id := New_Elmt_List;
      --  List of globals referenced by body of procedure

      Call_List : constant Elist_Id := New_Elmt_List;
      --  List of recursive calls in body of procedure

      Shad_List : constant Elist_Id := New_Elmt_List;
      --  List of entity id's for entities created to capture the
      --  value of referenced globals on entry to the procedure.

      Scop : constant Uint := Scope_Depth (Spec);
      --  This is used to record the scope depth of the current
      --  procedure, so that we can identify global references.

      Max_Vars : constant := 4;
      --  Do not test more than four global variables

      Count_Vars : Natural := 0;
      --  Count variables found so far

      Var  : Entity_Id;
      Elm  : Elmt_Id;
      Ent  : Entity_Id;
      Call : Elmt_Id;
      Decl : Node_Id;
      Test : Node_Id;
      Elm1 : Elmt_Id;
      Elm2 : Elmt_Id;
      Last : Node_Id;

      function Process (Nod : Node_Id) return Traverse_Result;
      --  Function to traverse the subprogram body (using Traverse_Func)

      -------------
      -- Process --
      -------------

      function Process (Nod : Node_Id) return Traverse_Result is
      begin
         --  Procedure call

         if Nkind (Nod) = N_Procedure_Call_Statement then

            --  Case of one of the detected recursive calls

            if Is_Entity_Name (Name (Nod))
              and then Has_Recursive_Call (Entity (Name (Nod)))
              and then Entity (Name (Nod)) = Spec
            then
               Append_Elmt (Nod, Call_List);
               return Skip;

            --  Any other procedure call may have side effects

            else
               return Abandon;
            end if;

         --  A call to a pure function can always be ignored

         elsif Nkind (Nod) = N_Function_Call
           and then Is_Entity_Name (Name (Nod))
           and then Is_Pure (Entity (Name (Nod)))
         then
            return Skip;

         --  Case of an identifier reference

         elsif Nkind (Nod) = N_Identifier then
            Ent := Entity (Nod);

            --  If no entity, then ignore the reference

            --  Not clear why this can happen. To investigate, remove this
            --  test and look at the crash that occurs here in 3401-004 ???

            if No (Ent) then
               return Skip;

            --  Ignore entities with no Scope, again not clear how this
            --  can happen, to investigate, look at 4108-008 ???

            elsif No (Scope (Ent)) then
               return Skip;

            --  Ignore the reference if not to a more global object

            elsif Scope_Depth (Scope (Ent)) >= Scop then
               return Skip;

            --  References to types, exceptions and constants are always OK

            elsif Is_Type (Ent)
              or else Ekind (Ent) = E_Exception
              or else Ekind (Ent) = E_Constant
            then
               return Skip;

            --  If other than a non-volatile scalar variable, we have some
            --  kind of global reference (e.g. to a function) that we cannot
            --  deal with so we forget the attempt.

            elsif Ekind (Ent) /= E_Variable
              or else not Is_Scalar_Type (Etype (Ent))
              or else Treat_As_Volatile (Ent)
            then
               return Abandon;

            --  Otherwise we have a reference to a global scalar

            else
               --  Loop through global entities already detected

               Elm := First_Elmt (Var_List);
               loop
                  --  If not detected before, record this new global reference

                  if No (Elm) then
                     Count_Vars := Count_Vars + 1;

                     if Count_Vars <= Max_Vars then
                        Append_Elmt (Entity (Nod), Var_List);
                     else
                        return Abandon;
                     end if;

                     exit;

                  --  If recorded before, ignore

                  elsif Node (Elm) = Entity (Nod) then
                     return Skip;

                  --  Otherwise keep looking

                  else
                     Next_Elmt (Elm);
                  end if;
               end loop;

               return Skip;
            end if;

         --  For all other node kinds, recursively visit syntactic children

         else
            return OK;
         end if;
      end Process;

      function Traverse_Body is new Traverse_Func;

   --  Start of processing for Detect_Infinite_Recursion

   begin
      --  Do not attempt detection in No_Implicit_Conditional mode,
      --  since we won't be able to generate the code to handle the
      --  recursion in any case.

      if Restrictions (No_Implicit_Conditionals) then
         return;
      end if;

      --  Otherwise do traversal and quit if we get abandon signal

      if Traverse_Body (N) = Abandon then
         return;

      --  We must have a call, since Has_Recursive_Call was set. If not
      --  just ignore (this is only an error check, so if we have a funny
      --  situation, due to bugs or errors, we do not want to bomb!)

      elsif Is_Empty_Elmt_List (Call_List) then
         return;
      end if;

      --  Here is the case where we detect recursion at compile time

      --  Push our current scope for analyzing the declarations and
      --  code that we will insert for the checking.

      New_Scope (Spec);

      --  This loop builds temporary variables for each of the
      --  referenced globals, so that at the end of the loop the
      --  list Shad_List contains these temporaries in one-to-one
      --  correspondence with the elements in Var_List.

      Last := Empty;
      Elm := First_Elmt (Var_List);
      while Present (Elm) loop
         Var := Node (Elm);
         Ent :=
           Make_Defining_Identifier (Loc,
             Chars => New_Internal_Name ('S'));
         Append_Elmt (Ent, Shad_List);

         --  Insert a declaration for this temporary at the start of
         --  the declarations for the procedure. The temporaries are
         --  declared as constant objects initialized to the current
         --  values of the corresponding temporaries.

         Decl :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Ent,
             Object_Definition   => New_Occurrence_Of (Etype (Var), Loc),
             Constant_Present    => True,
             Expression          => New_Occurrence_Of (Var, Loc));

         if No (Last) then
            Prepend (Decl, Declarations (N));
         else
            Insert_After (Last, Decl);
         end if;

         Last := Decl;
         Analyze (Decl);
         Next_Elmt (Elm);
      end loop;

      --  Loop through calls

      Call := First_Elmt (Call_List);
      while Present (Call) loop

         --  Build a predicate expression of the form

         --    True
         --      and then global1 = temp1
         --      and then global2 = temp2
         --      ...

         --  This predicate determines if any of the global values
         --  referenced by the procedure have changed since the
         --  current call, if not an infinite recursion is assured.

         Test := New_Occurrence_Of (Standard_True, Loc);

         Elm1 := First_Elmt (Var_List);
         Elm2 := First_Elmt (Shad_List);
         while Present (Elm1) loop
            Test :=
              Make_And_Then (Loc,
                Left_Opnd  => Test,
                Right_Opnd =>
                  Make_Op_Eq (Loc,
                    Left_Opnd  => New_Occurrence_Of (Node (Elm1), Loc),
                    Right_Opnd => New_Occurrence_Of (Node (Elm2), Loc)));

            Next_Elmt (Elm1);
            Next_Elmt (Elm2);
         end loop;

         --  Now we replace the call with the sequence

         --    if no-changes (see above) then
         --       raise Storage_Error;
         --    else
         --       original-call
         --    end if;

         Rewrite (Node (Call),
           Make_If_Statement (Loc,
             Condition       => Test,
             Then_Statements => New_List (
               Make_Raise_Storage_Error (Loc,
                 Reason => SE_Infinite_Recursion)),

             Else_Statements => New_List (
               Relocate_Node (Node (Call)))));

         Analyze (Node (Call));

         Next_Elmt (Call);
      end loop;

      --  Remove temporary scope stack entry used for analysis

      Pop_Scope;
   end Detect_Infinite_Recursion;

   --------------------
   -- Expand_Actuals --
   --------------------

   procedure Expand_Actuals (N : Node_Id; Subp : Entity_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Actual    : Node_Id;
      Formal    : Entity_Id;
      N_Node    : Node_Id;
      Post_Call : List_Id;
      E_Formal  : Entity_Id;

      procedure Add_Call_By_Copy_Code;
      --  For cases where the parameter must be passed by copy, this routine
      --  generates a temporary variable into which the actual is copied and
      --  then passes this as the parameter. For an OUT or IN OUT parameter,
      --  an assignment is also generated to copy the result back. The call
      --  also takes care of any constraint checks required for the type
      --  conversion case (on both the way in and the way out).

      procedure Add_Packed_Call_By_Copy_Code;
      --  This is used when the actual involves a reference to an element
      --  of a packed array, where we can appropriately use a simpler
      --  approach than the full call by copy code. We just copy the value
      --  in and out of an appropriate temporary.

      procedure Check_Fortran_Logical;
      --  A value of type Logical that is passed through a formal parameter
      --  must be normalized because .TRUE. usually does not have the same
      --  representation as True. We assume that .FALSE. = False = 0.
      --  What about functions that return a logical type ???

      function Make_Var (Actual : Node_Id) return Entity_Id;
      --  Returns an entity that refers to the given actual parameter,
      --  Actual (not including any type conversion). If Actual is an
      --  entity name, then this entity is returned unchanged, otherwise
      --  a renaming is created to provide an entity for the actual.

      procedure Reset_Packed_Prefix;
      --  The expansion of a packed array component reference is delayed in
      --  the context of a call. Now we need to complete the expansion, so we
      --  unmark the analyzed bits in all prefixes.

      ---------------------------
      -- Add_Call_By_Copy_Code --
      ---------------------------

      procedure Add_Call_By_Copy_Code is
         Expr    : Node_Id;
         Init    : Node_Id;
         Temp    : Entity_Id;
         Var     : Entity_Id;
         V_Typ   : Entity_Id;
         Crep    : Boolean;

      begin
         Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));

         if Nkind (Actual) = N_Type_Conversion then
            V_Typ := Etype (Expression (Actual));

            --  If the formal is an (in-)out parameter, capture the name
            --  of the variable in order to build the post-call assignment.

            Var := Make_Var (Expression (Actual));

            Crep := not Same_Representation
                          (Etype (Formal), Etype (Expression (Actual)));

         else
            V_Typ := Etype (Actual);
            Var   := Make_Var (Actual);
            Crep  := False;
         end if;

         --  Setup initialization for case of in out parameter, or an out
         --  parameter where the formal is an unconstrained array (in the
         --  latter case, we have to pass in an object with bounds).

         if Ekind (Formal) = E_In_Out_Parameter
           or else (Is_Array_Type (Etype (Formal))
                     and then
                    not Is_Constrained (Etype (Formal)))
         then
            if Nkind (Actual) = N_Type_Conversion then
               if Conversion_OK (Actual) then
                  Init := OK_Convert_To
                            (Etype (Formal), New_Occurrence_Of (Var, Loc));
               else
                  Init := Convert_To
                            (Etype (Formal), New_Occurrence_Of (Var, Loc));
               end if;
            else
               Init := New_Occurrence_Of (Var, Loc);
            end if;

         --  An initialization is created for packed conversions as
         --  actuals for out parameters to enable Make_Object_Declaration
         --  to determine the proper subtype for N_Node. Note that this
         --  is wasteful because the extra copying on the call side is
         --  not required for such out parameters. ???

         elsif Ekind (Formal) = E_Out_Parameter
           and then Nkind (Actual) = N_Type_Conversion
           and then (Is_Bit_Packed_Array (Etype (Formal))
                       or else
                     Is_Bit_Packed_Array (Etype (Expression (Actual))))
         then
            if Conversion_OK (Actual) then
               Init :=
                 OK_Convert_To (Etype (Formal), New_Occurrence_Of (Var, Loc));
            else
               Init :=
                 Convert_To (Etype (Formal), New_Occurrence_Of (Var, Loc));
            end if;
         else
            Init := Empty;
         end if;

         N_Node :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Object_Definition   =>
               New_Occurrence_Of (Etype (Formal), Loc),
             Expression => Init);
         Set_Assignment_OK (N_Node);
         Insert_Action (N, N_Node);

         --  Now, normally the deal here is that we use the defining
         --  identifier created by that object declaration. There is
         --  one exception to this. In the change of representation case
         --  the above declaration will end up looking like:

         --    temp : type := identifier;

         --  And in this case we might as well use the identifier directly
         --  and eliminate the temporary. Note that the analysis of the
         --  declaration was not a waste of time in that case, since it is
         --  what generated the necessary change of representation code. If
         --  the change of representation introduced additional code, as in
         --  a fixed-integer conversion, the expression is not an identifier
         --  and must be kept.

         if Crep
           and then Present (Expression (N_Node))
           and then Is_Entity_Name (Expression (N_Node))
         then
            Temp := Entity (Expression (N_Node));
            Rewrite (N_Node, Make_Null_Statement (Loc));
         end if;

         --  For IN parameter, all we do is to replace the actual

         if Ekind (Formal) = E_In_Parameter then
            Rewrite (Actual, New_Reference_To (Temp, Loc));
            Analyze (Actual);

         --  Processing for OUT or IN OUT parameter

         else
            --  If type conversion, use reverse conversion on exit

            if Nkind (Actual) = N_Type_Conversion then
               if Conversion_OK (Actual) then
                  Expr := OK_Convert_To (V_Typ, New_Occurrence_Of (Temp, Loc));
               else
                  Expr := Convert_To (V_Typ, New_Occurrence_Of (Temp, Loc));
               end if;
            else
               Expr := New_Occurrence_Of (Temp, Loc);
            end if;

            Rewrite (Actual, New_Reference_To (Temp, Loc));
            Analyze (Actual);

            Append_To (Post_Call,
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (Var, Loc),
                Expression => Expr));

            Set_Assignment_OK (Name (Last (Post_Call)));
         end if;
      end Add_Call_By_Copy_Code;

      ----------------------------------
      -- Add_Packed_Call_By_Copy_Code --
      ----------------------------------

      procedure Add_Packed_Call_By_Copy_Code is
         Temp   : Entity_Id;
         Incod  : Node_Id;
         Outcod : Node_Id;
         Lhs    : Node_Id;
         Rhs    : Node_Id;

      begin
         Reset_Packed_Prefix;

         --  Prepare to generate code

         Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
         Incod  := Relocate_Node (Actual);
         Outcod := New_Copy_Tree (Incod);

         --  Generate declaration of temporary variable, initializing it
         --  with the input parameter unless we have an OUT variable.

         if Ekind (Formal) = E_Out_Parameter then
            Incod := Empty;
         end if;

         Insert_Action (N,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
             Object_Definition   =>
               New_Occurrence_Of (Etype (Formal), Loc),
             Expression => Incod));

         --  The actual is simply a reference to the temporary

         Rewrite (Actual, New_Occurrence_Of (Temp, Loc));

         --  Generate copy out if OUT or IN OUT parameter

         if Ekind (Formal) /= E_In_Parameter then
            Lhs := Outcod;
            Rhs := New_Occurrence_Of (Temp, Loc);

            --  Deal with conversion

            if Nkind (Lhs) = N_Type_Conversion then
               Lhs := Expression (Lhs);
               Rhs := Convert_To (Etype (Actual), Rhs);
            end if;

            Append_To (Post_Call,
              Make_Assignment_Statement (Loc,
                Name       => Lhs,
                Expression => Rhs));
         end if;
      end Add_Packed_Call_By_Copy_Code;

      ---------------------------
      -- Check_Fortran_Logical --
      ---------------------------

      procedure Check_Fortran_Logical is
         Logical : constant Entity_Id := Etype (Formal);
         Var     : Entity_Id;

      --  Note: this is very incomplete, e.g. it does not handle arrays
      --  of logical values. This is really not the right approach at all???)

      begin
         if Convention (Subp) = Convention_Fortran
           and then Root_Type (Etype (Formal)) = Standard_Boolean
           and then Ekind (Formal) /= E_In_Parameter
         then
            Var := Make_Var (Actual);
            Append_To (Post_Call,
              Make_Assignment_Statement (Loc,
                Name => New_Occurrence_Of (Var, Loc),
                Expression =>
                  Unchecked_Convert_To (
                    Logical,
                    Make_Op_Ne (Loc,
                      Left_Opnd  => New_Occurrence_Of (Var, Loc),
                      Right_Opnd =>
                        Unchecked_Convert_To (
                          Logical,
                          New_Occurrence_Of (Standard_False, Loc))))));
         end if;
      end Check_Fortran_Logical;

      --------------
      -- Make_Var --
      --------------

      function Make_Var (Actual : Node_Id) return Entity_Id is
         Var : Entity_Id;

      begin
         if Is_Entity_Name (Actual) then
            return Entity (Actual);

         else
            Var := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));

            N_Node :=
              Make_Object_Renaming_Declaration (Loc,
                Defining_Identifier => Var,
                Subtype_Mark        =>
                  New_Occurrence_Of (Etype (Actual), Loc),
                Name                => Relocate_Node (Actual));

            Insert_Action (N, N_Node);
            return Var;
         end if;
      end Make_Var;

      -------------------------
      -- Reset_Packed_Prefix --
      -------------------------

      procedure Reset_Packed_Prefix is
         Pfx : Node_Id := Actual;

      begin
         loop
            Set_Analyzed (Pfx, False);
            exit when Nkind (Pfx) /= N_Selected_Component
              and then Nkind (Pfx) /= N_Indexed_Component;
            Pfx := Prefix (Pfx);
         end loop;
      end Reset_Packed_Prefix;

   --  Start of processing for Expand_Actuals

   begin
      Formal := First_Formal (Subp);
      Actual := First_Actual (N);

      Post_Call := New_List;

      while Present (Formal) loop
         E_Formal := Etype (Formal);

         if Is_Scalar_Type (E_Formal)
           or else Nkind (Actual) = N_Slice
         then
            Check_Fortran_Logical;

         --  RM 6.4.1 (11)

         elsif Ekind (Formal) /= E_Out_Parameter then

            --  The unusual case of the current instance of a protected type
            --  requires special handling. This can only occur in the context
            --  of a call within the body of a protected operation.

            if Is_Entity_Name (Actual)
              and then Ekind (Entity (Actual)) = E_Protected_Type
              and then In_Open_Scopes (Entity (Actual))
            then
               if Scope (Subp) /= Entity (Actual) then
                  Error_Msg_N ("operation outside protected type may not "
                    & "call back its protected operations?", Actual);
               end if;

               Rewrite (Actual,
                 Expand_Protected_Object_Reference (N, Entity (Actual)));
            end if;

            Apply_Constraint_Check (Actual, E_Formal);

         --  Out parameter case. No constraint checks on access type
         --  RM 6.4.1 (13)

         elsif Is_Access_Type (E_Formal) then
            null;

         --  RM 6.4.1 (14)

         elsif Has_Discriminants (Base_Type (E_Formal))
           or else Has_Non_Null_Base_Init_Proc (E_Formal)
         then
            Apply_Constraint_Check (Actual, E_Formal);

         --  RM 6.4.1 (15)

         else
            Apply_Constraint_Check (Actual, Base_Type (E_Formal));
         end if;

         --  Processing for IN-OUT and OUT parameters

         if Ekind (Formal) /= E_In_Parameter then

            --  For type conversions of arrays, apply length/range checks

            if Is_Array_Type (E_Formal)
              and then Nkind (Actual) = N_Type_Conversion
            then
               if Is_Constrained (E_Formal) then
                  Apply_Length_Check (Expression (Actual), E_Formal);
               else
                  Apply_Range_Check (Expression (Actual), E_Formal);
               end if;
            end if;

            --  If argument is a type conversion for a type that is passed
            --  by copy, then we must pass the parameter by copy.

            if Nkind (Actual) = N_Type_Conversion
              and then
                (Is_Numeric_Type (E_Formal)
                  or else Is_Access_Type (E_Formal)
                  or else Is_Enumeration_Type (E_Formal)
                  or else Is_Bit_Packed_Array (Etype (Formal))
                  or else Is_Bit_Packed_Array (Etype (Expression (Actual)))

                  --  Also pass by copy if change of representation

                  or else not Same_Representation
                               (Etype (Formal),
                                Etype (Expression (Actual))))
            then
               Add_Call_By_Copy_Code;

            --  References to components of bit packed arrays are expanded
            --  at this point, rather than at the point of analysis of the
            --  actuals, to handle the expansion of the assignment to
            --  [in] out parameters.

            elsif Is_Ref_To_Bit_Packed_Array (Actual) then
               Add_Packed_Call_By_Copy_Code;

            --  References to slices of bit packed arrays are expanded

            elsif Is_Ref_To_Bit_Packed_Slice (Actual) then
               Add_Call_By_Copy_Code;

            --  References to possibly unaligned slices of arrays are expanded

            elsif Is_Possibly_Unaligned_Slice (Actual) then
               Add_Call_By_Copy_Code;

            --  Deal with access types where the actual subtpe and the
            --  formal subtype are not the same, requiring a check.

            --  It is necessary to exclude tagged types because of "downward
            --  conversion" errors and a strange assertion error in namet
            --  from gnatf in bug 1215-001 ???

            elsif Is_Access_Type (E_Formal)
              and then not Same_Type (E_Formal, Etype (Actual))
              and then not Is_Tagged_Type (Designated_Type (E_Formal))
            then
               Add_Call_By_Copy_Code;

            elsif Is_Entity_Name (Actual)
              and then Treat_As_Volatile (Entity (Actual))
              and then not Is_Scalar_Type (Etype (Entity (Actual)))
              and then not Treat_As_Volatile (E_Formal)
            then
               Add_Call_By_Copy_Code;

            elsif Nkind (Actual) = N_Indexed_Component
              and then Is_Entity_Name (Prefix (Actual))
              and then Has_Volatile_Components (Entity (Prefix (Actual)))
            then
               Add_Call_By_Copy_Code;
            end if;

         --  Processing for IN parameters

         else
            --  For IN parameters is in the packed array case, we expand an
            --  indexed component (the circuit in Exp_Ch4 deliberately left
            --  indexed components appearing as actuals untouched, so that
            --  the special processing above for the OUT and IN OUT cases
            --  could be performed. We could make the test in Exp_Ch4 more
            --  complex and have it detect the parameter mode, but it is
            --  easier simply to handle all cases here.

            if Nkind (Actual) = N_Indexed_Component
              and then Is_Packed (Etype (Prefix (Actual)))
            then
               Reset_Packed_Prefix;
               Expand_Packed_Element_Reference (Actual);

            --  If we have a reference to a bit packed array, we copy it,
            --  since the actual must be byte aligned.

            --  Is this really necessary in all cases???

            elsif Is_Ref_To_Bit_Packed_Array (Actual) then
               Add_Packed_Call_By_Copy_Code;

            --  Similarly, we have to expand slices of packed arrays here
            --  because the result must be byte aligned.

            elsif Is_Ref_To_Bit_Packed_Slice (Actual) then
               Add_Call_By_Copy_Code;

            --  Only processing remaining is to pass by copy if this is a
            --  reference to a possibly unaligned slice, since the caller
            --  expects an appropriately aligned argument.

            elsif Is_Possibly_Unaligned_Slice (Actual) then
               Add_Call_By_Copy_Code;
            end if;
         end if;

         Next_Formal (Formal);
         Next_Actual (Actual);
      end loop;

      --  Find right place to put post call stuff if it is present

      if not Is_Empty_List (Post_Call) then

         --  If call is not a list member, it must be the triggering
         --  statement of a triggering alternative or an entry call
         --  alternative, and we can add the post call stuff to the
         --  corresponding statement list.

         if not Is_List_Member (N) then
            declare
               P : constant Node_Id := Parent (N);

            begin
               pragma Assert (Nkind (P) = N_Triggering_Alternative
                 or else Nkind (P) = N_Entry_Call_Alternative);

               if Is_Non_Empty_List (Statements (P)) then
                  Insert_List_Before_And_Analyze
                    (First (Statements (P)), Post_Call);
               else
                  Set_Statements (P, Post_Call);
               end if;
            end;

         --  Otherwise, normal case where N is in a statement sequence,
         --  just put the post-call stuff after the call statement.

         else
            Insert_Actions_After (N, Post_Call);
         end if;
      end if;

      --  The call node itself is re-analyzed in Expand_Call.

   end Expand_Actuals;

   -----------------
   -- Expand_Call --
   -----------------

   --  This procedure handles expansion of function calls and procedure call
   --  statements (i.e. it serves as the body for Expand_N_Function_Call and
   --  Expand_N_Procedure_Call_Statement. Processing for calls includes:

   --    Replace call to Raise_Exception by Raise_Exception always if possible
   --    Provide values of actuals for all formals in Extra_Formals list
   --    Replace "call" to enumeration literal function by literal itself
   --    Rewrite call to predefined operator as operator
   --    Replace actuals to in-out parameters that are numeric conversions,
   --     with explicit assignment to temporaries before and after the call.
   --    Remove optional actuals if First_Optional_Parameter specified.

   --   Note that the list of actuals has been filled with default expressions
   --   during semantic analysis of the call. Only the extra actuals required
   --   for the 'Constrained attribute and for accessibility checks are added
   --   at this point.

   procedure Expand_Call (N : Node_Id) is
      Loc           : constant Source_Ptr := Sloc (N);
      Remote        : constant Boolean    := Is_Remote_Call (N);
      Subp          : Entity_Id;
      Orig_Subp     : Entity_Id := Empty;
      Parent_Subp   : Entity_Id;
      Parent_Formal : Entity_Id;
      Actual        : Node_Id;
      Formal        : Entity_Id;
      Prev          : Node_Id := Empty;
      Prev_Orig     : Node_Id;
      Scop          : Entity_Id;
      Extra_Actuals : List_Id := No_List;
      Cond          : Node_Id;

      procedure Add_Actual_Parameter (Insert_Param : Node_Id);
      --  Adds one entry to the end of the actual parameter list. Used for
      --  default parameters and for extra actuals (for Extra_Formals).
      --  The argument is an N_Parameter_Association node.

      procedure Add_Extra_Actual (Expr : Node_Id; EF : Entity_Id);
      --  Adds an extra actual to the list of extra actuals. Expr
      --  is the expression for the value of the actual, EF is the
      --  entity for the extra formal.

      function Inherited_From_Formal (S : Entity_Id) return Entity_Id;
      --  Within an instance, a type derived from a non-tagged formal derived
      --  type inherits from the original parent, not from the actual. This is
      --  tested in 4723-003. The current derivation mechanism has the derived
      --  type inherit from the actual, which is only correct outside of the
      --  instance. If the subprogram is inherited, we test for this particular
      --  case through a convoluted tree traversal before setting the proper
      --  subprogram to be called.

      --------------------------
      -- Add_Actual_Parameter --
      --------------------------

      procedure Add_Actual_Parameter (Insert_Param : Node_Id) is
         Actual_Expr : constant Node_Id :=
                         Explicit_Actual_Parameter (Insert_Param);

      begin
         --  Case of insertion is first named actual

         if No (Prev) or else
            Nkind (Parent (Prev)) /= N_Parameter_Association
         then
            Set_Next_Named_Actual (Insert_Param, First_Named_Actual (N));
            Set_First_Named_Actual (N, Actual_Expr);

            if No (Prev) then
               if not Present (Parameter_Associations (N)) then
                  Set_Parameter_Associations (N, New_List);
                  Append (Insert_Param, Parameter_Associations (N));
               end if;
            else
               Insert_After (Prev, Insert_Param);
            end if;

         --  Case of insertion is not first named actual

         else
            Set_Next_Named_Actual
              (Insert_Param, Next_Named_Actual (Parent (Prev)));
            Set_Next_Named_Actual (Parent (Prev), Actual_Expr);
            Append (Insert_Param, Parameter_Associations (N));
         end if;

         Prev := Actual_Expr;
      end Add_Actual_Parameter;

      ----------------------
      -- Add_Extra_Actual --
      ----------------------

      procedure Add_Extra_Actual (Expr : Node_Id; EF : Entity_Id) is
         Loc : constant Source_Ptr := Sloc (Expr);

      begin
         if Extra_Actuals = No_List then
            Extra_Actuals := New_List;
            Set_Parent (Extra_Actuals, N);
         end if;

         Append_To (Extra_Actuals,
           Make_Parameter_Association (Loc,
             Explicit_Actual_Parameter => Expr,
             Selector_Name =>
               Make_Identifier (Loc, Chars (EF))));

         Analyze_And_Resolve (Expr, Etype (EF));
      end Add_Extra_Actual;

      ---------------------------
      -- Inherited_From_Formal --
      ---------------------------

      function Inherited_From_Formal (S : Entity_Id) return Entity_Id is
         Par      : Entity_Id;
         Gen_Par  : Entity_Id;
         Gen_Prim : Elist_Id;
         Elmt     : Elmt_Id;
         Indic    : Node_Id;

      begin
         --  If the operation is inherited, it is attached to the corresponding
         --  type derivation. If the parent in the derivation is a generic
         --  actual, it is a subtype of the actual, and we have to recover the
         --  original derived type declaration to find the proper parent.

         if Nkind (Parent (S)) /= N_Full_Type_Declaration
           or else not Is_Derived_Type (Defining_Identifier (Parent (S)))
           or else Nkind (Type_Definition (Original_Node (Parent (S))))
             /= N_Derived_Type_Definition
           or else not In_Instance
         then
            return Empty;

         else
            Indic :=
              (Subtype_Indication
                (Type_Definition (Original_Node (Parent (S)))));

            if Nkind (Indic) = N_Subtype_Indication then
               Par := Entity (Subtype_Mark (Indic));
            else
               Par := Entity (Indic);
            end if;
         end if;

         if not Is_Generic_Actual_Type (Par)
           or else Is_Tagged_Type (Par)
           or else Nkind (Parent (Par)) /= N_Subtype_Declaration
           or else not In_Open_Scopes (Scope (Par))
         then
            return Empty;

         else
            Gen_Par := Generic_Parent_Type (Parent (Par));
         end if;

         --  If the generic parent type is still the generic type, this
         --  is a private formal, not a derived formal, and there are no
         --  operations inherited from the formal.

         if Nkind (Parent (Gen_Par)) = N_Formal_Type_Declaration then
            return Empty;
         end if;

         Gen_Prim := Collect_Primitive_Operations (Gen_Par);
         Elmt := First_Elmt (Gen_Prim);

         while Present (Elmt) loop
            if Chars (Node (Elmt)) = Chars (S) then
               declare
                  F1 : Entity_Id;
                  F2 : Entity_Id;
               begin

                  F1 := First_Formal (S);
                  F2 := First_Formal (Node (Elmt));

                  while Present (F1)
                    and then Present (F2)
                  loop

                     if Etype (F1) = Etype (F2)
                       or else Etype (F2) = Gen_Par
                     then
                        Next_Formal (F1);
                        Next_Formal (F2);
                     else
                        Next_Elmt (Elmt);
                        exit;   --  not the right subprogram
                     end if;

                     return Node (Elmt);
                  end loop;
               end;

            else
               Next_Elmt (Elmt);
            end if;
         end loop;

         raise Program_Error;
      end Inherited_From_Formal;

   --  Start of processing for Expand_Call

   begin
      --  Ignore if previous error

      if Nkind (N) in N_Has_Etype and then Etype (N) = Any_Type then
         return;
      end if;

      --  Call using access to subprogram with explicit dereference

      if Nkind (Name (N)) = N_Explicit_Dereference then
         Subp        := Etype (Name (N));
         Parent_Subp := Empty;

      --  Case of call to simple entry, where the Name is a selected component
      --  whose prefix is the task, and whose selector name is the entry name

      elsif Nkind (Name (N)) = N_Selected_Component then
         Subp        := Entity (Selector_Name (Name (N)));
         Parent_Subp := Empty;

      --  Case of call to member of entry family, where Name is an indexed
      --  component, with the prefix being a selected component giving the
      --  task and entry family name, and the index being the entry index.

      elsif Nkind (Name (N)) = N_Indexed_Component then
         Subp        := Entity (Selector_Name (Prefix (Name (N))));
         Parent_Subp := Empty;

      --  Normal case

      else
         Subp        := Entity (Name (N));
         Parent_Subp := Alias (Subp);

         --  Replace call to Raise_Exception by call to Raise_Exception_Always
         --  if we can tell that the first parameter cannot possibly be null.
         --  This helps optimization and also generation of warnings.

         if not Restrictions (No_Exception_Handlers)
           and then Is_RTE (Subp, RE_Raise_Exception)
         then
            declare
               FA : constant Node_Id := Original_Node (First_Actual (N));

            begin
               --  The case we catch is where the first argument is obtained
               --  using the Identity attribute (which must always be non-null)

               if Nkind (FA) = N_Attribute_Reference
                 and then Attribute_Name (FA) = Name_Identity
               then
                  Subp := RTE (RE_Raise_Exception_Always);
                  Set_Entity (Name (N), Subp);
               end if;
            end;
         end if;

         if Ekind (Subp) = E_Entry then
            Parent_Subp := Empty;
         end if;
      end if;

      --  First step, compute extra actuals, corresponding to any
      --  Extra_Formals present. Note that we do not access Extra_Formals
      --  directly, instead we simply note the presence of the extra
      --  formals as we process the regular formals and collect the
      --  corresponding actuals in Extra_Actuals.

      --  We also generate any required range checks for actuals as we go
      --  through the loop, since this is a convenient place to do this.

      Formal := First_Formal (Subp);
      Actual := First_Actual (N);
      while Present (Formal) loop

         --  Generate range check if required (not activated yet ???)

--         if Do_Range_Check (Actual) then
--            Set_Do_Range_Check (Actual, False);
--            Generate_Range_Check
--              (Actual, Etype (Formal), CE_Range_Check_Failed);
--         end if;

         --  Prepare to examine current entry

         Prev := Actual;
         Prev_Orig := Original_Node (Prev);

         --  Create possible extra actual for constrained case. Usually,
         --  the extra actual is of the form actual'constrained, but since
         --  this attribute is only available for unconstrained records,
         --  TRUE is expanded if the type of the formal happens to be
         --  constrained (for instance when this procedure is inherited
         --  from an unconstrained record to a constrained one) or if the
         --  actual has no discriminant (its type is constrained). An
         --  exception to this is the case of a private type without
         --  discriminants. In this case we pass FALSE because the
         --  object has underlying discriminants with defaults.

         if Present (Extra_Constrained (Formal)) then
            if Ekind (Etype (Prev)) in Private_Kind
              and then not Has_Discriminants (Base_Type (Etype (Prev)))
            then
               Add_Extra_Actual (
                 New_Occurrence_Of (Standard_False, Loc),
                 Extra_Constrained (Formal));

            elsif Is_Constrained (Etype (Formal))
              or else not Has_Discriminants (Etype (Prev))
            then
               Add_Extra_Actual (
                 New_Occurrence_Of (Standard_True, Loc),
                 Extra_Constrained (Formal));

            else
               --  If the actual is a type conversion, then the constrained
               --  test applies to the actual, not the target type.

               declare
                  Act_Prev : Node_Id := Prev;

               begin
                  --  Test for unchecked conversions as well, which can
                  --  occur as out parameter actuals on calls to stream
                  --  procedures.

                  while Nkind (Act_Prev) = N_Type_Conversion
                    or else Nkind (Act_Prev) = N_Unchecked_Type_Conversion
                  loop
                     Act_Prev := Expression (Act_Prev);
                  end loop;

                  Add_Extra_Actual (
                    Make_Attribute_Reference (Sloc (Prev),
                      Prefix =>
                        Duplicate_Subexpr_No_Checks
                          (Act_Prev, Name_Req => True),
                      Attribute_Name => Name_Constrained),
                    Extra_Constrained (Formal));
               end;
            end if;
         end if;

         --  Create possible extra actual for accessibility level

         if Present (Extra_Accessibility (Formal)) then
            if Is_Entity_Name (Prev_Orig) then

               --  When passing an access parameter as the actual to another
               --  access parameter we need to pass along the actual's own
               --  associated access level parameter. This is done is we are
               --  in the scope of the formal access parameter (if this is an
               --  inlined body the extra formal is irrelevant).

               if Ekind (Entity (Prev_Orig)) in Formal_Kind
                 and then Ekind (Etype (Prev_Orig)) = E_Anonymous_Access_Type
                 and then In_Open_Scopes (Scope (Entity (Prev_Orig)))
               then
                  declare
                     Parm_Ent : constant Entity_Id := Param_Entity (Prev_Orig);

                  begin
                     pragma Assert (Present (Parm_Ent));

                     if Present (Extra_Accessibility (Parm_Ent)) then
                        Add_Extra_Actual (
                          New_Occurrence_Of
                            (Extra_Accessibility (Parm_Ent), Loc),
                          Extra_Accessibility (Formal));

                     --  If the actual access parameter does not have an
                     --  associated extra formal providing its scope level,
                     --  then treat the actual as having library-level
                     --  accessibility.

                     else
                        Add_Extra_Actual (
                          Make_Integer_Literal (Loc,
                            Intval => Scope_Depth (Standard_Standard)),
                          Extra_Accessibility (Formal));
                     end if;
                  end;

               --  The actual is a normal access value, so just pass the
               --  level of the actual's access type.

               else
                  Add_Extra_Actual (
                    Make_Integer_Literal (Loc,
                      Intval => Type_Access_Level (Etype (Prev_Orig))),
                    Extra_Accessibility (Formal));
               end if;

            else
               case Nkind (Prev_Orig) is

                  when N_Attribute_Reference =>

                     case Get_Attribute_Id (Attribute_Name (Prev_Orig)) is

                        --  For X'Access, pass on the level of the prefix X

                        when Attribute_Access =>
                           Add_Extra_Actual (
                             Make_Integer_Literal (Loc,
                               Intval =>
                                 Object_Access_Level (Prefix (Prev_Orig))),
                             Extra_Accessibility (Formal));

                        --  Treat the unchecked attributes as library-level

                        when Attribute_Unchecked_Access |
                           Attribute_Unrestricted_Access =>
                           Add_Extra_Actual (
                             Make_Integer_Literal (Loc,
                               Intval => Scope_Depth (Standard_Standard)),
                             Extra_Accessibility (Formal));

                        --  No other cases of attributes returning access
                        --  values that can be passed to access parameters

                        when others =>
                           raise Program_Error;

                     end case;

                  --  For allocators we pass the level of the execution of
                  --  the called subprogram, which is one greater than the
                  --  current scope level.

                  when N_Allocator =>
                     Add_Extra_Actual (
                       Make_Integer_Literal (Loc,
                        Scope_Depth (Current_Scope) + 1),
                       Extra_Accessibility (Formal));

                  --  For other cases we simply pass the level of the
                  --  actual's access type.

                  when others =>
                     Add_Extra_Actual (
                       Make_Integer_Literal (Loc,
                         Intval => Type_Access_Level (Etype (Prev_Orig))),
                       Extra_Accessibility (Formal));

               end case;
            end if;
         end if;

         --  Perform the check of 4.6(49) that prevents a null value
         --  from being passed as an actual to an access parameter.
         --  Note that the check is elided in the common cases of
         --  passing an access attribute or access parameter as an
         --  actual. Also, we currently don't enforce this check for
         --  expander-generated actuals and when -gnatdj is set.

         if Ekind (Etype (Formal)) /= E_Anonymous_Access_Type
           or else Access_Checks_Suppressed (Subp)
         then
            null;

         elsif Debug_Flag_J then
            null;

         elsif not Comes_From_Source (Prev) then
            null;

         elsif Is_Entity_Name (Prev)
           and then Ekind (Etype (Prev)) = E_Anonymous_Access_Type
         then
            null;

         elsif Nkind (Prev) = N_Allocator
           or else Nkind (Prev) = N_Attribute_Reference
         then
            null;

         --  Suppress null checks when passing to access parameters
         --  of Java subprograms. (Should this be done for other
         --  foreign conventions as well ???)

         elsif Convention (Subp) = Convention_Java then
            null;

         else
            Cond :=
              Make_Op_Eq (Loc,
                Left_Opnd => Duplicate_Subexpr_No_Checks (Prev),
                Right_Opnd => Make_Null (Loc));
            Insert_Action (Prev,
              Make_Raise_Constraint_Error (Loc,
                Condition => Cond,
                Reason    => CE_Access_Parameter_Is_Null));
         end if;

         --  Perform appropriate validity checks on parameters that
         --  are entities.

         if Validity_Checks_On then
            if Ekind (Formal) = E_In_Parameter
              and then Validity_Check_In_Params
            then
               --  If the actual is an indexed component of a packed
               --  type, it has not been expanded yet. It will be
               --  copied in the validity code that follows, and has
               --  to be expanded appropriately, so reanalyze it.

               if Nkind (Actual) = N_Indexed_Component then
                  Set_Analyzed (Actual, False);
               end if;

               Ensure_Valid (Actual);

            elsif Ekind (Formal) = E_In_Out_Parameter
              and then Validity_Check_In_Out_Params
            then
               Ensure_Valid (Actual);
            end if;
         end if;

         --  For IN OUT and OUT parameters, ensure that subscripts are valid
         --  since this is a left side reference. We only do this for calls
         --  from the source program since we assume that compiler generated
         --  calls explicitly generate any required checks. We also need it
         --  only if we are doing standard validity checks, since clearly it
         --  is not needed if validity checks are off, and in subscript
         --  validity checking mode, all indexed components are checked with
         --  a call directly from Expand_N_Indexed_Component.

         if Comes_From_Source (N)
           and then Ekind (Formal) /= E_In_Parameter
           and then Validity_Checks_On
           and then Validity_Check_Default
           and then not Validity_Check_Subscripts
         then
            Check_Valid_Lvalue_Subscripts (Actual);
         end if;

         --  Mark any scalar OUT parameter that is a simple variable
         --  as no longer known to be valid (unless the type is always
         --  valid). This reflects the fact that if an OUT parameter
         --  is never set in a procedure, then it can become invalid
         --  on return from the procedure.

         if Ekind (Formal) = E_Out_Parameter
           and then Is_Entity_Name (Actual)
           and then Ekind (Entity (Actual)) = E_Variable
           and then not Is_Known_Valid (Etype (Actual))
         then
            Set_Is_Known_Valid (Entity (Actual), False);
         end if;

         --  For an OUT or IN OUT parameter of an access type, if the
         --  actual is an entity, then it is no longer known to be non-null.

         if Ekind (Formal) /= E_In_Parameter
           and then Is_Entity_Name (Actual)
           and then Is_Access_Type (Etype (Actual))
         then
            Set_Is_Known_Non_Null (Entity (Actual), False);
         end if;

         --  If the formal is class wide and the actual is an aggregate, force
         --  evaluation so that the back end who does not know about class-wide
         --  type, does not generate a temporary of the wrong size.

         if not Is_Class_Wide_Type (Etype (Formal)) then
            null;

         elsif Nkind (Actual) = N_Aggregate
           or else (Nkind (Actual) = N_Qualified_Expression
                     and then Nkind (Expression (Actual)) = N_Aggregate)
         then
            Force_Evaluation (Actual);
         end if;

         --  In a remote call, if the formal is of a class-wide type, check
         --  that the actual meets the requirements described in E.4(18).

         if Remote
           and then Is_Class_Wide_Type (Etype (Formal))
         then
            Insert_Action (Actual,
              Make_Implicit_If_Statement (N,
                Condition       =>
                  Make_Op_Not (Loc,
                    Get_Remotely_Callable
                      (Duplicate_Subexpr_Move_Checks (Actual))),
                Then_Statements => New_List (
                  Make_Procedure_Call_Statement (Loc,
                    New_Occurrence_Of (RTE
                      (RE_Raise_Program_Error_For_E_4_18), Loc)))));
         end if;

         Next_Actual (Actual);
         Next_Formal (Formal);
      end loop;

      --  If we are expanding a rhs of an assignement we need to check if
      --  tag propagation is needed. This code belongs theorically in Analyze
      --  Assignment but has to be done earlier (bottom-up) because the
      --  assignment might be transformed into a declaration for an uncons-
      --  trained value, if the expression is classwide.

      if Nkind (N) = N_Function_Call
        and then Is_Tag_Indeterminate (N)
        and then Is_Entity_Name (Name (N))
      then
         declare
            Ass : Node_Id := Empty;

         begin
            if Nkind (Parent (N)) = N_Assignment_Statement then
               Ass := Parent (N);

            elsif Nkind (Parent (N)) = N_Qualified_Expression
              and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
            then
               Ass := Parent (Parent (N));
            end if;

            if Present (Ass)
              and then Is_Class_Wide_Type (Etype (Name (Ass)))
            then
               if Etype (N) /= Root_Type (Etype (Name (Ass))) then
                  Error_Msg_NE
                    ("tag-indeterminate expression must have type&"
                      & "('R'M 5.2 (6))", N, Root_Type (Etype (Name (Ass))));
               else
                  Propagate_Tag (Name (Ass), N);
               end if;

               --  The call will be rewritten as a dispatching call, and
               --  expanded as such.

               return;
            end if;
         end;
      end if;

      --  Deals with Dispatch_Call if we still have a call, before expanding
      --  extra actuals since this will be done on the re-analysis of the
      --  dispatching call. Note that we do not try to shorten the actual
      --  list for a dispatching call, it would not make sense to do so.
      --  Expansion of dispatching calls is suppressed when Java_VM, because
      --  the JVM back end directly handles the generation of dispatching
      --  calls and would have to undo any expansion to an indirect call.

      if (Nkind (N) = N_Function_Call
           or else Nkind (N) =  N_Procedure_Call_Statement)
        and then Present (Controlling_Argument (N))
        and then not Java_VM
      then
         Expand_Dispatch_Call (N);

         --  The following return is worrisome. Is it really OK to
         --  skip all remaining processing in this procedure ???

         return;

      --  Similarly, expand calls to RCI subprograms on which pragma
      --  All_Calls_Remote applies. The rewriting will be reanalyzed
      --  later. Do this only when the call comes from source since we do
      --  not want such a rewritting to occur in expanded code.

      elsif Is_All_Remote_Call (N) then
         Expand_All_Calls_Remote_Subprogram_Call (N);

      --  Similarly, do not add extra actuals for an entry call whose entity
      --  is a protected procedure, or for an internal protected subprogram
      --  call, because it will be rewritten as a protected subprogram call
      --  and reanalyzed (see Expand_Protected_Subprogram_Call).

      elsif Is_Protected_Type (Scope (Subp))
         and then (Ekind (Subp) = E_Procedure
                    or else Ekind (Subp) = E_Function)
      then
         null;

      --  During that loop we gathered the extra actuals (the ones that
      --  correspond to Extra_Formals), so now they can be appended.

      else
         while Is_Non_Empty_List (Extra_Actuals) loop
            Add_Actual_Parameter (Remove_Head (Extra_Actuals));
         end loop;
      end if;

      if Ekind (Subp) = E_Procedure
         or else (Ekind (Subp) = E_Subprogram_Type
                   and then Etype (Subp) = Standard_Void_Type)
         or else Is_Entry (Subp)
      then
         Expand_Actuals (N, Subp);
      end if;

      --  If the subprogram is a renaming, or if it is inherited, replace it
      --  in the call with the name of the actual subprogram being called.
      --  If this is a dispatching call, the run-time decides what to call.
      --  The Alias attribute does not apply to entries.

      if Nkind (N) /= N_Entry_Call_Statement
        and then No (Controlling_Argument (N))
        and then Present (Parent_Subp)
      then
         if Present (Inherited_From_Formal (Subp)) then
            Parent_Subp := Inherited_From_Formal (Subp);
         else
            while Present (Alias (Parent_Subp)) loop
               Parent_Subp := Alias (Parent_Subp);
            end loop;
         end if;

         Set_Entity (Name (N), Parent_Subp);

         if Is_Abstract (Parent_Subp)
           and then not In_Instance
         then
            Error_Msg_NE
              ("cannot call abstract subprogram &!", Name (N), Parent_Subp);
         end if;

         --  Add an explicit conversion for parameter of the derived type.
         --  This is only done for scalar and access in-parameters. Others
         --  have been expanded in expand_actuals.

         Formal := First_Formal (Subp);
         Parent_Formal := First_Formal (Parent_Subp);
         Actual := First_Actual (N);

         --  It is not clear that conversion is needed for intrinsic
         --  subprograms, but it certainly is for those that are user-
         --  defined, and that can be inherited on derivation, namely
         --  unchecked conversion and deallocation.
         --  General case needs study ???

         if not Is_Intrinsic_Subprogram (Parent_Subp)
           or else Is_Generic_Instance (Parent_Subp)
         then
            while Present (Formal) loop

               if Etype (Formal) /= Etype (Parent_Formal)
                 and then Is_Scalar_Type (Etype (Formal))
                 and then Ekind (Formal) = E_In_Parameter
                 and then not Raises_Constraint_Error (Actual)
               then
                  Rewrite (Actual,
                    OK_Convert_To (Etype (Parent_Formal),
                      Relocate_Node (Actual)));

                  Analyze (Actual);
                  Resolve (Actual, Etype (Parent_Formal));
                  Enable_Range_Check (Actual);

               elsif Is_Access_Type (Etype (Formal))
                 and then Base_Type (Etype (Parent_Formal))
                   /= Base_Type (Etype (Actual))
               then
                  if Ekind (Formal) /= E_In_Parameter then
                     Rewrite (Actual,
                       Convert_To (Etype (Parent_Formal),
                         Relocate_Node (Actual)));

                     Analyze (Actual);
                     Resolve (Actual, Etype (Parent_Formal));

                  elsif
                    Ekind (Etype (Parent_Formal)) = E_Anonymous_Access_Type
                      and then Designated_Type (Etype (Parent_Formal))
                                 /=
                               Designated_Type (Etype (Actual))
                      and then not Is_Controlling_Formal (Formal)
                  then
                     --  This unchecked conversion is not necessary unless
                     --  inlining is enabled, because in that case the type
                     --  mismatch may become visible in the body about to be
                     --  inlined.

                     Rewrite (Actual,
                       Unchecked_Convert_To (Etype (Parent_Formal),
                         Relocate_Node (Actual)));

                     Analyze (Actual);
                     Resolve (Actual, Etype (Parent_Formal));
                  end if;
               end if;

               Next_Formal (Formal);
               Next_Formal (Parent_Formal);
               Next_Actual (Actual);
            end loop;
         end if;

         Orig_Subp := Subp;
         Subp := Parent_Subp;
      end if;

      if Is_RTE (Subp, RE_Abort_Task) then
         Check_Restriction (No_Abort_Statements, N);
      end if;

      --  Some more special cases for cases other than explicit dereference

      if Nkind (Name (N)) /= N_Explicit_Dereference then

         --  Calls to an enumeration literal are replaced by the literal
         --  This case occurs only when we have a call to a function that
         --  is a renaming of an enumeration literal. The normal case of
         --  a direct reference to an enumeration literal has already been
         --  been dealt with by Resolve_Call. If the function is itself
         --  inherited (see 7423-001) the literal of the parent type must
         --  be explicitly converted to the return type of the function.

         if Ekind (Subp) = E_Enumeration_Literal then
            if Base_Type (Etype (Subp)) /= Base_Type (Etype (N)) then
               Rewrite
                 (N, Convert_To (Etype (N), New_Occurrence_Of (Subp, Loc)));
            else
               Rewrite (N, New_Occurrence_Of (Subp, Loc));
            end if;

            Resolve (N);
         end if;

      --  Handle case of access to protected subprogram type

      else
         if Ekind (Base_Type (Etype (Prefix (Name (N))))) =
                               E_Access_Protected_Subprogram_Type
         then
            --  If this is a call through an access to protected operation,
            --  the prefix has the form (object'address, operation'access).
            --  Rewrite as a for other protected calls: the object is the
            --  first parameter of the list of actuals.

            declare
               Call : Node_Id;
               Parm : List_Id;
               Nam  : Node_Id;
               Obj  : Node_Id;
               Ptr  : constant Node_Id := Prefix (Name (N));

               T : constant Entity_Id :=
                     Equivalent_Type (Base_Type (Etype (Ptr)));

               D_T : constant Entity_Id :=
                       Designated_Type (Base_Type (Etype (Ptr)));

            begin
               Obj := Make_Selected_Component (Loc,
                 Prefix => Unchecked_Convert_To (T, Ptr),
                 Selector_Name => New_Occurrence_Of (First_Entity (T), Loc));

               Nam := Make_Selected_Component (Loc,
                 Prefix => Unchecked_Convert_To (T, Ptr),
                 Selector_Name => New_Occurrence_Of (
                   Next_Entity (First_Entity (T)), Loc));

               Nam := Make_Explicit_Dereference (Loc, Nam);

               if Present (Parameter_Associations (N))  then
                  Parm := Parameter_Associations (N);
               else
                  Parm := New_List;
               end if;

               Prepend (Obj, Parm);

               if Etype (D_T) = Standard_Void_Type then
                  Call := Make_Procedure_Call_Statement (Loc,
                    Name => Nam,
                    Parameter_Associations => Parm);
               else
                  Call := Make_Function_Call (Loc,
                    Name => Nam,
                    Parameter_Associations => Parm);
               end if;

               Set_First_Named_Actual (Call, First_Named_Actual (N));
               Set_Etype (Call, Etype (D_T));

               --  We do not re-analyze the call to avoid infinite recursion.
               --  We analyze separately the prefix and the object, and set
               --  the checks on the prefix that would otherwise be emitted
               --  when resolving a call.

               Rewrite (N, Call);
               Analyze (Nam);
               Apply_Access_Check (Nam);
               Analyze (Obj);
               return;
            end;
         end if;
      end if;

      --  If this is a call to an intrinsic subprogram, then perform the
      --  appropriate expansion to the corresponding tree node and we
      --  are all done (since after that the call is gone!)

      if Is_Intrinsic_Subprogram (Subp) then
         Expand_Intrinsic_Call (N, Subp);
         return;
      end if;

      if Ekind (Subp) = E_Function
        or else Ekind (Subp) = E_Procedure
      then
         if Is_Inlined (Subp) then

            declare
               Bod         : Node_Id;
               Must_Inline : Boolean := False;
               Spec        : constant Node_Id := Unit_Declaration_Node (Subp);
               Scop        : constant Entity_Id := Scope (Subp);

            begin
               --  Verify that the body to inline has already been seen,
               --  and that if the body is in the current unit the inlining
               --  does not occur earlier. This avoids order-of-elaboration
               --  problems in gigi.

               if No (Spec)
                 or else Nkind (Spec) /= N_Subprogram_Declaration
                 or else No (Body_To_Inline (Spec))
               then
                  Must_Inline := False;

               --  If this an inherited function that returns a private
               --  type, do not inline if the full view is an unconstrained
               --  array, because such calls cannot be inlined.

               elsif Present (Orig_Subp)
                 and then Is_Array_Type (Etype (Orig_Subp))
                 and then not Is_Constrained (Etype (Orig_Subp))
               then
                  Must_Inline := False;

               --  If the subprogram comes from an instance in the same
               --  unit, and the instance is not yet frozen, inlining might
               --  trigger order-of-elaboration problems in gigi.

               elsif Is_Generic_Instance (Scop)
                 and then Present (Freeze_Node (Scop))
                 and then not Analyzed (Freeze_Node (Scop))
               then
                  Must_Inline := False;

               else
                  Bod := Body_To_Inline (Spec);

                  if (In_Extended_Main_Code_Unit (N)
                        or else In_Extended_Main_Code_Unit (Parent (N))
                        or else Is_Always_Inlined (Subp))
                    and then (not In_Same_Extended_Unit (Sloc (Bod), Loc)
                               or else
                                 Earlier_In_Extended_Unit (Sloc (Bod), Loc))
                  then
                     Must_Inline := True;

                  --  If we are compiling a package body that is not the main
                  --  unit, it must be for inlining/instantiation purposes,
                  --  in which case we inline the call to insure that the same
                  --  temporaries are generated when compiling the body by
                  --  itself. Otherwise link errors can occur.

                  elsif not (In_Extended_Main_Code_Unit (N))
                    and then In_Package_Body
                  then
                     Must_Inline := True;
                  end if;
               end if;

               if Must_Inline then
                  Expand_Inlined_Call (N, Subp, Orig_Subp);

               else
                  --  Let the back end handle it

                  Add_Inlined_Body (Subp);

                  if Front_End_Inlining
                    and then Nkind (Spec) = N_Subprogram_Declaration
                    and then (In_Extended_Main_Code_Unit (N))
                    and then No (Body_To_Inline (Spec))
                    and then not Has_Completion (Subp)
                    and then In_Same_Extended_Unit (Sloc (Spec), Loc)
                  then
                     Cannot_Inline
                      ("cannot inline& (body not seen yet)?",
                       N, Subp);
                  end if;
               end if;
            end;
         end if;
      end if;

      --  Check for a protected subprogram. This is either an intra-object
      --  call, or a protected function call. Protected procedure calls are
      --  rewritten as entry calls and handled accordingly.

      Scop := Scope (Subp);

      if Nkind (N) /= N_Entry_Call_Statement
        and then Is_Protected_Type (Scop)
      then
         --  If the call is an internal one, it is rewritten as a call to
         --  to the corresponding unprotected subprogram.

         Expand_Protected_Subprogram_Call (N, Subp, Scop);
      end if;

      --  Functions returning controlled objects need special attention

      if Controlled_Type (Etype (Subp))
        and then not Is_Return_By_Reference_Type (Etype (Subp))
      then
         Expand_Ctrl_Function_Call (N);
      end if;

      --  Test for First_Optional_Parameter, and if so, truncate parameter
      --  list if there are optional parameters at the trailing end.
      --  Note we never delete procedures for call via a pointer.

      if (Ekind (Subp) = E_Procedure or else Ekind (Subp) = E_Function)
        and then Present (First_Optional_Parameter (Subp))
      then
         declare
            Last_Keep_Arg : Node_Id;

         begin
            --  Last_Keep_Arg will hold the last actual that should be
            --  retained. If it remains empty at the end, it means that
            --  all parameters are optional.

            Last_Keep_Arg := Empty;

            --  Find first optional parameter, must be present since we
            --  checked the validity of the parameter before setting it.

            Formal := First_Formal (Subp);
            Actual := First_Actual (N);
            while Formal /= First_Optional_Parameter (Subp) loop
               Last_Keep_Arg := Actual;
               Next_Formal (Formal);
               Next_Actual (Actual);
            end loop;

            --  We have Formal and Actual pointing to the first potentially
            --  droppable argument. We can drop all the trailing arguments
            --  whose actual matches the default. Note that we know that all
            --  remaining formals have defaults, because we checked that this
            --  requirement was met before setting First_Optional_Parameter.

            --  We use Fully_Conformant_Expressions to check for identity
            --  between formals and actuals, which may miss some cases, but
            --  on the other hand, this is only an optimization (if we fail
            --  to truncate a parameter it does not affect functionality).
            --  So if the default is 3 and the actual is 1+2, we consider
            --  them unequal, which hardly seems worrisome.

            while Present (Formal) loop
               if not Fully_Conformant_Expressions
                    (Actual, Default_Value (Formal))
               then
                  Last_Keep_Arg := Actual;
               end if;

               Next_Formal (Formal);
               Next_Actual (Actual);
            end loop;

            --  If no arguments, delete entire list, this is the easy case

            if No (Last_Keep_Arg) then
               while Is_Non_Empty_List (Parameter_Associations (N)) loop
                  Delete_Tree (Remove_Head (Parameter_Associations (N)));
               end loop;

               Set_Parameter_Associations (N, No_List);
               Set_First_Named_Actual (N, Empty);

            --  Case where at the last retained argument is positional. This
            --  is also an easy case, since the retained arguments are already
            --  in the right form, and we don't need to worry about the order
            --  of arguments that get eliminated.

            elsif Is_List_Member (Last_Keep_Arg) then
               while Present (Next (Last_Keep_Arg)) loop
                  Delete_Tree (Remove_Next (Last_Keep_Arg));
               end loop;

               Set_First_Named_Actual (N, Empty);

            --  This is the annoying case where the last retained argument
            --  is a named parameter. Since the original arguments are not
            --  in declaration order, we may have to delete some fairly
            --  random collection of arguments.

            else
               declare
                  Temp   : Node_Id;
                  Passoc : Node_Id;

                  Discard : Node_Id;
                  pragma Warnings (Off, Discard);

               begin
                  --  First step, remove all the named parameters from the
                  --  list (they are still chained using First_Named_Actual
                  --  and Next_Named_Actual, so we have not lost them!)

                  Temp := First (Parameter_Associations (N));

                  --  Case of all parameters named, remove them all

                  if Nkind (Temp) = N_Parameter_Association then
                     while Is_Non_Empty_List (Parameter_Associations (N)) loop
                        Temp := Remove_Head (Parameter_Associations (N));
                     end loop;

                  --  Case of mixed positional/named, remove named parameters

                  else
                     while Nkind (Next (Temp)) /= N_Parameter_Association loop
                        Next (Temp);
                     end loop;

                     while Present (Next (Temp)) loop
                        Discard := Remove_Next (Temp);
                     end loop;
                  end if;

                  --  Now we loop through the named parameters, till we get
                  --  to the last one to be retained, adding them to the list.
                  --  Note that the Next_Named_Actual list does not need to be
                  --  touched since we are only reordering them on the actual
                  --  parameter association list.

                  Passoc := Parent (First_Named_Actual (N));
                  loop
                     Temp := Relocate_Node (Passoc);
                     Append_To
                       (Parameter_Associations (N), Temp);
                     exit when
                       Last_Keep_Arg = Explicit_Actual_Parameter (Passoc);
                     Passoc := Parent (Next_Named_Actual (Passoc));
                  end loop;

                  Set_Next_Named_Actual (Temp, Empty);

                  loop
                     Temp := Next_Named_Actual (Passoc);
                     exit when No (Temp);
                     Set_Next_Named_Actual
                       (Passoc, Next_Named_Actual (Parent (Temp)));
                     Delete_Tree (Temp);
                  end loop;
               end;
            end if;
         end;
      end if;
   end Expand_Call;

   --------------------------
   -- Expand_Inlined_Call --
   --------------------------

   procedure Expand_Inlined_Call
    (N         : Node_Id;
     Subp      : Entity_Id;
     Orig_Subp : Entity_Id)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Is_Predef : constant Boolean :=
                   Is_Predefined_File_Name
                     (Unit_File_Name (Get_Source_Unit (Subp)));
      Orig_Bod  : constant Node_Id :=
                    Body_To_Inline (Unit_Declaration_Node (Subp));

      Blk      : Node_Id;
      Bod      : Node_Id;
      Decl     : Node_Id;
      Exit_Lab : Entity_Id := Empty;
      F        : Entity_Id;
      A        : Node_Id;
      Lab_Decl : Node_Id;
      Lab_Id   : Node_Id;
      New_A    : Node_Id;
      Num_Ret  : Int := 0;
      Ret_Type : Entity_Id;
      Targ     : Node_Id;
      Temp     : Entity_Id;
      Temp_Typ : Entity_Id;

      procedure Make_Exit_Label;
      --  Build declaration for exit label to be used in Return statements.

      function Process_Formals (N : Node_Id) return Traverse_Result;
      --  Replace occurrence of a formal with the corresponding actual, or
      --  the thunk generated for it.

      function Process_Sloc (Nod : Node_Id) return Traverse_Result;
      --  If the call being expanded is that of an internal subprogram,
      --  set the sloc of the generated block to that of the call itself,
      --  so that the expansion is skipped by the -next- command in gdb.
      --  Same processing for a subprogram in a predefined file, e.g.
      --  Ada.Tags. If Debug_Generated_Code is true, suppress this change
      --  to simplify our own development.

      procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id);
      --  If the function body is a single expression, replace call with
      --  expression, else insert block appropriately.

      procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id);
      --  If procedure body has no local variables, inline body without
      --  creating block,  otherwise rewrite call with block.

      ---------------------
      -- Make_Exit_Label --
      ---------------------

      procedure Make_Exit_Label is
      begin
         --  Create exit label for subprogram, if one doesn't exist yet.

         if No (Exit_Lab) then
            Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L'));
            Set_Entity (Lab_Id,
              Make_Defining_Identifier (Loc, Chars (Lab_Id)));
            Exit_Lab := Make_Label (Loc, Lab_Id);

            Lab_Decl :=
              Make_Implicit_Label_Declaration (Loc,
                Defining_Identifier  => Entity (Lab_Id),
                Label_Construct      => Exit_Lab);
         end if;
      end Make_Exit_Label;

      ---------------------
      -- Process_Formals --
      ---------------------

      function Process_Formals (N : Node_Id) return Traverse_Result is
         A   : Entity_Id;
         E   : Entity_Id;
         Ret : Node_Id;

      begin
         if Is_Entity_Name (N)
           and then Present (Entity (N))
         then
            E := Entity (N);

            if Is_Formal (E)
              and then Scope (E) = Subp
            then
               A := Renamed_Object (E);

               if Is_Entity_Name (A) then
                  Rewrite (N, New_Occurrence_Of (Entity (A), Loc));

               elsif Nkind (A) = N_Defining_Identifier then
                  Rewrite (N, New_Occurrence_Of (A, Loc));

               else   --  numeric literal
                  Rewrite (N, New_Copy (A));
               end if;
            end if;

            return Skip;

         elsif Nkind (N) = N_Return_Statement then

            if No (Expression (N)) then
               Make_Exit_Label;
               Rewrite (N, Make_Goto_Statement (Loc,
                 Name => New_Copy (Lab_Id)));

            else
               if Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
                 and then Nkind (Parent (Parent (N))) = N_Subprogram_Body
               then
                  --  Function body is a single expression. No need for
                  --  exit label.

                  null;

               else
                  Num_Ret := Num_Ret + 1;
                  Make_Exit_Label;
               end if;

               --  Because of the presence of private types, the views of the
               --  expression and the context may be different, so place an
               --  unchecked conversion to the context type to avoid spurious
               --  errors, eg. when the expression is a numeric literal and
               --  the context is private. If the expression is an aggregate,
               --  use a qualified expression, because an aggregate is not a
               --  legal argument of a conversion.

               if Nkind (Expression (N)) = N_Aggregate
                 or else Nkind (Expression (N)) = N_Null
               then
                  Ret :=
                    Make_Qualified_Expression (Sloc (N),
                       Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
                       Expression => Relocate_Node (Expression (N)));
               else
                  Ret :=
                    Unchecked_Convert_To
                      (Ret_Type, Relocate_Node (Expression (N)));
               end if;

               if Nkind (Targ) = N_Defining_Identifier then
                  Rewrite (N,
                    Make_Assignment_Statement (Loc,
                      Name => New_Occurrence_Of (Targ, Loc),
                      Expression => Ret));
               else
                  Rewrite (N,
                    Make_Assignment_Statement (Loc,
                      Name => New_Copy (Targ),
                      Expression => Ret));
               end if;

               Set_Assignment_OK (Name (N));

               if Present (Exit_Lab) then
                  Insert_After (N,
                    Make_Goto_Statement (Loc,
                      Name => New_Copy (Lab_Id)));
               end if;
            end if;

            return OK;

         --  Remove pragma Unreferenced since it may refer to formals that
         --  are not visible in the inlined body, and in any case we will
         --  not be posting warnings on the inlined body so it is unneeded.

         elsif Nkind (N) = N_Pragma
           and then Chars (N) = Name_Unreferenced
         then
            Rewrite (N, Make_Null_Statement (Sloc (N)));
            return OK;

         else
            return OK;
         end if;
      end Process_Formals;

      procedure Replace_Formals is new Traverse_Proc (Process_Formals);

      ------------------
      -- Process_Sloc --
      ------------------

      function Process_Sloc (Nod : Node_Id) return Traverse_Result is
      begin
         if not Debug_Generated_Code then
            Set_Sloc (Nod, Sloc (N));
            Set_Comes_From_Source (Nod, False);
         end if;

         return OK;
      end Process_Sloc;

      procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);

      ---------------------------
      -- Rewrite_Function_Call --
      ---------------------------

      procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
         HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
         Fst : constant Node_Id := First (Statements (HSS));

      begin
         --  Optimize simple case: function body is a single return statement,
         --  which has been expanded into an assignment.

         if Is_Empty_List (Declarations (Blk))
           and then Nkind (Fst) = N_Assignment_Statement
           and then No (Next (Fst))
         then

            --  The function call may have been rewritten as the temporary
            --  that holds the result of the call, in which case remove the
            --  now useless declaration.

            if Nkind (N) = N_Identifier
              and then Nkind (Parent (Entity (N))) = N_Object_Declaration
            then
               Rewrite (Parent (Entity (N)), Make_Null_Statement (Loc));
            end if;

            Rewrite (N, Expression (Fst));

         elsif Nkind (N) = N_Identifier
           and then Nkind (Parent (Entity (N))) = N_Object_Declaration
         then

            --  The block assigns the result of the call to the temporary.

            Insert_After (Parent (Entity (N)), Blk);

         elsif Nkind (Parent (N)) = N_Assignment_Statement
           and then Is_Entity_Name (Name (Parent (N)))
         then

            --  Replace assignment with the block

            Rewrite (Parent (N), Blk);

         elsif Nkind (Parent (N)) = N_Object_Declaration then
            Set_Expression (Parent (N), Empty);
            Insert_After (Parent (N), Blk);
         end if;
      end Rewrite_Function_Call;

      ----------------------------
      -- Rewrite_Procedure_Call --
      ----------------------------

      procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
         HSS  : constant Node_Id := Handled_Statement_Sequence (Blk);

      begin
         if Is_Empty_List (Declarations (Blk)) then
            Insert_List_After (N, Statements (HSS));
            Rewrite (N, Make_Null_Statement (Loc));
         else
            Rewrite (N, Blk);
         end if;
      end Rewrite_Procedure_Call;

   --  Start of processing for Expand_Inlined_Call

   begin
      --  Check for special case of To_Address call, and if so, just
      --  do an unchecked conversion instead of expanding the call.
      --  Not only is this more efficient, but it also avoids a
      --  problem with order of elaboration when address clauses
      --  are inlined (address expr elaborated at wrong point).

      if Subp = RTE (RE_To_Address) then
         Rewrite (N,
           Unchecked_Convert_To
            (RTE (RE_Address),
             Relocate_Node (First_Actual (N))));
         return;
      end if;

      if Nkind (Orig_Bod) = N_Defining_Identifier then

         --  Subprogram is a renaming_as_body. Calls appearing after the
         --  renaming can be replaced with calls to the renamed entity
         --  directly, because the subprograms are subtype conformant.

         Set_Name (N, New_Occurrence_Of (Orig_Bod, Loc));
         return;
      end if;

      --  Use generic machinery to copy body of inlined subprogram, as if it
      --  were an instantiation, resetting source locations appropriately, so
      --  that nested inlined calls appear in the main unit.

      Save_Env (Subp, Empty);
      Set_Copied_Sloc_For_Inlined_Body (N, Defining_Entity (Orig_Bod));

      Bod := Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
      Blk :=
        Make_Block_Statement (Loc,
          Declarations => Declarations (Bod),
          Handled_Statement_Sequence => Handled_Statement_Sequence (Bod));

      if No (Declarations (Bod)) then
         Set_Declarations (Blk, New_List);
      end if;

      --  If this is a derived function, establish the proper return type.

      if Present (Orig_Subp)
        and then Orig_Subp /= Subp
      then
         Ret_Type := Etype (Orig_Subp);
      else
         Ret_Type := Etype (Subp);
      end if;

      F := First_Formal (Subp);
      A := First_Actual (N);

      --  Create temporaries for the actuals that are expressions, or that
      --  are scalars and require copying to preserve semantics.

      while Present (F) loop
         if Present (Renamed_Object (F)) then
            Error_Msg_N (" cannot inline call to recursive subprogram", N);
            return;
         end if;

         --  If the argument may be a controlling argument in a call within
         --  the inlined body, we must preserve its classwide nature to
         --  insure that dynamic dispatching take place subsequently.
         --  If the formal has a constraint it must be preserved to retain
         --  the semantics of the body.

         if Is_Class_Wide_Type (Etype (F))
           or else (Is_Access_Type (Etype (F))
                      and then
                    Is_Class_Wide_Type (Designated_Type (Etype (F))))
         then
            Temp_Typ := Etype (F);

         elsif Base_Type (Etype (F)) = Base_Type (Etype (A))
           and then Etype (F) /= Base_Type (Etype (F))
         then
            Temp_Typ := Etype (F);

         else
            Temp_Typ := Etype (A);
         end if;

         --  If the actual is a simple name or a literal, no need to
         --  create a temporary, object can be used directly.

         if (Is_Entity_Name (A)
              and then
               (not Is_Scalar_Type (Etype (A))
                 or else Ekind (Entity (A)) = E_Enumeration_Literal))

           or else Nkind (A) = N_Real_Literal
           or else Nkind (A) = N_Integer_Literal
           or else Nkind (A) = N_Character_Literal
         then
            if Etype (F) /= Etype (A) then
               Set_Renamed_Object
                (F, Unchecked_Convert_To (Etype (F), Relocate_Node (A)));
            else
               Set_Renamed_Object (F, A);
            end if;

         else
            Temp :=
              Make_Defining_Identifier (Loc,
                Chars => New_Internal_Name ('C'));

            --  If the actual for an in/in-out parameter is a view conversion,
            --  make it into an unchecked conversion, given that an untagged
            --  type conversion is not a proper object for a renaming.

            --  In-out conversions that involve real conversions have already
            --  been transformed in Expand_Actuals.

            if Nkind (A) = N_Type_Conversion
              and then Ekind (F) /= E_In_Parameter
            then
               New_A := Make_Unchecked_Type_Conversion (Loc,
                 Subtype_Mark => New_Occurrence_Of (Etype (F), Loc),
                 Expression   => Relocate_Node (Expression (A)));

            elsif Etype (F) /= Etype (A) then
               New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A));
               Temp_Typ := Etype (F);

            else
               New_A := Relocate_Node (A);
            end if;

            Set_Sloc (New_A, Sloc (N));

            if Ekind (F) = E_In_Parameter
              and then not Is_Limited_Type (Etype (A))
            then
               Decl :=
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Constant_Present => True,
                   Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
                   Expression => New_A);
            else
               Decl :=
                 Make_Object_Renaming_Declaration (Loc,
                   Defining_Identifier => Temp,
                   Subtype_Mark        => New_Occurrence_Of (Temp_Typ, Loc),
                   Name                => New_A);
            end if;

            Prepend (Decl, Declarations (Blk));
            Set_Renamed_Object (F, Temp);
         end if;

         Next_Formal (F);
         Next_Actual (A);
      end loop;

      --  Establish target of function call. If context is not assignment or
      --  declaration, create a temporary as a target. The declaration for
      --  the temporary may be subsequently optimized away if the body is a
      --  single expression, or if the left-hand side of the assignment is
      --  simple enough.

      if Ekind (Subp) = E_Function then
         if Nkind (Parent (N)) = N_Assignment_Statement
           and then Is_Entity_Name (Name (Parent (N)))
         then
            Targ := Name (Parent (N));

         else
            --  Replace call with temporary, and create its declaration.

            Temp :=
              Make_Defining_Identifier (Loc, New_Internal_Name ('C'));

            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp,
                Object_Definition =>
                  New_Occurrence_Of (Ret_Type, Loc));

            Set_No_Initialization (Decl);
            Insert_Action (N, Decl);
            Rewrite (N, New_Occurrence_Of (Temp, Loc));
            Targ := Temp;
         end if;
      end if;

      --  Traverse the tree and replace  formals with actuals or their thunks.
      --  Attach block to tree before analysis and rewriting.

      Replace_Formals (Blk);
      Set_Parent (Blk, N);

      if not Comes_From_Source (Subp)
        or else Is_Predef
      then
         Reset_Slocs (Blk);
      end if;

      if Present (Exit_Lab) then

         --  If the body was a single expression, the single return statement
         --  and the corresponding label are useless.

         if Num_Ret = 1
           and then
             Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
               N_Goto_Statement
         then
            Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
         else
            Append (Lab_Decl, (Declarations (Blk)));
            Append (Exit_Lab, Statements (Handled_Statement_Sequence (Blk)));
         end if;
      end if;

      --  Analyze Blk with In_Inlined_Body set, to avoid spurious errors on
      --  conflicting private views that Gigi would ignore. If this is a
      --  predefined unit, analyze with checks off, as is done in the non-
      --  inlined run-time units.

      declare
         I_Flag : constant Boolean := In_Inlined_Body;

      begin
         In_Inlined_Body := True;

         if Is_Predef then
            declare
               Style : constant Boolean := Style_Check;
            begin
               Style_Check := False;
               Analyze (Blk, Suppress => All_Checks);
               Style_Check := Style;
            end;

         else
            Analyze (Blk);
         end if;

         In_Inlined_Body := I_Flag;
      end;

      if Ekind (Subp) = E_Procedure then
         Rewrite_Procedure_Call (N, Blk);
      else
         Rewrite_Function_Call (N, Blk);
      end if;

      Restore_Env;

      --  Cleanup mapping between formals and actuals, for other expansions.

      F := First_Formal (Subp);

      while Present (F) loop
         Set_Renamed_Object (F, Empty);
         Next_Formal (F);
      end loop;
   end Expand_Inlined_Call;

   ----------------------------
   -- Expand_N_Function_Call --
   ----------------------------

   procedure Expand_N_Function_Call (N : Node_Id) is
      Typ : constant Entity_Id := Etype (N);

      function Returned_By_Reference return Boolean;
      --  If the return type is returned through the secondary stack. that is
      --  by reference, we don't want to create a temp to force stack checking.

      function Returned_By_Reference return Boolean is
         S : Entity_Id := Current_Scope;

      begin
         if Is_Return_By_Reference_Type (Typ) then
            return True;

         elsif Nkind (Parent (N)) /= N_Return_Statement then
            return False;

         elsif Requires_Transient_Scope (Typ) then

            --  Verify that the return type of the enclosing function has
            --  the same constrained status as that of the expression.

            while Ekind (S) /= E_Function loop
               S := Scope (S);
            end loop;

            return Is_Constrained (Typ) = Is_Constrained (Etype (S));
         else
            return False;
         end if;
      end Returned_By_Reference;

   --  Start of processing for Expand_N_Function_Call

   begin
      --  A special check. If stack checking is enabled, and the return type
      --  might generate a large temporary, and the call is not the right
      --  side of an assignment, then generate an explicit temporary. We do
      --  this because otherwise gigi may generate a large temporary on the
      --  fly and this can cause trouble with stack checking.

      if May_Generate_Large_Temp (Typ)
        and then Nkind (Parent (N)) /= N_Assignment_Statement
        and then
          (Nkind (Parent (N)) /= N_Qualified_Expression
             or else Nkind (Parent (Parent (N))) /= N_Assignment_Statement)
        and then
          (Nkind (Parent (N)) /= N_Object_Declaration
             or else Expression (Parent (N)) /= N)
        and then not Returned_By_Reference
      then
         --  Note: it might be thought that it would be OK to use a call to
         --  Force_Evaluation here, but that's not good enough, because that
         --  results in a 'Reference construct that may still need a temporary.

         declare
            Loc      : constant Source_Ptr := Sloc (N);
            Temp_Obj : constant Entity_Id :=
                         Make_Defining_Identifier (Loc,
                           Chars => New_Internal_Name ('F'));
            Temp_Typ : Entity_Id := Typ;
            Decl     : Node_Id;
            A        : Node_Id;
            F        : Entity_Id;
            Proc     : Entity_Id;

         begin
            if Is_Tagged_Type (Typ)
              and then Present (Controlling_Argument (N))
            then
               if Nkind (Parent (N)) /= N_Procedure_Call_Statement
                 and then Nkind (Parent (N)) /= N_Function_Call
               then
                  --  If this is a tag-indeterminate call, the object must
                  --  be classwide.

                  if Is_Tag_Indeterminate (N) then
                     Temp_Typ := Class_Wide_Type (Typ);
                  end if;

               else
                  --  If this is a dispatching call that is itself the
                  --  controlling argument of an enclosing call, the nominal
                  --  subtype of the object that replaces it must be classwide,
                  --  so that dispatching will take place properly. If it is
                  --  not a controlling argument, the object is not classwide.

                  Proc := Entity (Name (Parent (N)));
                  F    := First_Formal (Proc);
                  A    := First_Actual (Parent (N));

                  while A /= N loop
                     Next_Formal (F);
                     Next_Actual (A);
                  end loop;

                  if Is_Controlling_Formal (F) then
                     Temp_Typ := Class_Wide_Type (Typ);
                  end if;
               end if;
            end if;

            Decl :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Temp_Obj,
                Object_Definition   => New_Occurrence_Of (Temp_Typ, Loc),
                Constant_Present    => True,
                Expression          => Relocate_Node (N));
            Set_Assignment_OK (Decl);

            Insert_Actions (N, New_List (Decl));
            Rewrite (N, New_Occurrence_Of (Temp_Obj, Loc));
         end;

      --  Normal case, expand the call

      else
         Expand_Call (N);
      end if;
   end Expand_N_Function_Call;

   ---------------------------------------
   -- Expand_N_Procedure_Call_Statement --
   ---------------------------------------

   procedure Expand_N_Procedure_Call_Statement (N : Node_Id) is
   begin
      Expand_Call (N);
   end Expand_N_Procedure_Call_Statement;

   ------------------------------
   -- Expand_N_Subprogram_Body --
   ------------------------------

   --  Add poll call if ATC polling is enabled

   --  Add return statement if last statement in body is not a return
   --  statement (this makes things easier on Gigi which does not want
   --  to have to handle a missing return).

   --  Add call to Activate_Tasks if body is a task activator

   --  Deal with possible detection of infinite recursion

   --  Eliminate body completely if convention stubbed

   --  Encode entity names within body, since we will not need to reference
   --  these entities any longer in the front end.

   --  Initialize scalar out parameters if Initialize/Normalize_Scalars

   --  Reset Pure indication if any parameter has root type System.Address

   --  Wrap thread body

   procedure Expand_N_Subprogram_Body (N : Node_Id) is
      Loc      : constant Source_Ptr := Sloc (N);
      H        : constant Node_Id    := Handled_Statement_Sequence (N);
      Body_Id  : Entity_Id;
      Spec_Id  : Entity_Id;
      Except_H : Node_Id;
      Scop     : Entity_Id;
      Dec      : Node_Id;
      Next_Op  : Node_Id;
      L        : List_Id;

      procedure Add_Return (S : List_Id);
      --  Append a return statement to the statement sequence S if the last
      --  statement is not already a return or a goto statement. Note that
      --  the latter test is not critical, it does not matter if we add a
      --  few extra returns, since they get eliminated anyway later on.

      procedure Expand_Thread_Body;
      --  Perform required expansion of a thread body

      ----------------
      -- Add_Return --
      ----------------

      procedure Add_Return (S : List_Id) is
      begin
         if not Is_Transfer (Last (S)) then

            --  The source location for the return is the end label
            --  of the procedure in all cases. This is a bit odd when
            --  there are exception handlers, but not much else we can do.

            Append_To (S, Make_Return_Statement (Sloc (End_Label (H))));
         end if;
      end Add_Return;

      ------------------------
      -- Expand_Thread_Body --
      ------------------------

      --  The required expansion of a thread body is as follows

      --  procedure <thread body procedure name> is

      --    _Secondary_Stack : aliased
      --       Storage_Elements.Storage_Array
      --         (1 .. Storage_Offset (Sec_Stack_Size));
      --    for _Secondary_Stack'Alignment use Standard'Maximum_Alignment;

      --    _Process_ATSD : aliased System.Threads.ATSD;

      --  begin
      --     System.Threads.Thread_Body_Enter;
      --       (_Secondary_Stack'Address,
      --        _Secondary_Stack'Length,
      --        _Process_ATSD'Address);

      --     declare
      --        <user declarations>
      --     begin
      --        <user statements>
      --     <user exception handlers>
      --     end;

      --    System.Threads.Thread_Body_Leave;

      --  exception
      --     when E : others =>
      --       System.Threads.Thread_Body_Exceptional_Exit (E);
      --  end;

      --  Note the exception handler is omitted if pragma Restriction
      --  No_Exception_Handlers is currently active.

      procedure Expand_Thread_Body is
         User_Decls    : constant List_Id := Declarations (N);
         Sec_Stack_Len : Node_Id;

         TB_Pragma  : constant Node_Id :=
                        Get_Rep_Pragma (Spec_Id, Name_Thread_Body);

         Ent_SS   : Entity_Id;
         Ent_ATSD : Entity_Id;
         Ent_EO   : Entity_Id;

         Decl_SS   : Node_Id;
         Decl_ATSD : Node_Id;

         Excep_Handlers : List_Id;

      begin
         New_Scope (Spec_Id);

         --  Get proper setting for secondary stack size

         if List_Length (Pragma_Argument_Associations (TB_Pragma)) = 2 then
            Sec_Stack_Len :=
              Expression (Last (Pragma_Argument_Associations (TB_Pragma)));
         else
            Sec_Stack_Len :=
              New_Occurrence_Of (RTE (RE_Default_Secondary_Stack_Size), Loc);
         end if;

         Sec_Stack_Len := Convert_To (RTE (RE_Storage_Offset), Sec_Stack_Len);

         --  Build and set declarations for the wrapped thread body

         Ent_SS   := Make_Defining_Identifier (Loc, Name_uSecondary_Stack);
         Ent_ATSD := Make_Defining_Identifier (Loc, Name_uProcess_ATSD);

         Decl_SS :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Ent_SS,
             Aliased_Present     => True,
             Object_Definition   =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark =>
                   New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
                 Constraint   =>
                   Make_Index_Or_Discriminant_Constraint (Loc,
                     Constraints => New_List (
                       Make_Range (Loc,
                         Low_Bound  => Make_Integer_Literal (Loc, 1),
                         High_Bound => Sec_Stack_Len)))));

         Decl_ATSD :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Ent_ATSD,
             Aliased_Present     => True,
             Object_Definition   => New_Occurrence_Of (RTE (RE_ATSD), Loc));

         Set_Declarations (N, New_List (Decl_SS, Decl_ATSD));
         Analyze (Decl_SS);
         Analyze (Decl_ATSD);
         Set_Alignment (Ent_SS, UI_From_Int (Maximum_Alignment));

         --  Create new exception handler

         if Restrictions (No_Exception_Handlers) then
            Excep_Handlers := No_List;

         else
            Check_Restriction (No_Exception_Handlers, N);

            Ent_EO := Make_Defining_Identifier (Loc, Name_uE);

            Excep_Handlers := New_List (
              Make_Exception_Handler (Loc,
                Choice_Parameter => Ent_EO,
                Exception_Choices => New_List (
                  Make_Others_Choice (Loc)),
                Statements => New_List (
                  Make_Procedure_Call_Statement (Loc,
                    Name =>
                      New_Occurrence_Of
                        (RTE (RE_Thread_Body_Exceptional_Exit), Loc),
                    Parameter_Associations => New_List (
                      New_Occurrence_Of (Ent_EO, Loc))))));
         end if;

         --  Now build new handled statement sequence and analyze it

         Set_Handled_Statement_Sequence (N,
           Make_Handled_Sequence_Of_Statements (Loc,
             Statements => New_List (

               Make_Procedure_Call_Statement (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Thread_Body_Enter), Loc),
                 Parameter_Associations => New_List (

                   Make_Attribute_Reference (Loc,
                     Prefix => New_Occurrence_Of (Ent_SS, Loc),
                     Attribute_Name => Name_Address),

                   Make_Attribute_Reference (Loc,
                     Prefix => New_Occurrence_Of (Ent_SS, Loc),
                     Attribute_Name => Name_Length),

                   Make_Attribute_Reference (Loc,
                     Prefix => New_Occurrence_Of (Ent_ATSD, Loc),
                     Attribute_Name => Name_Address))),

               Make_Block_Statement (Loc,
                 Declarations => User_Decls,
                 Handled_Statement_Sequence => H),

               Make_Procedure_Call_Statement (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Thread_Body_Leave), Loc))),

             Exception_Handlers => Excep_Handlers));

         Analyze (Handled_Statement_Sequence (N));
         End_Scope;
      end Expand_Thread_Body;

   --  Start of processing for Expand_N_Subprogram_Body

   begin
      --  Set L to either the list of declarations if present, or
      --  to the list of statements if no declarations are present.
      --  This is used to insert new stuff at the start.

      if Is_Non_Empty_List (Declarations (N)) then
         L := Declarations (N);
      else
         L := Statements (Handled_Statement_Sequence (N));
      end if;

      --  Need poll on entry to subprogram if polling enabled. We only
      --  do this for non-empty subprograms, since it does not seem
      --  necessary to poll for a dummy null subprogram.

      if Is_Non_Empty_List (L) then
         Generate_Poll_Call (First (L));
      end if;

      --  Find entity for subprogram

      Body_Id := Defining_Entity (N);

      if Present (Corresponding_Spec (N)) then
         Spec_Id := Corresponding_Spec (N);
      else
         Spec_Id := Body_Id;
      end if;

      --  If this is a Pure function which has any parameters whose root
      --  type is System.Address, reset the Pure indication, since it will
      --  likely cause incorrect code to be generated as the parameter is
      --  probably a pointer, and the fact that the same pointer is passed
      --  does not mean that the same value is being referenced.

      --  Note that if the programmer gave an explicit Pure_Function pragma,
      --  then we believe the programmer, and leave the subprogram Pure.

      --  This code should probably be at the freeze point, so that it
      --  happens even on a -gnatc (or more importantly -gnatt) compile
      --  so that the semantic tree has Is_Pure set properly ???

      if Is_Pure (Spec_Id)
        and then Is_Subprogram (Spec_Id)
        and then not Has_Pragma_Pure_Function (Spec_Id)
      then
         declare
            F : Entity_Id := First_Formal (Spec_Id);

         begin
            while Present (F) loop
               if Is_RTE (Root_Type (Etype (F)), RE_Address) then
                  Set_Is_Pure (Spec_Id, False);

                  if Spec_Id /= Body_Id then
                     Set_Is_Pure (Body_Id, False);
                  end if;

                  exit;
               end if;

               Next_Formal (F);
            end loop;
         end;
      end if;

      --  Initialize any scalar OUT args if Initialize/Normalize_Scalars

      if Init_Or_Norm_Scalars and then Is_Subprogram (Spec_Id) then
         declare
            F : Entity_Id        := First_Formal (Spec_Id);
            V : constant Boolean := Validity_Checks_On;

         begin
            --  We turn off validity checking, since we do not want any
            --  check on the initializing value itself (which we know
            --  may well be invalid!)

            Validity_Checks_On := False;

            --  Loop through formals

            while Present (F) loop
               if Is_Scalar_Type (Etype (F))
                 and then Ekind (F) = E_Out_Parameter
               then
                  Insert_Before_And_Analyze (First (L),
                    Make_Assignment_Statement (Loc,
                      Name => New_Occurrence_Of (F, Loc),
                      Expression => Get_Simple_Init_Val (Etype (F), Loc)));
               end if;

               Next_Formal (F);
            end loop;

            Validity_Checks_On := V;
         end;
      end if;

      --  Clear out statement list for stubbed procedure

      if Present (Corresponding_Spec (N)) then
         Set_Elaboration_Flag (N, Spec_Id);

         if Convention (Spec_Id) = Convention_Stubbed
           or else Is_Eliminated (Spec_Id)
         then
            Set_Declarations (N, Empty_List);
            Set_Handled_Statement_Sequence (N,
              Make_Handled_Sequence_Of_Statements (Loc,
                Statements => New_List (
                  Make_Null_Statement (Loc))));
            return;
         end if;
      end if;

      Scop := Scope (Spec_Id);

      --  Returns_By_Ref flag is normally set when the subprogram is frozen
      --  but subprograms with no specs are not frozen

      declare
         Typ  : constant Entity_Id := Etype (Spec_Id);
         Utyp : constant Entity_Id := Underlying_Type (Typ);

      begin
         if not Acts_As_Spec (N)
           and then Nkind (Parent (Parent (Spec_Id))) /=
             N_Subprogram_Body_Stub
         then
            null;

         elsif Is_Return_By_Reference_Type (Typ) then
            Set_Returns_By_Ref (Spec_Id);

         elsif Present (Utyp) and then Controlled_Type (Utyp) then
            Set_Returns_By_Ref (Spec_Id);
         end if;
      end;

      --  For a procedure, we add a return for all possible syntactic ends
      --  of the subprogram. Note that reanalysis is not necessary in this
      --  case since it would require a lot of work and accomplish nothing.

      if Ekind (Spec_Id) = E_Procedure
        or else Ekind (Spec_Id) = E_Generic_Procedure
      then
         Add_Return (Statements (H));

         if Present (Exception_Handlers (H)) then
            Except_H := First_Non_Pragma (Exception_Handlers (H));

            while Present (Except_H) loop
               Add_Return (Statements (Except_H));
               Next_Non_Pragma (Except_H);
            end loop;
         end if;

      --  For a function, we must deal with the case where there is at
      --  least one missing return. What we do is to wrap the entire body
      --  of the function in a block:

      --    begin
      --      ...
      --    end;

      --  becomes

      --    begin
      --       begin
      --          ...
      --       end;

      --       raise Program_Error;
      --    end;

      --  This approach is necessary because the raise must be signalled
      --  to the caller, not handled by any local handler (RM 6.4(11)).

      --  Note: we do not need to analyze the constructed sequence here,
      --  since it has no handler, and an attempt to analyze the handled
      --  statement sequence twice is risky in various ways (e.g. the
      --  issue of expanding cleanup actions twice).

      elsif Has_Missing_Return (Spec_Id) then
         declare
            Hloc : constant Source_Ptr := Sloc (H);
            Blok : constant Node_Id    :=
                     Make_Block_Statement (Hloc,
                       Handled_Statement_Sequence => H);
            Rais : constant Node_Id    :=
                     Make_Raise_Program_Error (Hloc,
                       Reason => PE_Missing_Return);

         begin
            Set_Handled_Statement_Sequence (N,
              Make_Handled_Sequence_Of_Statements (Hloc,
                Statements => New_List (Blok, Rais)));

            New_Scope (Spec_Id);
            Analyze (Blok);
            Analyze (Rais);
            Pop_Scope;
         end;
      end if;

      --  Add discriminal renamings to protected subprograms.
      --  Install new discriminals for expansion of the next
      --  subprogram of this protected type, if any.

      if Is_List_Member (N)
        and then Present (Parent (List_Containing (N)))
        and then Nkind (Parent (List_Containing (N))) = N_Protected_Body
      then
         Add_Discriminal_Declarations
           (Declarations (N), Scop, Name_uObject, Loc);
         Add_Private_Declarations (Declarations (N), Scop, Name_uObject, Loc);

         --  Associate privals and discriminals with the next protected
         --  operation body to be expanded. These are used to expand
         --  references to private data objects and discriminants,
         --  respectively.

         Next_Op := Next_Protected_Operation (N);

         if Present (Next_Op) then
            Dec := Parent (Base_Type (Scop));
            Set_Privals (Dec, Next_Op, Loc);
            Set_Discriminals (Dec);
         end if;
      end if;

      --  If subprogram contains a parameterless recursive call, then we may
      --  have an infinite recursion, so see if we can generate code to check
      --  for this possibility if storage checks are not suppressed.

      if Ekind (Spec_Id) = E_Procedure
        and then Has_Recursive_Call (Spec_Id)
        and then not Storage_Checks_Suppressed (Spec_Id)
      then
         Detect_Infinite_Recursion (N, Spec_Id);
      end if;

      --  Finally, if we are in Normalize_Scalars mode, then any scalar out
      --  parameters must be initialized to the appropriate default value.

      if Ekind (Spec_Id) = E_Procedure and then Normalize_Scalars then
         declare
            Floc   : Source_Ptr;
            Formal : Entity_Id;
            Stm    : Node_Id;

         begin
            Formal := First_Formal (Spec_Id);

            while Present (Formal) loop
               Floc := Sloc (Formal);

               if Ekind (Formal) = E_Out_Parameter
                 and then Is_Scalar_Type (Etype (Formal))
               then
                  Stm :=
                    Make_Assignment_Statement (Floc,
                      Name => New_Occurrence_Of (Formal, Floc),
                      Expression =>
                        Get_Simple_Init_Val (Etype (Formal), Floc));
                  Prepend (Stm, Declarations (N));
                  Analyze (Stm);
               end if;

               Next_Formal (Formal);
            end loop;
         end;
      end if;

      --  Deal with thread body

      if Is_Thread_Body (Spec_Id) then
         Expand_Thread_Body;
      end if;

      --  If the subprogram does not have pending instantiations, then we
      --  must generate the subprogram descriptor now, since the code for
      --  the subprogram is complete, and this is our last chance. However
      --  if there are pending instantiations, then the code is not
      --  complete, and we will delay the generation.

      if Is_Subprogram (Spec_Id)
        and then not Delay_Subprogram_Descriptors (Spec_Id)
      then
         Generate_Subprogram_Descriptor_For_Subprogram (N, Spec_Id);
      end if;

      --  Set to encode entity names in package body before gigi is called

      Qualify_Entity_Names (N);
   end Expand_N_Subprogram_Body;

   -----------------------------------
   -- Expand_N_Subprogram_Body_Stub --
   -----------------------------------

   procedure Expand_N_Subprogram_Body_Stub (N : Node_Id) is
   begin
      if Present (Corresponding_Body (N)) then
         Expand_N_Subprogram_Body (
           Unit_Declaration_Node (Corresponding_Body (N)));
      end if;
   end Expand_N_Subprogram_Body_Stub;

   -------------------------------------
   -- Expand_N_Subprogram_Declaration --
   -------------------------------------

   --  If the declaration appears within a protected body, it is a private
   --  operation of the protected type. We must create the corresponding
   --  protected subprogram an associated formals. For a normal protected
   --  operation, this is done when expanding the protected type declaration.

   procedure Expand_N_Subprogram_Declaration (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Subp      : constant Entity_Id  := Defining_Entity (N);
      Scop      : constant Entity_Id  := Scope (Subp);
      Prot_Decl : Node_Id;
      Prot_Bod  : Node_Id;
      Prot_Id   : Entity_Id;

   begin
      --  Deal with case of protected subprogram

      if Is_List_Member (N)
        and then Present (Parent (List_Containing (N)))
        and then Nkind (Parent (List_Containing (N))) = N_Protected_Body
        and then Is_Protected_Type (Scop)
      then
         if No (Protected_Body_Subprogram (Subp)) then
            Prot_Decl :=
              Make_Subprogram_Declaration (Loc,
                Specification =>
                  Build_Protected_Sub_Specification
                    (N, Scop, Unprotected => True));

            --  The protected subprogram is declared outside of the protected
            --  body. Given that the body has frozen all entities so far, we
            --  analyze the subprogram and perform freezing actions explicitly.
            --  If the body is a subunit, the insertion point is before the
            --  stub in the parent.

            Prot_Bod := Parent (List_Containing (N));

            if Nkind (Parent (Prot_Bod)) = N_Subunit then
               Prot_Bod := Corresponding_Stub (Parent (Prot_Bod));
            end if;

            Insert_Before (Prot_Bod, Prot_Decl);
            Prot_Id := Defining_Unit_Name (Specification (Prot_Decl));

            New_Scope (Scope (Scop));
            Analyze (Prot_Decl);
            Create_Extra_Formals (Prot_Id);
            Set_Protected_Body_Subprogram (Subp, Prot_Id);
            Pop_Scope;
         end if;
      end if;
   end Expand_N_Subprogram_Declaration;

   ---------------------------------------
   -- Expand_Protected_Object_Reference --
   ---------------------------------------

   function Expand_Protected_Object_Reference
     (N    : Node_Id;
      Scop : Entity_Id)
     return Node_Id
   is
      Loc   : constant Source_Ptr := Sloc (N);
      Corr  : Entity_Id;
      Rec   : Node_Id;
      Param : Entity_Id;
      Proc  : Entity_Id;

   begin
      Rec := Make_Identifier (Loc, Name_uObject);
      Set_Etype (Rec, Corresponding_Record_Type (Scop));

      --  Find enclosing protected operation, and retrieve its first
      --  parameter, which denotes the enclosing protected object.
      --  If the enclosing operation is an entry, we are immediately
      --  within the protected body, and we can retrieve the object
      --  from the service entries procedure. A barrier function has
      --  has the same signature as an entry. A barrier function is
      --  compiled within the protected object, but unlike protected
      --  operations its never needs locks, so that its protected body
      --  subprogram points to itself.

      Proc := Current_Scope;

      while Present (Proc)
        and then Scope (Proc) /= Scop
      loop
         Proc := Scope (Proc);
      end loop;

      Corr := Protected_Body_Subprogram (Proc);

      if No (Corr) then

         --  Previous error left expansion incomplete.
         --  Nothing to do on this call.

         return Empty;
      end if;

      Param :=
        Defining_Identifier
          (First (Parameter_Specifications (Parent (Corr))));

      if Is_Subprogram (Proc)
        and then Proc /= Corr
      then
         --  Protected function or procedure.

         Set_Entity (Rec, Param);

         --  Rec is a reference to an entity which will not be in scope
         --  when the call is reanalyzed, and needs no further analysis.

         Set_Analyzed (Rec);

      else
         --  Entry or barrier function for entry body.
         --  The first parameter of the entry body procedure is a
         --  pointer to the object. We create a local variable
         --  of the proper type, duplicating what is done to define
         --  _object later on.

         declare
            Decls : List_Id;
            Obj_Ptr : constant Entity_Id :=  Make_Defining_Identifier (Loc,
                                               Chars =>
                                                 New_Internal_Name ('T'));

         begin
            Decls := New_List (
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Obj_Ptr,
                  Type_Definition =>
                     Make_Access_To_Object_Definition (Loc,
                       Subtype_Indication =>
                         New_Reference_To
                      (Corresponding_Record_Type (Scop), Loc))));

            Insert_Actions (N, Decls);
            Insert_Actions (N, Freeze_Entity (Obj_Ptr, Sloc (N)));

            Rec :=
              Make_Explicit_Dereference (Loc,
                Unchecked_Convert_To (Obj_Ptr,
                  New_Occurrence_Of (Param, Loc)));

            --  Analyze new actual. Other actuals in calls are already
            --  analyzed and the list of actuals is not renalyzed after
            --  rewriting.

            Set_Parent (Rec, N);
            Analyze (Rec);
         end;
      end if;

      return Rec;
   end Expand_Protected_Object_Reference;

   --------------------------------------
   -- Expand_Protected_Subprogram_Call --
   --------------------------------------

   procedure Expand_Protected_Subprogram_Call
     (N    : Node_Id;
      Subp : Entity_Id;
      Scop : Entity_Id)
   is
      Rec   : Node_Id;

   begin
      --  If the protected object is not an enclosing scope, this is
      --  an inter-object function call. Inter-object procedure
      --  calls are expanded by Exp_Ch9.Build_Simple_Entry_Call.
      --  The call is intra-object only if the subprogram being
      --  called is in the protected body being compiled, and if the
      --  protected object in the call is statically the enclosing type.
      --  The object may be an component of some other data structure,
      --  in which case this must be handled as an inter-object call.

      if not In_Open_Scopes (Scop)
        or else not Is_Entity_Name (Name (N))
      then
         if Nkind (Name (N)) = N_Selected_Component then
            Rec := Prefix (Name (N));

         else
            pragma Assert (Nkind (Name (N)) = N_Indexed_Component);
            Rec := Prefix (Prefix (Name (N)));
         end if;

         Build_Protected_Subprogram_Call (N,
           Name => New_Occurrence_Of (Subp, Sloc (N)),
           Rec =>  Convert_Concurrent (Rec, Etype (Rec)),
           External => True);

      else
         Rec := Expand_Protected_Object_Reference (N, Scop);

         if No (Rec) then
            return;
         end if;

         Build_Protected_Subprogram_Call (N,
           Name     => Name (N),
           Rec      => Rec,
           External => False);

      end if;

      Analyze (N);

      --  If it is a function call it can appear in elaboration code and
      --  the called entity must be frozen here.

      if Ekind (Subp) = E_Function then
         Freeze_Expression (Name (N));
      end if;
   end Expand_Protected_Subprogram_Call;

   -----------------------
   -- Freeze_Subprogram --
   -----------------------

   procedure Freeze_Subprogram (N : Node_Id) is
      E : constant Entity_Id := Entity (N);

   begin
      --  When a primitive is frozen, enter its name in the corresponding
      --  dispatch table. If the DTC_Entity field is not set this is an
      --  overridden primitive that can be ignored. We suppress the
      --  initialization of the dispatch table entry when Java_VM because
      --  the dispatching mechanism is handled internally by the JVM.

      if Is_Dispatching_Operation (E)
        and then not Is_Abstract (E)
        and then Present (DTC_Entity (E))
        and then not Is_CPP_Class (Scope (DTC_Entity (E)))
        and then not Java_VM
      then
         Check_Overriding_Operation (E);
         Insert_After (N, Fill_DT_Entry (Sloc (N), E));
      end if;

      --  Mark functions that return by reference. Note that it cannot be
      --  part of the normal semantic analysis of the spec since the
      --  underlying returned type may not be known yet (for private types)

      declare
         Typ  : constant Entity_Id := Etype (E);
         Utyp : constant Entity_Id := Underlying_Type (Typ);

      begin
         if Is_Return_By_Reference_Type (Typ) then
            Set_Returns_By_Ref (E);

         elsif Present (Utyp) and then Controlled_Type (Utyp) then
            Set_Returns_By_Ref (E);
         end if;
      end;
   end Freeze_Subprogram;

end Exp_Ch6;
