------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ E L A B                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1997-2005 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 Elists;   use Elists;
with Errout;   use Errout;
with Exp_Tss;  use Exp_Tss;
with Exp_Util; use Exp_Util;
with Expander; use Expander;
with Fname;    use Fname;
with Lib;      use Lib;
with Lib.Load; use Lib.Load;
with Namet;    use Namet;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Output;   use Output;
with Restrict; use Restrict;
with Rident;   use Rident;
with Sem;      use Sem;
with Sem_Cat;  use Sem_Cat;
with Sem_Ch7;  use Sem_Ch7;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Sinput;   use Sinput;
with Snames;   use Snames;
with Stand;    use Stand;
with Table;
with Tbuild;   use Tbuild;
with Uname;    use Uname;

package body Sem_Elab is

   --  The following table records the recursive call chain for output
   --  in the Output routine. Each entry records the call node and the
   --  entity of the called routine. The number of entries in the table
   --  (i.e. the value of Elab_Call.Last) indicates the current depth
   --  of recursion and is used to identify the outer level.

   type Elab_Call_Entry is record
      Cloc : Source_Ptr;
      Ent  : Entity_Id;
   end record;

   package Elab_Call is new Table.Table (
     Table_Component_Type => Elab_Call_Entry,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 50,
     Table_Increment      => 100,
     Table_Name           => "Elab_Call");

   --  This table is initialized at the start of each outer level call.
   --  It holds the entities for all subprograms that have been examined
   --  for this particular outer level call, and is used to prevent both
   --  infinite recursion, and useless reanalysis of bodies already seen

   package Elab_Visited is new Table.Table (
     Table_Component_Type => Entity_Id,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 200,
     Table_Increment      => 100,
     Table_Name           => "Elab_Visited");

   --  This table stores calls to Check_Internal_Call that are delayed
   --  until all generics are instantiated, and in particular that all
   --  generic bodies have been inserted. We need to delay, because we
   --  need to be able to look through the inserted bodies.

   type Delay_Element is record
      N : Node_Id;
      --  The parameter N from the call to Check_Internal_Call. Note that
      --  this node may get rewritten over the delay period by expansion
      --  in the call case (but not in the instantiation case).

      E : Entity_Id;
      --  The parameter E from the call to Check_Internal_Call

      Orig_Ent : Entity_Id;
      --  The parameter Orig_Ent from the call to Check_Internal_Call

      Curscop : Entity_Id;
      --  The current scope of the call. This is restored when we complete
      --  the delayed call, so that we do this in the right scope.

      From_Elab_Code : Boolean;
      --  Save indication of whether this call is from elaboration code

      Outer_Scope : Entity_Id;
      --  Save scope of outer level call

   end record;

   package Delay_Check is new Table.Table (
     Table_Component_Type => Delay_Element,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 1000,
     Table_Increment      => 100,
     Table_Name           => "Delay_Check");

   C_Scope : Entity_Id;
   --  Top level scope of current scope. We need to compute this only
   --  once at the outer level, i.e. for a call to Check_Elab_Call from
   --  outside this unit.

   Outer_Level_Sloc : Source_Ptr;
   --  Save Sloc value for outer level call node for comparisons of source
   --  locations. A body is too late if it appears after the *outer* level
   --  call, not the particular call that is being analyzed.

   From_Elab_Code : Boolean;
   --  This flag shows whether the outer level call currently being examined
   --  is or is not in elaboration code. We are only interested in calls to
   --  routines in other units if this flag is True.

   In_Task_Activation : Boolean := False;
   --  This flag indicates whether we are performing elaboration checks on
   --  task procedures, at the point of activation. If true, we do not trace
   --  internal calls in these procedures, because all local bodies are known
   --  to be elaborated.

   Delaying_Elab_Checks : Boolean := True;
   --  This is set True till the compilation is complete, including the
   --  insertion of all instance bodies. Then when Check_Elab_Calls is
   --  called, the delay table is used to make the delayed calls and
   --  this flag is reset to False, so that the calls are processed

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

   --  Note: Outer_Scope in all following specs represents the scope of
   --  interest of the outer level call. If it is set to Standard_Standard,
   --  then it means the outer level call was at elaboration level, and that
   --  thus all calls are of interest. If it was set to some other scope,
   --  then the original call was an inner call, and we are not interested
   --  in calls that go outside this scope.

   procedure Check_A_Call
     (N                 : Node_Id;
      E                 : Entity_Id;
      Outer_Scope       : Entity_Id;
      Inter_Unit_Only   : Boolean;
      Generate_Warnings : Boolean := True);
   --  This is the internal recursive routine that is called to check for
   --  a possible elaboration error. The argument N is a subprogram call
   --  or generic instantiation to be checked, and E is the entity of
   --  the called subprogram, or instantiated generic unit. The flag
   --  Outer_Scope is the outer level scope for the original call.
   --  Inter_Unit_Only is set if the call is only to be checked in the
   --  case where it is to another unit (and skipped if within a unit).
   --  Generate_Warnings is set to False to suppress warning messages
   --  about missing pragma Elaborate_All's. These messages are not
   --  wanted for inner calls in the dynamic model.

   procedure Check_Bad_Instantiation (N : Node_Id);
   --  N is a node for an instantiation (if called with any other node kind,
   --  Check_Bad_Instantiation ignores the call). This subprogram checks for
   --  the special case of a generic instantiation of a generic spec in the
   --  same declarative part as the instantiation where a body is present and
   --  has not yet been seen. This is an obvious error, but needs to be checked
   --  specially at the time of the instantiation, since it is a case where we
   --  cannot insert the body anywhere. If this case is detected, warnings are
   --  generated, and a raise of Program_Error is inserted. In addition any
   --  subprograms in the generic spec are stubbed, and the Bad_Instantiation
   --  flag is set on the instantiation node. The caller in Sem_Ch12 uses this
   --  flag as an indication that no attempt should be made to insert an
   --  instance body.

   procedure Check_Internal_Call
     (N           : Node_Id;
      E           : Entity_Id;
      Outer_Scope : Entity_Id;
      Orig_Ent    : Entity_Id);
   --  N is a function call or procedure statement call node and E is
   --  the entity of the called function, which is within the current
   --  compilation unit (where subunits count as part of the parent).
   --  This call checks if this call, or any call within any accessed
   --  body could cause an ABE, and if so, outputs a warning. Orig_Ent
   --  differs from E only in the case of renamings, and points to the
   --  original name of the entity. This is used for error messages.
   --  Outer_Scope is the outer level scope for the original call.

   procedure Check_Internal_Call_Continue
     (N           : Node_Id;
      E           : Entity_Id;
      Outer_Scope : Entity_Id;
      Orig_Ent    : Entity_Id);
   --  The processing for Check_Internal_Call is divided up into two phases,
   --  and this represents the second phase. The second phase is delayed if
   --  Delaying_Elab_Calls is set to True. In this delayed case, the first
   --  phase makes an entry in the Delay_Check table, which is processed
   --  when Check_Elab_Calls is called. N, E and Orig_Ent are as for the call
   --  to Check_Internal_Call. Outer_Scope is the outer level scope for
   --  the original call.

   procedure Set_Elaboration_Constraint
    (Call : Node_Id;
     Subp : Entity_Id;
     Scop : Entity_Id);
   --  The current unit U may depend semantically on some unit P which is not
   --  in the current context. If there is an elaboration call that reaches P,
   --  we need to indicate that P requires an Elaborate_All, but this is not
   --  effective in U's ali file, if there is no with_clause for P. In this
   --  case we add the Elaborate_All on the unit Q that directly or indirectly
   --  makes P available. This can happen in two cases:
   --
   --    a) Q declares a subtype of a type declared in P, and the call is an
   --    initialization call for an object of that subtype.
   --
   --    b) Q declares an object of some tagged type whose root type is
   --    declared in P, and the initialization call uses object notation on
   --    that object to reach a primitive operation or a classwide operation
   --    declared in P.
   --
   --  If P appears in the context of U, the current processing is correct.
   --  Otherwise we must identify these two cases to retrieve Q and place the
   --  Elaborate_All_Desirable on it.

   function Has_Generic_Body (N : Node_Id) return Boolean;
   --  N is a generic package instantiation node, and this routine determines
   --  if this package spec does in fact have a generic body. If so, then
   --  True is returned, otherwise False. Note that this is not at all the
   --  same as checking if the unit requires a body, since it deals with
   --  the case of optional bodies accurately (i.e. if a body is optional,
   --  then it looks to see if a body is actually present). Note: this
   --  function can only do a fully correct job if in generating code mode
   --  where all bodies have to be present. If we are operating in semantics
   --  check only mode, then in some cases of optional bodies, a result of
   --  False may incorrectly be given. In practice this simply means that
   --  some cases of warnings for incorrect order of elaboration will only
   --  be given when generating code, which is not a big problem (and is
   --  inevitable, given the optional body semantics of Ada).

   procedure Insert_Elab_Check (N : Node_Id; C : Node_Id := Empty);
   --  Given code for an elaboration check (or unconditional raise if
   --  the check is not needed), inserts the code in the appropriate
   --  place. N is the call or instantiation node for which the check
   --  code is required. C is the test whose failure triggers the raise.

   procedure Output_Calls (N : Node_Id);
   --  Outputs chain of calls stored in the Elab_Call table. The caller
   --  has already generated the main warning message, so the warnings
   --  generated are all continuation messages. The argument is the
   --  call node at which the messages are to be placed.

   function Same_Elaboration_Scope (Scop1, Scop2 : Entity_Id) return Boolean;
   --  Given two scopes, determine whether they are the same scope from an
   --  elaboration point of view, i.e. packages and blocks are ignored.

   procedure Set_C_Scope;
   --  On entry C_Scope is set to some scope. On return, C_Scope is reset
   --  to be the enclosing compilation unit of this scope.

   function Spec_Entity (E : Entity_Id) return Entity_Id;
   --  Given a compilation unit entity, if it is a spec entity, it is
   --  returned unchanged. If it is a body entity, then the spec for
   --  the corresponding spec is returned

   procedure Supply_Bodies (N : Node_Id);
   --  Given a node, N, that is either a subprogram declaration or a package
   --  declaration, this procedure supplies dummy bodies for the subprogram
   --  or for all subprograms in the package. If the given node is not one
   --  of these two possibilities, then Supply_Bodies does nothing. The
   --  dummy body is supplied by setting the subprogram to be Imported with
   --  convention Stubbed.

   procedure Supply_Bodies (L : List_Id);
   --  Calls Supply_Bodies for all elements of the given list L.

   function Within (E1, E2 : Entity_Id) return Boolean;
   --  Given two scopes E1 and E2, returns True if E1 is equal to E2, or
   --  is one of its contained scopes, False otherwise.

   function Within_Elaborate_All (E : Entity_Id) return Boolean;
   --  Before emitting a warning on a scope E for a missing elaborate_all,
   --  check whether E may be in the context of a directly visible unit
   --  U to which the pragma applies. This prevents spurious warnings when
   --  the called entity is renamed within U.

   ------------------
   -- Check_A_Call --
   ------------------

   procedure Check_A_Call
     (N                 : Node_Id;
      E                 : Entity_Id;
      Outer_Scope       : Entity_Id;
      Inter_Unit_Only   : Boolean;
      Generate_Warnings : Boolean := True)
   is
      Loc  : constant Source_Ptr := Sloc (N);
      Ent  : Entity_Id;
      Decl : Node_Id;

      E_Scope : Entity_Id;
      --  Top level scope of entity for called subprogram. This
      --  value includes following renamings and derivations, so
      --  this scope can be in a non-visible unit. This is the
      --  scope that is to be investigated to see whether an
      --  elaboration check is required.

      W_Scope : Entity_Id;
      --  Top level scope of directly called entity for subprogram. This
      --  differs from E_Scope in the case where renamings or derivations
      --  are involved, since it does not follow these links. W_Scope is
      --  generally in a visible unit, and it is this scope that may require
      --  an Elaborate_All. However, there are some cases (initialization
      --  calls and calls involving object notation) where W_Scope might not
      --  be in the context of the current unit, and there is an intermediate
      --  package that is, in which case the Elaborate_All has to be placed
      --  on this intedermediate package. These special cases are handled in
      --  Set_Elaboration_Constraint.

      Body_Acts_As_Spec : Boolean;
      --  Set to true if call is to body acting as spec (no separate spec)

      Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;
      --  Indicates if we have instantiation case

      Caller_Unit_Internal : Boolean;
      Callee_Unit_Internal : Boolean;

      Inst_Caller : Source_Ptr;
      Inst_Callee : Source_Ptr;

      Unit_Caller : Unit_Number_Type;
      Unit_Callee : Unit_Number_Type;

      Cunit_SC : Boolean := False;
      --  Set to suppress dynamic elaboration checks where one of the
      --  enclosing scopes has Elaboration_Checks_Suppressed set, or else
      --  if a pragma Elaborate (_All) applies to that scope, in which case
      --  warnings on the scope are also suppressed. For the internal case,
      --  we ignore this flag.

   begin
      --  If the call is known to be within a local Suppress Elaboration
      --  pragma, nothing to check. This can happen in task bodies.

      if (Nkind (N) = N_Function_Call
           or else Nkind (N) = N_Procedure_Call_Statement)
        and then  No_Elaboration_Check (N)
      then
         return;
      end if;

      --  Go to parent for derived subprogram, or to original subprogram
      --  in the case of a renaming (Alias covers both these cases)

      Ent := E;
      loop
         if (Suppress_Elaboration_Warnings (Ent)
              or else Elaboration_Checks_Suppressed (Ent))
           and then (Inst_Case or else No (Alias (Ent)))
         then
            return;
         end if;

         --  Nothing to do for imported entities

         if Is_Imported (Ent) then
            return;
         end if;

         exit when Inst_Case or else No (Alias (Ent));
         Ent := Alias (Ent);
      end loop;

      Decl := Unit_Declaration_Node (Ent);

      if Nkind (Decl) = N_Subprogram_Body then
         Body_Acts_As_Spec := True;

      elsif Nkind (Decl) = N_Subprogram_Declaration
        or else Nkind (Decl) = N_Subprogram_Body_Stub
        or else Inst_Case
      then
         Body_Acts_As_Spec := False;

      --  If we have none of an instantiation, subprogram body or
      --  subprogram declaration, then it is not a case that we want
      --  to check. (One case is a call to a generic formal subprogram,
      --  where we do not want the check in the template).

      else
         return;
      end if;

      E_Scope := Ent;
      loop
         if Elaboration_Checks_Suppressed (E_Scope)
           or else Suppress_Elaboration_Warnings (E_Scope)
         then
            Cunit_SC := True;
         end if;

         --  Exit when we get to compilation unit, not counting subunits

         exit when Is_Compilation_Unit (E_Scope)
           and then (Is_Child_Unit (E_Scope)
                       or else Scope (E_Scope) = Standard_Standard);

         --  If we did not find a compilation unit, other than standard,
         --  then nothing to check (happens in some instantiation cases)

         if E_Scope = Standard_Standard then
            return;

         --  Otherwise move up a scope looking for compilation unit

         else
            E_Scope := Scope (E_Scope);
         end if;
      end loop;

      --  No checks needed for pure or preelaborated compilation units

      if Is_Pure (E_Scope)
        or else Is_Preelaborated (E_Scope)
      then
         return;
      end if;

      --  If the generic entity is within a deeper instance than we are, then
      --  either the instantiation to which we refer itself caused an ABE, in
      --  which case that will be handled separately, or else we know that the
      --  body we need appears as needed at the point of the instantiation.
      --  However, this assumption is only valid if we are in static mode.

      if not Dynamic_Elaboration_Checks
        and then Instantiation_Depth (Sloc (Ent)) >
                 Instantiation_Depth (Sloc (N))
      then
         return;
      end if;

      --  Do not give a warning for a package with no body

      if Ekind (Ent) = E_Generic_Package
        and then not Has_Generic_Body (N)
      then
         return;
      end if;

      --  Case of entity is not in current unit (i.e. with'ed unit case)

      if E_Scope /= C_Scope then

         --  We are only interested in such calls if the outer call was from
         --  elaboration code, or if we are in Dynamic_Elaboration_Checks mode.

         if not From_Elab_Code and then not Dynamic_Elaboration_Checks then
            return;
         end if;

         --  Nothing to do if some scope said that no checks were required

         if Cunit_SC then
            return;
         end if;

         --  Nothing to do for a generic instance, because in this case
         --  the checking was at the point of instantiation of the generic
         --  However, this shortcut is only applicable in static mode.

         if Is_Generic_Instance (Ent) and not Dynamic_Elaboration_Checks then
            return;
         end if;

         --  Nothing to do if subprogram with no separate spec. However,
         --  a call to Deep_Initialize may result in a call to a user-defined
         --  Initialize procedure, which imposes a body dependency. This
         --  happens only if the type is controlled and the Initialize
         --  procedure is not inherited.

         if Body_Acts_As_Spec then
            if Is_TSS (Ent, TSS_Deep_Initialize) then
               declare
                  Typ  : Entity_Id;
                  Init : Entity_Id;
               begin
                  Typ  := Etype (Next_Formal (First_Formal (Ent)));

                  if not Is_Controlled (Typ) then
                     return;
                  else
                     Init := Find_Prim_Op (Typ, Name_Initialize);

                     if Comes_From_Source (Init) then
                        Ent := Init;
                     else
                        return;
                     end if;
                  end if;
               end;

            else
               return;
            end if;
         end if;

         --  Check cases of internal units

         Callee_Unit_Internal :=
           Is_Internal_File_Name
             (Unit_File_Name (Get_Source_Unit (E_Scope)));

         --  Do not give a warning if the with'ed unit is internal
         --  and this is the generic instantiation case (this saves a
         --  lot of hassle dealing with the Text_IO special child units)

         if Callee_Unit_Internal and Inst_Case then
            return;
         end if;

         if C_Scope = Standard_Standard then
            Caller_Unit_Internal := False;
         else
            Caller_Unit_Internal :=
              Is_Internal_File_Name
                (Unit_File_Name (Get_Source_Unit (C_Scope)));
         end if;

         --  Do not give a warning if the with'ed unit is internal
         --  and the caller is not internal (since the binder always
         --  elaborates internal units first).

         if Callee_Unit_Internal and (not Caller_Unit_Internal) then
            return;
         end if;

         --  For now, if debug flag -gnatdE is not set, do no checking for
         --  one internal unit withing another. This fixes the problem with
         --  the sgi build and storage errors. To be resolved later ???

         if (Callee_Unit_Internal and Caller_Unit_Internal)
            and then not Debug_Flag_EE
         then
            return;
         end if;

         if Is_TSS (E, TSS_Deep_Initialize) then
            Ent := E;
         end if;

         --  If the call is in an instance, and the called entity is not
         --  defined in the same instance, then the elaboration issue
         --  focuses around the unit containing the template, it is
         --  this unit which requires an Elaborate_All.

         --  However, if we are doing dynamic elaboration, we need to
         --  chase the call in the usual manner.

         --  We do not handle the case of calling a generic formal correctly
         --  in the static case. See test 4703-004 to explore this gap ???

         Inst_Caller := Instantiation (Get_Source_File_Index (Sloc (N)));
         Inst_Callee := Instantiation (Get_Source_File_Index (Sloc (Ent)));

         if Inst_Caller = No_Location then
            Unit_Caller := No_Unit;
         else
            Unit_Caller := Get_Source_Unit (N);
         end if;

         if Inst_Callee = No_Location then
            Unit_Callee := No_Unit;
         else
            Unit_Callee := Get_Source_Unit (Ent);
         end if;

         if Unit_Caller /= No_Unit
           and then Unit_Callee /= Unit_Caller
           and then not Dynamic_Elaboration_Checks
         then
            E_Scope := Spec_Entity (Cunit_Entity (Unit_Caller));

            --  If we don't get a spec entity, just ignore call. Not
            --  quite clear why this check is necessary.

            if No (E_Scope) then
               return;
            end if;

            --  Otherwise step to enclosing compilation unit

            while not Is_Compilation_Unit (E_Scope) loop
               E_Scope := Scope (E_Scope);
            end loop;

         --  For the case N is not an instance, or a call within instance
         --  We recompute E_Scope for the error message, since we
         --  do NOT want to go to the unit which has the ultimate
         --  declaration in the case of renaming and derivation and
         --  we also want to go to the generic unit in the case of
         --  an instance, and no further.

         else
            --  Loop to carefully follow renamings and derivations
            --  one step outside the current unit, but not further.

            if not Inst_Case
              and then Present (Alias (Ent))
            then
               E_Scope := Alias (Ent);
            else
               E_Scope := Ent;
            end if;

            loop
               while not Is_Compilation_Unit (E_Scope) loop
                  E_Scope := Scope (E_Scope);
               end loop;

               --  If E_Scope is the same as C_Scope, it means that there
               --  definitely was a local renaming or derivation, and we
               --  are not yet out of the current unit.

               exit when E_Scope /= C_Scope;
               Ent := Alias (Ent);
               E_Scope := Ent;

               --  If no alias, there is a previous error

               if No (Ent) then
                  return;
               end if;
            end loop;
         end if;

         if Within_Elaborate_All (E_Scope) then
            return;
         end if;

         --  Find top level scope for called entity (not following renamings
         --  or derivations). This is where the Elaborate_All will go if it
         --  is needed. We start with the called entity, except in the case
         --  of an initialization procedure outside the current package, where
         --  the init proc is in the root package, and we start from the entity
         --  of the name in the call.

         if Is_Entity_Name (Name (N))
           and then Is_Init_Proc (Entity (Name (N)))
           and then not In_Same_Extended_Unit (N, Entity (Name (N)))
         then
            W_Scope := Scope (Entity (Name (N)));
         else
            W_Scope := E;
         end if;

         while not Is_Compilation_Unit (W_Scope) loop
            W_Scope := Scope (W_Scope);
         end loop;

         --  Now check if an elaborate_all (or dynamic check) is needed

         if not Suppress_Elaboration_Warnings (Ent)
           and then not Elaboration_Checks_Suppressed (Ent)
           and then not Suppress_Elaboration_Warnings (E_Scope)
           and then not Elaboration_Checks_Suppressed (E_Scope)
           and then Elab_Warnings
           and then Generate_Warnings
         then
            if Inst_Case then
               Error_Msg_NE
                 ("instantiation of& may raise Program_Error?", N, Ent);

            else
               if Is_Init_Proc (Entity (Name (N)))
                 and then Comes_From_Source (Ent)
               then
                  Error_Msg_NE
                    ("implicit call to & may raise Program_Error?", N, Ent);

               else
                  Error_Msg_NE
                    ("call to & may raise Program_Error?", N, Ent);
               end if;
            end if;

            Error_Msg_Qual_Level := Nat'Last;
            Error_Msg_NE
              ("\missing pragma Elaborate_All for&?", N, W_Scope);
            Error_Msg_Qual_Level := 0;
            Output_Calls (N);

            --  Set flag to prevent further warnings for same unit
            --  unless in All_Errors_Mode.

            if not All_Errors_Mode and not Dynamic_Elaboration_Checks then
               Set_Suppress_Elaboration_Warnings (W_Scope, True);
            end if;
         end if;

         --  Check for runtime elaboration check required

         if Dynamic_Elaboration_Checks then
            if not Elaboration_Checks_Suppressed (Ent)
              and then not Elaboration_Checks_Suppressed (W_Scope)
              and then not Elaboration_Checks_Suppressed (E_Scope)
              and then not Cunit_SC
            then
               --  Runtime elaboration check required. Generate check of the
               --  elaboration Boolean for the unit containing the entity.

               --  Note that for this case, we do check the real unit (the
               --  one from following renamings, since that is the issue!)

               --  Could this possibly miss a useless but required PE???

               Insert_Elab_Check (N,
                 Make_Attribute_Reference (Loc,
                   Attribute_Name => Name_Elaborated,
                   Prefix =>
                     New_Occurrence_Of
                       (Spec_Entity (E_Scope), Loc)));
            end if;

         --  Case of static elaboration model

         else
            --  Do not do anything if elaboration checks suppressed. Note
            --  that we check Ent here, not E, since we want the real entity
            --  for the body to see if checks are suppressed for it, not the
            --  dummy entry for renamings or derivations.

            if Elaboration_Checks_Suppressed (Ent)
              or else Elaboration_Checks_Suppressed (E_Scope)
              or else Elaboration_Checks_Suppressed (W_Scope)
            then
               null;

            --  Here we need to generate an implicit elaborate all

            else
               --  Generate elaborate_all warning unless suppressed

               if (Elab_Warnings and Generate_Warnings and not Inst_Case)
                 and then not Suppress_Elaboration_Warnings (Ent)
                 and then not Suppress_Elaboration_Warnings (E_Scope)
                 and then not Suppress_Elaboration_Warnings (W_Scope)
               then
                  Error_Msg_Node_2 := W_Scope;
                  Error_Msg_NE
                    ("call to& in elaboration code " &
                     "requires pragma Elaborate_All on&?", N, E);
               end if;

               --  Set indication for binder to generate Elaborate_All

               Set_Elaboration_Constraint (N, E, W_Scope);
            end if;
         end if;

      --  Case of entity is in same unit as call or instantiation

      elsif not Inter_Unit_Only then
         Check_Internal_Call (N, Ent, Outer_Scope, E);
      end if;
   end Check_A_Call;

   -----------------------------
   -- Check_Bad_Instantiation --
   -----------------------------

   procedure Check_Bad_Instantiation (N : Node_Id) is
      Ent : Entity_Id;

   begin
      --  Nothing to do if we do not have an instantiation (happens in some
      --  error cases, and also in the formal package declaration case)

      if Nkind (N) not in N_Generic_Instantiation then
         return;

      --  Nothing to do if serious errors detected (avoid cascaded errors)

      elsif Serious_Errors_Detected /= 0 then
         return;

      --  Nothing to do if not in full analysis mode

      elsif not Full_Analysis then
         return;

      --  Nothing to do if inside a generic template

      elsif Inside_A_Generic then
         return;

      --  Nothing to do if a library level instantiation

      elsif Nkind (Parent (N)) = N_Compilation_Unit then
         return;

      --  Nothing to do if we are compiling a proper body for semantic
      --  purposes only. The generic body may be in another proper body.

      elsif
        Nkind (Parent (Unit_Declaration_Node (Main_Unit_Entity))) = N_Subunit
      then
         return;
      end if;

      Ent := Get_Generic_Entity (N);

      --  The case we are interested in is when the generic spec is in the
      --  current declarative part

      if not Same_Elaboration_Scope (Current_Scope, Scope (Ent))
        or else not In_Same_Extended_Unit (N, Ent)
      then
         return;
      end if;

      --  If the generic entity is within a deeper instance than we are, then
      --  either the instantiation to which we refer itself caused an ABE, in
      --  which case that will be handled separately. Otherwise, we know that
      --  the body we need appears as needed at the point of the instantiation.
      --  If they are both at the same level but not within the same instance
      --  then the body of the generic will be in the earlier instance.

      declare
         D1 : constant Int := Instantiation_Depth (Sloc (Ent));
         D2 : constant Int := Instantiation_Depth (Sloc (N));

      begin
         if D1 > D2 then
            return;

         elsif D1 = D2
           and then Is_Generic_Instance (Scope (Ent))
           and then not In_Open_Scopes (Scope (Ent))
         then
            return;
         end if;
      end;

      --  Now we can proceed, if the entity being called has a completion,
      --  then we are definitely OK, since we have already seen the body.

      if Has_Completion (Ent) then
         return;
      end if;

      --  If there is no body, then nothing to do

      if not Has_Generic_Body (N) then
         return;
      end if;

      --  Here we definitely have a bad instantiation

      Error_Msg_NE
        ("?cannot instantiate& before body seen", N, Ent);

      if Present (Instance_Spec (N)) then
         Supply_Bodies (Instance_Spec (N));
      end if;

      Error_Msg_N
        ("\?Program_Error will be raised at run time", N);
      Insert_Elab_Check (N);
      Set_ABE_Is_Certain (N);

   end Check_Bad_Instantiation;

   ---------------------
   -- Check_Elab_Call --
   ---------------------

   procedure Check_Elab_Call
     (N           : Node_Id;
      Outer_Scope : Entity_Id := Empty)
   is
      Ent : Entity_Id;
      P   : Node_Id;

      function Get_Called_Ent return Entity_Id;
      --  Retrieve called entity. If this is a call to a protected subprogram,
      --  entity is a selected component. The callable entity may be absent,
      --  in which case there is no check to perform.  This happens with
      --  non-analyzed calls in nested generics.

      --------------------
      -- Get_Called_Ent --
      --------------------

      function Get_Called_Ent return Entity_Id is
         Nam : Node_Id;

      begin
         Nam := Name (N);

         if No (Nam) then
            return Empty;

         elsif Nkind (Nam) = N_Selected_Component then
            return Entity (Selector_Name (Nam));

         elsif not Is_Entity_Name (Nam) then
            return Empty;

         else
            return Entity (Nam);
         end if;
      end Get_Called_Ent;

   --  Start of processing for Check_Elab_Call

   begin
      --  If the call does not come from the main unit, there is nothing to
      --  check. Elaboration call from units in the context of the main unit
      --  will lead to semantic dependencies when those units are compiled.

      if not In_Extended_Main_Code_Unit (N) then
         return;
      end if;

      --  For an entry call, check relevant restriction

      if Nkind (N) = N_Entry_Call_Statement
         and then not In_Subprogram_Or_Concurrent_Unit
      then
         Check_Restriction (No_Entry_Calls_In_Elaboration_Code, N);

      --  Nothing to do if this is not a call (happens in some error
      --  conditions, and in some cases where rewriting occurs).

      elsif Nkind (N) /= N_Function_Call
        and then Nkind (N) /= N_Procedure_Call_Statement
      then
         return;

      --  Nothing to do if this is a call already rewritten for elab checking.

      elsif Nkind (Parent (N)) = N_Conditional_Expression then
         return;

      --  Nothing to do if inside a generic template

      elsif Inside_A_Generic
        and then not Present (Enclosing_Generic_Body (N))
      then
         return;
      end if;

      --  Here we have a call at elaboration time which must be checked

      if Debug_Flag_LL then
         Write_Str ("  Check_Elab_Call: ");

         if No (Name (N))
           or else not Is_Entity_Name (Name (N))
         then
            Write_Str ("<<not entity name>> ");
         else
            Write_Name (Chars (Entity (Name (N))));
         end if;

         Write_Str ("  call at ");
         Write_Location (Sloc (N));
         Write_Eol;
      end if;

      --  Climb up the tree to make sure we are not inside a
      --  default expression of a parameter specification or
      --  a record component, since in both these cases, we
      --  will be doing the actual call later, not now, and it
      --  is at the time of the actual call (statically speaking)
      --  that we must do our static check, not at the time of
      --  its initial analysis). However, we have to check calls
      --  within component definitions (e.g., a function call
      --  that determines an array component bound), so we
      --  terminate the loop in that case.

      P := Parent (N);
      while Present (P) loop
         if Nkind (P) = N_Parameter_Specification
              or else
            Nkind (P) = N_Component_Declaration
         then
            return;

         --  The call occurs within the constraint of a component,
         --  so it must be checked.

         elsif Nkind (P) = N_Component_Definition then
            exit;

         else
            P := Parent (P);
         end if;
      end loop;

      --  Stuff that happens only at the outer level

      if No (Outer_Scope) then
         Elab_Visited.Set_Last (0);

         --  Nothing to do if current scope is Standard (this is a bit
         --  odd, but it happens in the case of generic instantiations).

         C_Scope := Current_Scope;

         if C_Scope = Standard_Standard then
            return;
         end if;

         --  First case, we are in elaboration code

         From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit;
         if From_Elab_Code then

            --  Complain if call that comes from source in preelaborated
            --  unit and we are not inside a subprogram (i.e. we are in
            --  elab code)

            if Comes_From_Source (N)
              and then In_Preelaborated_Unit
              and then not In_Inlined_Body
            then
               Error_Msg_N
                 ("non-static call not allowed in preelaborated unit", N);
               return;
            end if;

         --  Second case, we are inside a subprogram or concurrent unit
         --  i.e, we are not in elaboration code.

         else
            --  In this case, the issue is whether we are inside the
            --  declarative part of the unit in which we live, or inside
            --  its statements. In the latter case, there is no issue of
            --  ABE calls at this level (a call from outside to the unit
            --  in which we live might cause an ABE, but that will be
            --  detected when we analyze that outer level call, as it
            --  recurses into the called unit).

            --  Climb up the tree, doing this test, and also testing
            --  for being inside a default expression, which, as
            --  discussed above, is not checked at this stage.

            declare
               P : Node_Id;
               L : List_Id;

            begin
               P := N;
               loop
                  --  If we find a parentless subtree, it seems safe to
                  --  assume that we are not in a declarative part and
                  --  that no checking is required.

                  if No (P) then
                     return;
                  end if;

                  if Is_List_Member (P) then
                     L := List_Containing (P);
                     P := Parent (L);
                  else
                     L := No_List;
                     P := Parent (P);
                  end if;

                  exit when Nkind (P) = N_Subunit;

                  --  Filter out case of default expressions, where
                  --  we do not do the check at this stage.

                  if Nkind (P) = N_Parameter_Specification
                       or else
                     Nkind (P) = N_Component_Declaration
                  then
                     return;
                  end if;

                  if Nkind (P) = N_Subprogram_Body
                       or else
                     Nkind (P) = N_Protected_Body
                       or else
                     Nkind (P) = N_Task_Body
                       or else
                     Nkind (P) = N_Block_Statement
                  then
                     if L = Declarations (P) then
                        exit;

                     --  We are not in elaboration code, but we are doing
                     --  dynamic elaboration checks, in this case, we still
                     --  need to do the call, since the subprogram we are in
                     --  could be called from another unit, also in dynamic
                     --  elaboration check mode, at elaboration time.

                     elsif Dynamic_Elaboration_Checks then

                        --  This is a rather new check, going into version
                        --  3.14a1 for the first time (V1.80 of this unit),
                        --  so we provide a debug flag to enable it. That
                        --  way we have an easy work around for regressions
                        --  that are caused by this new check. This debug
                        --  flag can be removed later.

                        if Debug_Flag_DD then
                           return;
                        end if;

                        --  Do the check in this case

                        exit;

                     elsif Nkind (P) = N_Task_Body then

                        --  The check is deferred until Check_Task_Activation
                        --  but we need to capture local suppress pragmas
                        --  that may inhibit checks on this call.

                        Ent := Get_Called_Ent;

                        if No (Ent) then
                           return;

                        elsif Elaboration_Checks_Suppressed (Current_Scope)
                          or else Elaboration_Checks_Suppressed (Ent)
                          or else Elaboration_Checks_Suppressed (Scope (Ent))
                        then
                           Set_No_Elaboration_Check (N);
                        end if;

                        return;

                     --  Static model, call is not in elaboration code, we
                     --  never need to worry, because in the static model
                     --  the top level caller always takes care of things.

                     else
                        return;
                     end if;
                  end if;
               end loop;
            end;
         end if;
      end if;

      Ent := Get_Called_Ent;

      if No (Ent) then
         return;
      end if;

      --  Nothing to do if this is a recursive call (i.e. a call to
      --  an entity that is already in the Elab_Call stack)

      for J in 1 .. Elab_Visited.Last loop
         if Ent = Elab_Visited.Table (J) then
            return;
         end if;
      end loop;

      --  See if we need to analyze this call. We analyze it if either of
      --  the following conditions is met:

      --    It is an inner level call (since in this case it was triggered
      --    by an outer level call from elaboration code), but only if the
      --    call is within the scope of the original outer level call.

      --    It is an outer level call from elaboration code, or the called
      --    entity is in the same elaboration scope.

      --  And in these cases, we will check both inter-unit calls and
      --  intra-unit (within a single unit) calls.

      C_Scope := Current_Scope;

      --  If not outer level call, then we follow it if it is within
      --  the original scope of the outer call.

      if Present (Outer_Scope)
        and then Within (Scope (Ent), Outer_Scope)
      then
         Set_C_Scope;
         Check_A_Call (N, Ent, Outer_Scope, Inter_Unit_Only => False);

      elsif Elaboration_Checks_Suppressed (Current_Scope) then
         null;

      elsif From_Elab_Code then
         Set_C_Scope;
         Check_A_Call (N, Ent, Standard_Standard, Inter_Unit_Only => False);

      elsif Same_Elaboration_Scope (C_Scope, Scope (Ent)) then
         Set_C_Scope;
         Check_A_Call (N, Ent, Scope (Ent), Inter_Unit_Only => False);

      --  If none of those cases holds, but Dynamic_Elaboration_Checks mode
      --  is set, then we will do the check, but only in the inter-unit case
      --  (this is to accommodate unguarded elaboration calls from other units
      --  in which this same mode is set). We don't want warnings in this case,
      --  it would generate warnings having nothing to do with elaboration.

      elsif Dynamic_Elaboration_Checks then
         Set_C_Scope;
         Check_A_Call
           (N,
            Ent,
            Standard_Standard,
            Inter_Unit_Only => True,
            Generate_Warnings => False);

      --  Otherwise nothing to do

      else
         return;
      end if;

      --  A call to an Init_Proc in elaboration code may bring additional
      --  dependencies, if some of the record components thereof have
      --  initializations that are function calls that come from source.
      --  We treat the current node as a call to each of these functions,
      --  to check their elaboration impact.

      if Is_Init_Proc (Ent)
        and then From_Elab_Code
      then
         Process_Init_Proc : declare
            Unit_Decl : constant Node_Id := Unit_Declaration_Node (Ent);

            function Process (Nod : Node_Id) return Traverse_Result;
            --  Find subprogram calls within body of init_proc for
            --  Traverse instantiation below.

            function Process (Nod : Node_Id) return Traverse_Result is
               Func : Entity_Id;

            begin
               if (Nkind (Nod) = N_Function_Call
                    or else Nkind (Nod) = N_Procedure_Call_Statement)
                 and then Is_Entity_Name (Name (Nod))
               then
                  Func := Entity (Name (Nod));

                  if Comes_From_Source (Func) then
                     Check_A_Call
                       (N, Func, Standard_Standard, Inter_Unit_Only => True);
                  end if;

                  return OK;

               else
                  return OK;
               end if;
            end Process;

            procedure Traverse_Body is new Traverse_Proc (Process);

         --  Start of processing for Process_Init_Proc

         begin
            if Nkind (Unit_Decl) = N_Subprogram_Body then
               Traverse_Body (Handled_Statement_Sequence (Unit_Decl));
            end if;
         end Process_Init_Proc;
      end if;
   end Check_Elab_Call;

   ----------------------
   -- Check_Elab_Calls --
   ----------------------

   procedure Check_Elab_Calls is
   begin
      --  If expansion is disabled, do not generate any checks. Also
      --  skip checks if any subunits are missing because in either
      --  case we lack the full information that we need, and no object
      --  file will be created in any case.

      if not Expander_Active
        or else Is_Generic_Unit (Cunit_Entity (Main_Unit))
        or else Subunits_Missing
      then
         return;
      end if;

      --  Skip delayed calls if we had any errors

      if Serious_Errors_Detected = 0 then
         Delaying_Elab_Checks := False;
         Expander_Mode_Save_And_Set (True);

         for J in Delay_Check.First .. Delay_Check.Last loop
            New_Scope (Delay_Check.Table (J).Curscop);
            From_Elab_Code := Delay_Check.Table (J).From_Elab_Code;

            Check_Internal_Call_Continue (
              N           => Delay_Check.Table (J).N,
              E           => Delay_Check.Table (J).E,
              Outer_Scope => Delay_Check.Table (J).Outer_Scope,
              Orig_Ent    => Delay_Check.Table (J).Orig_Ent);

            Pop_Scope;
         end loop;

         --  Set Delaying_Elab_Checks back on for next main compilation

         Expander_Mode_Restore;
         Delaying_Elab_Checks := True;
      end if;
   end Check_Elab_Calls;

   ------------------------------
   -- Check_Elab_Instantiation --
   ------------------------------

   procedure Check_Elab_Instantiation
     (N           : Node_Id;
      Outer_Scope : Entity_Id := Empty)
   is
      Ent : Entity_Id;

   begin
      --  Check for and deal with bad instantiation case. There is some
      --  duplicated code here, but we will worry about this later ???

      Check_Bad_Instantiation (N);

      if ABE_Is_Certain (N) then
         return;
      end if;

      --  Nothing to do if we do not have an instantiation (happens in some
      --  error cases, and also in the formal package declaration case)

      if Nkind (N) not in N_Generic_Instantiation then
         return;
      end if;

      --  Nothing to do if inside a generic template

      if Inside_A_Generic then
         return;
      end if;

      --  Nothing to do if the instantiation is not in the main unit.

      if not In_Extended_Main_Code_Unit (N) then
         return;
      end if;

      Ent := Get_Generic_Entity (N);
      From_Elab_Code := not In_Subprogram_Or_Concurrent_Unit;

      --  See if we need to analyze this instantiation. We analyze it if
      --  either of the following conditions is met:

      --    It is an inner level instantiation (since in this case it was
      --    triggered by an outer level call from elaboration code), but
      --    only if the instantiation is within the scope of the original
      --    outer level call.

      --    It is an outer level instantiation from elaboration code, or the
      --    instantiated entity is in the same elaboratoin scope.

      --  And in these cases, we will check both the inter-unit case and
      --  the intra-unit (within a single unit) case.

      C_Scope := Current_Scope;

      if Present (Outer_Scope)
        and then Within (Scope (Ent), Outer_Scope)
      then
         Set_C_Scope;
         Check_A_Call (N, Ent, Outer_Scope, Inter_Unit_Only => False);

      elsif From_Elab_Code then
         Set_C_Scope;
         Check_A_Call (N, Ent, Standard_Standard, Inter_Unit_Only => False);

      elsif Same_Elaboration_Scope (C_Scope, Scope (Ent)) then
         Set_C_Scope;
         Check_A_Call (N, Ent, Scope (Ent), Inter_Unit_Only => False);

      --  If none of those cases holds, but Dynamic_Elaboration_Checks mode
      --  is set, then we will do the check, but only in the inter-unit case
      --  (this is to accommodate unguarded elaboration calls from other units
      --  in which this same mode is set). We inhibit warnings in this case,
      --  since this instantiation is not occurring in elaboration code.

      elsif Dynamic_Elaboration_Checks then
         Set_C_Scope;
         Check_A_Call
           (N,
            Ent,
            Standard_Standard,
            Inter_Unit_Only => True,
            Generate_Warnings => False);

      else
         return;
      end if;
   end Check_Elab_Instantiation;

   -------------------------
   -- Check_Internal_Call --
   -------------------------

   procedure Check_Internal_Call
     (N           : Node_Id;
      E           : Entity_Id;
      Outer_Scope : Entity_Id;
      Orig_Ent    : Entity_Id)
   is
      Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;

   begin
      --  If not function or procedure call or instantiation, then ignore
      --  call (this happens in some error case and rewriting cases)

      if Nkind (N) /= N_Function_Call
           and then
         Nkind (N) /= N_Procedure_Call_Statement
           and then
         not Inst_Case
      then
         return;

      --  Nothing to do if this is a call or instantiation that has
      --  already been found to be a sure ABE

      elsif ABE_Is_Certain (N) then
         return;

      --  Nothing to do if errors already detected (avoid cascaded errors)

      elsif Serious_Errors_Detected /= 0 then
         return;

      --  Nothing to do if not in full analysis mode

      elsif not Full_Analysis then
         return;

      --  Nothing to do if within a default expression, since the call
      --  is not actualy being made at this time.

      elsif In_Default_Expression then
         return;

      --  Nothing to do for call to intrinsic subprogram

      elsif Is_Intrinsic_Subprogram (E) then
         return;

      --  No need to trace local calls if checking task activation, because
      --  other local bodies are elaborated already.

      elsif In_Task_Activation then
         return;
      end if;

      --  Delay this call if we are still delaying calls

      if Delaying_Elab_Checks then
         Delay_Check.Increment_Last;
         Delay_Check.Table (Delay_Check.Last) :=
           (N              => N,
            E              => E,
            Orig_Ent       => Orig_Ent,
            Curscop        => Current_Scope,
            Outer_Scope    => Outer_Scope,
            From_Elab_Code => From_Elab_Code);
         return;

      --  Otherwise, call phase 2 continuation right now

      else
         Check_Internal_Call_Continue (N, E, Outer_Scope, Orig_Ent);
      end if;

   end Check_Internal_Call;

   ----------------------------------
   -- Check_Internal_Call_Continue --
   ----------------------------------

   procedure Check_Internal_Call_Continue
     (N           : Node_Id;
      E           : Entity_Id;
      Outer_Scope : Entity_Id;
      Orig_Ent    : Entity_Id)
   is
      Loc       : constant Source_Ptr := Sloc (N);
      Inst_Case : constant Boolean := Is_Generic_Unit (E);

      Sbody : Node_Id;
      Ebody : Entity_Id;

      function Process (N : Node_Id) return Traverse_Result;
      --  Function applied to each node as we traverse the body.
      --  Checks for call that needs checking, and if so checks
      --  it. Always returns OK, so entire tree is traversed.

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

      function Process (N : Node_Id) return Traverse_Result is
      begin
         --  If user has specified that there are no entry calls in elaboration
         --  code, do not trace past an accept statement, because the rendez-
         --  vous will happen after elaboration.

         if (Nkind (Original_Node (N)) = N_Accept_Statement
              or else Nkind (Original_Node (N)) = N_Selective_Accept)
           and then Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
         then
            return Abandon;

         --  If we have a subprogram call, check it

         elsif Nkind (N) = N_Function_Call
           or else Nkind (N) = N_Procedure_Call_Statement
         then
            Check_Elab_Call (N, Outer_Scope);
            return OK;

         --  If we have a generic instantiation, check it

         elsif Nkind (N) in N_Generic_Instantiation then
            Check_Elab_Instantiation (N, Outer_Scope);
            return OK;

         --  Skip subprogram bodies that come from source (wait for
         --  call to analyze these). The reason for the come from
         --  source test is to avoid catching task bodies.

         --  For task bodies, we should really avoid these too, waiting
         --  for the task activation, but that's too much trouble to
         --  catch for now, so we go in unconditionally. This is not
         --  so terrible, it means the error backtrace is not quite
         --  complete, and we are too eager to scan bodies of tasks
         --  that are unused, but this is hardly very significant!

         elsif Nkind (N) = N_Subprogram_Body
           and then Comes_From_Source (N)
         then
            return Skip;

         else
            return OK;
         end if;
      end Process;

      procedure Traverse is new Atree.Traverse_Proc;
      --  Traverse procedure using above Process function

   --  Start of processing for Check_Internal_Call_Continue

   begin
      --  Save outer level call if at outer level

      if Elab_Call.Last = 0 then
         Outer_Level_Sloc := Loc;
      end if;

      Elab_Visited.Increment_Last;
      Elab_Visited.Table (Elab_Visited.Last) := E;

      --  If the call is to a function that renames a literal, no check
      --  is needed.

      if Ekind (E) = E_Enumeration_Literal then
         return;
      end if;

      Sbody := Unit_Declaration_Node (E);

      if Nkind (Sbody) /= N_Subprogram_Body
           and then
         Nkind (Sbody) /= N_Package_Body
      then
         Ebody := Corresponding_Body (Sbody);

         if No (Ebody) then
            return;
         else
            Sbody := Unit_Declaration_Node (Ebody);
         end if;
      end if;

      --  If the body appears after the outer level call or
      --  instantiation then we have an error case handled below.

      if Earlier_In_Extended_Unit (Outer_Level_Sloc, Sloc (Sbody))
        and then not In_Task_Activation
      then
         null;

      --  If we have the instantiation case we are done, since we now
      --  know that the body of the generic appeared earlier.

      elsif Inst_Case then
         return;

      --  Otherwise we have a call, so we trace through the called
      --  body to see if it has any problems ..

      else
         pragma Assert (Nkind (Sbody) = N_Subprogram_Body);

         Elab_Call.Increment_Last;
         Elab_Call.Table (Elab_Call.Last).Cloc := Loc;
         Elab_Call.Table (Elab_Call.Last).Ent  := E;

         if Debug_Flag_LL then
            Write_Str ("Elab_Call.Last = ");
            Write_Int (Int (Elab_Call.Last));
            Write_Str ("   Ent = ");
            Write_Name (Chars (E));
            Write_Str ("   at ");
            Write_Location (Sloc (N));
            Write_Eol;
         end if;

         --  Now traverse declarations and statements of subprogram body.
         --  Note that we cannot simply Traverse (Sbody), since traverse
         --  does not normally visit subprogram bodies.

         declare
            Decl : Node_Id := First (Declarations (Sbody));

         begin
            while Present (Decl) loop
               Traverse (Decl);
               Next (Decl);
            end loop;
         end;

         Traverse (Handled_Statement_Sequence (Sbody));

         Elab_Call.Decrement_Last;
         return;
      end if;

      --  Here is the case of calling a subprogram where the body has
      --  not yet been encountered, a warning message is needed.

      --  If we have nothing in the call stack, then this is at the
      --  outer level, and the ABE is bound to occur.

      if Elab_Call.Last = 0 then
         if Inst_Case then
            Error_Msg_NE
              ("?cannot instantiate& before body seen", N, Orig_Ent);
         else
            Error_Msg_NE
              ("?cannot call& before body seen", N, Orig_Ent);
         end if;

         Error_Msg_N
           ("\?Program_Error will be raised at run time", N);
         Insert_Elab_Check (N);

      --  Call is not at outer level

      else
         --  Deal with dynamic elaboration check

         if not Elaboration_Checks_Suppressed (E) then
            Set_Elaboration_Entity_Required (E);

            --  Case of no elaboration entity allocated yet

            if No (Elaboration_Entity (E)) then

               --  Create object declaration for elaboration entity, and put it
               --  just in front of the spec of the subprogram or generic unit,
               --  in the same scope as this unit.

               declare
                  Loce : constant Source_Ptr := Sloc (E);
                  Ent  : constant Entity_Id  :=
                           Make_Defining_Identifier (Loc,
                             Chars => New_External_Name (Chars (E), 'E'));

               begin
                  Set_Elaboration_Entity (E, Ent);
                  New_Scope (Scope (E));

                  Insert_Action (Declaration_Node (E),
                    Make_Object_Declaration (Loce,
                      Defining_Identifier => Ent,
                      Object_Definition =>
                        New_Occurrence_Of (Standard_Boolean, Loce),
                      Expression => New_Occurrence_Of (Standard_False, Loce)));

                  --  Set elaboration flag at the point of the body

                  Set_Elaboration_Flag (Sbody, E);

                  --  Kill current value indication. This is necessary
                  --  because the tests of this flag are inserted out of
                  --  sequence and must not pick up bogus indications of
                  --  the wrong constant value. Also, this is never a true
                  --  constant, since one way or another, it gets reset.

                  Set_Current_Value    (Ent, Empty);
                  Set_Is_True_Constant (Ent, False);
                  Pop_Scope;
               end;
            end if;

            --  Generate check of the elaboration Boolean

            Insert_Elab_Check (N,
              New_Occurrence_Of (Elaboration_Entity (E), Loc));
         end if;

         --  Generate the warning

         if not Suppress_Elaboration_Warnings (E)
           and then not Elaboration_Checks_Suppressed (E)
         then
            if Inst_Case then
               Error_Msg_NE
                 ("instantiation of& may occur before body is seen?",
                  N, Orig_Ent);
            else
               Error_Msg_NE
                 ("call to& may occur before body is seen?", N, Orig_Ent);
            end if;

            Error_Msg_N
              ("\Program_Error may be raised at run time?", N);

            Output_Calls (N);
         end if;
      end if;

      --  Set flag to suppress further warnings on same subprogram
      --  unless in all errors mode

      if not All_Errors_Mode then
         Set_Suppress_Elaboration_Warnings (E);
      end if;
   end Check_Internal_Call_Continue;

   ---------------------------
   -- Check_Task_Activation --
   ---------------------------

   procedure Check_Task_Activation (N : Node_Id) is
      Loc         : constant Source_Ptr := Sloc (N);
      Inter_Procs : constant Elist_Id   := New_Elmt_List;
      Intra_Procs : constant Elist_Id   := New_Elmt_List;
      Ent         : Entity_Id;
      P           : Entity_Id;
      Task_Scope  : Entity_Id;
      Cunit_SC    : Boolean := False;
      Decl        : Node_Id;
      Elmt        : Elmt_Id;
      Enclosing   : Entity_Id;

      procedure Add_Task_Proc (Typ : Entity_Id);
      --  Add to Task_Procs the task body procedure(s) of task types in Typ.
      --  For record types, this procedure recurses over component types.

      procedure Collect_Tasks (Decls : List_Id);
      --  Collect the types of the tasks that are to be activated in the given
      --  list of declarations, in order to perform elaboration checks on the
      --  corresponding task procedures which are called implicitly here.

      function Outer_Unit (E : Entity_Id) return Entity_Id;
      --  find enclosing compilation unit of Entity, ignoring subunits, or
      --  else enclosing subprogram. If E is not a package, there is no need
      --  for inter-unit elaboration checks.

      -------------------
      -- Add_Task_Proc --
      -------------------

      procedure Add_Task_Proc (Typ : Entity_Id) is
         Comp : Entity_Id;
         Proc : Entity_Id := Empty;

      begin
         if Is_Task_Type (Typ) then
            Proc := Get_Task_Body_Procedure (Typ);

         elsif Is_Array_Type (Typ)
           and then Has_Task (Base_Type (Typ))
         then
            Add_Task_Proc (Component_Type (Typ));

         elsif Is_Record_Type (Typ)
           and then Has_Task (Base_Type (Typ))
         then
            Comp := First_Component (Typ);

            while Present (Comp) loop
               Add_Task_Proc (Etype (Comp));
               Comp := Next_Component (Comp);
            end loop;
         end if;

         --  If the task type is another unit, we will perform the usual
         --  elaboration check on its enclosing unit. If the type is in the
         --  same unit, we can trace the task body as for an internal call,
         --  but we only need to examine other external calls, because at
         --  the point the task is activated, internal subprogram bodies
         --  will have been elaborated already. We keep separate lists for
         --  each kind of task.

         --  Skip this test if errors have occurred, since in this case
         --  we can get false indications.

         if Serious_Errors_Detected /= 0 then
            return;
         end if;

         if Present (Proc) then
            if Outer_Unit (Scope (Proc)) = Enclosing then

               if No (Corresponding_Body (Unit_Declaration_Node (Proc)))
                 and then
                   (not Is_Generic_Instance (Scope (Proc))
                      or else
                    Scope (Proc) = Scope (Defining_Identifier (Decl)))
               then
                  Error_Msg_N
                    ("task will be activated before elaboration of its body?",
                      Decl);
                  Error_Msg_N
                    ("Program_Error will be raised at run-time?", Decl);

               elsif
                 Present (Corresponding_Body (Unit_Declaration_Node (Proc)))
               then
                  Append_Elmt (Proc, Intra_Procs);
               end if;

            else
               Elmt := First_Elmt (Inter_Procs);

               --  No need for multiple entries of the same type.

               while Present (Elmt) loop
                  if Node (Elmt) = Proc then
                     return;
                  end if;

                  Next_Elmt (Elmt);
               end loop;

               Append_Elmt (Proc, Inter_Procs);
            end if;
         end if;
      end Add_Task_Proc;

      -------------------
      -- Collect_Tasks --
      -------------------

      procedure Collect_Tasks (Decls : List_Id) is
      begin
         if Present (Decls) then
            Decl := First (Decls);

            while Present (Decl) loop

               if Nkind (Decl) = N_Object_Declaration
                 and then Has_Task (Etype (Defining_Identifier (Decl)))
               then
                  Add_Task_Proc (Etype (Defining_Identifier (Decl)));
               end if;

               Next (Decl);
            end loop;
         end if;
      end Collect_Tasks;

      ----------------
      -- Outer_Unit --
      ----------------

      function Outer_Unit (E : Entity_Id) return Entity_Id is
         Outer : Entity_Id := E;

      begin
         while Present (Outer) loop
            if Elaboration_Checks_Suppressed (Outer) then
               Cunit_SC := True;
            end if;

            exit when Is_Child_Unit (Outer)
              or else Scope (Outer) = Standard_Standard
              or else Ekind (Outer) /= E_Package;
            Outer := Scope (Outer);
         end loop;

         return Outer;
      end Outer_Unit;

   --  Start of processing for Check_Task_Activation

   begin
      Enclosing := Outer_Unit (Current_Scope);

      --  Find all tasks declared in the current unit.

      if Nkind (N) = N_Package_Body then
         P := Unit_Declaration_Node (Corresponding_Spec (N));

         Collect_Tasks (Declarations (N));
         Collect_Tasks (Visible_Declarations (Specification (P)));
         Collect_Tasks (Private_Declarations (Specification (P)));

      elsif Nkind (N) = N_Package_Declaration then
         Collect_Tasks (Visible_Declarations (Specification (N)));
         Collect_Tasks (Private_Declarations (Specification (N)));

      else
         Collect_Tasks (Declarations (N));
      end if;

      --  We only perform detailed checks in all tasks are library level
      --  entities. If the master is a subprogram or task, activation will
      --  depend on the activation of the master itself.
      --  Should dynamic checks be added in the more general case???

      if Ekind (Enclosing) /= E_Package then
         return;
      end if;

      --  For task types defined in other units, we want the unit containing
      --  the task body to be elaborated before the current one.

      Elmt := First_Elmt (Inter_Procs);

      while Present (Elmt) loop
         Ent := Node (Elmt);
         Task_Scope := Outer_Unit (Scope (Ent));

         if not Is_Compilation_Unit (Task_Scope) then
            null;

         elsif Suppress_Elaboration_Warnings (Task_Scope)
           or else Elaboration_Checks_Suppressed (Task_Scope)
         then
            null;

         elsif Dynamic_Elaboration_Checks then
            if not Elaboration_Checks_Suppressed (Ent)
              and then not Cunit_SC
              and then
                not Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
            then
               --  Runtime elaboration check required. generate check of the
               --  elaboration Boolean for the unit containing the entity.

               Insert_Elab_Check (N,
                 Make_Attribute_Reference (Loc,
                   Attribute_Name => Name_Elaborated,
                   Prefix =>
                     New_Occurrence_Of
                       (Spec_Entity (Task_Scope), Loc)));
            end if;

         else
            --  Force the binder to elaborate other unit first

            if not Suppress_Elaboration_Warnings (Ent)
              and then not Elaboration_Checks_Suppressed (Ent)
              and then Elab_Warnings
              and then not Suppress_Elaboration_Warnings (Task_Scope)
              and then not Elaboration_Checks_Suppressed (Task_Scope)
            then
               Error_Msg_Node_2 := Task_Scope;
               Error_Msg_NE ("activation of an instance of task type&" &
                  " requires pragma Elaborate_All on &?", N, Ent);
            end if;

            Set_Elaborate_All_Desirable (Task_Scope);
            Set_Suppress_Elaboration_Warnings (Task_Scope);
         end if;

         Next_Elmt (Elmt);
      end loop;

      --  For tasks declared in the current unit, trace other calls within
      --  the task procedure bodies, which are available.

      In_Task_Activation := True;
      Elmt := First_Elmt (Intra_Procs);

      while Present (Elmt) loop
         Ent := Node (Elmt);
         Check_Internal_Call_Continue (N, Ent, Enclosing, Ent);
         Next_Elmt (Elmt);
      end loop;

      In_Task_Activation := False;
   end Check_Task_Activation;

   --------------------------------
   -- Set_Elaboration_Constraint --
   --------------------------------

   procedure Set_Elaboration_Constraint
    (Call : Node_Id;
     Subp : Entity_Id;
     Scop : Entity_Id)
   is
      Elab_Unit  : Entity_Id;
      Init_Call  : constant Boolean :=
                     Chars (Subp) = Name_Initialize
                       and then Comes_From_Source (Subp)
                       and then Present (Parameter_Associations (Call))
                       and then Is_Controlled
                         (Etype (First (Parameter_Associations (Call))));
   begin
      --  If the unit is mentioned in a with_clause of the current
      --  unit, it is visible, and we can set the elaboration flag.

      if Is_Immediately_Visible (Scop)
        or else
          (Is_Child_Unit (Scop) and then Is_Visible_Child_Unit (Scop))
      then
         Set_Elaborate_All_Desirable (Scop);
         Set_Suppress_Elaboration_Warnings (Scop, True);
         return;
      end if;

      --  If this is not an initialization call or a call using object notation
      --  we know that the unit of the called entity is in the context, and
      --  we can set the flag as well. The unit need not be visible if the call
      --  occurs within an instantiation.

      if Is_Init_Proc (Subp)
        or else Init_Call
        or else Nkind (Original_Node (Call)) = N_Selected_Component
      then
         null;  --  detailed processing follows.

      else
         Set_Elaborate_All_Desirable (Scop);
         Set_Suppress_Elaboration_Warnings (Scop, True);
         return;
      end if;

      --  If the unit is not in the context, there must be an intermediate
      --  unit that is, on which we need to place to elaboration flag.

      if Is_Init_Proc (Subp)
        or else Init_Call
      then
         --  The initialization call is on an object whose type is not
         --  declared in the same scope as the subprogram. The type of
         --  the object must be a subtype of the type of operation. This
         --  object is the first actual in the call.

         declare
            Typ  : constant Entity_Id :=
                     Etype (First (Parameter_Associations (Call)));
         begin
            Elab_Unit := Scope (Typ);

            while (Present (Elab_Unit))
              and then not Is_Compilation_Unit (Elab_Unit)
            loop
               Elab_Unit := Scope (Elab_Unit);
            end loop;
         end;
      elsif Nkind (Original_Node (Call)) = N_Selected_Component then

         --  If original node uses selected component notation, the
         --  prefix is visible and determines the scope that must be
         --  elaborated. After rewriting, the prefix is the first actual
         --  in the call.

         Elab_Unit := Scope (Etype (First (Parameter_Associations (Call))));

      else
         --  Using previously computed scope. If the elaboration check is
         --  done after analysis, the scope is not visible any longer, but
         --  must still be in the context.

         Elab_Unit := Scop;
      end if;

      Set_Elaborate_All_Desirable (Elab_Unit);
      Set_Suppress_Elaboration_Warnings (Elab_Unit, True);
   end Set_Elaboration_Constraint;

   ----------------------
   -- Has_Generic_Body --
   ----------------------

   function Has_Generic_Body (N : Node_Id) return Boolean is
      Ent  : constant Entity_Id := Get_Generic_Entity (N);
      Decl : constant Node_Id   := Unit_Declaration_Node (Ent);
      Scop : Entity_Id;

      function Find_Body_In (E : Entity_Id; N : Node_Id) return Node_Id;
      --  Determine if the list of nodes headed by N and linked by Next
      --  contains a package body for the package spec entity E, and if
      --  so return the package body. If not, then returns Empty.

      function Load_Package_Body (Nam : Unit_Name_Type) return Node_Id;
      --  This procedure is called load the unit whose name is given by Nam.
      --  This unit is being loaded to see whether it contains an optional
      --  generic body. The returned value is the loaded unit, which is
      --  always a package body (only package bodies can contain other
      --  entities in the sense in which Has_Generic_Body is interested).
      --  We only attempt to load bodies if we are generating code. If we
      --  are in semantics check only mode, then it would be wrong to load
      --  bodies that are not required from a semantic point of view, so
      --  in this case we return Empty. The result is that the caller may
      --  incorrectly decide that a generic spec does not have a body when
      --  in fact it does, but the only harm in this is that some warnings
      --  on elaboration problems may be lost in semantic checks only mode,
      --  which is not big loss. We also return Empty if we go for a body
      --  and it is not there.

      function Locate_Corresponding_Body (PE : Entity_Id) return Node_Id;
      --  PE is the entity for a package spec. This function locates the
      --  corresponding package body, returning Empty if none is found.
      --  The package body returned is fully parsed but may not yet be
      --  analyzed, so only syntactic fields should be referenced.

      ------------------
      -- Find_Body_In --
      ------------------

      function Find_Body_In (E : Entity_Id; N : Node_Id) return Node_Id is
         Nod : Node_Id;

      begin
         Nod := N;
         while Present (Nod) loop

            --  If we found the package body we are looking for, return it

            if Nkind (Nod) = N_Package_Body
              and then Chars (Defining_Unit_Name (Nod)) = Chars (E)
            then
               return Nod;

            --  If we found the stub for the body, go after the subunit,
            --  loading it if necessary.

            elsif Nkind (Nod) = N_Package_Body_Stub
              and then Chars (Defining_Identifier (Nod)) = Chars (E)
            then
               if Present (Library_Unit (Nod)) then
                  return Unit (Library_Unit (Nod));

               else
                  return Load_Package_Body (Get_Unit_Name (Nod));
               end if;

            --  If neither package body nor stub, keep looking on chain

            else
               Next (Nod);
            end if;
         end loop;

         return Empty;
      end Find_Body_In;

      -----------------------
      -- Load_Package_Body --
      -----------------------

      function Load_Package_Body (Nam : Unit_Name_Type) return Node_Id is
         U : Unit_Number_Type;

      begin
         if Operating_Mode /= Generate_Code then
            return Empty;
         else
            U :=
              Load_Unit
                (Load_Name  => Nam,
                 Required   => False,
                 Subunit    => False,
                 Error_Node => N);

            if U = No_Unit then
               return Empty;
            else
               return Unit (Cunit (U));
            end if;
         end if;
      end Load_Package_Body;

      -------------------------------
      -- Locate_Corresponding_Body --
      -------------------------------

      function Locate_Corresponding_Body (PE : Entity_Id) return Node_Id is
         Spec  : constant Node_Id   := Declaration_Node (PE);
         Decl  : constant Node_Id   := Parent (Spec);
         Scop  : constant Entity_Id := Scope (PE);
         PBody : Node_Id;

      begin
         if Is_Library_Level_Entity (PE) then

            --  If package is a library unit that requires a body, we have
            --  no choice but to go after that body because it might contain
            --  an optional body for the original generic package.

            if Unit_Requires_Body (PE) then

               --  Load the body. Note that we are a little careful here to
               --  use Spec to get the unit number, rather than PE or Decl,
               --  since in the case where the package is itself a library
               --  level instantiation, Spec will properly reference the
               --  generic template, which is what we really want.

               return
                 Load_Package_Body
                   (Get_Body_Name (Unit_Name (Get_Source_Unit (Spec))));

            --  But if the package is a library unit that does NOT require
            --  a body, then no body is permitted, so we are sure that there
            --  is no body for the original generic package.

            else
               return Empty;
            end if;

         --  Otherwise look and see if we are embedded in a further package

         elsif Is_Package (Scop) then

            --  If so, get the body of the enclosing package, and look in
            --  its package body for the package body we are looking for.

            PBody := Locate_Corresponding_Body (Scop);

            if No (PBody) then
               return Empty;
            else
               return Find_Body_In (PE, First (Declarations (PBody)));
            end if;

         --  If we are not embedded in a further package, then the body
         --  must be in the same declarative part as we are.

         else
            return Find_Body_In (PE, Next (Decl));
         end if;
      end Locate_Corresponding_Body;

   --  Start of processing for Has_Generic_Body

   begin
      if Present (Corresponding_Body (Decl)) then
         return True;

      elsif Unit_Requires_Body (Ent) then
         return True;

      --  Compilation units cannot have optional bodies

      elsif Is_Compilation_Unit (Ent) then
         return False;

      --  Otherwise look at what scope we are in

      else
         Scop := Scope (Ent);

         --  Case of entity is in other than a package spec, in this case
         --  the body, if present, must be in the same declarative part.

         if not Is_Package (Scop) then
            declare
               P : Node_Id;

            begin
               P := Declaration_Node (Ent);

               --  Declaration node may get us a spec, so if so, go to
               --  the parent declaration.

               while not Is_List_Member (P) loop
                  P := Parent (P);
               end loop;

               return Present (Find_Body_In (Ent, Next (P)));
            end;

         --  If the entity is in a package spec, then we have to locate
         --  the corresponding package body, and look there.

         else
            declare
               PBody : constant Node_Id := Locate_Corresponding_Body (Scop);

            begin
               if No (PBody) then
                  return False;
               else
                  return
                    Present
                      (Find_Body_In (Ent, (First (Declarations (PBody)))));
               end if;
            end;
         end if;
      end if;
   end Has_Generic_Body;

   -----------------------
   -- Insert_Elab_Check --
   -----------------------

   procedure Insert_Elab_Check (N : Node_Id; C : Node_Id := Empty) is
      Nod : Node_Id;
      Loc : constant Source_Ptr := Sloc (N);

   begin
      --  If expansion is disabled, do not generate any checks. Also
      --  skip checks if any subunits are missing because in either
      --  case we lack the full information that we need, and no object
      --  file will be created in any case.

      if not Expander_Active or else Subunits_Missing then
         return;
      end if;

      --  If we have a generic instantiation, where Instance_Spec is set,
      --  then this field points to a generic instance spec that has
      --  been inserted before the instantiation node itself, so that
      --  is where we want to insert a check.

      if Nkind (N) in N_Generic_Instantiation
        and then Present (Instance_Spec (N))
      then
         Nod := Instance_Spec (N);
      else
         Nod := N;
      end if;

      --  If we are inserting at the top level, insert in Aux_Decls

      if Nkind (Parent (Nod)) = N_Compilation_Unit then
         declare
            ADN : constant Node_Id := Aux_Decls_Node (Parent (Nod));
            R   : Node_Id;

         begin
            if No (C) then
               R :=
                 Make_Raise_Program_Error (Loc,
                   Reason => PE_Access_Before_Elaboration);
            else
               R :=
                 Make_Raise_Program_Error (Loc,
                   Condition => Make_Op_Not (Loc, C),
                   Reason    => PE_Access_Before_Elaboration);
            end if;

            if No (Declarations (ADN)) then
               Set_Declarations (ADN, New_List (R));
            else
               Append_To (Declarations (ADN), R);
            end if;

            Analyze (R);
         end;

      --  Otherwise just insert before the node in question. However, if
      --  the context of the call has already been analyzed, an insertion
      --  will not work if it depends on subsequent expansion (e.g. a call in
      --  a branch of a short-circuit). In that case we replace the call with
      --  a conditional expression, or with a Raise if it is unconditional.
      --  Unfortunately this does not work if the call has a dynamic size,
      --  because gigi regards it as a dynamic-sized temporary. If such a call
      --  appears in a short-circuit expression, the elaboration check will be
      --  missed (rare enough ???). Otherwise, the code below inserts the check
      --  at the appropriate place before the call. Same applies in the even
      --  rarer case the return type has a known size but is unconstrained.

      else
         if Nkind (N) = N_Function_Call
           and then Analyzed (Parent (N))
           and then Size_Known_At_Compile_Time (Etype (N))
           and then
            (not Has_Discriminants (Etype (N))
              or else Is_Constrained (Etype (N)))

         then
            declare
               Typ : constant Entity_Id := Etype (N);
               Chk : constant Boolean   := Do_Range_Check (N);

               R   : constant Node_Id :=
                       Make_Raise_Program_Error (Loc,
                         Reason => PE_Access_Before_Elaboration);

            begin
               Set_Etype (R, Typ);

               if No (C) then
                  Rewrite (N, R);

               else
                  Rewrite (N,
                    Make_Conditional_Expression (Loc,
                      Expressions => New_List (C, Relocate_Node (N), R)));
               end if;

               Analyze_And_Resolve (N, Typ);

               --  If the original call requires a range check, so does the
               --  conditional expression.

               if Chk then
                  Enable_Range_Check (N);
               else
                  Set_Do_Range_Check (N, False);
               end if;
            end;

         else
            if No (C) then
               Insert_Action (Nod,
                  Make_Raise_Program_Error (Loc,
                    Reason => PE_Access_Before_Elaboration));
            else
               Insert_Action (Nod,
                  Make_Raise_Program_Error (Loc,
                    Condition =>
                      Make_Op_Not (Loc,
                        Right_Opnd => C),
                    Reason => PE_Access_Before_Elaboration));
            end if;
         end if;
      end if;
   end Insert_Elab_Check;

   ------------------
   -- Output_Calls --
   ------------------

   procedure Output_Calls (N : Node_Id) is
      Ent : Entity_Id;

      function Is_Printable_Error_Name (Nm : Name_Id) return Boolean;
      --  An internal function, used to determine if a name, Nm, is either
      --  a non-internal name, or is an internal name that is printable
      --  by the error message circuits (i.e. it has a single upper
      --  case letter at the end).

      function Is_Printable_Error_Name (Nm : Name_Id) return Boolean is
      begin
         if not Is_Internal_Name (Nm) then
            return True;

         elsif Name_Len = 1 then
            return False;

         else
            Name_Len := Name_Len - 1;
            return not Is_Internal_Name;
         end if;
      end Is_Printable_Error_Name;

   --  Start of processing for Output_Calls

   begin
      for J in reverse 1 .. Elab_Call.Last loop
         Error_Msg_Sloc := Elab_Call.Table (J).Cloc;

         Ent := Elab_Call.Table (J).Ent;

         if Is_Generic_Unit (Ent) then
            Error_Msg_NE ("\?& instantiated #", N, Ent);

         elsif Is_Init_Proc (Ent) then
            Error_Msg_N ("\?initialization procedure called #", N);

         elsif Is_Printable_Error_Name (Chars (Ent)) then
            Error_Msg_NE ("\?& called #", N, Ent);

         else
            Error_Msg_N ("\? called #", N);
         end if;
      end loop;
   end Output_Calls;

   ----------------------------
   -- Same_Elaboration_Scope --
   ----------------------------

   function Same_Elaboration_Scope (Scop1, Scop2 : Entity_Id) return Boolean is
      S1 : Entity_Id := Scop1;
      S2 : Entity_Id := Scop2;

   begin
      while S1 /= Standard_Standard
        and then (Ekind (S1) = E_Package
                    or else
                  Ekind (S1) = E_Block)
      loop
         S1 := Scope (S1);
      end loop;

      while S2 /= Standard_Standard
        and then (Ekind (S2) = E_Package
                    or else
                  Ekind (S2) = E_Protected_Type
                    or else
                  Ekind (S2) = E_Block)
      loop
         S2 := Scope (S2);
      end loop;

      return S1 = S2;
   end Same_Elaboration_Scope;

   -----------------
   -- Set_C_Scope --
   -----------------

   procedure Set_C_Scope is
   begin
      while not Is_Compilation_Unit (C_Scope) loop
         C_Scope := Scope (C_Scope);
      end loop;
   end Set_C_Scope;

   -----------------
   -- Spec_Entity --
   -----------------

   function Spec_Entity (E : Entity_Id) return Entity_Id is
      Decl : Node_Id;

   begin
      --  Check for case of body entity
      --  Why is the check for E_Void needed???

      if Ekind (E) = E_Void
        or else Ekind (E) = E_Subprogram_Body
        or else Ekind (E) = E_Package_Body
      then
         Decl := E;

         loop
            Decl := Parent (Decl);
            exit when Nkind (Decl) in N_Proper_Body;
         end loop;

         return Corresponding_Spec (Decl);

      else
         return E;
      end if;
   end Spec_Entity;

   -------------------
   -- Supply_Bodies --
   -------------------

   procedure Supply_Bodies (N : Node_Id) is
   begin
      if Nkind (N) = N_Subprogram_Declaration then
         declare
            Ent : constant Entity_Id := Defining_Unit_Name (Specification (N));

         begin
            Set_Is_Imported (Ent);
            Set_Convention  (Ent, Convention_Stubbed);
         end;

      elsif Nkind (N) = N_Package_Declaration then
         declare
            Spec : constant Node_Id := Specification (N);

         begin
            New_Scope (Defining_Unit_Name (Spec));
            Supply_Bodies (Visible_Declarations (Spec));
            Supply_Bodies (Private_Declarations (Spec));
            Pop_Scope;
         end;
      end if;
   end Supply_Bodies;

   procedure Supply_Bodies (L : List_Id) is
      Elmt : Node_Id;

   begin
      if Present (L) then
         Elmt := First (L);
         while Present (Elmt) loop
            Supply_Bodies (Elmt);
            Next (Elmt);
         end loop;
      end if;
   end Supply_Bodies;

   ------------
   -- Within --
   ------------

   function Within (E1, E2 : Entity_Id) return Boolean is
      Scop : Entity_Id;

   begin
      Scop := E1;

      loop
         if Scop = E2 then
            return True;

         elsif Scop = Standard_Standard then
            return False;

         else
            Scop := Scope (Scop);
         end if;
      end loop;

      raise Program_Error;
   end Within;

   --------------------------
   -- Within_Elaborate_All --
   --------------------------

   function Within_Elaborate_All (E : Entity_Id) return Boolean is
      Item    : Node_Id;
      Item2   : Node_Id;
      Elab_Id : Entity_Id;
      Par     : Node_Id;

   begin
      Item := First (Context_Items (Cunit (Current_Sem_Unit)));

      while Present (Item) loop
         if Nkind (Item) = N_Pragma
           and then Get_Pragma_Id (Chars (Item)) = Pragma_Elaborate_All
         then
            if Error_Posted (Item) then

               --  Some previous error on the pragma itself

               return False;
            end if;

            Elab_Id :=
              Entity (
                Expression (First (Pragma_Argument_Associations (Item))));

            Par   := Parent (Unit_Declaration_Node (Elab_Id));
            Item2 := First (Context_Items (Par));

            while Present (Item2) loop
               if Nkind (Item2) = N_With_Clause
                 and then Entity (Name (Item2)) = E
               then
                  return True;
               end if;

               Next (Item2);
            end loop;
         end if;

         Next (Item);
      end loop;

      return False;
   end Within_Elaborate_All;

end Sem_Elab;
