------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ E L A B                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1997-2022, 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 3,  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 COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with ALI;            use ALI;
with Atree;          use Atree;
with Checks;         use Checks;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Exp_Ch11;       use Exp_Ch11;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Expander;       use Expander;
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 Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Cat;        use Sem_Cat;
with Sem_Ch7;        use Sem_Ch7;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Disp;       use Sem_Disp;
with Sem_Prag;       use Sem_Prag;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Stand;          use Stand;
with Table;
with Tbuild;         use Tbuild;
with Uintp;          use Uintp;
with Uname;          use Uname;

with GNAT;                 use GNAT;
with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
with GNAT.Lists;           use GNAT.Lists;
with GNAT.Sets;            use GNAT.Sets;

package body Sem_Elab is

   -----------------------------------------
   -- Access-before-elaboration mechanism --
   -----------------------------------------

   --  The access-before-elaboration (ABE) mechanism implemented in this unit
   --  has the following objectives:
   --
   --    * Diagnose at compile time or install run-time checks to prevent ABE
   --      access to data and behavior.
   --
   --      The high-level idea is to accurately diagnose ABE issues within a
   --      single unit because the ABE mechanism can inspect the whole unit.
   --      As soon as the elaboration graph extends to an external unit, the
   --      diagnostics stop because the body of the unit may not be available.
   --      Due to control and data flow, the ABE mechanism cannot accurately
   --      determine whether a particular scenario will be elaborated or not.
   --      Conditional ABE checks are therefore used to verify the elaboration
   --      status of local and external targets at run time.
   --
   --    * Supply implicit elaboration dependencies for a unit to binde
   --
   --      The ABE mechanism creates implicit dependencies in the form of with
   --      clauses subject to pragma Elaborate[_All] when the elaboration graph
   --      reaches into an external unit. The implicit dependencies are encoded
   --      in the ALI file of the main unit. GNATbind and binde then use these
   --      dependencies to augment the library item graph and determine the
   --      elaboration order of all units in the compilation.
   --
   --    * Supply pieces of the invocation graph for a unit to bindo
   --
   --      The ABE mechanism captures paths starting from elaboration code or
   --      top level constructs that reach into an external unit. The paths are
   --      encoded in the ALI file of the main unit in the form of declarations
   --      which represent nodes, and relations which represent edges. GNATbind
   --      and bindo then build the full invocation graph in order to augment
   --      the library item graph and determine the elaboration order of all
   --      units in the compilation.
   --
   --  The ABE mechanism supports three models of elaboration:
   --
   --    * Dynamic model - This is the most permissive of the three models.
   --      When the dynamic model is in effect, the mechanism diagnoses and
   --      installs run-time checks to detect ABE issues in the main unit.
   --      The behavior of this model is identical to that specified by the
   --      Ada RM. This model is enabled with switch -gnatE.
   --
   --    Static model - This is the middle ground of the three models. When
   --      the static model is in effect, the mechanism diagnoses and installs
   --      run-time checks to detect ABE issues in the main unit. In addition,
   --      the mechanism generates implicit dependencies between units in the
   --      form of with clauses subject to pragma Elaborate[_All] to ensure
   --      the prior elaboration of withed units. This is the default model.
   --
   --    * SPARK model - This is the most conservative of the three models and
   --      implements the semantics defined in SPARK RM 7.7. The SPARK model
   --      is in effect only when a context resides in a SPARK_Mode On region,
   --      otherwise the mechanism falls back to one of the previous models.
   --
   --  The ABE mechanism consists of a "recording" phase and a "processing"
   --  phase.

   -----------------
   -- Terminology --
   -----------------

   --  * ABE - An attempt to invoke a scenario which has not been elaborated
   --    yet.
   --
   --  * Bridge target - A type of target. A bridge target is a link between
   --    scenarios. It is usually a byproduct of expansion and does not have
   --    any direct ABE ramifications.
   --
   --  * Call marker - A special node used to indicate the presence of a call
   --    in the tree in case expansion transforms or eliminates the original
   --    call. N_Call_Marker nodes do not have static and run-time semantics.
   --
   --  * Conditional ABE - A type of ABE. A conditional ABE occurs when the
   --    invocation of a target by a scenario within the main unit causes an
   --    ABE, but does not cause an ABE for another scenarios within the main
   --    unit.
   --
   --  * Declaration level - A type of enclosing level. A scenario or target is
   --    at the declaration level when it appears within the declarations of a
   --    block statement, entry body, subprogram body, or task body, ignoring
   --    enclosing packages.
   --
   --  * Early call region - A section of code which ends at a subprogram body
   --    and starts from the nearest non-preelaborable construct which precedes
   --    the subprogram body. The early call region extends from a package body
   --    to a package spec when the spec carries pragma Elaborate_Body.
   --
   --  * Generic library level - A type of enclosing level. A scenario or
   --    target is at the generic library level if it appears in a generic
   --    package library unit, ignoring enclosing packages.
   --
   --  * Guaranteed ABE - A type of ABE. A guaranteed ABE occurs when the
   --    invocation of a target by all scenarios within the main unit causes
   --    an ABE.
   --
   --  * Instantiation library level - A type of enclosing level. A scenario
   --    or target is at the instantiation library level if it appears in an
   --    instantiation library unit, ignoring enclosing packages.
   --
   --  * Invocation - The act of activating a task, calling a subprogram, or
   --    instantiating a generic.
   --
   --  * Invocation construct - An entry declaration, [single] protected type,
   --    subprogram declaration, subprogram instantiation, or a [single] task
   --    type declared in the visible, private, or body declarations of the
   --    main unit.
   --
   --  * Invocation relation - A flow link between two invocation constructs
   --
   --  * Invocation signature - A set of attributes that uniquely identify an
   --    invocation construct within the namespace of all ALI files.
   --
   --  * Library level - A type of enclosing level. A scenario or target is at
   --    the library level if it appears in a package library unit, ignoring
   --    enclosing packages.
   --
   --  * Non-library-level encapsulator - A construct that cannot be elaborated
   --    on its own and requires elaboration by a top-level scenario.
   --
   --  * Scenario - A construct or context which is invoked by elaboration code
   --    or invocation construct. The scenarios recognized by the ABE mechanism
   --    are as follows:
   --
   --      - '[Unrestricted_]Access of entries, operators, and subprograms
   --
   --      - Assignments to variables
   --
   --      - Calls to entries, operators, and subprograms
   --
   --      - Derived type declarations
   --
   --      - Instantiations
   --
   --      - Pragma Refined_State
   --
   --      - Reads of variables
   --
   --      - Task activation
   --
   --  * Target - A construct invoked by a scenario. The targets recognized by
   --    the ABE mechanism are as follows:
   --
   --      - For '[Unrestricted_]Access of entries, operators, and subprograms,
   --        the target is the entry, operator, or subprogram.
   --
   --      - For assignments to variables, the target is the variable
   --
   --      - For calls, the target is the entry, operator, or subprogram
   --
   --      - For derived type declarations, the target is the derived type
   --
   --      - For instantiations, the target is the generic template
   --
   --      - For pragma Refined_State, the targets are the constituents
   --
   --      - For reads of variables, the target is the variable
   --
   --      - For task activation, the target is the task body

   ------------------
   -- Architecture --
   ------------------

   --     Analysis/Resolution
   --     |
   --     +- Build_Call_Marker
   --     |
   --     +- Build_Variable_Reference_Marker
   --     |
   --  +- | -------------------- Recording phase ---------------------------+
   --  |  v                                                                 |
   --  |  Record_Elaboration_Scenario                                       |
   --  |  |                                                                 |
   --  |  +--> Check_Preelaborated_Call                                     |
   --  |  |                                                                 |
   --  |  +--> Process_Guaranteed_ABE                                       |
   --  |  |    |                                                            |
   --  |  |    +--> Process_Guaranteed_ABE_Activation                       |
   --  |  |    +--> Process_Guaranteed_ABE_Call                             |
   --  |  |    +--> Process_Guaranteed_ABE_Instantiation                    |
   --  |  |                                                                 |
   --  +- | ----------------------------------------------------------------+
   --     |
   --     |
   --     +--> Internal_Representation
   --     |
   --     +--> Scenario_Storage
   --     |
   --     End of Compilation
   --     |
   --  +- | --------------------- Processing phase -------------------------+
   --  |  v                                                                 |
   --  |  Check_Elaboration_Scenarios                                       |
   --  |  |                                                                 |
   --  |  +--> Check_Conditional_ABE_Scenarios                              |
   --  |  |    |                                                            |
   --  |  |    +--> Process_Conditional_ABE <----------------------+        |
   --  |  |         |                                              |        |
   --  |  |         +--> Process_Conditional_ABE_Activation        |        |
   --  |  |         |    |                                         |        |
   --  |  |         |    +-----------------------------+           |        |
   --  |  |         |                                  |           |        |
   --  |  |         +--> Process_Conditional_ABE_Call  +---> Traverse_Body  |
   --  |  |         |    |                             |                    |
   --  |  |         |    +-----------------------------+                    |
   --  |  |         |                                                       |
   --  |  |         +--> Process_Conditional_ABE_Access_Taken               |
   --  |  |         +--> Process_Conditional_ABE_Instantiation              |
   --  |  |         +--> Process_Conditional_ABE_Variable_Assignment        |
   --  |  |         +--> Process_Conditional_ABE_Variable_Reference         |
   --  |  |                                                                 |
   --  |  +--> Check_SPARK_Scenario                                         |
   --  |  |    |                                                            |
   --  |  |    +--> Process_SPARK_Scenario                                  |
   --  |  |         |                                                       |
   --  |  |         +--> Process_SPARK_Derived_Type                         |
   --  |  |         +--> Process_SPARK_Instantiation                        |
   --  |  |         +--> Process_SPARK_Refined_State_Pragma                 |
   --  |  |                                                                 |
   --  |  +--> Record_Invocation_Graph                                      |
   --  |       |                                                            |
   --  |       +--> Process_Invocation_Body_Scenarios                       |
   --  |       +--> Process_Invocation_Spec_Scenarios                       |
   --  |       +--> Process_Main_Unit                                       |
   --  |            |                                                       |
   --  |            +--> Process_Invocation_Scenario <-------------+        |
   --  |                 |                                         |        |
   --  |                 +--> Process_Invocation_Activation        |        |
   --  |                 |    |                                    |        |
   --  |                 |    +------------------------+           |        |
   --  |                 |                             |           |        |
   --  |                 +--> Process_Invocation_Call  +---> Traverse_Body  |
   --  |                      |                        |                    |
   --  |                      +------------------------+                    |
   --  |                                                                    |
   --  +--------------------------------------------------------------------+

   ---------------------
   -- Recording phase --
   ---------------------

   --  The Recording phase coincides with the analysis/resolution phase of the
   --  compiler. It has the following objectives:
   --
   --    * Record all suitable scenarios for examination by the Processing
   --      phase.
   --
   --      Saving only a certain number of nodes improves the performance of
   --      the ABE mechanism. This eliminates the need to examine the whole
   --      tree in a separate pass.
   --
   --    * Record certain SPARK scenarios which are not necessarily invoked
   --      during elaboration, but still require elaboration-related checks.
   --
   --      Saving only a certain number of nodes improves the performance of
   --      the ABE mechanism. This eliminates the need to examine the whole
   --      tree in a separate pass.
   --
   --    * Detect and diagnose calls in preelaborable or pure units, including
   --      generic bodies.
   --
   --      This diagnostic is carried out during the Recording phase because it
   --      does not need the heavy recursive traversal done by the Processing
   --      phase.
   --
   --    * Detect and diagnose guaranteed ABEs caused by instantiations, calls,
   --      and task activation.
   --
   --      The issues detected by the ABE mechanism are reported as warnings
   --      because they do not violate Ada semantics. Forward instantiations
   --      may thus reach gigi, however gigi cannot handle certain kinds of
   --      premature instantiations and may crash. To avoid this limitation,
   --      the ABE mechanism must identify forward instantiations as early as
   --      possible and suppress their bodies. Calls and task activations are
   --      included in this category for completeness.

   ----------------------
   -- Processing phase --
   ----------------------

   --  The Processing phase is a separate pass which starts after instantiating
   --  and/or inlining of bodies, but before the removal of Ghost code. It has
   --  the following objectives:
   --
   --    * Examine all scenarios saved during the Recording phase, and perform
   --      the following actions:
   --
   --        - Dynamic model
   --
   --          Diagnose conditional ABEs, and install run-time conditional ABE
   --          checks for all scenarios.
   --
   --        - SPARK model
   --
   --          Enforce the SPARK elaboration rules
   --
   --        - Static model
   --
   --          Diagnose conditional ABEs, install run-time conditional ABE
   --          checks only for scenarios are reachable from elaboration code,
   --          and guarantee the elaboration of external units by creating
   --          implicit with clauses subject to pragma Elaborate[_All].
   --
   --    * Examine library-level scenarios and invocation constructs, and
   --      perform the following actions:
   --
   --        - Determine whether the flow of execution reaches into an external
   --          unit. If this is the case, encode the path in the ALI file of
   --          the main unit.
   --
   --        - Create declarations for invocation constructs in the ALI file of
   --          the main unit.

   ----------------------
   -- Important points --
   ----------------------

   --  The Processing phase starts after the analysis, resolution, expansion
   --  phase has completed. As a result, no current semantic information is
   --  available. The scope stack is empty, global flags such as In_Instance
   --  or Inside_A_Generic become useless. To remedy this, the ABE mechanism
   --  must either save or recompute semantic information.
   --
   --  Expansion heavily transforms calls and to some extent instantiations. To
   --  remedy this, the ABE mechanism generates N_Call_Marker nodes in order to
   --  capture the target and relevant attributes of the original call.
   --
   --  The diagnostics of the ABE mechanism depend on accurate source locations
   --  to determine the spatial relation of nodes.

   -----------------------------------------
   -- Suppression of elaboration warnings --
   -----------------------------------------

   --  Elaboration warnings along multiple traversal paths rooted at a scenario
   --  are suppressed when the scenario has elaboration warnings suppressed.
   --
   --    Root scenario
   --    |
   --    +-- Child scenario 1
   --    |   |
   --    |   +-- Grandchild scenario 1
   --    |   |
   --    |   +-- Grandchild scenario N
   --    |
   --    +-- Child scenario N
   --
   --  If the root scenario has elaboration warnings suppressed, then all its
   --  child, grandchild, etc. scenarios will have their elaboration warnings
   --  suppressed.
   --
   --  In addition to switch -gnatwL, pragma Warnings may be used to suppress
   --  elaboration-related warnings when used in the following manner:
   --
   --    pragma Warnings ("L");
   --    <scenario-or-target>
   --
   --    <target>
   --    pragma Warnings (Off, target);
   --
   --    pragma Warnings (Off);
   --    <scenario-or-target>
   --
   --  * To suppress elaboration warnings for '[Unrestricted_]Access of
   --    entries, operators, and subprograms, either:
   --
   --      - Suppress the entry, operator, or subprogram, or
   --      - Suppress the attribute, or
   --      - Use switch -gnatw.f
   --
   --  * To suppress elaboration warnings for calls to entries, operators,
   --    and subprograms, either:
   --
   --      - Suppress the entry, operator, or subprogram, or
   --      - Suppress the call
   --
   --  * To suppress elaboration warnings for instantiations, suppress the
   --    instantiation.
   --
   --  * To suppress elaboration warnings for task activations, either:
   --
   --      - Suppress the task object, or
   --      - Suppress the task type, or
   --      - Suppress the activation call

   --------------
   -- Switches --
   --------------

   --  The following switches may be used to control the behavior of the ABE
   --  mechanism.
   --
   --  -gnatd_a stop elaboration checks on accept or select statement
   --
   --           The ABE mechanism stops the traversal of a task body when it
   --           encounters an accept or a select statement. This behavior is
   --           equivalent to restriction No_Entry_Calls_In_Elaboration_Code,
   --           but without penalizing actual entry calls during elaboration.
   --
   --  -gnatd_e ignore entry calls and requeue statements for elaboration
   --
   --           The ABE mechanism does not generate N_Call_Marker nodes for
   --           protected or task entry calls as well as requeue statements.
   --           As a result, the calls and requeues are not recorded or
   --           processed.
   --
   --  -gnatdE  elaboration checks on predefined units
   --
   --           The ABE mechanism considers scenarios which appear in internal
   --           units (Ada, GNAT, Interfaces, System).
   --
   --  -gnatd_F encode full invocation paths in ALI files
   --
   --           The ABE mechanism encodes the full path from an elaboration
   --           procedure or invocable construct to an external target. The
   --           path contains all intermediate activations, instantiations,
   --           and calls.
   --
   --  -gnatd.G ignore calls through generic formal parameters for elaboration
   --
   --           The ABE mechanism does not generate N_Call_Marker nodes for
   --           calls which occur in expanded instances, and invoke generic
   --           actual subprograms through generic formal subprograms. As a
   --           result, the calls are not recorded or processed.
   --
   --  -gnatd_i ignore activations and calls to instances for elaboration
   --
   --           The ABE mechanism ignores calls and task activations when they
   --           target a subprogram or task type defined an external instance.
   --           As a result, the calls and task activations are not processed.
   --
   --  -gnatdL  ignore external calls from instances for elaboration
   --
   --           The ABE mechanism does not generate N_Call_Marker nodes for
   --           calls which occur in expanded instances, do not invoke generic
   --           actual subprograms through formal subprograms, and the target
   --           is external to the instance. As a result, the calls are not
   --           recorded or processed.
   --
   --  -gnatd.o conservative elaboration order for indirect calls
   --
   --           The ABE mechanism treats '[Unrestricted_]Access of an entry,
   --           operator, or subprogram as an immediate invocation of the
   --           target. As a result, it performs ABE checks and diagnostics on
   --           the immediate call.
   --
   --  -gnatd_p ignore assertion pragmas for elaboration
   --
   --           The ABE mechanism does not generate N_Call_Marker nodes for
   --           calls to subprograms which verify the run-time semantics of
   --           the following assertion pragmas:
   --
   --              Default_Initial_Condition
   --              Initial_Condition
   --              Invariant
   --              Invariant'Class
   --              Post
   --              Post'Class
   --              Postcondition
   --              Type_Invariant
   --              Type_Invariant_Class
   --
   --           As a result, the assertion expressions of the pragmas are not
   --           processed.
   --
   --  -gnatd_s stop elaboration checks on synchronous suspension
   --
   --           The ABE mechanism stops the traversal of a task body when it
   --           encounters a call to one of the following routines:
   --
   --             Ada.Synchronous_Barriers.Wait_For_Release
   --             Ada.Synchronous_Task_Control.Suspend_Until_True
   --
   --  -gnatd_T output trace information on invocation relation construction
   --
   --           The ABE mechanism outputs text information concerning relation
   --           construction to standard output.
   --
   --  -gnatd.U ignore indirect calls for static elaboration
   --
   --           The ABE mechanism does not consider '[Unrestricted_]Access of
   --           entries, operators, and subprograms. As a result, the scenarios
   --           are not recorder or processed.
   --
   --  -gnatd.v enforce SPARK elaboration rules in SPARK code
   --
   --           The ABE mechanism applies some of the SPARK elaboration rules
   --           defined in the SPARK reference manual, chapter 7.7. Note that
   --           certain rules are always enforced, regardless of whether the
   --           switch is active.
   --
   --  -gnatd.y disable implicit pragma Elaborate_All on task bodies
   --
   --           The ABE mechanism does not generate implicit Elaborate_All when
   --           the need for the pragma came from a task body.
   --
   --  -gnatE   dynamic elaboration checking mode enabled
   --
   --           The ABE mechanism assumes that any scenario is elaborated or
   --           invoked by elaboration code. The ABE mechanism performs very
   --           little diagnostics and generates condintional ABE checks to
   --           detect ABE issues at run-time.
   --
   --  -gnatel  turn on info messages on generated Elaborate[_All] pragmas
   --
   --           The ABE mechanism produces information messages on generated
   --           implicit Elabote[_All] pragmas along with traceback showing
   --           why the pragma was generated. In addition, the ABE mechanism
   --           produces information messages for each scenario elaborated or
   --           invoked by elaboration code.
   --
   --  -gnateL  turn off info messages on generated Elaborate[_All] pragmas
   --
   --           The complementary switch for -gnatel.
   --
   --  -gnatH   legacy elaboration checking mode enabled
   --
   --           When this switch is in effect, the pre-18.x ABE model becomes
   --           the de facto ABE model. This amounts to cutting off all entry
   --           points into the new ABE mechanism, and giving full control to
   --           the old ABE mechanism.
   --
   --  -gnatJ   permissive elaboration checking mode enabled
   --
   --           This switch activates the following switches:
   --
   --              -gnatd_a
   --              -gnatd_e
   --              -gnatd.G
   --              -gnatd_i
   --              -gnatdL
   --              -gnatd_p
   --              -gnatd_s
   --              -gnatd.U
   --              -gnatd.y
   --
   --           IMPORTANT: The behavior of the ABE mechanism becomes more
   --           permissive at the cost of accurate diagnostics and runtime
   --           ABE checks.
   --
   --  -gnatw.f turn on warnings for suspicious Subp'Access
   --
   --           The ABE mechanism treats '[Unrestricted_]Access of an entry,
   --           operator, or subprogram as a pseudo invocation of the target.
   --           As a result, it performs ABE diagnostics on the pseudo call.
   --
   --  -gnatw.F turn off warnings for suspicious Subp'Access
   --
   --           The complementary switch for -gnatw.f.
   --
   --  -gnatwl  turn on warnings for elaboration problems
   --
   --           The ABE mechanism produces warnings on detected ABEs along with
   --           a traceback showing the graph of the ABE.
   --
   --  -gnatwL  turn off warnings for elaboration problems
   --
   --           The complementary switch for -gnatwl.

   --------------------------
   -- Debugging ABE issues --
   --------------------------

   --  * If the issue involves a call, ensure that the call is eligible for ABE
   --    processing and receives a corresponding call marker. The routines of
   --    interest are
   --
   --      Build_Call_Marker
   --      Record_Elaboration_Scenario
   --
   --  * If the issue involves an arbitrary scenario, ensure that the scenario
   --    is either recorded, or is successfully recognized while traversing a
   --    body. The routines of interest are
   --
   --      Record_Elaboration_Scenario
   --      Process_Conditional_ABE
   --      Process_Guaranteed_ABE
   --      Traverse_Body
   --
   --  * If the issue involves a circularity in the elaboration order, examine
   --    the ALI files and look for the following encodings next to units:
   --
   --       E indicates a source Elaborate
   --
   --      EA indicates a source Elaborate_All
   --
   --      AD indicates an implicit Elaborate_All
   --
   --      ED indicates an implicit Elaborate
   --
   --    If possible, compare these encodings with those generated by the old
   --    ABE mechanism. The routines of interest are
   --
   --      Ensure_Prior_Elaboration

   -----------
   -- Kinds --
   -----------

   --  The following type enumerates all possible elaboration phase statutes

   type Elaboration_Phase_Status is
     (Inactive,
      --  The elaboration phase of the compiler has not started yet

      Active,
      --  The elaboration phase of the compiler is currently in progress

      Completed);
      --  The elaboration phase of the compiler has finished

   Elaboration_Phase : Elaboration_Phase_Status := Inactive;
   --  The status of the elaboration phase. Use routine Set_Elaboration_Phase
   --  to alter its value.

   --  The following type enumerates all subprogram body traversal modes

   type Body_Traversal_Kind is
     (Deep_Traversal,
      --  The traversal examines the internals of a subprogram

      No_Traversal);

   --  The following type enumerates all operation modes

   type Processing_Kind is
     (Conditional_ABE_Processing,
      --  The ABE mechanism detects and diagnoses conditional ABEs for library
      --  and declaration-level scenarios.

      Dynamic_Model_Processing,
      --  The ABE mechanism installs conditional ABE checks for all eligible
      --  scenarios when the dynamic model is in effect.

      Guaranteed_ABE_Processing,
      --  The ABE mechanism detects and diagnoses guaranteed ABEs caused by
      --  calls, instantiations, and task activations.

      Invocation_Construct_Processing,
      --  The ABE mechanism locates all invocation constructs within the main
      --  unit and utilizes them as roots of miltiple DFS traversals aimed at
      --  detecting transitions from the main unit to an external unit.

      Invocation_Body_Processing,
      --  The ABE mechanism utilizes all library-level body scenarios as roots
      --  of miltiple DFS traversals aimed at detecting transitions from the
      --  main unit to an external unit.

      Invocation_Spec_Processing,
      --  The ABE mechanism utilizes all library-level spec scenarios as roots
      --  of miltiple DFS traversals aimed at detecting transitions from the
      --  main unit to an external unit.

      SPARK_Processing,
      --  The ABE mechanism detects and diagnoses violations of the SPARK
      --  elaboration rules for SPARK-specific scenarios.

      No_Processing);

   --  The following type enumerates all possible scenario kinds

   type Scenario_Kind is
     (Access_Taken_Scenario,
      --  An attribute reference which takes 'Access or 'Unrestricted_Access of
      --  an entry, operator, or subprogram.

      Call_Scenario,
      --  A call which invokes an entry, operator, or subprogram

      Derived_Type_Scenario,
      --  A declaration of a derived type. This is a SPARK-specific scenario.

      Instantiation_Scenario,
      --  An instantiation which instantiates a generic package or subprogram.
      --  This scenario is also subject to SPARK-specific rules.

      Refined_State_Pragma_Scenario,
      --  A Refined_State pragma. This is a SPARK-specific scenario.

      Task_Activation_Scenario,
      --  A call which activates objects of various task types

      Variable_Assignment_Scenario,
      --  An assignment statement which modifies the value of some variable

      Variable_Reference_Scenario,
      --  A reference to a variable. This is a SPARK-specific scenario.

      No_Scenario);

   --  The following type enumerates all possible consistency models of target
   --  and scenario representations.

   type Representation_Kind is
     (Inconsistent_Representation,
      --  A representation is said to be "inconsistent" when it is created from
      --  a partially analyzed tree. In such an environment, certain attributes
      --  such as a completing body may not be available yet.

      Consistent_Representation,
      --  A representation is said to be "consistent" when it is created from a
      --  fully analyzed tree, where all attributes are available.

      No_Representation);

   --  The following type enumerates all possible target kinds

   type Target_Kind is
     (Generic_Target,
      --  A generic unit being instantiated

      Package_Target,
      --  The package form of an instantiation

      Subprogram_Target,
      --  An entry, operator, or subprogram being invoked, or aliased through
      --  'Access or 'Unrestricted_Access.

      Task_Target,
      --  A task being activated by an activation call

      Variable_Target,
      --  A variable being updated through an assignment statement, or read
      --  through a variable reference.

      No_Target);

   -----------
   -- Types --
   -----------

   procedure Destroy (NE : in out Node_Or_Entity_Id);
   pragma Inline (Destroy);
   --  Destroy node or entity NE

   function Hash (NE : Node_Or_Entity_Id) return Bucket_Range_Type;
   pragma Inline (Hash);
   --  Obtain the hash value of key NE

   --  The following is a general purpose list for nodes and entities

   package NE_List is new Doubly_Linked_Lists
     (Element_Type    => Node_Or_Entity_Id,
      "="             => "=",
      Destroy_Element => Destroy);

   --  The following is a general purpose map which relates nodes and entities
   --  to lists of nodes and entities.

   package NE_List_Map is new Dynamic_Hash_Tables
     (Key_Type              => Node_Or_Entity_Id,
      Value_Type            => NE_List.Doubly_Linked_List,
      No_Value              => NE_List.Nil,
      Expansion_Threshold   => 1.5,
      Expansion_Factor      => 2,
      Compression_Threshold => 0.3,
      Compression_Factor    => 2,
      "="                   => "=",
      Destroy_Value         => NE_List.Destroy,
      Hash                  => Hash);

   --  The following is a general purpose membership set for nodes and entities

   package NE_Set is new Membership_Sets
     (Element_Type => Node_Or_Entity_Id,
      "="          => "=",
      Hash         => Hash);

   --  The following type captures relevant attributes which pertain to the
   --  in state of the Processing phase.

   type Processing_In_State is record
      Processing : Processing_Kind := No_Processing;
      --  Operation mode of the Processing phase. Once set, this value should
      --  not be changed.

      Representation : Representation_Kind := No_Representation;
      --  Required level of scenario and target representation. Once set, this
      --  value should not be changed.

      Suppress_Checks : Boolean := False;
      --  This flag is set when the Processing phase must not generate any ABE
      --  checks.

      Suppress_Implicit_Pragmas : Boolean := False;
      --  This flag is set when the Processing phase must not generate any
      --  implicit Elaborate[_All] pragmas.

      Suppress_Info_Messages : Boolean := False;
      --  This flag is set when the Processing phase must not emit any info
      --  messages.

      Suppress_Up_Level_Targets : Boolean := False;
      --  This flag is set when the Processing phase must ignore up-level
      --  targets.

      Suppress_Warnings : Boolean := False;
      --  This flag is set when the Processing phase must not emit any warnings
      --  on elaboration problems.

      Traversal : Body_Traversal_Kind := No_Traversal;
      --  The subprogram body traversal mode. Once set, this value should not
      --  be changed.

      Within_Generic : Boolean := False;
      --  This flag is set when the Processing phase is currently within a
      --  generic unit.

      Within_Initial_Condition : Boolean := False;
      --  This flag is set when the Processing phase is currently examining a
      --  scenario which was reached from an initial condition procedure.

      Within_Partial_Finalization : Boolean := False;
      --  This flag is set when the Processing phase is currently examining a
      --  scenario which was reached from a partial finalization procedure.

      Within_Task_Body : Boolean := False;
      --  This flag is set when the Processing phase is currently examining a
      --  scenario which was reached from a task body.
   end record;

   --  The following constants define the various operational states of the
   --  Processing phase.

   --  The conditional ABE state is used when processing scenarios that appear
   --  at the declaration, instantiation, and library levels to detect errors
   --  and install conditional ABE checks.

   Conditional_ABE_State : constant Processing_In_State :=
     (Processing                => Conditional_ABE_Processing,
      Representation            => Consistent_Representation,
      Traversal                 => Deep_Traversal,
      others                    => False);

   --  The dynamic model state is used to install conditional ABE checks when
   --  switch -gnatE (dynamic elaboration checking mode enabled) is in effect.

   Dynamic_Model_State : constant Processing_In_State :=
     (Processing                => Dynamic_Model_Processing,
      Representation            => Consistent_Representation,
      Suppress_Implicit_Pragmas => True,
      Suppress_Info_Messages    => True,
      Suppress_Up_Level_Targets => True,
      Suppress_Warnings         => True,
      Traversal                 => No_Traversal,
      others                    => False);

   --  The guaranteed ABE state is used when processing scenarios that appear
   --  at the declaration, instantiation, and library levels to detect errors
   --  and install guarateed ABE failures.

   Guaranteed_ABE_State : constant Processing_In_State :=
     (Processing                => Guaranteed_ABE_Processing,
      Representation            => Inconsistent_Representation,
      Suppress_Implicit_Pragmas => True,
      Traversal                 => No_Traversal,
      others                    => False);

   --  The invocation body state is used when processing scenarios that appear
   --  at the body library level to encode paths that start from elaboration
   --  code and ultimately reach into external units.

   Invocation_Body_State : constant Processing_In_State :=
     (Processing                => Invocation_Body_Processing,
      Representation            => Consistent_Representation,
      Suppress_Checks           => True,
      Suppress_Implicit_Pragmas => True,
      Suppress_Info_Messages    => True,
      Suppress_Up_Level_Targets => True,
      Suppress_Warnings         => True,
      Traversal                 => Deep_Traversal,
      others                    => False);

   --  The invocation construct state is used when processing constructs that
   --  appear within the spec and body of the main unit and eventually reach
   --  into external units.

   Invocation_Construct_State : constant Processing_In_State :=
     (Processing                => Invocation_Construct_Processing,
      Representation            => Consistent_Representation,
      Suppress_Checks           => True,
      Suppress_Implicit_Pragmas => True,
      Suppress_Info_Messages    => True,
      Suppress_Up_Level_Targets => True,
      Suppress_Warnings         => True,
      Traversal                 => Deep_Traversal,
      others                    => False);

   --  The invocation spec state is used when processing scenarios that appear
   --  at the spec library level to encode paths that start from elaboration
   --  code and ultimately reach into external units.

   Invocation_Spec_State : constant Processing_In_State :=
     (Processing                => Invocation_Spec_Processing,
      Representation            => Consistent_Representation,
      Suppress_Checks           => True,
      Suppress_Implicit_Pragmas => True,
      Suppress_Info_Messages    => True,
      Suppress_Up_Level_Targets => True,
      Suppress_Warnings         => True,
      Traversal                 => Deep_Traversal,
      others                    => False);

   --  The SPARK state is used when verying SPARK-specific semantics of certain
   --  scenarios.

   SPARK_State : constant Processing_In_State :=
     (Processing                => SPARK_Processing,
      Representation            => Consistent_Representation,
      Traversal                 => No_Traversal,
      others                    => False);

   --  The following type identifies a scenario representation

   type Scenario_Rep_Id is new Natural;

   No_Scenario_Rep    : constant Scenario_Rep_Id := Scenario_Rep_Id'First;
   First_Scenario_Rep : constant Scenario_Rep_Id := No_Scenario_Rep + 1;

   --  The following type identifies a target representation

   type Target_Rep_Id is new Natural;

   No_Target_Rep    : constant Target_Rep_Id := Target_Rep_Id'First;
   First_Target_Rep : constant Target_Rep_Id := No_Target_Rep + 1;

   --------------
   -- Services --
   --------------

   --  The following package keeps track of all active scenarios during a DFS
   --  traversal.

   package Active_Scenarios is

      -----------
      -- Types --
      -----------

      --  The following type defines the position within the active scenario
      --  stack.

      type Active_Scenario_Pos is new Natural;

      ---------------------
      -- Data structures --
      ---------------------

      --  The following table stores all active scenarios in a DFS traversal.
      --  This table must be maintained in a FIFO fashion.

      package Active_Scenario_Stack is new Table.Table
        (Table_Index_Type     => Active_Scenario_Pos,
         Table_Component_Type => Node_Id,
         Table_Low_Bound      => 1,
         Table_Initial        => 50,
         Table_Increment      => 200,
         Table_Name           => "Active_Scenario_Stack");

      ---------
      -- API --
      ---------

      procedure Output_Active_Scenarios
        (Error_Nod : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Output_Active_Scenarios);
      --  Output the contents of the active scenario stack from earliest to
      --  latest to supplement an earlier error emitted for node Error_Nod.
      --  In_State denotes the current state of the Processing phase.

      procedure Pop_Active_Scenario (N : Node_Id);
      pragma Inline (Pop_Active_Scenario);
      --  Pop the top of the scenario stack. A check is made to ensure that the
      --  scenario being removed is the same as N.

      procedure Push_Active_Scenario (N : Node_Id);
      pragma Inline (Push_Active_Scenario);
      --  Push scenario N on top of the scenario stack

      function Root_Scenario return Node_Id;
      pragma Inline (Root_Scenario);
      --  Return the scenario which started a DFS traversal

   end Active_Scenarios;
   use Active_Scenarios;

   --  The following package provides the main entry point for task activation
   --  processing.

   package Activation_Processor is

      -----------
      -- Types --
      -----------

      type Activation_Processor_Ptr is access procedure
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      --  Reference to a procedure that takes all attributes of an activation
      --  and performs a desired action. Call is the activation call. Call_Rep
      --  is the representation of the call. Obj_Id is the task object being
      --  activated. Obj_Rep is the representation of the object. Task_Typ is
      --  the task type whose body is being activated. Task_Rep denotes the
      --  representation of the task type. In_State is the current state of
      --  the Processing phase.

      ---------
      -- API --
      ---------

      procedure Process_Activation
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Processor : Activation_Processor_Ptr;
         In_State  : Processing_In_State);
      --  Find all task objects activated by activation call Call and invoke
      --  Processor on them. Call_Rep denotes the representation of the call.
      --  In_State is the current state of the Processing phase.

   end Activation_Processor;
   use Activation_Processor;

   --  The following package profides functionality for traversing subprogram
   --  bodies in DFS manner and processing of eligible scenarios within.

   package Body_Processor is

      -----------
      -- Types --
      -----------

      type Scenario_Predicate_Ptr is access function
        (N : Node_Id) return Boolean;
      --  Reference to a function which determines whether arbitrary node N
      --  denotes a suitable scenario for processing.

      type Scenario_Processor_Ptr is access procedure
        (N : Node_Id; In_State : Processing_In_State);
      --  Reference to a procedure which processes scenario N. In_State is the
      --  current state of the Processing phase.

      ---------
      -- API --
      ---------

      procedure Traverse_Body
        (N                   : Node_Id;
         Requires_Processing : Scenario_Predicate_Ptr;
         Processor           : Scenario_Processor_Ptr;
         In_State            : Processing_In_State);
      pragma Inline (Traverse_Body);
      --  Traverse the declarations and handled statements of subprogram body
      --  N, looking for scenarios that satisfy predicate Requires_Processing.
      --  Routine Processor is invoked for each such scenario.

      procedure Reset_Traversed_Bodies;
      pragma Inline (Reset_Traversed_Bodies);
      --  Reset the visited status of all subprogram bodies that have already
      --  been processed by routine Traverse_Body.

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Body_Processor;
      pragma Inline (Finalize_Body_Processor);
      --  Finalize all internal data structures

      procedure Initialize_Body_Processor;
      pragma Inline (Initialize_Body_Processor);
      --  Initialize all internal data structures

   end Body_Processor;
   use Body_Processor;

   --  The following package provides functionality for installing ABE-related
   --  checks and failures.

   package Check_Installer is

      ---------
      -- API --
      ---------

      function Check_Or_Failure_Generation_OK return Boolean;
      pragma Inline (Check_Or_Failure_Generation_OK);
      --  Determine whether a conditional ABE check or guaranteed ABE failure
      --  can be generated.

      procedure Install_Dynamic_ABE_Checks;
      pragma Inline (Install_Dynamic_ABE_Checks);
      --  Install conditional ABE checks for all saved scenarios when the
      --  dynamic model is in effect.

      procedure Install_Scenario_ABE_Check
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Scenario_Rep_Id);
      pragma Inline (Install_Scenario_ABE_Check);
      --  Install a conditional ABE check for scenario N to ensure that target
      --  Targ_Id is properly elaborated. Targ_Rep is the representation of the
      --  target. If the check is installed, disable the elaboration checks of
      --  scenario Disable.

      procedure Install_Scenario_ABE_Check
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Target_Rep_Id);
      pragma Inline (Install_Scenario_ABE_Check);
      --  Install a conditional ABE check for scenario N to ensure that target
      --  Targ_Id is properly elaborated. Targ_Rep is the representation of the
      --  target. If the check is installed, disable the elaboration checks of
      --  target Disable.

      procedure Install_Scenario_ABE_Failure
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Scenario_Rep_Id);
      pragma Inline (Install_Scenario_ABE_Failure);
      --  Install a guaranteed ABE failure for scenario N with target Targ_Id.
      --  Targ_Rep denotes the representation of the target. If the failure is
      --  installed, disable the elaboration checks of scenario Disable.

      procedure Install_Scenario_ABE_Failure
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Target_Rep_Id);
      pragma Inline (Install_Scenario_ABE_Failure);
      --  Install a guaranteed ABE failure for scenario N with target Targ_Id.
      --  Targ_Rep denotes the representation of the target. If the failure is
      --  installed, disable the elaboration checks of target Disable.

      procedure Install_Unit_ABE_Check
        (N       : Node_Id;
         Unit_Id : Entity_Id;
         Disable : Scenario_Rep_Id);
      pragma Inline (Install_Unit_ABE_Check);
      --  Install a conditional ABE check for scenario N to ensure that unit
      --  Unit_Id is properly elaborated. If the check is installed, disable
      --  the elaboration checks of scenario Disable.

      procedure Install_Unit_ABE_Check
        (N       : Node_Id;
         Unit_Id : Entity_Id;
         Disable : Target_Rep_Id);
      pragma Inline (Install_Unit_ABE_Check);
      --  Install a conditional ABE check for scenario N to ensure that unit
      --  Unit_Id is properly elaborated. If the check is installed, disable
      --  the elaboration checks of target Disable.

   end Check_Installer;
   use Check_Installer;

   --  The following package provides the main entry point for conditional ABE
   --  checks and diagnostics.

   package Conditional_ABE_Processor is

      ---------
      -- API --
      ---------

      procedure Check_Conditional_ABE_Scenarios
        (Iter : in out NE_Set.Iterator);
      pragma Inline (Check_Conditional_ABE_Scenarios);
      --  Perform conditional ABE checks and diagnostics for all scenarios
      --  available through iterator Iter.

      procedure Process_Conditional_ABE
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE);
      --  Perform conditional ABE checks and diagnostics for scenario N.
      --  In_State denotes the current state of the Processing phase.

   end Conditional_ABE_Processor;
   use Conditional_ABE_Processor;

   --  The following package provides functionality to emit errors, information
   --  messages, and warnings.

   package Diagnostics is

      ---------
      -- API --
      ---------

      procedure Elab_Msg_NE
        (Msg      : String;
         N        : Node_Id;
         Id       : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean);
      pragma Inline (Elab_Msg_NE);
      --  Wrapper around Error_Msg_NE. Emit message Msg concerning arbitrary
      --  node N and entity. If flag Info_Msg is set, the routine emits an
      --  information message, otherwise it emits an error. If flag In_SPARK
      --  is set, then string " in SPARK" is added to the end of the message.

      procedure Info_Call
        (Call     : Node_Id;
         Subp_Id  : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean);
      pragma Inline (Info_Call);
      --  Output information concerning call Call that invokes subprogram
      --  Subp_Id. When flag Info_Msg is set, the routine emits an information
      --  message, otherwise it emits an error. When flag In_SPARK is set, " in
      --  SPARK" is added to the end of the message.

      procedure Info_Instantiation
        (Inst     : Node_Id;
         Gen_Id   : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean);
      pragma Inline (Info_Instantiation);
      --  Output information concerning instantiation Inst which instantiates
      --  generic unit Gen_Id. If flag Info_Msg is set, the routine emits an
      --  information message, otherwise it emits an error. If flag In_SPARK
      --  is set, then string " in SPARK" is added to the end of the message.

      procedure Info_Variable_Reference
        (Ref    : Node_Id;
         Var_Id : Entity_Id);
      pragma Inline (Info_Variable_Reference);
      --  Output information concerning reference Ref which mentions variable
      --  Var_Id. The routine emits an error suffixed with " in SPARK".

   end Diagnostics;
   use Diagnostics;

   --  The following package provides functionality to locate the early call
   --  region of a subprogram body.

   package Early_Call_Region_Processor is

      ---------
      -- API --
      ---------

      function Find_Early_Call_Region
        (Body_Decl        : Node_Id;
         Assume_Elab_Body : Boolean := False;
         Skip_Memoization : Boolean := False) return Node_Id;
      pragma Inline (Find_Early_Call_Region);
      --  Find the start of the early call region that belongs to subprogram
      --  body Body_Decl as defined in SPARK RM 7.7. This routine finds the
      --  early call region, memoizes it, and returns it, but this behavior
      --  can be altered. Flag Assume_Elab_Body should be set when a package
      --  spec may lack pragma Elaborate_Body, but the routine must still
      --  examine that spec. Flag Skip_Memoization should be set when the
      --  routine must avoid memoizing the region.

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Early_Call_Region_Processor;
      pragma Inline (Finalize_Early_Call_Region_Processor);
      --  Finalize all internal data structures

      procedure Initialize_Early_Call_Region_Processor;
      pragma Inline (Initialize_Early_Call_Region_Processor);
      --  Initialize all internal data structures

   end Early_Call_Region_Processor;
   use Early_Call_Region_Processor;

   --  The following package provides access to the elaboration statuses of all
   --  units withed by the main unit.

   package Elaborated_Units is

      ---------
      -- API --
      ---------

      procedure Collect_Elaborated_Units;
      pragma Inline (Collect_Elaborated_Units);
      --  Save the elaboration statuses of all units withed by the main unit

      procedure Ensure_Prior_Elaboration
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State);
      pragma Inline (Ensure_Prior_Elaboration);
      --  Guarantee the elaboration of unit Unit_Id with respect to the main
      --  unit by either suggesting or installing an Elaborate[_All] pragma
      --  denoted by Prag_Nam. N denotes the related scenario. In_State is the
      --  current state of the Processing phase.

      function Has_Prior_Elaboration
        (Unit_Id      : Entity_Id;
         Context_OK   : Boolean := False;
         Elab_Body_OK : Boolean := False;
         Same_Unit_OK : Boolean := False) return Boolean;
      pragma Inline (Has_Prior_Elaboration);
      --  Determine whether unit Unit_Id is elaborated prior to the main unit.
      --  If flag Context_OK is set, the routine considers the following case
      --  as valid prior elaboration:
      --
      --    * Unit_Id is in the elaboration context of the main unit
      --
      --  If flag Elab_Body_OK is set, the routine considers the following case
      --  as valid prior elaboration:
      --
      --    * Unit_Id has pragma Elaborate_Body and is not the main unit
      --
      --  If flag Same_Unit_OK is set, the routine considers the following
      --  cases as valid prior elaboration:
      --
      --    * Unit_Id is the main unit
      --
      --    * Unit_Id denotes the spec of the main unit body

      procedure Meet_Elaboration_Requirement
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Req_Nam  : Name_Id;
         In_State : Processing_In_State);
      pragma Inline (Meet_Elaboration_Requirement);
      --  Determine whether elaboration requirement Req_Nam for scenario N with
      --  target Targ_Id is met by the context of the main unit using the SPARK
      --  rules. Req_Nam must denote either Elaborate or Elaborate_All. Emit an
      --  error if this is not the case. In_State denotes the current state of
      --  the Processing phase.

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Elaborated_Units;
      pragma Inline (Finalize_Elaborated_Units);
      --  Finalize all internal data structures

      procedure Initialize_Elaborated_Units;
      pragma Inline (Initialize_Elaborated_Units);
      --  Initialize all internal data structures

   end Elaborated_Units;
   use Elaborated_Units;

   --  The following package provides the main entry point for guaranteed ABE
   --  checks and diagnostics.

   package Guaranteed_ABE_Processor is

      ---------
      -- API --
      ---------

      procedure Process_Guaranteed_ABE
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Guaranteed_ABE);
      --  Perform guaranteed ABE checks and diagnostics for scenario N.
      --  In_State is the current state of the Processing phase.

   end Guaranteed_ABE_Processor;
   use Guaranteed_ABE_Processor;

   --  The following package provides access to the internal representation of
   --  scenarios and targets.

   package Internal_Representation is

      -----------
      -- Types --
      -----------

      --  The following type enumerates all possible Ghost mode kinds

      type Extended_Ghost_Mode is
        (Is_Ignored,
         Is_Checked_Or_Not_Specified);

      --  The following type enumerates all possible SPARK mode kinds

      type Extended_SPARK_Mode is
        (Is_On,
         Is_Off_Or_Not_Specified);

      --------------
      -- Builders --
      --------------

      function Scenario_Representation_Of
        (N        : Node_Id;
         In_State : Processing_In_State) return Scenario_Rep_Id;
      pragma Inline (Scenario_Representation_Of);
      --  Obtain the id of elaboration scenario N's representation. The routine
      --  constructs the representation if it is not available. In_State is the
      --  current state of the Processing phase.

      function Target_Representation_Of
        (Id       : Entity_Id;
         In_State : Processing_In_State) return Target_Rep_Id;
      pragma Inline (Target_Representation_Of);
      --  Obtain the id of elaboration target Id's representation. The routine
      --  constructs the representation if it is not available. In_State is the
      --  current state of the Processing phase.

      -------------------------
      -- Scenario attributes --
      -------------------------

      function Activated_Task_Objects
        (S_Id : Scenario_Rep_Id) return NE_List.Doubly_Linked_List;
      pragma Inline (Activated_Task_Objects);
      --  For Task_Activation_Scenario S_Id, obtain the list of task objects
      --  the scenario is activating.

      function Activated_Task_Type (S_Id : Scenario_Rep_Id) return Entity_Id;
      pragma Inline (Activated_Task_Type);
      --  For Task_Activation_Scenario S_Id, obtain the currently activated
      --  task type.

      procedure Disable_Elaboration_Checks (S_Id : Scenario_Rep_Id);
      pragma Inline (Disable_Elaboration_Checks);
      --  Disable elaboration checks of scenario S_Id

      function Elaboration_Checks_OK (S_Id : Scenario_Rep_Id) return Boolean;
      pragma Inline (Elaboration_Checks_OK);
      --  Determine whether scenario S_Id may be subjected to elaboration
      --  checks.

      function Elaboration_Warnings_OK (S_Id : Scenario_Rep_Id) return Boolean;
      pragma Inline (Elaboration_Warnings_OK);
      --  Determine whether scenario S_Id may be subjected to elaboration
      --  warnings.

      function Ghost_Mode_Of
        (S_Id : Scenario_Rep_Id) return Extended_Ghost_Mode;
      pragma Inline (Ghost_Mode_Of);
      --  Obtain the Ghost mode of scenario S_Id

      function Is_Dispatching_Call (S_Id : Scenario_Rep_Id) return Boolean;
      pragma Inline (Is_Dispatching_Call);
      --  For Call_Scenario S_Id, determine whether the call is dispatching

      function Is_Read_Reference (S_Id : Scenario_Rep_Id) return Boolean;
      pragma Inline (Is_Read_Reference);
      --  For Variable_Reference_Scenario S_Id, determine whether the reference
      --  is a read.

      function Kind (S_Id : Scenario_Rep_Id) return Scenario_Kind;
      pragma Inline (Kind);
      --  Obtain the nature of scenario S_Id

      function Level (S_Id : Scenario_Rep_Id) return Enclosing_Level_Kind;
      pragma Inline (Level);
      --  Obtain the enclosing level of scenario S_Id

      procedure Set_Activated_Task_Objects
        (S_Id      : Scenario_Rep_Id;
         Task_Objs : NE_List.Doubly_Linked_List);
      pragma Inline (Set_Activated_Task_Objects);
      --  For Task_Activation_Scenario S_Id, set the list of task objects
      --  activated by the scenario to Task_Objs.

      procedure Set_Activated_Task_Type
        (S_Id     : Scenario_Rep_Id;
         Task_Typ : Entity_Id);
      pragma Inline (Set_Activated_Task_Type);
      --  For Task_Activation_Scenario S_Id, set the currently activated task
      --  type to Task_Typ.

      function SPARK_Mode_Of
        (S_Id : Scenario_Rep_Id) return Extended_SPARK_Mode;
      pragma Inline (SPARK_Mode_Of);
      --  Obtain the SPARK mode of scenario S_Id

      function Target (S_Id : Scenario_Rep_Id) return Entity_Id;
      pragma Inline (Target);
      --  Obtain the target of scenario S_Id

      -----------------------
      -- Target attributes --
      -----------------------

      function Barrier_Body_Declaration (T_Id : Target_Rep_Id) return Node_Id;
      pragma Inline (Barrier_Body_Declaration);
      --  For Subprogram_Target T_Id, obtain the declaration of the barrier
      --  function's body.

      function Body_Declaration (T_Id : Target_Rep_Id) return Node_Id;
      pragma Inline (Body_Declaration);
      --  Obtain the declaration of the body which belongs to target T_Id

      procedure Disable_Elaboration_Checks (T_Id : Target_Rep_Id);
      pragma Inline (Disable_Elaboration_Checks);
      --  Disable elaboration checks of target T_Id

      function Elaboration_Checks_OK (T_Id : Target_Rep_Id) return Boolean;
      pragma Inline (Elaboration_Checks_OK);
      --  Determine whether target T_Id may be subjected to elaboration checks

      function Elaboration_Warnings_OK (T_Id : Target_Rep_Id) return Boolean;
      pragma Inline (Elaboration_Warnings_OK);
      --  Determine whether target T_Id may be subjected to elaboration
      --  warnings.

      function Ghost_Mode_Of (T_Id : Target_Rep_Id) return Extended_Ghost_Mode;
      pragma Inline (Ghost_Mode_Of);
      --  Obtain the Ghost mode of target T_Id

      function Kind (T_Id : Target_Rep_Id) return Target_Kind;
      pragma Inline (Kind);
      --  Obtain the nature of target T_Id

      function SPARK_Mode_Of (T_Id : Target_Rep_Id) return Extended_SPARK_Mode;
      pragma Inline (SPARK_Mode_Of);
      --  Obtain the SPARK mode of target T_Id

      function Spec_Declaration (T_Id : Target_Rep_Id) return Node_Id;
      pragma Inline (Spec_Declaration);
      --  Obtain the declaration of the spec which belongs to target T_Id

      function Unit (T_Id : Target_Rep_Id) return Entity_Id;
      pragma Inline (Unit);
      --  Obtain the unit where the target is defined

      function Variable_Declaration (T_Id : Target_Rep_Id) return Node_Id;
      pragma Inline (Variable_Declaration);
      --  For Variable_Target T_Id, obtain the declaration of the variable

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Internal_Representation;
      pragma Inline (Finalize_Internal_Representation);
      --  Finalize all internal data structures

      procedure Initialize_Internal_Representation;
      pragma Inline (Initialize_Internal_Representation);
      --  Initialize all internal data structures

   end Internal_Representation;
   use Internal_Representation;

   --  The following package provides functionality for recording pieces of the
   --  invocation graph in the ALI file of the main unit.

   package Invocation_Graph is

      ---------
      -- API --
      ---------

      procedure Record_Invocation_Graph;
      pragma Inline (Record_Invocation_Graph);
      --  Process all declaration, instantiation, and library level scenarios,
      --  along with invocation construct within the spec and body of the main
      --  unit to determine whether any of these reach into an external unit.
      --  If such a path exists, encode in the ALI file of the main unit.

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Invocation_Graph;
      pragma Inline (Finalize_Invocation_Graph);
      --  Finalize all internal data structures

      procedure Initialize_Invocation_Graph;
      pragma Inline (Initialize_Invocation_Graph);
      --  Initialize all internal data structures

   end Invocation_Graph;
   use Invocation_Graph;

   --  The following package stores scenarios

   package Scenario_Storage is

      ---------
      -- API --
      ---------

      procedure Add_Declaration_Scenario (N : Node_Id);
      pragma Inline (Add_Declaration_Scenario);
      --  Save declaration level scenario N

      procedure Add_Dynamic_ABE_Check_Scenario (N : Node_Id);
      pragma Inline (Add_Dynamic_ABE_Check_Scenario);
      --  Save scenario N for conditional ABE check installation purposes when
      --  the dynamic model is in effect.

      procedure Add_Library_Body_Scenario (N : Node_Id);
      pragma Inline (Add_Library_Body_Scenario);
      --  Save library-level body scenario N

      procedure Add_Library_Spec_Scenario (N : Node_Id);
      pragma Inline (Add_Library_Spec_Scenario);
      --  Save library-level spec scenario N

      procedure Add_SPARK_Scenario (N : Node_Id);
      pragma Inline (Add_SPARK_Scenario);
      --  Save SPARK scenario N

      procedure Delete_Scenario (N : Node_Id);
      pragma Inline (Delete_Scenario);
      --  Delete arbitrary scenario N

      function Iterate_Declaration_Scenarios return NE_Set.Iterator;
      pragma Inline (Iterate_Declaration_Scenarios);
      --  Obtain an iterator over all declaration level scenarios

      function Iterate_Dynamic_ABE_Check_Scenarios return NE_Set.Iterator;
      pragma Inline (Iterate_Dynamic_ABE_Check_Scenarios);
      --  Obtain an iterator over all scenarios that require a conditional ABE
      --  check when the dynamic model is in effect.

      function Iterate_Library_Body_Scenarios return NE_Set.Iterator;
      pragma Inline (Iterate_Library_Body_Scenarios);
      --  Obtain an iterator over all library level body scenarios

      function Iterate_Library_Spec_Scenarios return NE_Set.Iterator;
      pragma Inline (Iterate_Library_Spec_Scenarios);
      --  Obtain an iterator over all library level spec scenarios

      function Iterate_SPARK_Scenarios return NE_Set.Iterator;
      pragma Inline (Iterate_SPARK_Scenarios);
      --  Obtain an iterator over all SPARK scenarios

      procedure Replace_Scenario (Old_N : Node_Id; New_N : Node_Id);
      pragma Inline (Replace_Scenario);
      --  Replace scenario Old_N with scenario New_N

      -----------------
      -- Maintenance --
      -----------------

      procedure Finalize_Scenario_Storage;
      pragma Inline (Finalize_Scenario_Storage);
      --  Finalize all internal data structures

      procedure Initialize_Scenario_Storage;
      pragma Inline (Initialize_Scenario_Storage);
      --  Initialize all internal data structures

   end Scenario_Storage;
   use Scenario_Storage;

   --  The following package provides various semantic predicates

   package Semantics is

      ---------
      -- API --
      ---------

      function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Accept_Alternative_Proc);
      --  Determine whether arbitrary entity Id denotes an internally generated
      --  procedure which encapsulates the statements of an accept alternative.

      function Is_Activation_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Activation_Proc);
      --  Determine whether arbitrary entity Id denotes a runtime procedure in
      --  charge with activating tasks.

      function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Ada_Semantic_Target);
      --  Determine whether arbitrary entity Id denotes a source or internally
      --  generated subprogram which emulates Ada semantics.

      function Is_Assertion_Pragma_Target (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Assertion_Pragma_Target);
      --  Determine whether arbitrary entity Id denotes a procedure which
      --  verifies the run-time semantics of an assertion pragma.

      function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean;
      pragma Inline (Is_Bodiless_Subprogram);
      --  Determine whether subprogram Subp_Id will never have a body

      function Is_Bridge_Target (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Bridge_Target);
      --  Determine whether arbitrary entity Id denotes a bridge target

      function Is_Controlled_Proc
        (Subp_Id  : Entity_Id;
         Subp_Nam : Name_Id) return Boolean;
      pragma Inline (Is_Controlled_Proc);
      --  Determine whether subprogram Subp_Id denotes controlled type
      --  primitives Adjust, Finalize, or Initialize as denoted by name
      --  Subp_Nam.

      function Is_Default_Initial_Condition_Proc
        (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Default_Initial_Condition_Proc);
      --  Determine whether arbitrary entity Id denotes internally generated
      --  routine Default_Initial_Condition.

      function Is_Finalizer_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Finalizer_Proc);
      --  Determine whether arbitrary entity Id denotes internally generated
      --  routine _Finalizer.

      function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Initial_Condition_Proc);
      --  Determine whether arbitrary entity Id denotes internally generated
      --  routine Initial_Condition.

      function Is_Initialized (Obj_Decl : Node_Id) return Boolean;
      pragma Inline (Is_Initialized);
      --  Determine whether object declaration Obj_Decl is initialized

      function Is_Invariant_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Invariant_Proc);
      --  Determine whether arbitrary entity Id denotes an invariant procedure

      function Is_Non_Library_Level_Encapsulator (N : Node_Id) return Boolean;
      pragma Inline (Is_Non_Library_Level_Encapsulator);
      --  Determine whether arbitrary node N is a non-library encapsulator

      function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Partial_Invariant_Proc);
      --  Determine whether arbitrary entity Id denotes a partial invariant
      --  procedure.

      function Is_Postconditions_Proc (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Postconditions_Proc);
      --  Determine whether arbitrary entity Id denotes internally generated
      --  routine _Postconditions.

      function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Preelaborated_Unit);
      --  Determine whether arbitrary entity Id denotes a unit which is subject
      --  to one of the following pragmas:
      --
      --    * Preelaborable
      --    * Pure
      --    * Remote_Call_Interface
      --    * Remote_Types
      --    * Shared_Passive

      function Is_Protected_Entry (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Protected_Entry);
      --  Determine whether arbitrary entity Id denotes a protected entry

      function Is_Protected_Subp (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Protected_Subp);
      --  Determine whether entity Id denotes a protected subprogram

      function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Protected_Body_Subp);
      --  Determine whether entity Id denotes the protected or unprotected
      --  version of a protected subprogram.

      function Is_Scenario (N : Node_Id) return Boolean;
      pragma Inline (Is_Scenario);
      --  Determine whether attribute node N denotes a scenario. The scenario
      --  may not necessarily be eligible for ABE processing.

      function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean;
      pragma Inline (Is_SPARK_Semantic_Target);
      --  Determine whether arbitrary entity Id denotes a source or internally
      --  generated subprogram which emulates SPARK semantics.

      function Is_Subprogram_Inst (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Subprogram_Inst);
      --  Determine whether arbitrary entity Id denotes a subprogram instance

      function Is_Suitable_Access_Taken (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_Access_Taken);
      --  Determine whether arbitrary node N denotes a suitable attribute for
      --  ABE processing.

      function Is_Suitable_Call (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_Call);
      --  Determine whether arbitrary node N denotes a suitable call for ABE
      --  processing.

      function Is_Suitable_Instantiation (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_Instantiation);
      --  Determine whether arbitrary node N is a suitable instantiation for
      --  ABE processing.

      function Is_Suitable_SPARK_Derived_Type (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_SPARK_Derived_Type);
      --  Determine whether arbitrary node N denotes a suitable derived type
      --  declaration for ABE processing using the SPARK rules.

      function Is_Suitable_SPARK_Instantiation (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_SPARK_Instantiation);
      --  Determine whether arbitrary node N denotes a suitable instantiation
      --  for ABE processing using the SPARK rules.

      function Is_Suitable_SPARK_Refined_State_Pragma
        (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_SPARK_Refined_State_Pragma);
      --  Determine whether arbitrary node N denotes a suitable Refined_State
      --  pragma for ABE processing using the SPARK rules.

      function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_Variable_Assignment);
      --  Determine whether arbitrary node N denotes a suitable assignment for
      --  ABE processing.

      function Is_Suitable_Variable_Reference (N : Node_Id) return Boolean;
      pragma Inline (Is_Suitable_Variable_Reference);
      --  Determine whether arbitrary node N is a suitable variable reference
      --  for ABE processing.

      function Is_Task_Entry (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Task_Entry);
      --  Determine whether arbitrary entity Id denotes a task entry

      function Is_Up_Level_Target
        (Targ_Decl : Node_Id;
         In_State  : Processing_In_State) return Boolean;
      pragma Inline (Is_Up_Level_Target);
      --  Determine whether the current root resides at the declaration level.
      --  If this is the case, determine whether a target with by declaration
      --  Target_Decl is within a context which encloses the current root or is
      --  in a different unit. In_State is the current state of the Processing
      --  phase.

   end Semantics;
   use Semantics;

   --  The following package provides the main entry point for SPARK-related
   --  checks and diagnostics.

   package SPARK_Processor is

      ---------
      -- API --
      ---------

      procedure Check_SPARK_Model_In_Effect;
      pragma Inline (Check_SPARK_Model_In_Effect);
      --  Determine whether a suitable elaboration model is currently in effect
      --  for verifying SPARK rules. Emit a warning if this is not the case.

      procedure Check_SPARK_Scenarios;
      pragma Inline (Check_SPARK_Scenarios);
      --  Examine SPARK scenarios which are not necessarily executable during
      --  elaboration, but still requires elaboration-related checks.

   end SPARK_Processor;
   use SPARK_Processor;

   -----------------------
   -- Local subprograms --
   -----------------------

   function Assignment_Target (Asmt : Node_Id) return Node_Id;
   pragma Inline (Assignment_Target);
   --  Obtain the target of assignment statement Asmt

   function Call_Name (Call : Node_Id) return Node_Id;
   pragma Inline (Call_Name);
   --  Obtain the name of an entry, operator, or subprogram call Call

   function Canonical_Subprogram (Subp_Id : Entity_Id) return Entity_Id;
   pragma Inline (Canonical_Subprogram);
   --  Obtain the uniform canonical entity of subprogram Subp_Id

   function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id;
   pragma Inline (Compilation_Unit);
   --  Return the N_Compilation_Unit node of unit Unit_Id

   function Elaboration_Phase_Active return Boolean;
   pragma Inline (Elaboration_Phase_Active);
   --  Determine whether the elaboration phase of the compilation has started

   procedure Error_Preelaborated_Call (N : Node_Id);
   --  Give an error or warning for a non-static/non-preelaborable call in a
   --  preelaborated unit.

   procedure Finalize_All_Data_Structures;
   pragma Inline (Finalize_All_Data_Structures);
   --  Destroy all internal data structures

   function Find_Enclosing_Instance (N : Node_Id) return Node_Id;
   pragma Inline (Find_Enclosing_Instance);
   --  Find the declaration or body of the nearest expanded instance which
   --  encloses arbitrary node N. Return Empty if no such instance exists.

   function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id;
   pragma Inline (Find_Top_Unit);
   --  Return the top unit which contains arbitrary node or entity N. The unit
   --  is obtained by logically unwinding instantiations and subunits when N
   --  resides within one.

   function Find_Unit_Entity (N : Node_Id) return Entity_Id;
   pragma Inline (Find_Unit_Entity);
   --  Return the entity of unit N

   function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id;
   pragma Inline (First_Formal_Type);
   --  Return the type of subprogram Subp_Id's first formal parameter. If the
   --  subprogram lacks formal parameters, return Empty.

   function Has_Body (Pack_Decl : Node_Id) return Boolean;
   pragma Inline (Has_Body);
   --  Determine whether package declaration Pack_Decl has a corresponding body
   --  or would eventually have one.

   function In_External_Instance
     (N           : Node_Id;
      Target_Decl : Node_Id) return Boolean;
   pragma Inline (In_External_Instance);
   --  Determine whether a target desctibed by its declaration Target_Decl
   --  resides in a package instance which is external to scenario N.

   function In_Main_Context (N : Node_Id) return Boolean;
   pragma Inline (In_Main_Context);
   --  Determine whether arbitrary node N appears within the main compilation
   --  unit.

   function In_Same_Context
     (N1        : Node_Id;
      N2        : Node_Id;
      Nested_OK : Boolean := False) return Boolean;
   pragma Inline (In_Same_Context);
   --  Determine whether two arbitrary nodes N1 and N2 appear within the same
   --  context ignoring enclosing library levels. Nested_OK should be set when
   --  the context of N1 can enclose that of N2.

   procedure Initialize_All_Data_Structures;
   pragma Inline (Initialize_All_Data_Structures);
   --  Create all internal data structures

   function Instantiated_Generic (Inst : Node_Id) return Entity_Id;
   pragma Inline (Instantiated_Generic);
   --  Obtain the generic instantiated by instance Inst

   function Is_Safe_Activation
     (Call     : Node_Id;
      Task_Rep : Target_Rep_Id) return Boolean;
   pragma Inline (Is_Safe_Activation);
   --  Determine whether activation call Call which activates an object of a
   --  task type described by representation Task_Rep is always ABE-safe.

   function Is_Safe_Call
     (Call     : Node_Id;
      Subp_Id  : Entity_Id;
      Subp_Rep : Target_Rep_Id) return Boolean;
   pragma Inline (Is_Safe_Call);
   --  Determine whether call Call which invokes entry, operator, or subprogram
   --  Subp_Id is always ABE-safe. Subp_Rep is the representation of the entry,
   --  operator, or subprogram.

   function Is_Safe_Instantiation
     (Inst    : Node_Id;
      Gen_Id  : Entity_Id;
      Gen_Rep : Target_Rep_Id) return Boolean;
   pragma Inline (Is_Safe_Instantiation);
   --  Determine whether instantiation Inst which instantiates generic Gen_Id
   --  is always ABE-safe. Gen_Rep is the representation of the generic.

   function Is_Same_Unit
     (Unit_1 : Entity_Id;
      Unit_2 : Entity_Id) return Boolean;
   pragma Inline (Is_Same_Unit);
   --  Determine whether entities Unit_1 and Unit_2 denote the same unit

   function Main_Unit_Entity return Entity_Id;
   pragma Inline (Main_Unit_Entity);
   --  Return the entity of the main unit

   function Non_Private_View (Typ : Entity_Id) return Entity_Id;
   pragma Inline (Non_Private_View);
   --  Return the full view of private type Typ if available, otherwise return
   --  type Typ.

   function Scenario (N : Node_Id) return Node_Id;
   pragma Inline (Scenario);
   --  Return the appropriate scenario node for scenario N

   procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status);
   pragma Inline (Set_Elaboration_Phase);
   --  Change the status of the elaboration phase of the compiler to Status

   procedure Spec_And_Body_From_Entity
     (Id        : Entity_Id;
      Spec_Decl : out Node_Id;
      Body_Decl : out Node_Id);
   pragma Inline (Spec_And_Body_From_Entity);
   --  Given arbitrary entity Id representing a construct with a spec and body,
   --  retrieve declaration of the spec in Spec_Decl and the declaration of the
   --  body in Body_Decl.

   procedure Spec_And_Body_From_Node
     (N         : Node_Id;
      Spec_Decl : out Node_Id;
      Body_Decl : out Node_Id);
   pragma Inline (Spec_And_Body_From_Node);
   --  Given arbitrary node N representing a construct with a spec and body,
   --  retrieve declaration of the spec in Spec_Decl and the declaration of
   --  the body in Body_Decl.

   function Static_Elaboration_Checks return Boolean;
   pragma Inline (Static_Elaboration_Checks);
   --  Determine whether the static model is in effect

   function Unit_Entity (Unit_Id : Entity_Id) return Entity_Id;
   pragma Inline (Unit_Entity);
   --  Return the entity of the initial declaration for unit Unit_Id

   procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id);
   pragma Inline (Update_Elaboration_Scenario);
   --  Update all relevant internal data structures when scenario Old_N is
   --  transformed into scenario New_N by Atree.Rewrite.

   ----------------------
   -- Active_Scenarios --
   ----------------------

   package body Active_Scenarios is

      -----------------------
      -- Local subprograms --
      -----------------------

      procedure Output_Access_Taken
        (Attr      : Node_Id;
         Attr_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Access_Taken);
      --  Emit a specific diagnostic message for 'Access attribute reference
      --  Attr with representation Attr_Rep. The message is associated with
      --  node Error_Nod.

      procedure Output_Active_Scenario
        (N         : Node_Id;
         Error_Nod : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Output_Active_Scenario);
      --  Top level dispatcher for outputting a scenario. Emit a specific
      --  diagnostic message for scenario N. The message is associated with
      --  node Error_Nod. In_State is the current state of the Processing
      --  phase.

      procedure Output_Call
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Call);
      --  Emit a diagnostic message for call Call with representation Call_Rep.
      --  The message is associated with node Error_Nod.

      procedure Output_Header (Error_Nod : Node_Id);
      pragma Inline (Output_Header);
      --  Emit a specific diagnostic message for the unit of the root scenario.
      --  The message is associated with node Error_Nod.

      procedure Output_Instantiation
        (Inst      : Node_Id;
         Inst_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Instantiation);
      --  Emit a specific diagnostic message for instantiation Inst with
      --  representation Inst_Rep. The message is associated with node
      --  Error_Nod.

      procedure Output_Refined_State_Pragma
        (Prag      : Node_Id;
         Prag_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Refined_State_Pragma);
      --  Emit a specific diagnostic message for Refined_State pragma Prag
      --  with representation Prag_Rep. The message is associated with node
      --  Error_Nod.

      procedure Output_Task_Activation
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Task_Activation);
      --  Emit a specific diagnostic message for activation call Call
      --  with representation Call_Rep. The message is associated with
      --  node Error_Nod.

      procedure Output_Variable_Assignment
        (Asmt      : Node_Id;
         Asmt_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Variable_Assignment);
      --  Emit a specific diagnostic message for assignment statement Asmt
      --  with representation Asmt_Rep. The message is associated with node
      --  Error_Nod.

      procedure Output_Variable_Reference
        (Ref      : Node_Id;
         Ref_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id);
      pragma Inline (Output_Variable_Reference);
      --  Emit a specific diagnostic message for read reference Ref with
      --  representation Ref_Rep. The message is associated with node
      --  Error_Nod.

      -------------------
      -- Output_Access --
      -------------------

      procedure Output_Access_Taken
        (Attr      : Node_Id;
         Attr_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         Subp_Id : constant Entity_Id := Target (Attr_Rep);

      begin
         Error_Msg_Name_1 := Attribute_Name (Attr);
         Error_Msg_Sloc   := Sloc (Attr);
         Error_Msg_NE ("\\  % of & taken #", Error_Nod, Subp_Id);
      end Output_Access_Taken;

      ----------------------------
      -- Output_Active_Scenario --
      ----------------------------

      procedure Output_Active_Scenario
        (N         : Node_Id;
         Error_Nod : Node_Id;
         In_State  : Processing_In_State)
      is
         Scen     : constant Node_Id := Scenario (N);
         Scen_Rep : Scenario_Rep_Id;

      begin
         --  'Access

         if Is_Suitable_Access_Taken (Scen) then
            Output_Access_Taken
              (Attr      => Scen,
               Attr_Rep  => Scenario_Representation_Of (Scen, In_State),
               Error_Nod => Error_Nod);

         --  Call or task activation

         elsif Is_Suitable_Call (Scen) then
            Scen_Rep := Scenario_Representation_Of (Scen, In_State);

            if Kind (Scen_Rep) = Call_Scenario then
               Output_Call
                 (Call      => Scen,
                  Call_Rep  => Scen_Rep,
                  Error_Nod => Error_Nod);

            else
               pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);

               Output_Task_Activation
                 (Call      => Scen,
                  Call_Rep  => Scen_Rep,
                  Error_Nod => Error_Nod);
            end if;

         --  Instantiation

         elsif Is_Suitable_Instantiation (Scen) then
            Output_Instantiation
              (Inst      => Scen,
               Inst_Rep  => Scenario_Representation_Of (Scen, In_State),
               Error_Nod => Error_Nod);

         --  Pragma Refined_State

         elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
            Output_Refined_State_Pragma
              (Prag      => Scen,
               Prag_Rep  => Scenario_Representation_Of (Scen, In_State),
               Error_Nod => Error_Nod);

         --  Variable assignment

         elsif Is_Suitable_Variable_Assignment (Scen) then
            Output_Variable_Assignment
              (Asmt      => Scen,
               Asmt_Rep  => Scenario_Representation_Of (Scen, In_State),
               Error_Nod => Error_Nod);

         --  Variable reference

         elsif Is_Suitable_Variable_Reference (Scen) then
            Output_Variable_Reference
              (Ref       => Scen,
               Ref_Rep   => Scenario_Representation_Of (Scen, In_State),
               Error_Nod => Error_Nod);
         end if;
      end Output_Active_Scenario;

      -----------------------------
      -- Output_Active_Scenarios --
      -----------------------------

      procedure Output_Active_Scenarios
        (Error_Nod : Node_Id;
         In_State  : Processing_In_State)
      is
         package Scenarios renames Active_Scenario_Stack;

         Header_Posted : Boolean := False;

      begin
         --  Output the contents of the active scenario stack starting from the
         --  bottom, or the least recent scenario.

         for Index in Scenarios.First .. Scenarios.Last loop
            if not Header_Posted then
               Output_Header (Error_Nod);
               Header_Posted := True;
            end if;

            Output_Active_Scenario
              (N         => Scenarios.Table (Index),
               Error_Nod => Error_Nod,
               In_State  => In_State);
         end loop;
      end Output_Active_Scenarios;

      -----------------
      -- Output_Call --
      -----------------

      procedure Output_Call
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         procedure Output_Accept_Alternative (Alt_Id : Entity_Id);
         pragma Inline (Output_Accept_Alternative);
         --  Emit a specific diagnostic message concerning accept alternative
         --  with entity Alt_Id.

         procedure Output_Call (Subp_Id : Entity_Id; Kind : String);
         pragma Inline (Output_Call);
         --  Emit a specific diagnostic message concerning a call of kind Kind
         --  which invokes subprogram Subp_Id.

         procedure Output_Type_Actions (Subp_Id : Entity_Id; Action : String);
         pragma Inline (Output_Type_Actions);
         --  Emit a specific diagnostic message concerning action Action of a
         --  type performed by subprogram Subp_Id.

         procedure Output_Verification_Call
           (Pred    : String;
            Id      : Entity_Id;
            Id_Kind : String);
         pragma Inline (Output_Verification_Call);
         --  Emit a specific diagnostic message concerning the verification of
         --  predicate Pred applied to related entity Id with kind Id_Kind.

         -------------------------------
         -- Output_Accept_Alternative --
         -------------------------------

         procedure Output_Accept_Alternative (Alt_Id : Entity_Id) is
            Entry_Id : constant Entity_Id := Receiving_Entry (Alt_Id);

         begin
            pragma Assert (Present (Entry_Id));

            Error_Msg_NE ("\\  entry & selected #", Error_Nod, Entry_Id);
         end Output_Accept_Alternative;

         -----------------
         -- Output_Call --
         -----------------

         procedure Output_Call (Subp_Id : Entity_Id; Kind : String) is
         begin
            Error_Msg_NE ("\\  " & Kind & " & called #", Error_Nod, Subp_Id);
         end Output_Call;

         -------------------------
         -- Output_Type_Actions --
         -------------------------

         procedure Output_Type_Actions
           (Subp_Id : Entity_Id;
            Action  : String)
         is
            Typ : constant Entity_Id := First_Formal_Type (Subp_Id);

         begin
            pragma Assert (Present (Typ));

            Error_Msg_NE
              ("\\  " & Action & " actions for type & #", Error_Nod, Typ);
         end Output_Type_Actions;

         ------------------------------
         -- Output_Verification_Call --
         ------------------------------

         procedure Output_Verification_Call
           (Pred    : String;
            Id      : Entity_Id;
            Id_Kind : String)
         is
         begin
            pragma Assert (Present (Id));

            Error_Msg_NE
              ("\\  " & Pred & " of " & Id_Kind & " & verified #",
               Error_Nod, Id);
         end Output_Verification_Call;

         --  Local variables

         Subp_Id : constant Entity_Id := Target (Call_Rep);

      --  Start of processing for Output_Call

      begin
         Error_Msg_Sloc := Sloc (Call);

         --  Accept alternative

         if Is_Accept_Alternative_Proc (Subp_Id) then
            Output_Accept_Alternative (Subp_Id);

         --  Adjustment

         elsif Is_TSS (Subp_Id, TSS_Deep_Adjust) then
            Output_Type_Actions (Subp_Id, "adjustment");

         --  Default_Initial_Condition

         elsif Is_Default_Initial_Condition_Proc (Subp_Id) then

            --  Only do output for a normal DIC procedure, since partial DIC
            --  procedures are subsidiary to those.

            if not Is_Partial_DIC_Procedure (Subp_Id) then
               Output_Verification_Call
                 (Pred    => "Default_Initial_Condition",
                  Id      => First_Formal_Type (Subp_Id),
                  Id_Kind => "type");
            end if;

         --  Entries

         elsif Is_Protected_Entry (Subp_Id) then
            Output_Call (Subp_Id, "entry");

         --  Task entry calls are never processed because the entry being
         --  invoked does not have a corresponding "body", it has a select. A
         --  task entry call appears in the stack of active scenarios for the
         --  sole purpose of checking No_Entry_Calls_In_Elaboration_Code and
         --  nothing more.

         elsif Is_Task_Entry (Subp_Id) then
            null;

         --  Finalization

         elsif Is_TSS (Subp_Id, TSS_Deep_Finalize) then
            Output_Type_Actions (Subp_Id, "finalization");

         --  Calls to _Finalizer procedures must not appear in the output
         --  because this creates confusing noise.

         elsif Is_Finalizer_Proc (Subp_Id) then
            null;

         --  Initial_Condition

         elsif Is_Initial_Condition_Proc (Subp_Id) then
            Output_Verification_Call
              (Pred    => "Initial_Condition",
               Id      => Find_Enclosing_Scope (Call),
               Id_Kind => "package");

         --  Initialization

         elsif Is_Init_Proc (Subp_Id)
           or else Is_TSS (Subp_Id, TSS_Deep_Initialize)
         then
            Output_Type_Actions (Subp_Id, "initialization");

         --  Invariant

         elsif Is_Invariant_Proc (Subp_Id) then
            Output_Verification_Call
              (Pred    => "invariants",
               Id      => First_Formal_Type (Subp_Id),
               Id_Kind => "type");

         --  Partial invariant calls must not appear in the output because this
         --  creates confusing noise. Note that a partial invariant is always
         --  invoked by the "full" invariant which is already placed on the
         --  stack.

         elsif Is_Partial_Invariant_Proc (Subp_Id) then
            null;

         --  _Postconditions

         elsif Is_Postconditions_Proc (Subp_Id) then
            Output_Verification_Call
              (Pred    => "postconditions",
               Id      => Find_Enclosing_Scope (Call),
               Id_Kind => "subprogram");

         --  Subprograms must come last because some of the previous cases fall
         --  under this category.

         elsif Ekind (Subp_Id) = E_Function then
            Output_Call (Subp_Id, "function");

         elsif Ekind (Subp_Id) = E_Procedure then
            Output_Call (Subp_Id, "procedure");

         else
            pragma Assert (False);
            return;
         end if;
      end Output_Call;

      -------------------
      -- Output_Header --
      -------------------

      procedure Output_Header (Error_Nod : Node_Id) is
         Unit_Id : constant Entity_Id := Find_Top_Unit (Root_Scenario);

      begin
         if Ekind (Unit_Id) = E_Package then
            Error_Msg_NE ("\\  spec of unit & elaborated", Error_Nod, Unit_Id);

         elsif Ekind (Unit_Id) = E_Package_Body then
            Error_Msg_NE ("\\  body of unit & elaborated", Error_Nod, Unit_Id);

         else
            Error_Msg_NE ("\\  in body of unit &", Error_Nod, Unit_Id);
         end if;
      end Output_Header;

      --------------------------
      -- Output_Instantiation --
      --------------------------

      procedure Output_Instantiation
        (Inst      : Node_Id;
         Inst_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String);
         pragma Inline (Output_Instantiation);
         --  Emit a specific diagnostic message concerning an instantiation of
         --  generic unit Gen_Id. Kind denotes the kind of the instantiation.

         --------------------------
         -- Output_Instantiation --
         --------------------------

         procedure Output_Instantiation (Gen_Id : Entity_Id; Kind : String) is
         begin
            Error_Msg_NE
              ("\\  " & Kind & " & instantiated as & #", Error_Nod, Gen_Id);
         end Output_Instantiation;

         --  Local variables

         Gen_Id : constant Entity_Id := Target (Inst_Rep);

      --  Start of processing for Output_Instantiation

      begin
         Error_Msg_Node_2 := Defining_Entity (Inst);
         Error_Msg_Sloc   := Sloc (Inst);

         if Nkind (Inst) = N_Function_Instantiation then
            Output_Instantiation (Gen_Id, "function");

         elsif Nkind (Inst) = N_Package_Instantiation then
            Output_Instantiation (Gen_Id, "package");

         elsif Nkind (Inst) = N_Procedure_Instantiation then
            Output_Instantiation (Gen_Id, "procedure");

         else
            pragma Assert (False);
            return;
         end if;
      end Output_Instantiation;

      ---------------------------------
      -- Output_Refined_State_Pragma --
      ---------------------------------

      procedure Output_Refined_State_Pragma
        (Prag      : Node_Id;
         Prag_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         pragma Unreferenced (Prag_Rep);

      begin
         Error_Msg_Sloc := Sloc (Prag);
         Error_Msg_N ("\\  refinement constituents read #", Error_Nod);
      end Output_Refined_State_Pragma;

      ----------------------------
      -- Output_Task_Activation --
      ----------------------------

      procedure Output_Task_Activation
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         pragma Unreferenced (Call_Rep);

         function Find_Activator return Entity_Id;
         --  Find the nearest enclosing construct which houses call Call

         --------------------
         -- Find_Activator --
         --------------------

         function Find_Activator return Entity_Id is
            Par : Node_Id;

         begin
            --  Climb the parent chain looking for a package [body] or a
            --  construct with a statement sequence.

            Par := Parent (Call);
            while Present (Par) loop
               if Nkind (Par) in N_Package_Body | N_Package_Declaration then
                  return Defining_Entity (Par);

               elsif Nkind (Par) = N_Handled_Sequence_Of_Statements then
                  return Defining_Entity (Parent (Par));
               end if;

               Par := Parent (Par);
            end loop;

            return Empty;
         end Find_Activator;

         --  Local variables

         Activator : constant Entity_Id := Find_Activator;

      --  Start of processing for Output_Task_Activation

      begin
         pragma Assert (Present (Activator));

         Error_Msg_NE ("\\  local tasks of & activated", Error_Nod, Activator);
      end Output_Task_Activation;

      --------------------------------
      -- Output_Variable_Assignment --
      --------------------------------

      procedure Output_Variable_Assignment
        (Asmt      : Node_Id;
         Asmt_Rep  : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         Var_Id : constant Entity_Id := Target (Asmt_Rep);

      begin
         Error_Msg_Sloc := Sloc (Asmt);
         Error_Msg_NE ("\\  variable & assigned #", Error_Nod, Var_Id);
      end Output_Variable_Assignment;

      -------------------------------
      -- Output_Variable_Reference --
      -------------------------------

      procedure Output_Variable_Reference
        (Ref       : Node_Id;
         Ref_Rep   : Scenario_Rep_Id;
         Error_Nod : Node_Id)
      is
         Var_Id : constant Entity_Id := Target (Ref_Rep);

      begin
         Error_Msg_Sloc := Sloc (Ref);
         Error_Msg_NE ("\\  variable & read #", Error_Nod, Var_Id);
      end Output_Variable_Reference;

      -------------------------
      -- Pop_Active_Scenario --
      -------------------------

      procedure Pop_Active_Scenario (N : Node_Id) is
         package Scenarios renames Active_Scenario_Stack;
         Top : Node_Id renames Scenarios.Table (Scenarios.Last);

      begin
         pragma Assert (Top = N);
         Scenarios.Decrement_Last;
      end Pop_Active_Scenario;

      --------------------------
      -- Push_Active_Scenario --
      --------------------------

      procedure Push_Active_Scenario (N : Node_Id) is
      begin
         Active_Scenario_Stack.Append (N);
      end Push_Active_Scenario;

      -------------------
      -- Root_Scenario --
      -------------------

      function Root_Scenario return Node_Id is
         package Scenarios renames Active_Scenario_Stack;

      begin
         --  Ensure that the scenario stack has at least one active scenario in
         --  it. The one at the bottom (index First) is the root scenario.

         pragma Assert (Scenarios.Last >= Scenarios.First);
         return Scenarios.Table (Scenarios.First);
      end Root_Scenario;
   end Active_Scenarios;

   --------------------------
   -- Activation_Processor --
   --------------------------

   package body Activation_Processor is

      ------------------------
      -- Process_Activation --
      ------------------------

      procedure Process_Activation
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         Processor : Activation_Processor_Ptr;
         In_State  : Processing_In_State)
      is
         procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id);
         pragma Inline (Process_Task_Object);
         --  Invoke Processor for task object Obj_Id of type Typ

         procedure Process_Task_Objects
           (Task_Objs : NE_List.Doubly_Linked_List);
         pragma Inline (Process_Task_Objects);
         --  Invoke Processor for all task objects found in list Task_Objs

         procedure Traverse_List
           (List      : List_Id;
            Task_Objs : NE_List.Doubly_Linked_List);
         pragma Inline (Traverse_List);
         --  Traverse declarative or statement list List while searching for
         --  objects of a task type, or containing task components. If such an
         --  object is found, first save it in list Task_Objs and then invoke
         --  Processor on it.

         -------------------------
         -- Process_Task_Object --
         -------------------------

         procedure Process_Task_Object (Obj_Id : Entity_Id; Typ : Entity_Id) is
            Root_Typ : constant Entity_Id :=
                         Non_Private_View (Root_Type (Typ));
            Comp_Id  : Entity_Id;
            Obj_Rep  : Target_Rep_Id;
            Root_Rep : Target_Rep_Id;

            New_In_State : Processing_In_State := In_State;
            --  Each step of the Processing phase constitutes a new state

         begin
            if Is_Task_Type (Typ) then
               Obj_Rep  := Target_Representation_Of (Obj_Id,   New_In_State);
               Root_Rep := Target_Representation_Of (Root_Typ, New_In_State);

               --  Warnings are suppressed when a prior scenario is already in
               --  that mode, or when the object, activation call, or task type
               --  have warnings suppressed. Update the state of the Processing
               --  phase to reflect this.

               New_In_State.Suppress_Warnings :=
                 New_In_State.Suppress_Warnings
                   or else not Elaboration_Warnings_OK (Call_Rep)
                   or else not Elaboration_Warnings_OK (Obj_Rep)
                   or else not Elaboration_Warnings_OK (Root_Rep);

               --  Update the state of the Processing phase to indicate that
               --  any further traversal is now within a task body.

               New_In_State.Within_Task_Body := True;

               --  Associate the current task type with the activation call

               Set_Activated_Task_Type (Call_Rep, Root_Typ);

               --  Process the activation of the current task object by calling
               --  the supplied processor.

               Processor.all
                 (Call     => Call,
                  Call_Rep => Call_Rep,
                  Obj_Id   => Obj_Id,
                  Obj_Rep  => Obj_Rep,
                  Task_Typ => Root_Typ,
                  Task_Rep => Root_Rep,
                  In_State => New_In_State);

               --  Reset the association between the current task and the
               --  activtion call.

               Set_Activated_Task_Type (Call_Rep, Empty);

            --  Examine the component type when the object is an array

            elsif Is_Array_Type (Typ) and then Has_Task (Root_Typ) then
               Process_Task_Object
                 (Obj_Id => Obj_Id,
                  Typ    => Component_Type (Typ));

            --  Examine individual component types when the object is a record

            elsif Is_Record_Type (Typ) and then Has_Task (Root_Typ) then
               Comp_Id := First_Component (Typ);
               while Present (Comp_Id) loop
                  Process_Task_Object
                    (Obj_Id => Obj_Id,
                     Typ    => Etype (Comp_Id));

                  Next_Component (Comp_Id);
               end loop;
            end if;
         end Process_Task_Object;

         --------------------------
         -- Process_Task_Objects --
         --------------------------

         procedure Process_Task_Objects
           (Task_Objs : NE_List.Doubly_Linked_List)
         is
            Iter   : NE_List.Iterator;
            Obj_Id : Entity_Id;

         begin
            Iter := NE_List.Iterate (Task_Objs);
            while NE_List.Has_Next (Iter) loop
               NE_List.Next (Iter, Obj_Id);

               Process_Task_Object
                 (Obj_Id => Obj_Id,
                  Typ    => Etype (Obj_Id));
            end loop;
         end Process_Task_Objects;

         -------------------
         -- Traverse_List --
         -------------------

         procedure Traverse_List
           (List      : List_Id;
            Task_Objs : NE_List.Doubly_Linked_List)
         is
            Item     : Node_Id;
            Item_Id  : Entity_Id;
            Item_Typ : Entity_Id;

         begin
            --  Examine the contents of the list looking for an object
            --  declaration of a task type or one that contains a task
            --  within.

            Item := First (List);
            while Present (Item) loop
               if Nkind (Item) = N_Object_Declaration then
                  Item_Id  := Defining_Entity (Item);
                  Item_Typ := Etype (Item_Id);

                  if Has_Task (Item_Typ) then

                     --  The object is either of a task type, or contains a
                     --  task component. Save it in the list of task objects
                     --  associated with the activation call.

                     NE_List.Append (Task_Objs, Item_Id);

                     Process_Task_Object
                       (Obj_Id => Item_Id,
                        Typ    => Item_Typ);
                  end if;
               end if;

               Next (Item);
            end loop;
         end Traverse_List;

         --  Local variables

         Context   : Node_Id;
         Spec      : Node_Id;
         Task_Objs : NE_List.Doubly_Linked_List;

      --  Start of processing for Process_Activation

      begin
         --  Nothing to do when the activation is a guaranteed ABE

         if Is_Known_Guaranteed_ABE (Call) then
            return;
         end if;

         Task_Objs := Activated_Task_Objects (Call_Rep);

         --  The activation call has been processed at least once, and all
         --  task objects have already been collected. Directly process the
         --  objects without having to reexamine the context of the call.

         if NE_List.Present (Task_Objs) then
            Process_Task_Objects (Task_Objs);

         --  Otherwise the activation call is being processed for the first
         --  time. Collect all task objects in case the call is reprocessed
         --  multiple times.

         else
            Task_Objs := NE_List.Create;
            Set_Activated_Task_Objects (Call_Rep, Task_Objs);

            --  Find the context of the activation call where all task objects
            --  being activated are declared. This is usually the parent of the
            --  call.

            Context := Parent (Call);

            --  Handle the case where the activation call appears within the
            --  handled statements of a block or a body.

            if Nkind (Context) = N_Handled_Sequence_Of_Statements then
               Context := Parent (Context);
            end if;

            --  Process all task objects in both the spec and body when the
            --  activation call appears in a package body.

            if Nkind (Context) = N_Package_Body then
               Spec :=
                 Specification
                   (Unit_Declaration_Node (Corresponding_Spec (Context)));

               Traverse_List
                 (List      => Visible_Declarations (Spec),
                  Task_Objs => Task_Objs);

               Traverse_List
                 (List      => Private_Declarations (Spec),
                  Task_Objs => Task_Objs);

               Traverse_List
                 (List      => Declarations (Context),
                  Task_Objs => Task_Objs);

            --  Process all task objects in the spec when the activation call
            --  appears in a package spec.

            elsif Nkind (Context) = N_Package_Specification then
               Traverse_List
                 (List      => Visible_Declarations (Context),
                  Task_Objs => Task_Objs);

               Traverse_List
                 (List      => Private_Declarations (Context),
                  Task_Objs => Task_Objs);

            --  Otherwise the context must be a block or a body. Process all
            --  task objects found in the declarations.

            else
               pragma Assert
                 (Nkind (Context) in
                    N_Block_Statement | N_Entry_Body | N_Protected_Body |
                    N_Subprogram_Body | N_Task_Body);

               Traverse_List
                 (List      => Declarations (Context),
                  Task_Objs => Task_Objs);
            end if;
         end if;
      end Process_Activation;
   end Activation_Processor;

   -----------------------
   -- Assignment_Target --
   -----------------------

   function Assignment_Target (Asmt : Node_Id) return Node_Id is
      Nam : Node_Id;

   begin
      Nam := Name (Asmt);

      --  When the name denotes an array or record component, find the whole
      --  object.

      while Nkind (Nam) in
        N_Explicit_Dereference | N_Indexed_Component |
        N_Selected_Component   | N_Slice
      loop
         Nam := Prefix (Nam);
      end loop;

      return Nam;
   end Assignment_Target;

   --------------------
   -- Body_Processor --
   --------------------

   package body Body_Processor is

      ---------------------
      -- Data structures --
      ---------------------

      --  The following map relates scenario lists to subprogram bodies

      Nested_Scenarios_Map : NE_List_Map.Dynamic_Hash_Table := NE_List_Map.Nil;

      --  The following set contains all subprogram bodies that have been
      --  processed by routine Traverse_Body.

      Traversed_Bodies_Set : NE_Set.Membership_Set := NE_Set.Nil;

      -----------------------
      -- Local subprograms --
      -----------------------

      function Is_Traversed_Body (N : Node_Id) return Boolean;
      pragma Inline (Is_Traversed_Body);
      --  Determine whether subprogram body N has already been traversed

      function Nested_Scenarios
        (N : Node_Id) return NE_List.Doubly_Linked_List;
      pragma Inline (Nested_Scenarios);
      --  Obtain the list of scenarios associated with subprogram body N

      procedure Set_Is_Traversed_Body (N : Node_Id);
      pragma Inline (Set_Is_Traversed_Body);
      --  Mark subprogram body N as traversed

      procedure Set_Nested_Scenarios
        (N         : Node_Id;
         Scenarios : NE_List.Doubly_Linked_List);
      pragma Inline (Set_Nested_Scenarios);
      --  Associate scenario list Scenarios with subprogram body N

      -----------------------------
      -- Finalize_Body_Processor --
      -----------------------------

      procedure Finalize_Body_Processor is
      begin
         NE_List_Map.Destroy (Nested_Scenarios_Map);
         NE_Set.Destroy      (Traversed_Bodies_Set);
      end Finalize_Body_Processor;

      -------------------------------
      -- Initialize_Body_Processor --
      -------------------------------

      procedure Initialize_Body_Processor is
      begin
         Nested_Scenarios_Map := NE_List_Map.Create (250);
         Traversed_Bodies_Set := NE_Set.Create      (250);
      end Initialize_Body_Processor;

      -----------------------
      -- Is_Traversed_Body --
      -----------------------

      function Is_Traversed_Body (N : Node_Id) return Boolean is
         pragma Assert (Present (N));
      begin
         return NE_Set.Contains (Traversed_Bodies_Set, N);
      end Is_Traversed_Body;

      ----------------------
      -- Nested_Scenarios --
      ----------------------

      function Nested_Scenarios
        (N : Node_Id) return NE_List.Doubly_Linked_List
      is
         pragma Assert (Present (N));
         pragma Assert (Nkind (N) = N_Subprogram_Body);

      begin
         return NE_List_Map.Get (Nested_Scenarios_Map, N);
      end Nested_Scenarios;

      ----------------------------
      -- Reset_Traversed_Bodies --
      ----------------------------

      procedure Reset_Traversed_Bodies is
      begin
         NE_Set.Reset (Traversed_Bodies_Set);
      end Reset_Traversed_Bodies;

      ---------------------------
      -- Set_Is_Traversed_Body --
      ---------------------------

      procedure Set_Is_Traversed_Body (N : Node_Id) is
         pragma Assert (Present (N));

      begin
         NE_Set.Insert (Traversed_Bodies_Set, N);
      end Set_Is_Traversed_Body;

      --------------------------
      -- Set_Nested_Scenarios --
      --------------------------

      procedure Set_Nested_Scenarios
        (N         : Node_Id;
         Scenarios : NE_List.Doubly_Linked_List)
      is
         pragma Assert (Present (N));
      begin
         NE_List_Map.Put (Nested_Scenarios_Map, N, Scenarios);
      end Set_Nested_Scenarios;

      -------------------
      -- Traverse_Body --
      -------------------

      procedure Traverse_Body
        (N                   : Node_Id;
         Requires_Processing : Scenario_Predicate_Ptr;
         Processor           : Scenario_Processor_Ptr;
         In_State            : Processing_In_State)
      is
         Scenarios : NE_List.Doubly_Linked_List := NE_List.Nil;
         --  The list of scenarios that appear within the declarations and
         --  statement of subprogram body N. The variable is intentionally
         --  global because Is_Potential_Scenario needs to populate it.

         function In_Task_Body (Nod : Node_Id) return Boolean;
         pragma Inline (In_Task_Body);
         --  Determine whether arbitrary node Nod appears within a task body

         function Is_Synchronous_Suspension_Call
           (Nod : Node_Id) return Boolean;
         pragma Inline (Is_Synchronous_Suspension_Call);
         --  Determine whether arbitrary node Nod denotes a call to one of
         --  these routines:
         --
         --    Ada.Synchronous_Barriers.Wait_For_Release
         --    Ada.Synchronous_Task_Control.Suspend_Until_True

         procedure Traverse_Collected_Scenarios;
         pragma Inline (Traverse_Collected_Scenarios);
         --  Traverse the already collected scenarios in list Scenarios by
         --  invoking Processor on each individual one.

         procedure Traverse_List (List : List_Id);
         pragma Inline (Traverse_List);
         --  Invoke Traverse_Potential_Scenarios on each node in list List

         function Traverse_Potential_Scenario
           (Scen : Node_Id) return Traverse_Result;
         pragma Inline (Traverse_Potential_Scenario);
         --  Determine whether arbitrary node Scen is a suitable scenario using
         --  predicate Is_Scenario and traverse it by invoking Processor on it.

         procedure Traverse_Potential_Scenarios is
           new Traverse_Proc (Traverse_Potential_Scenario);

         ------------------
         -- In_Task_Body --
         ------------------

         function In_Task_Body (Nod : Node_Id) return Boolean is
            Par : Node_Id;

         begin
            --  Climb the parent chain looking for a task body [procedure]

            Par := Nod;
            while Present (Par) loop
               if Nkind (Par) = N_Task_Body then
                  return True;

               elsif Nkind (Par) = N_Subprogram_Body
                 and then Is_Task_Body_Procedure (Par)
               then
                  return True;

               --  Prevent the search from going too far. Note that this test
               --  shares nodes with the two cases above, and must come last.

               elsif Is_Body_Or_Package_Declaration (Par) then
                  return False;
               end if;

               Par := Parent (Par);
            end loop;

            return False;
         end In_Task_Body;

         ------------------------------------
         -- Is_Synchronous_Suspension_Call --
         ------------------------------------

         function Is_Synchronous_Suspension_Call
           (Nod : Node_Id) return Boolean
         is
            Subp_Id : Entity_Id;

         begin
            --  To qualify, the call must invoke one of the runtime routines
            --  which perform synchronous suspension.

            if Is_Suitable_Call (Nod) then
               Subp_Id := Target (Nod);

               return
                 Is_RTE (Subp_Id, RE_Suspend_Until_True)
                   or else
                 Is_RTE (Subp_Id, RE_Wait_For_Release);
            end if;

            return False;
         end Is_Synchronous_Suspension_Call;

         ----------------------------------
         -- Traverse_Collected_Scenarios --
         ----------------------------------

         procedure Traverse_Collected_Scenarios is
            Iter : NE_List.Iterator;
            Scen : Node_Id;

         begin
            Iter := NE_List.Iterate (Scenarios);
            while NE_List.Has_Next (Iter) loop
               NE_List.Next (Iter, Scen);

               --  The current scenario satisfies the input predicate, process
               --  it.

               if Requires_Processing.all (Scen) then
                  Processor.all (Scen, In_State);
               end if;
            end loop;
         end Traverse_Collected_Scenarios;

         -------------------
         -- Traverse_List --
         -------------------

         procedure Traverse_List (List : List_Id) is
            Scen : Node_Id;

         begin
            Scen := First (List);
            while Present (Scen) loop
               Traverse_Potential_Scenarios (Scen);
               Next (Scen);
            end loop;
         end Traverse_List;

         ---------------------------------
         -- Traverse_Potential_Scenario --
         ---------------------------------

         function Traverse_Potential_Scenario
           (Scen : Node_Id) return Traverse_Result
         is
         begin
            --  Special cases

            --  Skip constructs which do not have elaboration of their own and
            --  need to be elaborated by other means such as invocation, task
            --  activation, etc.

            if Is_Non_Library_Level_Encapsulator (Scen) then
               return Skip;

            --  Terminate the traversal of a task body when encountering an
            --  accept or select statement, and
            --
            --    * Entry calls during elaboration are not allowed. In this
            --      case the accept or select statement will cause the task
            --      to block at elaboration time because there are no entry
            --      calls to unblock it.
            --
            --  or
            --
            --    * Switch -gnatd_a (stop elaboration checks on accept or
            --      select statement) is in effect.

            elsif (Debug_Flag_Underscore_A
                    or else Restriction_Active
                              (No_Entry_Calls_In_Elaboration_Code))
              and then Nkind (Original_Node (Scen)) in
                         N_Accept_Statement | N_Selective_Accept
            then
               return Abandon;

            --  Terminate the traversal of a task body when encountering a
            --  suspension call, and
            --
            --    * Entry calls during elaboration are not allowed. In this
            --      case the suspension call emulates an entry call and will
            --      cause the task to block at elaboration time.
            --
            --  or
            --
            --    * Switch -gnatd_s (stop elaboration checks on synchronous
            --      suspension) is in effect.
            --
            --  Note that the guard should not be checking the state of flag
            --  Within_Task_Body because only suspension calls which appear
            --  immediately within the statements of the task are supported.
            --  Flag Within_Task_Body carries over to deeper levels of the
            --  traversal.

            elsif (Debug_Flag_Underscore_S
                    or else Restriction_Active
                              (No_Entry_Calls_In_Elaboration_Code))
              and then Is_Synchronous_Suspension_Call (Scen)
              and then In_Task_Body (Scen)
            then
               return Abandon;

            --  Certain nodes carry semantic lists which act as repositories
            --  until expansion transforms the node and relocates the contents.
            --  Examine these lists in case expansion is disabled.

            elsif Nkind (Scen) in N_And_Then | N_Or_Else then
               Traverse_List (Actions (Scen));

            elsif Nkind (Scen) in N_Elsif_Part | N_Iteration_Scheme then
               Traverse_List (Condition_Actions (Scen));

            elsif Nkind (Scen) = N_If_Expression then
               Traverse_List (Then_Actions (Scen));
               Traverse_List (Else_Actions (Scen));

            elsif Nkind (Scen) in
                    N_Component_Association | N_Iterated_Component_Association
            then
               Traverse_List (Loop_Actions (Scen));

            --  General case

            --  The current node satisfies the input predicate, process it

            elsif Requires_Processing.all (Scen) then
               Processor.all (Scen, In_State);
            end if;

            --  Save a general scenario regardless of whether it satisfies the
            --  input predicate. This allows for quick subsequent traversals of
            --  general scenarios, even with different predicates.

            if Is_Suitable_Access_Taken (Scen)
              or else Is_Suitable_Call (Scen)
              or else Is_Suitable_Instantiation (Scen)
              or else Is_Suitable_Variable_Assignment (Scen)
              or else Is_Suitable_Variable_Reference (Scen)
            then
               NE_List.Append (Scenarios, Scen);
            end if;

            return OK;
         end Traverse_Potential_Scenario;

      --  Start of processing for Traverse_Body

      begin
         --  Nothing to do when the traversal is suppressed

         if In_State.Traversal = No_Traversal then
            return;

         --  Nothing to do when there is no input

         elsif No (N) then
            return;

         --  Nothing to do when the input is not a subprogram body

         elsif Nkind (N) /= N_Subprogram_Body then
            return;

         --  Nothing to do if the subprogram body was already traversed

         elsif Is_Traversed_Body (N) then
            return;
         end if;

         --  Mark the subprogram body as traversed

         Set_Is_Traversed_Body (N);

         Scenarios := Nested_Scenarios (N);

         --  The subprogram body has been traversed at least once, and all
         --  scenarios that appear within its declarations and statements
         --  have already been collected. Directly retraverse the scenarios
         --  without having to retraverse the subprogram body subtree.

         if NE_List.Present (Scenarios) then
            Traverse_Collected_Scenarios;

         --  Otherwise the subprogram body is being traversed for the first
         --  time. Collect all scenarios that appear within its declarations
         --  and statements in case the subprogram body has to be retraversed
         --  multiple times.

         else
            Scenarios := NE_List.Create;
            Set_Nested_Scenarios (N, Scenarios);

            Traverse_List (Declarations (N));
            Traverse_Potential_Scenarios (Handled_Statement_Sequence (N));
         end if;
      end Traverse_Body;
   end Body_Processor;

   -----------------------
   -- Build_Call_Marker --
   -----------------------

   procedure Build_Call_Marker (N : Node_Id) is
      function In_External_Context
        (Call    : Node_Id;
         Subp_Id : Entity_Id) return Boolean;
      pragma Inline (In_External_Context);
      --  Determine whether entry, operator, or subprogram Subp_Id is external
      --  to call Call which must reside within an instance.

      function In_Premature_Context (Call : Node_Id) return Boolean;
      pragma Inline (In_Premature_Context);
      --  Determine whether call Call appears within a premature context

      function Is_Default_Expression (Call : Node_Id) return Boolean;
      pragma Inline (Is_Default_Expression);
      --  Determine whether call Call acts as the expression of a defaulted
      --  parameter within a source call.

      function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean;
      pragma Inline (Is_Generic_Formal_Subp);
      --  Determine whether subprogram Subp_Id denotes a generic formal
      --  subprogram which appears in the "prologue" of an instantiation.

      -------------------------
      -- In_External_Context --
      -------------------------

      function In_External_Context
        (Call    : Node_Id;
         Subp_Id : Entity_Id) return Boolean
      is
         Spec_Decl : constant Entity_Id := Unit_Declaration_Node (Subp_Id);

         Inst      : Node_Id;
         Inst_Body : Node_Id;
         Inst_Spec : Node_Id;

      begin
         Inst := Find_Enclosing_Instance (Call);

         --  The call appears within an instance

         if Present (Inst) then

            --  The call comes from the main unit and the target does not

            if In_Extended_Main_Code_Unit (Call)
              and then not In_Extended_Main_Code_Unit (Spec_Decl)
            then
               return True;

            --  Otherwise the target declaration must not appear within the
            --  instance spec or body.

            else
               Spec_And_Body_From_Node
                 (N         => Inst,
                  Spec_Decl => Inst_Spec,
                  Body_Decl => Inst_Body);

               return not In_Subtree
                            (N     => Spec_Decl,
                             Root1 => Inst_Spec,
                             Root2 => Inst_Body);
            end if;
         end if;

         return False;
      end In_External_Context;

      --------------------------
      -- In_Premature_Context --
      --------------------------

      function In_Premature_Context (Call : Node_Id) return Boolean is
         Par : Node_Id;

      begin
         --  Climb the parent chain looking for premature contexts

         Par := Parent (Call);
         while Present (Par) loop

            --  Aspect specifications and generic associations are premature
            --  contexts because nested calls has not been relocated to their
            --  final context.

            if Nkind (Par) in N_Aspect_Specification | N_Generic_Association
            then
               return True;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);
         end loop;

         return False;
      end In_Premature_Context;

      ---------------------------
      -- Is_Default_Expression --
      ---------------------------

      function Is_Default_Expression (Call : Node_Id) return Boolean is
         Outer_Call : constant Node_Id := Parent (Call);
         Outer_Nam  : Node_Id;

      begin
         --  To qualify, the node must appear immediately within a source call
         --  which invokes a source target.

         if Nkind (Outer_Call) in N_Entry_Call_Statement
                                | N_Function_Call
                                | N_Procedure_Call_Statement
           and then Comes_From_Source (Outer_Call)
         then
            Outer_Nam := Call_Name (Outer_Call);

            return
              Is_Entity_Name (Outer_Nam)
                and then Present (Entity (Outer_Nam))
                and then Is_Subprogram_Or_Entry (Entity (Outer_Nam))
                and then Comes_From_Source (Entity (Outer_Nam));
         end if;

         return False;
      end Is_Default_Expression;

      ----------------------------
      -- Is_Generic_Formal_Subp --
      ----------------------------

      function Is_Generic_Formal_Subp (Subp_Id : Entity_Id) return Boolean is
         Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id);
         Context   : constant Node_Id := Parent (Subp_Decl);

      begin
         --  To qualify, the subprogram must rename a generic actual subprogram
         --  where the enclosing context is an instantiation.

         return
           Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
             and then not Comes_From_Source (Subp_Decl)
             and then Nkind (Context) in N_Function_Specification
                                       | N_Package_Specification
                                       | N_Procedure_Specification
             and then Present (Generic_Parent (Context));
      end Is_Generic_Formal_Subp;

      --  Local variables

      Call_Nam : Node_Id;
      Marker   : Node_Id;
      Subp_Id  : Entity_Id;

   --  Start of processing for Build_Call_Marker

   begin
      --  Nothing to do when switch -gnatH (legacy elaboration checking mode
      --  enabled) is in effect because the legacy ABE mechanism does not need
      --  to carry out this action.

      if Legacy_Elaboration_Checks then
         return;

      --  Nothing to do when the call is being preanalyzed as the marker will
      --  be inserted in the wrong place.

      elsif Preanalysis_Active then
         return;

      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      elsif not Elaboration_Phase_Active then
         return;

      --  Nothing to do when the input does not denote a call or a requeue

      elsif Nkind (N) not in N_Entry_Call_Statement
                           | N_Function_Call
                           | N_Procedure_Call_Statement
                           | N_Requeue_Statement
      then
         return;

      --  Nothing to do when the input denotes entry call or requeue statement,
      --  and switch -gnatd_e (ignore entry calls and requeue statements for
      --  elaboration) is in effect.

      elsif Debug_Flag_Underscore_E
        and then Nkind (N) in N_Entry_Call_Statement | N_Requeue_Statement
      then
         return;

      --  Nothing to do when the call is analyzed/resolved too early within an
      --  intermediate context. This check is saved for last because it incurs
      --  a performance penalty.

      elsif In_Premature_Context (N) then
         return;
      end if;

      Call_Nam := Call_Name (N);

      --  Nothing to do when the call is erroneous or left in a bad state

      if not (Is_Entity_Name (Call_Nam)
               and then Present (Entity (Call_Nam))
               and then Is_Subprogram_Or_Entry (Entity (Call_Nam)))
      then
         return;
      end if;

      Subp_Id := Canonical_Subprogram (Entity (Call_Nam));

      --  Nothing to do when the call invokes a generic formal subprogram and
      --  switch -gnatd.G (ignore calls through generic formal parameters for
      --  elaboration) is in effect. This check must be performed with the
      --  direct target of the call to avoid the side effects of mapping
      --  actuals to formals using renamings.

      if Debug_Flag_Dot_GG
        and then Is_Generic_Formal_Subp (Entity (Call_Nam))
      then
         return;

      --  Nothing to do when the call appears within the expanded spec or
      --  body of an instantiated generic, the call does not invoke a generic
      --  formal subprogram, the target is external to the instance, and switch
      --  -gnatdL (ignore external calls from instances for elaboration) is in
      --  effect. This check must be performed with the direct target of the
      --  call to avoid the side effects of mapping actuals to formals using
      --  renamings.

      elsif Debug_Flag_LL
        and then not Is_Generic_Formal_Subp (Entity (Call_Nam))
        and then In_External_Context
                   (Call    => N,
                    Subp_Id => Subp_Id)
      then
         return;

      --  Nothing to do when the call invokes an assertion pragma procedure
      --  and switch -gnatd_p (ignore assertion pragmas for elaboration) is
      --  in effect.

      elsif Debug_Flag_Underscore_P
        and then Is_Assertion_Pragma_Target (Subp_Id)
      then
         return;

      --  Static expression functions require no ABE processing

      elsif Is_Static_Function (Subp_Id) then
         return;

      --  Source calls to source targets are always considered because they
      --  reflect the original call graph.

      elsif Comes_From_Source (N) and then Comes_From_Source (Subp_Id) then
         null;

      --  A call to a source function which acts as the default expression in
      --  another call requires special detection.

      elsif Comes_From_Source (Subp_Id)
        and then Nkind (N) = N_Function_Call
        and then Is_Default_Expression (N)
      then
         null;

      --  The target emulates Ada semantics

      elsif Is_Ada_Semantic_Target (Subp_Id) then
         null;

      --  The target acts as a link between scenarios

      elsif Is_Bridge_Target (Subp_Id) then
         null;

      --  The target emulates SPARK semantics

      elsif Is_SPARK_Semantic_Target (Subp_Id) then
         null;

      --  Otherwise the call is not suitable for ABE processing. This prevents
      --  the generation of call markers which will never play a role in ABE
      --  diagnostics.

      else
         return;
      end if;

      --  At this point it is known that the call will play some role in ABE
      --  checks and diagnostics. Create a corresponding call marker in case
      --  the original call is heavily transformed by expansion later on.

      Marker := Make_Call_Marker (Sloc (N));

      --  Inherit the attributes of the original call

      Set_Is_Declaration_Level_Node
        (Marker, Find_Enclosing_Level (N) = Declaration_Level);

      Set_Is_Dispatching_Call
        (Marker,
         Nkind (N) in N_Subprogram_Call
           and then Present (Controlling_Argument (N)));

      Set_Is_Elaboration_Checks_OK_Node
        (Marker, Is_Elaboration_Checks_OK_Node (N));

      Set_Is_Elaboration_Warnings_OK_Node
        (Marker, Is_Elaboration_Warnings_OK_Node (N));

      Set_Is_Ignored_Ghost_Node (Marker, Is_Ignored_Ghost_Node (N));
      Set_Is_Source_Call        (Marker, Comes_From_Source (N));
      Set_Is_SPARK_Mode_On_Node (Marker, Is_SPARK_Mode_On_Node (N));
      Set_Target                (Marker, Subp_Id);

      --  Ada 2022 (AI12-0175): Calls to certain functions that are essentially
      --  unchecked conversions are preelaborable.

      if Ada_Version >= Ada_2022 then
         Set_Is_Preelaborable_Call (Marker, Is_Preelaborable_Construct (N));
      else
         Set_Is_Preelaborable_Call (Marker, False);
      end if;

      --  The marker is inserted prior to the original call. This placement has
      --  several desirable effects:

      --    1) The marker appears in the same context, in close proximity to
      --       the call.

      --         <marker>
      --         <call>

      --    2) Inserting the marker prior to the call ensures that an ABE check
      --       will take effect prior to the call.

      --         <ABE check>
      --         <marker>
      --         <call>

      --    3) The above two properties are preserved even when the call is a
      --       function which is subsequently relocated in order to capture its
      --       result. Note that if the call is relocated to a new context, the
      --       relocated call will receive a marker of its own.

      --         <ABE check>
      --         <maker>
      --         Temp : ... := Func_Call ...;
      --         ... Temp ...

      --  The insertion must take place even when the call does not occur in
      --  the main unit to keep the tree symmetric. This ensures that internal
      --  name serialization is consistent in case the call marker causes the
      --  tree to transform in some way.

      Insert_Action (N, Marker);

      --  The marker becomes the "corresponding" scenario for the call. Save
      --  the marker for later processing by the ABE phase.

      Record_Elaboration_Scenario (Marker);
   end Build_Call_Marker;

   -------------------------------------
   -- Build_Variable_Reference_Marker --
   -------------------------------------

   procedure Build_Variable_Reference_Marker
     (N     : Node_Id;
      Read  : Boolean;
      Write : Boolean)
   is
      function Ultimate_Variable (Var_Id : Entity_Id) return Entity_Id;
      pragma Inline (Ultimate_Variable);
      --  Obtain the ultimate renamed variable of variable Var_Id

      -----------------------
      -- Ultimate_Variable --
      -----------------------

      function Ultimate_Variable (Var_Id : Entity_Id) return Entity_Id is
         pragma Assert (Ekind (Var_Id) = E_Variable);
         Ren_Id : Entity_Id;
      begin
         Ren_Id := Var_Id;
         while Present (Renamed_Object (Ren_Id))
           and then Nkind (Renamed_Object (Ren_Id)) in N_Entity
         loop
            Ren_Id := Renamed_Object (Ren_Id);
         end loop;

         return Ren_Id;
      end Ultimate_Variable;

      --  Local variables

      Var_Id : constant Entity_Id := Ultimate_Variable (Entity (N));
      Marker : Node_Id;

   --  Start of processing for Build_Variable_Reference_Marker

   begin
      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      if not Elaboration_Phase_Active then
         return;
      end if;

      Marker := Make_Variable_Reference_Marker (Sloc (N));

      --  Inherit the attributes of the original variable reference

      Set_Is_Elaboration_Checks_OK_Node
        (Marker, Is_Elaboration_Checks_OK_Node (N));

      Set_Is_Elaboration_Warnings_OK_Node
        (Marker, Is_Elaboration_Warnings_OK_Node (N));

      Set_Is_Read               (Marker, Read);
      Set_Is_SPARK_Mode_On_Node (Marker, Is_SPARK_Mode_On_Node (N));
      Set_Is_Write              (Marker, Write);
      Set_Target                (Marker, Var_Id);

      --  The marker is inserted prior to the original variable reference. The
      --  insertion must take place even when the reference does not occur in
      --  the main unit to keep the tree symmetric. This ensures that internal
      --  name serialization is consistent in case the variable marker causes
      --  the tree to transform in some way.

      Insert_Action (N, Marker);

      --  The marker becomes the "corresponding" scenario for the reference.
      --  Save the marker for later processing for the ABE phase.

      Record_Elaboration_Scenario (Marker);
   end Build_Variable_Reference_Marker;

   ---------------
   -- Call_Name --
   ---------------

   function Call_Name (Call : Node_Id) return Node_Id is
      Nam : Node_Id;

   begin
      Nam := Name (Call);

      --  When the call invokes an entry family, the name appears as an indexed
      --  component.

      if Nkind (Nam) = N_Indexed_Component then
         Nam := Prefix (Nam);
      end if;

      --  When the call employs the object.operation form, the name appears as
      --  a selected component.

      if Nkind (Nam) = N_Selected_Component then
         Nam := Selector_Name (Nam);
      end if;

      return Nam;
   end Call_Name;

   --------------------------
   -- Canonical_Subprogram --
   --------------------------

   function Canonical_Subprogram (Subp_Id : Entity_Id) return Entity_Id is
      Canon_Id : Entity_Id;

   begin
      Canon_Id := Subp_Id;

      --  Use the original protected subprogram when dealing with one of the
      --  specialized lock-manipulating versions.

      if Is_Protected_Body_Subp (Canon_Id) then
         Canon_Id := Protected_Subprogram (Canon_Id);
      end if;

      --  Obtain the original subprogram except when the subprogram is also
      --  an instantiation. In this case the alias is the internally generated
      --  subprogram which appears within the anonymous package created for the
      --  instantiation, making it unuitable.

      if not Is_Generic_Instance (Canon_Id) then
         Canon_Id := Get_Renamed_Entity (Canon_Id);
      end if;

      return Canon_Id;
   end Canonical_Subprogram;

   ---------------------------------
   -- Check_Elaboration_Scenarios --
   ---------------------------------

   procedure Check_Elaboration_Scenarios is
      Iter : NE_Set.Iterator;

   begin
      --  Nothing to do when switch -gnatH (legacy elaboration checking mode
      --  enabled) is in effect because the legacy ABE mechanism does not need
      --  to carry out this action.

      if Legacy_Elaboration_Checks then
         Finalize_All_Data_Structures;
         return;

      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      elsif not Elaboration_Phase_Active then
         Finalize_All_Data_Structures;
         return;
      end if;

      --  Restore the original elaboration model which was in effect when the
      --  scenarios were first recorded. The model may be specified by pragma
      --  Elaboration_Checks which appears on the initial declaration of the
      --  main unit.

      Install_Elaboration_Model (Unit_Entity (Main_Unit_Entity));

      --  Examine the context of the main unit and record all units with prior
      --  elaboration with respect to it.

      Collect_Elaborated_Units;

      --  Examine all scenarios saved during the Recording phase applying the
      --  Ada or SPARK elaboration rules in order to detect and diagnose ABE
      --  issues, install conditional ABE checks, and ensure the elaboration
      --  of units.

      Iter := Iterate_Declaration_Scenarios;
      Check_Conditional_ABE_Scenarios (Iter);

      Iter := Iterate_Library_Body_Scenarios;
      Check_Conditional_ABE_Scenarios (Iter);

      Iter := Iterate_Library_Spec_Scenarios;
      Check_Conditional_ABE_Scenarios (Iter);

      --  Examine each SPARK scenario saved during the Recording phase which
      --  is not necessarily executable during elaboration, but still requires
      --  elaboration-related checks.

      Check_SPARK_Scenarios;

      --  Add conditional ABE checks for all scenarios that require one when
      --  the dynamic model is in effect.

      Install_Dynamic_ABE_Checks;

      --  Examine all scenarios saved during the Recording phase along with
      --  invocation constructs within the spec and body of the main unit.
      --  Record the declarations and paths that reach into an external unit
      --  in the ALI file of the main unit.

      Record_Invocation_Graph;

      --  Destroy all internal data structures and complete the elaboration
      --  phase of the compiler.

      Finalize_All_Data_Structures;
      Set_Elaboration_Phase (Completed);
   end Check_Elaboration_Scenarios;

   ---------------------
   -- Check_Installer --
   ---------------------

   package body Check_Installer is

      -----------------------
      -- Local subprograms --
      -----------------------

      function ABE_Check_Or_Failure_OK
        (N       : Node_Id;
         Targ_Id : Entity_Id;
         Unit_Id : Entity_Id) return Boolean;
      pragma Inline (ABE_Check_Or_Failure_OK);
      --  Determine whether a conditional ABE check or guaranteed ABE failure
      --  can be installed for scenario N with target Targ_Id which resides in
      --  unit Unit_Id.

      function Insertion_Node (N : Node_Id) return Node_Id;
      pragma Inline (Insertion_Node);
      --  Obtain the proper insertion node of an ABE check or failure for
      --  scenario N.

      procedure Insert_ABE_Check_Or_Failure (N : Node_Id; Check : Node_Id);
      pragma Inline (Insert_ABE_Check_Or_Failure);
      --  Insert conditional ABE check or guaranteed ABE failure Check prior to
      --  scenario N.

      procedure Install_Scenario_ABE_Check_Common
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id);
      pragma Inline (Install_Scenario_ABE_Check_Common);
      --  Install a conditional ABE check for scenario N to ensure that target
      --  Targ_Id is properly elaborated. Targ_Rep is the representation of the
      --  target.

      procedure Install_Scenario_ABE_Failure_Common (N : Node_Id);
      pragma Inline (Install_Scenario_ABE_Failure_Common);
      --  Install a guaranteed ABE failure for scenario N

      procedure Install_Unit_ABE_Check_Common
        (N       : Node_Id;
         Unit_Id : Entity_Id);
      pragma Inline (Install_Unit_ABE_Check_Common);
      --  Install a conditional ABE check for scenario N to ensure that unit
      --  Unit_Id is properly elaborated.

      -----------------------------
      -- ABE_Check_Or_Failure_OK --
      -----------------------------

      function ABE_Check_Or_Failure_OK
        (N       : Node_Id;
         Targ_Id : Entity_Id;
         Unit_Id : Entity_Id) return Boolean
      is
         pragma Unreferenced (Targ_Id);

         Ins_Node : constant Node_Id := Insertion_Node (N);

      begin
         if not Check_Or_Failure_Generation_OK then
            return False;

         --  Nothing to do when the scenario denots a compilation unit because
         --  there is no executable environment at that level.

         elsif Nkind (Parent (Ins_Node)) = N_Compilation_Unit then
            return False;

         --  An ABE check or failure is not needed when the target is defined
         --  in a unit which is elaborated prior to the main unit. This check
         --  must also consider the following cases:
         --
         --  * The unit of the target appears in the context of the main unit
         --
         --  * The unit of the target is subject to pragma Elaborate_Body. An
         --    ABE check MUST NOT be generated because the unit is always
         --    elaborated prior to the main unit.
         --
         --  * The unit of the target is the main unit. An ABE check MUST be
         --    added in this case because a conditional ABE may be raised
         --    depending on the flow of execution within the main unit (flag
         --    Same_Unit_OK is False).

         elsif Has_Prior_Elaboration
                 (Unit_Id      => Unit_Id,
                  Context_OK   => True,
                  Elab_Body_OK => True)
         then
            return False;
         end if;

         return True;
      end ABE_Check_Or_Failure_OK;

      ------------------------------------
      -- Check_Or_Failure_Generation_OK --
      ------------------------------------

      function Check_Or_Failure_Generation_OK return Boolean is
      begin
         --  An ABE check or failure is not needed when the compilation will
         --  not produce an executable.

         if Serious_Errors_Detected > 0 then
            return False;

         --  An ABE check or failure must not be installed when compiling for
         --  GNATprove because raise statements are not supported.

         elsif GNATprove_Mode then
            return False;
         end if;

         return True;
      end Check_Or_Failure_Generation_OK;

      --------------------
      -- Insertion_Node --
      --------------------

      function Insertion_Node (N : Node_Id) return Node_Id is
      begin
         --  When the scenario denotes an instantiation, the proper insertion
         --  node is the instance spec. This ensures that the generic actuals
         --  will not be evaluated prior to a potential ABE.

         if Nkind (N) in N_Generic_Instantiation
           and then Present (Instance_Spec (N))
         then
            return Instance_Spec (N);

         --  Otherwise the proper insertion node is the scenario itself

         else
            return N;
         end if;
      end Insertion_Node;

      ---------------------------------
      -- Insert_ABE_Check_Or_Failure --
      ---------------------------------

      procedure Insert_ABE_Check_Or_Failure (N : Node_Id; Check : Node_Id) is
         Ins_Nod : constant Node_Id   := Insertion_Node (N);
         Scop_Id : constant Entity_Id := Find_Enclosing_Scope (Ins_Nod);

      begin
         --  Install the nearest enclosing scope of the scenario as there must
         --  be something on the scope stack.

         Push_Scope (Scop_Id);

         Insert_Action (Ins_Nod, Check);

         Pop_Scope;
      end Insert_ABE_Check_Or_Failure;

      --------------------------------
      -- Install_Dynamic_ABE_Checks --
      --------------------------------

      procedure Install_Dynamic_ABE_Checks is
         Iter : NE_Set.Iterator;
         N    : Node_Id;

      begin
         if not Check_Or_Failure_Generation_OK then
            return;

         --  Nothing to do if the dynamic model is not in effect

         elsif not Dynamic_Elaboration_Checks then
            return;
         end if;

         --  Install a conditional ABE check for each saved scenario

         Iter := Iterate_Dynamic_ABE_Check_Scenarios;
         while NE_Set.Has_Next (Iter) loop
            NE_Set.Next (Iter, N);

            Process_Conditional_ABE
              (N        => N,
               In_State => Dynamic_Model_State);
         end loop;
      end Install_Dynamic_ABE_Checks;

      --------------------------------
      -- Install_Scenario_ABE_Check --
      --------------------------------

      procedure Install_Scenario_ABE_Check
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Scenario_Rep_Id)
      is
      begin
         --  Nothing to do when the scenario does not need an ABE check

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Targ_Id,
                   Unit_Id => Unit (Targ_Rep))
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Scenario_ABE_Check_Common
           (N        => N,
            Targ_Id  => Targ_Id,
            Targ_Rep => Targ_Rep);
      end Install_Scenario_ABE_Check;

      --------------------------------
      -- Install_Scenario_ABE_Check --
      --------------------------------

      procedure Install_Scenario_ABE_Check
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Target_Rep_Id)
      is
      begin
         --  Nothing to do when the scenario does not need an ABE check

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Targ_Id,
                   Unit_Id => Unit (Targ_Rep))
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Scenario_ABE_Check_Common
           (N        => N,
            Targ_Id  => Targ_Id,
            Targ_Rep => Targ_Rep);
      end Install_Scenario_ABE_Check;

      ---------------------------------------
      -- Install_Scenario_ABE_Check_Common --
      ---------------------------------------

      procedure Install_Scenario_ABE_Check_Common
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id)
      is
         Targ_Body : constant Node_Id := Body_Declaration (Targ_Rep);
         Targ_Decl : constant Node_Id := Spec_Declaration (Targ_Rep);

         pragma Assert (Present (Targ_Body));
         pragma Assert (Present (Targ_Decl));

         procedure Build_Elaboration_Entity;
         pragma Inline (Build_Elaboration_Entity);
         --  Create a new elaboration flag for Targ_Id, insert it prior to
         --  Targ_Decl, and set it after Targ_Body.

         ------------------------------
         -- Build_Elaboration_Entity --
         ------------------------------

         procedure Build_Elaboration_Entity is
            Loc     : constant Source_Ptr := Sloc (Targ_Id);
            Flag_Id : Entity_Id;

         begin
            --  Nothing to do if the target has an elaboration flag

            if Present (Elaboration_Entity (Targ_Id)) then
               return;
            end if;

            --  Create the declaration of the elaboration flag. The name
            --  carries a unique counter in case the name is overloaded.

            Flag_Id :=
              Make_Defining_Identifier (Loc,
                Chars => New_External_Name (Chars (Targ_Id), 'E', -1));

            Set_Elaboration_Entity          (Targ_Id, Flag_Id);
            Set_Elaboration_Entity_Required (Targ_Id);

            Push_Scope (Scope (Targ_Id));

            --  Generate:
            --    Enn : Short_Integer := 0;

            Insert_Action (Targ_Decl,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Flag_Id,
                Object_Definition   =>
                  New_Occurrence_Of (Standard_Short_Integer, Loc),
                Expression          => Make_Integer_Literal (Loc, Uint_0)));

            --  Generate:
            --    Enn := 1;

            Set_Elaboration_Flag (Targ_Body, Targ_Id);

            Pop_Scope;
         end Build_Elaboration_Entity;

         --  Local variables

         Loc  : constant Source_Ptr := Sloc (N);

      --  Start for processing for Install_Scenario_ABE_Check_Common

      begin
         --  Create an elaboration flag for the target when it does not have
         --  one.

         Build_Elaboration_Entity;

         --  Generate:
         --    if not Targ_Id'Elaborated then
         --       raise Program_Error with "access before elaboration";
         --    end if;

         Insert_ABE_Check_Or_Failure
           (N     => N,
            Check =>
              Make_Raise_Program_Error (Loc,
                Condition =>
                  Make_Op_Not (Loc,
                    Right_Opnd =>
                      Make_Attribute_Reference (Loc,
                        Prefix         => New_Occurrence_Of (Targ_Id, Loc),
                        Attribute_Name => Name_Elaborated)),
                Reason    => PE_Access_Before_Elaboration));
      end Install_Scenario_ABE_Check_Common;

      ----------------------------------
      -- Install_Scenario_ABE_Failure --
      ----------------------------------

      procedure Install_Scenario_ABE_Failure
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Scenario_Rep_Id)
      is
      begin
         --  Nothing to do when the scenario does not require an ABE failure

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Targ_Id,
                   Unit_Id => Unit (Targ_Rep))
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Scenario_ABE_Failure_Common (N);
      end Install_Scenario_ABE_Failure;

      ----------------------------------
      -- Install_Scenario_ABE_Failure --
      ----------------------------------

      procedure Install_Scenario_ABE_Failure
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Targ_Rep : Target_Rep_Id;
         Disable  : Target_Rep_Id)
      is
      begin
         --  Nothing to do when the scenario does not require an ABE failure

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Targ_Id,
                   Unit_Id => Unit (Targ_Rep))
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Scenario_ABE_Failure_Common (N);
      end Install_Scenario_ABE_Failure;

      -----------------------------------------
      -- Install_Scenario_ABE_Failure_Common --
      -----------------------------------------

      procedure Install_Scenario_ABE_Failure_Common (N : Node_Id) is
         Loc : constant Source_Ptr := Sloc (N);

      begin
         --  Generate:
         --    raise Program_Error with "access before elaboration";

         Insert_ABE_Check_Or_Failure
           (N     => N,
            Check =>
              Make_Raise_Program_Error (Loc,
                Reason => PE_Access_Before_Elaboration));
      end Install_Scenario_ABE_Failure_Common;

      ----------------------------
      -- Install_Unit_ABE_Check --
      ----------------------------

      procedure Install_Unit_ABE_Check
        (N       : Node_Id;
         Unit_Id : Entity_Id;
         Disable : Scenario_Rep_Id)
      is
         Spec_Id : constant Entity_Id  := Unique_Entity (Unit_Id);

      begin
         --  Nothing to do when the scenario does not require an ABE check

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Empty,
                   Unit_Id => Spec_Id)
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Unit_ABE_Check_Common
           (N       => N,
            Unit_Id => Unit_Id);
      end Install_Unit_ABE_Check;

      ----------------------------
      -- Install_Unit_ABE_Check --
      ----------------------------

      procedure Install_Unit_ABE_Check
        (N       : Node_Id;
         Unit_Id : Entity_Id;
         Disable : Target_Rep_Id)
      is
         Spec_Id : constant Entity_Id  := Unique_Entity (Unit_Id);

      begin
         --  Nothing to do when the scenario does not require an ABE check

         if not ABE_Check_Or_Failure_OK
                  (N       => N,
                   Targ_Id => Empty,
                   Unit_Id => Spec_Id)
         then
            return;
         end if;

         --  Prevent multiple attempts to install the same ABE check

         Disable_Elaboration_Checks (Disable);

         Install_Unit_ABE_Check_Common
           (N       => N,
            Unit_Id => Unit_Id);
      end Install_Unit_ABE_Check;

      -----------------------------------
      -- Install_Unit_ABE_Check_Common --
      -----------------------------------

      procedure Install_Unit_ABE_Check_Common
        (N       : Node_Id;
         Unit_Id : Entity_Id)
      is
         Loc     : constant Source_Ptr := Sloc (N);
         Spec_Id : constant Entity_Id  := Unique_Entity (Unit_Id);

      begin
         --  Generate:
         --    if not Spec_Id'Elaborated then
         --       raise Program_Error with "access before elaboration";
         --    end if;

         Insert_ABE_Check_Or_Failure
           (N     => N,
            Check =>
              Make_Raise_Program_Error (Loc,
                Condition =>
                  Make_Op_Not (Loc,
                    Right_Opnd =>
                      Make_Attribute_Reference (Loc,
                        Prefix         => New_Occurrence_Of (Spec_Id, Loc),
                        Attribute_Name => Name_Elaborated)),
                Reason    => PE_Access_Before_Elaboration));
      end Install_Unit_ABE_Check_Common;
   end Check_Installer;

   ----------------------
   -- Compilation_Unit --
   ----------------------

   function Compilation_Unit (Unit_Id : Entity_Id) return Node_Id is
      Comp_Unit : Node_Id;

   begin
      Comp_Unit := Parent (Unit_Id);

      --  Handle the case where a concurrent subunit is rewritten as a null
      --  statement due to expansion activities.

      if Nkind (Comp_Unit) = N_Null_Statement
        and then Nkind (Original_Node (Comp_Unit)) in
                   N_Protected_Body | N_Task_Body
      then
         Comp_Unit := Parent (Comp_Unit);
         pragma Assert (Nkind (Comp_Unit) = N_Subunit);

      --  Otherwise use the declaration node of the unit

      else
         Comp_Unit := Parent (Unit_Declaration_Node (Unit_Id));
      end if;

      --  Handle the case where a subprogram instantiation which acts as a
      --  compilation unit is expanded into an anonymous package that wraps
      --  the instantiated subprogram.

      if Nkind (Comp_Unit) = N_Package_Specification
        and then Nkind (Original_Node (Parent (Comp_Unit))) in
                   N_Function_Instantiation | N_Procedure_Instantiation
      then
         Comp_Unit := Parent (Parent (Comp_Unit));

      --  Handle the case where the compilation unit is a subunit

      elsif Nkind (Comp_Unit) = N_Subunit then
         Comp_Unit := Parent (Comp_Unit);
      end if;

      pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit);

      return Comp_Unit;
   end Compilation_Unit;

   -------------------------------
   -- Conditional_ABE_Processor --
   -------------------------------

   package body Conditional_ABE_Processor is

      -----------------------
      -- Local subprograms --
      -----------------------

      function Is_Conditional_ABE_Scenario (N : Node_Id) return Boolean;
      pragma Inline (Is_Conditional_ABE_Scenario);
      --  Determine whether node N is a suitable scenario for conditional ABE
      --  checks and diagnostics.

      procedure Process_Conditional_ABE_Access_Taken
        (Attr     : Node_Id;
         Attr_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Access_Taken);
      --  Perform ABE checks and diagnostics for attribute reference Attr with
      --  representation Attr_Rep which takes 'Access of an entry, operator, or
      --  subprogram. In_State is the current state of the Processing phase.

      procedure Process_Conditional_ABE_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Activation);
      --  Perform common conditional ABE checks and diagnostics for activation
      --  call Call which activates object Obj_Id of task type Task_Typ. Formal
      --  Call_Rep denotes the representation of the call. Obj_Rep denotes the
      --  representation of the object. Task_Rep denotes the representation of
      --  the task type. In_State is the current state of the Processing phase.

      procedure Process_Conditional_ABE_Call
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Call);
      --  Top-level dispatcher for processing of calls. Perform ABE checks and
      --  diagnostics for call Call with representation Call_Rep. In_State is
      --  the current state of the Processing phase.

      procedure Process_Conditional_ABE_Call_Ada
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Subp_Id  : Entity_Id;
         Subp_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Call_Ada);
      --  Perform ABE checks and diagnostics for call Call which invokes entry,
      --  operator, or subprogram Subp_Id using the Ada rules. Call_Rep denotes
      --  the representation of the call. Subp_Rep denotes the representation
      --  of the subprogram. In_State is the current state of the Processing
      --  phase.

      procedure Process_Conditional_ABE_Call_SPARK
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Subp_Id  : Entity_Id;
         Subp_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Call_SPARK);
      --  Perform ABE checks and diagnostics for call Call which invokes entry,
      --  operator, or subprogram Subp_Id using the SPARK rules. Call_Rep is
      --  the representation of the call. Subp_Rep denotes the representation
      --  of the subprogram. In_State is the current state of the Processing
      --  phase.

      procedure Process_Conditional_ABE_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Instantiation);
      --  Top-level dispatcher for processing of instantiations. Perform ABE
      --  checks and diagnostics for instantiation Inst with representation
      --  Inst_Rep. In_State is the current state of the Processing phase.

      procedure Process_Conditional_ABE_Instantiation_Ada
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         Gen_Id   : Entity_Id;
         Gen_Rep  : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Instantiation_Ada);
      --  Perform ABE checks and diagnostics for instantiation Inst of generic
      --  Gen_Id using the Ada rules. Inst_Rep denotes the representation of
      --  the instnace. Gen_Rep is the representation of the generic. In_State
      --  is the current state of the Processing phase.

      procedure Process_Conditional_ABE_Instantiation_SPARK
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         Gen_Id   : Entity_Id;
         Gen_Rep  : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Instantiation_SPARK);
      --  Perform ABE checks and diagnostics for instantiation Inst of generic
      --  Gen_Id using the SPARK rules. Inst_Rep denotes the representation of
      --  the instnace. Gen_Rep is the representation of the generic. In_State
      --  is the current state of the Processing phase.

      procedure Process_Conditional_ABE_Variable_Assignment
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Variable_Assignment);
      --  Top-level dispatcher for processing of variable assignments. Perform
      --  ABE checks and diagnostics for assignment Asmt with representation
      --  Asmt_Rep. In_State denotes the current state of the Processing phase.

      procedure Process_Conditional_ABE_Variable_Assignment_Ada
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         Var_Id   : Entity_Id;
         Var_Rep  : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Variable_Assignment_Ada);
      --  Perform ABE checks and diagnostics for assignment statement Asmt that
      --  modifies the value of variable Var_Id using the Ada rules. Asmt_Rep
      --  denotes the representation of the assignment. Var_Rep denotes the
      --  representation of the variable. In_State is the current state of the
      --  Processing phase.

      procedure Process_Conditional_ABE_Variable_Assignment_SPARK
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         Var_Id   : Entity_Id;
         Var_Rep  : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Variable_Assignment_SPARK);
      --  Perform ABE checks and diagnostics for assignment statement Asmt that
      --  modifies the value of variable Var_Id using the SPARK rules. Asmt_Rep
      --  denotes the representation of the assignment. Var_Rep denotes the
      --  representation of the variable. In_State is the current state of the
      --  Processing phase.

      procedure Process_Conditional_ABE_Variable_Reference
        (Ref      : Node_Id;
         Ref_Rep  : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Conditional_ABE_Variable_Reference);
      --  Perform ABE checks and diagnostics for variable reference Ref with
      --  representation Ref_Rep. In_State denotes the current state of the
      --  Processing phase.

      procedure Traverse_Conditional_ABE_Body
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Traverse_Conditional_ABE_Body);
      --  Traverse subprogram body N looking for suitable scenarios that need
      --  to be processed for conditional ABE checks and diagnostics. In_State
      --  is the current state of the Processing phase.

      -------------------------------------
      -- Check_Conditional_ABE_Scenarios --
      -------------------------------------

      procedure Check_Conditional_ABE_Scenarios
        (Iter : in out NE_Set.Iterator)
      is
         N : Node_Id;

      begin
         while NE_Set.Has_Next (Iter) loop
            NE_Set.Next (Iter, N);

            --  Reset the traversed status of all subprogram bodies because the
            --  current conditional scenario acts as a new DFS traversal root.

            Reset_Traversed_Bodies;

            Process_Conditional_ABE
              (N        => N,
               In_State => Conditional_ABE_State);
         end loop;
      end Check_Conditional_ABE_Scenarios;

      ---------------------------------
      -- Is_Conditional_ABE_Scenario --
      ---------------------------------

      function Is_Conditional_ABE_Scenario (N : Node_Id) return Boolean is
      begin
         return
           Is_Suitable_Access_Taken (N)
             or else Is_Suitable_Call (N)
             or else Is_Suitable_Instantiation (N)
             or else Is_Suitable_Variable_Assignment (N)
             or else Is_Suitable_Variable_Reference (N);
      end Is_Conditional_ABE_Scenario;

      -----------------------------
      -- Process_Conditional_ABE --
      -----------------------------

      procedure Process_Conditional_ABE
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
         Scen     : constant Node_Id := Scenario (N);
         Scen_Rep : Scenario_Rep_Id;

      begin
         --  Add the current scenario to the stack of active scenarios

         Push_Active_Scenario (Scen);

         --  'Access

         if Is_Suitable_Access_Taken (Scen) then
            Process_Conditional_ABE_Access_Taken
              (Attr     => Scen,
               Attr_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);

         --  Call or task activation

         elsif Is_Suitable_Call (Scen) then
            Scen_Rep := Scenario_Representation_Of (Scen, In_State);

            --  Routine Build_Call_Marker creates call markers regardless of
            --  whether the call occurs within the main unit or not. This way
            --  the serialization of internal names is kept consistent. Only
            --  call markers found within the main unit must be processed.

            if In_Main_Context (Scen) then
               Scen_Rep := Scenario_Representation_Of (Scen, In_State);

               if Kind (Scen_Rep) = Call_Scenario then
                  Process_Conditional_ABE_Call
                    (Call     => Scen,
                     Call_Rep => Scen_Rep,
                     In_State => In_State);

               else
                  pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);

                  Process_Activation
                    (Call      => Scen,
                     Call_Rep  => Scen_Rep,
                     Processor => Process_Conditional_ABE_Activation'Access,
                     In_State  => In_State);
               end if;
            end if;

         --  Instantiation

         elsif Is_Suitable_Instantiation (Scen) then
            Process_Conditional_ABE_Instantiation
              (Inst     => Scen,
               Inst_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);

         --  Variable assignments

         elsif Is_Suitable_Variable_Assignment (Scen) then
            Process_Conditional_ABE_Variable_Assignment
              (Asmt     => Scen,
               Asmt_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);

         --  Variable references

         elsif Is_Suitable_Variable_Reference (Scen) then

            --  Routine Build_Variable_Reference_Marker makes variable markers
            --  regardless of whether the reference occurs within the main unit
            --  or not. This way the serialization of internal names is kept
            --  consistent. Only variable markers within the main unit must be
            --  processed.

            if In_Main_Context (Scen) then
               Process_Conditional_ABE_Variable_Reference
                 (Ref      => Scen,
                  Ref_Rep  => Scenario_Representation_Of (Scen, In_State),
                  In_State => In_State);
            end if;
         end if;

         --  Remove the current scenario from the stack of active scenarios
         --  once all ABE diagnostics and checks have been performed.

         Pop_Active_Scenario (Scen);
      end Process_Conditional_ABE;

      ------------------------------------------
      -- Process_Conditional_ABE_Access_Taken --
      ------------------------------------------

      procedure Process_Conditional_ABE_Access_Taken
        (Attr     : Node_Id;
         Attr_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         function Build_Access_Marker (Subp_Id : Entity_Id) return Node_Id;
         pragma Inline (Build_Access_Marker);
         --  Create a suitable call marker which invokes subprogram Subp_Id

         -------------------------
         -- Build_Access_Marker --
         -------------------------

         function Build_Access_Marker (Subp_Id : Entity_Id) return Node_Id is
            Marker : Node_Id;

         begin
            Marker := Make_Call_Marker (Sloc (Attr));

            --  Inherit relevant attributes from the attribute

            Set_Target (Marker, Subp_Id);
            Set_Is_Declaration_Level_Node
                       (Marker, Level (Attr_Rep) = Declaration_Level);
            Set_Is_Dispatching_Call
                       (Marker, False);
            Set_Is_Elaboration_Checks_OK_Node
                       (Marker, Elaboration_Checks_OK (Attr_Rep));
            Set_Is_Elaboration_Warnings_OK_Node
                       (Marker, Elaboration_Warnings_OK (Attr_Rep));
            Set_Is_Preelaborable_Call
                       (Marker, False);
            Set_Is_Source_Call
                       (Marker, Comes_From_Source (Attr));
            Set_Is_SPARK_Mode_On_Node
                       (Marker, SPARK_Mode_Of (Attr_Rep) = Is_On);

            --  Partially insert the call marker into the tree by setting its
            --  parent pointer.

            Set_Parent (Marker, Attr);

            return Marker;
         end Build_Access_Marker;

         --  Local variables

         Root      : constant Node_Id       := Root_Scenario;
         Subp_Id   : constant Entity_Id     := Target (Attr_Rep);
         Subp_Rep  : constant Target_Rep_Id :=
                                Target_Representation_Of (Subp_Id, In_State);
         Body_Decl : constant Node_Id       := Body_Declaration (Subp_Rep);

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      --  Start of processing for Process_Conditional_ABE_Access

      begin
         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not New_In_State.Suppress_Info_Messages
         then
            Error_Msg_NE
              ("info: access to & during elaboration", Attr, Subp_Id);
         end if;

         --  Warnings are suppressed when a prior scenario is already in that
         --  mode or when the attribute or the target have warnings suppressed.
         --  Update the state of the Processing phase to reflect this.

         New_In_State.Suppress_Warnings :=
           New_In_State.Suppress_Warnings
             or else not Elaboration_Warnings_OK (Attr_Rep)
             or else not Elaboration_Warnings_OK (Subp_Rep);

         --  Do not emit any ABE diagnostics when the current or previous
         --  scenario in this traversal has suppressed elaboration warnings.

         if New_In_State.Suppress_Warnings then
            null;

         --  Both the attribute and the corresponding subprogram body are in
         --  the same unit. The body must appear prior to the root scenario
         --  which started the recursive search. If this is not the case, then
         --  there is a potential ABE if the access value is used to call the
         --  subprogram. Emit a warning only when switch -gnatw.f (warnings on
         --  suspicious 'Access) is in effect.

         elsif Warn_On_Elab_Access
           and then Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)
           and then Earlier_In_Extended_Unit (Root, Body_Decl)
         then
            Error_Msg_Name_1 := Attribute_Name (Attr);
            Error_Msg_NE
              ("??% attribute of & before body seen", Attr, Subp_Id);
            Error_Msg_N ("\possible Program_Error on later references", Attr);

            Output_Active_Scenarios (Attr, New_In_State);
         end if;

         --  Treat the attribute an immediate invocation of the target when
         --  switch -gnatd.o (conservative elaboration order for indirect
         --  calls) is in effect. This has the following desirable effects:
         --
         --    * Ensure that the unit with the corresponding body is elaborated
         --      prior to the main unit.
         --
         --    * Perform conditional ABE checks and diagnostics
         --
         --    * Traverse the body of the target (if available)

         if Debug_Flag_Dot_O then
            Process_Conditional_ABE
              (N        => Build_Access_Marker (Subp_Id),
               In_State => New_In_State);

         --  Otherwise ensure that the unit with the corresponding body is
         --  elaborated prior to the main unit.

         else
            Ensure_Prior_Elaboration
              (N        => Attr,
               Unit_Id  => Unit (Subp_Rep),
               Prag_Nam => Name_Elaborate_All,
               In_State => New_In_State);
         end if;
      end Process_Conditional_ABE_Access_Taken;

      ----------------------------------------
      -- Process_Conditional_ABE_Activation --
      ----------------------------------------

      procedure Process_Conditional_ABE_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Task_Typ);

         Body_Decl : constant Node_Id := Body_Declaration (Task_Rep);
         Spec_Decl : constant Node_Id := Spec_Declaration (Task_Rep);
         Root      : constant Node_Id := Root_Scenario;
         Unit_Id   : constant Node_Id := Unit (Task_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Obj_Rep)  /= Is_Ignored
                        and then Ghost_Mode_Of (Task_Rep) /= Is_Ignored
                        and then Elaboration_Checks_OK (Obj_Rep)
                        and then Elaboration_Checks_OK (Task_Rep);
         --  A run-time ABE check may be installed only when the object and the
         --  task type have active elaboration checks, and both are not ignored
         --  Ghost constructs.

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      begin
         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not New_In_State.Suppress_Info_Messages
         then
            Error_Msg_NE
              ("info: activation of & during elaboration", Call, Obj_Id);
         end if;

         --  Nothing to do when the call activates a task whose type is defined
         --  within an instance and switch -gnatd_i (ignore activations and
         --  calls to instances for elaboration) is in effect.

         if Debug_Flag_Underscore_I
           and then In_External_Instance
                      (N           => Call,
                       Target_Decl => Spec_Decl)
         then
            return;

         --  Nothing to do when the activation is a guaranteed ABE

         elsif Is_Known_Guaranteed_ABE (Call) then
            return;

         --  Nothing to do when the root scenario appears at the declaration
         --  level and the task is in the same unit, but outside this context.
         --
         --    task type Task_Typ;                  --  task declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             declare
         --                T : Task_Typ;
         --             begin
         --                <activation call>        --  activation site
         --             end;
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    task body Task_Typ is
         --       ...
         --    end Task_Typ;
         --
         --  In the example above, the context of X is the declarative list of
         --  Proc. The "elaboration" of X may reach the activation of T whose
         --  body is defined outside of X's context. The task body is relevant
         --  only when Proc is invoked, but this happens only during "normal"
         --  elaboration, therefore the task body must not be considered if
         --  this is not the case.

         elsif Is_Up_Level_Target
                 (Targ_Decl => Spec_Decl,
                  In_State  => New_In_State)
         then
            return;

         --  Nothing to do when the activation is ABE-safe
         --
         --    generic
         --    package Gen is
         --       task type Task_Typ;
         --    end Gen;
         --
         --    package body Gen is
         --       task body Task_Typ is
         --       begin
         --          ...
         --       end Task_Typ;
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       package Nested is
         --          package Inst is new Gen;
         --          T : Inst.Task_Typ;
         --          <activation call>              --  safe activation
         --       end Nested;
         --    ...

         elsif Is_Safe_Activation (Call, Task_Rep) then

            --  Note that the task body must still be examined for any nested
            --  scenarios.

            null;

         --  The activation call and the task body are both in the main unit
         --
         --  If the root scenario appears prior to the task body, then this is
         --  a possible ABE with respect to the root scenario.
         --
         --    task type Task_Typ;
         --
         --    function A ... is
         --    begin
         --       if Some_Condition then
         --          declare
         --             package Pack is
         --                T : Task_Typ;
         --             end Pack;                --  activation of T
         --       ...
         --    end A;
         --
         --    X : ... := A;                     --  root scenario
         --
         --    task body Task_Typ is             --  task body
         --       ...
         --    end Task_Typ;
         --
         --    Y : ... := A;                     --  root scenario
         --
         --  IMPORTANT: The activation of T is a possible ABE for X, but
         --  not for Y. Intalling an unconditional ABE raise prior to the
         --  activation call would be wrong as it will fail for Y as well
         --  but in Y's case the activation of T is never an ABE.

         elsif Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)
         then
            if Earlier_In_Extended_Unit (Root, Body_Decl) then

               --  Do not emit any ABE diagnostics when a previous scenario in
               --  this traversal has suppressed elaboration warnings.

               if New_In_State.Suppress_Warnings then
                  null;

               --  Do not emit any ABE diagnostics when the activation occurs
               --  in a partial finalization context because this action leads
               --  to confusing noise.

               elsif New_In_State.Within_Partial_Finalization then
                  null;

               --  Otherwise emit the ABE disgnostic

               else
                  Error_Msg_Sloc := Sloc (Call);
                  Error_Msg_N
                    ("??task & will be activated # before elaboration of its "
                     & "body", Obj_Id);
                  Error_Msg_N
                    ("\Program_Error may be raised at run time", Obj_Id);

                  Output_Active_Scenarios (Obj_Id, New_In_State);
               end if;

               --  Install a conditional run-time ABE check to verify that the
               --  task body has been elaborated prior to the activation call.

               if Check_OK then
                  Install_Scenario_ABE_Check
                    (N        => Call,
                     Targ_Id  => Defining_Entity (Spec_Decl),
                     Targ_Rep => Task_Rep,
                     Disable  => Obj_Rep);

                  --  Update the state of the Processing phase to indicate that
                  --  no implicit Elaborate[_All] pragma must be generated from
                  --  this point on.
                  --
                  --    task type Task_Typ;
                  --
                  --    function A ... is
                  --    begin
                  --       if Some_Condition then
                  --          declare
                  --             package Pack is
                  --                <ABE check>
                  --                T : Task_Typ;
                  --             end Pack;          --  activation of T
                  --       ...
                  --    end A;
                  --
                  --    X : ... := A;
                  --
                  --    task body Task_Typ is
                  --    begin
                  --       External.Subp;           --  imparts Elaborate_All
                  --    end Task_Typ;
                  --
                  --  If Some_Condition is True, then the ABE check will fail
                  --  at runtime and the call to External.Subp will never take
                  --  place, rendering the implicit Elaborate_All useless.
                  --
                  --  If the value of Some_Condition is False, then the call
                  --  to External.Subp will never take place, rendering the
                  --  implicit Elaborate_All useless.

                  New_In_State.Suppress_Implicit_Pragmas := True;
               end if;
            end if;

         --  Otherwise the task body is not available in this compilation or
         --  it resides in an external unit. Install a run-time ABE check to
         --  verify that the task body has been elaborated prior to the
         --  activation call when the dynamic model is in effect.

         elsif Check_OK
           and then New_In_State.Processing = Dynamic_Model_Processing
         then
            Install_Unit_ABE_Check
              (N       => Call,
               Unit_Id => Unit_Id,
               Disable => Obj_Rep);
         end if;

         --  Both the activation call and task type are subject to SPARK_Mode
         --  On, this triggers the SPARK rules for task activation. Compared
         --  to calls and instantiations, task activation in SPARK does not
         --  require the presence of Elaborate[_All] pragmas in case the task
         --  type is defined outside the main unit. This is because SPARK uses
         --  a special policy which activates all tasks after the main unit has
         --  finished its elaboration.

         if SPARK_Mode_Of (Call_Rep) = Is_On
           and then SPARK_Mode_Of (Task_Rep) = Is_On
         then
            null;

         --  Otherwise the Ada rules are in effect. Ensure that the unit with
         --  the task body is elaborated prior to the main unit.

         else
            Ensure_Prior_Elaboration
              (N        => Call,
               Unit_Id  => Unit_Id,
               Prag_Nam => Name_Elaborate_All,
               In_State => New_In_State);
         end if;

         Traverse_Conditional_ABE_Body
           (N        => Body_Decl,
            In_State => New_In_State);
      end Process_Conditional_ABE_Activation;

      ----------------------------------
      -- Process_Conditional_ABE_Call --
      ----------------------------------

      procedure Process_Conditional_ABE_Call
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         function In_Initialization_Context (N : Node_Id) return Boolean;
         pragma Inline (In_Initialization_Context);
         --  Determine whether arbitrary node N appears within a type init
         --  proc, primitive [Deep_]Initialize, or a block created for
         --  initialization purposes.

         function Is_Partial_Finalization_Proc
           (Subp_Id : Entity_Id) return Boolean;
         pragma Inline (Is_Partial_Finalization_Proc);
         --  Determine whether subprogram Subp_Id is a partial finalization
         --  procedure.

         -------------------------------
         -- In_Initialization_Context --
         -------------------------------

         function In_Initialization_Context (N : Node_Id) return Boolean is
            Par     : Node_Id;
            Spec_Id : Entity_Id;

         begin
            --  Climb the parent chain looking for initialization actions

            Par := Parent (N);
            while Present (Par) loop

               --  A block may be part of the initialization actions of a
               --  default initialized object.

               if Nkind (Par) = N_Block_Statement
                 and then Is_Initialization_Block (Par)
               then
                  return True;

               --  A subprogram body may denote an initialization routine

               elsif Nkind (Par) = N_Subprogram_Body then
                  Spec_Id := Unique_Defining_Entity (Par);

                  --  The current subprogram body denotes a type init proc or
                  --  primitive [Deep_]Initialize.

                  if Is_Init_Proc (Spec_Id)
                    or else Is_Controlled_Proc (Spec_Id, Name_Initialize)
                    or else Is_TSS (Spec_Id, TSS_Deep_Initialize)
                  then
                     return True;
                  end if;

               --  Prevent the search from going too far

               elsif Is_Body_Or_Package_Declaration (Par) then
                  exit;
               end if;

               Par := Parent (Par);
            end loop;

            return False;
         end In_Initialization_Context;

         ----------------------------------
         -- Is_Partial_Finalization_Proc --
         ----------------------------------

         function Is_Partial_Finalization_Proc
           (Subp_Id : Entity_Id) return Boolean
         is
         begin
            --  To qualify, the subprogram must denote a finalizer procedure
            --  or primitive [Deep_]Finalize, and the call must appear within
            --  an initialization context.

            return
              (Is_Controlled_Proc (Subp_Id, Name_Finalize)
                 or else Is_Finalizer_Proc (Subp_Id)
                 or else Is_TSS (Subp_Id, TSS_Deep_Finalize))
               and then In_Initialization_Context (Call);
         end Is_Partial_Finalization_Proc;

         --  Local variables

         Subp_Id   : constant Entity_Id     := Target (Call_Rep);
         Subp_Rep  : constant Target_Rep_Id :=
                       Target_Representation_Of (Subp_Id, In_State);
         Subp_Decl : constant Node_Id       := Spec_Declaration (Subp_Rep);

         SPARK_Rules_On : constant Boolean :=
                            SPARK_Mode_Of (Call_Rep) = Is_On
                              and then SPARK_Mode_Of (Subp_Rep) = Is_On;

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      --  Start of processing for Process_Conditional_ABE_Call

      begin
         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not New_In_State.Suppress_Info_Messages
         then
            Info_Call
              (Call     => Call,
               Subp_Id  => Subp_Id,
               Info_Msg => True,
               In_SPARK => SPARK_Rules_On);
         end if;

         --  Check whether the invocation of an entry clashes with an existing
         --  restriction. This check is relevant only when the processing was
         --  started from some library-level scenario.

         if Is_Protected_Entry (Subp_Id) then
            Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call);

         elsif Is_Task_Entry (Subp_Id) then
            Check_Restriction (No_Entry_Calls_In_Elaboration_Code, Call);

            --  Task entry calls are never processed because the entry being
            --  invoked does not have a corresponding "body", it has a select.

            return;
         end if;

         --  Nothing to do when the call invokes a target defined within an
         --  instance and switch -gnatd_i (ignore activations and calls to
         --  instances for elaboration) is in effect.

         if Debug_Flag_Underscore_I
           and then In_External_Instance
                      (N           => Call,
                       Target_Decl => Subp_Decl)
         then
            return;

         --  Nothing to do when the call is a guaranteed ABE

         elsif Is_Known_Guaranteed_ABE (Call) then
            return;

         --  Nothing to do when the root scenario appears at the declaration
         --  level and the target is in the same unit but outside this context.
         --
         --    function B ...;                      --  target declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             return B;                   --  call site
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    function B ... is
         --       ...
         --    end B;
         --
         --  In the example above, the context of X is the declarative region
         --  of Proc. The "elaboration" of X may eventually reach B which is
         --  defined outside of X's context. B is relevant only when Proc is
         --  invoked, but this happens only by means of "normal" elaboration,
         --  therefore B must not be considered if this is not the case.

         elsif Is_Up_Level_Target
                 (Targ_Decl => Subp_Decl,
                  In_State  => New_In_State)
         then
            return;
         end if;

         --  Warnings are suppressed when a prior scenario is already in that
         --  mode, or the call or target have warnings suppressed. Update the
         --  state of the Processing phase to reflect this.

         New_In_State.Suppress_Warnings :=
           New_In_State.Suppress_Warnings
             or else not Elaboration_Warnings_OK (Call_Rep)
             or else not Elaboration_Warnings_OK (Subp_Rep);

         --  The call occurs in an initial condition context when a prior
         --  scenario is already in that mode, or when the target is an
         --  Initial_Condition procedure. Update the state of the Processing
         --  phase to reflect this.

         New_In_State.Within_Initial_Condition :=
           New_In_State.Within_Initial_Condition
             or else Is_Initial_Condition_Proc (Subp_Id);

         --  The call occurs in a partial finalization context when a prior
         --  scenario is already in that mode, or when the target denotes a
         --  [Deep_]Finalize primitive or a finalizer within an initialization
         --  context. Update the state of the Processing phase to reflect this.

         New_In_State.Within_Partial_Finalization :=
           New_In_State.Within_Partial_Finalization
             or else Is_Partial_Finalization_Proc (Subp_Id);

         --  The SPARK rules are in effect. Note that -gnatd.v (enforce SPARK
         --  elaboration rules in SPARK code) is intentionally not taken into
         --  account here because Process_Conditional_ABE_Call_SPARK has two
         --  separate modes of operation.

         if SPARK_Rules_On then
            Process_Conditional_ABE_Call_SPARK
              (Call     => Call,
               Call_Rep => Call_Rep,
               Subp_Id  => Subp_Id,
               Subp_Rep => Subp_Rep,
               In_State => New_In_State);

         --  Otherwise the Ada rules are in effect

         else
            Process_Conditional_ABE_Call_Ada
              (Call     => Call,
               Call_Rep => Call_Rep,
               Subp_Id  => Subp_Id,
               Subp_Rep => Subp_Rep,
               In_State => New_In_State);
         end if;

         --  Inspect the target body (and barried function) for other suitable
         --  elaboration scenarios.

         Traverse_Conditional_ABE_Body
           (N        => Barrier_Body_Declaration (Subp_Rep),
            In_State => New_In_State);

         Traverse_Conditional_ABE_Body
           (N        => Body_Declaration (Subp_Rep),
            In_State => New_In_State);
      end Process_Conditional_ABE_Call;

      --------------------------------------
      -- Process_Conditional_ABE_Call_Ada --
      --------------------------------------

      procedure Process_Conditional_ABE_Call_Ada
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Subp_Id  : Entity_Id;
         Subp_Rep : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
         Root      : constant Node_Id := Root_Scenario;
         Unit_Id   : constant Node_Id := Unit (Subp_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Call_Rep) /= Is_Ignored
                        and then Ghost_Mode_Of (Subp_Rep) /= Is_Ignored
                        and then Elaboration_Checks_OK (Call_Rep)
                        and then Elaboration_Checks_OK (Subp_Rep);
         --  A run-time ABE check may be installed only when both the call
         --  and the target have active elaboration checks, and both are not
         --  ignored Ghost constructs.

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      begin
         --  Nothing to do for an Ada dispatching call because there are no
         --  ABE diagnostics for either models. ABE checks for the dynamic
         --  model are handled by Install_Primitive_Elaboration_Check.

         if Is_Dispatching_Call (Call_Rep) then
            return;

         --  Nothing to do when the call is ABE-safe
         --
         --    generic
         --    function Gen ...;
         --
         --    function Gen ... is
         --    begin
         --       ...
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       function Inst is new Gen;
         --       X : ... := Inst;                  --  safe call
         --    ...

         elsif Is_Safe_Call (Call, Subp_Id, Subp_Rep) then
            return;

         --  The call and the target body are both in the main unit
         --
         --  If the root scenario appears prior to the target body, then this
         --  is a possible ABE with respect to the root scenario.
         --
         --    function B ...;
         --
         --    function A ... is
         --    begin
         --       if Some_Condition then
         --          return B;                      --  call site
         --       ...
         --    end A;
         --
         --    X : ... := A;                        --  root scenario
         --
         --    function B ... is                    --  target body
         --       ...
         --    end B;
         --
         --    Y : ... := A;                        --  root scenario
         --
         --  IMPORTANT: The call to B from A is a possible ABE for X, but
         --  not for Y. Installing an unconditional ABE raise prior to the
         --  call to B would be wrong as it will fail for Y as well, but in
         --  Y's case the call to B is never an ABE.

         elsif Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)
         then
            if Earlier_In_Extended_Unit (Root, Body_Decl) then

               --  Do not emit any ABE diagnostics when a previous scenario in
               --  this traversal has suppressed elaboration warnings.

               if New_In_State.Suppress_Warnings then
                  null;

               --  Do not emit any ABE diagnostics when the call occurs in a
               --  partial finalization context because this leads to confusing
               --  noise.

               elsif New_In_State.Within_Partial_Finalization then
                  null;

               --  Otherwise emit the ABE diagnostic

               else
                  Error_Msg_NE
                    ("??cannot call & before body seen", Call, Subp_Id);
                  Error_Msg_N
                    ("\Program_Error may be raised at run time", Call);

                  Output_Active_Scenarios (Call, New_In_State);
               end if;

               --  Install a conditional run-time ABE check to verify that the
               --  target body has been elaborated prior to the call.

               if Check_OK then
                  Install_Scenario_ABE_Check
                    (N        => Call,
                     Targ_Id  => Subp_Id,
                     Targ_Rep => Subp_Rep,
                     Disable  => Call_Rep);

                  --  Update the state of the Processing phase to indicate that
                  --  no implicit Elaborate[_All] pragma must be generated from
                  --  this point on.
                  --
                  --    function B ...;
                  --
                  --    function A ... is
                  --    begin
                  --       if Some_Condition then
                  --          <ABE check>
                  --          return B;
                  --       ...
                  --    end A;
                  --
                  --    X : ... := A;
                  --
                  --    function B ... is
                  --       External.Subp;           --  imparts Elaborate_All
                  --    end B;
                  --
                  --  If Some_Condition is True, then the ABE check will fail
                  --  at runtime and the call to External.Subp will never take
                  --  place, rendering the implicit Elaborate_All useless.
                  --
                  --  If the value of Some_Condition is False, then the call
                  --  to External.Subp will never take place, rendering the
                  --  implicit Elaborate_All useless.

                  New_In_State.Suppress_Implicit_Pragmas := True;
               end if;
            end if;

         --  Otherwise the target body is not available in this compilation or
         --  it resides in an external unit. Install a run-time ABE check to
         --  verify that the target body has been elaborated prior to the call
         --  site when the dynamic model is in effect.

         elsif Check_OK
           and then New_In_State.Processing = Dynamic_Model_Processing
         then
            Install_Unit_ABE_Check
              (N       => Call,
               Unit_Id => Unit_Id,
               Disable => Call_Rep);
         end if;

         --  Ensure that the unit with the target body is elaborated prior to
         --  the main unit. The implicit Elaborate[_All] is generated only when
         --  the call has elaboration checks enabled. This behavior parallels
         --  that of the old ABE mechanism.

         if Elaboration_Checks_OK (Call_Rep) then
            Ensure_Prior_Elaboration
              (N        => Call,
               Unit_Id  => Unit_Id,
               Prag_Nam => Name_Elaborate_All,
               In_State => New_In_State);
         end if;
      end Process_Conditional_ABE_Call_Ada;

      ----------------------------------------
      -- Process_Conditional_ABE_Call_SPARK --
      ----------------------------------------

      procedure Process_Conditional_ABE_Call_SPARK
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Subp_Id  : Entity_Id;
         Subp_Rep : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Call_Rep);

         Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
         Region    : Node_Id;

      begin
         --  Ensure that a suitable elaboration model is in effect for SPARK
         --  rule verification.

         Check_SPARK_Model_In_Effect;

         --  The call and the target body are both in the main unit

         if Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)
           and then Earlier_In_Extended_Unit (Call, Body_Decl)
         then
            --  Do not emit any ABE diagnostics when a previous scenario in
            --  this traversal has suppressed elaboration warnings.

            if In_State.Suppress_Warnings then
               null;

            --  Do not emit any ABE diagnostics when the call occurs in an
            --  initial condition context because this leads to incorrect
            --  diagnostics.

            elsif In_State.Within_Initial_Condition then
               null;

            --  Do not emit any ABE diagnostics when the call occurs in a
            --  partial finalization context because this leads to confusing
            --  noise.

            elsif In_State.Within_Partial_Finalization then
               null;

            --  Ensure that a call that textually precedes the subprogram body
            --  it invokes appears within the early call region of the body.
            --
            --  IMPORTANT: This check must always be performed even when switch
            --  -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
            --  specified because the static model cannot guarantee the absence
            --  of elaboration issues when dispatching calls are involved.

            else
               Region := Find_Early_Call_Region (Body_Decl);

               if Earlier_In_Extended_Unit (Call, Region) then
                  Error_Msg_NE
                    ("call must appear within early call region of subprogram "
                     & "body & (SPARK RM 7.7(3))",
                     Call, Subp_Id);

                  Error_Msg_Sloc := Sloc (Region);
                  Error_Msg_N ("\region starts #", Call);

                  Error_Msg_Sloc := Sloc (Body_Decl);
                  Error_Msg_N ("\region ends #", Call);

                  Output_Active_Scenarios (Call, In_State);
               end if;
            end if;
         end if;

         --  A call to a source target or to a target which emulates Ada
         --  or SPARK semantics imposes an Elaborate_All requirement on the
         --  context of the main unit. Determine whether the context has a
         --  pragma strong enough to meet the requirement.
         --
         --  IMPORTANT: This check must be performed only when switch -gnatd.v
         --  (enforce SPARK elaboration rules in SPARK code) is active because
         --  the static model can ensure the prior elaboration of the unit
         --  which contains a body by installing an implicit Elaborate[_All]
         --  pragma.

         if Debug_Flag_Dot_V then
            if Comes_From_Source (Subp_Id)
              or else Is_Ada_Semantic_Target (Subp_Id)
              or else Is_SPARK_Semantic_Target (Subp_Id)
            then
               Meet_Elaboration_Requirement
                 (N        => Call,
                  Targ_Id  => Subp_Id,
                  Req_Nam  => Name_Elaborate_All,
                  In_State => In_State);
            end if;

         --  Otherwise ensure that the unit with the target body is elaborated
         --  prior to the main unit.

         else
            Ensure_Prior_Elaboration
              (N        => Call,
               Unit_Id  => Unit (Subp_Rep),
               Prag_Nam => Name_Elaborate_All,
               In_State => In_State);
         end if;
      end Process_Conditional_ABE_Call_SPARK;

      -------------------------------------------
      -- Process_Conditional_ABE_Instantiation --
      -------------------------------------------

      procedure Process_Conditional_ABE_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         Gen_Id  : constant Entity_Id     := Target (Inst_Rep);
         Gen_Rep : constant Target_Rep_Id :=
                     Target_Representation_Of (Gen_Id, In_State);

         SPARK_Rules_On : constant Boolean :=
                            SPARK_Mode_Of (Inst_Rep) = Is_On
                              and then SPARK_Mode_Of (Gen_Rep) = Is_On;

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      begin
         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not New_In_State.Suppress_Info_Messages
         then
            Info_Instantiation
              (Inst     => Inst,
               Gen_Id   => Gen_Id,
               Info_Msg => True,
               In_SPARK => SPARK_Rules_On);
         end if;

         --  Nothing to do when the instantiation is a guaranteed ABE

         if Is_Known_Guaranteed_ABE (Inst) then
            return;

         --  Nothing to do when the root scenario appears at the declaration
         --  level and the generic is in the same unit, but outside this
         --  context.
         --
         --    generic
         --    procedure Gen is ...;                --  generic declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             declare
         --                procedure I is new Gen;  --  instantiation site
         --             ...
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    procedure Gen is
         --       ...
         --    end Gen;
         --
         --  In the example above, the context of X is the declarative region
         --  of Proc. The "elaboration" of X may eventually reach Gen which
         --  appears outside of X's context. Gen is relevant only when Proc is
         --  invoked, but this happens only by means of "normal" elaboration,
         --  therefore Gen must not be considered if this is not the case.

         elsif Is_Up_Level_Target
                 (Targ_Decl => Spec_Declaration (Gen_Rep),
                  In_State  => New_In_State)
         then
            return;
         end if;

         --  Warnings are suppressed when a prior scenario is already in that
         --  mode, or when the instantiation has warnings suppressed. Update
         --  the state of the processing phase to reflect this.

         New_In_State.Suppress_Warnings :=
           New_In_State.Suppress_Warnings
             or else not Elaboration_Warnings_OK (Inst_Rep);

         --  The SPARK rules are in effect

         if SPARK_Rules_On then
            Process_Conditional_ABE_Instantiation_SPARK
              (Inst     => Inst,
               Inst_Rep => Inst_Rep,
               Gen_Id   => Gen_Id,
               Gen_Rep  => Gen_Rep,
               In_State => New_In_State);

         --  Otherwise the Ada rules are in effect, or SPARK code is allowed to
         --  violate the SPARK rules.

         else
            Process_Conditional_ABE_Instantiation_Ada
              (Inst     => Inst,
               Inst_Rep => Inst_Rep,
               Gen_Id   => Gen_Id,
               Gen_Rep  => Gen_Rep,
               In_State => New_In_State);
         end if;
      end Process_Conditional_ABE_Instantiation;

      -----------------------------------------------
      -- Process_Conditional_ABE_Instantiation_Ada --
      -----------------------------------------------

      procedure Process_Conditional_ABE_Instantiation_Ada
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         Gen_Id   : Entity_Id;
         Gen_Rep  : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         Body_Decl : constant Node_Id   := Body_Declaration (Gen_Rep);
         Root      : constant Node_Id   := Root_Scenario;
         Unit_Id   : constant Entity_Id := Unit (Gen_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Inst_Rep) /= Is_Ignored
                        and then Ghost_Mode_Of (Gen_Rep)  /= Is_Ignored
                        and then Elaboration_Checks_OK (Inst_Rep)
                        and then Elaboration_Checks_OK (Gen_Rep);
         --  A run-time ABE check may be installed only when both the instance
         --  and the generic have active elaboration checks and both are not
         --  ignored Ghost constructs.

         New_In_State : Processing_In_State := In_State;
         --  Each step of the Processing phase constitutes a new state

      begin
         --  Nothing to do when the instantiation is ABE-safe
         --
         --    generic
         --    package Gen is
         --       ...
         --    end Gen;
         --
         --    package body Gen is
         --       ...
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       package Inst is new Gen (ABE);    --  safe instantiation
         --    ...

         if Is_Safe_Instantiation (Inst, Gen_Id, Gen_Rep) then
            return;

         --  The instantiation and the generic body are both in the main unit
         --
         --  If the root scenario appears prior to the generic body, then this
         --  is a possible ABE with respect to the root scenario.
         --
         --    generic
         --    package Gen is
         --       ...
         --    end Gen;
         --
         --    function A ... is
         --    begin
         --       if Some_Condition then
         --          declare
         --             package Inst is new Gen;    --  instantiation site
         --       ...
         --    end A;
         --
         --    X : ... := A;                        --  root scenario
         --
         --    package body Gen is                  --  generic body
         --       ...
         --    end Gen;
         --
         --    Y : ... := A;                        --  root scenario
         --
         --  IMPORTANT: The instantiation of Gen is a possible ABE for X,
         --  but not for Y. Installing an unconditional ABE raise prior to
         --  the instance site would be wrong as it will fail for Y as well,
         --  but in Y's case the instantiation of Gen is never an ABE.

         elsif Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)
         then
            if Earlier_In_Extended_Unit (Root, Body_Decl) then

               --  Do not emit any ABE diagnostics when a previous scenario in
               --  this traversal has suppressed elaboration warnings.

               if New_In_State.Suppress_Warnings then
                  null;

               --  Do not emit any ABE diagnostics when the instantiation
               --  occurs in partial finalization context because this leads
               --  to unwanted noise.

               elsif New_In_State.Within_Partial_Finalization then
                  null;

               --  Otherwise output the diagnostic

               else
                  Error_Msg_NE
                    ("??cannot instantiate & before body seen", Inst, Gen_Id);
                  Error_Msg_N
                    ("\Program_Error may be raised at run time", Inst);

                  Output_Active_Scenarios (Inst, New_In_State);
               end if;

               --  Install a conditional run-time ABE check to verify that the
               --  generic body has been elaborated prior to the instantiation.

               if Check_OK then
                  Install_Scenario_ABE_Check
                    (N        => Inst,
                     Targ_Id  => Gen_Id,
                     Targ_Rep => Gen_Rep,
                     Disable  => Inst_Rep);

                  --  Update the state of the Processing phase to indicate that
                  --  no implicit Elaborate[_All] pragma must be generated from
                  --  this point on.
                  --
                  --    generic
                  --    package Gen is
                  --       ...
                  --    end Gen;
                  --
                  --    function A ... is
                  --    begin
                  --       if Some_Condition then
                  --          <ABE check>
                  --          declare Inst is new Gen;
                  --       ...
                  --    end A;
                  --
                  --    X : ... := A;
                  --
                  --    package body Gen is
                  --    begin
                  --       External.Subp;           --  imparts Elaborate_All
                  --    end Gen;
                  --
                  --  If Some_Condition is True, then the ABE check will fail
                  --  at runtime and the call to External.Subp will never take
                  --  place, rendering the implicit Elaborate_All useless.
                  --
                  --  If the value of Some_Condition is False, then the call
                  --  to External.Subp will never take place, rendering the
                  --  implicit Elaborate_All useless.

                  New_In_State.Suppress_Implicit_Pragmas := True;
               end if;
            end if;

         --  Otherwise the generic body is not available in this compilation
         --  or it resides in an external unit. Install a run-time ABE check
         --  to verify that the generic body has been elaborated prior to the
         --  instantiation when the dynamic model is in effect.

         elsif Check_OK
           and then New_In_State.Processing = Dynamic_Model_Processing
         then
            Install_Unit_ABE_Check
              (N       => Inst,
               Unit_Id => Unit_Id,
               Disable => Inst_Rep);
         end if;

         --  Ensure that the unit with the generic body is elaborated prior
         --  to the main unit. No implicit pragma has to be generated if the
         --  instantiation has elaboration checks suppressed. This behavior
         --  parallels that of the old ABE mechanism.

         if Elaboration_Checks_OK (Inst_Rep) then
            Ensure_Prior_Elaboration
              (N        => Inst,
               Unit_Id  => Unit_Id,
               Prag_Nam => Name_Elaborate,
               In_State => New_In_State);
         end if;
      end Process_Conditional_ABE_Instantiation_Ada;

      -------------------------------------------------
      -- Process_Conditional_ABE_Instantiation_SPARK --
      -------------------------------------------------

      procedure Process_Conditional_ABE_Instantiation_SPARK
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         Gen_Id   : Entity_Id;
         Gen_Rep  : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Inst_Rep);

         Req_Nam : Name_Id;

      begin
         --  Ensure that a suitable elaboration model is in effect for SPARK
         --  rule verification.

         Check_SPARK_Model_In_Effect;

         --  A source instantiation imposes an Elaborate[_All] requirement
         --  on the context of the main unit. Determine whether the context
         --  has a pragma strong enough to meet the requirement. The check
         --  is orthogonal to the ABE ramifications of the instantiation.
         --
         --  IMPORTANT: This check must be performed only when switch -gnatd.v
         --  (enforce SPARK elaboration rules in SPARK code) is active because
         --  the static model can ensure the prior elaboration of the unit
         --  which contains a body by installing an implicit Elaborate[_All]
         --  pragma.

         if Debug_Flag_Dot_V then
            if Nkind (Inst) = N_Package_Instantiation then
               Req_Nam := Name_Elaborate_All;
            else
               Req_Nam := Name_Elaborate;
            end if;

            Meet_Elaboration_Requirement
              (N        => Inst,
               Targ_Id  => Gen_Id,
               Req_Nam  => Req_Nam,
               In_State => In_State);

         --  Otherwise ensure that the unit with the target body is elaborated
         --  prior to the main unit.

         else
            Ensure_Prior_Elaboration
              (N        => Inst,
               Unit_Id  => Unit (Gen_Rep),
               Prag_Nam => Name_Elaborate,
               In_State => In_State);
         end if;
      end Process_Conditional_ABE_Instantiation_SPARK;

      -------------------------------------------------
      -- Process_Conditional_ABE_Variable_Assignment --
      -------------------------------------------------

      procedure Process_Conditional_ABE_Variable_Assignment
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is

         Var_Id  : constant Entity_Id     := Target (Asmt_Rep);
         Var_Rep : constant Target_Rep_Id :=
                     Target_Representation_Of (Var_Id, In_State);

         SPARK_Rules_On : constant Boolean :=
                            SPARK_Mode_Of (Asmt_Rep) = Is_On
                              and then SPARK_Mode_Of (Var_Rep) = Is_On;

      begin
         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not In_State.Suppress_Info_Messages
         then
            Elab_Msg_NE
              (Msg      => "assignment to & during elaboration",
               N        => Asmt,
               Id       => Var_Id,
               Info_Msg => True,
               In_SPARK => SPARK_Rules_On);
         end if;

         --  The SPARK rules are in effect. These rules are applied regardless
         --  of whether switch -gnatd.v (enforce SPARK elaboration rules in
         --  SPARK code) is in effect because the static model cannot ensure
         --  safe assignment of variables.

         if SPARK_Rules_On then
            Process_Conditional_ABE_Variable_Assignment_SPARK
              (Asmt     => Asmt,
               Asmt_Rep => Asmt_Rep,
               Var_Id   => Var_Id,
               Var_Rep  => Var_Rep,
               In_State => In_State);

         --  Otherwise the Ada rules are in effect

         else
            Process_Conditional_ABE_Variable_Assignment_Ada
              (Asmt     => Asmt,
               Asmt_Rep => Asmt_Rep,
               Var_Id   => Var_Id,
               Var_Rep  => Var_Rep,
               In_State => In_State);
         end if;
      end Process_Conditional_ABE_Variable_Assignment;

      -----------------------------------------------------
      -- Process_Conditional_ABE_Variable_Assignment_Ada --
      -----------------------------------------------------

      procedure Process_Conditional_ABE_Variable_Assignment_Ada
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         Var_Id   : Entity_Id;
         Var_Rep  : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Asmt_Rep);

         Var_Decl : constant Node_Id   := Variable_Declaration (Var_Rep);
         Unit_Id  : constant Entity_Id := Unit (Var_Rep);

      begin
         --  Emit a warning when an uninitialized variable declared in a
         --  package spec without a pragma Elaborate_Body is initialized
         --  by elaboration code within the corresponding body.

         if Is_Elaboration_Warnings_OK_Id (Var_Id)
           and then not Is_Initialized (Var_Decl)
           and then not Has_Pragma_Elaborate_Body (Unit_Id)
         then
            --  Do not emit any ABE diagnostics when a previous scenario in
            --  this traversal has suppressed elaboration warnings.

            if not In_State.Suppress_Warnings then
               Error_Msg_NE
                 ("??variable & can be accessed by clients before this "
                  & "initialization", Asmt, Var_Id);

               Error_Msg_NE
                 ("\add pragma ""Elaborate_Body"" to spec & to ensure proper "
                  & "initialization", Asmt, Unit_Id);

               Output_Active_Scenarios (Asmt, In_State);
            end if;

            --  Generate an implicit Elaborate_Body in the spec

            Set_Elaborate_Body_Desirable (Unit_Id);
         end if;
      end Process_Conditional_ABE_Variable_Assignment_Ada;

      -------------------------------------------------------
      -- Process_Conditional_ABE_Variable_Assignment_SPARK --
      -------------------------------------------------------

      procedure Process_Conditional_ABE_Variable_Assignment_SPARK
        (Asmt     : Node_Id;
         Asmt_Rep : Scenario_Rep_Id;
         Var_Id   : Entity_Id;
         Var_Rep  : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Asmt_Rep);

         Var_Decl : constant Node_Id   := Variable_Declaration (Var_Rep);
         Unit_Id  : constant Entity_Id := Unit (Var_Rep);

      begin
         --  Ensure that a suitable elaboration model is in effect for SPARK
         --  rule verification.

         Check_SPARK_Model_In_Effect;

         --  Do not emit any ABE diagnostics when a previous scenario in this
         --  traversal has suppressed elaboration warnings.

         if In_State.Suppress_Warnings then
            null;

         --  Emit an error when an initialized variable declared in a package
         --  spec that is missing pragma Elaborate_Body is further modified by
         --  elaboration code within the corresponding body.

         elsif Is_Elaboration_Warnings_OK_Id (Var_Id)
           and then Is_Initialized (Var_Decl)
           and then not Has_Pragma_Elaborate_Body (Unit_Id)
         then
            Error_Msg_NE
              ("variable & modified by elaboration code in package body",
               Asmt, Var_Id);

            Error_Msg_NE
              ("\add pragma ""Elaborate_Body"" to spec & to ensure full "
               & "initialization", Asmt, Unit_Id);

            Output_Active_Scenarios (Asmt, In_State);
         end if;
      end Process_Conditional_ABE_Variable_Assignment_SPARK;

      ------------------------------------------------
      -- Process_Conditional_ABE_Variable_Reference --
      ------------------------------------------------

      procedure Process_Conditional_ABE_Variable_Reference
        (Ref      : Node_Id;
         Ref_Rep  : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         Var_Id  : constant Entity_Id := Target (Ref);
         Var_Rep : Target_Rep_Id;
         Unit_Id : Entity_Id;

      begin
         --  Nothing to do when the variable reference is not a read

         if not Is_Read_Reference (Ref_Rep) then
            return;
         end if;

         Var_Rep := Target_Representation_Of (Var_Id, In_State);
         Unit_Id := Unit (Var_Rep);

         --  Output relevant information when switch -gnatel (info messages on
         --  implicit Elaborate[_All] pragmas) is in effect.

         if Elab_Info_Messages
           and then not In_State.Suppress_Info_Messages
         then
            Elab_Msg_NE
              (Msg      => "read of variable & during elaboration",
               N        => Ref,
               Id       => Var_Id,
               Info_Msg => True,
               In_SPARK => True);
         end if;

         --  Nothing to do when the variable appears within the main unit
         --  because diagnostics on reads are relevant only for external
         --  variables.

         if Is_Same_Unit (Unit_Id, Main_Unit_Entity) then
            null;

         --  Nothing to do when the variable is already initialized. Note that
         --  the variable may be further modified by the external unit.

         elsif Is_Initialized (Variable_Declaration (Var_Rep)) then
            null;

         --  Nothing to do when the external unit guarantees the initialization
         --  of the variable by means of pragma Elaborate_Body.

         elsif Has_Pragma_Elaborate_Body (Unit_Id) then
            null;

         --  A variable read imposes an Elaborate requirement on the context of
         --  the main unit. Determine whether the context has a pragma strong
         --  enough to meet the requirement.

         else
            Meet_Elaboration_Requirement
              (N        => Ref,
               Targ_Id  => Var_Id,
               Req_Nam  => Name_Elaborate,
               In_State => In_State);
         end if;
      end Process_Conditional_ABE_Variable_Reference;

      -----------------------------------
      -- Traverse_Conditional_ABE_Body --
      -----------------------------------

      procedure Traverse_Conditional_ABE_Body
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
      begin
         Traverse_Body
           (N                   => N,
            Requires_Processing => Is_Conditional_ABE_Scenario'Access,
            Processor           => Process_Conditional_ABE'Access,
            In_State            => In_State);
      end Traverse_Conditional_ABE_Body;
   end Conditional_ABE_Processor;

   -------------
   -- Destroy --
   -------------

   procedure Destroy (NE : in out Node_Or_Entity_Id) is
      pragma Unreferenced (NE);
   begin
      null;
   end Destroy;

   -----------------
   -- Diagnostics --
   -----------------

   package body Diagnostics is

      -----------------
      -- Elab_Msg_NE --
      -----------------

      procedure Elab_Msg_NE
        (Msg      : String;
         N        : Node_Id;
         Id       : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean)
      is
         function Prefix return String;
         pragma Inline (Prefix);
         --  Obtain the prefix of the message

         function Suffix return String;
         pragma Inline (Suffix);
         --  Obtain the suffix of the message

         ------------
         -- Prefix --
         ------------

         function Prefix return String is
         begin
            if Info_Msg then
               return "info: ";
            else
               return "";
            end if;
         end Prefix;

         ------------
         -- Suffix --
         ------------

         function Suffix return String is
         begin
            if In_SPARK then
               return " in SPARK";
            else
               return "";
            end if;
         end Suffix;

      --  Start of processing for Elab_Msg_NE

      begin
         Error_Msg_NE (Prefix & Msg & Suffix, N, Id);
      end Elab_Msg_NE;

      ---------------
      -- Info_Call --
      ---------------

      procedure Info_Call
        (Call     : Node_Id;
         Subp_Id  : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean)
      is
         procedure Info_Accept_Alternative;
         pragma Inline (Info_Accept_Alternative);
         --  Output information concerning an accept alternative

         procedure Info_Simple_Call;
         pragma Inline (Info_Simple_Call);
         --  Output information concerning the call

         procedure Info_Type_Actions (Action : String);
         pragma Inline (Info_Type_Actions);
         --  Output information concerning action Action of a type

         procedure Info_Verification_Call
           (Pred    : String;
            Id      : Entity_Id;
            Id_Kind : String);
         pragma Inline (Info_Verification_Call);
         --  Output information concerning the verification of predicate Pred
         --  applied to related entity Id with kind Id_Kind.

         -----------------------------
         -- Info_Accept_Alternative --
         -----------------------------

         procedure Info_Accept_Alternative is
            Entry_Id : constant Entity_Id := Receiving_Entry (Subp_Id);
            pragma Assert (Present (Entry_Id));

         begin
            Elab_Msg_NE
              (Msg      => "accept for entry & during elaboration",
               N        => Call,
               Id       => Entry_Id,
               Info_Msg => Info_Msg,
               In_SPARK => In_SPARK);
         end Info_Accept_Alternative;

         ----------------------
         -- Info_Simple_Call --
         ----------------------

         procedure Info_Simple_Call is
         begin
            Elab_Msg_NE
              (Msg      => "call to & during elaboration",
               N        => Call,
               Id       => Subp_Id,
               Info_Msg => Info_Msg,
               In_SPARK => In_SPARK);
         end Info_Simple_Call;

         -----------------------
         -- Info_Type_Actions --
         -----------------------

         procedure Info_Type_Actions (Action : String) is
            Typ : constant Entity_Id := First_Formal_Type (Subp_Id);
            pragma Assert (Present (Typ));

         begin
            Elab_Msg_NE
              (Msg      => Action & " actions for type & during elaboration",
               N        => Call,
               Id       => Typ,
               Info_Msg => Info_Msg,
               In_SPARK => In_SPARK);
         end Info_Type_Actions;

         ----------------------------
         -- Info_Verification_Call --
         ----------------------------

         procedure Info_Verification_Call
           (Pred    : String;
            Id      : Entity_Id;
            Id_Kind : String)
         is
            pragma Assert (Present (Id));

         begin
            Elab_Msg_NE
              (Msg      =>
                 "verification of " & Pred & " of " & Id_Kind & " & during "
                 & "elaboration",
               N        => Call,
               Id       => Id,
               Info_Msg => Info_Msg,
               In_SPARK => In_SPARK);
         end Info_Verification_Call;

      --  Start of processing for Info_Call

      begin
         --  Do not output anything for targets defined in internal units
         --  because this creates noise.

         if not In_Internal_Unit (Subp_Id) then

            --  Accept alternative

            if Is_Accept_Alternative_Proc (Subp_Id) then
               Info_Accept_Alternative;

            --  Adjustment

            elsif Is_TSS (Subp_Id, TSS_Deep_Adjust) then
               Info_Type_Actions ("adjustment");

            --  Default_Initial_Condition

            elsif Is_Default_Initial_Condition_Proc (Subp_Id) then
               Info_Verification_Call
                 (Pred    => "Default_Initial_Condition",
                  Id      => First_Formal_Type (Subp_Id),
                  Id_Kind => "type");

            --  Entries

            elsif Is_Protected_Entry (Subp_Id) then
               Info_Simple_Call;

            --  Task entry calls are never processed because the entry being
            --  invoked does not have a corresponding "body", it has a select.

            elsif Is_Task_Entry (Subp_Id) then
               null;

            --  Finalization

            elsif Is_TSS (Subp_Id, TSS_Deep_Finalize) then
               Info_Type_Actions ("finalization");

            --  Calls to _Finalizer procedures must not appear in the output
            --  because this creates confusing noise.

            elsif Is_Finalizer_Proc (Subp_Id) then
               null;

            --  Initial_Condition

            elsif Is_Initial_Condition_Proc (Subp_Id) then
               Info_Verification_Call
                 (Pred    => "Initial_Condition",
                  Id      => Find_Enclosing_Scope (Call),
                  Id_Kind => "package");

            --  Initialization

            elsif Is_Init_Proc (Subp_Id)
              or else Is_TSS (Subp_Id, TSS_Deep_Initialize)
            then
               Info_Type_Actions ("initialization");

            --  Invariant

            elsif Is_Invariant_Proc (Subp_Id) then
               Info_Verification_Call
                 (Pred    => "invariants",
                  Id      => First_Formal_Type (Subp_Id),
                  Id_Kind => "type");

            --  Partial invariant calls must not appear in the output because
            --  this creates confusing noise.

            elsif Is_Partial_Invariant_Proc (Subp_Id) then
               null;

            --  _Postconditions

            elsif Is_Postconditions_Proc (Subp_Id) then
               Info_Verification_Call
                 (Pred    => "postconditions",
                  Id      => Find_Enclosing_Scope (Call),
                  Id_Kind => "subprogram");

            --  Subprograms must come last because some of the previous cases
            --  fall under this category.

            elsif Ekind (Subp_Id) = E_Function then
               Info_Simple_Call;

            elsif Ekind (Subp_Id) = E_Procedure then
               Info_Simple_Call;

            else
               pragma Assert (False);
               return;
            end if;
         end if;
      end Info_Call;

      ------------------------
      -- Info_Instantiation --
      ------------------------

      procedure Info_Instantiation
        (Inst     : Node_Id;
         Gen_Id   : Entity_Id;
         Info_Msg : Boolean;
         In_SPARK : Boolean)
      is
      begin
         Elab_Msg_NE
           (Msg      => "instantiation of & during elaboration",
            N        => Inst,
            Id       => Gen_Id,
            Info_Msg => Info_Msg,
            In_SPARK => In_SPARK);
      end Info_Instantiation;

      -----------------------------
      -- Info_Variable_Reference --
      -----------------------------

      procedure Info_Variable_Reference
        (Ref    : Node_Id;
         Var_Id : Entity_Id)
      is
      begin
         if Is_Read (Ref) then
            Elab_Msg_NE
              (Msg      => "read of variable & during elaboration",
               N        => Ref,
               Id       => Var_Id,
               Info_Msg => False,
               In_SPARK => True);
         end if;
      end Info_Variable_Reference;
   end Diagnostics;

   ---------------------------------
   -- Early_Call_Region_Processor --
   ---------------------------------

   package body Early_Call_Region_Processor is

      ---------------------
      -- Data structures --
      ---------------------

      --  The following map relates early call regions to subprogram bodies

      procedure Destroy (N : in out Node_Id);
      --  Destroy node N

      package ECR_Map is new Dynamic_Hash_Tables
        (Key_Type              => Entity_Id,
         Value_Type            => Node_Id,
         No_Value              => Empty,
         Expansion_Threshold   => 1.5,
         Expansion_Factor      => 2,
         Compression_Threshold => 0.3,
         Compression_Factor    => 2,
         "="                   => "=",
         Destroy_Value         => Destroy,
         Hash                  => Hash);

      Early_Call_Regions_Map : ECR_Map.Dynamic_Hash_Table := ECR_Map.Nil;

      -----------------------
      -- Local subprograms --
      -----------------------

      function Early_Call_Region (Body_Id : Entity_Id) return Node_Id;
      pragma Inline (Early_Call_Region);
      --  Obtain the early call region associated with entry or subprogram body
      --  Body_Id.

      procedure Set_Early_Call_Region (Body_Id : Entity_Id; Start : Node_Id);
      pragma Inline (Set_Early_Call_Region);
      --  Associate an early call region with begins at construct Start with
      --  entry or subprogram body Body_Id.

      -------------
      -- Destroy --
      -------------

      procedure Destroy (N : in out Node_Id) is
         pragma Unreferenced (N);
      begin
         null;
      end Destroy;

      -----------------------
      -- Early_Call_Region --
      -----------------------

      function Early_Call_Region (Body_Id : Entity_Id) return Node_Id is
         pragma Assert (Present (Body_Id));
      begin
         return ECR_Map.Get (Early_Call_Regions_Map, Body_Id);
      end Early_Call_Region;

      ------------------------------------------
      -- Finalize_Early_Call_Region_Processor --
      ------------------------------------------

      procedure Finalize_Early_Call_Region_Processor is
      begin
         ECR_Map.Destroy (Early_Call_Regions_Map);
      end Finalize_Early_Call_Region_Processor;

      ----------------------------
      -- Find_Early_Call_Region --
      ----------------------------

      function Find_Early_Call_Region
        (Body_Decl        : Node_Id;
         Assume_Elab_Body : Boolean := False;
         Skip_Memoization : Boolean := False) return Node_Id
      is
         --  NOTE: The routines within Find_Early_Call_Region are intentionally
         --  unnested to avoid deep indentation of code.

         ECR_Found : exception;
         --  This exception is raised when the early call region has been found

         Start : Node_Id := Empty;
         --  The start of the early call region. This variable is updated by
         --  the various nested routines. Due to the use of exceptions, the
         --  variable must be global to the nested routines.

         --  The algorithm implemented in this routine attempts to find the
         --  early call region of a subprogram body by inspecting constructs
         --  in reverse declarative order, while navigating the tree. The
         --  algorithm consists of an Inspection phase and Advancement phase.
         --  The pseudocode is as follows:
         --
         --    loop
         --       inspection phase
         --       advancement phase
         --    end loop
         --
         --  The infinite loop is terminated by raising exception ECR_Found.
         --  The algorithm utilizes two pointers, Curr and Start, to represent
         --  the current construct to inspect and the start of the early call
         --  region.
         --
         --  IMPORTANT: The algorithm must maintain the following invariant at
         --  all time for it to function properly:
         --
         --    A nested construct is entered only when it contains suitable
         --    constructs.
         --
         --  This guarantees that leaving a nested or encapsulating construct
         --  functions properly.
         --
         --  The Inspection phase determines whether the current construct is
         --  non-preelaborable, and if it is, the algorithm terminates.
         --
         --  The Advancement phase walks the tree in reverse declarative order,
         --  while entering and leaving nested and encapsulating constructs. It
         --  may also terminate the elaborithm. There are several special cases
         --  of advancement.
         --
         --  1) General case:
         --
         --    <construct 1>
         --     ...
         --    <construct N-1>                      <- Curr
         --    <construct N>                        <- Start
         --    <subprogram body>
         --
         --  In the general case, a declarative or statement list is traversed
         --  in reverse order where Curr is the lead pointer, and Start is the
         --  last preelaborable construct.
         --
         --  2) Entering handled bodies
         --
         --    package body Nested is               <- Curr (2.3)
         --       <declarations>                    <- Curr (2.2)
         --    begin
         --       <statements>                      <- Curr (2.1)
         --    end Nested;
         --    <construct>                          <- Start
         --
         --  In this case, the algorithm enters a handled body by starting from
         --  the last statement (2.1), or the last declaration (2.2), or the
         --  body is consumed (2.3) because it is empty and thus preelaborable.
         --
         --  3) Entering package declarations
         --
         --    package Nested is                    <- Curr (2.3)
         --       <visible declarations>            <- Curr (2.2)
         --    private
         --       <private declarations>            <- Curr (2.1)
         --    end Nested;
         --    <construct>                          <- Start
         --
         --  In this case, the algorithm enters a package declaration by
         --  starting from the last private declaration (2.1), the last visible
         --  declaration (2.2), or the package is consumed (2.3) because it is
         --  empty and thus preelaborable.
         --
         --  4) Transitioning from list to list of the same construct
         --
         --  Certain constructs have two eligible lists. The algorithm must
         --  thus transition from the second to the first list when the second
         --  list is exhausted.
         --
         --    declare                              <- Curr (4.2)
         --       <declarations>                    <- Curr (4.1)
         --    begin
         --       <statements>                      <- Start
         --    end;
         --
         --  In this case, the algorithm has exhausted the second list (the
         --  statements in the example above), and continues with the last
         --  declaration (4.1) or the construct is consumed (4.2) because it
         --  contains only preelaborable code.
         --
         --  5) Transitioning from list to construct
         --
         --    tack body Task is                    <- Curr (5.1)
         --                                         <- Curr (Empty)
         --       <construct 1>                     <- Start
         --
         --  In this case, the algorithm has exhausted a list, Curr is Empty,
         --  and the owner of the list is consumed (5.1).
         --
         --  6) Transitioning from unit to unit
         --
         --  A package body with a spec subject to pragma Elaborate_Body
         --  extends the possible range of the early call region to the package
         --  spec.
         --
         --    package Pack is                      <- Curr (6.3)
         --       pragma Elaborate_Body;            <- Curr (6.2)
         --       <visible declarations>            <- Curr (6.2)
         --    private
         --       <private declarations>            <- Curr (6.1)
         --    end Pack;
         --
         --    package body Pack is                 <- Curr, Start
         --
         --  In this case, the algorithm has reached a package body compilation
         --  unit whose spec is subject to pragma Elaborate_Body, or the caller
         --  of the algorithm has specified this behavior. This transition is
         --  equivalent to 3).
         --
         --  7) Transitioning from unit to termination
         --
         --  Reaching a compilation unit always terminates the algorithm as
         --  there are no more lists to examine. This must take case 6) into
         --  account.
         --
         --  8) Transitioning from subunit to stub
         --
         --    package body Pack is separate;       <- Curr (8.1)
         --
         --    separate (...)
         --    package body Pack is                 <- Curr, Start
         --
         --  Reaching a subunit continues the search from the corresponding
         --  stub (8.1).

         procedure Advance (Curr : in out Node_Id);
         pragma Inline (Advance);
         --  Update the Curr and Start pointers depending on their location
         --  in the tree to the next eligible construct. This routine raises
         --  ECR_Found.

         procedure Enter_Handled_Body (Curr : in out Node_Id);
         pragma Inline (Enter_Handled_Body);
         --  Update the Curr and Start pointers to enter a nested handled body
         --  if applicable. This routine raises ECR_Found.

         procedure Enter_Package_Declaration (Curr : in out Node_Id);
         pragma Inline (Enter_Package_Declaration);
         --  Update the Curr and Start pointers to enter a nested package spec
         --  if applicable. This routine raises ECR_Found.

         function Find_ECR (N : Node_Id) return Node_Id;
         pragma Inline (Find_ECR);
         --  Find an early call region starting from arbitrary node N

         function Has_Suitable_Construct (List : List_Id) return Boolean;
         pragma Inline (Has_Suitable_Construct);
         --  Determine whether list List contains a suitable construct for
         --  inclusion into an early call region.

         procedure Include (N : Node_Id; Curr : out Node_Id);
         pragma Inline (Include);
         --  Update the Curr and Start pointers to include arbitrary construct
         --  N in the early call region. This routine raises ECR_Found.

         function Is_OK_Preelaborable_Construct (N : Node_Id) return Boolean;
         pragma Inline (Is_OK_Preelaborable_Construct);
         --  Determine whether arbitrary node N denotes a preelaboration-safe
         --  construct.

         function Is_Suitable_Construct (N : Node_Id) return Boolean;
         pragma Inline (Is_Suitable_Construct);
         --  Determine whether arbitrary node N denotes a suitable construct
         --  for inclusion into the early call region.

         function Previous_Suitable_Construct (N : Node_Id) return Node_Id;
         pragma Inline (Previous_Suitable_Construct);
         --  Return the previous node suitable for inclusion into the early
         --  call region.

         procedure Transition_Body_Declarations
           (Bod  : Node_Id;
            Curr : out Node_Id);
         pragma Inline (Transition_Body_Declarations);
         --  Update the Curr and Start pointers when construct Bod denotes a
         --  block statement or a suitable body. This routine raises ECR_Found.

         procedure Transition_Handled_Statements
           (HSS  : Node_Id;
            Curr : out Node_Id);
         pragma Inline (Transition_Handled_Statements);
         --  Update the Curr and Start pointers when node HSS denotes a handled
         --  sequence of statements. This routine raises ECR_Found.

         procedure Transition_Spec_Declarations
           (Spec : Node_Id;
            Curr : out Node_Id);
         pragma Inline (Transition_Spec_Declarations);
         --  Update the Curr and Start pointers when construct Spec denotes
         --  a concurrent definition or a package spec. This routine raises
         --  ECR_Found.

         procedure Transition_Unit (Unit : Node_Id; Curr : out Node_Id);
         pragma Inline (Transition_Unit);
         --  Update the Curr and Start pointers when node Unit denotes a
         --  potential compilation unit. This routine raises ECR_Found.

         -------------
         -- Advance --
         -------------

         procedure Advance (Curr : in out Node_Id) is
            Context : Node_Id;

         begin
            --  Curr denotes one of the following cases upon entry into this
            --  routine:
            --
            --    * Empty - There is no current construct when a declarative or
            --      a statement list has been exhausted. This does not indicate
            --      that the early call region has been computed as it is still
            --      possible to transition to another list.
            --
            --    * Encapsulator - The current construct wraps declarations
            --      and/or statements. This indicates that the early call
            --      region may extend within the nested construct.
            --
            --    * Preelaborable - The current construct is preelaborable
            --      because Find_ECR would not invoke Advance if this was not
            --      the case.

            --  The current construct is an encapsulator or is preelaborable

            if Present (Curr) then

               --  Enter encapsulators by inspecting their declarations and/or
               --  statements.

               if Nkind (Curr) in N_Block_Statement | N_Package_Body then
                  Enter_Handled_Body (Curr);

               elsif Nkind (Curr) = N_Package_Declaration then
                  Enter_Package_Declaration (Curr);

               --  Early call regions have a property which can be exploited to
               --  optimize the algorithm.
               --
               --    <preceding subprogram body>
               --    <preelaborable construct 1>
               --     ...
               --    <preelaborable construct N>
               --    <initiating subprogram body>
               --
               --  If a traversal initiated from a subprogram body reaches a
               --  preceding subprogram body, then both bodies share the same
               --  early call region.
               --
               --  The property results in the following desirable effects:
               --
               --  * If the preceding body already has an early call region,
               --    then the initiating body can reuse it. This minimizes the
               --    amount of processing performed by the algorithm.
               --
               --  * If the preceding body lack an early call region, then the
               --    algorithm can compute the early call region, and reuse it
               --    for the initiating body. This processing performs the same
               --    amount of work, but has the beneficial effect of computing
               --    the early call regions of all preceding bodies.

               elsif Nkind (Curr) in N_Entry_Body | N_Subprogram_Body then
                  Start :=
                    Find_Early_Call_Region
                      (Body_Decl        => Curr,
                       Assume_Elab_Body => Assume_Elab_Body,
                       Skip_Memoization => Skip_Memoization);

                  raise ECR_Found;

               --  Otherwise current construct is preelaborable. Unpdate the
               --  early call region to include it.

               else
                  Include (Curr, Curr);
               end if;

            --  Otherwise the current construct is missing, indicating that the
            --  current list has been exhausted. Depending on the context of
            --  the list, several transitions are possible.

            else
               --  The invariant of the algorithm ensures that Curr and Start
               --  are at the same level of nesting at the point of transition.
               --  The algorithm can determine which list the traversal came
               --  from by examining Start.

               Context := Parent (Start);

               --  Attempt the following transitions:
               --
               --    private declarations -> visible declarations
               --    private declarations -> upper level
               --    private declarations -> terminate
               --    visible declarations -> upper level
               --    visible declarations -> terminate

               if Nkind (Context) in N_Package_Specification
                                   | N_Protected_Definition
                                   | N_Task_Definition
               then
                  Transition_Spec_Declarations (Context, Curr);

               --  Attempt the following transitions:
               --
               --    statements -> declarations
               --    statements -> upper level
               --    statements -> corresponding package spec (Elab_Body)
               --    statements -> terminate

               elsif Nkind (Context) = N_Handled_Sequence_Of_Statements then
                  Transition_Handled_Statements (Context, Curr);

               --  Attempt the following transitions:
               --
               --    declarations -> upper level
               --    declarations -> corresponding package spec (Elab_Body)
               --    declarations -> terminate

               elsif Nkind (Context) in N_Block_Statement
                                      | N_Entry_Body
                                      | N_Package_Body
                                      | N_Protected_Body
                                      | N_Subprogram_Body
                                      | N_Task_Body
               then
                  Transition_Body_Declarations (Context, Curr);

               --  Otherwise it is not possible to transition. Stop the search
               --  because there are no more declarations or statements to
               --  check.

               else
                  raise ECR_Found;
               end if;
            end if;
         end Advance;

         --------------------------
         -- Enter_Handled_Body --
         --------------------------

         procedure Enter_Handled_Body (Curr : in out Node_Id) is
            Decls : constant List_Id := Declarations (Curr);
            HSS   : constant Node_Id := Handled_Statement_Sequence (Curr);
            Stmts : List_Id := No_List;

         begin
            if Present (HSS) then
               Stmts := Statements (HSS);
            end if;

            --  The handled body has a non-empty statement sequence. The
            --  construct to inspect is the last statement.

            if Has_Suitable_Construct (Stmts) then
               Curr := Last (Stmts);

            --  The handled body lacks statements, but has non-empty
            --  declarations. The construct to inspect is the last declaration.

            elsif Has_Suitable_Construct (Decls) then
               Curr := Last (Decls);

            --  Otherwise the handled body lacks both declarations and
            --  statements. The construct to inspect is the node which precedes
            --  the handled body. Update the early call region to include the
            --  handled body.

            else
               Include (Curr, Curr);
            end if;
         end Enter_Handled_Body;

         -------------------------------
         -- Enter_Package_Declaration --
         -------------------------------

         procedure Enter_Package_Declaration (Curr : in out Node_Id) is
            Pack_Spec : constant Node_Id := Specification (Curr);
            Prv_Decls : constant List_Id := Private_Declarations (Pack_Spec);
            Vis_Decls : constant List_Id := Visible_Declarations (Pack_Spec);

         begin
            --  The package has a non-empty private declarations. The construct
            --  to inspect is the last private declaration.

            if Has_Suitable_Construct (Prv_Decls) then
               Curr := Last (Prv_Decls);

            --  The package lacks private declarations, but has non-empty
            --  visible declarations. In this case the construct to inspect
            --  is the last visible declaration.

            elsif Has_Suitable_Construct (Vis_Decls) then
               Curr := Last (Vis_Decls);

            --  Otherwise the package lacks any declarations. The construct
            --  to inspect is the node which precedes the package. Update the
            --  early call region to include the package declaration.

            else
               Include (Curr, Curr);
            end if;
         end Enter_Package_Declaration;

         --------------
         -- Find_ECR --
         --------------

         function Find_ECR (N : Node_Id) return Node_Id is
            Curr : Node_Id;

         begin
            --  The early call region starts at N

            Curr  := Previous_Suitable_Construct (N);
            Start := N;

            --  Inspect each node in reverse declarative order while going in
            --  and out of nested and enclosing constructs. Note that the only
            --  way to terminate this infinite loop is to raise ECR_Found.

            loop
               --  The current construct is not preelaboration-safe. Terminate
               --  the traversal.

               if Present (Curr)
                 and then not Is_OK_Preelaborable_Construct (Curr)
               then
                  raise ECR_Found;
               end if;

               --  Advance to the next suitable construct. This may terminate
               --  the traversal by raising ECR_Found.

               Advance (Curr);
            end loop;

         exception
            when ECR_Found =>
               return Start;
         end Find_ECR;

         ----------------------------
         -- Has_Suitable_Construct --
         ----------------------------

         function Has_Suitable_Construct (List : List_Id) return Boolean is
            Item : Node_Id;

         begin
            --  Examine the list in reverse declarative order, looking for a
            --  suitable construct.

            if Present (List) then
               Item := Last (List);
               while Present (Item) loop
                  if Is_Suitable_Construct (Item) then
                     return True;
                  end if;

                  Prev (Item);
               end loop;
            end if;

            return False;
         end Has_Suitable_Construct;

         -------------
         -- Include --
         -------------

         procedure Include (N : Node_Id; Curr : out Node_Id) is
         begin
            Start := N;

            --  The input node is a compilation unit. This terminates the
            --  search because there are no more lists to inspect and there are
            --  no more enclosing constructs to climb up to. The transitions
            --  are:
            --
            --    private declarations -> terminate
            --    visible declarations -> terminate
            --    statements           -> terminate
            --    declarations         -> terminate

            if Nkind (Parent (Start)) = N_Compilation_Unit then
               raise ECR_Found;

            --  Otherwise the input node is still within some list

            else
               Curr := Previous_Suitable_Construct (Start);
            end if;
         end Include;

         -----------------------------------
         -- Is_OK_Preelaborable_Construct --
         -----------------------------------

         function Is_OK_Preelaborable_Construct (N : Node_Id) return Boolean is
         begin
            --  Assignment statements are acceptable as long as they were
            --  produced by the ABE mechanism to update elaboration flags.

            if Nkind (N) = N_Assignment_Statement then
               return Is_Elaboration_Code (N);

            --  Block statements are acceptable even though they directly
            --  violate preelaborability. The intention is not to penalize
            --  the early call region when a block contains only preelaborable
            --  constructs.
            --
            --    declare
            --       Val : constant Integer := 1;
            --    begin
            --       pragma Assert (Val = 1);
            --       null;
            --    end;
            --
            --  Note that the Advancement phase does enter blocks, and will
            --  detect any non-preelaborable declarations or statements within.

            elsif Nkind (N) = N_Block_Statement then
               return True;
            end if;

            --  Otherwise the construct must be preelaborable. The check must
            --  take the syntactic and semantic structure of the construct. DO
            --  NOT use Is_Preelaborable_Construct here.

            return not Is_Non_Preelaborable_Construct (N);
         end Is_OK_Preelaborable_Construct;

         ---------------------------
         -- Is_Suitable_Construct --
         ---------------------------

         function Is_Suitable_Construct (N : Node_Id) return Boolean is
            Context : constant Node_Id := Parent (N);

         begin
            --  An internally-generated statement sequence which contains only
            --  a single null statement is not a suitable construct because it
            --  is a byproduct of the parser. Such a null statement should be
            --  excluded from the early call region because it carries the
            --  source location of the "end" keyword, and may lead to confusing
            --  diagnostics.

            if Nkind (N) = N_Null_Statement
              and then not Comes_From_Source (N)
              and then Present (Context)
              and then Nkind (Context) = N_Handled_Sequence_Of_Statements
            then
               return False;

            --  Similarly, internally-generated objects and types may have
            --  out-of-order source locations that confuse diagnostics, e.g.
            --  source locations in the body for objects/types generated in
            --  the spec.

            elsif Nkind (N) in N_Full_Type_Declaration | N_Object_Declaration
              and then not Comes_From_Source (N)
            then
               return False;
            end if;

            --  Otherwise only constructs which correspond to pure Ada
            --  constructs are considered suitable.

            case Nkind (N) is
               when N_Call_Marker
                  | N_Freeze_Entity
                  | N_Freeze_Generic_Entity
                  | N_Implicit_Label_Declaration
                  | N_Itype_Reference
                  | N_Pop_Constraint_Error_Label
                  | N_Pop_Program_Error_Label
                  | N_Pop_Storage_Error_Label
                  | N_Push_Constraint_Error_Label
                  | N_Push_Program_Error_Label
                  | N_Push_Storage_Error_Label
                  | N_SCIL_Dispatch_Table_Tag_Init
                  | N_SCIL_Dispatching_Call
                  | N_SCIL_Membership_Test
                  | N_Variable_Reference_Marker
               =>
                  return False;

               when others =>
                  return True;
            end case;
         end Is_Suitable_Construct;

         ---------------------------------
         -- Previous_Suitable_Construct --
         ---------------------------------

         function Previous_Suitable_Construct (N : Node_Id) return Node_Id is
            P : Node_Id;

         begin
            P := Prev (N);

            while Present (P) and then not Is_Suitable_Construct (P) loop
               Prev (P);
            end loop;

            return P;
         end Previous_Suitable_Construct;

         ----------------------------------
         -- Transition_Body_Declarations --
         ----------------------------------

         procedure Transition_Body_Declarations
           (Bod  : Node_Id;
            Curr : out Node_Id)
         is
            Decls : constant List_Id := Declarations (Bod);

         begin
            --  The search must come from the declarations of the body

            pragma Assert
              (Is_Non_Empty_List (Decls)
                and then List_Containing (Start) = Decls);

            --  The search finished inspecting the declarations. The construct
            --  to inspect is the node which precedes the handled body, unless
            --  the body is a compilation unit. The transitions are:
            --
            --    declarations -> upper level
            --    declarations -> corresponding package spec (Elab_Body)
            --    declarations -> terminate

            Transition_Unit (Bod, Curr);
         end Transition_Body_Declarations;

         -----------------------------------
         -- Transition_Handled_Statements --
         -----------------------------------

         procedure Transition_Handled_Statements
           (HSS  : Node_Id;
            Curr : out Node_Id)
         is
            Bod   : constant Node_Id := Parent (HSS);
            Decls : constant List_Id := Declarations (Bod);
            Stmts : constant List_Id := Statements (HSS);

         begin
            --  The search must come from the statements of certain bodies or
            --  statements.

            pragma Assert
              (Nkind (Bod) in
                 N_Block_Statement |
                 N_Entry_Body      |
                 N_Package_Body    |
                 N_Protected_Body  |
                 N_Subprogram_Body |
                 N_Task_Body);

            --  The search must come from the statements of the handled
            --  sequence.

            pragma Assert
              (Is_Non_Empty_List (Stmts)
                and then List_Containing (Start) = Stmts);

            --  The search finished inspecting the statements. The handled body
            --  has non-empty declarations. The construct to inspect is the
            --  last declaration. The transitions are:
            --
            --    statements -> declarations

            if Has_Suitable_Construct (Decls) then
               Curr := Last (Decls);

            --  Otherwise the handled body lacks declarations. The construct to
            --  inspect is the node which precedes the handled body, unless the
            --  body is a compilation unit. The transitions are:
            --
            --    statements -> upper level
            --    statements -> corresponding package spec (Elab_Body)
            --    statements -> terminate

            else
               Transition_Unit (Bod, Curr);
            end if;
         end Transition_Handled_Statements;

         ----------------------------------
         -- Transition_Spec_Declarations --
         ----------------------------------

         procedure Transition_Spec_Declarations
           (Spec : Node_Id;
            Curr : out Node_Id)
         is
            Prv_Decls : constant List_Id := Private_Declarations (Spec);
            Vis_Decls : constant List_Id := Visible_Declarations (Spec);

         begin
            pragma Assert (Present (Start) and then Is_List_Member (Start));

            --  The search came from the private declarations and finished
            --  their inspection.

            if Has_Suitable_Construct (Prv_Decls)
              and then List_Containing (Start) = Prv_Decls
            then
               --  The context has non-empty visible declarations. The node to
               --  inspect is the last visible declaration. The transitions
               --  are:
               --
               --    private declarations -> visible declarations

               if Has_Suitable_Construct (Vis_Decls) then
                  Curr := Last (Vis_Decls);

               --  Otherwise the context lacks visible declarations. The
               --  construct to inspect is the node which precedes the context
               --  unless the context is a compilation unit. The transitions
               --  are:
               --
               --    private declarations -> upper level
               --    private declarations -> terminate

               else
                  Transition_Unit (Parent (Spec), Curr);
               end if;

            --  The search came from the visible declarations and finished
            --  their inspections. The construct to inspect is the node which
            --  precedes the context, unless the context is a compilaton unit.
            --  The transitions are:
            --
            --    visible declarations -> upper level
            --    visible declarations -> terminate

            elsif Has_Suitable_Construct (Vis_Decls)
              and then List_Containing (Start) = Vis_Decls
            then
               Transition_Unit (Parent (Spec), Curr);

            --  At this point both declarative lists are empty, but the
            --  traversal still came from within the spec. This indicates
            --  that the invariant of the algorithm has been violated.

            else
               pragma Assert (False);
               raise ECR_Found;
            end if;
         end Transition_Spec_Declarations;

         ---------------------
         -- Transition_Unit --
         ---------------------

         procedure Transition_Unit
           (Unit : Node_Id;
            Curr : out Node_Id)
         is
            Context : constant Node_Id := Parent (Unit);

         begin
            --  The unit is a compilation unit. This terminates the search
            --  because there are no more lists to inspect and there are no
            --  more enclosing constructs to climb up to.

            if Nkind (Context) = N_Compilation_Unit then

               --  A package body with a corresponding spec subject to pragma
               --  Elaborate_Body is an exception to the above. The annotation
               --  allows the search to continue into the package declaration.
               --  The transitions are:
               --
               --    statements   -> corresponding package spec (Elab_Body)
               --    declarations -> corresponding package spec (Elab_Body)

               if Nkind (Unit) = N_Package_Body
                 and then (Assume_Elab_Body
                            or else Has_Pragma_Elaborate_Body
                                      (Corresponding_Spec (Unit)))
               then
                  Curr := Unit_Declaration_Node (Corresponding_Spec (Unit));
                  Enter_Package_Declaration (Curr);

               --  Otherwise terminate the search. The transitions are:
               --
               --    private declarations -> terminate
               --    visible declarations -> terminate
               --    statements           -> terminate
               --    declarations         -> terminate

               else
                  raise ECR_Found;
               end if;

            --  The unit is a subunit. The construct to inspect is the node
            --  which precedes the corresponding stub. Update the early call
            --  region to include the unit.

            elsif Nkind (Context) = N_Subunit then
               Start := Unit;
               Curr  := Corresponding_Stub (Context);

            --  Otherwise the unit is nested. The construct to inspect is the
            --  node which precedes the unit. Update the early call region to
            --  include the unit.

            else
               Include (Unit, Curr);
            end if;
         end Transition_Unit;

         --  Local variables

         Body_Id : constant Entity_Id := Unique_Defining_Entity (Body_Decl);
         Region  : Node_Id;

      --  Start of processing for Find_Early_Call_Region

      begin
         --  The caller demands the start of the early call region without
         --  saving or retrieving it to/from internal data structures.

         if Skip_Memoization then
            Region := Find_ECR (Body_Decl);

         --  Default behavior

         else
            --  Check whether the early call region of the subprogram body is
            --  available.

            Region := Early_Call_Region (Body_Id);

            if No (Region) then
               Region := Find_ECR (Body_Decl);

               --  Associate the early call region with the subprogram body in
               --  case other scenarios need it.

               Set_Early_Call_Region (Body_Id, Region);
            end if;
         end if;

         --  A subprogram body must always have an early call region

         pragma Assert (Present (Region));

         return Region;
      end Find_Early_Call_Region;

      --------------------------------------------
      -- Initialize_Early_Call_Region_Processor --
      --------------------------------------------

      procedure Initialize_Early_Call_Region_Processor is
      begin
         Early_Call_Regions_Map := ECR_Map.Create (100);
      end Initialize_Early_Call_Region_Processor;

      ---------------------------
      -- Set_Early_Call_Region --
      ---------------------------

      procedure Set_Early_Call_Region (Body_Id : Entity_Id; Start : Node_Id) is
         pragma Assert (Present (Body_Id));
         pragma Assert (Present (Start));

      begin
         ECR_Map.Put (Early_Call_Regions_Map, Body_Id, Start);
      end Set_Early_Call_Region;
   end Early_Call_Region_Processor;

   ----------------------
   -- Elaborated_Units --
   ----------------------

   package body Elaborated_Units is

      -----------
      -- Types --
      -----------

      --  The following type idenfities the elaboration attributes of a unit

      type Elaboration_Attributes_Id is new Natural;

      No_Elaboration_Attributes    : constant Elaboration_Attributes_Id :=
                                       Elaboration_Attributes_Id'First;
      First_Elaboration_Attributes : constant Elaboration_Attributes_Id :=
                                       No_Elaboration_Attributes + 1;

      --  The following type represents the elaboration attributes of a unit

      type Elaboration_Attributes_Record is record
         Elab_Pragma : Node_Id := Empty;
         --  This attribute denotes a source Elaborate or Elaborate_All pragma
         --  which guarantees the prior elaboration of some unit with respect
         --  to the main unit. The pragma may come from the following contexts:
         --
         --    * The main unit
         --    * The spec of the main unit (if applicable)
         --    * Any parent spec of the main unit (if applicable)
         --    * Any parent subunit of the main unit (if applicable)
         --
         --  The attribute remains Empty if no such pragma is available. Source
         --  pragmas play a role in satisfying SPARK elaboration requirements.

         With_Clause : Node_Id := Empty;
         --  This attribute denotes an internally-generated or a source with
         --  clause for some unit withed by the main unit. With clauses carry
         --  flags which represent implicit Elaborate or Elaborate_All pragmas.
         --  These clauses play a role in supplying elaboration dependencies to
         --  binde.
      end record;

      ---------------------
      -- Data structures --
      ---------------------

      --  The following table stores all elaboration attributes

      package Elaboration_Attributes is new Table.Table
        (Table_Index_Type     => Elaboration_Attributes_Id,
         Table_Component_Type => Elaboration_Attributes_Record,
         Table_Low_Bound      => First_Elaboration_Attributes,
         Table_Initial        => 250,
         Table_Increment      => 200,
         Table_Name           => "Elaboration_Attributes");

      procedure Destroy (EA_Id : in out Elaboration_Attributes_Id);
      --  Destroy elaboration attributes EA_Id

      package UA_Map is new Dynamic_Hash_Tables
        (Key_Type              => Entity_Id,
         Value_Type            => Elaboration_Attributes_Id,
         No_Value              => No_Elaboration_Attributes,
         Expansion_Threshold   => 1.5,
         Expansion_Factor      => 2,
         Compression_Threshold => 0.3,
         Compression_Factor    => 2,
         "="                   => "=",
         Destroy_Value         => Destroy,
         Hash                  => Hash);

      --  The following map relates an elaboration attributes of a unit to the
      --  unit.

      Unit_To_Attributes_Map : UA_Map.Dynamic_Hash_Table := UA_Map.Nil;

      ------------------
      -- Constructors --
      ------------------

      function Elaboration_Attributes_Of
        (Unit_Id : Entity_Id) return Elaboration_Attributes_Id;
      pragma Inline (Elaboration_Attributes_Of);
      --  Obtain the elaboration attributes of unit Unit_Id

      -----------------------
      -- Local subprograms --
      -----------------------

      function Elab_Pragma (EA_Id : Elaboration_Attributes_Id) return Node_Id;
      pragma Inline (Elab_Pragma);
      --  Obtain the Elaborate[_All] pragma of elaboration attributes EA_Id

      procedure Ensure_Prior_Elaboration_Dynamic
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State);
      pragma Inline (Ensure_Prior_Elaboration_Dynamic);
      --  Guarantee the elaboration of unit Unit_Id with respect to the main
      --  unit by suggesting the use of Elaborate[_All] with name Prag_Nam. N
      --  denotes the related scenario. In_State is the current state of the
      --  Processing phase.

      procedure Ensure_Prior_Elaboration_Static
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State);
      pragma Inline (Ensure_Prior_Elaboration_Static);
      --  Guarantee the elaboration of unit Unit_Id with respect to the main
      --  unit by installing an implicit Elaborate[_All] pragma with name
      --  Prag_Nam. N denotes the related scenario. In_State is the current
      --  state of the Processing phase.

      function Present (EA_Id : Elaboration_Attributes_Id) return Boolean;
      pragma Inline (Present);
      --  Determine whether elaboration attributes UA_Id exist

      procedure Set_Elab_Pragma
        (EA_Id : Elaboration_Attributes_Id;
         Prag  : Node_Id);
      pragma Inline (Set_Elab_Pragma);
      --  Set the Elaborate[_All] pragma of elaboration attributes EA_Id to
      --  Prag.

      procedure Set_With_Clause
        (EA_Id  : Elaboration_Attributes_Id;
         Clause : Node_Id);
      pragma Inline (Set_With_Clause);
      --  Set the with clause of elaboration attributes EA_Id to Clause

      function With_Clause (EA_Id : Elaboration_Attributes_Id) return Node_Id;
      pragma Inline (With_Clause);
      --  Obtain the implicit or source with clause of elaboration attributes
      --  EA_Id.

      ------------------------------
      -- Collect_Elaborated_Units --
      ------------------------------

      procedure Collect_Elaborated_Units is
         procedure Add_Pragma (Prag : Node_Id);
         pragma Inline (Add_Pragma);
         --  Determine whether pragma Prag denotes a legal Elaborate[_All]
         --  pragma. If this is the case, add the related unit to the context.
         --  For pragma Elaborate_All, include recursively all units withed by
         --  the related unit.

         procedure Add_Unit
           (Unit_Id      : Entity_Id;
            Prag         : Node_Id;
            Full_Context : Boolean);
         pragma Inline (Add_Unit);
         --  Add unit Unit_Id to the elaboration context. Prag denotes the
         --  pragma which prompted the inclusion of the unit to the context.
         --  If flag Full_Context is set, examine the nonlimited clauses of
         --  unit Unit_Id and add each withed unit to the context.

         procedure Find_Elaboration_Context (Comp_Unit : Node_Id);
         pragma Inline (Find_Elaboration_Context);
         --  Examine the context items of compilation unit Comp_Unit for
         --  suitable elaboration-related pragmas and add all related units
         --  to the context.

         ----------------
         -- Add_Pragma --
         ----------------

         procedure Add_Pragma (Prag : Node_Id) is
            Prag_Args : constant List_Id :=
                          Pragma_Argument_Associations (Prag);
            Prag_Nam  : constant Name_Id := Pragma_Name (Prag);
            Unit_Arg  : Node_Id;

         begin
            --  Nothing to do if the pragma is not related to elaboration

            if Prag_Nam not in Name_Elaborate | Name_Elaborate_All then
               return;

            --  Nothing to do when the pragma is illegal

            elsif Error_Posted (Prag) then
               return;
            end if;

            Unit_Arg := Get_Pragma_Arg (First (Prag_Args));

            --  The argument of the pragma may appear in package.package form

            if Nkind (Unit_Arg) = N_Selected_Component then
               Unit_Arg := Selector_Name (Unit_Arg);
            end if;

            Add_Unit
              (Unit_Id      => Entity (Unit_Arg),
               Prag         => Prag,
               Full_Context => Prag_Nam = Name_Elaborate_All);
         end Add_Pragma;

         --------------
         -- Add_Unit --
         --------------

         procedure Add_Unit
           (Unit_Id      : Entity_Id;
            Prag         : Node_Id;
            Full_Context : Boolean)
         is
            Clause    : Node_Id;
            EA_Id     : Elaboration_Attributes_Id;
            Unit_Prag : Node_Id;

         begin
            --  Nothing to do when some previous error left a with clause or a
            --  pragma in a bad state.

            if No (Unit_Id) then
               return;
            end if;

            EA_Id     := Elaboration_Attributes_Of (Unit_Id);
            Unit_Prag := Elab_Pragma (EA_Id);

            --  The unit is already included in the context by means of pragma
            --  Elaborate[_All].

            if Present (Unit_Prag) then

               --  Upgrade an existing pragma Elaborate when the unit is
               --  subject to Elaborate_All because the new pragma covers a
               --  larger set of units.

               if Pragma_Name (Unit_Prag) = Name_Elaborate
                 and then Pragma_Name (Prag) = Name_Elaborate_All
               then
                  Set_Elab_Pragma (EA_Id, Prag);

               --  Otherwise the unit retains its existing pragma and does not
               --  need to be included in the context again.

               else
                  return;
               end if;

            --  Otherwise the current unit is not included in the context

            else
               Set_Elab_Pragma (EA_Id, Prag);
            end if;

            --  Includes all units withed by the current one when computing the
            --  full context.

            if Full_Context then

               --  Process all nonlimited with clauses found in the context of
               --  the current unit. Note that limited clauses do not impose an
               --  elaboration order.

               Clause := First (Context_Items (Compilation_Unit (Unit_Id)));
               while Present (Clause) loop
                  if Nkind (Clause) = N_With_Clause
                    and then not Error_Posted (Clause)
                    and then not Limited_Present (Clause)
                  then
                     Add_Unit
                       (Unit_Id      => Entity (Name (Clause)),
                        Prag         => Prag,
                        Full_Context => Full_Context);
                  end if;

                  Next (Clause);
               end loop;
            end if;
         end Add_Unit;

         ------------------------------
         -- Find_Elaboration_Context --
         ------------------------------

         procedure Find_Elaboration_Context (Comp_Unit : Node_Id) is
            pragma Assert (Nkind (Comp_Unit) = N_Compilation_Unit);

            Prag : Node_Id;

         begin
            --  Process all elaboration-related pragmas found in the context of
            --  the compilation unit.

            Prag := First (Context_Items (Comp_Unit));
            while Present (Prag) loop
               if Nkind (Prag) = N_Pragma then
                  Add_Pragma (Prag);
               end if;

               Next (Prag);
            end loop;
         end Find_Elaboration_Context;

         --  Local variables

         Par_Id  : Entity_Id;
         Unit_Id : Node_Id;

      --  Start of processing for Collect_Elaborated_Units

      begin
         --  Perform a traversal to examines the context of the main unit. The
         --  traversal performs the following jumps:
         --
         --    subunit        -> parent subunit
         --    parent subunit -> body
         --    body           -> spec
         --    spec           -> parent spec
         --    parent spec    -> grandparent spec and so on
         --
         --  The traversal relies on units rather than scopes because the scope
         --  of a subunit is some spec, while this traversal must process the
         --  body as well. Given that protected and task bodies can also be
         --  subunits, this complicates the scope approach even further.

         Unit_Id := Unit (Cunit (Main_Unit));

         --  Perform the following traversals when the main unit is a subunit
         --
         --    subunit        -> parent subunit
         --    parent subunit -> body

         while Present (Unit_Id) and then Nkind (Unit_Id) = N_Subunit loop
            Find_Elaboration_Context (Parent (Unit_Id));

            --  Continue the traversal by going to the unit which contains the
            --  corresponding stub.

            if Present (Corresponding_Stub (Unit_Id)) then
               Unit_Id :=
                 Unit (Cunit (Get_Source_Unit (Corresponding_Stub (Unit_Id))));

            --  Otherwise the subunit may be erroneous or left in a bad state

            else
               exit;
            end if;
         end loop;

         --  Perform the following traversal now that subunits have been taken
         --  care of, or the main unit is a body.
         --
         --    body -> spec

         if Present (Unit_Id)
           and then Nkind (Unit_Id) in N_Package_Body | N_Subprogram_Body
         then
            Find_Elaboration_Context (Parent (Unit_Id));

            --  Continue the traversal by going to the unit which contains the
            --  corresponding spec.

            if Present (Corresponding_Spec (Unit_Id)) then
               Unit_Id :=
                 Unit (Cunit (Get_Source_Unit (Corresponding_Spec (Unit_Id))));
            end if;
         end if;

         --  Perform the following traversals now that the body has been taken
         --  care of, or the main unit is a spec.
         --
         --    spec        -> parent spec
         --    parent spec -> grandparent spec and so on

         if Present (Unit_Id)
           and then Nkind (Unit_Id) in N_Generic_Package_Declaration
                                     | N_Generic_Subprogram_Declaration
                                     | N_Package_Declaration
                                     | N_Subprogram_Declaration
         then
            Find_Elaboration_Context (Parent (Unit_Id));

            --  Process a potential chain of parent units which ends with the
            --  main unit spec. The traversal can now safely rely on the scope
            --  chain.

            Par_Id := Scope (Defining_Entity (Unit_Id));
            while Present (Par_Id) and then Par_Id /= Standard_Standard loop
               Find_Elaboration_Context (Compilation_Unit (Par_Id));

               Par_Id := Scope (Par_Id);
            end loop;
         end if;
      end Collect_Elaborated_Units;

      -------------
      -- Destroy --
      -------------

      procedure Destroy (EA_Id : in out Elaboration_Attributes_Id) is
         pragma Unreferenced (EA_Id);
      begin
         null;
      end Destroy;

      -----------------
      -- Elab_Pragma --
      -----------------

      function Elab_Pragma
        (EA_Id : Elaboration_Attributes_Id) return Node_Id
      is
         pragma Assert (Present (EA_Id));
      begin
         return Elaboration_Attributes.Table (EA_Id).Elab_Pragma;
      end Elab_Pragma;

      -------------------------------
      -- Elaboration_Attributes_Of --
      -------------------------------

      function Elaboration_Attributes_Of
        (Unit_Id : Entity_Id) return Elaboration_Attributes_Id
      is
         EA_Id : Elaboration_Attributes_Id;

      begin
         EA_Id := UA_Map.Get (Unit_To_Attributes_Map, Unit_Id);

         --  The unit lacks elaboration attributes. This indicates that the
         --  unit is encountered for the first time. Create the elaboration
         --  attributes for it.

         if not Present (EA_Id) then
            Elaboration_Attributes.Append
              ((Elab_Pragma => Empty,
                With_Clause => Empty));
            EA_Id := Elaboration_Attributes.Last;

            --  Associate the elaboration attributes with the unit

            UA_Map.Put (Unit_To_Attributes_Map, Unit_Id, EA_Id);
         end if;

         pragma Assert (Present (EA_Id));

         return EA_Id;
      end Elaboration_Attributes_Of;

      ------------------------------
      -- Ensure_Prior_Elaboration --
      ------------------------------

      procedure Ensure_Prior_Elaboration
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State)
      is
         pragma Assert (Prag_Nam in Name_Elaborate | Name_Elaborate_All);

      begin
         --  Nothing to do when the need for prior elaboration came from a
         --  partial finalization routine which occurs in an initialization
         --  context. This behavior parallels that of the old ABE mechanism.

         if In_State.Within_Partial_Finalization then
            return;

         --  Nothing to do when the need for prior elaboration came from a task
         --  body and switch -gnatd.y (disable implicit pragma Elaborate_All on
         --  task bodies) is in effect.

         elsif Debug_Flag_Dot_Y and then In_State.Within_Task_Body then
            return;

         --  Nothing to do when the unit is elaborated prior to the main unit.
         --  This check must also consider the following cases:
         --
         --  * No check is made against the context of the main unit because
         --    this is specific to the elaboration model in effect and requires
         --    custom handling (see Ensure_xxx_Prior_Elaboration).
         --
         --  * Unit_Id is subject to pragma Elaborate_Body. An implicit pragma
         --    Elaborate[_All] MUST be generated even though Unit_Id is always
         --    elaborated prior to the main unit. This conservative strategy
         --    ensures that other units withed by Unit_Id will not lead to an
         --  ABE.
         --
         --      package A is               package body A is
         --         procedure ABE;             procedure ABE is ... end ABE;
         --      end A;                     end A;
         --
         --      with A;
         --      package B is               package body B is
         --         pragma Elaborate_Body;     procedure Proc is
         --                                    begin
         --         procedure Proc;               A.ABE;
         --      package B;                    end Proc;
         --                                 end B;
         --
         --      with B;
         --      package C is               package body C is
         --         ...                        ...
         --      end C;                     begin
         --                                    B.Proc;
         --                                 end C;
         --
         --    In the example above, the elaboration of C invokes B.Proc. B is
         --    subject to pragma Elaborate_Body. If no pragma Elaborate[_All]
         --    is gnerated for B in C, then the following elaboratio order will
         --    lead to an ABE:
         --
         --       spec of A elaborated
         --       spec of B elaborated
         --       body of B elaborated
         --       spec of C elaborated
         --       body of C elaborated  <--  calls B.Proc which calls A.ABE
         --       body of A elaborated  <--  problem
         --
         --    The generation of an implicit pragma Elaborate_All (B) ensures
         --    that the elaboration-order mechanism will not pick the above
         --    order.
         --
         --    An implicit Elaborate is NOT generated when the unit is subject
         --    to Elaborate_Body because both pragmas have the same effect.
         --
         --  * Unit_Id is the main unit. An implicit pragma Elaborate[_All]
         --    MUST NOT be generated in this case because a unit cannot depend
         --    on its own elaboration. This case is therefore treated as valid
         --    prior elaboration.

         elsif Has_Prior_Elaboration
                 (Unit_Id      => Unit_Id,
                  Same_Unit_OK => True,
                  Elab_Body_OK => Prag_Nam = Name_Elaborate)
         then
            return;
         end if;

         --  Suggest the use of pragma Prag_Nam when the dynamic model is in
         --  effect.

         if Dynamic_Elaboration_Checks then
            Ensure_Prior_Elaboration_Dynamic
              (N        => N,
               Unit_Id  => Unit_Id,
               Prag_Nam => Prag_Nam,
               In_State => In_State);

         --  Install an implicit pragma Prag_Nam when the static model is in
         --  effect.

         else
            pragma Assert (Static_Elaboration_Checks);

            Ensure_Prior_Elaboration_Static
              (N        => N,
               Unit_Id  => Unit_Id,
               Prag_Nam => Prag_Nam,
               In_State => In_State);
         end if;
      end Ensure_Prior_Elaboration;

      --------------------------------------
      -- Ensure_Prior_Elaboration_Dynamic --
      --------------------------------------

      procedure Ensure_Prior_Elaboration_Dynamic
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State)
      is
         procedure Info_Missing_Pragma;
         pragma Inline (Info_Missing_Pragma);
         --  Output information concerning missing Elaborate or Elaborate_All
         --  pragma with name Prag_Nam for scenario N, which would ensure the
         --  prior elaboration of Unit_Id.

         -------------------------
         -- Info_Missing_Pragma --
         -------------------------

         procedure Info_Missing_Pragma is
         begin
            --  Internal units are ignored as they cause unnecessary noise

            if not In_Internal_Unit (Unit_Id) then

               --  The name of the unit subjected to the elaboration pragma is
               --  fully qualified to improve the clarity of the info message.

               Error_Msg_Name_1     := Prag_Nam;
               Error_Msg_Qual_Level := Nat'Last;

               Error_Msg_NE ("info: missing pragma % for unit &", N, Unit_Id);
               Error_Msg_Qual_Level := 0;
            end if;
         end Info_Missing_Pragma;

         --  Local variables

         EA_Id : constant Elaboration_Attributes_Id :=
                   Elaboration_Attributes_Of (Unit_Id);
         N_Lvl : Enclosing_Level_Kind;
         N_Rep : Scenario_Rep_Id;

      --  Start of processing for Ensure_Prior_Elaboration_Dynamic

      begin
         --  Nothing to do when the unit is guaranteed prior elaboration by
         --  means of a source Elaborate[_All] pragma.

         if Present (Elab_Pragma (EA_Id)) then
            return;
         end if;

         --  Output extra information on a missing Elaborate[_All] pragma when
         --  switch -gnatel (info messages on implicit Elaborate[_All] pragmas
         --  is in effect.

         if Elab_Info_Messages
           and then not In_State.Suppress_Info_Messages
         then
            N_Rep := Scenario_Representation_Of (N, In_State);
            N_Lvl := Level (N_Rep);

            --  Declaration-level scenario

            if (Is_Suitable_Call (N) or else Is_Suitable_Instantiation (N))
              and then N_Lvl = Declaration_Level
            then
               null;

            --  Library-level scenario

            elsif N_Lvl in Library_Level then
               null;

            --  Instantiation library-level scenario

            elsif N_Lvl = Instantiation_Level then
               null;

            --  Otherwise the scenario does not appear at the proper level

            else
               return;
            end if;

            Info_Missing_Pragma;
         end if;
      end Ensure_Prior_Elaboration_Dynamic;

      -------------------------------------
      -- Ensure_Prior_Elaboration_Static --
      -------------------------------------

      procedure Ensure_Prior_Elaboration_Static
        (N        : Node_Id;
         Unit_Id  : Entity_Id;
         Prag_Nam : Name_Id;
         In_State : Processing_In_State)
      is
         function Find_With_Clause
           (Items     : List_Id;
            Withed_Id : Entity_Id) return Node_Id;
         pragma Inline (Find_With_Clause);
         --  Find a nonlimited with clause in the list of context items Items
         --  that withs unit Withed_Id. Return Empty if no such clause exists.

         procedure Info_Implicit_Pragma;
         pragma Inline (Info_Implicit_Pragma);
         --  Output information concerning an implicitly generated Elaborate
         --  or Elaborate_All pragma with name Prag_Nam for scenario N which
         --  ensures the prior elaboration of unit Unit_Id.

         ----------------------
         -- Find_With_Clause --
         ----------------------

         function Find_With_Clause
           (Items     : List_Id;
            Withed_Id : Entity_Id) return Node_Id
         is
            Item : Node_Id;

         begin
            --  Examine the context clauses looking for a suitable with. Note
            --  that limited clauses do not affect the elaboration order.

            Item := First (Items);
            while Present (Item) loop
               if Nkind (Item) = N_With_Clause
                 and then not Error_Posted (Item)
                 and then not Limited_Present (Item)
                 and then Entity (Name (Item)) = Withed_Id
               then
                  return Item;
               end if;

               Next (Item);
            end loop;

            return Empty;
         end Find_With_Clause;

         --------------------------
         -- Info_Implicit_Pragma --
         --------------------------

         procedure Info_Implicit_Pragma is
         begin
            --  Internal units are ignored as they cause unnecessary noise

            if not In_Internal_Unit (Unit_Id) then

               --  The name of the unit subjected to the elaboration pragma is
               --  fully qualified to improve the clarity of the info message.

               Error_Msg_Name_1     := Prag_Nam;
               Error_Msg_Qual_Level := Nat'Last;

               Error_Msg_NE
                 ("info: implicit pragma % generated for unit &", N, Unit_Id);

               Error_Msg_Qual_Level := 0;
               Output_Active_Scenarios (N, In_State);
            end if;
         end Info_Implicit_Pragma;

         --  Local variables

         EA_Id : constant Elaboration_Attributes_Id :=
                   Elaboration_Attributes_Of (Unit_Id);

         Main_Cunit : constant Node_Id    := Cunit (Main_Unit);
         Loc        : constant Source_Ptr := Sloc (Main_Cunit);
         Unit_Cunit : constant Node_Id    := Compilation_Unit (Unit_Id);
         Unit_Prag  : constant Node_Id    := Elab_Pragma (EA_Id);
         Unit_With  : constant Node_Id    := With_Clause (EA_Id);

         Clause : Node_Id;
         Items  : List_Id;

      --  Start of processing for Ensure_Prior_Elaboration_Static

      begin
         --  Nothing to do when the caller has suppressed the generation of
         --  implicit Elaborate[_All] pragmas.

         if In_State.Suppress_Implicit_Pragmas then
            return;

         --  Nothing to do when the unit is guaranteed prior elaboration by
         --  means of a source Elaborate[_All] pragma.

         elsif Present (Unit_Prag) then
            return;

         --  Nothing to do when the unit has an existing implicit Elaborate or
         --  Elaborate_All pragma installed by a previous scenario.

         elsif Present (Unit_With) then

            --  The unit is already guaranteed prior elaboration by means of an
            --  implicit Elaborate pragma, however the current scenario imposes
            --  a stronger requirement of Elaborate_All. "Upgrade" the existing
            --  pragma to match this new requirement.

            if Elaborate_Desirable (Unit_With)
              and then Prag_Nam = Name_Elaborate_All
            then
               Set_Elaborate_All_Desirable (Unit_With);
               Set_Elaborate_Desirable     (Unit_With, False);
            end if;

            return;
         end if;

         --  At this point it is known that the unit has no prior elaboration
         --  according to pragmas and hierarchical relationships.

         Items := Context_Items (Main_Cunit);

         if No (Items) then
            Items := New_List;
            Set_Context_Items (Main_Cunit, Items);
         end if;

         --  Locate the with clause for the unit. Note that there may not be a
         --  clause if the unit is visible through a subunit-body, body-spec,
         --  or spec-parent relationship.

         Clause :=
           Find_With_Clause
             (Items     => Items,
              Withed_Id => Unit_Id);

         --  Generate:
         --    with Id;

         --  Note that adding implicit with clauses is safe because analysis,
         --  resolution, and expansion have already taken place and it is not
         --  possible to interfere with visibility.

         if No (Clause) then
            Clause :=
              Make_With_Clause (Loc,
                Name => New_Occurrence_Of (Unit_Id, Loc));

            Set_Implicit_With (Clause);
            Set_Library_Unit  (Clause, Unit_Cunit);

            Append_To (Items, Clause);
         end if;

         --  Mark the with clause depending on the pragma required

         if Prag_Nam = Name_Elaborate then
            Set_Elaborate_Desirable (Clause);
         else
            Set_Elaborate_All_Desirable (Clause);
         end if;

         --  The implicit Elaborate[_All] ensures the prior elaboration of
         --  the unit. Include the unit in the elaboration context of the
         --  main unit.

         Set_With_Clause (EA_Id, Clause);

         --  Output extra information on an implicit Elaborate[_All] pragma
         --  when switch -gnatel (info messages on implicit Elaborate[_All]
         --  pragmas is in effect.

         if Elab_Info_Messages then
            Info_Implicit_Pragma;
         end if;
      end Ensure_Prior_Elaboration_Static;

      -------------------------------
      -- Finalize_Elaborated_Units --
      -------------------------------

      procedure Finalize_Elaborated_Units is
      begin
         UA_Map.Destroy (Unit_To_Attributes_Map);
      end Finalize_Elaborated_Units;

      ---------------------------
      -- Has_Prior_Elaboration --
      ---------------------------

      function Has_Prior_Elaboration
        (Unit_Id      : Entity_Id;
         Context_OK   : Boolean := False;
         Elab_Body_OK : Boolean := False;
         Same_Unit_OK : Boolean := False) return Boolean
      is
         EA_Id     : constant Elaboration_Attributes_Id :=
                       Elaboration_Attributes_Of (Unit_Id);
         Main_Id   : constant Entity_Id := Main_Unit_Entity;
         Unit_Prag : constant Node_Id   := Elab_Pragma (EA_Id);
         Unit_With : constant Node_Id   := With_Clause (EA_Id);

      begin
         --  A preelaborated unit is always elaborated prior to the main unit

         if Is_Preelaborated_Unit (Unit_Id) then
            return True;

         --  An internal unit is always elaborated prior to a non-internal main
         --  unit.

         elsif In_Internal_Unit (Unit_Id)
           and then not In_Internal_Unit (Main_Id)
         then
            return True;

         --  A unit has prior elaboration if it appears within the context
         --  of the main unit. Consider this case only when requested by the
         --  caller.

         elsif Context_OK
           and then (Present (Unit_Prag) or else Present (Unit_With))
         then
            return True;

         --  A unit whose body is elaborated together with its spec has prior
         --  elaboration except with respect to itself. Consider this case only
         --  when requested by the caller.

         elsif Elab_Body_OK
           and then Has_Pragma_Elaborate_Body (Unit_Id)
           and then not Is_Same_Unit (Unit_Id, Main_Id)
         then
            return True;

         --  A unit has no prior elaboration with respect to itself, but does
         --  not require any means of ensuring its own elaboration either.
         --  Treat this case as valid prior elaboration only when requested by
         --  the caller.

         elsif Same_Unit_OK and then Is_Same_Unit (Unit_Id, Main_Id) then
            return True;
         end if;

         return False;
      end Has_Prior_Elaboration;

      ---------------------------------
      -- Initialize_Elaborated_Units --
      ---------------------------------

      procedure Initialize_Elaborated_Units is
      begin
         Unit_To_Attributes_Map := UA_Map.Create (250);
      end Initialize_Elaborated_Units;

      ----------------------------------
      -- Meet_Elaboration_Requirement --
      ----------------------------------

      procedure Meet_Elaboration_Requirement
        (N        : Node_Id;
         Targ_Id  : Entity_Id;
         Req_Nam  : Name_Id;
         In_State : Processing_In_State)
      is
         pragma Assert (Req_Nam in Name_Elaborate | Name_Elaborate_All);

         Main_Id : constant Entity_Id := Main_Unit_Entity;
         Unit_Id : constant Entity_Id := Find_Top_Unit (Targ_Id);

         procedure Elaboration_Requirement_Error;
         pragma Inline (Elaboration_Requirement_Error);
         --  Emit an error concerning scenario N which has failed to meet the
         --  elaboration requirement.

         function Find_Preelaboration_Pragma
           (Prag_Nam : Name_Id) return Node_Id;
         pragma Inline (Find_Preelaboration_Pragma);
         --  Traverse the visible declarations of unit Unit_Id and locate a
         --  source preelaboration-related pragma with name Prag_Nam.

         procedure Info_Requirement_Met (Prag : Node_Id);
         pragma Inline (Info_Requirement_Met);
         --  Output information concerning pragma Prag which meets requirement
         --  Req_Nam.

         -----------------------------------
         -- Elaboration_Requirement_Error --
         -----------------------------------

         procedure Elaboration_Requirement_Error is
         begin
            if Is_Suitable_Call (N) then
               Info_Call
                 (Call     => N,
                  Subp_Id  => Targ_Id,
                  Info_Msg => False,
                  In_SPARK => True);

            elsif Is_Suitable_Instantiation (N) then
               Info_Instantiation
                 (Inst     => N,
                  Gen_Id   => Targ_Id,
                  Info_Msg => False,
                  In_SPARK => True);

            elsif Is_Suitable_SPARK_Refined_State_Pragma (N) then
               Error_Msg_N
                 ("read of refinement constituents during elaboration in "
                  & "SPARK", N);

            elsif Is_Suitable_Variable_Reference (N) then
               Info_Variable_Reference
                 (Ref    => N,
                  Var_Id => Targ_Id);

            --  No other scenario may impose a requirement on the context of
            --  the main unit.

            else
               pragma Assert (False);
               return;
            end if;

            Error_Msg_Name_1 := Req_Nam;
            Error_Msg_Node_2 := Unit_Id;
            Error_Msg_NE ("\\unit & requires pragma % for &", N, Main_Id);

            Output_Active_Scenarios (N, In_State);
         end Elaboration_Requirement_Error;

         --------------------------------
         -- Find_Preelaboration_Pragma --
         --------------------------------

         function Find_Preelaboration_Pragma
           (Prag_Nam : Name_Id) return Node_Id
         is
            Spec : constant Node_Id := Parent (Unit_Id);
            Decl : Node_Id;

         begin
            --  A preelaboration-related pragma comes from source and appears
            --  at the top of the visible declarations of a package.

            if Nkind (Spec) = N_Package_Specification then
               Decl := First (Visible_Declarations (Spec));
               while Present (Decl) loop
                  if Comes_From_Source (Decl) then
                     if Nkind (Decl) = N_Pragma
                       and then Pragma_Name (Decl) = Prag_Nam
                     then
                        return Decl;

                     --  Otherwise the construct terminates the region where
                     --  the preelaboration-related pragma may appear.

                     else
                        exit;
                     end if;
                  end if;

                  Next (Decl);
               end loop;
            end if;

            return Empty;
         end Find_Preelaboration_Pragma;

         --------------------------
         -- Info_Requirement_Met --
         --------------------------

         procedure Info_Requirement_Met (Prag : Node_Id) is
            pragma Assert (Present (Prag));

         begin
            Error_Msg_Name_1 := Req_Nam;
            Error_Msg_Sloc   := Sloc (Prag);
            Error_Msg_NE
              ("\\% requirement for unit & met by pragma #", N, Unit_Id);
         end Info_Requirement_Met;

         --  Local variables

         EA_Id     : Elaboration_Attributes_Id;
         Elab_Nam  : Name_Id;
         Req_Met   : Boolean;
         Unit_Prag : Node_Id;

      --  Start of processing for Meet_Elaboration_Requirement

      begin
         --  Assume that the requirement has not been met

         Req_Met := False;

         --  If the target is within the main unit, either at the source level
         --  or through an instantiation, then there is no real requirement to
         --  meet because the main unit cannot force its own elaboration by
         --  means of an Elaborate[_All] pragma. Treat this case as valid
         --  coverage.

         if In_Extended_Main_Code_Unit (Targ_Id) then
            Req_Met := True;

         --  Otherwise the target resides in an external unit

         --  The requirement is met when the target comes from an internal unit
         --  because such a unit is elaborated prior to a non-internal unit.

         elsif In_Internal_Unit (Unit_Id)
           and then not In_Internal_Unit (Main_Id)
         then
            Req_Met := True;

         --  The requirement is met when the target comes from a preelaborated
         --  unit. This portion must parallel predicate Is_Preelaborated_Unit.

         elsif Is_Preelaborated_Unit (Unit_Id) then
            Req_Met := True;

            --  Output extra information when switch -gnatel (info messages on
            --  implicit Elaborate[_All] pragmas.

            if Elab_Info_Messages
              and then not In_State.Suppress_Info_Messages
            then
               if Is_Preelaborated (Unit_Id) then
                  Elab_Nam := Name_Preelaborate;

               elsif Is_Pure (Unit_Id) then
                  Elab_Nam := Name_Pure;

               elsif Is_Remote_Call_Interface (Unit_Id) then
                  Elab_Nam := Name_Remote_Call_Interface;

               elsif Is_Remote_Types (Unit_Id) then
                  Elab_Nam := Name_Remote_Types;

               else
                  pragma Assert (Is_Shared_Passive (Unit_Id));
                  Elab_Nam := Name_Shared_Passive;
               end if;

               Info_Requirement_Met (Find_Preelaboration_Pragma (Elab_Nam));
            end if;

         --  Determine whether the context of the main unit has a pragma strong
         --  enough to meet the requirement.

         else
            EA_Id     := Elaboration_Attributes_Of (Unit_Id);
            Unit_Prag := Elab_Pragma (EA_Id);

            --  The pragma must be either Elaborate_All or be as strong as the
            --  requirement.

            if Present (Unit_Prag)
              and then Pragma_Name (Unit_Prag) in Name_Elaborate_All | Req_Nam
            then
               Req_Met := True;

               --  Output extra information when switch -gnatel (info messages
               --  on implicit Elaborate[_All] pragmas.

               if Elab_Info_Messages
                 and then not In_State.Suppress_Info_Messages
               then
                  Info_Requirement_Met (Unit_Prag);
               end if;
            end if;
         end if;

         --  The requirement was not met by the context of the main unit, issue
         --  an error.

         if not Req_Met then
            Elaboration_Requirement_Error;
         end if;
      end Meet_Elaboration_Requirement;

      -------------
      -- Present --
      -------------

      function Present (EA_Id : Elaboration_Attributes_Id) return Boolean is
      begin
         return EA_Id /= No_Elaboration_Attributes;
      end Present;

      ---------------------
      -- Set_Elab_Pragma --
      ---------------------

      procedure Set_Elab_Pragma
        (EA_Id : Elaboration_Attributes_Id;
         Prag  : Node_Id)
      is
         pragma Assert (Present (EA_Id));
      begin
         Elaboration_Attributes.Table (EA_Id).Elab_Pragma := Prag;
      end Set_Elab_Pragma;

      ---------------------
      -- Set_With_Clause --
      ---------------------

      procedure Set_With_Clause
        (EA_Id  : Elaboration_Attributes_Id;
         Clause : Node_Id)
      is
         pragma Assert (Present (EA_Id));
      begin
         Elaboration_Attributes.Table (EA_Id).With_Clause := Clause;
      end Set_With_Clause;

      -----------------
      -- With_Clause --
      -----------------

      function With_Clause
        (EA_Id : Elaboration_Attributes_Id) return Node_Id
      is
         pragma Assert (Present (EA_Id));
      begin
         return Elaboration_Attributes.Table (EA_Id).With_Clause;
      end With_Clause;
   end Elaborated_Units;

   ------------------------------
   -- Elaboration_Phase_Active --
   ------------------------------

   function Elaboration_Phase_Active return Boolean is
   begin
      return Elaboration_Phase = Active;
   end Elaboration_Phase_Active;

   ------------------------------
   -- Error_Preelaborated_Call --
   ------------------------------

   procedure Error_Preelaborated_Call (N : Node_Id) is
   begin
      --  This is a warning in GNAT mode allowing such calls to be used in the
      --  predefined library units with appropriate care.

      Error_Msg_Warn := GNAT_Mode;

      --  Ada 2022 (AI12-0175): Calls to certain functions that are essentially
      --  unchecked conversions are preelaborable.

      if Ada_Version >= Ada_2022 then
         Error_Msg_N
           ("<<non-preelaborable call not allowed in preelaborated unit", N);
      else
         Error_Msg_N
           ("<<non-static call not allowed in preelaborated unit", N);
      end if;
   end Error_Preelaborated_Call;

   ----------------------------------
   -- Finalize_All_Data_Structures --
   ----------------------------------

   procedure Finalize_All_Data_Structures is
   begin
      Finalize_Body_Processor;
      Finalize_Early_Call_Region_Processor;
      Finalize_Elaborated_Units;
      Finalize_Internal_Representation;
      Finalize_Invocation_Graph;
      Finalize_Scenario_Storage;
   end Finalize_All_Data_Structures;

   -----------------------------
   -- Find_Enclosing_Instance --
   -----------------------------

   function Find_Enclosing_Instance (N : Node_Id) return Node_Id is
      Par : Node_Id;

   begin
      --  Climb the parent chain looking for an enclosing instance spec or body

      Par := N;
      while Present (Par) loop
         if Nkind (Par) in N_Package_Body
                         | N_Package_Declaration
                         | N_Subprogram_Body
                         | N_Subprogram_Declaration
           and then Is_Generic_Instance (Unique_Defining_Entity (Par))
         then
            return Par;
         end if;

         Par := Parent (Par);
      end loop;

      return Empty;
   end Find_Enclosing_Instance;

   --------------------------
   -- Find_Enclosing_Level --
   --------------------------

   function Find_Enclosing_Level (N : Node_Id) return Enclosing_Level_Kind is
      function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind;
      pragma Inline (Level_Of);
      --  Obtain the corresponding level of unit Unit

      --------------
      -- Level_Of --
      --------------

      function Level_Of (Unit : Node_Id) return Enclosing_Level_Kind is
         Spec_Id : Entity_Id;

      begin
         if Nkind (Unit) in N_Generic_Instantiation then
            return Instantiation_Level;

         elsif Nkind (Unit) = N_Generic_Package_Declaration then
            return Generic_Spec_Level;

         elsif Nkind (Unit) = N_Package_Declaration then
            return Library_Spec_Level;

         elsif Nkind (Unit) = N_Package_Body then
            Spec_Id := Corresponding_Spec (Unit);

            --  The body belongs to a generic package

            if Present (Spec_Id)
              and then Ekind (Spec_Id) = E_Generic_Package
            then
               return Generic_Body_Level;

            --  Otherwise the body belongs to a non-generic package. This also
            --  treats an illegal package body without a corresponding spec as
            --  a non-generic package body.

            else
               return Library_Body_Level;
            end if;
         end if;

         return No_Level;
      end Level_Of;

      --  Local variables

      Context : Node_Id;
      Curr    : Node_Id;
      Prev    : Node_Id;

   --  Start of processing for Find_Enclosing_Level

   begin
      --  Call markers and instantiations which appear at the declaration level
      --  but are later relocated in a different context retain their original
      --  declaration level.

      if Nkind (N) in N_Call_Marker
                    | N_Function_Instantiation
                    | N_Package_Instantiation
                    | N_Procedure_Instantiation
        and then Is_Declaration_Level_Node (N)
      then
         return Declaration_Level;
      end if;

      --  Climb the parent chain looking at the enclosing levels

      Prev := N;
      Curr := Parent (Prev);
      while Present (Curr) loop

         --  A traversal from a subunit continues via the corresponding stub

         if Nkind (Curr) = N_Subunit then
            Curr := Corresponding_Stub (Curr);

         --  The current construct is a package. Packages are ignored because
         --  they are always elaborated when the enclosing context is invoked
         --  or elaborated.

         elsif Nkind (Curr) in N_Package_Body | N_Package_Declaration then
            null;

         --  The current construct is a block statement

         elsif Nkind (Curr) = N_Block_Statement then

            --  Ignore internally generated blocks created by the expander for
            --  various purposes such as abort defer/undefer.

            if not Comes_From_Source (Curr) then
               null;

            --  If the traversal came from the handled sequence of statements,
            --  then the node appears at the level of the enclosing construct.
            --  This is a more reliable test because transients scopes within
            --  the declarative region of the encapsulator are hard to detect.

            elsif Nkind (Prev) = N_Handled_Sequence_Of_Statements
              and then Handled_Statement_Sequence (Curr) = Prev
            then
               return Find_Enclosing_Level (Parent (Curr));

            --  Otherwise the traversal came from the declarations, the node is
            --  at the declaration level.

            else
               return Declaration_Level;
            end if;

         --  The current construct is a declaration-level encapsulator

         elsif Nkind (Curr) in
                 N_Entry_Body | N_Subprogram_Body | N_Task_Body
         then
            --  If the traversal came from the handled sequence of statements,
            --  then the node cannot possibly appear at any level. This is
            --  a more reliable test because transients scopes within the
            --  declarative region of the encapsulator are hard to detect.

            if Nkind (Prev) = N_Handled_Sequence_Of_Statements
              and then Handled_Statement_Sequence (Curr) = Prev
            then
               return No_Level;

            --  Otherwise the traversal came from the declarations, the node is
            --  at the declaration level.

            else
               return Declaration_Level;
            end if;

         --  The current construct is a non-library-level encapsulator which
         --  indicates that the node cannot possibly appear at any level. Note
         --  that the check must come after the declaration-level check because
         --  both predicates share certain nodes.

         elsif Is_Non_Library_Level_Encapsulator (Curr) then
            Context := Parent (Curr);

            --  The sole exception is when the encapsulator is the compilation
            --  utit itself because the compilation unit node requires special
            --  processing (see below).

            if Present (Context)
              and then Nkind (Context) = N_Compilation_Unit
            then
               null;

            --  Otherwise the node is not at any level

            else
               return No_Level;
            end if;

         --  The current construct is a compilation unit. The node appears at
         --  the [generic] library level when the unit is a [generic] package.

         elsif Nkind (Curr) = N_Compilation_Unit then
            return Level_Of (Unit (Curr));
         end if;

         Prev := Curr;
         Curr := Parent (Prev);
      end loop;

      return No_Level;
   end Find_Enclosing_Level;

   -------------------
   -- Find_Top_Unit --
   -------------------

   function Find_Top_Unit (N : Node_Or_Entity_Id) return Entity_Id is
   begin
      return Find_Unit_Entity (Unit (Cunit (Get_Top_Level_Code_Unit (N))));
   end Find_Top_Unit;

   ----------------------
   -- Find_Unit_Entity --
   ----------------------

   function Find_Unit_Entity (N : Node_Id) return Entity_Id is
      Context : constant Node_Id := Parent (N);
      Orig_N  : constant Node_Id := Original_Node (N);

   begin
      --  The unit denotes a package body of an instantiation which acts as
      --  a compilation unit. The proper entity is that of the package spec.

      if Nkind (N) = N_Package_Body
        and then Nkind (Orig_N) = N_Package_Instantiation
        and then Nkind (Context) = N_Compilation_Unit
      then
         return Corresponding_Spec (N);

      --  The unit denotes an anonymous package created to wrap a subprogram
      --  instantiation which acts as a compilation unit. The proper entity is
      --  that of the "related instance".

      elsif Nkind (N) = N_Package_Declaration
        and then Nkind (Orig_N) in
                   N_Function_Instantiation | N_Procedure_Instantiation
        and then Nkind (Context) = N_Compilation_Unit
      then
         return Related_Instance (Defining_Entity (N));

      --  The unit denotes a concurrent body acting as a subunit. Such bodies
      --  are generally rewritten into null statements. The proper entity is
      --  that of the "original node".

      elsif Nkind (N) = N_Subunit
        and then Nkind (Proper_Body (N)) = N_Null_Statement
        and then Nkind (Original_Node (Proper_Body (N))) in
                   N_Protected_Body | N_Task_Body
      then
         return Defining_Entity (Original_Node (Proper_Body (N)));

      --  Otherwise the proper entity is the defining entity

      else
         return Defining_Entity (N);
      end if;
   end Find_Unit_Entity;

   -----------------------
   -- First_Formal_Type --
   -----------------------

   function First_Formal_Type (Subp_Id : Entity_Id) return Entity_Id is
      Formal_Id : constant Entity_Id := First_Formal (Subp_Id);
      Typ       : Entity_Id;

   begin
      if Present (Formal_Id) then
         Typ := Etype (Formal_Id);

         --  Handle various combinations of concurrent and private types

         loop
            if Ekind (Typ) in E_Protected_Type | E_Task_Type
              and then Present (Anonymous_Object (Typ))
            then
               Typ := Anonymous_Object (Typ);

            elsif Is_Concurrent_Record_Type (Typ) then
               Typ := Corresponding_Concurrent_Type (Typ);

            elsif Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
               Typ := Full_View (Typ);

            else
               exit;
            end if;
         end loop;

         return Typ;
      end if;

      return Empty;
   end First_Formal_Type;

   ------------------------------
   -- Guaranteed_ABE_Processor --
   ------------------------------

   package body Guaranteed_ABE_Processor is
      function Is_Guaranteed_ABE
        (N           : Node_Id;
         Target_Decl : Node_Id;
         Target_Body : Node_Id) return Boolean;
      pragma Inline (Is_Guaranteed_ABE);
      --  Determine whether scenario N with a target described by its initial
      --  declaration Target_Decl and body Target_Decl results in a guaranteed
      --  ABE.

      procedure Process_Guaranteed_ABE_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Guaranteed_ABE_Activation);
      --  Perform common guaranteed ABE checks and diagnostics for activation
      --  call Call which activates object Obj_Id of task type Task_Typ. Formal
      --  Call_Rep denotes the representation of the call. Obj_Rep denotes the
      --  representation of the object. Task_Rep denotes the representation of
      --  the task type. In_State is the current state of the Processing phase.

      procedure Process_Guaranteed_ABE_Call
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Guaranteed_ABE_Call);
      --  Perform common guaranteed ABE checks and diagnostics for call Call
      --  with representation Call_Rep. In_State denotes the current state of
      --  the Processing phase.

      procedure Process_Guaranteed_ABE_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Guaranteed_ABE_Instantiation);
      --  Perform common guaranteed ABE checks and diagnostics for instance
      --  Inst with representation Inst_Rep. In_State is the current state of
      --  the Processing phase.

      -----------------------
      -- Is_Guaranteed_ABE --
      -----------------------

      function Is_Guaranteed_ABE
        (N           : Node_Id;
         Target_Decl : Node_Id;
         Target_Body : Node_Id) return Boolean
      is
         Spec : Node_Id;
      begin
         --  Avoid cascaded errors if there were previous serious infractions.
         --  As a result the scenario will not be treated as a guaranteed ABE.
         --  This behavior parallels that of the old ABE mechanism.

         if Serious_Errors_Detected > 0 then
            return False;

         --  The scenario and the target appear in the same context ignoring
         --  enclosing library levels.

         elsif In_Same_Context (N, Target_Decl) then

            --  The target body has already been encountered. The scenario
            --  results in a guaranteed ABE if it appears prior to the body.

            if Present (Target_Body) then
               return Earlier_In_Extended_Unit (N, Target_Body);

            --  Otherwise the body has not been encountered yet. The scenario
            --  is a guaranteed ABE since the body will appear later, unless
            --  this is a null specification, which can occur if expansion is
            --  disabled (e.g. -gnatc or GNATprove mode). It is assumed that
            --  the caller has already ensured that the scenario is ABE-safe
            --  because optional bodies are not considered here.

            else
               Spec := Specification (Target_Decl);

               if Nkind (Spec) /= N_Procedure_Specification
                 or else not Null_Present (Spec)
               then
                  return True;
               end if;
            end if;
         end if;

         return False;
      end Is_Guaranteed_ABE;

      ----------------------------
      -- Process_Guaranteed_ABE --
      ----------------------------

      procedure Process_Guaranteed_ABE
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
         Scen     : constant Node_Id := Scenario (N);
         Scen_Rep : Scenario_Rep_Id;

      begin
         --  Add the current scenario to the stack of active scenarios

         Push_Active_Scenario (Scen);

         --  Only calls, instantiations, and task activations may result in a
         --  guaranteed ABE.

         --  Call or task activation

         if Is_Suitable_Call (Scen) then
            Scen_Rep := Scenario_Representation_Of (Scen, In_State);

            if Kind (Scen_Rep) = Call_Scenario then
               Process_Guaranteed_ABE_Call
                 (Call     => Scen,
                  Call_Rep => Scen_Rep,
                  In_State => In_State);

            else
               pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);

               Process_Activation
                 (Call      => Scen,
                  Call_Rep  => Scenario_Representation_Of (Scen, In_State),
                  Processor => Process_Guaranteed_ABE_Activation'Access,
                  In_State  => In_State);
            end if;

         --  Instantiation

         elsif Is_Suitable_Instantiation (Scen) then
            Process_Guaranteed_ABE_Instantiation
              (Inst     => Scen,
               Inst_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);
         end if;

         --  Remove the current scenario from the stack of active scenarios
         --  once all ABE diagnostics and checks have been performed.

         Pop_Active_Scenario (Scen);
      end Process_Guaranteed_ABE;

      ---------------------------------------
      -- Process_Guaranteed_ABE_Activation --
      ---------------------------------------

      procedure Process_Guaranteed_ABE_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         Spec_Decl : constant Node_Id := Spec_Declaration (Task_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Obj_Rep)  /= Is_Ignored
                        and then Ghost_Mode_Of (Task_Rep) /= Is_Ignored
                        and then Elaboration_Checks_OK (Obj_Rep)
                        and then Elaboration_Checks_OK (Task_Rep);
         --  A run-time ABE check may be installed only when the object and the
         --  task type have active elaboration checks, and both are not ignored
         --  Ghost constructs.

      begin
         --  Nothing to do when the root scenario appears at the declaration
         --  level and the task is in the same unit, but outside this context.
         --
         --    task type Task_Typ;                  --  task declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             declare
         --                T : Task_Typ;
         --             begin
         --                <activation call>        --  activation site
         --             end;
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    task body Task_Typ is
         --       ...
         --    end Task_Typ;
         --
         --  In the example above, the context of X is the declarative list
         --  of Proc. The "elaboration" of X may reach the activation of T
         --  whose body is defined outside of X's context. The task body is
         --  relevant only when Proc is invoked, but this happens only in
         --  "normal" elaboration, therefore the task body must not be
         --  considered if this is not the case.

         if Is_Up_Level_Target
              (Targ_Decl => Spec_Decl,
               In_State  => In_State)
         then
            return;

         --  Nothing to do when the activation is ABE-safe
         --
         --    generic
         --    package Gen is
         --       task type Task_Typ;
         --    end Gen;
         --
         --    package body Gen is
         --       task body Task_Typ is
         --       begin
         --          ...
         --       end Task_Typ;
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       package Nested is
         --          package Inst is new Gen;
         --          T : Inst.Task_Typ;
         --       end Nested;                       --  safe activation
         --    ...

         elsif Is_Safe_Activation (Call, Task_Rep) then
            return;

         --  An activation call leads to a guaranteed ABE when the activation
         --  call and the task appear within the same context ignoring library
         --  levels, and the body of the task has not been seen yet or appears
         --  after the activation call.
         --
         --    procedure Guaranteed_ABE is
         --       task type Task_Typ;
         --
         --       package Nested is
         --          T : Task_Typ;
         --          <activation call>              --  guaranteed ABE
         --       end Nested;
         --
         --       task body Task_Typ is
         --          ...
         --       end Task_Typ;
         --    ...

         elsif Is_Guaranteed_ABE
                 (N           => Call,
                  Target_Decl => Spec_Decl,
                  Target_Body => Body_Declaration (Task_Rep))
         then
            if Elaboration_Warnings_OK (Call_Rep) then
               Error_Msg_Sloc := Sloc (Call);
               Error_Msg_N
                 ("??task & will be activated # before elaboration of its "
                  & "body", Obj_Id);
               Error_Msg_N
                 ("\Program_Error will be raised at run time", Obj_Id);
            end if;

            --  Mark the activation call as a guaranteed ABE

            Set_Is_Known_Guaranteed_ABE (Call);

            --  Install a run-time ABE failue because this activation call will
            --  always result in an ABE.

            if Check_OK then
               Install_Scenario_ABE_Failure
                 (N        => Call,
                  Targ_Id  => Task_Typ,
                  Targ_Rep => Task_Rep,
                  Disable  => Obj_Rep);
            end if;
         end if;
      end Process_Guaranteed_ABE_Activation;

      ---------------------------------
      -- Process_Guaranteed_ABE_Call --
      ---------------------------------

      procedure Process_Guaranteed_ABE_Call
        (Call      : Node_Id;
         Call_Rep  : Scenario_Rep_Id;
         In_State  : Processing_In_State)
      is
         Subp_Id   : constant Entity_Id     := Target (Call_Rep);
         Subp_Rep  : constant Target_Rep_Id :=
                       Target_Representation_Of (Subp_Id, In_State);
         Spec_Decl : constant Node_Id       := Spec_Declaration (Subp_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Call_Rep) /= Is_Ignored
                        and then Ghost_Mode_Of (Subp_Rep) /= Is_Ignored
                        and then Elaboration_Checks_OK (Call_Rep)
                        and then Elaboration_Checks_OK (Subp_Rep);
         --  A run-time ABE check may be installed only when both the call
         --  and the target have active elaboration checks, and both are not
         --  ignored Ghost constructs.

      begin
         --  Nothing to do when the root scenario appears at the declaration
         --  level and the target is in the same unit but outside this context.
         --
         --    function B ...;                      --  target declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             return B;                   --  call site
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    function B ... is
         --       ...
         --    end B;
         --
         --  In the example above, the context of X is the declarative region
         --  of Proc. The "elaboration" of X may eventually reach B which is
         --  defined outside of X's context. B is relevant only when Proc is
         --  invoked, but this happens only by means of "normal" elaboration,
         --  therefore B must not be considered if this is not the case.

         if Is_Up_Level_Target
              (Targ_Decl => Spec_Decl,
               In_State  => In_State)
         then
            return;

         --  Nothing to do when the call is ABE-safe
         --
         --    generic
         --    function Gen ...;
         --
         --    function Gen ... is
         --    begin
         --       ...
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       function Inst is new Gen;
         --       X : ... := Inst;                  --  safe call
         --    ...

         elsif Is_Safe_Call (Call, Subp_Id, Subp_Rep) then
            return;

         --  A call leads to a guaranteed ABE when the call and the target
         --  appear within the same context ignoring library levels, and the
         --  body of the target has not been seen yet or appears after the
         --  call.
         --
         --    procedure Guaranteed_ABE is
         --       function Func ...;
         --
         --       package Nested is
         --          Obj : ... := Func;             --  guaranteed ABE
         --       end Nested;
         --
         --       function Func ... is
         --          ...
         --       end Func;
         --    ...

         elsif Is_Guaranteed_ABE
                 (N           => Call,
                  Target_Decl => Spec_Decl,
                  Target_Body => Body_Declaration (Subp_Rep))
         then
            if Elaboration_Warnings_OK (Call_Rep) then
               Error_Msg_NE
                 ("??cannot call & before body seen", Call, Subp_Id);
               Error_Msg_N ("\Program_Error will be raised at run time", Call);
            end if;

            --  Mark the call as a guaranteed ABE

            Set_Is_Known_Guaranteed_ABE (Call);

            --  Install a run-time ABE failure because the call will always
            --  result in an ABE.

            if Check_OK then
               Install_Scenario_ABE_Failure
                 (N        => Call,
                  Targ_Id  => Subp_Id,
                  Targ_Rep => Subp_Rep,
                  Disable  => Call_Rep);
            end if;
         end if;
      end Process_Guaranteed_ABE_Call;

      ------------------------------------------
      -- Process_Guaranteed_ABE_Instantiation --
      ------------------------------------------

      procedure Process_Guaranteed_ABE_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         Gen_Id    : constant Entity_Id     := Target (Inst_Rep);
         Gen_Rep   : constant Target_Rep_Id :=
                       Target_Representation_Of (Gen_Id, In_State);
         Spec_Decl : constant Node_Id       := Spec_Declaration (Gen_Rep);

         Check_OK : constant Boolean :=
                      not In_State.Suppress_Checks
                        and then Ghost_Mode_Of (Inst_Rep) /= Is_Ignored
                        and then Ghost_Mode_Of (Gen_Rep)  /= Is_Ignored
                        and then Elaboration_Checks_OK (Inst_Rep)
                        and then Elaboration_Checks_OK (Gen_Rep);
         --  A run-time ABE check may be installed only when both the instance
         --  and the generic have active elaboration checks and both are not
         --  ignored Ghost constructs.

      begin
         --  Nothing to do when the root scenario appears at the declaration
         --  level and the generic is in the same unit, but outside this
         --  context.
         --
         --    generic
         --    procedure Gen is ...;                --  generic declaration
         --
         --    procedure Proc is
         --       function A ... is
         --       begin
         --          if Some_Condition then
         --             declare
         --                procedure I is new Gen;  --  instantiation site
         --             ...
         --          ...
         --       end A;
         --
         --       X : ... := A;                     --  root scenario
         --    ...
         --
         --    procedure Gen is
         --       ...
         --    end Gen;
         --
         --  In the example above, the context of X is the declarative region
         --  of Proc. The "elaboration" of X may eventually reach Gen which
         --  appears outside of X's context. Gen is relevant only when Proc is
         --  invoked, but this happens only by means of "normal" elaboration,
         --  therefore Gen must not be considered if this is not the case.

         if Is_Up_Level_Target
              (Targ_Decl => Spec_Decl,
               In_State  => In_State)
         then
            return;

         --  Nothing to do when the instantiation is ABE-safe
         --
         --    generic
         --    package Gen is
         --       ...
         --    end Gen;
         --
         --    package body Gen is
         --       ...
         --    end Gen;
         --
         --    with Gen;
         --    procedure Main is
         --       package Inst is new Gen (ABE);    --  safe instantiation
         --    ...

         elsif Is_Safe_Instantiation (Inst, Gen_Id, Gen_Rep) then
            return;

         --  An instantiation leads to a guaranteed ABE when the instantiation
         --  and the generic appear within the same context ignoring library
         --  levels, and the body of the generic has not been seen yet or
         --  appears after the instantiation.
         --
         --    procedure Guaranteed_ABE is
         --       generic
         --       procedure Gen;
         --
         --       package Nested is
         --          procedure Inst is new Gen;     --  guaranteed ABE
         --       end Nested;
         --
         --       procedure Gen is
         --          ...
         --       end Gen;
         --    ...

         elsif Is_Guaranteed_ABE
                 (N           => Inst,
                  Target_Decl => Spec_Decl,
                  Target_Body => Body_Declaration (Gen_Rep))
         then
            if Elaboration_Warnings_OK (Inst_Rep) then
               Error_Msg_NE
                 ("??cannot instantiate & before body seen", Inst, Gen_Id);
               Error_Msg_N ("\Program_Error will be raised at run time", Inst);
            end if;

            --  Mark the instantiation as a guarantee ABE. This automatically
            --  suppresses the instantiation of the generic body.

            Set_Is_Known_Guaranteed_ABE (Inst);

            --  Install a run-time ABE failure because the instantiation will
            --  always result in an ABE.

            if Check_OK then
               Install_Scenario_ABE_Failure
                 (N        => Inst,
                  Targ_Id  => Gen_Id,
                  Targ_Rep => Gen_Rep,
                  Disable  => Inst_Rep);
            end if;
         end if;
      end Process_Guaranteed_ABE_Instantiation;
   end Guaranteed_ABE_Processor;

   --------------
   -- Has_Body --
   --------------

   function Has_Body (Pack_Decl : Node_Id) return Boolean is
      function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id;
      pragma Inline (Find_Corresponding_Body);
      --  Try to locate the corresponding body of spec Spec_Id. If no body is
      --  found, return Empty.

      function Find_Body
        (Spec_Id : Entity_Id;
         From    : Node_Id) return Node_Id;
      pragma Inline (Find_Body);
      --  Try to locate the corresponding body of spec Spec_Id in the node list
      --  which follows arbitrary node From. If no body is found, return Empty.

      function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id;
      pragma Inline (Load_Package_Body);
      --  Attempt to load the body of unit Unit_Nam. If the load failed, return
      --  Empty. If the compilation will not generate code, return Empty.

      -----------------------------
      -- Find_Corresponding_Body --
      -----------------------------

      function Find_Corresponding_Body (Spec_Id : Entity_Id) return Node_Id is
         Context   : constant Entity_Id := Scope (Spec_Id);
         Spec_Decl : constant Node_Id   := Unit_Declaration_Node (Spec_Id);
         Body_Decl : Node_Id;
         Body_Id   : Entity_Id;

      begin
         if Is_Compilation_Unit (Spec_Id) then
            Body_Id := Corresponding_Body (Spec_Decl);

            if Present (Body_Id) then
               return Unit_Declaration_Node (Body_Id);

            --  The package is at the library and requires a body. Load the
            --  corresponding body because the optional body may be declared
            --  there.

            elsif Unit_Requires_Body (Spec_Id) then
               return
                 Load_Package_Body
                   (Get_Body_Name (Unit_Name (Get_Source_Unit (Spec_Decl))));

            --  Otherwise there is no optional body

            else
               return Empty;
            end if;

         --  The immediate context is a package. The optional body may be
         --  within the body of that package.

         --    procedure Proc is
         --       package Nested_1 is
         --          package Nested_2 is
         --             generic
         --             package Pack is
         --             end Pack;
         --          end Nested_2;
         --       end Nested_1;

         --       package body Nested_1 is
         --          package body Nested_2 is separate;
         --       end Nested_1;

         --    separate (Proc.Nested_1.Nested_2)
         --    package body Nested_2 is
         --       package body Pack is           --  optional body
         --          ...
         --       end Pack;
         --    end Nested_2;

         elsif Is_Package_Or_Generic_Package (Context) then
            Body_Decl := Find_Corresponding_Body (Context);

            --  The optional body is within the body of the enclosing package

            if Present (Body_Decl) then
               return
                 Find_Body
                   (Spec_Id => Spec_Id,
                    From    => First (Declarations (Body_Decl)));

            --  Otherwise the enclosing package does not have a body. This may
            --  be the result of an error or a genuine lack of a body.

            else
               return Empty;
            end if;

         --  Otherwise the immediate context is a body. The optional body may
         --  be within the same list as the spec.

         --    procedure Proc is
         --       generic
         --       package Pack is
         --       end Pack;

         --       package body Pack is           --  optional body
         --          ...
         --       end Pack;

         else
            return
              Find_Body
                (Spec_Id => Spec_Id,
                 From    => Next (Spec_Decl));
         end if;
      end Find_Corresponding_Body;

      ---------------
      -- Find_Body --
      ---------------

      function Find_Body
        (Spec_Id : Entity_Id;
         From    : Node_Id) return Node_Id
      is
         Spec_Nam : constant Name_Id := Chars (Spec_Id);
         Item     : Node_Id;
         Lib_Unit : Node_Id;

      begin
         Item := From;
         while Present (Item) loop

            --  The current item denotes the optional body

            if Nkind (Item) = N_Package_Body
              and then Chars (Defining_Entity (Item)) = Spec_Nam
            then
               return Item;

            --  The current item denotes a stub, the optional body may be in
            --  the subunit.

            elsif Nkind (Item) = N_Package_Body_Stub
              and then Chars (Defining_Entity (Item)) = Spec_Nam
            then
               Lib_Unit := Library_Unit (Item);

               --  The corresponding subunit was previously loaded

               if Present (Lib_Unit) then
                  return Lib_Unit;

               --  Otherwise attempt to load the corresponding subunit

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

            Next (Item);
         end loop;

         return Empty;
      end Find_Body;

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

      function Load_Package_Body (Unit_Nam : Unit_Name_Type) return Node_Id is
         Body_Decl : Node_Id;
         Unit_Num  : Unit_Number_Type;

      begin
         --  The load is performed only when the compilation will generate code

         if Operating_Mode = Generate_Code then
            Unit_Num :=
              Load_Unit
                (Load_Name  => Unit_Nam,
                 Required   => False,
                 Subunit    => False,
                 Error_Node => Pack_Decl);

            --  The load failed most likely because the physical file is
            --  missing.

            if Unit_Num = No_Unit then
               return Empty;

            --  Otherwise the load was successful, return the body of the unit

            else
               Body_Decl := Unit (Cunit (Unit_Num));

               --  If the unit is a subunit with an available proper body,
               --  return the proper body.

               if Nkind (Body_Decl) = N_Subunit
                 and then Present (Proper_Body (Body_Decl))
               then
                  Body_Decl := Proper_Body (Body_Decl);
               end if;

               return Body_Decl;
            end if;
         end if;

         return Empty;
      end Load_Package_Body;

      --  Local variables

      Pack_Id : constant Entity_Id := Defining_Entity (Pack_Decl);

   --  Start of processing for Has_Body

   begin
      --  The body is available

      if Present (Corresponding_Body (Pack_Decl)) then
         return True;

      --  The body is required if the package spec contains a construct which
      --  requires a completion in a body.

      elsif Unit_Requires_Body (Pack_Id) then
         return True;

      --  The body may be optional

      else
         return Present (Find_Corresponding_Body (Pack_Id));
      end if;
   end Has_Body;

   ----------
   -- Hash --
   ----------

   function Hash (NE : Node_Or_Entity_Id) return Bucket_Range_Type is
      pragma Assert (Present (NE));
   begin
      return Bucket_Range_Type (NE);
   end Hash;

   --------------------------
   -- In_External_Instance --
   --------------------------

   function In_External_Instance
     (N           : Node_Id;
      Target_Decl : Node_Id) return Boolean
   is
      Inst      : Node_Id;
      Inst_Body : Node_Id;
      Inst_Spec : Node_Id;

   begin
      Inst := Find_Enclosing_Instance (Target_Decl);

      --  The target declaration appears within an instance spec. Visibility is
      --  ignored because internally generated primitives for private types may
      --  reside in the private declarations and still be invoked from outside.

      if Present (Inst) and then Nkind (Inst) = N_Package_Declaration then

         --  The scenario comes from the main unit and the instance does not

         if In_Extended_Main_Code_Unit (N)
           and then not In_Extended_Main_Code_Unit (Inst)
         then
            return True;

         --  Otherwise the scenario must not appear within the instance spec or
         --  body.

         else
            Spec_And_Body_From_Node
              (N         => Inst,
               Spec_Decl => Inst_Spec,
               Body_Decl => Inst_Body);

            return not In_Subtree
                         (N     => N,
                          Root1 => Inst_Spec,
                          Root2 => Inst_Body);
         end if;
      end if;

      return False;
   end In_External_Instance;

   ---------------------
   -- In_Main_Context --
   ---------------------

   function In_Main_Context (N : Node_Id) return Boolean is
   begin
      --  Scenarios outside the main unit are not considered because the ALI
      --  information supplied to binde is for the main unit only.

      if not In_Extended_Main_Code_Unit (N) then
         return False;

      --  Scenarios within internal units are not considered unless switch
      --  -gnatdE (elaboration checks on predefined units) is in effect.

      elsif not Debug_Flag_EE and then In_Internal_Unit (N) then
         return False;
      end if;

      return True;
   end In_Main_Context;

   ---------------------
   -- In_Same_Context --
   ---------------------

   function In_Same_Context
     (N1        : Node_Id;
      N2        : Node_Id;
      Nested_OK : Boolean := False) return Boolean
   is
      function Find_Enclosing_Context (N : Node_Id) return Node_Id;
      pragma Inline (Find_Enclosing_Context);
      --  Return the nearest enclosing non-library-level or compilation unit
      --  node which encapsulates arbitrary node N. Return Empty is no such
      --  context is available.

      function In_Nested_Context
        (Outer : Node_Id;
         Inner : Node_Id) return Boolean;
      pragma Inline (In_Nested_Context);
      --  Determine whether arbitrary node Outer encapsulates arbitrary node
      --  Inner.

      ----------------------------
      -- Find_Enclosing_Context --
      ----------------------------

      function Find_Enclosing_Context (N : Node_Id) return Node_Id is
         Context : Node_Id;
         Par     : Node_Id;

      begin
         Par := Parent (N);
         while Present (Par) loop

            --  A traversal from a subunit continues via the corresponding stub

            if Nkind (Par) = N_Subunit then
               Par := Corresponding_Stub (Par);

            --  Stop the traversal when the nearest enclosing non-library-level
            --  encapsulator has been reached.

            elsif Is_Non_Library_Level_Encapsulator (Par) then
               Context := Parent (Par);

               --  The sole exception is when the encapsulator is the unit of
               --  compilation because this case requires special processing
               --  (see below).

               if Present (Context)
                 and then Nkind (Context) = N_Compilation_Unit
               then
                  null;

               else
                  return Par;
               end if;

            --  Reaching a compilation unit node without hitting a non-library-
            --  level encapsulator indicates that N is at the library level in
            --  which case the compilation unit is the context.

            elsif Nkind (Par) = N_Compilation_Unit then
               return Par;
            end if;

            Par := Parent (Par);
         end loop;

         return Empty;
      end Find_Enclosing_Context;

      -----------------------
      -- In_Nested_Context --
      -----------------------

      function In_Nested_Context
        (Outer : Node_Id;
         Inner : Node_Id) return Boolean
      is
         Par : Node_Id;

      begin
         Par := Inner;
         while Present (Par) loop

            --  A traversal from a subunit continues via the corresponding stub

            if Nkind (Par) = N_Subunit then
               Par := Corresponding_Stub (Par);

            elsif Par = Outer then
               return True;
            end if;

            Par := Parent (Par);
         end loop;

         return False;
      end In_Nested_Context;

      --  Local variables

      Context_1 : constant Node_Id := Find_Enclosing_Context (N1);
      Context_2 : constant Node_Id := Find_Enclosing_Context (N2);

   --  Start of processing for In_Same_Context

   begin
      --  Both nodes appear within the same context

      if Context_1 = Context_2 then
         return True;

      --  Both nodes appear in compilation units. Determine whether one unit
      --  is the body of the other.

      elsif Nkind (Context_1) = N_Compilation_Unit
        and then Nkind (Context_2) = N_Compilation_Unit
      then
         return
           Is_Same_Unit
             (Unit_1 => Defining_Entity (Unit (Context_1)),
              Unit_2 => Defining_Entity (Unit (Context_2)));

      --  The context of N1 encloses the context of N2

      elsif Nested_OK and then In_Nested_Context (Context_1, Context_2) then
         return True;
      end if;

      return False;
   end In_Same_Context;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      --  Set the soft link which enables Atree.Rewrite to update a scenario
      --  each time it is transformed into another node.

      Set_Rewriting_Proc (Update_Elaboration_Scenario'Access);

      --  Create all internal data structures and activate the elaboration
      --  phase of the compiler.

      Initialize_All_Data_Structures;
      Set_Elaboration_Phase (Active);
   end Initialize;

   ------------------------------------
   -- Initialize_All_Data_Structures --
   ------------------------------------

   procedure Initialize_All_Data_Structures is
   begin
      Initialize_Body_Processor;
      Initialize_Early_Call_Region_Processor;
      Initialize_Elaborated_Units;
      Initialize_Internal_Representation;
      Initialize_Invocation_Graph;
      Initialize_Scenario_Storage;
   end Initialize_All_Data_Structures;

   --------------------------
   -- Instantiated_Generic --
   --------------------------

   function Instantiated_Generic (Inst : Node_Id) return Entity_Id is
   begin
      --  Traverse a possible chain of renamings to obtain the original generic
      --  being instantiatied.

      return Get_Renamed_Entity (Entity (Name (Inst)));
   end Instantiated_Generic;

   -----------------------------
   -- Internal_Representation --
   -----------------------------

   package body Internal_Representation is

      -----------
      -- Types --
      -----------

      --  The following type represents the contents of a scenario

      type Scenario_Rep_Record is record
         Elab_Checks_OK : Boolean := False;
         --  The status of elaboration checks for the scenario

         Elab_Warnings_OK : Boolean := False;
         --  The status of elaboration warnings for the scenario

         GM : Extended_Ghost_Mode := Is_Checked_Or_Not_Specified;
         --  The Ghost mode of the scenario

         Kind : Scenario_Kind := No_Scenario;
         --  The nature of the scenario

         Level : Enclosing_Level_Kind := No_Level;
         --  The enclosing level where the scenario resides

         SM : Extended_SPARK_Mode := Is_Off_Or_Not_Specified;
         --  The SPARK mode of the scenario

         Target : Entity_Id := Empty;
         --  The target of the scenario

         --  The following attributes are multiplexed and depend on the Kind of
         --  the scenario. They are mapped as follows:
         --
         --    Call_Scenario
         --      Is_Dispatching_Call (Flag_1)
         --
         --    Task_Activation_Scenario
         --      Activated_Task_Objects (List_1)
         --      Activated_Task_Type (Field_1)
         --
         --    Variable_Reference
         --      Is_Read_Reference (Flag_1)

         Flag_1  : Boolean                    := False;
         Field_1 : Node_Or_Entity_Id          := Empty;
         List_1  : NE_List.Doubly_Linked_List := NE_List.Nil;
      end record;

      --  The following type represents the contents of a target

      type Target_Rep_Record is record
         Body_Decl : Node_Id := Empty;
         --  The declaration of the target body

         Elab_Checks_OK : Boolean := False;
         --  The status of elaboration checks for the target

         Elab_Warnings_OK : Boolean := False;
         --  The status of elaboration warnings for the target

         GM : Extended_Ghost_Mode := Is_Checked_Or_Not_Specified;
         --  The Ghost mode of the target

         Kind : Target_Kind := No_Target;
         --  The nature of the target

         SM : Extended_SPARK_Mode := Is_Off_Or_Not_Specified;
         --  The SPARK mode of the target

         Spec_Decl : Node_Id := Empty;
         --  The declaration of the target spec

         Unit : Entity_Id := Empty;
         --  The top unit where the target is declared

         Version : Representation_Kind := No_Representation;
         --  The version of the target representation

         --  The following attributes are multiplexed and depend on the Kind of
         --  the target. They are mapped as follows:
         --
         --    Subprogram_Target
         --      Barrier_Body_Declaration (Field_1)
         --
         --    Variable_Target
         --      Variable_Declaration (Field_1)

         Field_1 : Node_Or_Entity_Id := Empty;
      end record;

      ---------------------
      -- Data structures --
      ---------------------

      procedure Destroy (T_Id : in out Target_Rep_Id);
      --  Destroy a target representation T_Id

      package ETT_Map is new Dynamic_Hash_Tables
        (Key_Type              => Entity_Id,
         Value_Type            => Target_Rep_Id,
         No_Value              => No_Target_Rep,
         Expansion_Threshold   => 1.5,
         Expansion_Factor      => 2,
         Compression_Threshold => 0.3,
         Compression_Factor    => 2,
         "="                   => "=",
         Destroy_Value         => Destroy,
         Hash                  => Hash);

      --  The following map relates target representations to entities

      Entity_To_Target_Map : ETT_Map.Dynamic_Hash_Table := ETT_Map.Nil;

      procedure Destroy (S_Id : in out Scenario_Rep_Id);
      --  Destroy a scenario representation S_Id

      package NTS_Map is new Dynamic_Hash_Tables
        (Key_Type              => Node_Id,
         Value_Type            => Scenario_Rep_Id,
         No_Value              => No_Scenario_Rep,
         Expansion_Threshold   => 1.5,
         Expansion_Factor      => 2,
         Compression_Threshold => 0.3,
         Compression_Factor    => 2,
         "="                   => "=",
         Destroy_Value         => Destroy,
         Hash                  => Hash);

      --  The following map relates scenario representations to nodes

      Node_To_Scenario_Map : NTS_Map.Dynamic_Hash_Table := NTS_Map.Nil;

      --  The following table stores all scenario representations

      package Scenario_Reps is new Table.Table
        (Table_Index_Type     => Scenario_Rep_Id,
         Table_Component_Type => Scenario_Rep_Record,
         Table_Low_Bound      => First_Scenario_Rep,
         Table_Initial        => 1000,
         Table_Increment      => 200,
         Table_Name           => "Scenario_Reps");

      --  The following table stores all target representations

      package Target_Reps is new Table.Table
        (Table_Index_Type     => Target_Rep_Id,
         Table_Component_Type => Target_Rep_Record,
         Table_Low_Bound      => First_Target_Rep,
         Table_Initial        => 1000,
         Table_Increment      => 200,
         Table_Name           => "Target_Reps");

      --------------
      -- Builders --
      --------------

      function Create_Access_Taken_Rep
        (Attr : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Access_Taken_Rep);
      --  Create the representation of 'Access attribute Attr

      function Create_Call_Or_Task_Activation_Rep
        (Call : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Call_Or_Task_Activation_Rep);
      --  Create the representation of call or task activation Call

      function Create_Derived_Type_Rep
        (Typ_Decl : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Derived_Type_Rep);
      --  Create the representation of a derived type described by declaration
      --  Typ_Decl.

      function Create_Generic_Rep
        (Gen_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Generic_Rep);
      --  Create the representation of generic Gen_Id

      function Create_Instantiation_Rep
        (Inst : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Instantiation_Rep);
      --  Create the representation of instantiation Inst

      function Create_Package_Rep
        (Pack_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Package_Rep);
      --  Create the representation of package Pack_Id

      function Create_Protected_Entry_Rep
        (PE_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Protected_Entry_Rep);
      --  Create the representation of protected entry PE_Id

      function Create_Protected_Subprogram_Rep
        (PS_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Protected_Subprogram_Rep);
      --  Create the representation of protected subprogram PS_Id

      function Create_Refined_State_Pragma_Rep
        (Prag : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Refined_State_Pragma_Rep);
      --  Create the representation of Refined_State pragma Prag

      function Create_Scenario_Rep
        (N        : Node_Id;
         In_State : Processing_In_State) return Scenario_Rep_Record;
      pragma Inline (Create_Scenario_Rep);
      --  Top level dispatcher. Create the representation of elaboration
      --  scenario N. In_State is the current state of the Processing phase.

      function Create_Subprogram_Rep
        (Subp_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Subprogram_Rep);
      --  Create the representation of entry, operator, or subprogram Subp_Id

      function Create_Target_Rep
        (Id       : Entity_Id;
         In_State : Processing_In_State) return Target_Rep_Record;
      pragma Inline (Create_Target_Rep);
      --  Top level dispatcher. Create the representation of elaboration target
      --  Id. In_State is the current state of the Processing phase.

      function Create_Task_Entry_Rep
        (TE_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Task_Entry_Rep);
      --  Create the representation of task entry TE_Id

      function Create_Task_Rep (Task_Typ : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Task_Rep);
      --  Create the representation of task type Typ

      function Create_Variable_Assignment_Rep
        (Asmt : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Variable_Assignment_Rep);
      --  Create the representation of variable assignment Asmt

      function Create_Variable_Reference_Rep
        (Ref : Node_Id) return Scenario_Rep_Record;
      pragma Inline (Create_Variable_Reference_Rep);
      --  Create the representation of variable reference Ref

      function Create_Variable_Rep
        (Var_Id : Entity_Id) return Target_Rep_Record;
      pragma Inline (Create_Variable_Rep);
      --  Create the representation of variable Var_Id

      -----------------------
      -- Local subprograms --
      -----------------------

      function Ghost_Mode_Of_Entity
        (Id : Entity_Id) return Extended_Ghost_Mode;
      pragma Inline (Ghost_Mode_Of_Entity);
      --  Obtain the extended Ghost mode of arbitrary entity Id

      function Ghost_Mode_Of_Node (N : Node_Id) return Extended_Ghost_Mode;
      pragma Inline (Ghost_Mode_Of_Node);
      --  Obtain the extended Ghost mode of arbitrary node N

      function Present (S_Id : Scenario_Rep_Id) return Boolean;
      pragma Inline (Present);
      --  Determine whether scenario representation S_Id exists

      function Present (T_Id : Target_Rep_Id) return Boolean;
      pragma Inline (Present);
      --  Determine whether target representation T_Id exists

      function SPARK_Mode_Of_Entity
        (Id : Entity_Id) return Extended_SPARK_Mode;
      pragma Inline (SPARK_Mode_Of_Entity);
      --  Obtain the extended SPARK mode of arbitrary entity Id

      function SPARK_Mode_Of_Node (N : Node_Id) return Extended_SPARK_Mode;
      pragma Inline (SPARK_Mode_Of_Node);
      --  Obtain the extended SPARK mode of arbitrary node N

      function To_Ghost_Mode
        (Ignored_Status : Boolean) return Extended_Ghost_Mode;
      pragma Inline (To_Ghost_Mode);
      --  Convert a Ghost mode indicated by Ignored_Status into its extended
      --  equivalent.

      function To_SPARK_Mode (On_Status : Boolean) return Extended_SPARK_Mode;
      pragma Inline (To_SPARK_Mode);
      --  Convert a SPARK mode indicated by On_Status into its extended
      --  equivalent.

      function Version (T_Id : Target_Rep_Id) return Representation_Kind;
      pragma Inline (Version);
      --  Obtain the version of target representation T_Id

      ----------------------------
      -- Activated_Task_Objects --
      ----------------------------

      function Activated_Task_Objects
        (S_Id : Scenario_Rep_Id) return NE_List.Doubly_Linked_List
      is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Task_Activation_Scenario);

      begin
         return Scenario_Reps.Table (S_Id).List_1;
      end Activated_Task_Objects;

      -------------------------
      -- Activated_Task_Type --
      -------------------------

      function Activated_Task_Type
        (S_Id : Scenario_Rep_Id) return Entity_Id
      is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Task_Activation_Scenario);

      begin
         return Scenario_Reps.Table (S_Id).Field_1;
      end Activated_Task_Type;

      ------------------------------
      -- Barrier_Body_Declaration --
      ------------------------------

      function Barrier_Body_Declaration
        (T_Id : Target_Rep_Id) return Node_Id
      is
         pragma Assert (Present (T_Id));
         pragma Assert (Kind (T_Id) = Subprogram_Target);

      begin
         return Target_Reps.Table (T_Id).Field_1;
      end Barrier_Body_Declaration;

      ----------------------
      -- Body_Declaration --
      ----------------------

      function Body_Declaration (T_Id : Target_Rep_Id) return Node_Id is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Body_Decl;
      end Body_Declaration;

      -----------------------------
      -- Create_Access_Taken_Rep --
      -----------------------------

      function Create_Access_Taken_Rep
        (Attr : Node_Id) return Scenario_Rep_Record
      is
         Rec : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Node (Attr);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Attr);
         Rec.GM               := Is_Checked_Or_Not_Specified;
         Rec.SM               := SPARK_Mode_Of_Node (Attr);
         Rec.Kind             := Access_Taken_Scenario;
         Rec.Target           := Canonical_Subprogram (Entity (Prefix (Attr)));

         return Rec;
      end Create_Access_Taken_Rep;

      ----------------------------------------
      -- Create_Call_Or_Task_Activation_Rep --
      ----------------------------------------

      function Create_Call_Or_Task_Activation_Rep
        (Call : Node_Id) return Scenario_Rep_Record
      is
         Subp_Id : constant Entity_Id := Canonical_Subprogram (Target (Call));
         Kind    : Scenario_Kind;
         Rec     : Scenario_Rep_Record;

      begin
         if Is_Activation_Proc (Subp_Id) then
            Kind := Task_Activation_Scenario;
         else
            Kind := Call_Scenario;
         end if;

         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Node (Call);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Call);
         Rec.GM               := Ghost_Mode_Of_Node (Call);
         Rec.SM               := SPARK_Mode_Of_Node (Call);
         Rec.Kind             := Kind;
         Rec.Target           := Subp_Id;

         --  Scenario-specific attributes

         Rec.Flag_1 := Is_Dispatching_Call (Call);  --  Dispatching_Call

         return Rec;
      end Create_Call_Or_Task_Activation_Rep;

      -----------------------------
      -- Create_Derived_Type_Rep --
      -----------------------------

      function Create_Derived_Type_Rep
        (Typ_Decl : Node_Id) return Scenario_Rep_Record
      is
         Typ : constant Entity_Id := Defining_Entity (Typ_Decl);
         Rec : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := False;  --  not relevant
         Rec.Elab_Warnings_OK := False;  --  not relevant
         Rec.GM               := Ghost_Mode_Of_Entity (Typ);
         Rec.SM               := SPARK_Mode_Of_Entity (Typ);
         Rec.Kind             := Derived_Type_Scenario;
         Rec.Target           := Typ;

         return Rec;
      end Create_Derived_Type_Rep;

      ------------------------
      -- Create_Generic_Rep --
      ------------------------

      function Create_Generic_Rep
        (Gen_Id : Entity_Id) return Target_Rep_Record
      is
         Rec : Target_Rep_Record;

      begin
         Rec.Kind := Generic_Target;

         Spec_And_Body_From_Entity
           (Id        => Gen_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Generic_Rep;

      ------------------------------
      -- Create_Instantiation_Rep --
      ------------------------------

      function Create_Instantiation_Rep
        (Inst : Node_Id) return Scenario_Rep_Record
      is
         Rec : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Node (Inst);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Inst);
         Rec.GM               := Ghost_Mode_Of_Node (Inst);
         Rec.SM               := SPARK_Mode_Of_Node (Inst);
         Rec.Kind             := Instantiation_Scenario;
         Rec.Target           := Instantiated_Generic (Inst);

         return Rec;
      end Create_Instantiation_Rep;

      ------------------------
      -- Create_Package_Rep --
      ------------------------

      function Create_Package_Rep
        (Pack_Id : Entity_Id) return Target_Rep_Record
      is
         Rec : Target_Rep_Record;

      begin
         Rec.Kind := Package_Target;

         Spec_And_Body_From_Entity
           (Id        => Pack_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Package_Rep;

      --------------------------------
      -- Create_Protected_Entry_Rep --
      --------------------------------

      function Create_Protected_Entry_Rep
        (PE_Id : Entity_Id) return Target_Rep_Record
      is
         Prot_Id : constant Entity_Id := Protected_Body_Subprogram (PE_Id);

         Barf_Id : Entity_Id;
         Dummy   : Node_Id;
         Rec     : Target_Rep_Record;
         Spec_Id : Entity_Id;

      begin
         --  When the entry [family] has already been expanded, it carries both
         --  the procedure which emulates the behavior of the entry [family] as
         --  well as the barrier function.

         if Present (Prot_Id) then
            Barf_Id := Barrier_Function (PE_Id);
            Spec_Id := Prot_Id;

         --  Otherwise no expansion took place

         else
            Barf_Id := Empty;
            Spec_Id := PE_Id;
         end if;

         Rec.Kind := Subprogram_Target;

         Spec_And_Body_From_Entity
           (Id        => Spec_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         --  Target-specific attributes

         if Present (Barf_Id) then
            Spec_And_Body_From_Entity
              (Id        => Barf_Id,
               Body_Decl => Rec.Field_1,  --  Barrier_Body_Declaration
               Spec_Decl => Dummy);
         end if;

         return Rec;
      end Create_Protected_Entry_Rep;

      -------------------------------------
      -- Create_Protected_Subprogram_Rep --
      -------------------------------------

      function Create_Protected_Subprogram_Rep
        (PS_Id : Entity_Id) return Target_Rep_Record
      is
         Prot_Id : constant Entity_Id := Protected_Body_Subprogram (PS_Id);
         Rec     : Target_Rep_Record;
         Spec_Id : Entity_Id;

      begin
         --  When the protected subprogram has already been expanded, it
         --  carries the subprogram which seizes the lock and invokes the
         --  original statements.

         if Present (Prot_Id) then
            Spec_Id := Prot_Id;

         --  Otherwise no expansion took place

         else
            Spec_Id := PS_Id;
         end if;

         Rec.Kind := Subprogram_Target;

         Spec_And_Body_From_Entity
           (Id        => Spec_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Protected_Subprogram_Rep;

      -------------------------------------
      -- Create_Refined_State_Pragma_Rep --
      -------------------------------------

      function Create_Refined_State_Pragma_Rep
        (Prag : Node_Id) return Scenario_Rep_Record
      is
         Rec : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := False;  --  not relevant
         Rec.Elab_Warnings_OK := False;  --  not relevant
         Rec.GM               :=
           To_Ghost_Mode (Is_Ignored_Ghost_Pragma (Prag));
         Rec.SM               := Is_Off_Or_Not_Specified;
         Rec.Kind             := Refined_State_Pragma_Scenario;
         Rec.Target           := Empty;

         return Rec;
      end Create_Refined_State_Pragma_Rep;

      -------------------------
      -- Create_Scenario_Rep --
      -------------------------

      function Create_Scenario_Rep
        (N        : Node_Id;
         In_State : Processing_In_State) return Scenario_Rep_Record
      is
         pragma Unreferenced (In_State);

         Rec : Scenario_Rep_Record;

      begin
         if Is_Suitable_Access_Taken (N) then
            Rec := Create_Access_Taken_Rep (N);

         elsif Is_Suitable_Call (N) then
            Rec := Create_Call_Or_Task_Activation_Rep (N);

         elsif Is_Suitable_Instantiation (N) then
            Rec := Create_Instantiation_Rep (N);

         elsif Is_Suitable_SPARK_Derived_Type (N) then
            Rec := Create_Derived_Type_Rep (N);

         elsif Is_Suitable_SPARK_Refined_State_Pragma (N) then
            Rec := Create_Refined_State_Pragma_Rep (N);

         elsif Is_Suitable_Variable_Assignment (N) then
            Rec := Create_Variable_Assignment_Rep (N);

         elsif Is_Suitable_Variable_Reference (N) then
            Rec := Create_Variable_Reference_Rep (N);

         else
            pragma Assert (False);
            return Rec;
         end if;

         --  Common scenario attributes

         Rec.Level := Find_Enclosing_Level (N);

         return Rec;
      end Create_Scenario_Rep;

      ---------------------------
      -- Create_Subprogram_Rep --
      ---------------------------

      function Create_Subprogram_Rep
        (Subp_Id : Entity_Id) return Target_Rep_Record
      is
         Rec     : Target_Rep_Record;
         Spec_Id : Entity_Id;

      begin
         Spec_Id := Subp_Id;

         --  The elaboration target denotes an internal function that returns a
         --  constrained array type in a SPARK-to-C compilation. In this case
         --  the function receives a corresponding procedure which has an out
         --  parameter. The proper body for ABE checks and diagnostics is that
         --  of the procedure.

         if Ekind (Spec_Id) = E_Function
           and then Rewritten_For_C (Spec_Id)
         then
            Spec_Id := Corresponding_Procedure (Spec_Id);
         end if;

         Rec.Kind := Subprogram_Target;

         Spec_And_Body_From_Entity
           (Id        => Spec_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Subprogram_Rep;

      -----------------------
      -- Create_Target_Rep --
      -----------------------

      function Create_Target_Rep
        (Id       : Entity_Id;
         In_State : Processing_In_State) return Target_Rep_Record
      is
         Rec : Target_Rep_Record;

      begin
         if Is_Generic_Unit (Id) then
            Rec := Create_Generic_Rep (Id);

         elsif Is_Protected_Entry (Id) then
            Rec := Create_Protected_Entry_Rep (Id);

         elsif Is_Protected_Subp (Id) then
            Rec := Create_Protected_Subprogram_Rep (Id);

         elsif Is_Task_Entry (Id) then
            Rec := Create_Task_Entry_Rep (Id);

         elsif Is_Task_Type (Id) then
            Rec := Create_Task_Rep (Id);

         elsif Ekind (Id) in E_Constant | E_Variable then
            Rec := Create_Variable_Rep (Id);

         elsif Ekind (Id) in E_Entry | E_Function | E_Operator | E_Procedure
         then
            Rec := Create_Subprogram_Rep (Id);

         elsif Ekind (Id) = E_Package then
            Rec := Create_Package_Rep (Id);

         else
            pragma Assert (False);
            return Rec;
         end if;

         --  Common target attributes

         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Id (Id);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Id (Id);
         Rec.GM               := Ghost_Mode_Of_Entity (Id);
         Rec.SM               := SPARK_Mode_Of_Entity (Id);
         Rec.Unit             := Find_Top_Unit (Id);
         Rec.Version          := In_State.Representation;

         return Rec;
      end Create_Target_Rep;

      ---------------------------
      -- Create_Task_Entry_Rep --
      ---------------------------

      function Create_Task_Entry_Rep
        (TE_Id : Entity_Id) return Target_Rep_Record
      is
         Task_Typ     : constant Entity_Id := Non_Private_View (Scope (TE_Id));
         Task_Body_Id : constant Entity_Id := Task_Body_Procedure (Task_Typ);

         Rec     : Target_Rep_Record;
         Spec_Id : Entity_Id;

      begin
         --  The task type has already been expanded, it carries the procedure
         --  which emulates the behavior of the task body.

         if Present (Task_Body_Id) then
            Spec_Id := Task_Body_Id;

         --  Otherwise no expansion took place

         else
            Spec_Id := TE_Id;
         end if;

         Rec.Kind := Subprogram_Target;

         Spec_And_Body_From_Entity
           (Id        => Spec_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Task_Entry_Rep;

      ---------------------
      -- Create_Task_Rep --
      ---------------------

      function Create_Task_Rep
        (Task_Typ : Entity_Id) return Target_Rep_Record
      is
         Task_Body_Id : constant Entity_Id := Task_Body_Procedure (Task_Typ);

         Rec     : Target_Rep_Record;
         Spec_Id : Entity_Id;

      begin
         --  The task type has already been expanded, it carries the procedure
         --  which emulates the behavior of the task body.

         if Present (Task_Body_Id) then
            Spec_Id := Task_Body_Id;

         --  Otherwise no expansion took place

         else
            Spec_Id := Task_Typ;
         end if;

         Rec.Kind := Task_Target;

         Spec_And_Body_From_Entity
           (Id        => Spec_Id,
            Body_Decl => Rec.Body_Decl,
            Spec_Decl => Rec.Spec_Decl);

         return Rec;
      end Create_Task_Rep;

      ------------------------------------
      -- Create_Variable_Assignment_Rep --
      ------------------------------------

      function Create_Variable_Assignment_Rep
        (Asmt : Node_Id) return Scenario_Rep_Record
      is
         Var_Id : constant Entity_Id := Entity (Assignment_Target (Asmt));
         Rec    : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Node (Asmt);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Id (Var_Id);
         Rec.GM               := Ghost_Mode_Of_Node (Asmt);
         Rec.SM               := SPARK_Mode_Of_Node (Asmt);
         Rec.Kind             := Variable_Assignment_Scenario;
         Rec.Target           := Var_Id;

         return Rec;
      end Create_Variable_Assignment_Rep;

      -----------------------------------
      -- Create_Variable_Reference_Rep --
      -----------------------------------

      function Create_Variable_Reference_Rep
        (Ref : Node_Id) return Scenario_Rep_Record
      is
         Rec : Scenario_Rep_Record;

      begin
         Rec.Elab_Checks_OK   := Is_Elaboration_Checks_OK_Node (Ref);
         Rec.Elab_Warnings_OK := Is_Elaboration_Warnings_OK_Node (Ref);
         Rec.GM               := Ghost_Mode_Of_Node (Ref);
         Rec.SM               := SPARK_Mode_Of_Node (Ref);
         Rec.Kind             := Variable_Reference_Scenario;
         Rec.Target           := Target (Ref);

         --  Scenario-specific attributes

         Rec.Flag_1 := Is_Read (Ref);  --  Is_Read_Reference

         return Rec;
      end Create_Variable_Reference_Rep;

      -------------------------
      -- Create_Variable_Rep --
      -------------------------

      function Create_Variable_Rep
        (Var_Id : Entity_Id) return Target_Rep_Record
      is
         Rec : Target_Rep_Record;

      begin
         Rec.Kind := Variable_Target;

         --  Target-specific attributes

         Rec.Field_1 := Declaration_Node (Var_Id);  --  Variable_Declaration

         return Rec;
      end Create_Variable_Rep;

      -------------
      -- Destroy --
      -------------

      procedure Destroy (S_Id : in out Scenario_Rep_Id) is
         pragma Unreferenced (S_Id);
      begin
         null;
      end Destroy;

      -------------
      -- Destroy --
      -------------

      procedure Destroy (T_Id : in out Target_Rep_Id) is
         pragma Unreferenced (T_Id);
      begin
         null;
      end Destroy;

      --------------------------------
      -- Disable_Elaboration_Checks --
      --------------------------------

      procedure Disable_Elaboration_Checks (S_Id : Scenario_Rep_Id) is
         pragma Assert (Present (S_Id));
      begin
         Scenario_Reps.Table (S_Id).Elab_Checks_OK := False;
      end Disable_Elaboration_Checks;

      --------------------------------
      -- Disable_Elaboration_Checks --
      --------------------------------

      procedure Disable_Elaboration_Checks (T_Id : Target_Rep_Id) is
         pragma Assert (Present (T_Id));
      begin
         Target_Reps.Table (T_Id).Elab_Checks_OK := False;
      end Disable_Elaboration_Checks;

      ---------------------------
      -- Elaboration_Checks_OK --
      ---------------------------

      function Elaboration_Checks_OK (S_Id : Scenario_Rep_Id) return Boolean is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).Elab_Checks_OK;
      end Elaboration_Checks_OK;

      ---------------------------
      -- Elaboration_Checks_OK --
      ---------------------------

      function Elaboration_Checks_OK (T_Id : Target_Rep_Id) return Boolean is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Elab_Checks_OK;
      end Elaboration_Checks_OK;

      -----------------------------
      -- Elaboration_Warnings_OK --
      -----------------------------

      function Elaboration_Warnings_OK
        (S_Id : Scenario_Rep_Id) return Boolean
      is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).Elab_Warnings_OK;
      end Elaboration_Warnings_OK;

      -----------------------------
      -- Elaboration_Warnings_OK --
      -----------------------------

      function Elaboration_Warnings_OK (T_Id : Target_Rep_Id) return Boolean is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Elab_Warnings_OK;
      end Elaboration_Warnings_OK;

      --------------------------------------
      -- Finalize_Internal_Representation --
      --------------------------------------

      procedure Finalize_Internal_Representation is
      begin
         ETT_Map.Destroy (Entity_To_Target_Map);
         NTS_Map.Destroy (Node_To_Scenario_Map);
      end Finalize_Internal_Representation;

      -------------------
      -- Ghost_Mode_Of --
      -------------------

      function Ghost_Mode_Of
        (S_Id : Scenario_Rep_Id) return Extended_Ghost_Mode
      is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).GM;
      end Ghost_Mode_Of;

      -------------------
      -- Ghost_Mode_Of --
      -------------------

      function Ghost_Mode_Of
        (T_Id : Target_Rep_Id) return Extended_Ghost_Mode
      is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).GM;
      end Ghost_Mode_Of;

      --------------------------
      -- Ghost_Mode_Of_Entity --
      --------------------------

      function Ghost_Mode_Of_Entity
        (Id : Entity_Id) return Extended_Ghost_Mode
      is
      begin
         return To_Ghost_Mode (Is_Ignored_Ghost_Entity (Id));
      end Ghost_Mode_Of_Entity;

      ------------------------
      -- Ghost_Mode_Of_Node --
      ------------------------

      function Ghost_Mode_Of_Node (N : Node_Id) return Extended_Ghost_Mode is
      begin
         return To_Ghost_Mode (Is_Ignored_Ghost_Node (N));
      end Ghost_Mode_Of_Node;

      ----------------------------------------
      -- Initialize_Internal_Representation --
      ----------------------------------------

      procedure Initialize_Internal_Representation is
      begin
         Entity_To_Target_Map := ETT_Map.Create (500);
         Node_To_Scenario_Map := NTS_Map.Create (500);
      end Initialize_Internal_Representation;

      -------------------------
      -- Is_Dispatching_Call --
      -------------------------

      function Is_Dispatching_Call (S_Id : Scenario_Rep_Id) return Boolean is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Call_Scenario);

      begin
         return Scenario_Reps.Table (S_Id).Flag_1;
      end Is_Dispatching_Call;

      -----------------------
      -- Is_Read_Reference --
      -----------------------

      function Is_Read_Reference (S_Id : Scenario_Rep_Id) return Boolean is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Variable_Reference_Scenario);

      begin
         return Scenario_Reps.Table (S_Id).Flag_1;
      end Is_Read_Reference;

      ----------
      -- Kind --
      ----------

      function Kind (S_Id : Scenario_Rep_Id) return Scenario_Kind is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).Kind;
      end Kind;

      ----------
      -- Kind --
      ----------

      function Kind (T_Id : Target_Rep_Id) return Target_Kind is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Kind;
      end Kind;

      -----------
      -- Level --
      -----------

      function Level (S_Id : Scenario_Rep_Id) return Enclosing_Level_Kind is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).Level;
      end Level;

      -------------
      -- Present --
      -------------

      function Present (S_Id : Scenario_Rep_Id) return Boolean is
      begin
         return S_Id /= No_Scenario_Rep;
      end Present;

      -------------
      -- Present --
      -------------

      function Present (T_Id : Target_Rep_Id) return Boolean is
      begin
         return T_Id /= No_Target_Rep;
      end Present;

      --------------------------------
      -- Scenario_Representation_Of --
      --------------------------------

      function Scenario_Representation_Of
        (N        : Node_Id;
         In_State : Processing_In_State) return Scenario_Rep_Id
      is
         S_Id : Scenario_Rep_Id;

      begin
         S_Id := NTS_Map.Get (Node_To_Scenario_Map, N);

         --  The elaboration scenario lacks a representation. This indicates
         --  that the scenario is encountered for the first time. Create the
         --  representation of it.

         if not Present (S_Id) then
            Scenario_Reps.Append (Create_Scenario_Rep (N, In_State));
            S_Id := Scenario_Reps.Last;

            --  Associate the internal representation with the elaboration
            --  scenario.

            NTS_Map.Put (Node_To_Scenario_Map, N, S_Id);
         end if;

         pragma Assert (Present (S_Id));

         return S_Id;
      end Scenario_Representation_Of;

      --------------------------------
      -- Set_Activated_Task_Objects --
      --------------------------------

      procedure Set_Activated_Task_Objects
        (S_Id      : Scenario_Rep_Id;
         Task_Objs : NE_List.Doubly_Linked_List)
      is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Task_Activation_Scenario);

      begin
         Scenario_Reps.Table (S_Id).List_1 := Task_Objs;
      end Set_Activated_Task_Objects;

      -----------------------------
      -- Set_Activated_Task_Type --
      -----------------------------

      procedure Set_Activated_Task_Type
        (S_Id     : Scenario_Rep_Id;
         Task_Typ : Entity_Id)
      is
         pragma Assert (Present (S_Id));
         pragma Assert (Kind (S_Id) = Task_Activation_Scenario);

      begin
         Scenario_Reps.Table (S_Id).Field_1 := Task_Typ;
      end Set_Activated_Task_Type;

      -------------------
      -- SPARK_Mode_Of --
      -------------------

      function SPARK_Mode_Of
        (S_Id : Scenario_Rep_Id) return Extended_SPARK_Mode
      is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).SM;
      end SPARK_Mode_Of;

      -------------------
      -- SPARK_Mode_Of --
      -------------------

      function SPARK_Mode_Of
        (T_Id : Target_Rep_Id) return Extended_SPARK_Mode
      is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).SM;
      end SPARK_Mode_Of;

      --------------------------
      -- SPARK_Mode_Of_Entity --
      --------------------------

      function SPARK_Mode_Of_Entity
        (Id : Entity_Id) return Extended_SPARK_Mode
      is
         Prag : constant Node_Id := SPARK_Pragma (Id);

      begin
         return
           To_SPARK_Mode
             (Present (Prag)
               and then Get_SPARK_Mode_From_Annotation (Prag) = On);
      end SPARK_Mode_Of_Entity;

      ------------------------
      -- SPARK_Mode_Of_Node --
      ------------------------

      function SPARK_Mode_Of_Node (N : Node_Id) return Extended_SPARK_Mode is
      begin
         return To_SPARK_Mode (Is_SPARK_Mode_On_Node (N));
      end SPARK_Mode_Of_Node;

      ----------------------
      -- Spec_Declaration --
      ----------------------

      function Spec_Declaration (T_Id : Target_Rep_Id) return Node_Id is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Spec_Decl;
      end Spec_Declaration;

      ------------
      -- Target --
      ------------

      function Target (S_Id : Scenario_Rep_Id) return Entity_Id is
         pragma Assert (Present (S_Id));
      begin
         return Scenario_Reps.Table (S_Id).Target;
      end Target;

      ------------------------------
      -- Target_Representation_Of --
      ------------------------------

      function Target_Representation_Of
        (Id       : Entity_Id;
         In_State : Processing_In_State) return Target_Rep_Id
      is
         T_Id : Target_Rep_Id;

      begin
         T_Id := ETT_Map.Get (Entity_To_Target_Map, Id);

         --  The elaboration target lacks an internal representation. This
         --  indicates that the target is encountered for the first time.
         --  Create the internal representation of it.

         if not Present (T_Id) then
            Target_Reps.Append (Create_Target_Rep (Id, In_State));
            T_Id := Target_Reps.Last;

            --  Associate the internal representation with the elaboration
            --  target.

            ETT_Map.Put (Entity_To_Target_Map, Id, T_Id);

         --  The Processing phase is working with a partially analyzed tree,
         --  where various attributes become available as analysis continues.
         --  This case arrises in the context of guaranteed ABE processing.
         --  Update the existing representation by including new attributes.

         elsif In_State.Representation = Inconsistent_Representation then
            Target_Reps.Table (T_Id) := Create_Target_Rep (Id, In_State);

         --  Otherwise the Processing phase imposes a particular representation
         --  version which is not satisfied by the target. This case arrises
         --  when the Processing phase switches from guaranteed ABE checks and
         --  diagnostics to some other mode of operation. Update the existing
         --  representation to include all attributes.

         elsif In_State.Representation /= Version (T_Id) then
            Target_Reps.Table (T_Id) := Create_Target_Rep (Id, In_State);
         end if;

         pragma Assert (Present (T_Id));

         return T_Id;
      end Target_Representation_Of;

      -------------------
      -- To_Ghost_Mode --
      -------------------

      function To_Ghost_Mode
        (Ignored_Status : Boolean) return Extended_Ghost_Mode
      is
      begin
         if Ignored_Status then
            return Is_Ignored;
         else
            return Is_Checked_Or_Not_Specified;
         end if;
      end To_Ghost_Mode;

      -------------------
      -- To_SPARK_Mode --
      -------------------

      function To_SPARK_Mode
        (On_Status : Boolean) return Extended_SPARK_Mode
      is
      begin
         if On_Status then
            return Is_On;
         else
            return Is_Off_Or_Not_Specified;
         end if;
      end To_SPARK_Mode;

      ----------
      -- Unit --
      ----------

      function Unit (T_Id : Target_Rep_Id) return Entity_Id is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Unit;
      end Unit;

      --------------------------
      -- Variable_Declaration --
      --------------------------

      function Variable_Declaration (T_Id : Target_Rep_Id) return Node_Id is
         pragma Assert (Present (T_Id));
         pragma Assert (Kind (T_Id) = Variable_Target);

      begin
         return Target_Reps.Table (T_Id).Field_1;
      end Variable_Declaration;

      -------------
      -- Version --
      -------------

      function Version (T_Id : Target_Rep_Id) return Representation_Kind is
         pragma Assert (Present (T_Id));
      begin
         return Target_Reps.Table (T_Id).Version;
      end Version;
   end Internal_Representation;

   ----------------------
   -- Invocation_Graph --
   ----------------------

   package body Invocation_Graph is

      -----------
      -- Types --
      -----------

      --  The following type represents simplified version of an invocation
      --  relation.

      type Invoker_Target_Relation is record
         Invoker : Entity_Id := Empty;
         Target  : Entity_Id := Empty;
      end record;

      --  The following variables define the entities of the dummy elaboration
      --  procedures used as origins of library level paths.

      Elab_Body_Id : Entity_Id := Empty;
      Elab_Spec_Id : Entity_Id := Empty;

      ---------------------
      -- Data structures --
      ---------------------

      --  The following set contains all declared invocation constructs. It
      --  ensures that the same construct is not declared multiple times in
      --  the ALI file of the main unit.

      Saved_Constructs_Set : NE_Set.Membership_Set := NE_Set.Nil;

      function Hash (Key : Invoker_Target_Relation) return Bucket_Range_Type;
      --  Obtain the hash value of pair Key

      package IR_Set is new Membership_Sets
        (Element_Type => Invoker_Target_Relation,
         "="          => "=",
         Hash         => Hash);

      --  The following set contains all recorded simple invocation relations.
      --  It ensures that multiple relations involving the same invoker and
      --  target do not appear in the ALI file of the main unit.

      Saved_Relations_Set : IR_Set.Membership_Set := IR_Set.Nil;

      --------------
      -- Builders --
      --------------

      function Signature_Of (Id : Entity_Id) return Invocation_Signature_Id;
      pragma Inline (Signature_Of);
      --  Obtain the invication signature id of arbitrary entity Id

      -----------------------
      -- Local subprograms --
      -----------------------

      procedure Build_Elaborate_Body_Procedure;
      pragma Inline (Build_Elaborate_Body_Procedure);
      --  Create a dummy elaborate body procedure and store its entity in
      --  Elab_Body_Id.

      procedure Build_Elaborate_Procedure
        (Proc_Id  : out Entity_Id;
         Proc_Nam : Name_Id;
         Loc      : Source_Ptr);
      pragma Inline (Build_Elaborate_Procedure);
      --  Create a dummy elaborate procedure with name Proc_Nam and source
      --  location Loc. The entity is returned in Proc_Id.

      procedure Build_Elaborate_Spec_Procedure;
      pragma Inline (Build_Elaborate_Spec_Procedure);
      --  Create a dummy elaborate spec procedure and store its entity in
      --  Elab_Spec_Id.

      function Build_Subprogram_Invocation
        (Subp_Id : Entity_Id) return Node_Id;
      pragma Inline (Build_Subprogram_Invocation);
      --  Create a dummy call marker that invokes subprogram Subp_Id

      function Build_Task_Activation
        (Task_Typ : Entity_Id;
         In_State : Processing_In_State) return Node_Id;
      pragma Inline (Build_Task_Activation);
      --  Create a dummy call marker that activates an anonymous task object of
      --  type Task_Typ.

      procedure Declare_Invocation_Construct
        (Constr_Id : Entity_Id;
         In_State  : Processing_In_State);
      pragma Inline (Declare_Invocation_Construct);
      --  Declare invocation construct Constr_Id by creating a declaration for
      --  it in the ALI file of the main unit. In_State is the current state of
      --  the Processing phase.

      function Invocation_Graph_Recording_OK return Boolean;
      pragma Inline (Invocation_Graph_Recording_OK);
      --  Determine whether the invocation graph can be recorded

      function Is_Invocation_Scenario (N : Node_Id) return Boolean;
      pragma Inline (Is_Invocation_Scenario);
      --  Determine whether node N is a suitable scenario for invocation graph
      --  recording purposes.

      function Is_Invocation_Target (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Invocation_Target);
      --  Determine whether arbitrary entity Id denotes an invocation target

      function Is_Saved_Construct (Constr : Entity_Id) return Boolean;
      pragma Inline (Is_Saved_Construct);
      --  Determine whether invocation construct Constr has already been
      --  declared in the ALI file of the main unit.

      function Is_Saved_Relation
        (Rel : Invoker_Target_Relation) return Boolean;
      pragma Inline (Is_Saved_Relation);
      --  Determine whether simple invocation relation Rel has already been
      --  recorded in the ALI file of the main unit.

      procedure Process_Declarations
        (Decls    : List_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Declarations);
      --  Process declaration list Decls by processing all invocation scenarios
      --  within it.

      procedure Process_Freeze_Node
        (Fnode    : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Freeze_Node);
      --  Process freeze node Fnode by processing all invocation scenarios in
      --  its Actions list.

      procedure Process_Invocation_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Invocation_Activation);
      --  Process activation call Call which activates object Obj_Id of task
      --  type Task_Typ by processing all invocation scenarios within the task
      --  body. Call_Rep is the representation of the call. Obj_Rep denotes the
      --  representation of the object. Task_Rep is the representation of the
      --  task type. In_State is the current state of the Processing phase.

      procedure Process_Invocation_Body_Scenarios;
      pragma Inline (Process_Invocation_Body_Scenarios);
      --  Process all library level body scenarios

      procedure Process_Invocation_Call
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Invocation_Call);
      --  Process invocation call scenario Call with representation Call_Rep.
      --  In_State is the current state of the Processing phase.

      procedure Process_Invocation_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Invocation_Instantiation);
      --  Process invocation instantiation scenario Inst with representation
      --  Inst_Rep. In_State is the current state of the Processing phase.

      procedure Process_Invocation_Scenario
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Invocation_Scenario);
      --  Process single invocation scenario N. In_State is the current state
      --  of the Processing phase.

      procedure Process_Invocation_Scenarios
        (Iter     : in out NE_Set.Iterator;
         In_State : Processing_In_State);
      pragma Inline (Process_Invocation_Scenarios);
      --  Process all invocation scenarios obtained via iterator Iter. In_State
      --  is the current state of the Processing phase.

      procedure Process_Invocation_Spec_Scenarios;
      pragma Inline (Process_Invocation_Spec_Scenarios);
      --  Process all library level spec scenarios

      procedure Process_Main_Unit;
      pragma Inline (Process_Main_Unit);
      --  Process all invocation scenarios within the main unit

      procedure Process_Package_Declaration
        (Pack_Decl : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Process_Package_Declaration);
      --  Process package declaration Pack_Decl by processing all invocation
      --  scenarios in its visible and private declarations. If the main unit
      --  contains a generic, the declarations of the body are also examined.
      --  In_State is the current state of the Processing phase.

      procedure Process_Protected_Type_Declaration
        (Prot_Decl : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Process_Protected_Type_Declaration);
      --  Process the declarations of protected type Prot_Decl. In_State is the
      --  current state of the Processing phase.

      procedure Process_Subprogram_Declaration
        (Subp_Decl : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Process_Subprogram_Declaration);
      --  Process subprogram declaration Subp_Decl by processing all invocation
      --  scenarios within its body. In_State denotes the current state of the
      --  Processing phase.

      procedure Process_Subprogram_Instantiation
        (Inst     : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_Subprogram_Instantiation);
      --  Process subprogram instantiation Inst. In_State is the current state
      --  of the Processing phase.

      procedure Process_Task_Type_Declaration
        (Task_Decl : Node_Id;
         In_State  : Processing_In_State);
      pragma Inline (Process_Task_Type_Declaration);
      --  Process task declaration Task_Decl by processing all invocation
      --  scenarios within its body. In_State is the current state of the
      --  Processing phase.

      procedure Record_Full_Invocation_Path (In_State : Processing_In_State);
      pragma Inline (Record_Full_Invocation_Path);
      --  Record all relations between scenario pairs found in the stack of
      --  active scenarios. In_State is the current state of the Processing
      --  phase.

      procedure Record_Invocation_Graph_Encoding;
      pragma Inline (Record_Invocation_Graph_Encoding);
      --  Record the encoding format used to capture information related to
      --  invocation constructs and relations.

      procedure Record_Invocation_Path (In_State : Processing_In_State);
      pragma Inline (Record_Invocation_Path);
      --  Record the invocation relations found within the path represented in
      --  the active scenario stack. In_State denotes the current state of the
      --  Processing phase.

      procedure Record_Simple_Invocation_Path (In_State : Processing_In_State);
      pragma Inline (Record_Simple_Invocation_Path);
      --  Record a single relation from the start to the end of the stack of
      --  active scenarios. In_State is the current state of the Processing
      --  phase.

      procedure Record_Invocation_Relation
        (Invk_Id  : Entity_Id;
         Targ_Id  : Entity_Id;
         In_State : Processing_In_State);
      pragma Inline (Record_Invocation_Relation);
      --  Record an invocation relation with invoker Invk_Id and target Targ_Id
      --  by creating an entry for it in the ALI file of the main unit. Formal
      --  In_State denotes the current state of the Processing phase.

      procedure Set_Is_Saved_Construct (Constr : Entity_Id);
      pragma Inline (Set_Is_Saved_Construct);
      --  Mark invocation construct Constr as declared in the ALI file of the
      --  main unit.

      procedure Set_Is_Saved_Relation (Rel : Invoker_Target_Relation);
      pragma Inline (Set_Is_Saved_Relation);
      --  Mark simple invocation relation Rel as recorded in the ALI file of
      --  the main unit.

      function Target_Of
        (Pos      : Active_Scenario_Pos;
         In_State : Processing_In_State) return Entity_Id;
      pragma Inline (Target_Of);
      --  Given position within the active scenario stack Pos, obtain the
      --  target of the indicated scenario. In_State is the current state
      --  of the Processing phase.

      procedure Traverse_Invocation_Body
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Traverse_Invocation_Body);
      --  Traverse subprogram body N looking for suitable invocation scenarios
      --  that need to be processed for invocation graph recording purposes.
      --  In_State is the current state of the Processing phase.

      procedure Write_Invocation_Path (In_State : Processing_In_State);
      pragma Inline (Write_Invocation_Path);
      --  Write out a path represented by the active scenario on the stack to
      --  standard output. In_State denotes the current state of the Processing
      --  phase.

      ------------------------------------
      -- Build_Elaborate_Body_Procedure --
      ------------------------------------

      procedure Build_Elaborate_Body_Procedure is
         Body_Decl : Node_Id;
         Spec_Decl : Node_Id;

      begin
         --  Nothing to do when a previous call already created the procedure

         if Present (Elab_Body_Id) then
            return;
         end if;

         Spec_And_Body_From_Entity
           (Id        => Main_Unit_Entity,
            Body_Decl => Body_Decl,
            Spec_Decl => Spec_Decl);

         pragma Assert (Present (Body_Decl));

         Build_Elaborate_Procedure
           (Proc_Id  => Elab_Body_Id,
            Proc_Nam => Name_B,
            Loc      => Sloc (Body_Decl));
      end Build_Elaborate_Body_Procedure;

      -------------------------------
      -- Build_Elaborate_Procedure --
      -------------------------------

      procedure Build_Elaborate_Procedure
        (Proc_Id  : out Entity_Id;
         Proc_Nam : Name_Id;
         Loc      : Source_Ptr)
      is
         Proc_Decl : Node_Id;
         pragma Unreferenced (Proc_Decl);

      begin
         Proc_Id := Make_Defining_Identifier (Loc, Proc_Nam);

         --  Partially decorate the elaboration procedure because it will not
         --  be insertred into the tree and analyzed.

         Mutate_Ekind (Proc_Id, E_Procedure);
         Set_Etype (Proc_Id, Standard_Void_Type);
         Set_Scope (Proc_Id, Unique_Entity (Main_Unit_Entity));

         --  Create a dummy declaration for the elaboration procedure. The
         --  declaration does not need to be syntactically legal, but must
         --  carry an accurate source location.

         Proc_Decl :=
           Make_Subprogram_Body (Loc,
             Specification              =>
               Make_Procedure_Specification (Loc,
                 Defining_Unit_Name => Proc_Id),
             Declarations               => No_List,
             Handled_Statement_Sequence => Empty);
      end Build_Elaborate_Procedure;

      ------------------------------------
      -- Build_Elaborate_Spec_Procedure --
      ------------------------------------

      procedure Build_Elaborate_Spec_Procedure is
         Body_Decl : Node_Id;
         Spec_Decl : Node_Id;

      begin
         --  Nothing to do when a previous call already created the procedure

         if Present (Elab_Spec_Id) then
            return;
         end if;

         Spec_And_Body_From_Entity
           (Id        => Main_Unit_Entity,
            Body_Decl => Body_Decl,
            Spec_Decl => Spec_Decl);

         pragma Assert (Present (Spec_Decl));

         Build_Elaborate_Procedure
           (Proc_Id  => Elab_Spec_Id,
            Proc_Nam => Name_S,
            Loc      => Sloc (Spec_Decl));
      end Build_Elaborate_Spec_Procedure;

      ---------------------------------
      -- Build_Subprogram_Invocation --
      ---------------------------------

      function Build_Subprogram_Invocation
        (Subp_Id : Entity_Id) return Node_Id
      is
         Marker    : constant Node_Id := Make_Call_Marker (Sloc (Subp_Id));
         Subp_Decl : constant Node_Id := Unit_Declaration_Node (Subp_Id);

      begin
         --  Create a dummy call marker which invokes the subprogram

         Set_Is_Declaration_Level_Node       (Marker, False);
         Set_Is_Dispatching_Call             (Marker, False);
         Set_Is_Elaboration_Checks_OK_Node   (Marker, False);
         Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
         Set_Is_Ignored_Ghost_Node           (Marker, False);
         Set_Is_Preelaborable_Call           (Marker, False);
         Set_Is_Source_Call                  (Marker, False);
         Set_Is_SPARK_Mode_On_Node           (Marker, False);

         --  Invoke the uniform canonical entity of the subprogram

         Set_Target (Marker, Canonical_Subprogram (Subp_Id));

         --  Partially insert the marker into the tree

         Set_Parent (Marker, Parent (Subp_Decl));

         return Marker;
      end Build_Subprogram_Invocation;

      ---------------------------
      -- Build_Task_Activation --
      ---------------------------

      function Build_Task_Activation
        (Task_Typ : Entity_Id;
         In_State : Processing_In_State) return Node_Id
      is
         Loc       : constant Source_Ptr := Sloc (Task_Typ);
         Marker    : constant Node_Id    := Make_Call_Marker (Loc);
         Task_Decl : constant Node_Id    := Unit_Declaration_Node (Task_Typ);

         Activ_Id      : Entity_Id;
         Marker_Rep_Id : Scenario_Rep_Id;
         Task_Obj      : Entity_Id;
         Task_Objs     : NE_List.Doubly_Linked_List;

      begin
         --  Create a dummy call marker which activates some tasks

         Set_Is_Declaration_Level_Node       (Marker, False);
         Set_Is_Dispatching_Call             (Marker, False);
         Set_Is_Elaboration_Checks_OK_Node   (Marker, False);
         Set_Is_Elaboration_Warnings_OK_Node (Marker, False);
         Set_Is_Ignored_Ghost_Node           (Marker, False);
         Set_Is_Preelaborable_Call           (Marker, False);
         Set_Is_Source_Call                  (Marker, False);
         Set_Is_SPARK_Mode_On_Node           (Marker, False);

         --  Invoke the appropriate version of Activate_Tasks

         if Restricted_Profile then
            Activ_Id := RTE (RE_Activate_Restricted_Tasks);
         else
            Activ_Id := RTE (RE_Activate_Tasks);
         end if;

         Set_Target (Marker, Activ_Id);

         --  Partially insert the marker into the tree

         Set_Parent (Marker, Parent (Task_Decl));

         --  Create a dummy task object. Partially decorate the object because
         --  it will not be inserted into the tree and analyzed.

         Task_Obj := Make_Temporary (Loc, 'T');
         Mutate_Ekind (Task_Obj, E_Variable);
         Set_Etype (Task_Obj, Task_Typ);

         --  Associate the dummy task object with the activation call

         Task_Objs := NE_List.Create;
         NE_List.Append (Task_Objs, Task_Obj);

         Marker_Rep_Id := Scenario_Representation_Of (Marker, In_State);
         Set_Activated_Task_Objects (Marker_Rep_Id, Task_Objs);
         Set_Activated_Task_Type    (Marker_Rep_Id, Task_Typ);

         return Marker;
      end Build_Task_Activation;

      ----------------------------------
      -- Declare_Invocation_Construct --
      ----------------------------------

      procedure Declare_Invocation_Construct
        (Constr_Id : Entity_Id;
         In_State  : Processing_In_State)
      is
         function Body_Placement_Of
           (Id : Entity_Id) return Declaration_Placement_Kind;
         pragma Inline (Body_Placement_Of);
         --  Obtain the placement of arbitrary entity Id's body

         function Declaration_Placement_Of_Node
           (N : Node_Id) return Declaration_Placement_Kind;
         pragma Inline (Declaration_Placement_Of_Node);
         --  Obtain the placement of arbitrary node N

         function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind;
         pragma Inline (Kind_Of);
         --  Obtain the invocation construct kind of arbitrary entity Id

         function Spec_Placement_Of
           (Id : Entity_Id) return Declaration_Placement_Kind;
         pragma Inline (Spec_Placement_Of);
         --  Obtain the placement of arbitrary entity Id's spec

         -----------------------
         -- Body_Placement_Of --
         -----------------------

         function Body_Placement_Of
           (Id : Entity_Id) return Declaration_Placement_Kind
         is
            Id_Rep    : constant Target_Rep_Id :=
                          Target_Representation_Of (Id, In_State);
            Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
            Spec_Decl : constant Node_Id := Spec_Declaration (Id_Rep);

         begin
            --  The entity has a body

            if Present (Body_Decl) then
               return Declaration_Placement_Of_Node (Body_Decl);

            --  Otherwise the entity must have a spec

            else
               pragma Assert (Present (Spec_Decl));
               return Declaration_Placement_Of_Node (Spec_Decl);
            end if;
         end Body_Placement_Of;

         -----------------------------------
         -- Declaration_Placement_Of_Node --
         -----------------------------------

         function Declaration_Placement_Of_Node
           (N : Node_Id) return Declaration_Placement_Kind
         is
            Main_Unit_Id : constant Entity_Id := Main_Unit_Entity;
            N_Unit_Id    : constant Entity_Id := Find_Top_Unit (N);

         begin
            --  The node is in the main unit, its placement depends on the main
            --  unit kind.

            if N_Unit_Id = Main_Unit_Id then

               --  The main unit is a body

               if Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
               then
                  return In_Body;

               --  The main unit is a stand-alone subprogram body

               elsif Ekind (Main_Unit_Id) in E_Function | E_Procedure
                 and then Nkind (Unit_Declaration_Node (Main_Unit_Id)) =
                            N_Subprogram_Body
               then
                  return In_Body;

               --  Otherwise the main unit is a spec

               else
                  return In_Spec;
               end if;

            --  Otherwise the node is in the complementary unit of the main
            --  unit. The main unit is a body, the node is in the spec.

            elsif Ekind (Main_Unit_Id) in E_Package_Body | E_Subprogram_Body
            then
               return In_Spec;

            --  The main unit is a spec, the node is in the body

            else
               return In_Body;
            end if;
         end Declaration_Placement_Of_Node;

         -------------
         -- Kind_Of --
         -------------

         function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind is
         begin
            if Id = Elab_Body_Id then
               return Elaborate_Body_Procedure;

            elsif Id = Elab_Spec_Id then
               return Elaborate_Spec_Procedure;

            else
               return Regular_Construct;
            end if;
         end Kind_Of;

         -----------------------
         -- Spec_Placement_Of --
         -----------------------

         function Spec_Placement_Of
           (Id : Entity_Id) return Declaration_Placement_Kind
         is
            Id_Rep    : constant Target_Rep_Id :=
                          Target_Representation_Of (Id, In_State);
            Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
            Spec_Decl : constant Node_Id := Spec_Declaration (Id_Rep);

         begin
            --  The entity has a spec

            if Present (Spec_Decl) then
               return Declaration_Placement_Of_Node (Spec_Decl);

            --  Otherwise the entity must have a body

            else
               pragma Assert (Present (Body_Decl));
               return Declaration_Placement_Of_Node (Body_Decl);
            end if;
         end Spec_Placement_Of;

      --  Start of processing for Declare_Invocation_Construct

      begin
         --  Nothing to do when the construct has already been declared in the
         --  ALI file.

         if Is_Saved_Construct (Constr_Id) then
            return;
         end if;

         --  Mark the construct as declared in the ALI file

         Set_Is_Saved_Construct (Constr_Id);

         --  Add the construct in the ALI file

         Add_Invocation_Construct
           (Body_Placement => Body_Placement_Of (Constr_Id),
            Kind           => Kind_Of           (Constr_Id),
            Signature      => Signature_Of      (Constr_Id),
            Spec_Placement => Spec_Placement_Of (Constr_Id),
            Update_Units   => False);
      end Declare_Invocation_Construct;

      -------------------------------
      -- Finalize_Invocation_Graph --
      -------------------------------

      procedure Finalize_Invocation_Graph is
      begin
         NE_Set.Destroy (Saved_Constructs_Set);
         IR_Set.Destroy (Saved_Relations_Set);
      end Finalize_Invocation_Graph;

      ----------
      -- Hash --
      ----------

      function Hash (Key : Invoker_Target_Relation) return Bucket_Range_Type is
         pragma Assert (Present (Key.Invoker));
         pragma Assert (Present (Key.Target));

      begin
         return
           Hash_Two_Keys
             (Bucket_Range_Type (Key.Invoker),
              Bucket_Range_Type (Key.Target));
      end Hash;

      ---------------------------------
      -- Initialize_Invocation_Graph --
      ---------------------------------

      procedure Initialize_Invocation_Graph is
      begin
         Saved_Constructs_Set := NE_Set.Create (100);
         Saved_Relations_Set  := IR_Set.Create (200);
      end Initialize_Invocation_Graph;

      -----------------------------------
      -- Invocation_Graph_Recording_OK --
      -----------------------------------

      function Invocation_Graph_Recording_OK return Boolean is
         Main_Cunit : constant Node_Id := Cunit (Main_Unit);

      begin
         --  Nothing to do when compiling for GNATprove because the invocation
         --  graph is not needed.

         if GNATprove_Mode then
            return False;

         --  Nothing to do when the compilation will not produce an ALI file

         elsif Serious_Errors_Detected > 0 then
            return False;

         --  Nothing to do when the main unit requires a body. Processing the
         --  completing body will create the ALI file for the unit and record
         --  the invocation graph.

         elsif Body_Required (Main_Cunit) then
            return False;
         end if;

         return True;
      end Invocation_Graph_Recording_OK;

      ----------------------------
      -- Is_Invocation_Scenario --
      ----------------------------

      function Is_Invocation_Scenario (N : Node_Id) return Boolean is
      begin
         return
           Is_Suitable_Access_Taken (N)
             or else Is_Suitable_Call (N)
             or else Is_Suitable_Instantiation (N);
      end Is_Invocation_Scenario;

      --------------------------
      -- Is_Invocation_Target --
      --------------------------

      function Is_Invocation_Target (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must either come from source, or denote an
         --  Ada, bridge, or SPARK target.

         return
           Comes_From_Source (Id)
             or else Is_Ada_Semantic_Target (Id)
             or else Is_Bridge_Target (Id)
             or else Is_SPARK_Semantic_Target (Id);
      end Is_Invocation_Target;

      ------------------------
      -- Is_Saved_Construct --
      ------------------------

      function Is_Saved_Construct (Constr : Entity_Id) return Boolean is
         pragma Assert (Present (Constr));
      begin
         return NE_Set.Contains (Saved_Constructs_Set, Constr);
      end Is_Saved_Construct;

      -----------------------
      -- Is_Saved_Relation --
      -----------------------

      function Is_Saved_Relation
        (Rel : Invoker_Target_Relation) return Boolean
      is
         pragma Assert (Present (Rel.Invoker));
         pragma Assert (Present (Rel.Target));

      begin
         return IR_Set.Contains (Saved_Relations_Set, Rel);
      end Is_Saved_Relation;

      --------------------------
      -- Process_Declarations --
      --------------------------

      procedure Process_Declarations
        (Decls    : List_Id;
         In_State : Processing_In_State)
      is
         Decl : Node_Id;

      begin
         Decl := First (Decls);
         while Present (Decl) loop

            --  Freeze node

            if Nkind (Decl) = N_Freeze_Entity then
               Process_Freeze_Node
                 (Fnode    => Decl,
                  In_State => In_State);

            --  Package (nested)

            elsif Nkind (Decl) = N_Package_Declaration then
               Process_Package_Declaration
                 (Pack_Decl => Decl,
                  In_State  => In_State);

            --  Protected type

            elsif Nkind (Decl) in N_Protected_Type_Declaration
                                | N_Single_Protected_Declaration
            then
               Process_Protected_Type_Declaration
                 (Prot_Decl => Decl,
                  In_State  => In_State);

            --  Subprogram or entry

            elsif Nkind (Decl) in N_Entry_Declaration
                                | N_Subprogram_Declaration
            then
               Process_Subprogram_Declaration
                 (Subp_Decl => Decl,
                  In_State  => In_State);

            --  Subprogram body (stand alone)

            elsif Nkind (Decl) = N_Subprogram_Body
              and then No (Corresponding_Spec (Decl))
            then
               Process_Subprogram_Declaration
                 (Subp_Decl => Decl,
                  In_State  => In_State);

            --  Subprogram instantiation

            elsif Nkind (Decl) in N_Subprogram_Instantiation then
               Process_Subprogram_Instantiation
                 (Inst     => Decl,
                  In_State => In_State);

            --  Task type

            elsif Nkind (Decl) in N_Single_Task_Declaration
                                | N_Task_Type_Declaration
            then
               Process_Task_Type_Declaration
                 (Task_Decl => Decl,
                  In_State  => In_State);

            --  Task type (derived)

            elsif Nkind (Decl) = N_Full_Type_Declaration
              and then Is_Task_Type (Defining_Entity (Decl))
            then
               Process_Task_Type_Declaration
                 (Task_Decl => Decl,
                  In_State  => In_State);
            end if;

            Next (Decl);
         end loop;
      end Process_Declarations;

      -------------------------
      -- Process_Freeze_Node --
      -------------------------

      procedure Process_Freeze_Node
        (Fnode    : Node_Id;
         In_State : Processing_In_State)
      is
      begin
         Process_Declarations
           (Decls    => Actions (Fnode),
            In_State => In_State);
      end Process_Freeze_Node;

      -----------------------------------
      -- Process_Invocation_Activation --
      -----------------------------------

      procedure Process_Invocation_Activation
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         Obj_Id   : Entity_Id;
         Obj_Rep  : Target_Rep_Id;
         Task_Typ : Entity_Id;
         Task_Rep : Target_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Call);
         pragma Unreferenced (Call_Rep);
         pragma Unreferenced (Obj_Id);
         pragma Unreferenced (Obj_Rep);

      begin
         --  Nothing to do when the task type appears within an internal unit

         if In_Internal_Unit (Task_Typ) then
            return;
         end if;

         --  The task type being activated is within the main unit. Extend the
         --  DFS traversal into its body.

         if In_Extended_Main_Code_Unit (Task_Typ) then
            Traverse_Invocation_Body
              (N        => Body_Declaration (Task_Rep),
               In_State => In_State);

         --  The task type being activated resides within an external unit
         --
         --      Main unit         External unit
         --    +-----------+      +-------------+
         --    |           |      |             |
         --    |  Start ------------> Task_Typ  |
         --    |           |      |             |
         --    +-----------+      +-------------+
         --
         --  Record the invocation path which originates from Start and reaches
         --  the task type.

         else
            Record_Invocation_Path (In_State);
         end if;
      end Process_Invocation_Activation;

      ---------------------------------------
      -- Process_Invocation_Body_Scenarios --
      ---------------------------------------

      procedure Process_Invocation_Body_Scenarios is
         Iter : NE_Set.Iterator := Iterate_Library_Body_Scenarios;
      begin
         Process_Invocation_Scenarios
           (Iter     => Iter,
            In_State => Invocation_Body_State);
      end Process_Invocation_Body_Scenarios;

      -----------------------------
      -- Process_Invocation_Call --
      -----------------------------

      procedure Process_Invocation_Call
        (Call     : Node_Id;
         Call_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Call);

         Subp_Id  : constant Entity_Id     := Target (Call_Rep);
         Subp_Rep : constant Target_Rep_Id :=
                      Target_Representation_Of (Subp_Id, In_State);

      begin
         --  Nothing to do when the subprogram appears within an internal unit

         if In_Internal_Unit (Subp_Id) then
            return;

         --  Nothing to do for an abstract subprogram because it has no body to
         --  examine.

         elsif Ekind (Subp_Id) in E_Function | E_Procedure
           and then Is_Abstract_Subprogram (Subp_Id)
         then
            return;

         --  Nothin to do for a formal subprogram because it has no body to
         --  examine.

         elsif Is_Formal_Subprogram (Subp_Id) then
            return;
         end if;

         --  The subprogram being called is within the main unit. Extend the
         --  DFS traversal into its barrier function and body.

         if In_Extended_Main_Code_Unit (Subp_Id) then
            if Ekind (Subp_Id) in E_Entry | E_Entry_Family | E_Procedure then
               Traverse_Invocation_Body
                 (N        => Barrier_Body_Declaration (Subp_Rep),
                  In_State => In_State);
            end if;

            Traverse_Invocation_Body
              (N        => Body_Declaration (Subp_Rep),
               In_State => In_State);

         --  The subprogram being called resides within an external unit
         --
         --      Main unit         External unit
         --    +-----------+      +-------------+
         --    |           |      |             |
         --    |  Start ------------> Subp_Id   |
         --    |           |      |             |
         --    +-----------+      +-------------+
         --
         --  Record the invocation path which originates from Start and reaches
         --  the subprogram.

         else
            Record_Invocation_Path (In_State);
         end if;
      end Process_Invocation_Call;

      --------------------------------------
      -- Process_Invocation_Instantiation --
      --------------------------------------

      procedure Process_Invocation_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Inst);

         Gen_Id : constant Entity_Id := Target (Inst_Rep);

      begin
         --  Nothing to do when the generic appears within an internal unit

         if In_Internal_Unit (Gen_Id) then
            return;
         end if;

         --  The generic being instantiated resides within an external unit
         --
         --      Main unit         External unit
         --    +-----------+      +-------------+
         --    |           |      |             |
         --    |  Start ------------> Generic   |
         --    |           |      |             |
         --    +-----------+      +-------------+
         --
         --  Record the invocation path which originates from Start and reaches
         --  the generic.

         if not In_Extended_Main_Code_Unit (Gen_Id) then
            Record_Invocation_Path (In_State);
         end if;
      end Process_Invocation_Instantiation;

      ---------------------------------
      -- Process_Invocation_Scenario --
      ---------------------------------

      procedure Process_Invocation_Scenario
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
         Scen     : constant Node_Id := Scenario (N);
         Scen_Rep : Scenario_Rep_Id;

      begin
         --  Add the current scenario to the stack of active scenarios

         Push_Active_Scenario (Scen);

         --  Call or task activation

         if Is_Suitable_Call (Scen) then
            Scen_Rep := Scenario_Representation_Of (Scen, In_State);

            --  Routine Build_Call_Marker creates call markers regardless of
            --  whether the call occurs within the main unit or not. This way
            --  the serialization of internal names is kept consistent. Only
            --  call markers found within the main unit must be processed.

            if In_Main_Context (Scen) then
               Scen_Rep := Scenario_Representation_Of (Scen, In_State);

               if Kind (Scen_Rep) = Call_Scenario then
                  Process_Invocation_Call
                    (Call     => Scen,
                     Call_Rep => Scen_Rep,
                     In_State => In_State);

               else
                  pragma Assert (Kind (Scen_Rep) = Task_Activation_Scenario);

                  Process_Activation
                    (Call      => Scen,
                     Call_Rep  => Scen_Rep,
                     Processor => Process_Invocation_Activation'Access,
                     In_State  => In_State);
               end if;
            end if;

         --  Instantiation

         elsif Is_Suitable_Instantiation (Scen) then
            Process_Invocation_Instantiation
              (Inst     => Scen,
               Inst_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);
         end if;

         --  Remove the current scenario from the stack of active scenarios
         --  once all invocation constructs and paths have been saved.

         Pop_Active_Scenario (Scen);
      end Process_Invocation_Scenario;

      ----------------------------------
      -- Process_Invocation_Scenarios --
      ----------------------------------

      procedure Process_Invocation_Scenarios
        (Iter     : in out NE_Set.Iterator;
         In_State : Processing_In_State)
      is
         N : Node_Id;

      begin
         while NE_Set.Has_Next (Iter) loop
            NE_Set.Next (Iter, N);

            --  Reset the traversed status of all subprogram bodies because the
            --  current invocation scenario acts as a new DFS traversal root.

            Reset_Traversed_Bodies;

            Process_Invocation_Scenario (N, In_State);
         end loop;
      end Process_Invocation_Scenarios;

      ---------------------------------------
      -- Process_Invocation_Spec_Scenarios --
      ---------------------------------------

      procedure Process_Invocation_Spec_Scenarios is
         Iter : NE_Set.Iterator := Iterate_Library_Spec_Scenarios;
      begin
         Process_Invocation_Scenarios
           (Iter     => Iter,
            In_State => Invocation_Spec_State);
      end Process_Invocation_Spec_Scenarios;

      -----------------------
      -- Process_Main_Unit --
      -----------------------

      procedure Process_Main_Unit is
         Unit_Decl : constant Node_Id := Unit (Cunit (Main_Unit));
         Spec_Id   : Entity_Id;

      begin
         --  The main unit is a [generic] package body

         if Nkind (Unit_Decl) = N_Package_Body then
            Spec_Id := Corresponding_Spec (Unit_Decl);
            pragma Assert (Present (Spec_Id));

            Process_Package_Declaration
              (Pack_Decl => Unit_Declaration_Node (Spec_Id),
               In_State  => Invocation_Construct_State);

         --  The main unit is a [generic] package declaration

         elsif Nkind (Unit_Decl) = N_Package_Declaration then
            Process_Package_Declaration
              (Pack_Decl => Unit_Decl,
               In_State  => Invocation_Construct_State);

         --  The main unit is a [generic] subprogram body

         elsif Nkind (Unit_Decl) = N_Subprogram_Body then
            Spec_Id := Corresponding_Spec (Unit_Decl);

            --  The body completes a previous declaration

            if Present (Spec_Id) then
               Process_Subprogram_Declaration
                 (Subp_Decl => Unit_Declaration_Node (Spec_Id),
                  In_State  => Invocation_Construct_State);

            --  Otherwise the body is stand-alone

            else
               Process_Subprogram_Declaration
                 (Subp_Decl => Unit_Decl,
                  In_State  => Invocation_Construct_State);
            end if;

         --  The main unit is a subprogram instantiation

         elsif Nkind (Unit_Decl) in N_Subprogram_Instantiation then
            Process_Subprogram_Instantiation
              (Inst     => Unit_Decl,
               In_State => Invocation_Construct_State);

         --  The main unit is an imported subprogram declaration

         elsif Nkind (Unit_Decl) = N_Subprogram_Declaration then
            Process_Subprogram_Declaration
              (Subp_Decl => Unit_Decl,
               In_State  => Invocation_Construct_State);
         end if;
      end Process_Main_Unit;

      ---------------------------------
      -- Process_Package_Declaration --
      ---------------------------------

      procedure Process_Package_Declaration
        (Pack_Decl : Node_Id;
         In_State  : Processing_In_State)
      is
         Body_Id : constant Entity_Id := Corresponding_Body (Pack_Decl);
         Spec    : constant Node_Id   := Specification (Pack_Decl);
         Spec_Id : constant Entity_Id := Defining_Entity (Pack_Decl);

      begin
         --  Add a declaration for the generic package in the ALI of the main
         --  unit in case a client unit instantiates it.

         if Ekind (Spec_Id) = E_Generic_Package then
            Declare_Invocation_Construct
              (Constr_Id => Spec_Id,
               In_State  => In_State);

         --  Otherwise inspect the visible and private declarations of the
         --  package for invocation constructs.

         else
            Process_Declarations
              (Decls    => Visible_Declarations (Spec),
               In_State => In_State);

            Process_Declarations
              (Decls    => Private_Declarations (Spec),
               In_State => In_State);

            --  The package body containst at least one generic unit or an
            --  inlinable subprogram. Such constructs may grant clients of
            --  the main unit access to the private enclosing contexts of
            --  the constructs. Process the main unit body to discover and
            --  encode relevant invocation constructs and relations that
            --  may ultimately reach an external unit.

            if Present (Body_Id)
              and then Save_Invocation_Graph_Of_Body (Cunit (Main_Unit))
            then
               Process_Declarations
                 (Decls    => Declarations (Unit_Declaration_Node (Body_Id)),
                  In_State => In_State);
            end if;
         end if;
      end Process_Package_Declaration;

      ----------------------------------------
      -- Process_Protected_Type_Declaration --
      ----------------------------------------

      procedure Process_Protected_Type_Declaration
        (Prot_Decl : Node_Id;
         In_State  : Processing_In_State)
      is
         Prot_Def : constant Node_Id := Protected_Definition (Prot_Decl);

      begin
         if Present (Prot_Def) then
            Process_Declarations
              (Decls    => Visible_Declarations (Prot_Def),
               In_State => In_State);
         end if;
      end Process_Protected_Type_Declaration;

      ------------------------------------
      -- Process_Subprogram_Declaration --
      ------------------------------------

      procedure Process_Subprogram_Declaration
        (Subp_Decl : Node_Id;
         In_State  : Processing_In_State)
      is
         Subp_Id : constant Entity_Id := Defining_Entity (Subp_Decl);

      begin
         --  Nothing to do when the subprogram is not an invocation target

         if not Is_Invocation_Target (Subp_Id) then
            return;
         end if;

         --  Add a declaration for the subprogram in the ALI file of the main
         --  unit in case a client unit calls or instantiates it.

         Declare_Invocation_Construct
           (Constr_Id => Subp_Id,
            In_State  => In_State);

         --  Do not process subprograms without a body because they do not
         --  contain any invocation scenarios.

         if Is_Bodiless_Subprogram (Subp_Id) then
            null;

         --  Do not process generic subprograms because generics must not be
         --  examined.

         elsif Is_Generic_Subprogram (Subp_Id) then
            null;

         --  Otherwise create a dummy scenario which calls the subprogram to
         --  act as a root for a DFS traversal.

         else
            --  Reset the traversed status of all subprogram bodies because the
            --  subprogram acts as a new DFS traversal root.

            Reset_Traversed_Bodies;

            Process_Invocation_Scenario
              (N        => Build_Subprogram_Invocation (Subp_Id),
               In_State => In_State);
         end if;
      end Process_Subprogram_Declaration;

      --------------------------------------
      -- Process_Subprogram_Instantiation --
      --------------------------------------

      procedure Process_Subprogram_Instantiation
        (Inst     : Node_Id;
         In_State : Processing_In_State)
      is
      begin
         --  Add a declaration for the instantiation in the ALI file of the
         --  main unit in case a client unit calls it.

         Declare_Invocation_Construct
           (Constr_Id => Defining_Entity (Inst),
            In_State  => In_State);
      end Process_Subprogram_Instantiation;

      -----------------------------------
      -- Process_Task_Type_Declaration --
      -----------------------------------

      procedure Process_Task_Type_Declaration
        (Task_Decl : Node_Id;
         In_State  : Processing_In_State)
      is
         Task_Typ : constant Entity_Id := Defining_Entity (Task_Decl);
         Task_Def : Node_Id;

      begin
         --  Add a declaration for the task type the ALI file of the main unit
         --  in case a client unit creates a task object and activates it.

         Declare_Invocation_Construct
           (Constr_Id => Task_Typ,
            In_State  => In_State);

         --  Process the entries of the task type because they represent valid
         --  entry points into the task body.

         if Nkind (Task_Decl) in N_Single_Task_Declaration
                               | N_Task_Type_Declaration
         then
            Task_Def := Task_Definition (Task_Decl);

            if Present (Task_Def) then
               Process_Declarations
                 (Decls    => Visible_Declarations (Task_Def),
                  In_State => In_State);
            end if;
         end if;

         --  Reset the traversed status of all subprogram bodies because the
         --  task type acts as a new DFS traversal root.

         Reset_Traversed_Bodies;

         --  Create a dummy scenario which activates an anonymous object of the
         --  task type to acts as a root of a DFS traversal.

         Process_Invocation_Scenario
           (N        => Build_Task_Activation (Task_Typ, In_State),
            In_State => In_State);
      end Process_Task_Type_Declaration;

      ---------------------------------
      -- Record_Full_Invocation_Path --
      ---------------------------------

      procedure Record_Full_Invocation_Path (In_State : Processing_In_State) is
         package Scenarios renames Active_Scenario_Stack;

      begin
         --  The path originates from the elaboration of the body. Add an extra
         --  relation from the elaboration body procedure to the first active
         --  scenario.

         if In_State.Processing = Invocation_Body_Processing then
            Build_Elaborate_Body_Procedure;

            Record_Invocation_Relation
              (Invk_Id  => Elab_Body_Id,
               Targ_Id  => Target_Of (Scenarios.First, In_State),
               In_State => In_State);

         --  The path originates from the elaboration of the spec. Add an extra
         --  relation from the elaboration spec procedure to the first active
         --  scenario.

         elsif In_State.Processing = Invocation_Spec_Processing then
            Build_Elaborate_Spec_Procedure;

            Record_Invocation_Relation
              (Invk_Id  => Elab_Spec_Id,
               Targ_Id  => Target_Of (Scenarios.First, In_State),
               In_State => In_State);
         end if;

         --  Record individual relations formed by pairs of scenarios

         for Index in Scenarios.First .. Scenarios.Last - 1 loop
            Record_Invocation_Relation
              (Invk_Id  => Target_Of (Index,     In_State),
               Targ_Id  => Target_Of (Index + 1, In_State),
               In_State => In_State);
         end loop;
      end Record_Full_Invocation_Path;

      -----------------------------
      -- Record_Invocation_Graph --
      -----------------------------

      procedure Record_Invocation_Graph is
      begin
         --  Nothing to do when the invocation graph is not recorded

         if not Invocation_Graph_Recording_OK then
            return;
         end if;

         --  Save the encoding format used to capture information about the
         --  invocation constructs and relations in the ALI file of the main
         --  unit.

         Record_Invocation_Graph_Encoding;

         --  Examine all library level invocation scenarios and perform DFS
         --  traversals from each one. Encode a path in the ALI file of the
         --  main unit if it reaches into an external unit.

         Process_Invocation_Body_Scenarios;
         Process_Invocation_Spec_Scenarios;

         --  Examine all invocation constructs within the spec and body of the
         --  main unit and perform DFS traversals from each one. Encode a path
         --  in the ALI file of the main unit if it reaches into an external
         --  unit.

         Process_Main_Unit;
      end Record_Invocation_Graph;

      --------------------------------------
      -- Record_Invocation_Graph_Encoding --
      --------------------------------------

      procedure Record_Invocation_Graph_Encoding is
         Kind : Invocation_Graph_Encoding_Kind := No_Encoding;

      begin
         --  Switch -gnatd_F (encode full invocation paths in ALI files) is in
         --  effect.

         if Debug_Flag_Underscore_FF then
            Kind := Full_Path_Encoding;
         else
            Kind := Endpoints_Encoding;
         end if;

         --  Save the encoding format in the ALI file of the main unit

         Set_Invocation_Graph_Encoding
           (Kind         => Kind,
            Update_Units => False);
      end Record_Invocation_Graph_Encoding;

      ----------------------------
      -- Record_Invocation_Path --
      ----------------------------

      procedure Record_Invocation_Path (In_State : Processing_In_State) is
         package Scenarios renames Active_Scenario_Stack;

      begin
         --  Save a path when the active scenario stack contains at least one
         --  invocation scenario.

         if Scenarios.Last - Scenarios.First < 0 then
            return;
         end if;

         --  Register all relations in the path when switch -gnatd_F (encode
         --  full invocation paths in ALI files) is in effect.

         if Debug_Flag_Underscore_FF then
            Record_Full_Invocation_Path (In_State);

         --  Otherwise register a single relation

         else
            Record_Simple_Invocation_Path (In_State);
         end if;

         Write_Invocation_Path (In_State);
      end Record_Invocation_Path;

      --------------------------------
      -- Record_Invocation_Relation --
      --------------------------------

      procedure Record_Invocation_Relation
        (Invk_Id  : Entity_Id;
         Targ_Id  : Entity_Id;
         In_State : Processing_In_State)
      is
         pragma Assert (Present (Invk_Id));
         pragma Assert (Present (Targ_Id));

         procedure Get_Invocation_Attributes
           (Extra : out Entity_Id;
            Kind  : out Invocation_Kind);
         pragma Inline (Get_Invocation_Attributes);
         --  Return the additional entity used in error diagnostics in Extra
         --  and the invocation kind in Kind which pertain to the invocation
         --  relation with invoker Invk_Id and target Targ_Id.

         -------------------------------
         -- Get_Invocation_Attributes --
         -------------------------------

         procedure Get_Invocation_Attributes
           (Extra : out Entity_Id;
            Kind  : out Invocation_Kind)
         is
            Targ_Rep  : constant Target_Rep_Id :=
                          Target_Representation_Of (Targ_Id, In_State);
            Spec_Decl : constant Node_Id := Spec_Declaration (Targ_Rep);

         begin
            --  Accept within a task body

            if Is_Accept_Alternative_Proc (Targ_Id) then
               Extra := Receiving_Entry (Targ_Id);
               Kind  := Accept_Alternative;

            --  Activation of a task object

            elsif Is_Activation_Proc (Targ_Id)
              or else Is_Task_Type (Targ_Id)
            then
               Extra := Empty;
               Kind  := Task_Activation;

            --  Controlled adjustment actions

            elsif Is_Controlled_Proc (Targ_Id, Name_Adjust) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Controlled_Adjustment;

            --  Controlled finalization actions

            elsif Is_Controlled_Proc (Targ_Id, Name_Finalize)
              or else Is_Finalizer_Proc (Targ_Id)
            then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Controlled_Finalization;

            --  Controlled initialization actions

            elsif Is_Controlled_Proc (Targ_Id, Name_Initialize) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Controlled_Initialization;

            --  Default_Initial_Condition verification

            elsif Is_Default_Initial_Condition_Proc (Targ_Id) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Default_Initial_Condition_Verification;

            --  Initialization of object

            elsif Is_Init_Proc (Targ_Id) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Type_Initialization;

            --  Initial_Condition verification

            elsif Is_Initial_Condition_Proc (Targ_Id) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Initial_Condition_Verification;

            --  Instantiation

            elsif Is_Generic_Unit (Targ_Id) then
               Extra := Empty;
               Kind  := Instantiation;

            --  Internal controlled adjustment actions

            elsif Is_TSS (Targ_Id, TSS_Deep_Adjust) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Internal_Controlled_Adjustment;

            --  Internal controlled finalization actions

            elsif Is_TSS (Targ_Id, TSS_Deep_Finalize) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Internal_Controlled_Finalization;

            --  Internal controlled initialization actions

            elsif Is_TSS (Targ_Id, TSS_Deep_Initialize) then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Internal_Controlled_Initialization;

            --  Invariant verification

            elsif Is_Invariant_Proc (Targ_Id)
              or else Is_Partial_Invariant_Proc (Targ_Id)
            then
               Extra := First_Formal_Type (Targ_Id);
               Kind  := Invariant_Verification;

            --  Postcondition verification

            elsif Is_Postconditions_Proc (Targ_Id) then
               Extra := Find_Enclosing_Scope (Spec_Decl);
               Kind  := Postcondition_Verification;

            --  Protected entry call

            elsif Is_Protected_Entry (Targ_Id) then
               Extra := Empty;
               Kind  := Protected_Entry_Call;

            --  Protected subprogram call

            elsif Is_Protected_Subp (Targ_Id) then
               Extra := Empty;
               Kind  := Protected_Subprogram_Call;

            --  Task entry call

            elsif Is_Task_Entry (Targ_Id) then
               Extra := Empty;
               Kind  := Task_Entry_Call;

            --  Entry, operator, or subprogram call. This case must come last
            --  because most invocations above are variations of this case.

            elsif Ekind (Targ_Id) in
                    E_Entry | E_Function | E_Operator | E_Procedure
            then
               Extra := Empty;
               Kind  := Call;

            else
               pragma Assert (False);
               Extra := Empty;
               Kind  := No_Invocation;
            end if;
         end Get_Invocation_Attributes;

         --  Local variables

         Extra     : Entity_Id;
         Extra_Nam : Name_Id;
         Kind      : Invocation_Kind;
         Rel       : Invoker_Target_Relation;

      --  Start of processing for Record_Invocation_Relation

      begin
         Rel.Invoker := Invk_Id;
         Rel.Target  := Targ_Id;

         --  Nothing to do when the invocation relation has already been
         --  recorded in ALI file of the main unit.

         if Is_Saved_Relation (Rel) then
            return;
         end if;

         --  Mark the relation as recorded in the ALI file

         Set_Is_Saved_Relation (Rel);

         --  Declare the invoker in the ALI file

         Declare_Invocation_Construct
           (Constr_Id => Invk_Id,
            In_State  => In_State);

         --  Obtain the invocation-specific attributes of the relation

         Get_Invocation_Attributes (Extra, Kind);

         --  Certain invocations lack an extra entity used in error diagnostics

         if Present (Extra) then
            Extra_Nam := Chars (Extra);
         else
            Extra_Nam := No_Name;
         end if;

         --  Add the relation in the ALI file

         Add_Invocation_Relation
           (Extra        => Extra_Nam,
            Invoker      => Signature_Of (Invk_Id),
            Kind         => Kind,
            Target       => Signature_Of (Targ_Id),
            Update_Units => False);
      end Record_Invocation_Relation;

      -----------------------------------
      -- Record_Simple_Invocation_Path --
      -----------------------------------

      procedure Record_Simple_Invocation_Path
        (In_State : Processing_In_State)
      is
         package Scenarios renames Active_Scenario_Stack;

         Last_Targ  : constant Entity_Id :=
                        Target_Of (Scenarios.Last, In_State);
         First_Targ : Entity_Id;

      begin
         --  The path originates from the elaboration of the body. Add an extra
         --  relation from the elaboration body procedure to the first active
         --  scenario.

         if In_State.Processing = Invocation_Body_Processing then
            Build_Elaborate_Body_Procedure;
            First_Targ := Elab_Body_Id;

         --  The path originates from the elaboration of the spec. Add an extra
         --  relation from the elaboration spec procedure to the first active
         --  scenario.

         elsif In_State.Processing = Invocation_Spec_Processing then
            Build_Elaborate_Spec_Procedure;
            First_Targ := Elab_Spec_Id;

         else
            First_Targ := Target_Of (Scenarios.First, In_State);
         end if;

         --  Record a single relation from the first to the last scenario

         if First_Targ /= Last_Targ then
            Record_Invocation_Relation
              (Invk_Id  => First_Targ,
               Targ_Id  => Last_Targ,
               In_State => In_State);
         end if;
      end Record_Simple_Invocation_Path;

      ----------------------------
      -- Set_Is_Saved_Construct --
      ----------------------------

      procedure Set_Is_Saved_Construct (Constr : Entity_Id) is
         pragma Assert (Present (Constr));

      begin
         NE_Set.Insert (Saved_Constructs_Set, Constr);
      end Set_Is_Saved_Construct;

      ---------------------------
      -- Set_Is_Saved_Relation --
      ---------------------------

      procedure Set_Is_Saved_Relation (Rel : Invoker_Target_Relation) is
      begin
         IR_Set.Insert (Saved_Relations_Set, Rel);
      end Set_Is_Saved_Relation;

      ------------------
      -- Signature_Of --
      ------------------

      function Signature_Of (Id : Entity_Id) return Invocation_Signature_Id is
         Loc : constant Source_Ptr := Sloc (Id);

         function Instantiation_Locations return Name_Id;
         pragma Inline (Instantiation_Locations);
         --  Create a concatenation of all lines and colums of each instance
         --  where source location Loc appears. Return No_Name if no instances
         --  exist.

         function Qualified_Scope return Name_Id;
         pragma Inline (Qualified_Scope);
         --  Obtain the qualified name of Id's scope

         -----------------------------
         -- Instantiation_Locations --
         -----------------------------

         function Instantiation_Locations return Name_Id is
            Buffer  : Bounded_String (2052);
            Inst    : Source_Ptr;
            Loc_Nam : Name_Id;
            SFI     : Source_File_Index;

         begin
            SFI  := Get_Source_File_Index (Loc);
            Inst := Instantiation (SFI);

            --  The location is within an instance. Construct a concatenation
            --  of all lines and colums of each individual instance using the
            --  following format:
            --
            --    line1_column1_line2_column2_ ... _lineN_columnN

            if Inst /= No_Location then
               loop
                  Append (Buffer, Nat (Get_Logical_Line_Number (Inst)));
                  Append (Buffer, '_');
                  Append (Buffer, Nat (Get_Column_Number (Inst)));

                  SFI  := Get_Source_File_Index (Inst);
                  Inst := Instantiation (SFI);

                  exit when Inst = No_Location;

                  Append (Buffer, '_');
               end loop;

               Loc_Nam := Name_Find (Buffer);
               return Loc_Nam;

            --  Otherwise there no instances are involved

            else
               return No_Name;
            end if;
         end Instantiation_Locations;

         ---------------------
         -- Qualified_Scope --
         ---------------------

         function Qualified_Scope return Name_Id is
            Scop : Entity_Id;

         begin
            Scop := Scope (Id);

            --  The entity appears within an anonymous concurrent type created
            --  for a single protected or task type declaration. Use the entity
            --  of the anonymous object as it represents the original scope.

            if Is_Concurrent_Type (Scop)
              and then Present (Anonymous_Object (Scop))
            then
               Scop := Anonymous_Object (Scop);
            end if;

            return Get_Qualified_Name (Scop);
         end Qualified_Scope;

      --  Start of processing for Signature_Of

      begin
         return
           Invocation_Signature_Of
             (Column    => Nat (Get_Column_Number (Loc)),
              Line      => Nat (Get_Logical_Line_Number (Loc)),
              Locations => Instantiation_Locations,
              Name      => Chars (Id),
              Scope     => Qualified_Scope);
      end Signature_Of;

      ---------------
      -- Target_Of --
      ---------------

      function Target_Of
        (Pos      : Active_Scenario_Pos;
         In_State : Processing_In_State) return Entity_Id
      is
         package Scenarios renames Active_Scenario_Stack;

         --  Ensure that the position is within the bounds of the active
         --  scenario stack.

         pragma Assert (Scenarios.First <= Pos);
         pragma Assert (Pos <= Scenarios.Last);

         Scen_Rep : constant Scenario_Rep_Id :=
                      Scenario_Representation_Of
                        (Scenarios.Table (Pos), In_State);

      begin
         --  The true target of an activation call is the current task type
         --  rather than routine Activate_Tasks.

         if Kind (Scen_Rep) = Task_Activation_Scenario then
            return Activated_Task_Type (Scen_Rep);
         else
            return Target (Scen_Rep);
         end if;
      end Target_Of;

      ------------------------------
      -- Traverse_Invocation_Body --
      ------------------------------

      procedure Traverse_Invocation_Body
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
      begin
         Traverse_Body
           (N                   => N,
            Requires_Processing => Is_Invocation_Scenario'Access,
            Processor           => Process_Invocation_Scenario'Access,
            In_State            => In_State);
      end Traverse_Invocation_Body;

      ---------------------------
      -- Write_Invocation_Path --
      ---------------------------

      procedure Write_Invocation_Path (In_State : Processing_In_State) is
         procedure Write_Target (Targ_Id : Entity_Id; Is_First : Boolean);
         pragma Inline (Write_Target);
         --  Write out invocation target Targ_Id to standard output. Flag
         --  Is_First should be set when the target is first in a path.

         -------------
         -- Targ_Id --
         -------------

         procedure Write_Target (Targ_Id : Entity_Id; Is_First : Boolean) is
         begin
            if not Is_First then
               Write_Str ("  --> ");
            end if;

            Write_Name (Get_Qualified_Name (Targ_Id));
            Write_Eol;
         end Write_Target;

         --  Local variables

         package Scenarios renames Active_Scenario_Stack;

         First_Seen : Boolean := False;

      --  Start of processing for Write_Invocation_Path

      begin
         --  Nothing to do when flag -gnatd_T (output trace information on
         --  invocation path recording) is not in effect.

         if not Debug_Flag_Underscore_TT then
            return;
         end if;

         --  The path originates from the elaboration of the body. Write the
         --  elaboration body procedure.

         if In_State.Processing = Invocation_Body_Processing then
            Write_Target (Elab_Body_Id, True);
            First_Seen := True;

         --  The path originates from the elaboration of the spec. Write the
         --  elaboration spec procedure.

         elsif In_State.Processing = Invocation_Spec_Processing then
            Write_Target (Elab_Spec_Id, True);
            First_Seen := True;
         end if;

         --  Write each individual target invoked by its corresponding scenario
         --  on the active scenario stack.

         for Index in Scenarios.First .. Scenarios.Last loop
            Write_Target
              (Targ_Id  => Target_Of (Index, In_State),
               Is_First => Index = Scenarios.First and then not First_Seen);
         end loop;

         Write_Eol;
      end Write_Invocation_Path;
   end Invocation_Graph;

   ------------------------
   -- Is_Safe_Activation --
   ------------------------

   function Is_Safe_Activation
     (Call     : Node_Id;
      Task_Rep : Target_Rep_Id) return Boolean
   is
   begin
      --  The activation of a task coming from an external instance cannot
      --  cause an ABE because the generic was already instantiated. Note
      --  that the instantiation itself may lead to an ABE.

      return
        In_External_Instance
          (N           => Call,
           Target_Decl => Spec_Declaration (Task_Rep));
   end Is_Safe_Activation;

   ------------------
   -- Is_Safe_Call --
   ------------------

   function Is_Safe_Call
     (Call     : Node_Id;
      Subp_Id  : Entity_Id;
      Subp_Rep : Target_Rep_Id) return Boolean
   is
      Body_Decl : constant Node_Id := Body_Declaration (Subp_Rep);
      Spec_Decl : constant Node_Id := Spec_Declaration (Subp_Rep);

   begin
      --  The target is either an abstract subprogram, formal subprogram, or
      --  imported, in which case it does not have a body at compile or bind
      --  time. Assume that the call is ABE-safe.

      if Is_Bodiless_Subprogram (Subp_Id) then
         return True;

      --  The target is an instantiation of a generic subprogram. The call
      --  cannot cause an ABE because the generic was already instantiated.
      --  Note that the instantiation itself may lead to an ABE.

      elsif Is_Generic_Instance (Subp_Id) then
         return True;

      --  The invocation of a target coming from an external instance cannot
      --  cause an ABE because the generic was already instantiated. Note that
      --  the instantiation itself may lead to an ABE.

      elsif In_External_Instance
              (N           => Call,
               Target_Decl => Spec_Decl)
      then
         return True;

      --  The target is a subprogram body without a previous declaration. The
      --  call cannot cause an ABE because the body has already been seen.

      elsif Nkind (Spec_Decl) = N_Subprogram_Body
        and then No (Corresponding_Spec (Spec_Decl))
      then
         return True;

      --  The target is a subprogram body stub without a prior declaration.
      --  The call cannot cause an ABE because the proper body substitutes
      --  the stub.

      elsif Nkind (Spec_Decl) = N_Subprogram_Body_Stub
        and then No (Corresponding_Spec_Of_Stub (Spec_Decl))
      then
         return True;

      --  A call to an expression function that is not a completion cannot
      --  cause an ABE because it has no prior declaration; this remains
      --  true even if the FE transforms the callee into something else.

      elsif Nkind (Original_Node (Spec_Decl)) = N_Expression_Function then
         return True;

      --  Subprogram bodies which wrap attribute references used as actuals
      --  in instantiations are always ABE-safe. These bodies are artifacts
      --  of expansion.

      elsif Present (Body_Decl)
        and then Nkind (Body_Decl) = N_Subprogram_Body
        and then Was_Attribute_Reference (Body_Decl)
      then
         return True;
      end if;

      return False;
   end Is_Safe_Call;

   ---------------------------
   -- Is_Safe_Instantiation --
   ---------------------------

   function Is_Safe_Instantiation
     (Inst    : Node_Id;
      Gen_Id  : Entity_Id;
      Gen_Rep : Target_Rep_Id) return Boolean
   is
      Spec_Decl : constant Node_Id := Spec_Declaration (Gen_Rep);

   begin
      --  The generic is an intrinsic subprogram in which case it does not
      --  have a body at compile or bind time. Assume that the instantiation
      --  is ABE-safe.

      if Is_Bodiless_Subprogram (Gen_Id) then
         return True;

      --  The instantiation of an external nested generic cannot cause an ABE
      --  if the outer generic was already instantiated. Note that the instance
      --  of the outer generic may lead to an ABE.

      elsif In_External_Instance
              (N           => Inst,
               Target_Decl => Spec_Decl)
      then
         return True;

      --  The generic is a package. The instantiation cannot cause an ABE when
      --  the package has no body.

      elsif Ekind (Gen_Id) = E_Generic_Package
        and then not Has_Body (Spec_Decl)
      then
         return True;
      end if;

      return False;
   end Is_Safe_Instantiation;

   ------------------
   -- Is_Same_Unit --
   ------------------

   function Is_Same_Unit
     (Unit_1 : Entity_Id;
      Unit_2 : Entity_Id) return Boolean
   is
   begin
      return Unit_Entity (Unit_1) = Unit_Entity (Unit_2);
   end Is_Same_Unit;

   -------------------------------
   -- Kill_Elaboration_Scenario --
   -------------------------------

   procedure Kill_Elaboration_Scenario (N : Node_Id) is
   begin
      --  Nothing to do when switch -gnatH (legacy elaboration checking mode
      --  enabled) is in effect because the legacy ABE lechanism does not need
      --  to carry out this action.

      if Legacy_Elaboration_Checks then
         return;

      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      elsif not Elaboration_Phase_Active then
         return;
      end if;

      --  Eliminate a recorded scenario when it appears within dead code
      --  because it will not be executed at elaboration time.

      if Is_Scenario (N) then
         Delete_Scenario (N);
      end if;
   end Kill_Elaboration_Scenario;

   ----------------------
   -- Main_Unit_Entity --
   ----------------------

   function Main_Unit_Entity return Entity_Id is
   begin
      --  Note that Cunit_Entity (Main_Unit) is not reliable in the presence of
      --  generic bodies and may return an outdated entity.

      return Defining_Entity (Unit (Cunit (Main_Unit)));
   end Main_Unit_Entity;

   ----------------------
   -- Non_Private_View --
   ----------------------

   function Non_Private_View (Typ : Entity_Id) return Entity_Id is
   begin
      if Is_Private_Type (Typ) and then Present (Full_View (Typ)) then
         return Full_View (Typ);
      else
         return Typ;
      end if;
   end Non_Private_View;

   ---------------------------------
   -- Record_Elaboration_Scenario --
   ---------------------------------

   procedure Record_Elaboration_Scenario (N : Node_Id) is
      procedure Check_Preelaborated_Call
        (Call     : Node_Id;
         Call_Lvl : Enclosing_Level_Kind);
      pragma Inline (Check_Preelaborated_Call);
      --  Verify that entry, operator, or subprogram call Call with enclosing
      --  level Call_Lvl does not appear at the library level of preelaborated
      --  unit.

      function Find_Code_Unit (Nod : Node_Or_Entity_Id) return Entity_Id;
      pragma Inline (Find_Code_Unit);
      --  Return the code unit which contains arbitrary node or entity Nod.
      --  This is the unit of the file which physically contains the related
      --  construct denoted by Nod except when Nod is within an instantiation.
      --  In that case the unit is that of the top-level instantiation.

      function In_Preelaborated_Context (Nod : Node_Id) return Boolean;
      pragma Inline (In_Preelaborated_Context);
      --  Determine whether arbitrary node Nod appears within a preelaborated
      --  context.

      procedure Record_Access_Taken
        (Attr     : Node_Id;
         Attr_Lvl : Enclosing_Level_Kind);
      pragma Inline (Record_Access_Taken);
      --  Record 'Access scenario Attr with enclosing level Attr_Lvl

      procedure Record_Call_Or_Task_Activation
        (Call     : Node_Id;
         Call_Lvl : Enclosing_Level_Kind);
      pragma Inline (Record_Call_Or_Task_Activation);
      --  Record call scenario Call with enclosing level Call_Lvl

      procedure Record_Instantiation
        (Inst     : Node_Id;
         Inst_Lvl : Enclosing_Level_Kind);
      pragma Inline (Record_Instantiation);
      --  Record instantiation scenario Inst with enclosing level Inst_Lvl

      procedure Record_Variable_Assignment
        (Asmt     : Node_Id;
         Asmt_Lvl : Enclosing_Level_Kind);
      pragma Inline (Record_Variable_Assignment);
      --  Record variable assignment scenario Asmt with enclosing level
      --  Asmt_Lvl.

      procedure Record_Variable_Reference
        (Ref     : Node_Id;
         Ref_Lvl : Enclosing_Level_Kind);
      pragma Inline (Record_Variable_Reference);
      --  Record variable reference scenario Ref with enclosing level Ref_Lvl

      ------------------------------
      -- Check_Preelaborated_Call --
      ------------------------------

      procedure Check_Preelaborated_Call
        (Call     : Node_Id;
         Call_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Nothing to do when the call is internally generated because it is
         --  assumed that it will never violate preelaboration.

         if not Is_Source_Call (Call) then
            return;

         --  Nothing to do when the call is preelaborable by definition

         elsif Is_Preelaborable_Call (Call) then
            return;

         --  Library-level calls are always considered because they are part of
         --  the associated unit's elaboration actions.

         elsif Call_Lvl in Library_Level then
            null;

         --  Calls at the library level of a generic package body have to be
         --  checked because they would render an instantiation illegal if the
         --  template is marked as preelaborated. Note that this does not apply
         --  to calls at the library level of a generic package spec.

         elsif Call_Lvl = Generic_Body_Level then
            null;

         --  Otherwise the call does not appear at the proper level and must
         --  not be considered for this check.

         else
            return;
         end if;

         --  If the call appears within a preelaborated unit, give an error

         if In_Preelaborated_Context (Call) then
            Error_Preelaborated_Call (Call);
         end if;
      end Check_Preelaborated_Call;

      --------------------
      -- Find_Code_Unit --
      --------------------

      function Find_Code_Unit (Nod : Node_Or_Entity_Id) return Entity_Id is
      begin
         return Find_Unit_Entity (Unit (Cunit (Get_Code_Unit (Nod))));
      end Find_Code_Unit;

      ------------------------------
      -- In_Preelaborated_Context --
      ------------------------------

      function In_Preelaborated_Context (Nod : Node_Id) return Boolean is
         Body_Id : constant Entity_Id := Find_Code_Unit (Nod);
         Spec_Id : constant Entity_Id := Unique_Entity (Body_Id);

      begin
         --  The node appears within a package body whose corresponding spec is
         --  subject to pragma Remote_Call_Interface or Remote_Types. This does
         --  not result in a preelaborated context because the package body may
         --  be on another machine.

         if Ekind (Body_Id) = E_Package_Body
           and then Is_Package_Or_Generic_Package (Spec_Id)
           and then (Is_Remote_Call_Interface (Spec_Id)
                      or else Is_Remote_Types (Spec_Id))
         then
            return False;

         --  Otherwise the node appears within a preelaborated context when the
         --  associated unit is preelaborated.

         else
            return Is_Preelaborated_Unit (Spec_Id);
         end if;
      end In_Preelaborated_Context;

      -------------------------
      -- Record_Access_Taken --
      -------------------------

      procedure Record_Access_Taken
        (Attr     : Node_Id;
         Attr_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Signal any enclosing local exception handlers that the 'Access may
         --  raise Program_Error due to a failed ABE check when switch -gnatd.o
         --  (conservative elaboration order for indirect calls) is in effect.
         --  Marking the exception handlers ensures proper expansion by both
         --  the front and back end restriction when No_Exception_Propagation
         --  is in effect.

         if Debug_Flag_Dot_O then
            Possible_Local_Raise (Attr, Standard_Program_Error);
         end if;

         --  Add 'Access to the appropriate set

         if Attr_Lvl = Library_Body_Level then
            Add_Library_Body_Scenario (Attr);

         elsif Attr_Lvl = Library_Spec_Level
           or else Attr_Lvl = Instantiation_Level
         then
            Add_Library_Spec_Scenario (Attr);
         end if;

         --  'Access requires a conditional ABE check when the dynamic model is
         --  in effect.

         Add_Dynamic_ABE_Check_Scenario (Attr);
      end Record_Access_Taken;

      ------------------------------------
      -- Record_Call_Or_Task_Activation --
      ------------------------------------

      procedure Record_Call_Or_Task_Activation
        (Call     : Node_Id;
         Call_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Signal any enclosing local exception handlers that the call may
         --  raise Program_Error due to failed ABE check. Marking the exception
         --  handlers ensures proper expansion by both the front and back end
         --  restriction when No_Exception_Propagation is in effect.

         Possible_Local_Raise (Call, Standard_Program_Error);

         --  Perform early detection of guaranteed ABEs in order to suppress
         --  the instantiation of generic bodies because gigi cannot handle
         --  certain types of premature instantiations.

         Process_Guaranteed_ABE
           (N        => Call,
            In_State => Guaranteed_ABE_State);

         --  Add the call or task activation to the appropriate set

         if Call_Lvl = Declaration_Level then
            Add_Declaration_Scenario (Call);

         elsif Call_Lvl = Library_Body_Level then
            Add_Library_Body_Scenario (Call);

         elsif Call_Lvl = Library_Spec_Level
           or else Call_Lvl = Instantiation_Level
         then
            Add_Library_Spec_Scenario (Call);
         end if;

         --  A call or a task activation requires a conditional ABE check when
         --  the dynamic model is in effect.

         Add_Dynamic_ABE_Check_Scenario (Call);
      end Record_Call_Or_Task_Activation;

      --------------------------
      -- Record_Instantiation --
      --------------------------

      procedure Record_Instantiation
        (Inst     : Node_Id;
         Inst_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Signal enclosing local exception handlers that instantiation may
         --  raise Program_Error due to failed ABE check. Marking the exception
         --  handlers ensures proper expansion by both the front and back end
         --  restriction when No_Exception_Propagation is in effect.

         Possible_Local_Raise (Inst, Standard_Program_Error);

         --  Perform early detection of guaranteed ABEs in order to suppress
         --  the instantiation of generic bodies because gigi cannot handle
         --  certain types of premature instantiations.

         Process_Guaranteed_ABE
           (N        => Inst,
            In_State => Guaranteed_ABE_State);

         --  Add the instantiation to the appropriate set

         if Inst_Lvl = Declaration_Level then
            Add_Declaration_Scenario (Inst);

         elsif Inst_Lvl = Library_Body_Level then
            Add_Library_Body_Scenario (Inst);

         elsif Inst_Lvl = Library_Spec_Level
           or else Inst_Lvl = Instantiation_Level
         then
            Add_Library_Spec_Scenario (Inst);
         end if;

         --  Instantiations of generics subject to SPARK_Mode On require
         --  elaboration-related checks even though the instantiations may
         --  not appear within elaboration code.

         if Is_Suitable_SPARK_Instantiation (Inst) then
            Add_SPARK_Scenario (Inst);
         end if;

         --  An instantiation requires a conditional ABE check when the dynamic
         --  model is in effect.

         Add_Dynamic_ABE_Check_Scenario (Inst);
      end Record_Instantiation;

      --------------------------------
      -- Record_Variable_Assignment --
      --------------------------------

      procedure Record_Variable_Assignment
        (Asmt     : Node_Id;
         Asmt_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Add the variable assignment to the appropriate set

         if Asmt_Lvl = Library_Body_Level then
            Add_Library_Body_Scenario (Asmt);

         elsif Asmt_Lvl = Library_Spec_Level
           or else Asmt_Lvl = Instantiation_Level
         then
            Add_Library_Spec_Scenario (Asmt);
         end if;
      end Record_Variable_Assignment;

      -------------------------------
      -- Record_Variable_Reference --
      -------------------------------

      procedure Record_Variable_Reference
        (Ref     : Node_Id;
         Ref_Lvl : Enclosing_Level_Kind)
      is
      begin
         --  Add the variable reference to the appropriate set

         if Ref_Lvl = Library_Body_Level then
            Add_Library_Body_Scenario (Ref);

         elsif Ref_Lvl = Library_Spec_Level
           or else Ref_Lvl = Instantiation_Level
         then
            Add_Library_Spec_Scenario (Ref);
         end if;
      end Record_Variable_Reference;

      --  Local variables

      Scen     : constant Node_Id := Scenario (N);
      Scen_Lvl : Enclosing_Level_Kind;

   --  Start of processing for Record_Elaboration_Scenario

   begin
      --  Nothing to do when switch -gnatH (legacy elaboration checking mode
      --  enabled) is in effect because the legacy ABE mechanism does not need
      --  to carry out this action.

      if Legacy_Elaboration_Checks then
         return;

      --  Nothing to do when the scenario is being preanalyzed

      elsif Preanalysis_Active then
         return;

      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      elsif not Elaboration_Phase_Active then
         return;
      end if;

      Scen_Lvl := Find_Enclosing_Level (Scen);

      --  Ensure that a library-level call does not appear in a preelaborated
      --  unit. The check must come before ignoring scenarios within external
      --  units or inside generics because calls in those context must also be
      --  verified.

      if Is_Suitable_Call (Scen) then
         Check_Preelaborated_Call (Scen, Scen_Lvl);
      end if;

      --  Nothing to do when the scenario does not appear within the main unit

      if not In_Main_Context (Scen) then
         return;

      --  Nothing to do when the scenario appears within a generic

      elsif Inside_A_Generic then
         return;

      --  'Access

      elsif Is_Suitable_Access_Taken (Scen) then
         Record_Access_Taken
           (Attr     => Scen,
            Attr_Lvl => Scen_Lvl);

      --  Call or task activation

      elsif Is_Suitable_Call (Scen) then
         Record_Call_Or_Task_Activation
           (Call     => Scen,
            Call_Lvl => Scen_Lvl);

      --  Derived type declaration

      elsif Is_Suitable_SPARK_Derived_Type (Scen) then
         Add_SPARK_Scenario (Scen);

      --  Instantiation

      elsif Is_Suitable_Instantiation (Scen) then
         Record_Instantiation
           (Inst     => Scen,
            Inst_Lvl => Scen_Lvl);

      --  Refined_State pragma

      elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
         Add_SPARK_Scenario (Scen);

      --  Variable assignment

      elsif Is_Suitable_Variable_Assignment (Scen) then
         Record_Variable_Assignment
           (Asmt     => Scen,
            Asmt_Lvl => Scen_Lvl);

      --  Variable reference

      elsif Is_Suitable_Variable_Reference (Scen) then
         Record_Variable_Reference
           (Ref     => Scen,
            Ref_Lvl => Scen_Lvl);
      end if;
   end Record_Elaboration_Scenario;

   --------------
   -- Scenario --
   --------------

   function Scenario (N : Node_Id) return Node_Id is
      Orig_N : constant Node_Id := Original_Node (N);

   begin
      --  An expanded instantiation is rewritten into a spec-body pair where
      --  N denotes the spec. In this case the original instantiation is the
      --  proper elaboration scenario.

      if Nkind (Orig_N) in N_Generic_Instantiation then
         return Orig_N;

      --  Otherwise the scenario is already in its proper form

      else
         return N;
      end if;
   end Scenario;

   ----------------------
   -- Scenario_Storage --
   ----------------------

   package body Scenario_Storage is

      ---------------------
      -- Data structures --
      ---------------------

      --  The following sets store all scenarios

      Declaration_Scenarios       : NE_Set.Membership_Set := NE_Set.Nil;
      Dynamic_ABE_Check_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
      Library_Body_Scenarios      : NE_Set.Membership_Set := NE_Set.Nil;
      Library_Spec_Scenarios      : NE_Set.Membership_Set := NE_Set.Nil;
      SPARK_Scenarios             : NE_Set.Membership_Set := NE_Set.Nil;

      -------------------------------
      -- Finalize_Scenario_Storage --
      -------------------------------

      procedure Finalize_Scenario_Storage is
      begin
         NE_Set.Destroy (Declaration_Scenarios);
         NE_Set.Destroy (Dynamic_ABE_Check_Scenarios);
         NE_Set.Destroy (Library_Body_Scenarios);
         NE_Set.Destroy (Library_Spec_Scenarios);
         NE_Set.Destroy (SPARK_Scenarios);
      end Finalize_Scenario_Storage;

      ---------------------------------
      -- Initialize_Scenario_Storage --
      ---------------------------------

      procedure Initialize_Scenario_Storage is
      begin
         Declaration_Scenarios       := NE_Set.Create (1000);
         Dynamic_ABE_Check_Scenarios := NE_Set.Create (500);
         Library_Body_Scenarios      := NE_Set.Create (1000);
         Library_Spec_Scenarios      := NE_Set.Create (1000);
         SPARK_Scenarios             := NE_Set.Create (100);
      end Initialize_Scenario_Storage;

      ------------------------------
      -- Add_Declaration_Scenario --
      ------------------------------

      procedure Add_Declaration_Scenario (N : Node_Id) is
         pragma Assert (Present (N));
      begin
         NE_Set.Insert (Declaration_Scenarios, N);
      end Add_Declaration_Scenario;

      ------------------------------------
      -- Add_Dynamic_ABE_Check_Scenario --
      ------------------------------------

      procedure Add_Dynamic_ABE_Check_Scenario (N : Node_Id) is
         pragma Assert (Present (N));

      begin
         if not Check_Or_Failure_Generation_OK then
            return;

         --  Nothing to do if the dynamic model is not in effect

         elsif not Dynamic_Elaboration_Checks then
            return;
         end if;

         NE_Set.Insert (Dynamic_ABE_Check_Scenarios, N);
      end Add_Dynamic_ABE_Check_Scenario;

      -------------------------------
      -- Add_Library_Body_Scenario --
      -------------------------------

      procedure Add_Library_Body_Scenario (N : Node_Id) is
         pragma Assert (Present (N));
      begin
         NE_Set.Insert (Library_Body_Scenarios, N);
      end Add_Library_Body_Scenario;

      -------------------------------
      -- Add_Library_Spec_Scenario --
      -------------------------------

      procedure Add_Library_Spec_Scenario (N : Node_Id) is
         pragma Assert (Present (N));
      begin
         NE_Set.Insert (Library_Spec_Scenarios, N);
      end Add_Library_Spec_Scenario;

      ------------------------
      -- Add_SPARK_Scenario --
      ------------------------

      procedure Add_SPARK_Scenario (N : Node_Id) is
         pragma Assert (Present (N));
      begin
         NE_Set.Insert (SPARK_Scenarios, N);
      end Add_SPARK_Scenario;

      ---------------------
      -- Delete_Scenario --
      ---------------------

      procedure Delete_Scenario (N : Node_Id) is
         pragma Assert (Present (N));

      begin
         --  Delete the scenario from whichever set it belongs to

         NE_Set.Delete (Declaration_Scenarios,       N);
         NE_Set.Delete (Dynamic_ABE_Check_Scenarios, N);
         NE_Set.Delete (Library_Body_Scenarios,      N);
         NE_Set.Delete (Library_Spec_Scenarios,      N);
         NE_Set.Delete (SPARK_Scenarios,             N);
      end Delete_Scenario;

      -----------------------------------
      -- Iterate_Declaration_Scenarios --
      -----------------------------------

      function Iterate_Declaration_Scenarios return NE_Set.Iterator is
      begin
         return NE_Set.Iterate (Declaration_Scenarios);
      end Iterate_Declaration_Scenarios;

      -----------------------------------------
      -- Iterate_Dynamic_ABE_Check_Scenarios --
      -----------------------------------------

      function Iterate_Dynamic_ABE_Check_Scenarios return NE_Set.Iterator is
      begin
         return NE_Set.Iterate (Dynamic_ABE_Check_Scenarios);
      end Iterate_Dynamic_ABE_Check_Scenarios;

      ------------------------------------
      -- Iterate_Library_Body_Scenarios --
      ------------------------------------

      function Iterate_Library_Body_Scenarios return NE_Set.Iterator is
      begin
         return NE_Set.Iterate (Library_Body_Scenarios);
      end Iterate_Library_Body_Scenarios;

      ------------------------------------
      -- Iterate_Library_Spec_Scenarios --
      ------------------------------------

      function Iterate_Library_Spec_Scenarios return NE_Set.Iterator is
      begin
         return NE_Set.Iterate (Library_Spec_Scenarios);
      end Iterate_Library_Spec_Scenarios;

      -----------------------------
      -- Iterate_SPARK_Scenarios --
      -----------------------------

      function Iterate_SPARK_Scenarios return NE_Set.Iterator is
      begin
         return NE_Set.Iterate (SPARK_Scenarios);
      end Iterate_SPARK_Scenarios;

      ----------------------
      -- Replace_Scenario --
      ----------------------

      procedure Replace_Scenario (Old_N : Node_Id; New_N : Node_Id) is
         procedure Replace_Scenario_In (Scenarios : NE_Set.Membership_Set);
         --  Determine whether scenario Old_N is present in set Scenarios, and
         --  if this is the case it, replace it with New_N.

         -------------------------
         -- Replace_Scenario_In --
         -------------------------

         procedure Replace_Scenario_In (Scenarios : NE_Set.Membership_Set) is
         begin
            --  The set is intentionally checked for existance because node
            --  rewriting may occur after Sem_Elab has verified all scenarios
            --  and data structures have been destroyed.

            if NE_Set.Present (Scenarios)
              and then NE_Set.Contains (Scenarios, Old_N)
            then
               NE_Set.Delete (Scenarios, Old_N);
               NE_Set.Insert (Scenarios, New_N);
            end if;
         end Replace_Scenario_In;

      --  Start of processing for Replace_Scenario

      begin
         Replace_Scenario_In (Declaration_Scenarios);
         Replace_Scenario_In (Dynamic_ABE_Check_Scenarios);
         Replace_Scenario_In (Library_Body_Scenarios);
         Replace_Scenario_In (Library_Spec_Scenarios);
         Replace_Scenario_In (SPARK_Scenarios);
      end Replace_Scenario;
   end Scenario_Storage;

   ---------------
   -- Semantics --
   ---------------

   package body Semantics is

      --------------------------------
      -- Is_Accept_Alternative_Proc --
      --------------------------------

      function Is_Accept_Alternative_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a procedure with a receiving
         --  entry.

         return
           Ekind (Id) = E_Procedure and then Present (Receiving_Entry (Id));
      end Is_Accept_Alternative_Proc;

      ------------------------
      -- Is_Activation_Proc --
      ------------------------

      function Is_Activation_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote one of the runtime procedures
         --  in charge of task activation.

         if Ekind (Id) = E_Procedure then
            if Restricted_Profile then
               return Is_RTE (Id, RE_Activate_Restricted_Tasks);
            else
               return Is_RTE (Id, RE_Activate_Tasks);
            end if;
         end if;

         return False;
      end Is_Activation_Proc;

      ----------------------------
      -- Is_Ada_Semantic_Target --
      ----------------------------

      function Is_Ada_Semantic_Target (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Activation_Proc (Id)
             or else Is_Controlled_Proc (Id, Name_Adjust)
             or else Is_Controlled_Proc (Id, Name_Finalize)
             or else Is_Controlled_Proc (Id, Name_Initialize)
             or else Is_Init_Proc (Id)
             or else Is_Invariant_Proc (Id)
             or else Is_Protected_Entry (Id)
             or else Is_Protected_Subp (Id)
             or else Is_Protected_Body_Subp (Id)
             or else Is_Subprogram_Inst (Id)
             or else Is_Task_Entry (Id);
      end Is_Ada_Semantic_Target;

      --------------------------------
      -- Is_Assertion_Pragma_Target --
      --------------------------------

      function Is_Assertion_Pragma_Target (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Default_Initial_Condition_Proc (Id)
             or else Is_Initial_Condition_Proc (Id)
             or else Is_Invariant_Proc (Id)
             or else Is_Partial_Invariant_Proc (Id)
             or else Is_Postconditions_Proc (Id);
      end Is_Assertion_Pragma_Target;

      ----------------------------
      -- Is_Bodiless_Subprogram --
      ----------------------------

      function Is_Bodiless_Subprogram (Subp_Id : Entity_Id) return Boolean is
      begin
         --  An abstract subprogram does not have a body

         if Ekind (Subp_Id) in E_Function | E_Operator | E_Procedure
           and then Is_Abstract_Subprogram (Subp_Id)
         then
            return True;

         --  A formal subprogram does not have a body

         elsif Is_Formal_Subprogram (Subp_Id) then
            return True;

         --  An imported subprogram may have a body, however it is not known at
         --  compile or bind time where the body resides and whether it will be
         --  elaborated on time.

         elsif Is_Imported (Subp_Id) then
            return True;
         end if;

         return False;
      end Is_Bodiless_Subprogram;

      ----------------------
      -- Is_Bridge_Target --
      ----------------------

      function Is_Bridge_Target (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Accept_Alternative_Proc (Id)
             or else Is_Finalizer_Proc (Id)
             or else Is_Partial_Invariant_Proc (Id)
             or else Is_Postconditions_Proc (Id)
             or else Is_TSS (Id, TSS_Deep_Adjust)
             or else Is_TSS (Id, TSS_Deep_Finalize)
             or else Is_TSS (Id, TSS_Deep_Initialize);
      end Is_Bridge_Target;

      ------------------------
      -- Is_Controlled_Proc --
      ------------------------

      function Is_Controlled_Proc
        (Subp_Id  : Entity_Id;
         Subp_Nam : Name_Id) return Boolean
      is
         Formal_Id : Entity_Id;

      begin
         pragma Assert
           (Subp_Nam in Name_Adjust | Name_Finalize | Name_Initialize);

         --  To qualify, the subprogram must denote a source procedure with
         --  name Adjust, Finalize, or Initialize where the sole formal is
         --  controlled.

         if Comes_From_Source (Subp_Id)
           and then Ekind (Subp_Id) = E_Procedure
           and then Chars (Subp_Id) = Subp_Nam
         then
            Formal_Id := First_Formal (Subp_Id);

            return
              Present (Formal_Id)
                and then Is_Controlled (Etype (Formal_Id))
                and then No (Next_Formal (Formal_Id));
         end if;

         return False;
      end Is_Controlled_Proc;

      ---------------------------------------
      -- Is_Default_Initial_Condition_Proc --
      ---------------------------------------

      function Is_Default_Initial_Condition_Proc
        (Id : Entity_Id) return Boolean
      is
      begin
         --  To qualify, the entity must denote a Default_Initial_Condition
         --  procedure.

         return Ekind (Id) = E_Procedure and then Is_DIC_Procedure (Id);
      end Is_Default_Initial_Condition_Proc;

      -----------------------
      -- Is_Finalizer_Proc --
      -----------------------

      function Is_Finalizer_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a _Finalizer procedure

         return Ekind (Id) = E_Procedure and then Chars (Id) = Name_uFinalizer;
      end Is_Finalizer_Proc;

      -------------------------------
      -- Is_Initial_Condition_Proc --
      -------------------------------

      function Is_Initial_Condition_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote an Initial_Condition procedure

         return
           Ekind (Id) = E_Procedure
             and then Is_Initial_Condition_Procedure (Id);
      end Is_Initial_Condition_Proc;

      --------------------
      -- Is_Initialized --
      --------------------

      function Is_Initialized (Obj_Decl : Node_Id) return Boolean is
      begin
         --  To qualify, the object declaration must have an expression

         return
           Present (Expression (Obj_Decl))
             or else Has_Init_Expression (Obj_Decl);
      end Is_Initialized;

      -----------------------
      -- Is_Invariant_Proc --
      -----------------------

      function Is_Invariant_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote the "full" invariant procedure

         return Ekind (Id) = E_Procedure and then Is_Invariant_Procedure (Id);
      end Is_Invariant_Proc;

      ---------------------------------------
      -- Is_Non_Library_Level_Encapsulator --
      ---------------------------------------

      function Is_Non_Library_Level_Encapsulator
        (N : Node_Id) return Boolean
      is
      begin
         case Nkind (N) is
            when N_Abstract_Subprogram_Declaration
               | N_Aspect_Specification
               | N_Component_Declaration
               | N_Entry_Body
               | N_Entry_Declaration
               | N_Expression_Function
               | N_Formal_Abstract_Subprogram_Declaration
               | N_Formal_Concrete_Subprogram_Declaration
               | N_Formal_Object_Declaration
               | N_Formal_Package_Declaration
               | N_Formal_Type_Declaration
               | N_Generic_Association
               | N_Implicit_Label_Declaration
               | N_Incomplete_Type_Declaration
               | N_Private_Extension_Declaration
               | N_Private_Type_Declaration
               | N_Protected_Body
               | N_Protected_Type_Declaration
               | N_Single_Protected_Declaration
               | N_Single_Task_Declaration
               | N_Subprogram_Body
               | N_Subprogram_Declaration
               | N_Task_Body
               | N_Task_Type_Declaration
            =>
               return True;

            when others =>
               return Is_Generic_Declaration_Or_Body (N);
         end case;
      end Is_Non_Library_Level_Encapsulator;

      -------------------------------
      -- Is_Partial_Invariant_Proc --
      -------------------------------

      function Is_Partial_Invariant_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote the "partial" invariant
         --  procedure.

         return
           Ekind (Id) = E_Procedure
             and then Is_Partial_Invariant_Procedure (Id);
      end Is_Partial_Invariant_Proc;

      ----------------------------
      -- Is_Postconditions_Proc --
      ----------------------------

      function Is_Postconditions_Proc (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a _Postconditions procedure

         return
           Ekind (Id) = E_Procedure and then Chars (Id) = Name_uPostconditions;
      end Is_Postconditions_Proc;

      ---------------------------
      -- Is_Preelaborated_Unit --
      ---------------------------

      function Is_Preelaborated_Unit (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Preelaborated (Id)
             or else Is_Pure (Id)
             or else Is_Remote_Call_Interface (Id)
             or else Is_Remote_Types (Id)
             or else Is_Shared_Passive (Id);
      end Is_Preelaborated_Unit;

      ------------------------
      -- Is_Protected_Entry --
      ------------------------

      function Is_Protected_Entry (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote an entry defined in a protected
         --  type.

         return
           Is_Entry (Id)
             and then Is_Protected_Type (Non_Private_View (Scope (Id)));
      end Is_Protected_Entry;

      -----------------------
      -- Is_Protected_Subp --
      -----------------------

      function Is_Protected_Subp (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a subprogram defined within a
         --  protected type.

         return
           Ekind (Id) in E_Function | E_Procedure
             and then Is_Protected_Type (Non_Private_View (Scope (Id)));
      end Is_Protected_Subp;

      ----------------------------
      -- Is_Protected_Body_Subp --
      ----------------------------

      function Is_Protected_Body_Subp (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a subprogram with attribute
         --  Protected_Subprogram set.

         return
           Ekind (Id) in E_Function | E_Procedure
             and then Present (Protected_Subprogram (Id));
      end Is_Protected_Body_Subp;

      -----------------
      -- Is_Scenario --
      -----------------

      function Is_Scenario (N : Node_Id) return Boolean is
      begin
         case Nkind (N) is
            when N_Assignment_Statement
               | N_Attribute_Reference
               | N_Call_Marker
               | N_Entry_Call_Statement
               | N_Expanded_Name
               | N_Function_Call
               | N_Function_Instantiation
               | N_Identifier
               | N_Package_Instantiation
               | N_Procedure_Call_Statement
               | N_Procedure_Instantiation
               | N_Requeue_Statement
            =>
               return True;

            when others =>
               return False;
         end case;
      end Is_Scenario;

      ------------------------------
      -- Is_SPARK_Semantic_Target --
      ------------------------------

      function Is_SPARK_Semantic_Target (Id : Entity_Id) return Boolean is
      begin
         return
           Is_Default_Initial_Condition_Proc (Id)
             or else Is_Initial_Condition_Proc (Id);
      end Is_SPARK_Semantic_Target;

      ------------------------
      -- Is_Subprogram_Inst --
      ------------------------

      function Is_Subprogram_Inst (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote a function or a procedure which
         --  is hidden within an anonymous package, and is a generic instance.

         return
           Ekind (Id) in E_Function | E_Procedure
             and then Is_Hidden (Id)
             and then Is_Generic_Instance (Id);
      end Is_Subprogram_Inst;

      ------------------------------
      -- Is_Suitable_Access_Taken --
      ------------------------------

      function Is_Suitable_Access_Taken (N : Node_Id) return Boolean is
         Nam     : Name_Id;
         Pref    : Node_Id;
         Subp_Id : Entity_Id;

      begin
         --  Nothing to do when switch -gnatd.U (ignore 'Access) is in effect

         if Debug_Flag_Dot_UU then
            return False;

         --  Nothing to do when the scenario is not an attribute reference

         elsif Nkind (N) /= N_Attribute_Reference then
            return False;

         --  Nothing to do for internally-generated attributes because they are
         --  assumed to be ABE safe.

         elsif not Comes_From_Source (N) then
            return False;
         end if;

         Nam  := Attribute_Name (N);
         Pref := Prefix (N);

         --  Sanitize the prefix of the attribute

         if not Is_Entity_Name (Pref) then
            return False;

         elsif No (Entity (Pref)) then
            return False;
         end if;

         Subp_Id := Entity (Pref);

         if not Is_Subprogram_Or_Entry (Subp_Id) then
            return False;
         end if;

         --  Traverse a possible chain of renamings to obtain the original
         --  entry or subprogram which the prefix may rename.

         Subp_Id := Get_Renamed_Entity (Subp_Id);

         --  To qualify, the attribute must meet the following prerequisites:

         return

           --  The prefix must denote a source entry, operator, or subprogram
           --  which is not imported.

           Comes_From_Source (Subp_Id)
             and then Is_Subprogram_Or_Entry (Subp_Id)
             and then not Is_Bodiless_Subprogram (Subp_Id)

             --  The attribute name must be one of the 'Access forms. Note that
             --  'Unchecked_Access cannot apply to a subprogram.

             and then Nam in Name_Access | Name_Unrestricted_Access;
      end Is_Suitable_Access_Taken;

      ----------------------
      -- Is_Suitable_Call --
      ----------------------

      function Is_Suitable_Call (N : Node_Id) return Boolean is
      begin
         --  Entry and subprogram calls are intentionally ignored because they
         --  may undergo expansion depending on the compilation mode, previous
         --  errors, generic context, etc. Call markers play the role of calls
         --  and provide a uniform foundation for ABE processing.

         return Nkind (N) = N_Call_Marker;
      end Is_Suitable_Call;

      -------------------------------
      -- Is_Suitable_Instantiation --
      -------------------------------

      function Is_Suitable_Instantiation (N : Node_Id) return Boolean is
         Inst : constant Node_Id := Scenario (N);

      begin
         --  To qualify, the instantiation must come from source

         return
           Comes_From_Source (Inst)
             and then Nkind (Inst) in N_Generic_Instantiation;
      end Is_Suitable_Instantiation;

      ------------------------------------
      -- Is_Suitable_SPARK_Derived_Type --
      ------------------------------------

      function Is_Suitable_SPARK_Derived_Type (N : Node_Id) return Boolean is
         Prag : Node_Id;
         Typ  : Entity_Id;

      begin
         --  To qualify, the type declaration must denote a derived tagged type
         --  with primitive operations, subject to pragma SPARK_Mode On.

         if Nkind (N) = N_Full_Type_Declaration
           and then Nkind (Type_Definition (N)) = N_Derived_Type_Definition
         then
            Typ  := Defining_Entity (N);
            Prag := SPARK_Pragma (Typ);

            return
              Is_Tagged_Type (Typ)
                and then Has_Primitive_Operations (Typ)
                and then Present (Prag)
                and then Get_SPARK_Mode_From_Annotation (Prag) = On;
         end if;

         return False;
      end Is_Suitable_SPARK_Derived_Type;

      -------------------------------------
      -- Is_Suitable_SPARK_Instantiation --
      -------------------------------------

      function Is_Suitable_SPARK_Instantiation (N : Node_Id) return Boolean is
         Inst : constant Node_Id := Scenario (N);

         Gen_Id : Entity_Id;
         Prag   : Node_Id;

      begin
         --  To qualify, both the instantiation and the generic must be subject
         --  to SPARK_Mode On.

         if Is_Suitable_Instantiation (N) then
            Gen_Id := Instantiated_Generic (Inst);
            Prag   := SPARK_Pragma (Gen_Id);

            return
              Is_SPARK_Mode_On_Node (Inst)
                and then Present (Prag)
                and then Get_SPARK_Mode_From_Annotation (Prag) = On;
         end if;

         return False;
      end Is_Suitable_SPARK_Instantiation;

      --------------------------------------------
      -- Is_Suitable_SPARK_Refined_State_Pragma --
      --------------------------------------------

      function Is_Suitable_SPARK_Refined_State_Pragma
        (N : Node_Id) return Boolean
      is
      begin
         --  To qualfy, the pragma must denote Refined_State

         return
           Nkind (N) = N_Pragma
             and then Pragma_Name (N) = Name_Refined_State;
      end Is_Suitable_SPARK_Refined_State_Pragma;

      -------------------------------------
      -- Is_Suitable_Variable_Assignment --
      -------------------------------------

      function Is_Suitable_Variable_Assignment (N : Node_Id) return Boolean is
         N_Unit      : Node_Id;
         N_Unit_Id   : Entity_Id;
         Nam         : Node_Id;
         Var_Decl    : Node_Id;
         Var_Id      : Entity_Id;
         Var_Unit    : Node_Id;
         Var_Unit_Id : Entity_Id;

      begin
         --  Nothing to do when the scenario is not an assignment

         if Nkind (N) /= N_Assignment_Statement then
            return False;

         --  Nothing to do for internally-generated assignments because they
         --  are assumed to be ABE safe.

         elsif not Comes_From_Source (N) then
            return False;

         --  Assignments are ignored in GNAT mode on the assumption that
         --  they are ABE-safe. This behavior parallels that of the old
         --  ABE mechanism.

         elsif GNAT_Mode then
            return False;
         end if;

         Nam := Assignment_Target (N);

         --  Sanitize the left hand side of the assignment

         if not Is_Entity_Name (Nam) then
            return False;

         elsif No (Entity (Nam)) then
            return False;
         end if;

         Var_Id := Entity (Nam);

         --  Sanitize the variable

         if Var_Id = Any_Id then
            return False;

         elsif Ekind (Var_Id) /= E_Variable then
            return False;
         end if;

         Var_Decl := Declaration_Node (Var_Id);

         if Nkind (Var_Decl) /= N_Object_Declaration then
            return False;
         end if;

         N_Unit_Id := Find_Top_Unit (N);
         N_Unit    := Unit_Declaration_Node (N_Unit_Id);

         Var_Unit_Id := Find_Top_Unit (Var_Decl);
         Var_Unit    := Unit_Declaration_Node (Var_Unit_Id);

         --  To qualify, the assignment must meet the following prerequisites:

         return
           Comes_From_Source (Var_Id)

             --  The variable must be declared in the spec of compilation unit
             --  U.

             and then Nkind (Var_Unit) = N_Package_Declaration
             and then Find_Enclosing_Level (Var_Decl) = Library_Spec_Level

             --  The assignment must occur in the body of compilation unit U

             and then Nkind (N_Unit) = N_Package_Body
             and then Present (Corresponding_Body (Var_Unit))
             and then Corresponding_Body (Var_Unit) = N_Unit_Id;
      end Is_Suitable_Variable_Assignment;

      ------------------------------------
      -- Is_Suitable_Variable_Reference --
      ------------------------------------

      function Is_Suitable_Variable_Reference (N : Node_Id) return Boolean is
      begin
         --  Expanded names and identifiers are intentionally ignored because
         --  they be folded, optimized away, etc. Variable references markers
         --  play the role of variable references and provide a uniform
         --  foundation for ABE processing.

         return Nkind (N) = N_Variable_Reference_Marker;
      end Is_Suitable_Variable_Reference;

      -------------------
      -- Is_Task_Entry --
      -------------------

      function Is_Task_Entry (Id : Entity_Id) return Boolean is
      begin
         --  To qualify, the entity must denote an entry defined in a task type

         return
           Is_Entry (Id) and then Is_Task_Type (Non_Private_View (Scope (Id)));
      end Is_Task_Entry;

      ------------------------
      -- Is_Up_Level_Target --
      ------------------------

      function Is_Up_Level_Target
        (Targ_Decl : Node_Id;
         In_State  : Processing_In_State) return Boolean
      is
         Root     : constant Node_Id         := Root_Scenario;
         Root_Rep : constant Scenario_Rep_Id :=
                      Scenario_Representation_Of (Root, In_State);

      begin
         --  The root appears within the declaratons of a block statement,
         --  entry body, subprogram body, or task body ignoring enclosing
         --  packages. The root is always within the main unit.

         if not In_State.Suppress_Up_Level_Targets
           and then Level (Root_Rep) = Declaration_Level
         then
            --  The target is within the main unit. It acts as an up-level
            --  target when it appears within a context which encloses the
            --  root.
            --
            --    package body Main_Unit is
            --       function Func ...;             --  target
            --
            --       procedure Proc is
            --          X : ... := Func;            --  root scenario

            if In_Extended_Main_Code_Unit (Targ_Decl) then
               return not In_Same_Context (Root, Targ_Decl, Nested_OK => True);

            --  Otherwise the target is external to the main unit which makes
            --  it an up-level target.

            else
               return True;
            end if;
         end if;

         return False;
      end Is_Up_Level_Target;
   end Semantics;

   ---------------------------
   -- Set_Elaboration_Phase --
   ---------------------------

   procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status) is
   begin
      Elaboration_Phase := Status;
   end Set_Elaboration_Phase;

   ---------------------
   -- SPARK_Processor --
   ---------------------

   package body SPARK_Processor is

      -----------------------
      -- Local subprograms --
      -----------------------

      procedure Process_SPARK_Derived_Type
        (Typ_Decl : Node_Id;
         Typ_Rep  : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_SPARK_Derived_Type);
      --  Verify that the freeze node of a derived type denoted by declaration
      --  Typ_Decl is within the early call region of each overriding primitive
      --  body that belongs to the derived type (SPARK RM 7.7(8)). Typ_Rep is
      --  the representation of the type. In_State denotes the current state of
      --  the Processing phase.

      procedure Process_SPARK_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_SPARK_Instantiation);
      --  Verify that instantiation Inst does not precede the generic body it
      --  instantiates (SPARK RM 7.7(6)). Inst_Rep is the representation of the
      --  instantiation. In_State is the current state of the Processing phase.

      procedure Process_SPARK_Refined_State_Pragma
        (Prag     : Node_Id;
         Prag_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_SPARK_Refined_State_Pragma);
      --  Verify that each constituent of Refined_State pragma Prag which
      --  belongs to abstract state mentioned in pragma Initializes has prior
      --  elaboration with respect to the main unit (SPARK RM 7.7.1(7)).
      --  Prag_Rep is the representation of the pragma. In_State denotes the
      --  current state of the Processing phase.

      procedure Process_SPARK_Scenario
        (N        : Node_Id;
         In_State : Processing_In_State);
      pragma Inline (Process_SPARK_Scenario);
      --  Top-level dispatcher for verifying SPARK scenarios which are not
      --  always executable during elaboration but still need elaboration-
      --  related checks. In_State is the current state of the Processing
      --  phase.

      ---------------------------------
      -- Check_SPARK_Model_In_Effect --
      ---------------------------------

      SPARK_Model_Warning_Posted : Boolean := False;
      --  This flag prevents the same SPARK model-related warning from being
      --  emitted multiple times.

      procedure Check_SPARK_Model_In_Effect is
         Spec_Id : constant Entity_Id := Unique_Entity (Main_Unit_Entity);

      begin
         --  Do not emit the warning multiple times as this creates useless
         --  noise.

         if SPARK_Model_Warning_Posted then
            null;

         --  SPARK rule verification requires the "strict" static model

         elsif Static_Elaboration_Checks
           and not Relaxed_Elaboration_Checks
         then
            null;

         --  Any other combination of models does not guarantee the absence of
         --  ABE problems for SPARK rule verification purposes. Note that there
         --  is no need to check for the presence of the legacy ABE mechanism
         --  because the legacy code has its own dedicated processing for SPARK
         --  rules.

         else
            SPARK_Model_Warning_Posted := True;

            Error_Msg_N
              ("??SPARK elaboration checks require static elaboration model",
               Spec_Id);

            if Dynamic_Elaboration_Checks then
               Error_Msg_N
                 ("\dynamic elaboration model is in effect", Spec_Id);

            else
               pragma Assert (Relaxed_Elaboration_Checks);
               Error_Msg_N
                 ("\relaxed elaboration model is in effect", Spec_Id);
            end if;
         end if;
      end Check_SPARK_Model_In_Effect;

      ---------------------------
      -- Check_SPARK_Scenarios --
      ---------------------------

      procedure Check_SPARK_Scenarios is
         Iter : NE_Set.Iterator;
         N    : Node_Id;

      begin
         Iter := Iterate_SPARK_Scenarios;
         while NE_Set.Has_Next (Iter) loop
            NE_Set.Next (Iter, N);

            Process_SPARK_Scenario
              (N        => N,
               In_State => SPARK_State);
         end loop;
      end Check_SPARK_Scenarios;

      --------------------------------
      -- Process_SPARK_Derived_Type --
      --------------------------------

      procedure Process_SPARK_Derived_Type
        (Typ_Decl : Node_Id;
         Typ_Rep  : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (In_State);

         Typ : constant Entity_Id := Target (Typ_Rep);

         Stop_Check : exception;
         --  This exception is raised when the freeze node violates the
         --  placement rules.

         procedure Check_Overriding_Primitive
           (Prim  : Entity_Id;
            FNode : Node_Id);
         pragma Inline (Check_Overriding_Primitive);
         --  Verify that freeze node FNode is within the early call region of
         --  overriding primitive Prim's body.

         function Freeze_Node_Location (FNode : Node_Id) return Source_Ptr;
         pragma Inline (Freeze_Node_Location);
         --  Return a more accurate source location associated with freeze node
         --  FNode.

         function Precedes_Source_Construct (N : Node_Id) return Boolean;
         pragma Inline (Precedes_Source_Construct);
         --  Determine whether arbitrary node N appears prior to some source
         --  construct.

         procedure Suggest_Elaborate_Body
           (N         : Node_Id;
            Body_Decl : Node_Id;
            Error_Nod : Node_Id);
         pragma Inline (Suggest_Elaborate_Body);
         --  Suggest the use of pragma Elaborate_Body when the pragma will
         --  allow for node N to appear within the early call region of
         --  subprogram body Body_Decl. The suggestion is attached to
         --  Error_Nod as a continuation error.

         --------------------------------
         -- Check_Overriding_Primitive --
         --------------------------------

         procedure Check_Overriding_Primitive
           (Prim  : Entity_Id;
            FNode : Node_Id)
         is
            Prim_Decl : constant Node_Id := Unit_Declaration_Node (Prim);
            Body_Decl : Node_Id;
            Body_Id   : Entity_Id;
            Region    : Node_Id;

         begin
            --  Nothing to do for predefined primitives because they are
            --  artifacts of tagged type expansion and cannot override source
            --  primitives. Nothing to do as well for inherited primitives, as
            --  the check concerns overriding ones.

            if Is_Predefined_Dispatching_Operation (Prim)
              or else not Is_Overriding_Subprogram (Prim)
            then
               return;
            end if;

            Body_Id := Corresponding_Body (Prim_Decl);

            --  Nothing to do when the primitive does not have a corresponding
            --  body. This can happen when the unit with the bodies is not the
            --  main unit subjected to ABE checks.

            if No (Body_Id) then
               return;

            --  The primitive overrides a parent or progenitor primitive

            elsif Present (Overridden_Operation (Prim)) then

               --  Nothing to do when overriding an interface primitive happens
               --  by inheriting a non-interface primitive as the check would
               --  be done on the parent primitive.

               if Present (Alias (Prim)) then
                  return;
               end if;

            --  Nothing to do when the primitive is not overriding. The body of
            --  such a primitive cannot be targeted by a dispatching call which
            --  is executable during elaboration, and cannot cause an ABE.

            else
               return;
            end if;

            Body_Decl := Unit_Declaration_Node (Body_Id);
            Region    := Find_Early_Call_Region (Body_Decl);

            --  The freeze node appears prior to the early call region of the
            --  primitive body.

            --  IMPORTANT: This check must always be performed even when
            --  -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
            --  specified because the static model cannot guarantee the absence
            --  of ABEs in the presence of dispatching calls.

            if Earlier_In_Extended_Unit (FNode, Region) then
               Error_Msg_Node_2 := Prim;
               Error_Msg_NE
                 ("first freezing point of type & must appear within early "
                  & "call region of primitive body & (SPARK RM 7.7(8))",
                  Typ_Decl, Typ);

               Error_Msg_Sloc := Sloc (Region);
               Error_Msg_N ("\region starts #", Typ_Decl);

               Error_Msg_Sloc := Sloc (Body_Decl);
               Error_Msg_N ("\region ends #", Typ_Decl);

               Error_Msg_Sloc := Freeze_Node_Location (FNode);
               Error_Msg_N ("\first freezing point #", Typ_Decl);

               --  If applicable, suggest the use of pragma Elaborate_Body in
               --  the associated package spec.

               Suggest_Elaborate_Body
                 (N         => FNode,
                  Body_Decl => Body_Decl,
                  Error_Nod => Typ_Decl);

               raise Stop_Check;
            end if;
         end Check_Overriding_Primitive;

         --------------------------
         -- Freeze_Node_Location --
         --------------------------

         function Freeze_Node_Location (FNode : Node_Id) return Source_Ptr is
            Context : constant Node_Id    := Parent (FNode);
            Loc     : constant Source_Ptr := Sloc (FNode);

            Prv_Decls : List_Id;
            Vis_Decls : List_Id;

         begin
            --  In general, the source location of the freeze node is as close
            --  as possible to the real freeze point, except when the freeze
            --  node is at the "bottom" of a package spec.

            if Nkind (Context) = N_Package_Specification then
               Prv_Decls := Private_Declarations (Context);
               Vis_Decls := Visible_Declarations (Context);

               --  The freeze node appears in the private declarations of the
               --  package.

               if Present (Prv_Decls)
                 and then List_Containing (FNode) = Prv_Decls
               then
                  null;

               --  The freeze node appears in the visible declarations of the
               --  package and there are no private declarations.

               elsif Present (Vis_Decls)
                 and then List_Containing (FNode) = Vis_Decls
                 and then Is_Empty_List (Prv_Decls)
               then
                  null;

               --  Otherwise the freeze node is not in the "last" declarative
               --  list of the package. Use the existing source location of the
               --  freeze node.

               else
                  return Loc;
               end if;

               --  The freeze node appears at the "bottom" of the package when
               --  it is in the "last" declarative list and is either the last
               --  in the list or is followed by internal constructs only. In
               --  that case the more appropriate source location is that of
               --  the package end label.

               if not Precedes_Source_Construct (FNode) then
                  return Sloc (End_Label (Context));
               end if;
            end if;

            return Loc;
         end Freeze_Node_Location;

         -------------------------------
         -- Precedes_Source_Construct --
         -------------------------------

         function Precedes_Source_Construct (N : Node_Id) return Boolean is
            Decl : Node_Id;

         begin
            Decl := Next (N);
            while Present (Decl) loop
               if Comes_From_Source (Decl) then
                  return True;

               --  A generated body for a source expression function is treated
               --  as a source construct.

               elsif Nkind (Decl) = N_Subprogram_Body
                 and then Was_Expression_Function (Decl)
                 and then Comes_From_Source (Original_Node (Decl))
               then
                  return True;
               end if;

               Next (Decl);
            end loop;

            return False;
         end Precedes_Source_Construct;

         ----------------------------
         -- Suggest_Elaborate_Body --
         ----------------------------

         procedure Suggest_Elaborate_Body
           (N         : Node_Id;
            Body_Decl : Node_Id;
            Error_Nod : Node_Id)
         is
            Unit_Id : constant Node_Id := Unit (Cunit (Main_Unit));
            Region  : Node_Id;

         begin
            --  The suggestion applies only when the subprogram body resides in
            --  a compilation package body, and a pragma Elaborate_Body would
            --  allow for the node to appear in the early call region of the
            --  subprogram body. This implies that all code from the subprogram
            --  body up to the node is preelaborable.

            if Nkind (Unit_Id) = N_Package_Body then

               --  Find the start of the early call region again assuming that
               --  the package spec has pragma Elaborate_Body. Note that the
               --  internal data structures are intentionally not updated
               --  because this is a speculative search.

               Region :=
                 Find_Early_Call_Region
                   (Body_Decl        => Body_Decl,
                    Assume_Elab_Body => True,
                    Skip_Memoization => True);

               --  If the node appears within the early call region, assuming
               --  that the package spec carries pragma Elaborate_Body, then it
               --  is safe to suggest the pragma.

               if Earlier_In_Extended_Unit (Region, N) then
                  Error_Msg_Name_1 := Name_Elaborate_Body;
                  Error_Msg_NE
                    ("\consider adding pragma % in spec of unit &",
                     Error_Nod, Defining_Entity (Unit_Id));
               end if;
            end if;
         end Suggest_Elaborate_Body;

         --  Local variables

         FNode : constant Node_Id  := Freeze_Node (Typ);
         Prims : constant Elist_Id := Direct_Primitive_Operations (Typ);

         Prim_Elmt : Elmt_Id;

      --  Start of processing for Process_SPARK_Derived_Type

      begin
         --  A type should have its freeze node set by the time SPARK scenarios
         --  are being verified.

         pragma Assert (Present (FNode));

         --  Verify that the freeze node of the derived type is within the
         --  early call region of each overriding primitive body
         --  (SPARK RM 7.7(8)).

         if Present (Prims) then
            Prim_Elmt := First_Elmt (Prims);
            while Present (Prim_Elmt) loop
               Check_Overriding_Primitive
                 (Prim  => Node (Prim_Elmt),
                  FNode => FNode);

               Next_Elmt (Prim_Elmt);
            end loop;
         end if;

      exception
         when Stop_Check =>
            null;
      end Process_SPARK_Derived_Type;

      ---------------------------------
      -- Process_SPARK_Instantiation --
      ---------------------------------

      procedure Process_SPARK_Instantiation
        (Inst     : Node_Id;
         Inst_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         Gen_Id    : constant Entity_Id     := Target (Inst_Rep);
         Gen_Rep   : constant Target_Rep_Id :=
                       Target_Representation_Of (Gen_Id, In_State);
         Body_Decl : constant Node_Id       := Body_Declaration (Gen_Rep);

      begin
         --  The instantiation and the generic body are both in the main unit

         if Present (Body_Decl)
           and then In_Extended_Main_Code_Unit (Body_Decl)

           --  If the instantiation appears prior to the generic body, then the
           --  instantiation is illegal (SPARK RM 7.7(6)).

           --  IMPORTANT: This check must always be performed even when
           --  -gnatd.v (enforce SPARK elaboration rules in SPARK code) is not
           --  specified because the rule prevents use-before-declaration of
           --  objects that may precede the generic body.

           and then Earlier_In_Extended_Unit (Inst, Body_Decl)
         then
            Error_Msg_NE
              ("cannot instantiate & before body seen", Inst, Gen_Id);
         end if;
      end Process_SPARK_Instantiation;

      ----------------------------
      -- Process_SPARK_Scenario --
      ----------------------------

      procedure Process_SPARK_Scenario
        (N        : Node_Id;
         In_State : Processing_In_State)
      is
         Scen : constant Node_Id := Scenario (N);

      begin
         --  Ensure that a suitable elaboration model is in effect for SPARK
         --  rule verification.

         Check_SPARK_Model_In_Effect;

         --  Add the current scenario to the stack of active scenarios

         Push_Active_Scenario (Scen);

         --  Derived type

         if Is_Suitable_SPARK_Derived_Type (Scen) then
            Process_SPARK_Derived_Type
              (Typ_Decl => Scen,
               Typ_Rep  => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);

         --  Instantiation

         elsif Is_Suitable_SPARK_Instantiation (Scen) then
            Process_SPARK_Instantiation
              (Inst     => Scen,
               Inst_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);

         --  Refined_State pragma

         elsif Is_Suitable_SPARK_Refined_State_Pragma (Scen) then
            Process_SPARK_Refined_State_Pragma
              (Prag     => Scen,
               Prag_Rep => Scenario_Representation_Of (Scen, In_State),
               In_State => In_State);
         end if;

         --  Remove the current scenario from the stack of active scenarios
         --  once all ABE diagnostics and checks have been performed.

         Pop_Active_Scenario (Scen);
      end Process_SPARK_Scenario;

      ----------------------------------------
      -- Process_SPARK_Refined_State_Pragma --
      ----------------------------------------

      procedure Process_SPARK_Refined_State_Pragma
        (Prag     : Node_Id;
         Prag_Rep : Scenario_Rep_Id;
         In_State : Processing_In_State)
      is
         pragma Unreferenced (Prag_Rep);

         procedure Check_SPARK_Constituent (Constit_Id : Entity_Id);
         pragma Inline (Check_SPARK_Constituent);
         --  Ensure that a single constituent Constit_Id is elaborated prior to
         --  the main unit.

         procedure Check_SPARK_Constituents (Constits : Elist_Id);
         pragma Inline (Check_SPARK_Constituents);
         --  Ensure that all constituents found in list Constits are elaborated
         --  prior to the main unit.

         procedure Check_SPARK_Initialized_State (State : Node_Id);
         pragma Inline (Check_SPARK_Initialized_State);
         --  Ensure that the constituents of single abstract state State are
         --  elaborated prior to the main unit.

         procedure Check_SPARK_Initialized_States (Pack_Id : Entity_Id);
         pragma Inline (Check_SPARK_Initialized_States);
         --  Ensure that the constituents of all abstract states which appear
         --  in the Initializes pragma of package Pack_Id are elaborated prior
         --  to the main unit.

         -----------------------------
         -- Check_SPARK_Constituent --
         -----------------------------

         procedure Check_SPARK_Constituent (Constit_Id : Entity_Id) is
            SM_Prag : Node_Id;

         begin
            --  Nothing to do for "null" constituents

            if Nkind (Constit_Id) = N_Null then
               return;

            --  Nothing to do for illegal constituents

            elsif Error_Posted (Constit_Id) then
               return;
            end if;

            SM_Prag := SPARK_Pragma (Constit_Id);

            --  The check applies only when the constituent is subject to
            --  pragma SPARK_Mode On.

            if Present (SM_Prag)
              and then Get_SPARK_Mode_From_Annotation (SM_Prag) = On
            then
               --  An external constituent of an abstract state which appears
               --  in the Initializes pragma of a package spec imposes an
               --  Elaborate requirement on the context of the main unit.
               --  Determine whether the context has a pragma strong enough to
               --  meet the requirement.

               --  IMPORTANT: This check is performed only when -gnatd.v
               --  (enforce SPARK elaboration rules in SPARK code) is in effect
               --  because the static model can ensure the prior elaboration of
               --  the unit which contains a constituent by installing implicit
               --  Elaborate pragma.

               if Debug_Flag_Dot_V then
                  Meet_Elaboration_Requirement
                    (N        => Prag,
                     Targ_Id  => Constit_Id,
                     Req_Nam  => Name_Elaborate,
                     In_State => In_State);

               --  Otherwise ensure that the unit with the external constituent
               --  is elaborated prior to the main unit.

               else
                  Ensure_Prior_Elaboration
                    (N        => Prag,
                     Unit_Id  => Find_Top_Unit (Constit_Id),
                     Prag_Nam => Name_Elaborate,
                     In_State => In_State);
               end if;
            end if;
         end Check_SPARK_Constituent;

         ------------------------------
         -- Check_SPARK_Constituents --
         ------------------------------

         procedure Check_SPARK_Constituents (Constits : Elist_Id) is
            Constit_Elmt : Elmt_Id;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Check_SPARK_Constituent (Node (Constit_Elmt));
                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;
         end Check_SPARK_Constituents;

         -----------------------------------
         -- Check_SPARK_Initialized_State --
         -----------------------------------

         procedure Check_SPARK_Initialized_State (State : Node_Id) is
            SM_Prag  : Node_Id;
            State_Id : Entity_Id;

         begin
            --  Nothing to do for "null" initialization items

            if Nkind (State) = N_Null then
               return;

            --  Nothing to do for illegal states

            elsif Error_Posted (State) then
               return;
            end if;

            State_Id := Entity_Of (State);

            --  Sanitize the state

            if No (State_Id) then
               return;

            elsif Error_Posted (State_Id) then
               return;

            elsif Ekind (State_Id) /= E_Abstract_State then
               return;
            end if;

            --  The check is performed only when the abstract state is subject
            --  to SPARK_Mode On.

            SM_Prag := SPARK_Pragma (State_Id);

            if Present (SM_Prag)
              and then Get_SPARK_Mode_From_Annotation (SM_Prag) = On
            then
               Check_SPARK_Constituents (Refinement_Constituents (State_Id));
            end if;
         end Check_SPARK_Initialized_State;

         ------------------------------------
         -- Check_SPARK_Initialized_States --
         ------------------------------------

         procedure Check_SPARK_Initialized_States (Pack_Id : Entity_Id) is
            Init_Prag : constant Node_Id :=
                          Get_Pragma (Pack_Id, Pragma_Initializes);

            Init  : Node_Id;
            Inits : Node_Id;

         begin
            if Present (Init_Prag) then
               Inits := Expression (Get_Argument (Init_Prag, Pack_Id));

               --  Avoid processing a "null" initialization list. The only
               --  other alternative is an aggregate.

               if Nkind (Inits) = N_Aggregate then

                  --  The initialization items appear in list form:
                  --
                  --    (state1, state2)

                  if Present (Expressions (Inits)) then
                     Init := First (Expressions (Inits));
                     while Present (Init) loop
                        Check_SPARK_Initialized_State (Init);
                        Next (Init);
                     end loop;
                  end if;

                  --  The initialization items appear in associated form:
                  --
                  --    (state1 => item1,
                  --     state2 => (item2, item3))

                  if Present (Component_Associations (Inits)) then
                     Init := First (Component_Associations (Inits));
                     while Present (Init) loop
                        Check_SPARK_Initialized_State (Init);
                        Next (Init);
                     end loop;
                  end if;
               end if;
            end if;
         end Check_SPARK_Initialized_States;

         --  Local variables

         Pack_Body : constant Node_Id := Find_Related_Package_Or_Body (Prag);

      --  Start of processing for Process_SPARK_Refined_State_Pragma

      begin
         --  Pragma Refined_State must be associated with a package body

         pragma Assert
           (Present (Pack_Body) and then Nkind (Pack_Body) = N_Package_Body);

         --  Verify that each external contitunent of an abstract state
         --  mentioned in pragma Initializes is properly elaborated.

         Check_SPARK_Initialized_States (Unique_Defining_Entity (Pack_Body));
      end Process_SPARK_Refined_State_Pragma;
   end SPARK_Processor;

   -------------------------------
   -- Spec_And_Body_From_Entity --
   -------------------------------

   procedure Spec_And_Body_From_Entity
     (Id        : Entity_Id;
      Spec_Decl : out Node_Id;
      Body_Decl : out Node_Id)
   is
   begin
      Spec_And_Body_From_Node
        (N         => Unit_Declaration_Node (Id),
         Spec_Decl => Spec_Decl,
         Body_Decl => Body_Decl);
   end Spec_And_Body_From_Entity;

   -----------------------------
   -- Spec_And_Body_From_Node --
   -----------------------------

   procedure Spec_And_Body_From_Node
     (N         : Node_Id;
      Spec_Decl : out Node_Id;
      Body_Decl : out Node_Id)
   is
      Body_Id : Entity_Id;
      Spec_Id : Entity_Id;

   begin
      --  Assume that the construct lacks spec and body

      Body_Decl := Empty;
      Spec_Decl := Empty;

      --  Bodies

      if Nkind (N) in N_Package_Body
                    | N_Protected_Body
                    | N_Subprogram_Body
                    | N_Task_Body
      then
         Spec_Id := Corresponding_Spec (N);

         --  The body completes a previous declaration

         if Present (Spec_Id) then
            Spec_Decl := Unit_Declaration_Node (Spec_Id);

         --  Otherwise the body acts as the initial declaration, and is both a
         --  spec and body. There is no need to look for an optional body.

         else
            Body_Decl := N;
            Spec_Decl := N;
            return;
         end if;

      --  Declarations

      elsif Nkind (N) in N_Entry_Declaration
                       | N_Generic_Package_Declaration
                       | N_Generic_Subprogram_Declaration
                       | N_Package_Declaration
                       | N_Protected_Type_Declaration
                       | N_Subprogram_Declaration
                       | N_Task_Type_Declaration
      then
         Spec_Decl := N;

      --  Expression function

      elsif Nkind (N) = N_Expression_Function then
         Spec_Id := Corresponding_Spec (N);
         pragma Assert (Present (Spec_Id));

         Spec_Decl := Unit_Declaration_Node (Spec_Id);

      --  Instantiations

      elsif Nkind (N) in N_Generic_Instantiation then
         Spec_Decl := Instance_Spec (N);
         pragma Assert (Present (Spec_Decl));

      --  Stubs

      elsif Nkind (N) in N_Body_Stub then
         Spec_Id := Corresponding_Spec_Of_Stub (N);

         --  The stub completes a previous declaration

         if Present (Spec_Id) then
            Spec_Decl := Unit_Declaration_Node (Spec_Id);

         --  Otherwise the stub acts as a spec

         else
            Spec_Decl := N;
         end if;
      end if;

      --  Obtain an optional or mandatory body

      if Present (Spec_Decl) then
         Body_Id := Corresponding_Body (Spec_Decl);

         if Present (Body_Id) then
            Body_Decl := Unit_Declaration_Node (Body_Id);
         end if;
      end if;
   end Spec_And_Body_From_Node;

   -------------------------------
   -- Static_Elaboration_Checks --
   -------------------------------

   function Static_Elaboration_Checks return Boolean is
   begin
      return not Dynamic_Elaboration_Checks;
   end Static_Elaboration_Checks;

   -----------------
   -- Unit_Entity --
   -----------------

   function Unit_Entity (Unit_Id : Entity_Id) return Entity_Id is
      function Is_Subunit (Id : Entity_Id) return Boolean;
      pragma Inline (Is_Subunit);
      --  Determine whether the entity of an initial declaration denotes a
      --  subunit.

      ----------------
      -- Is_Subunit --
      ----------------

      function Is_Subunit (Id : Entity_Id) return Boolean is
         Decl : constant Node_Id := Unit_Declaration_Node (Id);

      begin
         return
           Nkind (Decl) in N_Generic_Package_Declaration
                         | N_Generic_Subprogram_Declaration
                         | N_Package_Declaration
                         | N_Protected_Type_Declaration
                         | N_Subprogram_Declaration
                         | N_Task_Type_Declaration
             and then Present (Corresponding_Body (Decl))
             and then Nkind (Parent (Unit_Declaration_Node
                        (Corresponding_Body (Decl)))) = N_Subunit;
      end Is_Subunit;

      --  Local variables

      Id : Entity_Id;

   --  Start of processing for Unit_Entity

   begin
      Id := Unique_Entity (Unit_Id);

      --  Skip all subunits found in the scope chain which ends at the input
      --  unit.

      while Is_Subunit (Id) loop
         Id := Scope (Id);
      end loop;

      return Id;
   end Unit_Entity;

   ---------------------------------
   -- Update_Elaboration_Scenario --
   ---------------------------------

   procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id) is
   begin
      --  Nothing to do when the elaboration phase of the compiler is not
      --  active.

      if not Elaboration_Phase_Active then
         return;

      --  Nothing to do when the old and new scenarios are one and the same

      elsif Old_N = New_N then
         return;
      end if;

      --  A scenario is being transformed by Atree.Rewrite. Update all relevant
      --  internal data structures to reflect this change. This ensures that a
      --  potential run-time conditional ABE check or a guaranteed ABE failure
      --  is inserted at the proper place in the tree.

      if Is_Scenario (Old_N) then
         Replace_Scenario (Old_N, New_N);
      end if;
   end Update_Elaboration_Scenario;

   ---------------------------------------------------------------------------
   --                                                                       --
   --  L E G A C Y    A C C E S S    B E F O R E    E L A B O R A T I O N   --
   --                                                                       --
   --                          M E C H A N I S M                            --
   --                                                                       --
   ---------------------------------------------------------------------------

   --  This section contains the implementation of the pre-18.x legacy ABE
   --  mechanism. The mechanism can be activated using switch -gnatH (legacy
   --  elaboration checking mode enabled).

   -----------------------------
   -- Description of Approach --
   -----------------------------

   --  Every non-static call that is encountered by Sem_Res results in a call
   --  to Check_Elab_Call, with N being the call node, and Outer set to its
   --  default value of True. In addition X'Access is treated like a call
   --  for the access-to-procedure case, and in SPARK mode only we also
   --  check variable references.

   --  The goal of Check_Elab_Call is to determine whether or not the reference
   --  in question can generate an access before elaboration error (raising
   --  Program_Error) either by directly calling a subprogram whose body
   --  has not yet been elaborated, or indirectly, by calling a subprogram
   --  whose body has been elaborated, but which contains a call to such a
   --  subprogram.

   --  In addition, in SPARK mode, we are checking for a variable reference in
   --  another package, which requires an explicit Elaborate_All pragma.

   --  The only references that we need to look at the outer level are
   --  references that occur in elaboration code. There are two cases. The
   --  reference can be at the outer level of elaboration code, or it can
   --  be within another unit, e.g. the elaboration code of a subprogram.

   --  In the case of an elaboration call at the outer level, we must trace
   --  all calls to outer level routines either within the current unit or to
   --  other units that are with'ed. For calls within the current unit, we can
   --  determine if the body has been elaborated or not, and if it has not,
   --  then a warning is generated.

   --  Note that there are two subcases. If the original call directly calls a
   --  subprogram whose body has not been elaborated, then we know that an ABE
   --  will take place, and we replace the call by a raise of Program_Error.
   --  If the call is indirect, then we don't know that the PE will be raised,
   --  since the call might be guarded by a conditional. In this case we set
   --  Do_Elab_Check on the call so that a dynamic check is generated, and
   --  output a warning.

   --  For calls to a subprogram in a with'ed unit or a 'Access or variable
   --  reference (SPARK mode case), we require that a pragma Elaborate_All
   --  or pragma Elaborate be present, or that the referenced unit have a
   --  pragma Preelaborate, pragma Pure, or pragma Elaborate_Body. If none
   --  of these conditions is met, then a warning is generated that a pragma
   --  Elaborate_All may be needed (error in the SPARK case), or an implicit
   --  pragma is generated.

   --  For the case of an elaboration call at some inner level, we are
   --  interested in tracing only calls to subprograms at the same level, i.e.
   --  those that can be called during elaboration. Any calls to outer level
   --  routines cannot cause ABE's as a result of the original call (there
   --  might be an outer level call to the subprogram from outside that causes
   --  the ABE, but that gets analyzed separately).

   --  Note that we never trace calls to inner level subprograms, since these
   --  cannot result in ABE's unless there is an elaboration problem at a lower
   --  level, which will be separately detected.

   --  Note on pragma Elaborate. The checking here assumes that a pragma
   --  Elaborate on a with'ed unit guarantees that subprograms within the unit
   --  can be called without causing an ABE. This is not in fact the case since
   --  pragma Elaborate does not guarantee the transitive coverage guaranteed
   --  by Elaborate_All. However, we decide to trust the user in this case.

   --------------------------------------
   -- Instantiation Elaboration Errors --
   --------------------------------------

   --  A special case arises when an instantiation appears in a context that is
   --  known to be before the body is elaborated, e.g.

   --       generic package x is ...
   --       ...
   --       package xx is new x;
   --       ...
   --       package body x is ...

   --  In this situation it is certain that an elaboration error will occur,
   --  and an unconditional raise Program_Error statement is inserted before
   --  the instantiation, and a warning generated.

   --  The problem is that in this case we have no place to put the body of
   --  the instantiation. We can't put it in the normal place, because it is
   --  too early, and will cause errors to occur as a result of referencing
   --  entities before they are declared.

   --  Our approach in this case is simply to avoid creating the body of the
   --  instantiation in such a case. The instantiation spec is modified to
   --  include dummy bodies for all subprograms, so that the resulting code
   --  does not contain subprogram specs with no corresponding bodies.

   --  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_Element is record
      Cloc : Source_Ptr;
      Ent  : Entity_Id;
   end record;

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

   --  The following table records all calls that have been processed starting
   --  from an outer level call. The table prevents both infinite recursion and
   --  useless reanalysis of calls within the same context. The use of context
   --  is important because it allows for proper checks in more complex code:

   --    if ... then
   --       Call;  --  requires a check
   --       Call;  --  does not need a check thanks to the table
   --    elsif ... then
   --       Call;  --  requires a check, different context
   --    end if;

   --    Call;     --  requires a check, different context

   type Visited_Element is record
      Subp_Id : Entity_Id;
      --  The entity of the subprogram being called

      Context : Node_Id;
      --  The context where the call to the subprogram occurs
   end record;

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

   --  The following table records delayed calls which must be examined after
   --  all generic bodies have been instantiated.

   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.

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

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

      In_Task_Activation : Boolean;
      --  Save indication of whether this call is from a task body. Tasks are
      --  activated at the "begin", which is after all local procedure bodies,
      --  so calls to those procedures can't fail, even if they occur after the
      --  task body.

      From_SPARK_Code : Boolean;
      --  Save indication of whether this call is under SPARK_Mode => On
   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. 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
   --  bodies, at the point of activation. If true, we do not raise
   --  Program_Error for calls to local procedures, because all local bodies
   --  are known to be elaborated. However, we still need to trace such calls,
   --  because a local procedure could call a procedure in another package,
   --  so we might need an implicit Elaborate_All.

   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 Activate_Elaborate_All_Desirable (N : Node_Id; U : Entity_Id);
   --  Analysis of construct N shows that we should set Elaborate_All_Desirable
   --  for the WITH clause for unit U (which will always be present). A special
   --  case is when N is a function or procedure instantiation, in which case
   --  it is sufficient to set Elaborate_Desirable, since in this case there is
   --  no possibility of transitive elaboration issues.

   procedure Check_A_Call
     (N                 : Node_Id;
      E                 : Entity_Id;
      Outer_Scope       : Entity_Id;
      Inter_Unit_Only   : Boolean;
      Generate_Warnings : Boolean := True;
      In_Init_Proc      : Boolean := False);
   --  This is the internal recursive routine that is called to check for
   --  possible elaboration error. The argument N is a subprogram call or
   --  generic instantiation, or 'Access attribute reference to be checked, and
   --  E is the entity of the called subprogram, or instantiated generic unit,
   --  or subprogram referenced by 'Access.
   --
   --  In SPARK mode, N can also be a variable reference, since in SPARK this
   --  also triggers a requirement for Elaborate_All, and in this case E is the
   --  entity being referenced.
   --
   --  Outer_Scope is the outer level scope for the original reference.
   --  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. Note that an instance of the Access
   --  attribute applied to a subprogram also generates a call to this
   --  procedure (since the referenced subprogram may be called later
   --  indirectly). Flag In_Init_Proc should be set whenever the current
   --  context is a type init proc.
   --
   --  Note: this might better be called Check_A_Reference to recognize the
   --  variable case for SPARK, but we prefer to retain the historical name
   --  since in practice this is mostly about checking calls for the possible
   --  occurrence of an access-before-elaboration exception.

   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_Checks 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.

   function Get_Referenced_Ent (N : Node_Id) return Entity_Id;
   --  N is either a function or procedure call or an access attribute that
   --  references a subprogram. This call retrieves the relevant entity. If
   --  this is a call to a protected subprogram, the entity is a selected
   --  component. The callable entity may be absent, in which case Empty is
   --  returned. This happens with non-analyzed calls in nested generics.
   --
   --  If SPARK_Mode is On, then N can also be a reference to an E_Variable
   --  entity, in which case, the value returned is simply this entity.

   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.

   function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean;
   --  Returns True if node N is a call to a generic formal subprogram

   function Is_Finalization_Procedure (Id : Entity_Id) return Boolean;
   --  Determine whether entity Id denotes a [Deep_]Finalize procedure

   procedure Output_Calls
     (N               : Node_Id;
      Check_Elab_Flag : Boolean);
   --  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. When Check_Elab_Flag is set, calls are
   --  enumerated only when flag Elab_Warning is set for the dynamic case or
   --  when flag Elab_Info_Messages is set for the static case.

   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.

   procedure Set_Elaboration_Constraint
    (Call : Node_Id;
     Subp : Entity_Id;
     Scop : Entity_Id);
   --  The current unit U may depend semantically on some unit P that 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 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

   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
     (Unit : Unit_Number_Type;
      E    : Entity_Id) return Boolean;
   --  Return True if we are within the scope of an Elaborate_All for E, or if
   --  we are within the scope of an Elaborate_All for some other unit U, and U
   --  with's E. This prevents spurious warnings when the called entity is
   --  renamed within U, or in case of generic instances.

   --------------------------------------
   -- Activate_Elaborate_All_Desirable --
   --------------------------------------

   procedure Activate_Elaborate_All_Desirable (N : Node_Id; U : Entity_Id) is
      UN  : constant Unit_Number_Type := Get_Code_Unit (N);
      CU  : constant Node_Id          := Cunit (UN);
      UE  : constant Entity_Id        := Cunit_Entity (UN);
      Unm : constant Unit_Name_Type   := Unit_Name (UN);
      CI  : constant List_Id          := Context_Items (CU);
      Itm : Node_Id;
      Ent : Entity_Id;

      procedure Add_To_Context_And_Mark (Itm : Node_Id);
      --  This procedure is called when the elaborate indication must be
      --  applied to a unit not in the context of the referencing unit. The
      --  unit gets added to the context as an implicit with.

      function In_Withs_Of (UEs : Entity_Id) return Boolean;
      --  UEs is the spec entity of a unit. If the unit to be marked is
      --  in the context item list of this unit spec, then the call returns
      --  True and Itm is left set to point to the relevant N_With_Clause node.

      procedure Set_Elab_Flag (Itm : Node_Id);
      --  Sets Elaborate_[All_]Desirable as appropriate on Itm

      -----------------------------
      -- Add_To_Context_And_Mark --
      -----------------------------

      procedure Add_To_Context_And_Mark (Itm : Node_Id) is
         CW : constant Node_Id :=
                Make_With_Clause (Sloc (Itm),
                  Name => Name (Itm));

      begin
         Set_Library_Unit  (CW, Library_Unit (Itm));
         Set_Implicit_With (CW);

         --  Set elaborate all desirable on copy and then append the copy to
         --  the list of body with's and we are done.

         Set_Elab_Flag (CW);
         Append_To (CI, CW);
      end Add_To_Context_And_Mark;

      -----------------
      -- In_Withs_Of --
      -----------------

      function In_Withs_Of (UEs : Entity_Id) return Boolean is
         UNs : constant Unit_Number_Type := Get_Source_Unit (UEs);
         CUs : constant Node_Id          := Cunit (UNs);
         CIs : constant List_Id          := Context_Items (CUs);

      begin
         Itm := First (CIs);
         while Present (Itm) loop
            if Nkind (Itm) = N_With_Clause then
               Ent :=
                 Cunit_Entity (Get_Cunit_Unit_Number (Library_Unit (Itm)));

               if U = Ent then
                  return True;
               end if;
            end if;

            Next (Itm);
         end loop;

         return False;
      end In_Withs_Of;

      -------------------
      -- Set_Elab_Flag --
      -------------------

      procedure Set_Elab_Flag (Itm : Node_Id) is
      begin
         if Nkind (N) in N_Subprogram_Instantiation then
            Set_Elaborate_Desirable (Itm);
         else
            Set_Elaborate_All_Desirable (Itm);
         end if;
      end Set_Elab_Flag;

   --  Start of processing for Activate_Elaborate_All_Desirable

   begin
      --  Do not set binder indication if expansion is disabled, as when
      --  compiling a generic unit.

      if not Expander_Active then
         return;
      end if;

      --  If an instance of a generic package contains a controlled object (so
      --  we're calling Initialize at elaboration time), and the instance is in
      --  a package body P that says "with P;", then we need to return without
      --  adding "pragma Elaborate_All (P);" to P.

      if U = Main_Unit_Entity then
         return;
      end if;

      Itm := First (CI);
      while Present (Itm) loop
         if Nkind (Itm) = N_With_Clause then
            Ent := Cunit_Entity (Get_Cunit_Unit_Number (Library_Unit (Itm)));

            --  If we find it, then mark elaborate all desirable and return

            if U = Ent then
               Set_Elab_Flag (Itm);
               return;
            end if;
         end if;

         Next (Itm);
      end loop;

      --  If we fall through then the with clause is not present in the
      --  current unit. One legitimate possibility is that the with clause
      --  is present in the spec when we are a body.

      if Is_Body_Name (Unm)
        and then In_Withs_Of (Spec_Entity (UE))
      then
         Add_To_Context_And_Mark (Itm);
         return;
      end if;

      --  Similarly, we may be in the spec or body of a child unit, where
      --  the unit in question is with'ed by some ancestor of the child unit.

      if Is_Child_Name (Unm) then
         declare
            Pkg : Entity_Id;

         begin
            Pkg := UE;
            loop
               Pkg := Scope (Pkg);
               exit when Pkg = Standard_Standard;

               if In_Withs_Of (Pkg) then
                  Add_To_Context_And_Mark (Itm);
                  return;
               end if;
            end loop;
         end;
      end if;

      --  Here if we do not find with clause on spec or body. We just ignore
      --  this case; it means that the elaboration involves some other unit
      --  than the unit being compiled, and will be caught elsewhere.
   end Activate_Elaborate_All_Desirable;

   ------------------
   -- 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;
      In_Init_Proc      : Boolean := False)
   is
      Access_Case : constant Boolean := Nkind (N) = N_Attribute_Reference;
      --  Indicates if we have Access attribute case

      function Call_To_Instance_From_Outside (Id : Entity_Id) return Boolean;
      --  True if we're calling an instance of a generic subprogram, or a
      --  subprogram in an instance of a generic package, and the call is
      --  outside that instance.

      procedure Elab_Warning
        (Msg_D : String;
         Msg_S : String;
         Ent   : Node_Or_Entity_Id);
       --  Generate a call to Error_Msg_NE with parameters Msg_D or Msg_S (for
       --  dynamic or static elaboration model), N and Ent. Msg_D is a real
       --  warning (output if Msg_D is non-null and Elab_Warnings is set),
       --  Msg_S is an info message (output if Elab_Info_Messages is set).

      function Find_W_Scope return Entity_Id;
      --  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.

      -----------------------------------
      -- Call_To_Instance_From_Outside --
      -----------------------------------

      function Call_To_Instance_From_Outside (Id : Entity_Id) return Boolean is
         Scop : Entity_Id := Id;

      begin
         loop
            if Scop = Standard_Standard then
               return False;
            end if;

            if Is_Generic_Instance (Scop) then
               return not In_Open_Scopes (Scop);
            end if;

            Scop := Scope (Scop);
         end loop;
      end Call_To_Instance_From_Outside;

      ------------------
      -- Elab_Warning --
      ------------------

      procedure Elab_Warning
        (Msg_D : String;
         Msg_S : String;
         Ent   : Node_Or_Entity_Id)
      is
      begin
         --  Dynamic elaboration checks, real warning

         if Dynamic_Elaboration_Checks then
            if not Access_Case then
               if Msg_D /= "" and then Elab_Warnings then
                  Error_Msg_NE (Msg_D, N, Ent);
               end if;

            --  In the access case emit first warning message as well,
            --  otherwise list of calls will appear as errors.

            elsif Elab_Warnings then
               Error_Msg_NE (Msg_S, N, Ent);
            end if;

         --  Static elaboration checks, info message

         else
            if Elab_Info_Messages then
               Error_Msg_NE (Msg_S, N, Ent);
            end if;
         end if;
      end Elab_Warning;

      ------------------
      -- Find_W_Scope --
      ------------------

      function Find_W_Scope return Entity_Id is
         Refed_Ent : constant Entity_Id := Get_Referenced_Ent (N);
         W_Scope   : Entity_Id;

      begin
         if Is_Init_Proc (Refed_Ent)
           and then not In_Same_Extended_Unit (N, Refed_Ent)
         then
            W_Scope := Scope (Refed_Ent);
         else
            W_Scope := E;
         end if;

         --  Now loop through scopes to get to the enclosing compilation unit

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

         return W_Scope;
      end Find_W_Scope;

      --  Local variables

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

      Loc : constant Source_Ptr := Sloc (N);

      Variable_Case : constant Boolean :=
                        Nkind (N) in N_Has_Entity
                          and then Present (Entity (N))
                          and then Ekind (Entity (N)) = E_Variable;
      --  Indicates if we have variable reference case

      W_Scope : constant Entity_Id := Find_W_Scope;
      --  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 intermediate package. These special cases are handled in
      --  Set_Elaboration_Constraint.

      Ent                  : Entity_Id;
      Callee_Unit_Internal : Boolean;
      Caller_Unit_Internal : Boolean;
      Decl                 : Node_Id;
      Inst_Callee          : Source_Ptr;
      Inst_Caller          : Source_Ptr;
      Unit_Callee          : Unit_Number_Type;
      Unit_Caller          : Unit_Number_Type;

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

      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.

      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.

      Is_DIC : Boolean;
      --  Flag set when the subprogram being invoked is the procedure generated
      --  for pragma Default_Initial_Condition.

      SPARK_Elab_Errors : Boolean;
      --  Flag set when an entity is called or a variable is read during SPARK
      --  dynamic elaboration.

   --  Start of processing for Check_A_Call

   begin
      --  If the call is known to be within a local Suppress Elaboration
      --  pragma, nothing to check. This can happen in task bodies. But
      --  we ignore this for a call to a generic formal.

      if Nkind (N) in N_Subprogram_Call
        and then No_Elaboration_Check (N)
        and then not Is_Call_Of_Generic_Formal (N)
      then
         return;

      --  If this is a rewrite of a Valid_Scalars attribute, then nothing to
      --  check, we don't mind in this case if the call occurs before the body
      --  since this is all generated code.

      elsif Nkind (Original_Node (N)) = N_Attribute_Reference
        and then Attribute_Name (Original_Node (N)) = Name_Valid_Scalars
      then
         return;

      --  Intrinsics such as instances of Unchecked_Deallocation do not have
      --  any body, so elaboration checking is not needed, and would be wrong.

      elsif Is_Intrinsic_Subprogram (E) then
         return;

      --  Do not consider references to internal variables for SPARK semantics

      elsif Variable_Case and then not Comes_From_Source (E) then
         return;
      end if;

      --  Proceed with check

      Ent := E;

      --  For a variable reference, just set Body_Acts_As_Spec to False

      if Variable_Case then
         Body_Acts_As_Spec := False;

      --  Additional checks for all other cases

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

         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) in
                 N_Subprogram_Declaration | 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, or in the SPARK case, a variable reference, 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;
      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);

         pragma Assert (E_Scope /= Standard_Standard);

         --  Move up a scope looking for compilation unit

         E_Scope := Scope (E_Scope);
      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 in same unit as call or instantiation. In the
      --  instantiation case, W_Scope may be different from E_Scope; we want
      --  the unit in which the instantiation occurs, since we're analyzing
      --  based on the expansion.

      if W_Scope = C_Scope then
         if not Inter_Unit_Only then
            Check_Internal_Call (N, Ent, Outer_Scope, E);
         end if;

         return;
      end if;

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

      --  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 a call to an instance
      --  cannot fail the elaboration check, because the body of the instance
      --  is always elaborated immediately after the spec.

      if Call_To_Instance_From_Outside (Ent) 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  : constant Entity_Id := Etype (First_Formal (Ent));
               Init : Entity_Id;

            begin
               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 := In_Internal_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 := In_Internal_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 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 that
      --  requires an Elaborate_All.

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

      --  We also need to chase the call in the usual manner if it is a call
      --  to a generic formal parameter, since that case was not handled as
      --  part of the processing of the template.

      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
        and then not Is_Call_Of_Generic_Formal (N)
      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 where N is not an instance, and is not a call within
      --  instance to other than a generic formal, we recompute E_Scope
      --  for the error message, since we do NOT want to go to the unit
      --  that 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 or Variable_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 could be a previous error, but not if we've
            --  already reached the outermost level (Standard).

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

      if Within_Elaborate_All (Current_Sem_Unit, E_Scope) then
         return;
      end if;

      --  Determine whether the Default_Initial_Condition procedure of some
      --  type is being invoked.

      Is_DIC := Ekind (Ent) = E_Procedure and then Is_DIC_Procedure (Ent);

      --  Checks related to Default_Initial_Condition fall under the SPARK
      --  umbrella because this is a SPARK-specific annotation.

      SPARK_Elab_Errors :=
        SPARK_Mode = On and (Is_DIC or Dynamic_Elaboration_Checks);

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

      if (Elab_Info_Messages or Elab_Warnings or SPARK_Elab_Errors)
        and then Generate_Warnings
        and then 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)
      then
         --  Instantiation case

         if Inst_Case then
            if Comes_From_Source (Ent) and then SPARK_Elab_Errors then
               Error_Msg_NE
                 ("instantiation of & during elaboration in SPARK", N, Ent);
            else
               Elab_Warning
                 ("instantiation of & may raise Program_Error?l?",
                  "info: instantiation of & during elaboration?$?", Ent);
            end if;

         --  Indirect call case, info message only in static elaboration
         --  case, because the attribute reference itself cannot raise an
         --  exception. Note that SPARK does not permit indirect calls.

         elsif Access_Case then
            Elab_Warning ("", "info: access to & during elaboration?$?", Ent);

         --  Variable reference in SPARK mode

         elsif Variable_Case then
            if Comes_From_Source (Ent) and then SPARK_Elab_Errors then
               Error_Msg_NE
                 ("reference to & during elaboration in SPARK", N, Ent);
            end if;

         --  Subprogram call case

         else
            if Nkind (Name (N)) in N_Has_Entity
              and then Is_Init_Proc (Entity (Name (N)))
              and then Comes_From_Source (Ent)
            then
               Elab_Warning
                 ("implicit call to & may raise Program_Error?l?",
                  "info: implicit call to & during elaboration?$?",
                  Ent);

            elsif SPARK_Elab_Errors then

               --  Emit a specialized error message when the elaboration of an
               --  object of a private type evaluates the expression of pragma
               --  Default_Initial_Condition. This prevents the internal name
               --  of the procedure from appearing in the error message.

               if Is_DIC then
                  Error_Msg_N
                    ("call to Default_Initial_Condition during elaboration in "
                     & "SPARK", N);
               else
                  Error_Msg_NE
                    ("call to & during elaboration in SPARK", N, Ent);
               end if;

            else
               Elab_Warning
                 ("call to & may raise Program_Error?l?",
                  "info: call to & during elaboration?$?",
                  Ent);
            end if;
         end if;

         Error_Msg_Qual_Level := Nat'Last;

         --  Case of Elaborate_All not present and required, for SPARK this
         --  is an error, so give an error message.

         if SPARK_Elab_Errors then
            Error_Msg_NE -- CODEFIX
              ("\Elaborate_All pragma required for&", N, W_Scope);

         --  Otherwise we generate an implicit pragma. For a subprogram
         --  instantiation, Elaborate is good enough, since no transitive
         --  call is possible at elaboration time in this case.

         elsif Nkind (N) in N_Subprogram_Instantiation then
            Elab_Warning
              ("\missing pragma Elaborate for&?l?",
               "\implicit pragma Elaborate for& generated?$?",
               W_Scope);

         --  For all other cases, we need an implicit Elaborate_All

         else
            Elab_Warning
              ("\missing pragma Elaborate_All for&?l?",
               "\implicit pragma Elaborate_All for & generated?$?",
               W_Scope);
         end if;

         Error_Msg_Qual_Level := 0;

         --  Take into account the flags related to elaboration warning
         --  messages when enumerating the various calls involved. This
         --  ensures the proper pairing of the main warning and the
         --  clarification messages generated by Output_Calls.

         Output_Calls (N, Check_Elab_Flag => True);

         --  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);
         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)));

            --  Prevent duplicate elaboration checks on the same call, which
            --  can happen if the body enclosing the call appears itself in a
            --  call whose elaboration check is delayed.

            if Nkind (N) in N_Subprogram_Call then
               Set_No_Elaboration_Check (N);
            end if;
         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;

         --  Do not generate an Elaborate_All for finalization routines
         --  that perform partial clean up as part of initialization.

         elsif In_Init_Proc and then Is_Finalization_Procedure (Ent) then
            null;

         --  Here we need to generate an implicit elaborate all

         else
            --  Generate Elaborate_All warning unless suppressed

            if (Elab_Info_Messages 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
                 ("info: 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;
   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 Nat := Instantiation_Depth (Sloc (Ent));
         D2 : constant Nat := 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_Warn := SPARK_Mode /= On;
      Error_Msg_NE ("cannot instantiate& before body seen<<", N, Ent);
      Error_Msg_N ("\Program_Error [<<", N);

      Insert_Elab_Check (N);
      Set_Is_Known_Guaranteed_ABE (N);
   end Check_Bad_Instantiation;

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

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

   begin
      pragma Assert (Legacy_Elaboration_Checks);

      --  If the reference is not in 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 an expected type of reference (happens
      --  in some error conditions, and in some cases where rewriting occurs).

      elsif Nkind (N) not in N_Subprogram_Call
        and then Nkind (N) /= N_Attribute_Reference
        and then (SPARK_Mode /= On
                   or else Nkind (N) not in N_Has_Entity
                   or else No (Entity (N))
                   or else Ekind (Entity (N)) /= E_Variable)
      then
         return;

      --  Nothing to do if this is a call already rewritten for elab checking.
      --  Such calls appear as the targets of If_Expressions.

      --  This check MUST be wrong, it catches far too much

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

      --  Nothing to do if inside a generic template

      elsif Inside_A_Generic
        and then No (Enclosing_Generic_Body (N))
      then
         return;

      --  Nothing to do if call is being preanalyzed, as when within a
      --  pre/postcondition, a predicate, or an invariant.

      elsif In_Spec_Expression then
         return;
      end if;

      --  Nothing to do if this is a call to a postcondition, which is always
      --  within a subprogram body, even though the current scope may be the
      --  enclosing scope of the subprogram.

      if Nkind (N) = N_Procedure_Call_Statement
        and then Is_Entity_Name (Name (N))
        and then Chars (Entity (Name (N))) = Name_uPostconditions
      then
         return;
      end if;

      --  Here we have a reference at elaboration time that must be checked

      if Debug_Flag_Underscore_LL then
         Write_Str ("  Check_Elab_Ref: ");

         if Nkind (N) = N_Attribute_Reference then
            if not Is_Entity_Name (Prefix (N)) then
               Write_Str ("<<not entity name>>");
            else
               Write_Name (Chars (Entity (Prefix (N))));
            end if;

            Write_Str ("'Access");

         elsif 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 ("  reference at ");
         Write_Location (Sloc (N));
         Write_Eol;
      end if;

      --  Climb up the tree to make sure we are not inside default expression
      --  of a parameter specification or a record component, since in both
      --  these cases, we will be doing the actual reference later, not now,
      --  and it is at the time of the actual reference (statically speaking)
      --  that we must do our static check, not at the time of its initial
      --  analysis).

      --  However, we have to check references 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) in N_Parameter_Specification | N_Component_Declaration
         then
            return;

         --  The reference 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 ref that comes from source in preelaborated unit
            --  and we are not inside a subprogram (i.e. we are in elab code).

            --  Ada 2022 (AI12-0175): Calls to certain functions that are
            --  essentially unchecked conversions are preelaborable.

            if Comes_From_Source (N)
              and then In_Preelaborated_Unit
              and then not In_Inlined_Body
              and then Nkind (N) /= N_Attribute_Reference
              and then not (Ada_Version >= Ada_2022
                             and then Is_Preelaborable_Construct (N))
            then
               Error_Preelaborated_Call (N);
               return;
            end if;

         --  Second case, we are inside a subprogram or concurrent unit, which
         --  means 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) in
                       N_Parameter_Specification | N_Component_Declaration
                  then
                     return;
                  end if;

                  --  A protected body has no elaboration code and contains
                  --  only other bodies.

                  if Nkind (P) = N_Protected_Body then
                     return;

                  elsif Nkind (P) in N_Subprogram_Body
                                   | N_Task_Body
                                   | N_Block_Statement
                                   | N_Entry_Body
                  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 reference, 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

                        --  We provide a debug flag to disable this check. 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_Referenced_Ent (N);

                        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
                           if Nkind (N) in N_Subprogram_Call then
                              Set_No_Elaboration_Check (N);
                           end if;
                        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_Referenced_Ent (N);

      if No (Ent) then
         return;
      end if;

      --  Determine whether a prior call to the same subprogram was already
      --  examined within the same context. If this is the case, then there is
      --  no need to proceed with the various warnings and checks because the
      --  work was already done for the previous call.

      declare
         Self : constant Visited_Element :=
                  (Subp_Id => Ent, Context => Parent (N));

      begin
         for Index in 1 .. Elab_Visited.Last loop
            if Self = Elab_Visited.Table (Index) then
               return;
            end if;
         end loop;
      end;

      --  See if we need to analyze this reference. 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 reference from elaboration code, or a call to
      --    an 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 reference, then we follow it if it is within the
      --  original scope of the outer reference.

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

      --  Nothing to do if elaboration checks suppressed for this scope.
      --  However, an interesting exception, the fact that elaboration checks
      --  are suppressed within an instance (because we can trace the body when
      --  we process the template) does not extend to calls to generic formal
      --  subprograms.

      elsif Elaboration_Checks_Suppressed (Current_Scope)
        and then not Is_Call_Of_Generic_Formal (N)
      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 Check_Init_Call (Nod : Node_Id) return Traverse_Result;
            --  Find subprogram calls within body of Init_Proc for Traverse
            --  instantiation below.

            procedure Traverse_Body is new Traverse_Proc (Check_Init_Call);
            --  Traversal procedure to find all calls with body of Init_Proc

            ---------------------
            -- Check_Init_Call --
            ---------------------

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

            begin
               if Nkind (Nod) in N_Subprogram_Call
                 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 Check_Init_Call;

         --  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_Assign --
   -----------------------

   procedure Check_Elab_Assign (N : Node_Id) is
      Ent  : Entity_Id;
      Scop : Entity_Id;

      Pkg_Spec : Entity_Id;
      Pkg_Body : Entity_Id;

   begin
      pragma Assert (Legacy_Elaboration_Checks);

      --  For record or array component, check prefix. If it is an access type,
      --  then there is nothing to do (we do not know what is being assigned),
      --  but otherwise this is an assignment to the prefix.

      if Nkind (N) in N_Indexed_Component | N_Selected_Component | N_Slice then
         if not Is_Access_Type (Etype (Prefix (N))) then
            Check_Elab_Assign (Prefix (N));
         end if;

         return;
      end if;

      --  For type conversion, check expression

      if Nkind (N) = N_Type_Conversion then
         Check_Elab_Assign (Expression (N));
         return;
      end if;

      --  Nothing to do if this is not an entity reference otherwise get entity

      if Is_Entity_Name (N) then
         Ent := Entity (N);
      else
         return;
      end if;

      --  What we are looking for is a reference in the body of a package that
      --  modifies a variable declared in the visible part of the package spec.

      if Present (Ent)
        and then Comes_From_Source (N)
        and then not Suppress_Elaboration_Warnings (Ent)
        and then Ekind (Ent) = E_Variable
        and then not In_Private_Part (Ent)
        and then Is_Library_Level_Entity (Ent)
      then
         Scop := Current_Scope;
         loop
            if No (Scop) or else Scop = Standard_Standard then
               return;
            elsif Ekind (Scop) = E_Package
              and then Is_Compilation_Unit (Scop)
            then
               exit;
            else
               Scop := Scope (Scop);
            end if;
         end loop;

         --  Here Scop points to the containing library package

         Pkg_Spec := Scop;
         Pkg_Body := Body_Entity (Pkg_Spec);

         --  All OK if the package has an Elaborate_Body pragma

         if Has_Pragma_Elaborate_Body (Scop) then
            return;
         end if;

         --  OK if entity being modified is not in containing package spec

         if not In_Same_Source_Unit (Scop, Ent) then
            return;
         end if;

         --  All OK if entity appears in generic package or generic instance.
         --  We just get too messed up trying to give proper warnings in the
         --  presence of generics. Better no message than a junk one.

         Scop := Scope (Ent);
         while Present (Scop) and then Scop /= Pkg_Spec loop
            if Ekind (Scop) = E_Generic_Package then
               return;
            elsif Ekind (Scop) = E_Package
              and then Is_Generic_Instance (Scop)
            then
               return;
            end if;

            Scop := Scope (Scop);
         end loop;

         --  All OK if in task, don't issue warnings there

         if In_Task_Activation then
            return;
         end if;

         --  OK if no package body

         if No (Pkg_Body) then
            return;
         end if;

         --  OK if reference is not in package body

         if not In_Same_Source_Unit (Pkg_Body, N) then
            return;
         end if;

         --  OK if package body has no handled statement sequence

         declare
            HSS : constant Node_Id :=
                    Handled_Statement_Sequence (Declaration_Node (Pkg_Body));
         begin
            if No (HSS) or else not Comes_From_Source (HSS) then
               return;
            end if;
         end;

         --  We definitely have a case of a modification of an entity in
         --  the package spec from the elaboration code of the package body.
         --  We may not give the warning (because there are some additional
         --  checks to avoid too many false positives), but it would be a good
         --  idea for the binder to try to keep the body elaboration close to
         --  the spec elaboration.

         Set_Elaborate_Body_Desirable (Pkg_Spec);

         --  All OK in gnat mode (we know what we are doing)

         if GNAT_Mode then
            return;
         end if;

         --  All OK if all warnings suppressed

         if Warning_Mode = Suppress then
            return;
         end if;

         --  All OK if elaboration checks suppressed for entity

         if Checks_May_Be_Suppressed (Ent)
           and then Is_Check_Suppressed (Ent, Elaboration_Check)
         then
            return;
         end if;

         --  OK if the entity is initialized. Note that the No_Initialization
         --  flag usually means that the initialization has been rewritten into
         --  assignments, but that still counts for us.

         declare
            Decl : constant Node_Id := Declaration_Node (Ent);
         begin
            if Nkind (Decl) = N_Object_Declaration
              and then (Present (Expression (Decl))
                         or else No_Initialization (Decl))
            then
               return;
            end if;
         end;

         --  Here is where we give the warning

         --  All OK if warnings suppressed on the entity

         if not Has_Warnings_Off (Ent) then
            Error_Msg_Sloc := Sloc (Ent);

            Error_Msg_NE
              ("??& can be accessed by clients before this initialization",
               N, Ent);
            Error_Msg_NE
              ("\??add Elaborate_Body to spec to ensure & is initialized",
               N, Ent);
         end if;

         if not All_Errors_Mode then
            Set_Suppress_Elaboration_Warnings (Ent);
         end if;
      end if;
   end Check_Elab_Assign;

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

   --  WARNING: This routine manages SPARK regions

   procedure Check_Elab_Calls is
      Saved_SM  : SPARK_Mode_Type;
      Saved_SMP : Node_Id;

   begin
      pragma Assert (Legacy_Elaboration_Checks);

      --  If expansion is disabled, do not generate any checks, unless we
      --  are in GNATprove mode, so that errors are issued in GNATprove for
      --  violations of static elaboration rules in SPARK code. 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 and not GNATprove_Mode)
        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
            Push_Scope (Delay_Check.Table (J).Curscop);
            From_Elab_Code := Delay_Check.Table (J).From_Elab_Code;
            In_Task_Activation := Delay_Check.Table (J).In_Task_Activation;

            Saved_SM  := SPARK_Mode;
            Saved_SMP := SPARK_Mode_Pragma;

            --  Set appropriate value of SPARK_Mode

            if Delay_Check.Table (J).From_SPARK_Code then
               SPARK_Mode := On;
            end if;

            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);

            Restore_SPARK_Mode (Saved_SM, Saved_SMP);
            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
      pragma Assert (Legacy_Elaboration_Checks);

      --  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 Is_Known_Guaranteed_ABE (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 elaboration 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
      function Within_Initial_Condition (Call : Node_Id) return Boolean;
      --  Determine whether call Call occurs within pragma Initial_Condition or
      --  pragma Check with check_kind set to Initial_Condition.

      ------------------------------
      -- Within_Initial_Condition --
      ------------------------------

      function Within_Initial_Condition (Call : Node_Id) return Boolean is
         Args : List_Id;
         Nam  : Name_Id;
         Par  : Node_Id;

      begin
         --  Traverse the parent chain looking for an enclosing pragma

         Par := Call;
         while Present (Par) loop
            if Nkind (Par) = N_Pragma then
               Nam := Pragma_Name (Par);

               --  Pragma Initial_Condition appears in its alternative from as
               --  Check (Initial_Condition, ...).

               if Nam = Name_Check then
                  Args := Pragma_Argument_Associations (Par);

                  --  Pragma Check should have at least two arguments

                  pragma Assert (Present (Args));

                  return
                    Chars (Expression (First (Args))) = Name_Initial_Condition;

               --  Direct match

               elsif Nam = Name_Initial_Condition then
                  return True;

               --  Since pragmas are never nested within other pragmas, stop
               --  the traversal.

               else
                  return False;
               end if;

            --  Prevent the search from going too far

            elsif Is_Body_Or_Package_Declaration (Par) then
               exit;
            end if;

            Par := Parent (Par);

            --  If assertions are not enabled, the check pragma is rewritten
            --  as an if_statement in sem_prag, to generate various warnings
            --  on boolean expressions. Retrieve the original pragma.

            if Nkind (Original_Node (Par)) = N_Pragma then
               Par := Original_Node (Par);
            end if;
         end loop;

         return False;
      end Within_Initial_Condition;

      --  Local variables

      Inst_Case : constant Boolean := Nkind (N) in N_Generic_Instantiation;

   --  Start of processing for Check_Internal_Call

   begin
      --  For P'Access, we want to warn if the -gnatw.f switch is set, and the
      --  node comes from source.

      if Nkind (N) = N_Attribute_Reference
        and then ((not Warn_On_Elab_Access and then not Debug_Flag_Dot_O)
                    or else not Comes_From_Source (N))
      then
         return;

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

      elsif Nkind (N) not in N_Attribute_Reference
                           | N_Function_Call
                           | 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 Nkind (N) /= N_Attribute_Reference
        and then Is_Known_Guaranteed_ABE (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 analyzing in special spec-expression mode, since the
      --  call is not actually being made at this time.

      elsif In_Spec_Expression then
         return;

      --  Nothing to do for call to intrinsic subprogram

      elsif Is_Intrinsic_Subprogram (E) then
         return;

      --  Nothing to do if call is within a generic unit

      elsif Inside_A_Generic then
         return;

      --  Nothing to do when the call appears within pragma Initial_Condition.
      --  The pragma is part of the elaboration statements of a package body
      --  and may only call external subprograms or subprograms whose body is
      --  already available.

      elsif Within_Initial_Condition (N) then
         return;
      end if;

      --  Delay this call if we are still delaying calls

      if Delaying_Elab_Checks then
         Delay_Check.Append
           ((N                  => N,
             E                  => E,
             Orig_Ent           => Orig_Ent,
             Curscop            => Current_Scope,
             Outer_Scope        => Outer_Scope,
             From_Elab_Code     => From_Elab_Code,
             In_Task_Activation => In_Task_Activation,
             From_SPARK_Code    => SPARK_Mode = On));
         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
      function Find_Elab_Reference (N : Node_Id) return Traverse_Result;
      --  Function applied to each node as we traverse the body. Checks for
      --  call or entity reference that needs checking, and if so checks it.
      --  Always returns OK, so entire tree is traversed, except that as
      --  described below subprogram bodies are skipped for now.

      procedure Traverse is new Atree.Traverse_Proc (Find_Elab_Reference);
      --  Traverse procedure using above Find_Elab_Reference function

      -------------------------
      -- Find_Elab_Reference --
      -------------------------

      function Find_Elab_Reference (N : Node_Id) return Traverse_Result is
         Actual : Node_Id;

      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)) in
              N_Accept_Statement | N_Selective_Accept
           and then Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
         then
            return Abandon;

         --  If we have a function call, check it

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

         --  If we have a procedure call, check the call, and also check
         --  arguments that are assignments (OUT or IN OUT mode formals).

         elsif Nkind (N) = N_Procedure_Call_Statement then
            Check_Elab_Call (N, Outer_Scope, In_Init_Proc => Is_Init_Proc (E));

            Actual := First_Actual (N);
            while Present (Actual) loop
               if Known_To_Be_Assigned (Actual) then
                  Check_Elab_Assign (Actual);
               end if;

               Next_Actual (Actual);
            end loop;

            return OK;

         --  If we have an access attribute for a subprogram, check it.
         --  Suppress this behavior under debug flag.

         elsif not Debug_Flag_Dot_UU
           and then Nkind (N) = N_Attribute_Reference
           and then
             Attribute_Name (N) in Name_Access | Name_Unrestricted_Access
           and then Is_Entity_Name (Prefix (N))
           and then Is_Subprogram (Entity (Prefix (N)))
         then
            Check_Elab_Call (N, Outer_Scope);
            return OK;

         --  In SPARK mode, if we have an entity reference to a variable, then
         --  check it. For now we consider any reference.

         elsif SPARK_Mode = On
           and then Nkind (N) in N_Has_Entity
           and then Present (Entity (N))
           and then Ekind (Entity (N)) = E_Variable
         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;

         elsif Nkind (N) = N_Assignment_Statement
           and then Comes_From_Source (N)
         then
            Check_Elab_Assign (Name (N));
            return OK;

         else
            return OK;
         end if;
      end Find_Elab_Reference;

      Inst_Case : constant Boolean    := Is_Generic_Unit (E);
      Loc       : constant Source_Ptr := Sloc (N);

      Ebody : Entity_Id;
      Sbody : Node_Id;

   --  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;

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

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

      --  Register the subprogram as examined within this particular context.
      --  This ensures that calls to the same subprogram but in different
      --  contexts receive warnings and checks of their own since the calls
      --  may be reached through different flow paths.

      Elab_Visited.Append ((Subp_Id => E, Context => Parent (N)));

      Sbody := Unit_Declaration_Node (E);

      if Nkind (Sbody) not in N_Subprogram_Body | 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.Append ((Cloc => Loc, Ent => E));

         if Debug_Flag_Underscore_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;
         begin
            Decl := First (Declarations (Sbody));
            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, except if this is the
      --  case of appearing within an aspect specification that results in
      --  a check call, we do not really have such a situation, so no warning
      --  is needed (e.g. the case of a precondition, where the call appears
      --  textually before the body, but in actual fact is moved to the
      --  appropriate subprogram body and so does not need a check).

      declare
         P : Node_Id;
         O : Node_Id;

      begin
         P := Parent (N);
         loop
            --  Keep looking at parents if we are still in the subexpression

            if Nkind (P) in N_Subexpr then
               P := Parent (P);

            --  Here P is the parent of the expression, check for special case

            else
               O := Original_Node (P);

               --  Definitely not the special case if orig node is not a pragma

               exit when Nkind (O) /= N_Pragma;

               --  Check we have an If statement or a null statement (happens
               --  when the If has been expanded to be True).

               exit when Nkind (P) not in N_If_Statement | N_Null_Statement;

               --  Our special case will be indicated either by the pragma
               --  coming from an aspect ...

               if Present (Corresponding_Aspect (O)) then
                  return;

               --  Or, in the case of an initial condition, specifically by a
               --  Check pragma specifying an Initial_Condition check.

               elsif Pragma_Name (O) = Name_Check
                 and then
                   Chars
                     (Expression (First (Pragma_Argument_Associations (O)))) =
                                                       Name_Initial_Condition
               then
                  return;

               --  For anything else, we have an error

               else
                  exit;
               end if;
            end if;
         end loop;
      end;

      --  Not that special case, warning and dynamic check is required

      --  If we have nothing in the call stack, then this is at the outer
      --  level, and the ABE is bound to occur, unless it's a 'Access, or
      --  it's a renaming.

      if Elab_Call.Last = 0 then
         Error_Msg_Warn := SPARK_Mode /= On;

         declare
            Insert_Check : Boolean := True;
            --  This flag is set to True if an elaboration check should be
            --  inserted.

         begin
            if In_Task_Activation then
               Insert_Check := False;

            elsif Inst_Case then
               Error_Msg_NE
                 ("cannot instantiate& before body seen<<", N, Orig_Ent);

            elsif Nkind (N) = N_Attribute_Reference then
               Error_Msg_NE
                 ("Access attribute of & before body seen<<", N, Orig_Ent);
               Error_Msg_N
                 ("\possible Program_Error on later references<<", N);
               Insert_Check := False;

            elsif Nkind (Unit_Declaration_Node (Orig_Ent)) /=
                    N_Subprogram_Renaming_Declaration
              or else Is_Generic_Actual_Subprogram (Orig_Ent)
            then
               Error_Msg_NE
                 ("cannot call& before body seen<<", N, Orig_Ent);
            else
               Insert_Check := False;
            end if;

            if Insert_Check then
               Error_Msg_N ("\Program_Error [<<", N);
               Insert_Elab_Check (N);
            end if;
         end;

      --  Call is not at outer level

      else
         --  Do not generate elaboration checks in GNATprove mode because the
         --  elaboration counter and the check are both forms of expansion.

         if GNATprove_Mode then
            null;

         --  Generate an elaboration check

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

            --  Create a declaration of the elaboration entity, and insert it
            --  prior to the subprogram or the generic unit, within the same
            --  scope. Since the subprogram may be overloaded, create a unique
            --  entity.

            if No (Elaboration_Entity (E)) then
               declare
                  Loce : constant Source_Ptr := Sloc (E);
                  Ent  : constant Entity_Id  :=
                           Make_Defining_Identifier (Loc,
                             New_External_Name (Chars (E), 'E', -1));

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

                  Insert_Action (Declaration_Node (E),
                    Make_Object_Declaration (Loce,
                      Defining_Identifier => Ent,
                      Object_Definition   =>
                        New_Occurrence_Of (Standard_Short_Integer, Loce),
                      Expression          =>
                        Make_Integer_Literal (Loc, Uint_0)));

                  --  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_Last_Assignment  (Ent, Empty);
                  Set_Is_True_Constant (Ent, False);
                  Pop_Scope;
               end;
            end if;

            --  Generate:
            --    if Enn = 0 then
            --       raise Program_Error with "access before elaboration";
            --    end if;

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

         --  Generate the warning

         if not Suppress_Elaboration_Warnings (E)
           and then not Elaboration_Checks_Suppressed (E)

           --  Suppress this warning if we have a function call that occurred
           --  within an assertion expression, since we can get false warnings
           --  in this case, due to the out of order handling in this case.

           and then
             (Nkind (Original_Node (N)) /= N_Function_Call
               or else not In_Assertion_Expression_Pragma (Original_Node (N)))
         then
            Error_Msg_Warn := SPARK_Mode /= On;

            if Inst_Case then
               Error_Msg_NE
                 ("instantiation of& may occur before body is seen<l<",
                  N, Orig_Ent);
            else
               --  A rather specific check. For Finalize/Adjust/Initialize, if
               --  the type has Warnings_Off set, suppress the warning.

               if Chars (E) in Name_Adjust
                             | Name_Finalize
                             | Name_Initialize
                 and then Present (First_Formal (E))
               then
                  declare
                     T : constant Entity_Id := Etype (First_Formal (E));
                  begin
                     if Is_Controlled (T) then
                        if Warnings_Off (T)
                          or else (Ekind (T) = E_Private_Type
                                    and then Warnings_Off (Full_View (T)))
                        then
                           goto Output;
                        end if;
                     end if;
                  end;
               end if;

               --  Go ahead and give warning if not this special case

               Error_Msg_NE
                 ("call to& may occur before body is seen<l<", N, Orig_Ent);
            end if;

            Error_Msg_N ("\Program_Error ]<l<", N);

            --  There is no need to query the elaboration warning message flags
            --  because the main message is an error, not a warning, therefore
            --  all the clarification messages produces by Output_Calls must be
            --  emitted unconditionally.

            <<Output>>

            Output_Calls (N, Check_Elab_Flag => False);
         end if;
      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 that 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));
               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_Warn := SPARK_Mode /= On;
                  Error_Msg_N
                    ("task will be activated before elaboration of its body<<",
                      Decl);
                  Error_Msg_N ("\Program_Error [<<", Decl);

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

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

               Elmt := First_Elmt (Inter_Procs);
               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;

      begin
         Outer := E;
         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
      pragma Assert (Legacy_Elaboration_Checks);

      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 that 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 counter for the unit containing the entity.

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

         else
            --  Force the binder to elaborate other unit first

            if Elab_Info_Messages
              and then not Suppress_Elaboration_Warnings (Ent)
              and then not Elaboration_Checks_Suppressed (Ent)
              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
                 ("info: activation of an instance of task type & requires "
                  & "pragma Elaborate_All on &?$?", N, Ent);
            end if;

            Activate_Elaborate_All_Desirable (N, 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.

      if not Debug_Flag_Dot_Y then
         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 if;
   end Check_Task_Activation;

   ------------------------
   -- Get_Referenced_Ent --
   ------------------------

   function Get_Referenced_Ent (N : Node_Id) return Entity_Id is
      Nam : Node_Id;

   begin
      if Nkind (N) in N_Has_Entity
        and then Present (Entity (N))
        and then Ekind (Entity (N)) = E_Variable
      then
         return Entity (N);
      end if;

      if Nkind (N) = N_Attribute_Reference then
         Nam := Prefix (N);
      else
         Nam := Name (N);
      end if;

      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_Referenced_Ent;

   ----------------------
   -- 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_Or_Generic_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_Or_Generic_Package (Scop) then
            declare
               P : Node_Id;

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

               P := Declaration_Node (Ent);
               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);

      Chk : Node_Id;
      --  The check (N_Raise_Program_Error) node to be inserted

   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;

      --  Build check node, possibly with condition

      Chk :=
        Make_Raise_Program_Error (Loc, Reason => PE_Access_Before_Elaboration);

      if Present (C) then
         Set_Condition (Chk, Make_Op_Not (Loc, Right_Opnd => C));
      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));

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

            Analyze (Chk);
         end;

      --  Otherwise just insert as an action on the node in question

      else
         Insert_Action (Nod, Chk);
      end if;
   end Insert_Elab_Check;

   -------------------------------
   -- Is_Call_Of_Generic_Formal --
   -------------------------------

   function Is_Call_Of_Generic_Formal (N : Node_Id) return Boolean is
   begin
      return Nkind (N) in N_Subprogram_Call

        --  Always return False if debug flag -gnatd.G is set

        and then not Debug_Flag_Dot_GG

      --  For now, we detect this by looking for the strange identifier
      --  node, whose Chars reflect the name of the generic formal, but
      --  the Chars of the Entity references the generic actual.

        and then Nkind (Name (N)) = N_Identifier
        and then Chars (Name (N)) /= Chars (Entity (Name (N)));
   end Is_Call_Of_Generic_Formal;

   -------------------------------
   -- Is_Finalization_Procedure --
   -------------------------------

   function Is_Finalization_Procedure (Id : Entity_Id) return Boolean is
   begin
      --  Check whether Id is a procedure with at least one parameter

      if Ekind (Id) = E_Procedure and then Present (First_Formal (Id)) then
         declare
            Typ      : constant Entity_Id := Etype (First_Formal (Id));
            Deep_Fin : Entity_Id := Empty;
            Fin      : Entity_Id := Empty;

         begin
            --  If the type of the first formal does not require finalization
            --  actions, then this is definitely not [Deep_]Finalize.

            if not Needs_Finalization (Typ) then
               return False;
            end if;

            --  At this point we have the following scenario:

            --    procedure Name (Param1 : [in] [out] Ctrl[; Param2 : ...]);

            --  Recover the two possible versions of [Deep_]Finalize using the
            --  type of the first parameter and compare with the input.

            Deep_Fin := TSS (Typ, TSS_Deep_Finalize);

            if Is_Controlled (Typ) then
               Fin := Find_Prim_Op (Typ, Name_Finalize);
            end if;

            return    (Present (Deep_Fin) and then Id = Deep_Fin)
              or else (Present (Fin)      and then Id = Fin);
         end;
      end if;

      return False;
   end Is_Finalization_Procedure;

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

   procedure Output_Calls
     (N               : Node_Id;
      Check_Elab_Flag : Boolean)
   is
      function Emit (Flag : Boolean) return Boolean;
      --  Determine whether to emit an error message based on the combination
      --  of flags Check_Elab_Flag and Flag.

      function Is_Printable_Error_Name return Boolean;
      --  An internal function, used to determine if a name, stored in the
      --  Name_Buffer, 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).

      ----------
      -- Emit --
      ----------

      function Emit (Flag : Boolean) return Boolean is
      begin
         if Check_Elab_Flag then
            return Flag;
         else
            return True;
         end if;
      end Emit;

      -----------------------------
      -- Is_Printable_Error_Name --
      -----------------------------

      function Is_Printable_Error_Name return Boolean is
      begin
         if not Is_Internal_Name 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;

      --  Local variables

      Ent : Entity_Id;

   --  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;
         Get_Name_String (Chars (Ent));

         --  Dynamic elaboration model, warnings controlled by -gnatwl

         if Dynamic_Elaboration_Checks then
            if Emit (Elab_Warnings) then
               if Is_Generic_Unit (Ent) then
                  Error_Msg_NE ("\\?l?& instantiated #", N, Ent);
               elsif Is_Init_Proc (Ent) then
                  Error_Msg_N ("\\?l?initialization procedure called #", N);
               elsif Is_Printable_Error_Name then
                  Error_Msg_NE ("\\?l?& called #", N, Ent);
               else
                  Error_Msg_N ("\\?l?called #", N);
               end if;
            end if;

         --  Static elaboration model, info messages controlled by -gnatel

         else
            if Emit (Elab_Info_Messages) then
               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 then
                  Error_Msg_NE ("\\?$?& called #", N, Ent);
               else
                  Error_Msg_N ("\\?$?called #", N);
               end if;
            end if;
         end if;
      end loop;
   end Output_Calls;

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

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

   begin
      --  Find elaboration scope for Scop1
      --  This is either a subprogram or a compilation unit.

      S1 := Scop1;
      while S1 /= Standard_Standard
        and then not Is_Compilation_Unit (S1)
        and then Ekind (S1) in E_Package | E_Protected_Type | E_Block
      loop
         S1 := Scope (S1);
      end loop;

      --  Find elaboration scope for Scop2

      S2 := Scop2;
      while S2 /= Standard_Standard
        and then not Is_Compilation_Unit (S2)
        and then Ekind (S2) in E_Package | E_Protected_Type | 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;

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

   procedure Set_Elaboration_Constraint
    (Call : Node_Id;
     Subp : Entity_Id;
     Scop : Entity_Id)
   is
      Elab_Unit : Entity_Id;

      --  Check whether this is a call to an Initialize subprogram for a
      --  controlled type. Note that Call can also be a 'Access attribute
      --  reference, which now generates an elaboration check.

      Init_Call : constant Boolean :=
                    Nkind (Call) = N_Procedure_Call_Statement
                      and then Chars (Subp) = Name_Initialize
                      and then Comes_From_Source (Subp)
                      and then Present (Parameter_Associations (Call))
                      and then Is_Controlled (Etype (First_Actual (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_Lib_Unit (Scop))
      then
         Activate_Elaborate_All_Desirable (Call, Scop);
         Set_Suppress_Elaboration_Warnings (Scop);
         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
         Activate_Elaborate_All_Desirable (Call, Scop);
         Set_Suppress_Elaboration_Warnings (Scop);
         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. This happens
      --  with init proc calls.

      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;

      --  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.

      elsif Nkind (Original_Node (Call)) = N_Selected_Component then
         Elab_Unit := Scope (Etype (First (Parameter_Associations (Call))));

      --  Not one of special cases above

      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;

      Activate_Elaborate_All_Desirable (Call, Elab_Unit);
      Set_Suppress_Elaboration_Warnings (Elab_Unit);
   end Set_Elaboration_Constraint;

   -----------------
   -- 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) in E_Void | E_Subprogram_Body | 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;

   ------------
   -- 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;
   end Within;

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

   function Within_Elaborate_All
     (Unit : Unit_Number_Type;
      E    : Entity_Id) return Boolean
   is
      type Unit_Number_Set is array (Main_Unit .. Last_Unit) of Boolean;
      pragma Pack (Unit_Number_Set);

      Seen : Unit_Number_Set := (others => False);
      --  Seen (X) is True after we have seen unit X in the walk. This is used
      --  to prevent processing the same unit more than once.

      Result : Boolean := False;

      procedure Helper (Unit : Unit_Number_Type);
      --  This helper procedure does all the work for Within_Elaborate_All. It
      --  walks the dependency graph, and sets Result to True if it finds an
      --  appropriate Elaborate_All.

      ------------
      -- Helper --
      ------------

      procedure Helper (Unit : Unit_Number_Type) is
         CU : constant Node_Id := Cunit (Unit);

         Item    : Node_Id;
         Item2   : Node_Id;
         Elab_Id : Entity_Id;
         Par     : Node_Id;

      begin
         if Seen (Unit) then
            return;
         else
            Seen (Unit) := True;
         end if;

         --  First, check for Elaborate_Alls on this unit

         Item := First (Context_Items (CU));
         while Present (Item) loop
            if Nkind (Item) = N_Pragma
              and then Pragma_Name (Item) = Name_Elaborate_All
            then
               --  Return if some previous error on the pragma itself. The
               --  pragma may be unanalyzed, because of a previous error, or
               --  if it is the context of a subunit, inherited by its parent.

               if Error_Posted (Item) or else not Analyzed (Item) then
                  return;
               end if;

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

               if E = Elab_Id then
                  Result := True;
                  return;
               end if;

               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
                    and then not Limited_Present (Item2)
                  then
                     Result := True;
                     return;
                  end if;

                  Next (Item2);
               end loop;
            end if;

            Next (Item);
         end loop;

         --  Second, recurse on with's. We could do this as part of the above
         --  loop, but it's probably more efficient to have two loops, because
         --  the relevant Elaborate_All is likely to be on the initial unit. In
         --  other words, we're walking the with's breadth-first. This part is
         --  only necessary in the dynamic elaboration model.

         if Dynamic_Elaboration_Checks then
            Item := First (Context_Items (CU));
            while Present (Item) loop
               if Nkind (Item) = N_With_Clause
                 and then not Limited_Present (Item)
               then
                  --  Note: the following call to Get_Cunit_Unit_Number does a
                  --  linear search, which could be slow, but it's OK because
                  --  we're about to give a warning anyway. Also, there might
                  --  be hundreds of units, but not millions. If it turns out
                  --  to be a problem, we could store the Get_Cunit_Unit_Number
                  --  in each N_Compilation_Unit node, but that would involve
                  --  rearranging N_Compilation_Unit_Aux to make room.

                  Helper (Get_Cunit_Unit_Number (Library_Unit (Item)));

                  if Result then
                     return;
                  end if;
               end if;

               Next (Item);
            end loop;
         end if;
      end Helper;

   --  Start of processing for Within_Elaborate_All

   begin
      Helper (Unit);
      return Result;
   end Within_Elaborate_All;

end Sem_Elab;
