------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ P R A G                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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.      --
--                                                                          --
------------------------------------------------------------------------------

--  This unit contains the semantic processing for all pragmas, both language
--  and implementation defined. For most pragmas, the parser only does the
--  most basic job of checking the syntax, so Sem_Prag also contains the code
--  to complete the syntax checks. Certain pragmas are handled partially or
--  completely by the parser (see Par.Prag for further details).

with Aspects;        use Aspects;
with Atree;          use Atree;
with Casing;         use Casing;
with Checks;         use Checks;
with Contracts;      use Contracts;
with Csets;          use Csets;
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_Dist;       use Exp_Dist;
with Exp_Util;       use Exp_Util;
with Expander;       use Expander;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with GNAT_CUDA;      use GNAT_CUDA;
with Gnatvsn;        use Gnatvsn;
with Lib;            use Lib;
with Lib.Writ;       use Lib.Writ;
with Lib.Xref;       use Lib.Xref;
with Namet.Sp;       use Namet.Sp;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Output;         use Output;
with Par_SCO;        use Par_SCO;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch3;        use Sem_Ch3;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Ch12;       use Sem_Ch12;
with Sem_Ch13;       use Sem_Ch13;
with Sem_Disp;       use Sem_Disp;
with Sem_Dist;       use Sem_Dist;
with Sem_Elab;       use Sem_Elab;
with Sem_Elim;       use Sem_Elim;
with Sem_Eval;       use Sem_Eval;
with Sem_Intr;       use Sem_Intr;
with Sem_Mech;       use Sem_Mech;
with Sem_Res;        use Sem_Res;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Sem_Warn;       use Sem_Warn;
with Stand;          use Stand;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinfo.CN;       use Sinfo.CN;
with Sinput;         use Sinput;
with Stringt;        use Stringt;
with Stylesw;        use Stylesw;
with Table;
with Targparm;       use Targparm;
with Tbuild;         use Tbuild;
with Ttypes;
with Uintp;          use Uintp;
with Uname;          use Uname;
with Urealp;         use Urealp;
with Validsw;        use Validsw;
with Warnsw;         use Warnsw;

with System.Case_Util;

package body Sem_Prag is

   ----------------------------------------------
   -- Common Handling of Import-Export Pragmas --
   ----------------------------------------------

   --  In the following section, a number of Import_xxx and Export_xxx pragmas
   --  are defined by GNAT. These are compatible with the DEC pragmas of the
   --  same name, and all have the following common form and processing:

   --  pragma Export_xxx
   --        [Internal                 =>] LOCAL_NAME
   --     [, [External                 =>] EXTERNAL_SYMBOL]
   --     [, other optional parameters   ]);

   --  pragma Import_xxx
   --        [Internal                 =>] LOCAL_NAME
   --     [, [External                 =>] EXTERNAL_SYMBOL]
   --     [, other optional parameters   ]);

   --   EXTERNAL_SYMBOL ::=
   --     IDENTIFIER
   --   | static_string_EXPRESSION

   --  The internal LOCAL_NAME designates the entity that is imported or
   --  exported, and must refer to an entity in the current declarative
   --  part (as required by the rules for LOCAL_NAME).

   --  The external linker name is designated by the External parameter if
   --  given, or the Internal parameter if not (if there is no External
   --  parameter, the External parameter is a copy of the Internal name).

   --  If the External parameter is given as a string, then this string is
   --  treated as an external name (exactly as though it had been given as an
   --  External_Name parameter for a normal Import pragma).

   --  If the External parameter is given as an identifier (or there is no
   --  External parameter, so that the Internal identifier is used), then
   --  the external name is the characters of the identifier, translated
   --  to all lower case letters.

   --  Note: the external name specified or implied by any of these special
   --  Import_xxx or Export_xxx pragmas override an external or link name
   --  specified in a previous Import or Export pragma.

   --  Note: these and all other DEC-compatible GNAT pragmas allow full use of
   --  named notation, following the standard rules for subprogram calls, i.e.
   --  parameters can be given in any order if named notation is used, and
   --  positional and named notation can be mixed, subject to the rule that all
   --  positional parameters must appear first.

   --  Note: All these pragmas are implemented exactly following the DEC design
   --  and implementation and are intended to be fully compatible with the use
   --  of these pragmas in the DEC Ada compiler.

   --------------------------------------------
   -- Checking for Duplicated External Names --
   --------------------------------------------

   --  It is suspicious if two separate Export pragmas use the same external
   --  name. The following table is used to diagnose this situation so that
   --  an appropriate warning can be issued.

   --  The Node_Id stored is for the N_String_Literal node created to hold
   --  the value of the external name. The Sloc of this node is used to
   --  cross-reference the location of the duplication.

   package Externals is new Table.Table (
     Table_Component_Type => Node_Id,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => 100,
     Table_Increment      => 100,
     Table_Name           => "Name_Externals");

   -------------------------------------
   -- Local Subprograms and Variables --
   -------------------------------------

   function Adjust_External_Name_Case (N : Node_Id) return Node_Id;
   --  This routine is used for possible casing adjustment of an explicit
   --  external name supplied as a string literal (the node N), according to
   --  the casing requirement of Opt.External_Name_Casing. If this is set to
   --  As_Is, then the string literal is returned unchanged, but if it is set
   --  to Uppercase or Lowercase, then a new string literal with appropriate
   --  casing is constructed.

   procedure Analyze_Part_Of
     (Indic    : Node_Id;
      Item_Id  : Entity_Id;
      Encap    : Node_Id;
      Encap_Id : out Entity_Id;
      Legal    : out Boolean);
   --  Subsidiary to Analyze_Part_Of_In_Decl_Part, Analyze_Part_Of_Option and
   --  Analyze_Pragma. Perform full analysis of indicator Part_Of. Indic is the
   --  Part_Of indicator. Item_Id is the entity of an abstract state, object or
   --  package instantiation. Encap denotes the encapsulating state or single
   --  concurrent type. Encap_Id is the entity of Encap. Flag Legal is set when
   --  the indicator is legal.

   function Appears_In (List : Elist_Id; Item_Id : Entity_Id) return Boolean;
   --  Subsidiary to analysis of pragmas Depends, Global and Refined_Depends.
   --  Query whether a particular item appears in a mixed list of nodes and
   --  entities. It is assumed that all nodes in the list have entities.

   procedure Check_Postcondition_Use_In_Inlined_Subprogram
     (Prag    : Node_Id;
      Spec_Id : Entity_Id);
   --  Subsidiary to the analysis of pragmas Contract_Cases, Postcondition,
   --  Precondition, Refined_Post, and Test_Case. Emit a warning when pragma
   --  Prag is associated with subprogram Spec_Id subject to Inline_Always,
   --  and assertions are enabled.

   procedure Check_State_And_Constituent_Use
     (States   : Elist_Id;
      Constits : Elist_Id;
      Context  : Node_Id);
   --  Subsidiary to the analysis of pragmas [Refined_]Depends, [Refined_]
   --  Global and Initializes. Determine whether a state from list States and a
   --  corresponding constituent from list Constits (if any) appear in the same
   --  context denoted by Context. If this is the case, emit an error.

   procedure Contract_Freeze_Error
     (Contract_Id : Entity_Id;
      Freeze_Id   : Entity_Id);
   --  Subsidiary to the analysis of pragmas Contract_Cases, Part_Of, Post, and
   --  Pre. Emit a freezing-related error message where Freeze_Id is the entity
   --  of a body which caused contract freezing and Contract_Id denotes the
   --  entity of the affected contstruct.

   procedure Duplication_Error (Prag : Node_Id; Prev : Node_Id);
   --  Subsidiary to all Find_Related_xxx routines. Emit an error on pragma
   --  Prag that duplicates previous pragma Prev.

   function Find_Encapsulating_State
     (States     : Elist_Id;
      Constit_Id : Entity_Id) return Entity_Id;
   --  Given the entity of a constituent Constit_Id, find the corresponding
   --  encapsulating state which appears in States. The routine returns Empty
   --  if no such state is found.

   function Find_Related_Context
     (Prag      : Node_Id;
      Do_Checks : Boolean := False) return Node_Id;
   --  Subsidiary to the analysis of pragmas
   --    Async_Readers
   --    Async_Writers
   --    Constant_After_Elaboration
   --    Effective_Reads
   --    Effective_Writers
   --    No_Caching
   --    Part_Of
   --  Find the first source declaration or statement found while traversing
   --  the previous node chain starting from pragma Prag. If flag Do_Checks is
   --  set, the routine reports duplicate pragmas. The routine returns Empty
   --  when reaching the start of the node chain.

   function Get_Base_Subprogram (Def_Id : Entity_Id) return Entity_Id;
   --  If Def_Id refers to a renamed subprogram, then the base subprogram (the
   --  original one, following the renaming chain) is returned. Otherwise the
   --  entity is returned unchanged. Should be in Einfo???

   function Get_SPARK_Mode_Type (N : Name_Id) return SPARK_Mode_Type;
   --  Subsidiary to the analysis of pragma SPARK_Mode as well as subprogram
   --  Get_SPARK_Mode_From_Annotation. Convert a name into a corresponding
   --  value of type SPARK_Mode_Type.

   function Has_Extra_Parentheses (Clause : Node_Id) return Boolean;
   --  Subsidiary to the analysis of pragmas Depends and Refined_Depends.
   --  Determine whether dependency clause Clause is surrounded by extra
   --  parentheses. If this is the case, issue an error message.

   function Is_Unconstrained_Or_Tagged_Item (Item : Entity_Id) return Boolean;
   --  Subsidiary to Collect_Subprogram_Inputs_Outputs and the analysis of
   --  pragma Depends. Determine whether the type of dependency item Item is
   --  tagged, unconstrained array, unconstrained record or a record with at
   --  least one unconstrained component.

   procedure Record_Possible_Body_Reference
     (State_Id : Entity_Id;
      Ref      : Node_Id);
   --  Subsidiary to the analysis of pragmas [Refined_]Depends and [Refined_]
   --  Global. Given an abstract state denoted by State_Id and a reference Ref
   --  to it, determine whether the reference appears in a package body that
   --  will eventually refine the state. If this is the case, record the
   --  reference for future checks (see Analyze_Refined_State_In_Decls).

   procedure Resolve_State (N : Node_Id);
   --  Handle the overloading of state names by functions. When N denotes a
   --  function, this routine finds the corresponding state and sets the entity
   --  of N to that of the state.

   procedure Rewrite_Assertion_Kind
     (N           : Node_Id;
      From_Policy : Boolean := False);
   --  If N is Pre'Class, Post'Class, Invariant'Class, or Type_Invariant'Class,
   --  then it is rewritten as an identifier with the corresponding special
   --  name _Pre, _Post, _Invariant, or _Type_Invariant. Used by pragmas Check
   --  and Check_Policy. If the names are Precondition or Postcondition, this
   --  combination is deprecated in favor of Assertion_Policy and Ada2012
   --  Aspect names. The parameter From_Policy indicates that the pragma
   --  is the old non-standard Check_Policy and not a rewritten pragma.

   procedure Set_Elab_Unit_Name (N : Node_Id; With_Item : Node_Id);
   --  Place semantic information on the argument of an Elaborate/Elaborate_All
   --  pragma. Entity name for unit and its parents is taken from item in
   --  previous with_clause that mentions the unit.

   procedure Validate_Compile_Time_Warning_Or_Error
     (N    : Node_Id;
      Eloc : Source_Ptr);
   --  Common processing for Compile_Time_Error and Compile_Time_Warning of
   --  pragma N. Called when the pragma is processed as part of its regular
   --  analysis but also called after calling the back end to validate these
   --  pragmas for size and alignment appropriateness.

   procedure Defer_Compile_Time_Warning_Error_To_BE (N : Node_Id);
   --  N is a pragma Compile_Time_Error or Compile_Warning_Error whose boolean
   --  expression is not known at compile time during the front end. This
   --  procedure makes an entry in a table. The actual checking is performed by
   --  Validate_Compile_Time_Warning_Errors, which is invoked after calling the
   --  back end.

   Dummy : Integer := 0;
   pragma Volatile (Dummy);
   --  Dummy volatile integer used in bodies of ip/rv to prevent optimization

   procedure ip;
   pragma No_Inline (ip);
   --  A dummy procedure called when pragma Inspection_Point is analyzed. This
   --  is just to help debugging the front end. If a pragma Inspection_Point
   --  is added to a source program, then breaking on ip will get you to that
   --  point in the program.

   procedure rv;
   pragma No_Inline (rv);
   --  This is a dummy function called by the processing for pragma Reviewable.
   --  It is there for assisting front end debugging. By placing a Reviewable
   --  pragma in the source program, a breakpoint on rv catches this place in
   --  the source, allowing convenient stepping to the point of interest.

   ------------------------------------------------------
   -- Table for Defer_Compile_Time_Warning_Error_To_BE --
   ------------------------------------------------------

   --  The following table collects pragmas Compile_Time_Error and Compile_
   --  Time_Warning for validation. Entries are made by calls to subprogram
   --  Defer_Compile_Time_Warning_Error_To_BE, and the call to the procedure
   --  Validate_Compile_Time_Warning_Errors does the actual error checking
   --  and posting of warning and error messages. The reason for this delayed
   --  processing is to take advantage of back-annotations of attributes size
   --  and alignment values performed by the back end.

   --  Note: the reason we store a Source_Ptr value instead of a Node_Id is
   --  that by the time Validate_Compile_Time_Warning_Errors is called, Sprint
   --  will already have modified all Sloc values if the -gnatD option is set.

   type CTWE_Entry is record
      Eloc  : Source_Ptr;
      --  Source location used in warnings and error messages

      Prag  : Node_Id;
      --  Pragma Compile_Time_Error or Compile_Time_Warning

      Scope : Node_Id;
      --  The scope which encloses the pragma
   end record;

   package Compile_Time_Warnings_Errors is new Table.Table (
     Table_Component_Type => CTWE_Entry,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 1,
     Table_Initial        => 50,
     Table_Increment      => 200,
     Table_Name           => "Compile_Time_Warnings_Errors");

   -------------------------------
   -- Adjust_External_Name_Case --
   -------------------------------

   function Adjust_External_Name_Case (N : Node_Id) return Node_Id is
      CC : Char_Code;

   begin
      --  Adjust case of literal if required

      if Opt.External_Name_Exp_Casing = As_Is then
         return N;

      else
         --  Copy existing string

         Start_String;

         --  Set proper casing

         for J in 1 .. String_Length (Strval (N)) loop
            CC := Get_String_Char (Strval (N), J);

            if Opt.External_Name_Exp_Casing = Uppercase
              and then CC >= Get_Char_Code ('a')
              and then CC <= Get_Char_Code ('z')
            then
               Store_String_Char (CC - 32);

            elsif Opt.External_Name_Exp_Casing = Lowercase
              and then CC >= Get_Char_Code ('A')
              and then CC <= Get_Char_Code ('Z')
            then
               Store_String_Char (CC + 32);

            else
               Store_String_Char (CC);
            end if;
         end loop;

         return
           Make_String_Literal (Sloc (N),
             Strval => End_String);
      end if;
   end Adjust_External_Name_Case;

   -----------------------------------------
   -- Analyze_Contract_Cases_In_Decl_Part --
   -----------------------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Contract_Cases_In_Decl_Part
     (N         : Node_Id;
      Freeze_Id : Entity_Id := Empty)
   is
      Subp_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id := Unique_Defining_Entity (Subp_Decl);

      Others_Seen : Boolean := False;
      --  This flag is set when an "others" choice is encountered. It is used
      --  to detect multiple illegal occurrences of "others".

      procedure Analyze_Contract_Case (CCase : Node_Id);
      --  Verify the legality of a single contract case

      ---------------------------
      -- Analyze_Contract_Case --
      ---------------------------

      procedure Analyze_Contract_Case (CCase : Node_Id) is
         Case_Guard  : Node_Id;
         Conseq      : Node_Id;
         Errors      : Nat;
         Extra_Guard : Node_Id;

      begin
         if Nkind (CCase) = N_Component_Association then
            Case_Guard := First (Choices (CCase));
            Conseq     := Expression (CCase);

            --  Each contract case must have exactly one case guard

            Extra_Guard := Next (Case_Guard);

            if Present (Extra_Guard) then
               Error_Msg_N
                 ("contract case must have exactly one case guard",
                  Extra_Guard);
            end if;

            --  Check placement of OTHERS if available (SPARK RM 6.1.3(1))

            if Nkind (Case_Guard) = N_Others_Choice then
               if Others_Seen then
                  Error_Msg_N
                    ("only one OTHERS choice allowed in contract cases",
                     Case_Guard);
               else
                  Others_Seen := True;
               end if;

            elsif Others_Seen then
               Error_Msg_N
                 ("OTHERS must be the last choice in contract cases", N);
            end if;

            --  Preanalyze the case guard and consequence

            if Nkind (Case_Guard) /= N_Others_Choice then
               Errors := Serious_Errors_Detected;
               Preanalyze_Assert_Expression (Case_Guard, Standard_Boolean);

               --  Emit a clarification message when the case guard contains
               --  at least one undefined reference, possibly due to contract
               --  freezing.

               if Errors /= Serious_Errors_Detected
                 and then Present (Freeze_Id)
                 and then Has_Undefined_Reference (Case_Guard)
               then
                  Contract_Freeze_Error (Spec_Id, Freeze_Id);
               end if;
            end if;

            Errors := Serious_Errors_Detected;
            Preanalyze_Assert_Expression (Conseq, Standard_Boolean);

            --  Emit a clarification message when the consequence contains
            --  at least one undefined reference, possibly due to contract
            --  freezing.

            if Errors /= Serious_Errors_Detected
              and then Present (Freeze_Id)
              and then Has_Undefined_Reference (Conseq)
            then
               Contract_Freeze_Error (Spec_Id, Freeze_Id);
            end if;

         --  The contract case is malformed

         else
            Error_Msg_N ("wrong syntax in contract case", CCase);
         end if;
      end Analyze_Contract_Case;

      --  Local variables

      CCases : constant Node_Id := Expression (Get_Argument (N, Spec_Id));

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      CCase         : Node_Id;
      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Contract_Cases_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Set the Ghost mode in effect from the pragma. Due to the delayed
      --  analysis of the pragma, the Ghost mode at point of declaration and
      --  point of analysis may not necessarily be the same. Use the mode in
      --  effect at the point of declaration.

      Set_Ghost_Mode (N);

      --  Single and multiple contract cases must appear in aggregate form. If
      --  this is not the case, then either the parser or the analysis of the
      --  pragma failed to produce an aggregate, e.g. when the contract is
      --  "null" or a "(null record)".

      pragma Assert
        (if Nkind (CCases) = N_Aggregate
         then Null_Record_Present (CCases)
           xor (Present (Component_Associations (CCases))
                  or
                Present (Expressions (CCases)))
         else Nkind (CCases) = N_Null);

      --  Only CASE_GUARD => CONSEQUENCE clauses are allowed

      if Nkind (CCases) = N_Aggregate
        and then Present (Component_Associations (CCases))
        and then No (Expressions (CCases))
      then

         --  Check that the expression is a proper aggregate (no parentheses)

         if Paren_Count (CCases) /= 0 then
            Error_Msg_F -- CODEFIX
              ("redundant parentheses", CCases);
         end if;

         --  Ensure that the formal parameters are visible when analyzing all
         --  clauses. This falls out of the general rule of aspects pertaining
         --  to subprogram declarations.

         if not In_Open_Scopes (Spec_Id) then
            Restore_Scope := True;
            Push_Scope (Spec_Id);

            if Is_Generic_Subprogram (Spec_Id) then
               Install_Generic_Formals (Spec_Id);
            else
               Install_Formals (Spec_Id);
            end if;
         end if;

         CCase := First (Component_Associations (CCases));
         while Present (CCase) loop
            Analyze_Contract_Case (CCase);
            Next (CCase);
         end loop;

         if Restore_Scope then
            End_Scope;
         end if;

         --  Currently it is not possible to inline pre/postconditions on a
         --  subprogram subject to pragma Inline_Always.

         Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);

      --  Otherwise the pragma is illegal

      else
         Error_Msg_N ("wrong syntax for contract cases", N);
      end if;

      Set_Is_Analyzed_Pragma (N);

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Contract_Cases_In_Decl_Part;

   ----------------------------------
   -- Analyze_Depends_In_Decl_Part --
   ----------------------------------

   procedure Analyze_Depends_In_Decl_Part (N : Node_Id) is
      Loc       : constant Source_Ptr := Sloc (N);
      Subp_Decl : constant Node_Id    := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id  := Unique_Defining_Entity (Subp_Decl);

      All_Inputs_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all the inputs processed so far.
      --  The list is populated with unique entities because the same input
      --  may appear in multiple input lists.

      All_Outputs_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all the outputs processed so far.
      --  The list is populated with unique entities because output items are
      --  unique in a dependence relation.

      Constits_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all constituents processed so far.
      --  It aids in detecting illegal usage of a state and a corresponding
      --  constituent in pragma [Refinde_]Depends.

      Global_Seen : Boolean := False;
      --  A flag set when pragma Global has been processed

      Null_Output_Seen : Boolean := False;
      --  A flag used to track the legality of a null output

      Result_Seen : Boolean := False;
      --  A flag set when Spec_Id'Result is processed

      States_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all states processed so far. It
      --  helps in detecting illegal usage of a state and a corresponding
      --  constituent in pragma [Refined_]Depends.

      Subp_Inputs  : Elist_Id := No_Elist;
      Subp_Outputs : Elist_Id := No_Elist;
      --  Two lists containing the full set of inputs and output of the related
      --  subprograms. Note that these lists contain both nodes and entities.

      Task_Input_Seen  : Boolean := False;
      Task_Output_Seen : Boolean := False;
      --  Flags used to track the implicit dependence of a task unit on itself

      procedure Add_Item_To_Name_Buffer (Item_Id : Entity_Id);
      --  Subsidiary routine to Check_Role and Check_Usage. Add the item kind
      --  to the name buffer. The individual kinds are as follows:
      --    E_Abstract_State           - "state"
      --    E_Constant                 - "constant"
      --    E_Generic_In_Out_Parameter - "generic parameter"
      --    E_Generic_In_Parameter     - "generic parameter"
      --    E_In_Parameter             - "parameter"
      --    E_In_Out_Parameter         - "parameter"
      --    E_Loop_Parameter           - "loop parameter"
      --    E_Out_Parameter            - "parameter"
      --    E_Protected_Type           - "current instance of protected type"
      --    E_Task_Type                - "current instance of task type"
      --    E_Variable                 - "global"

      procedure Analyze_Dependency_Clause
        (Clause  : Node_Id;
         Is_Last : Boolean);
      --  Verify the legality of a single dependency clause. Flag Is_Last
      --  denotes whether Clause is the last clause in the relation.

      procedure Check_Function_Return;
      --  Verify that Funtion'Result appears as one of the outputs
      --  (SPARK RM 6.1.5(10)).

      procedure Check_Role
        (Item     : Node_Id;
         Item_Id  : Entity_Id;
         Is_Input : Boolean;
         Self_Ref : Boolean);
      --  Ensure that an item fulfills its designated input and/or output role
      --  as specified by pragma Global (if any) or the enclosing context. If
      --  this is not the case, emit an error. Item and Item_Id denote the
      --  attributes of an item. Flag Is_Input should be set when item comes
      --  from an input list. Flag Self_Ref should be set when the item is an
      --  output and the dependency clause has operator "+".

      procedure Check_Usage
        (Subp_Items : Elist_Id;
         Used_Items : Elist_Id;
         Is_Input   : Boolean);
      --  Verify that all items from Subp_Items appear in Used_Items. Emit an
      --  error if this is not the case.

      procedure Normalize_Clause (Clause : Node_Id);
      --  Remove a self-dependency "+" from the input list of a clause

      -----------------------------
      -- Add_Item_To_Name_Buffer --
      -----------------------------

      procedure Add_Item_To_Name_Buffer (Item_Id : Entity_Id) is
      begin
         if Ekind (Item_Id) = E_Abstract_State then
            Add_Str_To_Name_Buffer ("state");

         elsif Ekind (Item_Id) = E_Constant then
            Add_Str_To_Name_Buffer ("constant");

         elsif Is_Formal_Object (Item_Id) then
            Add_Str_To_Name_Buffer ("generic parameter");

         elsif Is_Formal (Item_Id) then
            Add_Str_To_Name_Buffer ("parameter");

         elsif Ekind (Item_Id) = E_Loop_Parameter then
            Add_Str_To_Name_Buffer ("loop parameter");

         elsif Ekind (Item_Id) = E_Protected_Type
           or else Is_Single_Protected_Object (Item_Id)
         then
            Add_Str_To_Name_Buffer ("current instance of protected type");

         elsif Ekind (Item_Id) = E_Task_Type
           or else Is_Single_Task_Object (Item_Id)
         then
            Add_Str_To_Name_Buffer ("current instance of task type");

         elsif Ekind (Item_Id) = E_Variable then
            Add_Str_To_Name_Buffer ("global");

         --  The routine should not be called with non-SPARK items

         else
            raise Program_Error;
         end if;
      end Add_Item_To_Name_Buffer;

      -------------------------------
      -- Analyze_Dependency_Clause --
      -------------------------------

      procedure Analyze_Dependency_Clause
        (Clause  : Node_Id;
         Is_Last : Boolean)
      is
         procedure Analyze_Input_List (Inputs : Node_Id);
         --  Verify the legality of a single input list

         procedure Analyze_Input_Output
           (Item          : Node_Id;
            Is_Input      : Boolean;
            Self_Ref      : Boolean;
            Top_Level     : Boolean;
            Seen          : in out Elist_Id;
            Null_Seen     : in out Boolean;
            Non_Null_Seen : in out Boolean);
         --  Verify the legality of a single input or output item. Flag
         --  Is_Input should be set whenever Item is an input, False when it
         --  denotes an output. Flag Self_Ref should be set when the item is an
         --  output and the dependency clause has a "+". Flag Top_Level should
         --  be set whenever Item appears immediately within an input or output
         --  list. Seen is a collection of all abstract states, objects and
         --  formals processed so far. Flag Null_Seen denotes whether a null
         --  input or output has been encountered. Flag Non_Null_Seen denotes
         --  whether a non-null input or output has been encountered.

         ------------------------
         -- Analyze_Input_List --
         ------------------------

         procedure Analyze_Input_List (Inputs : Node_Id) is
            Inputs_Seen : Elist_Id := No_Elist;
            --  A list containing the entities of all inputs that appear in the
            --  current input list.

            Non_Null_Input_Seen : Boolean := False;
            Null_Input_Seen     : Boolean := False;
            --  Flags used to check the legality of an input list

            Input : Node_Id;

         begin
            --  Multiple inputs appear as an aggregate

            if Nkind (Inputs) = N_Aggregate then
               if Present (Component_Associations (Inputs)) then
                  SPARK_Msg_N
                    ("nested dependency relations not allowed", Inputs);

               elsif Present (Expressions (Inputs)) then
                  Input := First (Expressions (Inputs));
                  while Present (Input) loop
                     Analyze_Input_Output
                       (Item          => Input,
                        Is_Input      => True,
                        Self_Ref      => False,
                        Top_Level     => False,
                        Seen          => Inputs_Seen,
                        Null_Seen     => Null_Input_Seen,
                        Non_Null_Seen => Non_Null_Input_Seen);

                     Next (Input);
                  end loop;

               --  Syntax error, always report

               else
                  Error_Msg_N ("malformed input dependency list", Inputs);
               end if;

            --  Process a solitary input

            else
               Analyze_Input_Output
                 (Item          => Inputs,
                  Is_Input      => True,
                  Self_Ref      => False,
                  Top_Level     => False,
                  Seen          => Inputs_Seen,
                  Null_Seen     => Null_Input_Seen,
                  Non_Null_Seen => Non_Null_Input_Seen);
            end if;

            --  Detect an illegal dependency clause of the form

            --    (null =>[+] null)

            if Null_Output_Seen and then Null_Input_Seen then
               SPARK_Msg_N
                 ("null dependency clause cannot have a null input list",
                  Inputs);
            end if;
         end Analyze_Input_List;

         --------------------------
         -- Analyze_Input_Output --
         --------------------------

         procedure Analyze_Input_Output
           (Item          : Node_Id;
            Is_Input      : Boolean;
            Self_Ref      : Boolean;
            Top_Level     : Boolean;
            Seen          : in out Elist_Id;
            Null_Seen     : in out Boolean;
            Non_Null_Seen : in out Boolean)
         is
            procedure Current_Task_Instance_Seen;
            --  Set the appropriate global flag when the current instance of a
            --  task unit is encountered.

            --------------------------------
            -- Current_Task_Instance_Seen --
            --------------------------------

            procedure Current_Task_Instance_Seen is
            begin
               if Is_Input then
                  Task_Input_Seen := True;
               else
                  Task_Output_Seen := True;
               end if;
            end Current_Task_Instance_Seen;

            --  Local variables

            Is_Output : constant Boolean := not Is_Input;
            Grouped   : Node_Id;
            Item_Id   : Entity_Id;

         --  Start of processing for Analyze_Input_Output

         begin
            --  Multiple input or output items appear as an aggregate

            if Nkind (Item) = N_Aggregate then
               if not Top_Level then
                  SPARK_Msg_N ("nested grouping of items not allowed", Item);

               elsif Present (Component_Associations (Item)) then
                  SPARK_Msg_N
                    ("nested dependency relations not allowed", Item);

               --  Recursively analyze the grouped items

               elsif Present (Expressions (Item)) then
                  Grouped := First (Expressions (Item));
                  while Present (Grouped) loop
                     Analyze_Input_Output
                       (Item          => Grouped,
                        Is_Input      => Is_Input,
                        Self_Ref      => Self_Ref,
                        Top_Level     => False,
                        Seen          => Seen,
                        Null_Seen     => Null_Seen,
                        Non_Null_Seen => Non_Null_Seen);

                     Next (Grouped);
                  end loop;

               --  Syntax error, always report

               else
                  Error_Msg_N ("malformed dependency list", Item);
               end if;

            --  Process attribute 'Result in the context of a dependency clause

            elsif Is_Attribute_Result (Item) then
               Non_Null_Seen := True;

               Analyze (Item);

               --  Attribute 'Result is allowed to appear on the output side of
               --  a dependency clause (SPARK RM 6.1.5(6)).

               if Is_Input then
                  SPARK_Msg_N ("function result cannot act as input", Item);

               elsif Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null dependency items", Item);

               else
                  Result_Seen := True;
               end if;

            --  Detect multiple uses of null in a single dependency list or
            --  throughout the whole relation. Verify the placement of a null
            --  output list relative to the other clauses (SPARK RM 6.1.5(12)).

            elsif Nkind (Item) = N_Null then
               if Null_Seen then
                  SPARK_Msg_N
                    ("multiple null dependency relations not allowed", Item);

               elsif Non_Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null dependency items", Item);

               else
                  Null_Seen := True;

                  if Is_Output then
                     if not Is_Last then
                        SPARK_Msg_N
                          ("null output list must be the last clause in a "
                           & "dependency relation", Item);

                     --  Catch a useless dependence of the form:
                     --    null =>+ ...

                     elsif Self_Ref then
                        SPARK_Msg_N
                          ("useless dependence, null depends on itself", Item);
                     end if;
                  end if;
               end if;

            --  Default case

            else
               Non_Null_Seen := True;

               if Null_Seen then
                  SPARK_Msg_N ("cannot mix null and non-null items", Item);
               end if;

               Analyze       (Item);
               Resolve_State (Item);

               --  Find the entity of the item. If this is a renaming, climb
               --  the renaming chain to reach the root object. Renamings of
               --  non-entire objects do not yield an entity (Empty).

               Item_Id := Entity_Of (Item);

               if Present (Item_Id) then

                  --  Constants

                  if Ekind (Item_Id) in E_Constant | E_Loop_Parameter
                      or else

                    --  Current instances of concurrent types

                    Ekind (Item_Id) in E_Protected_Type | E_Task_Type
                      or else

                    --  Formal parameters

                    Ekind (Item_Id) in E_Generic_In_Out_Parameter
                                     | E_Generic_In_Parameter
                                     | E_In_Parameter
                                     | E_In_Out_Parameter
                                     | E_Out_Parameter
                      or else

                    --  States, variables

                    Ekind (Item_Id) in E_Abstract_State | E_Variable
                  then
                     --  A [generic] function is not allowed to have Output
                     --  items in its dependency relations. Note that "null"
                     --  and attribute 'Result are still valid items.

                     if Ekind (Spec_Id) in E_Function | E_Generic_Function
                       and then not Is_Input
                     then
                        SPARK_Msg_N
                          ("output item is not applicable to function", Item);
                     end if;

                     --  The item denotes a concurrent type. Note that single
                     --  protected/task types are not considered here because
                     --  they behave as objects in the context of pragma
                     --  [Refined_]Depends.

                     if Ekind (Item_Id) in E_Protected_Type | E_Task_Type then

                        --  This use is legal as long as the concurrent type is
                        --  the current instance of an enclosing type.

                        if Is_CCT_Instance (Item_Id, Spec_Id) then

                           --  The dependence of a task unit on itself is
                           --  implicit and may or may not be explicitly
                           --  specified (SPARK RM 6.1.4).

                           if Ekind (Item_Id) = E_Task_Type then
                              Current_Task_Instance_Seen;
                           end if;

                        --  Otherwise this is not the current instance

                        else
                           SPARK_Msg_N
                             ("invalid use of subtype mark in dependency "
                              & "relation", Item);
                        end if;

                     --  The dependency of a task unit on itself is implicit
                     --  and may or may not be explicitly specified
                     --  (SPARK RM 6.1.4).

                     elsif Is_Single_Task_Object (Item_Id)
                       and then Is_CCT_Instance (Etype (Item_Id), Spec_Id)
                     then
                        Current_Task_Instance_Seen;
                     end if;

                     --  Ensure that the item fulfills its role as input and/or
                     --  output as specified by pragma Global or the enclosing
                     --  context.

                     Check_Role (Item, Item_Id, Is_Input, Self_Ref);

                     --  Detect multiple uses of the same state, variable or
                     --  formal parameter. If this is not the case, add the
                     --  item to the list of processed relations.

                     if Contains (Seen, Item_Id) then
                        SPARK_Msg_NE
                          ("duplicate use of item &", Item, Item_Id);
                     else
                        Append_New_Elmt (Item_Id, Seen);
                     end if;

                     --  Detect illegal use of an input related to a null
                     --  output. Such input items cannot appear in other
                     --  input lists (SPARK RM 6.1.5(13)).

                     if Is_Input
                       and then Null_Output_Seen
                       and then Contains (All_Inputs_Seen, Item_Id)
                     then
                        SPARK_Msg_N
                          ("input of a null output list cannot appear in "
                           & "multiple input lists", Item);
                     end if;

                     --  Add an input or a self-referential output to the list
                     --  of all processed inputs.

                     if Is_Input or else Self_Ref then
                        Append_New_Elmt (Item_Id, All_Inputs_Seen);
                     end if;

                     --  State related checks (SPARK RM 6.1.5(3))

                     if Ekind (Item_Id) = E_Abstract_State then

                        --  Package and subprogram bodies are instantiated
                        --  individually in a separate compiler pass. Due to
                        --  this mode of instantiation, the refinement of a
                        --  state may no longer be visible when a subprogram
                        --  body contract is instantiated. Since the generic
                        --  template is legal, do not perform this check in
                        --  the instance to circumvent this oddity.

                        if In_Instance then
                           null;

                        --  An abstract state with visible refinement cannot
                        --  appear in pragma [Refined_]Depends as its place
                        --  must be taken by some of its constituents
                        --  (SPARK RM 6.1.4(7)).

                        elsif Has_Visible_Refinement (Item_Id) then
                           SPARK_Msg_NE
                             ("cannot mention state & in dependence relation",
                              Item, Item_Id);
                           SPARK_Msg_N ("\use its constituents instead", Item);
                           return;

                        --  If the reference to the abstract state appears in
                        --  an enclosing package body that will eventually
                        --  refine the state, record the reference for future
                        --  checks.

                        else
                           Record_Possible_Body_Reference
                             (State_Id => Item_Id,
                              Ref      => Item);
                        end if;

                     elsif Ekind (Item_Id) in E_Constant | E_Variable
                       and then Present (Ultimate_Overlaid_Entity (Item_Id))
                     then
                        SPARK_Msg_NE
                          ("overlaying object & cannot appear in Depends",
                           Item, Item_Id);
                        SPARK_Msg_NE
                          ("\use the overlaid object & instead",
                           Item, Ultimate_Overlaid_Entity (Item_Id));
                        return;
                     end if;

                     --  When the item renames an entire object, replace the
                     --  item with a reference to the object.

                     if Entity (Item) /= Item_Id then
                        Rewrite (Item,
                          New_Occurrence_Of (Item_Id, Sloc (Item)));
                        Analyze (Item);
                     end if;

                     --  Add the entity of the current item to the list of
                     --  processed items.

                     if Ekind (Item_Id) = E_Abstract_State then
                        Append_New_Elmt (Item_Id, States_Seen);

                     --  The variable may eventually become a constituent of a
                     --  single protected/task type. Record the reference now
                     --  and verify its legality when analyzing the contract of
                     --  the variable (SPARK RM 9.3).

                     elsif Ekind (Item_Id) = E_Variable then
                        Record_Possible_Part_Of_Reference
                          (Var_Id => Item_Id,
                           Ref    => Item);
                     end if;

                     if Ekind (Item_Id) in E_Abstract_State
                                         | E_Constant
                                         | E_Variable
                       and then Present (Encapsulating_State (Item_Id))
                     then
                        Append_New_Elmt (Item_Id, Constits_Seen);
                     end if;

                  --  All other input/output items are illegal
                  --  (SPARK RM 6.1.5(1)).

                  else
                     SPARK_Msg_N
                       ("item must denote parameter, variable, state or "
                        & "current instance of concurrent type", Item);
                  end if;

               --  All other input/output items are illegal
               --  (SPARK RM 6.1.5(1)). This is a syntax error, always report.

               else
                  Error_Msg_N
                    ("item must denote parameter, variable, state or current "
                     & "instance of concurrent type", Item);
               end if;
            end if;
         end Analyze_Input_Output;

         --  Local variables

         Inputs   : Node_Id;
         Output   : Node_Id;
         Self_Ref : Boolean;

         Non_Null_Output_Seen : Boolean := False;
         --  Flag used to check the legality of an output list

      --  Start of processing for Analyze_Dependency_Clause

      begin
         Inputs   := Expression (Clause);
         Self_Ref := False;

         --  An input list with a self-dependency appears as operator "+" where
         --  the actuals inputs are the right operand.

         if Nkind (Inputs) = N_Op_Plus then
            Inputs   := Right_Opnd (Inputs);
            Self_Ref := True;
         end if;

         --  Process the output_list of a dependency_clause

         Output := First (Choices (Clause));
         while Present (Output) loop
            Analyze_Input_Output
              (Item          => Output,
               Is_Input      => False,
               Self_Ref      => Self_Ref,
               Top_Level     => True,
               Seen          => All_Outputs_Seen,
               Null_Seen     => Null_Output_Seen,
               Non_Null_Seen => Non_Null_Output_Seen);

            Next (Output);
         end loop;

         --  Process the input_list of a dependency_clause

         Analyze_Input_List (Inputs);
      end Analyze_Dependency_Clause;

      ---------------------------
      -- Check_Function_Return --
      ---------------------------

      procedure Check_Function_Return is
      begin
         if Ekind (Spec_Id) in E_Function | E_Generic_Function
           and then not Result_Seen
         then
            SPARK_Msg_NE
              ("result of & must appear in exactly one output list",
               N, Spec_Id);
         end if;
      end Check_Function_Return;

      ----------------
      -- Check_Role --
      ----------------

      procedure Check_Role
        (Item     : Node_Id;
         Item_Id  : Entity_Id;
         Is_Input : Boolean;
         Self_Ref : Boolean)
      is
         procedure Find_Role
           (Item_Is_Input  : out Boolean;
            Item_Is_Output : out Boolean);
         --  Find the input/output role of Item_Id. Flags Item_Is_Input and
         --  Item_Is_Output are set depending on the role.

         procedure Role_Error
           (Item_Is_Input  : Boolean;
            Item_Is_Output : Boolean);
         --  Emit an error message concerning the incorrect use of Item in
         --  pragma [Refined_]Depends. Flags Item_Is_Input and Item_Is_Output
         --  denote whether the item is an input and/or an output.

         ---------------
         -- Find_Role --
         ---------------

         procedure Find_Role
           (Item_Is_Input  : out Boolean;
            Item_Is_Output : out Boolean)
         is
            --  A constant or an IN parameter of a procedure or a protected
            --  entry, if it is of an access-to-variable type, should be
            --  handled like a variable, as the underlying memory pointed-to
            --  can be modified. Use Adjusted_Kind to do this adjustment.

            Adjusted_Kind : Entity_Kind := Ekind (Item_Id);

         begin
            if (Ekind (Item_Id) in E_Constant | E_Generic_In_Parameter
                  or else
                  (Ekind (Item_Id) = E_In_Parameter
                     and then Ekind (Scope (Item_Id))
                                not in E_Function | E_Generic_Function))
              and then Is_Access_Variable (Etype (Item_Id))
              and then Ekind (Spec_Id) not in E_Function
                                            | E_Generic_Function
            then
               Adjusted_Kind := E_Variable;
            end if;

            case Adjusted_Kind is

               --  Abstract states

               when E_Abstract_State =>

                  --  When pragma Global is present it determines the mode of
                  --  the abstract state.

                  if Global_Seen then
                     Item_Is_Input  := Appears_In (Subp_Inputs, Item_Id);
                     Item_Is_Output := Appears_In (Subp_Outputs, Item_Id);

                  --  Otherwise the state has a default IN OUT mode, because it
                  --  behaves as a variable.

                  else
                     Item_Is_Input  := True;
                     Item_Is_Output := True;
                  end if;

               --  Constants and IN parameters

               when E_Constant
                  | E_Generic_In_Parameter
                  | E_In_Parameter
                  | E_Loop_Parameter
               =>
                  --  When pragma Global is present it determines the mode
                  --  of constant objects as inputs (and such objects cannot
                  --  appear as outputs in the Global contract).

                  if Global_Seen then
                     Item_Is_Input := Appears_In (Subp_Inputs, Item_Id);
                  else
                     Item_Is_Input := True;
                  end if;

                  Item_Is_Output := False;

               --  Variables and IN OUT parameters, as well as constants and
               --  IN parameters of access type which are handled like
               --  variables.

               when E_Generic_In_Out_Parameter
                  | E_In_Out_Parameter
                  | E_Variable
               =>
                  --  When pragma Global is present it determines the mode of
                  --  the object.

                  if Global_Seen then

                     --  A variable has mode IN when its type is unconstrained
                     --  or tagged because array bounds, discriminants or tags
                     --  can be read.

                     Item_Is_Input :=
                       Appears_In (Subp_Inputs, Item_Id)
                         or else Is_Unconstrained_Or_Tagged_Item (Item_Id);

                     Item_Is_Output := Appears_In (Subp_Outputs, Item_Id);

                  --  Otherwise the variable has a default IN OUT mode

                  else
                     Item_Is_Input  := True;
                     Item_Is_Output := True;
                  end if;

               when E_Out_Parameter =>

                  --  An OUT parameter of the related subprogram; it cannot
                  --  appear in Global.

                  if Scope (Item_Id) = Spec_Id then

                     --  The parameter has mode IN if its type is unconstrained
                     --  or tagged because array bounds, discriminants or tags
                     --  can be read.

                     Item_Is_Input :=
                       Is_Unconstrained_Or_Tagged_Item (Item_Id);

                     Item_Is_Output := True;

                  --  An OUT parameter of an enclosing subprogram; it can
                  --  appear in Global and behaves as a read-write variable.

                  else
                     --  When pragma Global is present it determines the mode
                     --  of the object.

                     if Global_Seen then

                        --  A variable has mode IN when its type is
                        --  unconstrained or tagged because array
                        --  bounds, discriminants or tags can be read.

                        Item_Is_Input :=
                          Appears_In (Subp_Inputs, Item_Id)
                            or else Is_Unconstrained_Or_Tagged_Item (Item_Id);

                        Item_Is_Output := Appears_In (Subp_Outputs, Item_Id);

                     --  Otherwise the variable has a default IN OUT mode

                     else
                        Item_Is_Input  := True;
                        Item_Is_Output := True;
                     end if;
                  end if;

               --  Protected types

               when E_Protected_Type =>
                  if Global_Seen then

                     --  A variable has mode IN when its type is unconstrained
                     --  or tagged because array bounds, discriminants or tags
                     --  can be read.

                     Item_Is_Input :=
                       Appears_In (Subp_Inputs, Item_Id)
                         or else Is_Unconstrained_Or_Tagged_Item (Item_Id);

                     Item_Is_Output := Appears_In (Subp_Outputs, Item_Id);

                  else
                     --  A protected type acts as a formal parameter of mode IN
                     --  when it applies to a protected function.

                     if Ekind (Spec_Id) = E_Function then
                        Item_Is_Input  := True;
                        Item_Is_Output := False;

                     --  Otherwise the protected type acts as a formal of mode
                     --  IN OUT.

                     else
                        Item_Is_Input  := True;
                        Item_Is_Output := True;
                     end if;
                  end if;

               --  Task types

               when E_Task_Type =>

                  --  When pragma Global is present it determines the mode of
                  --  the object.

                  if Global_Seen then
                     Item_Is_Input :=
                       Appears_In (Subp_Inputs, Item_Id)
                         or else Is_Unconstrained_Or_Tagged_Item (Item_Id);

                     Item_Is_Output := Appears_In (Subp_Outputs, Item_Id);

                  --  Otherwise task types act as IN OUT parameters

                  else
                     Item_Is_Input  := True;
                     Item_Is_Output := True;
                  end if;

               when others =>
                  raise Program_Error;
            end case;
         end Find_Role;

         ----------------
         -- Role_Error --
         ----------------

         procedure Role_Error
           (Item_Is_Input  : Boolean;
            Item_Is_Output : Boolean)
         is
         begin
            Name_Len := 0;

            --  When the item is not part of the input and the output set of
            --  the related subprogram, then it appears as extra in pragma
            --  [Refined_]Depends.

            if not Item_Is_Input and then not Item_Is_Output then
               Add_Item_To_Name_Buffer (Item_Id);
               Add_Str_To_Name_Buffer
                 (" & cannot appear in dependence relation");

               SPARK_Msg_NE (To_String (Global_Name_Buffer), Item, Item_Id);

               Error_Msg_Name_1 := Chars (Spec_Id);
               SPARK_Msg_NE
                 (Fix_Msg (Spec_Id, "\& is not part of the input or output "
                  & "set of subprogram %"), Item, Item_Id);

            --  The mode of the item and its role in pragma [Refined_]Depends
            --  are in conflict. Construct a detailed message explaining the
            --  illegality (SPARK RM 6.1.5(5-6)).

            else
               if Item_Is_Input then
                  Add_Str_To_Name_Buffer ("read-only");
               else
                  Add_Str_To_Name_Buffer ("write-only");
               end if;

               Add_Char_To_Name_Buffer (' ');
               Add_Item_To_Name_Buffer (Item_Id);
               Add_Str_To_Name_Buffer  (" & cannot appear as ");

               if Item_Is_Input then
                  Add_Str_To_Name_Buffer ("output");
               else
                  Add_Str_To_Name_Buffer ("input");
               end if;

               Add_Str_To_Name_Buffer (" in dependence relation");

               SPARK_Msg_NE (To_String (Global_Name_Buffer), Item, Item_Id);
            end if;
         end Role_Error;

         --  Local variables

         Item_Is_Input  : Boolean;
         Item_Is_Output : Boolean;

      --  Start of processing for Check_Role

      begin
         Find_Role (Item_Is_Input, Item_Is_Output);

         --  Input item

         if Is_Input then
            if not Item_Is_Input then
               Role_Error (Item_Is_Input, Item_Is_Output);
            end if;

         --  Self-referential item

         elsif Self_Ref then
            if not Item_Is_Input or else not Item_Is_Output then
               Role_Error (Item_Is_Input, Item_Is_Output);
            end if;

         --  Output item

         elsif not Item_Is_Output then
            Role_Error (Item_Is_Input, Item_Is_Output);
         end if;
      end Check_Role;

      -----------------
      -- Check_Usage --
      -----------------

      procedure Check_Usage
        (Subp_Items : Elist_Id;
         Used_Items : Elist_Id;
         Is_Input   : Boolean)
      is
         procedure Usage_Error (Item_Id : Entity_Id);
         --  Emit an error concerning the illegal usage of an item

         -----------------
         -- Usage_Error --
         -----------------

         procedure Usage_Error (Item_Id : Entity_Id) is
         begin
            --  Input case

            if Is_Input then

               --  Unconstrained and tagged items are not part of the explicit
               --  input set of the related subprogram, they do not have to be
               --  present in a dependence relation and should not be flagged
               --  (SPARK RM 6.1.5(5)).

               if not Is_Unconstrained_Or_Tagged_Item (Item_Id) then
                  Name_Len := 0;

                  Add_Item_To_Name_Buffer (Item_Id);
                  Add_Str_To_Name_Buffer
                    (" & is missing from input dependence list");

                  SPARK_Msg_NE (To_String (Global_Name_Buffer), N, Item_Id);
                  SPARK_Msg_NE
                    ("\add `null ='> &` dependency to ignore this input",
                     N, Item_Id);
               end if;

            --  Output case (SPARK RM 6.1.5(10))

            else
               Name_Len := 0;

               Add_Item_To_Name_Buffer (Item_Id);
               Add_Str_To_Name_Buffer
                 (" & is missing from output dependence list");

               SPARK_Msg_NE (To_String (Global_Name_Buffer), N, Item_Id);
            end if;
         end Usage_Error;

         --  Local variables

         Elmt    : Elmt_Id;
         Item    : Node_Id;
         Item_Id : Entity_Id;

      --  Start of processing for Check_Usage

      begin
         if No (Subp_Items) then
            return;
         end if;

         --  Each input or output of the subprogram must appear in a dependency
         --  relation.

         Elmt := First_Elmt (Subp_Items);
         while Present (Elmt) loop
            Item := Node (Elmt);

            if Nkind (Item) = N_Defining_Identifier then
               Item_Id := Item;
            else
               Item_Id := Entity_Of (Item);
            end if;

            --  The item does not appear in a dependency

            if Present (Item_Id)
              and then not Contains (Used_Items, Item_Id)
            then
               if Is_Formal (Item_Id) then
                  Usage_Error (Item_Id);

               --  The current instance of a protected type behaves as a formal
               --  parameter (SPARK RM 6.1.4).

               elsif Ekind (Item_Id) = E_Protected_Type
                 or else Is_Single_Protected_Object (Item_Id)
               then
                  Usage_Error (Item_Id);

               --  The current instance of a task type behaves as a formal
               --  parameter (SPARK RM 6.1.4).

               elsif Ekind (Item_Id) = E_Task_Type
                 or else Is_Single_Task_Object (Item_Id)
               then
                  --  The dependence of a task unit on itself is implicit and
                  --  may or may not be explicitly specified (SPARK RM 6.1.4).
                  --  Emit an error if only one input/output is present.

                  if Task_Input_Seen /= Task_Output_Seen then
                     Usage_Error (Item_Id);
                  end if;

               --  States and global objects are not used properly only when
               --  the subprogram is subject to pragma Global.

               elsif Global_Seen then
                  Usage_Error (Item_Id);
               end if;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end Check_Usage;

      ----------------------
      -- Normalize_Clause --
      ----------------------

      procedure Normalize_Clause (Clause : Node_Id) is
         procedure Create_Or_Modify_Clause
           (Output   : Node_Id;
            Outputs  : Node_Id;
            Inputs   : Node_Id;
            After    : Node_Id;
            In_Place : Boolean;
            Multiple : Boolean);
         --  Create a brand new clause to represent the self-reference or
         --  modify the input and/or output lists of an existing clause. Output
         --  denotes a self-referencial output. Outputs is the output list of a
         --  clause. Inputs is the input list of a clause. After denotes the
         --  clause after which the new clause is to be inserted. Flag In_Place
         --  should be set when normalizing the last output of an output list.
         --  Flag Multiple should be set when Output comes from a list with
         --  multiple items.

         -----------------------------
         -- Create_Or_Modify_Clause --
         -----------------------------

         procedure Create_Or_Modify_Clause
           (Output   : Node_Id;
            Outputs  : Node_Id;
            Inputs   : Node_Id;
            After    : Node_Id;
            In_Place : Boolean;
            Multiple : Boolean)
         is
            procedure Propagate_Output
              (Output : Node_Id;
               Inputs : Node_Id);
            --  Handle the various cases of output propagation to the input
            --  list. Output denotes a self-referencial output item. Inputs
            --  is the input list of a clause.

            ----------------------
            -- Propagate_Output --
            ----------------------

            procedure Propagate_Output
              (Output : Node_Id;
               Inputs : Node_Id)
            is
               function In_Input_List
                 (Item   : Entity_Id;
                  Inputs : List_Id) return Boolean;
               --  Determine whether a particulat item appears in the input
               --  list of a clause.

               -------------------
               -- In_Input_List --
               -------------------

               function In_Input_List
                 (Item   : Entity_Id;
                  Inputs : List_Id) return Boolean
               is
                  Elmt : Node_Id;

               begin
                  Elmt := First (Inputs);
                  while Present (Elmt) loop
                     if Entity_Of (Elmt) = Item then
                        return True;
                     end if;

                     Next (Elmt);
                  end loop;

                  return False;
               end In_Input_List;

               --  Local variables

               Output_Id : constant Entity_Id := Entity_Of (Output);
               Grouped   : List_Id;

            --  Start of processing for Propagate_Output

            begin
               --  The clause is of the form:

               --    (Output =>+ null)

               --  Remove null input and replace it with a copy of the output:

               --    (Output => Output)

               if Nkind (Inputs) = N_Null then
                  Rewrite (Inputs, New_Copy_Tree (Output));

               --  The clause is of the form:

               --    (Output =>+ (Input1, ..., InputN))

               --  Determine whether the output is not already mentioned in the
               --  input list and if not, add it to the list of inputs:

               --    (Output => (Output, Input1, ..., InputN))

               elsif Nkind (Inputs) = N_Aggregate then
                  Grouped := Expressions (Inputs);

                  if not In_Input_List
                           (Item   => Output_Id,
                            Inputs => Grouped)
                  then
                     Prepend_To (Grouped, New_Copy_Tree (Output));
                  end if;

               --  The clause is of the form:

               --    (Output =>+ Input)

               --  If the input does not mention the output, group the two
               --  together:

               --    (Output => (Output, Input))

               elsif Entity_Of (Inputs) /= Output_Id then
                  Rewrite (Inputs,
                    Make_Aggregate (Loc,
                      Expressions => New_List (
                        New_Copy_Tree (Output),
                        New_Copy_Tree (Inputs))));
               end if;
            end Propagate_Output;

            --  Local variables

            Loc        : constant Source_Ptr := Sloc (Clause);
            New_Clause : Node_Id;

         --  Start of processing for Create_Or_Modify_Clause

         begin
            --  A null output depending on itself does not require any
            --  normalization.

            if Nkind (Output) = N_Null then
               return;

            --  A function result cannot depend on itself because it cannot
            --  appear in the input list of a relation (SPARK RM 6.1.5(10)).

            elsif Is_Attribute_Result (Output) then
               SPARK_Msg_N ("function result cannot depend on itself", Output);
               return;
            end if;

            --  When performing the transformation in place, simply add the
            --  output to the list of inputs (if not already there). This
            --  case arises when dealing with the last output of an output
            --  list. Perform the normalization in place to avoid generating
            --  a malformed tree.

            if In_Place then
               Propagate_Output (Output, Inputs);

               --  A list with multiple outputs is slowly trimmed until only
               --  one element remains. When this happens, replace aggregate
               --  with the element itself.

               if Multiple then
                  Remove  (Output);
                  Rewrite (Outputs, Output);
               end if;

            --  Default case

            else
               --  Unchain the output from its output list as it will appear in
               --  a new clause. Note that we cannot simply rewrite the output
               --  as null because this will violate the semantics of pragma
               --  Depends.

               Remove (Output);

               --  Generate a new clause of the form:
               --    (Output => Inputs)

               New_Clause :=
                 Make_Component_Association (Loc,
                   Choices    => New_List (Output),
                   Expression => New_Copy_Tree (Inputs));

               --  The new clause contains replicated content that has already
               --  been analyzed. There is not need to reanalyze or renormalize
               --  it again.

               Set_Analyzed (New_Clause);

               Propagate_Output
                 (Output => First (Choices (New_Clause)),
                  Inputs => Expression (New_Clause));

               Insert_After (After, New_Clause);
            end if;
         end Create_Or_Modify_Clause;

         --  Local variables

         Outputs     : constant Node_Id := First (Choices (Clause));
         Inputs      : Node_Id;
         Last_Output : Node_Id;
         Next_Output : Node_Id;
         Output      : Node_Id;

      --  Start of processing for Normalize_Clause

      begin
         --  A self-dependency appears as operator "+". Remove the "+" from the
         --  tree by moving the real inputs to their proper place.

         if Nkind (Expression (Clause)) = N_Op_Plus then
            Rewrite (Expression (Clause), Right_Opnd (Expression (Clause)));
            Inputs := Expression (Clause);

            --  Multiple outputs appear as an aggregate

            if Nkind (Outputs) = N_Aggregate then
               Last_Output := Last (Expressions (Outputs));

               Output := First (Expressions (Outputs));
               while Present (Output) loop

                  --  Normalization may remove an output from its list,
                  --  preserve the subsequent output now.

                  Next_Output := Next (Output);

                  Create_Or_Modify_Clause
                    (Output   => Output,
                     Outputs  => Outputs,
                     Inputs   => Inputs,
                     After    => Clause,
                     In_Place => Output = Last_Output,
                     Multiple => True);

                  Output := Next_Output;
               end loop;

            --  Solitary output

            else
               Create_Or_Modify_Clause
                 (Output   => Outputs,
                  Outputs  => Empty,
                  Inputs   => Inputs,
                  After    => Empty,
                  In_Place => True,
                  Multiple => False);
            end if;
         end if;
      end Normalize_Clause;

      --  Local variables

      Deps    : constant Node_Id   := Expression (Get_Argument (N, Spec_Id));
      Subp_Id : constant Entity_Id := Defining_Entity (Subp_Decl);

      Clause        : Node_Id;
      Errors        : Nat;
      Last_Clause   : Node_Id;
      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Depends_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Empty dependency list

      if Nkind (Deps) = N_Null then

         --  Gather all states, objects and formal parameters that the
         --  subprogram may depend on. These items are obtained from the
         --  parameter profile or pragma [Refined_]Global (if available).

         Collect_Subprogram_Inputs_Outputs
           (Subp_Id      => Subp_Id,
            Subp_Inputs  => Subp_Inputs,
            Subp_Outputs => Subp_Outputs,
            Global_Seen  => Global_Seen);

         --  Verify that every input or output of the subprogram appear in a
         --  dependency.

         Check_Usage (Subp_Inputs, All_Inputs_Seen, True);
         Check_Usage (Subp_Outputs, All_Outputs_Seen, False);
         Check_Function_Return;

      --  Dependency clauses appear as component associations of an aggregate

      elsif Nkind (Deps) = N_Aggregate then

         --  Do not attempt to perform analysis of a syntactically illegal
         --  clause as this will lead to misleading errors.

         if Has_Extra_Parentheses (Deps) then
            goto Leave;
         end if;

         if Present (Component_Associations (Deps)) then
            Last_Clause := Last (Component_Associations (Deps));

            --  Gather all states, objects and formal parameters that the
            --  subprogram may depend on. These items are obtained from the
            --  parameter profile or pragma [Refined_]Global (if available).

            Collect_Subprogram_Inputs_Outputs
              (Subp_Id      => Subp_Id,
               Subp_Inputs  => Subp_Inputs,
               Subp_Outputs => Subp_Outputs,
               Global_Seen  => Global_Seen);

            --  When pragma [Refined_]Depends appears on a single concurrent
            --  type, it is relocated to the anonymous object.

            if Is_Single_Concurrent_Object (Spec_Id) then
               null;

            --  Ensure that the formal parameters are visible when analyzing
            --  all clauses. This falls out of the general rule of aspects
            --  pertaining to subprogram declarations.

            elsif not In_Open_Scopes (Spec_Id) then
               Restore_Scope := True;
               Push_Scope (Spec_Id);

               if Ekind (Spec_Id) = E_Task_Type then

                  --  Task discriminants cannot appear in the [Refined_]Depends
                  --  contract, but must be present for the analysis so that we
                  --  can reject them with an informative error message.

                  if Has_Discriminants (Spec_Id) then
                     Install_Discriminants (Spec_Id);
                  end if;

               elsif Is_Generic_Subprogram (Spec_Id) then
                  Install_Generic_Formals (Spec_Id);

               else
                  Install_Formals (Spec_Id);
               end if;
            end if;

            Clause := First (Component_Associations (Deps));
            while Present (Clause) loop
               Errors := Serious_Errors_Detected;

               --  The normalization mechanism may create extra clauses that
               --  contain replicated input and output names. There is no need
               --  to reanalyze them.

               if not Analyzed (Clause) then
                  Set_Analyzed (Clause);

                  Analyze_Dependency_Clause
                    (Clause  => Clause,
                     Is_Last => Clause = Last_Clause);
               end if;

               --  Do not normalize a clause if errors were detected (count
               --  of Serious_Errors has increased) because the inputs and/or
               --  outputs may denote illegal items.

               if Serious_Errors_Detected = Errors then
                  Normalize_Clause (Clause);
               end if;

               Next (Clause);
            end loop;

            if Restore_Scope then
               End_Scope;
            end if;

            --  Verify that every input or output of the subprogram appear in a
            --  dependency.

            Check_Usage (Subp_Inputs, All_Inputs_Seen, True);
            Check_Usage (Subp_Outputs, All_Outputs_Seen, False);
            Check_Function_Return;

         --  The dependency list is malformed. This is a syntax error, always
         --  report.

         else
            Error_Msg_N ("malformed dependency relation", Deps);
            goto Leave;
         end if;

      --  The top level dependency relation is malformed. This is a syntax
      --  error, always report.

      else
         Error_Msg_N ("malformed dependency relation", Deps);
         goto Leave;
      end if;

      --  Ensure that a state and a corresponding constituent do not appear
      --  together in pragma [Refined_]Depends.

      Check_State_And_Constituent_Use
        (States   => States_Seen,
         Constits => Constits_Seen,
         Context  => N);

      <<Leave>>
      Set_Is_Analyzed_Pragma (N);
   end Analyze_Depends_In_Decl_Part;

   --------------------------------------------
   -- Analyze_External_Property_In_Decl_Part --
   --------------------------------------------

   procedure Analyze_External_Property_In_Decl_Part
     (N        : Node_Id;
      Expr_Val : out Boolean)
   is
      Prag_Id  : constant Pragma_Id := Get_Pragma_Id (Pragma_Name (N));
      Arg1     : constant Node_Id   :=
                   First (Pragma_Argument_Associations (N));
      Obj_Decl : constant Node_Id   := Find_Related_Context (N);
      Obj_Id   : constant Entity_Id := Defining_Entity (Obj_Decl);
      Expr     : Node_Id;

   begin
      --  Do not analyze the pragma multiple times, but set the output
      --  parameter to the argument specified by the pragma.

      if Is_Analyzed_Pragma (N) then
         goto Leave;
      end if;

      Error_Msg_Name_1 := Pragma_Name (N);

      --  An external property pragma must apply to an effectively volatile
      --  object other than a formal subprogram parameter (SPARK RM 7.1.3(2)).
      --  The check is performed at the end of the declarative region due to a
      --  possible out-of-order arrangement of pragmas:

      --    Obj : ...;
      --    pragma Async_Readers (Obj);
      --    pragma Volatile (Obj);

      if Prag_Id /= Pragma_No_Caching
        and then not Is_Effectively_Volatile (Obj_Id)
      then
         if Ekind (Obj_Id) = E_Variable
           and then No_Caching_Enabled (Obj_Id)
         then
            SPARK_Msg_N
              ("illegal combination of external property % and property "
               & """No_Caching"" (SPARK RM 7.1.2(6))", N);
         else
            SPARK_Msg_N
              ("external property % must apply to a volatile type or object",
               N);
         end if;

      --  Pragma No_Caching should only apply to volatile variables of
      --  a non-effectively volatile type (SPARK RM 7.1.2).

      elsif Prag_Id = Pragma_No_Caching then
         if Is_Effectively_Volatile (Etype (Obj_Id)) then
            SPARK_Msg_N ("property % must not apply to an object of "
                         & "an effectively volatile type", N);
         elsif not Is_Volatile (Obj_Id) then
            SPARK_Msg_N ("property % must apply to a volatile object", N);
         end if;
      end if;

      Set_Is_Analyzed_Pragma (N);

      <<Leave>>

      --  Ensure that the Boolean expression (if present) is static. A missing
      --  argument defaults the value to True (SPARK RM 7.1.2(5)).

      Expr_Val := True;

      if Present (Arg1) then
         Expr := Get_Pragma_Arg (Arg1);

         if Is_OK_Static_Expression (Expr) then
            Expr_Val := Is_True (Expr_Value (Expr));
         end if;
      end if;

   end Analyze_External_Property_In_Decl_Part;

   ---------------------------------
   -- Analyze_Global_In_Decl_Part --
   ---------------------------------

   procedure Analyze_Global_In_Decl_Part (N : Node_Id) is
      Subp_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id := Unique_Defining_Entity (Subp_Decl);
      Subp_Id   : constant Entity_Id := Defining_Entity (Subp_Decl);

      Constits_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all constituents processed so far.
      --  It aids in detecting illegal usage of a state and a corresponding
      --  constituent in pragma [Refinde_]Global.

      Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all the items processed so far. It
      --  plays a role in detecting distinct entities.

      States_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all states processed so far. It
      --  helps in detecting illegal usage of a state and a corresponding
      --  constituent in pragma [Refined_]Global.

      In_Out_Seen : Boolean := False;
      Input_Seen  : Boolean := False;
      Output_Seen : Boolean := False;
      Proof_Seen  : Boolean := False;
      --  Flags used to verify the consistency of modes

      procedure Analyze_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input);
      --  Verify the legality of a single global list declaration. Global_Mode
      --  denotes the current mode in effect.

      -------------------------
      -- Analyze_Global_List --
      -------------------------

      procedure Analyze_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input)
      is
         procedure Analyze_Global_Item
           (Item        : Node_Id;
            Global_Mode : Name_Id);
         --  Verify the legality of a single global item declaration denoted by
         --  Item. Global_Mode denotes the current mode in effect.

         procedure Check_Duplicate_Mode
           (Mode   : Node_Id;
            Status : in out Boolean);
         --  Flag Status denotes whether a particular mode has been seen while
         --  processing a global list. This routine verifies that Mode is not a
         --  duplicate mode and sets the flag Status (SPARK RM 6.1.4(9)).

         procedure Check_Mode_Restriction_In_Enclosing_Context
           (Item    : Node_Id;
            Item_Id : Entity_Id);
         --  Verify that an item of mode In_Out or Output does not appear as
         --  an input in the Global aspect of an enclosing subprogram or task
         --  unit. If this is the case, emit an error. Item and Item_Id are
         --  respectively the item and its entity.

         procedure Check_Mode_Restriction_In_Function (Mode : Node_Id);
         --  Mode denotes either In_Out or Output. Depending on the kind of the
         --  related subprogram, emit an error if those two modes apply to a
         --  function (SPARK RM 6.1.4(10)).

         -------------------------
         -- Analyze_Global_Item --
         -------------------------

         procedure Analyze_Global_Item
           (Item        : Node_Id;
            Global_Mode : Name_Id)
         is
            Item_Id : Entity_Id;

         begin
            --  Detect one of the following cases

            --    with Global => (null, Name)
            --    with Global => (Name_1, null, Name_2)
            --    with Global => (Name, null)

            if Nkind (Item) = N_Null then
               SPARK_Msg_N ("cannot mix null and non-null global items", Item);
               return;
            end if;

            Analyze       (Item);
            Resolve_State (Item);

            --  Find the entity of the item. If this is a renaming, climb the
            --  renaming chain to reach the root object. Renamings of non-
            --  entire objects do not yield an entity (Empty).

            Item_Id := Entity_Of (Item);

            if Present (Item_Id) then

               --  A global item may denote a formal parameter of an enclosing
               --  subprogram (SPARK RM 6.1.4(6)). Do this check first to
               --  provide a better error diagnostic.

               if Is_Formal (Item_Id) then
                  if Scope (Item_Id) = Spec_Id then
                     SPARK_Msg_NE
                       (Fix_Msg (Spec_Id, "global item cannot reference "
                        & "parameter of subprogram &"), Item, Spec_Id);
                     return;
                  end if;

               --  A global item may denote a concurrent type as long as it is
               --  the current instance of an enclosing protected or task type
               --  (SPARK RM 6.1.4).

               elsif Ekind (Item_Id) in E_Protected_Type | E_Task_Type then
                  if Is_CCT_Instance (Item_Id, Spec_Id) then

                     --  Pragma [Refined_]Global associated with a protected
                     --  subprogram cannot mention the current instance of a
                     --  protected type because the instance behaves as a
                     --  formal parameter.

                     if Ekind (Item_Id) = E_Protected_Type then
                        if Scope (Spec_Id) = Item_Id then
                           Error_Msg_Name_1 := Chars (Item_Id);
                           SPARK_Msg_NE
                             (Fix_Msg (Spec_Id, "global item of subprogram & "
                              & "cannot reference current instance of "
                              & "protected type %"), Item, Spec_Id);
                           return;
                        end if;

                     --  Pragma [Refined_]Global associated with a task type
                     --  cannot mention the current instance of a task type
                     --  because the instance behaves as a formal parameter.

                     else pragma Assert (Ekind (Item_Id) = E_Task_Type);
                        if Spec_Id = Item_Id then
                           Error_Msg_Name_1 := Chars (Item_Id);
                           SPARK_Msg_NE
                             (Fix_Msg (Spec_Id, "global item of subprogram & "
                              & "cannot reference current instance of task "
                              & "type %"), Item, Spec_Id);
                           return;
                        end if;
                     end if;

                  --  Otherwise the global item denotes a subtype mark that is
                  --  not a current instance.

                  else
                     SPARK_Msg_N
                       ("invalid use of subtype mark in global list", Item);
                     return;
                  end if;

               --  A global item may denote the anonymous object created for a
               --  single protected/task type as long as the current instance
               --  is the same single type (SPARK RM 6.1.4).

               elsif Is_Single_Concurrent_Object (Item_Id)
                 and then Is_CCT_Instance (Etype (Item_Id), Spec_Id)
               then
                  --  Pragma [Refined_]Global associated with a protected
                  --  subprogram cannot mention the current instance of a
                  --  protected type because the instance behaves as a formal
                  --  parameter.

                  if Is_Single_Protected_Object (Item_Id) then
                     if Scope (Spec_Id) = Etype (Item_Id) then
                        Error_Msg_Name_1 := Chars (Item_Id);
                        SPARK_Msg_NE
                          (Fix_Msg (Spec_Id, "global item of subprogram & "
                           & "cannot reference current instance of protected "
                           & "type %"), Item, Spec_Id);
                        return;
                     end if;

                  --  Pragma [Refined_]Global associated with a task type
                  --  cannot mention the current instance of a task type
                  --  because the instance behaves as a formal parameter.

                  else pragma Assert (Is_Single_Task_Object (Item_Id));
                     if Spec_Id = Item_Id then
                        Error_Msg_Name_1 := Chars (Item_Id);
                        SPARK_Msg_NE
                          (Fix_Msg (Spec_Id, "global item of subprogram & "
                           & "cannot reference current instance of task "
                           & "type %"), Item, Spec_Id);
                        return;
                     end if;
                  end if;

               --  A formal object may act as a global item inside a generic

               elsif Is_Formal_Object (Item_Id) then
                  null;

               elsif Ekind (Item_Id) in E_Constant | E_Variable
                 and then Present (Ultimate_Overlaid_Entity (Item_Id))
               then
                  SPARK_Msg_NE
                    ("overlaying object & cannot appear in Global",
                     Item, Item_Id);
                  SPARK_Msg_NE
                    ("\use the overlaid object & instead",
                     Item, Ultimate_Overlaid_Entity (Item_Id));
                  return;

               --  The only legal references are those to abstract states,
               --  objects and various kinds of constants (SPARK RM 6.1.4(4)).

               elsif Ekind (Item_Id) not in E_Abstract_State
                                          | E_Constant
                                          | E_Loop_Parameter
                                          | E_Variable
               then
                  SPARK_Msg_N
                    ("global item must denote object, state or current "
                     & "instance of concurrent type", Item);

                  if Is_Named_Number (Item_Id) then
                     SPARK_Msg_NE
                       ("\named number & is not an object", Item, Item_Id);
                  end if;

                  return;
               end if;

               --  State related checks

               if Ekind (Item_Id) = E_Abstract_State then

                  --  Package and subprogram bodies are instantiated
                  --  individually in a separate compiler pass. Due to this
                  --  mode of instantiation, the refinement of a state may
                  --  no longer be visible when a subprogram body contract
                  --  is instantiated. Since the generic template is legal,
                  --  do not perform this check in the instance to circumvent
                  --  this oddity.

                  if In_Instance then
                     null;

                  --  An abstract state with visible refinement cannot appear
                  --  in pragma [Refined_]Global as its place must be taken by
                  --  some of its constituents (SPARK RM 6.1.4(7)).

                  elsif Has_Visible_Refinement (Item_Id) then
                     SPARK_Msg_NE
                       ("cannot mention state & in global refinement",
                        Item, Item_Id);
                     SPARK_Msg_N ("\use its constituents instead", Item);
                     return;

                  --  An external state which has Async_Writers or
                  --  Effective_Reads enabled cannot appear as a global item
                  --  of a nonvolatile function (SPARK RM 7.1.3(8)).

                  elsif Is_External_State (Item_Id)
                    and then (Async_Writers_Enabled (Item_Id)
                               or else Effective_Reads_Enabled (Item_Id))
                    and then Ekind (Spec_Id) in E_Function | E_Generic_Function
                    and then not Is_Volatile_Function (Spec_Id)
                  then
                     SPARK_Msg_NE
                       ("external state & cannot act as global item of "
                        & "nonvolatile function", Item, Item_Id);
                     return;

                  --  If the reference to the abstract state appears in an
                  --  enclosing package body that will eventually refine the
                  --  state, record the reference for future checks.

                  else
                     Record_Possible_Body_Reference
                       (State_Id => Item_Id,
                        Ref      => Item);
                  end if;

               --  Constant related checks

               elsif Ekind (Item_Id) = E_Constant then

                  --  Constant is a read-only item, therefore it cannot act as
                  --  an output.

                  if Global_Mode in Name_In_Out | Name_Output then

                     --  Constant of an access-to-variable type is a read-write
                     --  item in procedures, generic procedures, protected
                     --  entries and tasks.

                     if Is_Access_Variable (Etype (Item_Id))
                       and then (Ekind (Spec_Id) in E_Entry
                                                  | E_Entry_Family
                                                  | E_Procedure
                                                  | E_Generic_Procedure
                                                  | E_Task_Type
                                 or else Is_Single_Task_Object (Spec_Id))
                     then
                        null;
                     else
                        SPARK_Msg_NE
                          ("constant & cannot act as output", Item, Item_Id);
                        return;
                     end if;
                  end if;

               --  Loop parameter related checks

               elsif Ekind (Item_Id) = E_Loop_Parameter then

                  --  A loop parameter is a read-only item, therefore it cannot
                  --  act as an output.

                  if Global_Mode in Name_In_Out | Name_Output then
                     SPARK_Msg_NE
                       ("loop parameter & cannot act as output",
                        Item, Item_Id);
                     return;
                  end if;

               --  Variable related checks. These are only relevant when
               --  SPARK_Mode is on as they are not standard Ada legality
               --  rules.

               elsif SPARK_Mode = On
                 and then Ekind (Item_Id) = E_Variable
                 and then Is_Effectively_Volatile_For_Reading (Item_Id)
               then
                  --  The current instance of a protected unit is not an
                  --  effectively volatile object, unless the protected unit
                  --  is already volatile for another reason (SPARK RM 7.1.2).

                  if Is_Single_Protected_Object (Item_Id)
                    and then Is_CCT_Instance (Etype (Item_Id), Spec_Id)
                    and then not Is_Effectively_Volatile_For_Reading
                      (Item_Id, Ignore_Protected => True)
                  then
                     null;

                  --  An effectively volatile object for reading cannot appear
                  --  as a global item of a nonvolatile function (SPARK RM
                  --  7.1.3(8)).

                  elsif Ekind (Spec_Id) in E_Function | E_Generic_Function
                    and then not Is_Volatile_Function (Spec_Id)
                  then
                     Error_Msg_NE
                       ("volatile object & cannot act as global item of a "
                        & "function", Item, Item_Id);
                     return;

                  --  An effectively volatile object with external property
                  --  Effective_Reads set to True must have mode Output or
                  --  In_Out (SPARK RM 7.1.3(10)).

                  elsif Effective_Reads_Enabled (Item_Id)
                    and then Global_Mode = Name_Input
                  then
                     Error_Msg_NE
                       ("volatile object & with property Effective_Reads must "
                        & "have mode In_Out or Output", Item, Item_Id);
                     return;
                  end if;
               end if;

               --  When the item renames an entire object, replace the item
               --  with a reference to the object.

               if Entity (Item) /= Item_Id then
                  Rewrite (Item, New_Occurrence_Of (Item_Id, Sloc (Item)));
                  Analyze (Item);
               end if;

            --  Some form of illegal construct masquerading as a name
            --  (SPARK RM 6.1.4(4)).

            else
               Error_Msg_N
                 ("global item must denote object, state or current instance "
                  & "of concurrent type", Item);
               return;
            end if;

            --  Verify that an output does not appear as an input in an
            --  enclosing subprogram.

            if Global_Mode in Name_In_Out | Name_Output then
               Check_Mode_Restriction_In_Enclosing_Context (Item, Item_Id);
            end if;

            --  The same entity might be referenced through various way.
            --  Check the entity of the item rather than the item itself
            --  (SPARK RM 6.1.4(10)).

            if Contains (Seen, Item_Id) then
               SPARK_Msg_N ("duplicate global item", Item);

            --  Add the entity of the current item to the list of processed
            --  items.

            else
               Append_New_Elmt (Item_Id, Seen);

               if Ekind (Item_Id) = E_Abstract_State then
                  Append_New_Elmt (Item_Id, States_Seen);

               --  The variable may eventually become a constituent of a single
               --  protected/task type. Record the reference now and verify its
               --  legality when analyzing the contract of the variable
               --  (SPARK RM 9.3).

               elsif Ekind (Item_Id) = E_Variable then
                  Record_Possible_Part_Of_Reference
                    (Var_Id => Item_Id,
                     Ref    => Item);
               end if;

               if Ekind (Item_Id) in E_Abstract_State | E_Constant | E_Variable
                 and then Present (Encapsulating_State (Item_Id))
               then
                  Append_New_Elmt (Item_Id, Constits_Seen);
               end if;
            end if;
         end Analyze_Global_Item;

         --------------------------
         -- Check_Duplicate_Mode --
         --------------------------

         procedure Check_Duplicate_Mode
           (Mode   : Node_Id;
            Status : in out Boolean)
         is
         begin
            if Status then
               SPARK_Msg_N ("duplicate global mode", Mode);
            end if;

            Status := True;
         end Check_Duplicate_Mode;

         -------------------------------------------------
         -- Check_Mode_Restriction_In_Enclosing_Context --
         -------------------------------------------------

         procedure Check_Mode_Restriction_In_Enclosing_Context
           (Item    : Node_Id;
            Item_Id : Entity_Id)
         is
            Context : Entity_Id;
            Dummy   : Boolean;
            Inputs  : Elist_Id := No_Elist;
            Outputs : Elist_Id := No_Elist;

         begin
            --  Traverse the scope stack looking for enclosing subprograms or
            --  tasks subject to pragma [Refined_]Global.

            Context := Scope (Subp_Id);
            while Present (Context) and then Context /= Standard_Standard loop

               --  For a single task type, retrieve the corresponding object to
               --  which pragma [Refined_]Global is attached.

               if Ekind (Context) = E_Task_Type
                 and then Is_Single_Concurrent_Type (Context)
               then
                  Context := Anonymous_Object (Context);
               end if;

               if Is_Subprogram_Or_Entry (Context)
                 or else Ekind (Context) = E_Task_Type
                 or else Is_Single_Task_Object (Context)
               then
                  Collect_Subprogram_Inputs_Outputs
                    (Subp_Id      => Context,
                     Subp_Inputs  => Inputs,
                     Subp_Outputs => Outputs,
                     Global_Seen  => Dummy);

                  --  The item is classified as In_Out or Output but appears as
                  --  an Input or a formal parameter of mode IN in an enclosing
                  --  subprogram or task unit (SPARK RM 6.1.4(13)).

                  if Appears_In (Inputs, Item_Id)
                    and then not Appears_In (Outputs, Item_Id)
                  then
                     SPARK_Msg_NE
                       ("global item & cannot have mode In_Out or Output",
                        Item, Item_Id);

                     if Is_Subprogram_Or_Entry (Context) then
                        SPARK_Msg_NE
                          (Fix_Msg (Subp_Id, "\item already appears as input "
                           & "of subprogram &"), Item, Context);
                     else
                        SPARK_Msg_NE
                          (Fix_Msg (Subp_Id, "\item already appears as input "
                           & "of task &"), Item, Context);
                     end if;

                     --  Stop the traversal once an error has been detected

                     exit;
                  end if;
               end if;

               Context := Scope (Context);
            end loop;
         end Check_Mode_Restriction_In_Enclosing_Context;

         ----------------------------------------
         -- Check_Mode_Restriction_In_Function --
         ----------------------------------------

         procedure Check_Mode_Restriction_In_Function (Mode : Node_Id) is
         begin
            if Ekind (Spec_Id) in E_Function | E_Generic_Function then
               SPARK_Msg_N
                 ("global mode & is not applicable to functions", Mode);
            end if;
         end Check_Mode_Restriction_In_Function;

         --  Local variables

         Assoc : Node_Id;
         Item  : Node_Id;
         Mode  : Node_Id;

      --  Start of processing for Analyze_Global_List

      begin
         if Nkind (List) = N_Null then
            Set_Analyzed (List);

         --  Single global item declaration

         elsif Nkind (List) in N_Expanded_Name
                             | N_Identifier
                             | N_Selected_Component
         then
            Analyze_Global_Item (List, Global_Mode);

         --  Simple global list or moded global list declaration

         elsif Nkind (List) = N_Aggregate then
            Set_Analyzed (List);

            --  The declaration of a simple global list appear as a collection
            --  of expressions.

            if Present (Expressions (List)) then
               if Present (Component_Associations (List)) then
                  SPARK_Msg_N
                    ("cannot mix moded and non-moded global lists", List);
               end if;

               Item := First (Expressions (List));
               while Present (Item) loop
                  Analyze_Global_Item (Item, Global_Mode);
                  Next (Item);
               end loop;

            --  The declaration of a moded global list appears as a collection
            --  of component associations where individual choices denote
            --  modes.

            elsif Present (Component_Associations (List)) then
               if Present (Expressions (List)) then
                  SPARK_Msg_N
                    ("cannot mix moded and non-moded global lists", List);
               end if;

               Assoc := First (Component_Associations (List));
               while Present (Assoc) loop
                  Mode := First (Choices (Assoc));

                  if Nkind (Mode) = N_Identifier then
                     if Chars (Mode) = Name_In_Out then
                        Check_Duplicate_Mode (Mode, In_Out_Seen);
                        Check_Mode_Restriction_In_Function (Mode);

                     elsif Chars (Mode) = Name_Input then
                        Check_Duplicate_Mode (Mode, Input_Seen);

                     elsif Chars (Mode) = Name_Output then
                        Check_Duplicate_Mode (Mode, Output_Seen);
                        Check_Mode_Restriction_In_Function (Mode);

                     elsif Chars (Mode) = Name_Proof_In then
                        Check_Duplicate_Mode (Mode, Proof_Seen);

                     else
                        SPARK_Msg_N ("invalid mode selector", Mode);
                     end if;

                  else
                     SPARK_Msg_N ("invalid mode selector", Mode);
                  end if;

                  --  Items in a moded list appear as a collection of
                  --  expressions. Reuse the existing machinery to analyze
                  --  them.

                  Analyze_Global_List
                    (List        => Expression (Assoc),
                     Global_Mode => Chars (Mode));

                  Next (Assoc);
               end loop;

            --  Invalid tree

            else
               raise Program_Error;
            end if;

         --  Any other attempt to declare a global item is illegal. This is a
         --  syntax error, always report.

         else
            Error_Msg_N ("malformed global list", List);
         end if;
      end Analyze_Global_List;

      --  Local variables

      Items : constant Node_Id := Expression (Get_Argument (N, Spec_Id));

      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Global_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  There is nothing to be done for a null global list

      if Nkind (Items) = N_Null then
         Set_Analyzed (Items);

      --  Analyze the various forms of global lists and items. Note that some
      --  of these may be malformed in which case the analysis emits error
      --  messages.

      else
         --  When pragma [Refined_]Global appears on a single concurrent type,
         --  it is relocated to the anonymous object.

         if Is_Single_Concurrent_Object (Spec_Id) then
            null;

         --  Ensure that the formal parameters are visible when processing an
         --  item. This falls out of the general rule of aspects pertaining to
         --  subprogram declarations.

         elsif not In_Open_Scopes (Spec_Id) then
            Restore_Scope := True;
            Push_Scope (Spec_Id);

            if Ekind (Spec_Id) = E_Task_Type then

               --  Task discriminants cannot appear in the [Refined_]Global
               --  contract, but must be present for the analysis so that we
               --  can reject them with an informative error message.

               if Has_Discriminants (Spec_Id) then
                  Install_Discriminants (Spec_Id);
               end if;

            elsif Is_Generic_Subprogram (Spec_Id) then
               Install_Generic_Formals (Spec_Id);

            else
               Install_Formals (Spec_Id);
            end if;
         end if;

         Analyze_Global_List (Items);

         if Restore_Scope then
            End_Scope;
         end if;
      end if;

      --  Ensure that a state and a corresponding constituent do not appear
      --  together in pragma [Refined_]Global.

      Check_State_And_Constituent_Use
        (States   => States_Seen,
         Constits => Constits_Seen,
         Context  => N);

      Set_Is_Analyzed_Pragma (N);
   end Analyze_Global_In_Decl_Part;

   --------------------------------------------
   -- Analyze_Initial_Condition_In_Decl_Part --
   --------------------------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Initial_Condition_In_Decl_Part (N : Node_Id) is
      Pack_Decl : constant Node_Id   := Find_Related_Package_Or_Body (N);
      Pack_Id   : constant Entity_Id := Defining_Entity (Pack_Decl);
      Expr      : constant Node_Id   := Expression (Get_Argument (N, Pack_Id));

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Set the Ghost mode in effect from the pragma. Due to the delayed
      --  analysis of the pragma, the Ghost mode at point of declaration and
      --  point of analysis may not necessarily be the same. Use the mode in
      --  effect at the point of declaration.

      Set_Ghost_Mode (N);

      --  The expression is preanalyzed because it has not been moved to its
      --  final place yet. A direct analysis may generate side effects and this
      --  is not desired at this point.

      Preanalyze_Assert_Expression (Expr, Standard_Boolean);
      Set_Is_Analyzed_Pragma (N);

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Initial_Condition_In_Decl_Part;

   --------------------------------------
   -- Analyze_Initializes_In_Decl_Part --
   --------------------------------------

   procedure Analyze_Initializes_In_Decl_Part (N : Node_Id) is
      Pack_Decl : constant Node_Id   := Find_Related_Package_Or_Body (N);
      Pack_Id   : constant Entity_Id := Defining_Entity (Pack_Decl);

      Constits_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all constituents processed so far.
      --  It aids in detecting illegal usage of a state and a corresponding
      --  constituent in pragma Initializes.

      Items_Seen : Elist_Id := No_Elist;
      --  A list of all initialization items processed so far. This list is
      --  used to detect duplicate items.

      States_And_Objs : Elist_Id := No_Elist;
      --  A list of all abstract states and objects declared in the visible
      --  declarations of the related package. This list is used to detect the
      --  legality of initialization items.

      States_Seen : Elist_Id := No_Elist;
      --  A list containing the entities of all states processed so far. It
      --  helps in detecting illegal usage of a state and a corresponding
      --  constituent in pragma Initializes.

      procedure Analyze_Initialization_Item (Item : Node_Id);
      --  Verify the legality of a single initialization item

      procedure Analyze_Initialization_Item_With_Inputs (Item : Node_Id);
      --  Verify the legality of a single initialization item followed by a
      --  list of input items.

      procedure Collect_States_And_Objects (Pack_Decl : Node_Id);
      --  Inspect the visible declarations of the related package and gather
      --  the entities of all abstract states and objects in States_And_Objs.

      ---------------------------------
      -- Analyze_Initialization_Item --
      ---------------------------------

      procedure Analyze_Initialization_Item (Item : Node_Id) is
         Item_Id : Entity_Id;

      begin
         Analyze       (Item);
         Resolve_State (Item);

         if Is_Entity_Name (Item) then
            Item_Id := Entity_Of (Item);

            if Present (Item_Id)
              and then Ekind (Item_Id) in
                         E_Abstract_State | E_Constant | E_Variable
            then
               --  When the initialization item is undefined, it appears as
               --  Any_Id. Do not continue with the analysis of the item.

               if Item_Id = Any_Id then
                  null;

               elsif Ekind (Item_Id) in E_Constant | E_Variable
                 and then Present (Ultimate_Overlaid_Entity (Item_Id))
               then
                  SPARK_Msg_NE
                    ("overlaying object & cannot appear in Initializes",
                     Item, Item_Id);
                  SPARK_Msg_NE
                    ("\use the overlaid object & instead",
                     Item, Ultimate_Overlaid_Entity (Item_Id));

               --  The state or variable must be declared in the visible
               --  declarations of the package (SPARK RM 7.1.5(7)).

               elsif not Contains (States_And_Objs, Item_Id) then
                  Error_Msg_Name_1 := Chars (Pack_Id);
                  SPARK_Msg_NE
                    ("initialization item & must appear in the visible "
                     & "declarations of package %", Item, Item_Id);

               --  Detect a duplicate use of the same initialization item
               --  (SPARK RM 7.1.5(5)).

               elsif Contains (Items_Seen, Item_Id) then
                  SPARK_Msg_N ("duplicate initialization item", Item);

               --  The item is legal, add it to the list of processed states
               --  and variables.

               else
                  Append_New_Elmt (Item_Id, Items_Seen);

                  if Ekind (Item_Id) = E_Abstract_State then
                     Append_New_Elmt (Item_Id, States_Seen);
                  end if;

                  if Present (Encapsulating_State (Item_Id)) then
                     Append_New_Elmt (Item_Id, Constits_Seen);
                  end if;
               end if;

            --  The item references something that is not a state or object
            --  (SPARK RM 7.1.5(3)).

            else
               SPARK_Msg_N
                 ("initialization item must denote object or state", Item);
            end if;

         --  Some form of illegal construct masquerading as a name
         --  (SPARK RM 7.1.5(3)). This is a syntax error, always report.

         else
            Error_Msg_N
              ("initialization item must denote object or state", Item);
         end if;
      end Analyze_Initialization_Item;

      ---------------------------------------------
      -- Analyze_Initialization_Item_With_Inputs --
      ---------------------------------------------

      procedure Analyze_Initialization_Item_With_Inputs (Item : Node_Id) is
         Inputs_Seen : Elist_Id := No_Elist;
         --  A list of all inputs processed so far. This list is used to detect
         --  duplicate uses of an input.

         Non_Null_Seen : Boolean := False;
         Null_Seen     : Boolean := False;
         --  Flags used to check the legality of an input list

         procedure Analyze_Input_Item (Input : Node_Id);
         --  Verify the legality of a single input item

         ------------------------
         -- Analyze_Input_Item --
         ------------------------

         procedure Analyze_Input_Item (Input : Node_Id) is
            Input_Id : Entity_Id;

         begin
            --  Null input list

            if Nkind (Input) = N_Null then
               if Null_Seen then
                  SPARK_Msg_N
                    ("multiple null initializations not allowed", Item);

               elsif Non_Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null initialization item", Item);
               else
                  Null_Seen := True;
               end if;

            --  Input item

            else
               Non_Null_Seen := True;

               if Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null initialization item", Item);
               end if;

               Analyze       (Input);
               Resolve_State (Input);

               if Is_Entity_Name (Input) then
                  Input_Id := Entity_Of (Input);

                  if Present (Input_Id)
                    and then Ekind (Input_Id) in E_Abstract_State
                                               | E_Constant
                                               | E_Generic_In_Out_Parameter
                                               | E_Generic_In_Parameter
                                               | E_In_Parameter
                                               | E_In_Out_Parameter
                                               | E_Out_Parameter
                                               | E_Protected_Type
                                               | E_Task_Type
                                               | E_Variable
                  then
                     --  The input cannot denote states or objects declared
                     --  within the related package (SPARK RM 7.1.5(4)).

                     if Within_Scope (Input_Id, Current_Scope) then

                        --  Do not consider generic formal parameters or their
                        --  respective mappings to generic formals. Even though
                        --  the formals appear within the scope of the package,
                        --  it is allowed for an initialization item to depend
                        --  on an input item.

                        if Is_Formal_Object (Input_Id) then
                           null;

                        elsif Ekind (Input_Id) in E_Constant | E_Variable
                          and then Present (Corresponding_Generic_Association
                                     (Declaration_Node (Input_Id)))
                        then
                           null;

                        else
                           Error_Msg_Name_1 := Chars (Pack_Id);
                           SPARK_Msg_NE
                             ("input item & cannot denote a visible object or "
                              & "state of package %", Input, Input_Id);
                           return;
                        end if;
                     end if;

                     if Ekind (Input_Id) in E_Constant | E_Variable
                       and then Present (Ultimate_Overlaid_Entity (Input_Id))
                     then
                        SPARK_Msg_NE
                          ("overlaying object & cannot appear in Initializes",
                           Input, Input_Id);
                        SPARK_Msg_NE
                          ("\use the overlaid object & instead",
                           Input, Ultimate_Overlaid_Entity (Input_Id));
                        return;
                     end if;

                     --  Detect a duplicate use of the same input item
                     --  (SPARK RM 7.1.5(5)).

                     if Contains (Inputs_Seen, Input_Id) then
                        SPARK_Msg_N ("duplicate input item", Input);
                        return;
                     end if;

                     --  At this point it is known that the input is legal. Add
                     --  it to the list of processed inputs.

                     Append_New_Elmt (Input_Id, Inputs_Seen);

                     if Ekind (Input_Id) = E_Abstract_State then
                        Append_New_Elmt (Input_Id, States_Seen);
                     end if;

                     if Ekind (Input_Id) in E_Abstract_State
                                          | E_Constant
                                          | E_Variable
                       and then Present (Encapsulating_State (Input_Id))
                     then
                        Append_New_Elmt (Input_Id, Constits_Seen);
                     end if;

                  --  The input references something that is not a state or an
                  --  object (SPARK RM 7.1.5(3)).

                  else
                     SPARK_Msg_N
                       ("input item must denote object or state", Input);
                  end if;

               --  Some form of illegal construct masquerading as a name
               --  (SPARK RM 7.1.5(3)). This is a syntax error, always report.

               else
                  Error_Msg_N
                    ("input item must denote object or state", Input);
               end if;
            end if;
         end Analyze_Input_Item;

         --  Local variables

         Inputs : constant Node_Id := Expression (Item);
         Elmt   : Node_Id;
         Input  : Node_Id;

         Name_Seen : Boolean := False;
         --  A flag used to detect multiple item names

      --  Start of processing for Analyze_Initialization_Item_With_Inputs

      begin
         --  Inspect the name of an item with inputs

         Elmt := First (Choices (Item));
         while Present (Elmt) loop
            if Name_Seen then
               SPARK_Msg_N ("only one item allowed in initialization", Elmt);
            else
               Name_Seen := True;
               Analyze_Initialization_Item (Elmt);
            end if;

            Next (Elmt);
         end loop;

         --  Multiple input items appear as an aggregate

         if Nkind (Inputs) = N_Aggregate then
            if Present (Expressions (Inputs)) then
               Input := First (Expressions (Inputs));
               while Present (Input) loop
                  Analyze_Input_Item (Input);
                  Next (Input);
               end loop;
            end if;

            if Present (Component_Associations (Inputs)) then
               SPARK_Msg_N
                 ("inputs must appear in named association form", Inputs);
            end if;

         --  Single input item

         else
            Analyze_Input_Item (Inputs);
         end if;
      end Analyze_Initialization_Item_With_Inputs;

      --------------------------------
      -- Collect_States_And_Objects --
      --------------------------------

      procedure Collect_States_And_Objects (Pack_Decl : Node_Id) is
         Pack_Spec  : constant Node_Id := Specification (Pack_Decl);
         Pack_Id    : constant Entity_Id := Defining_Entity (Pack_Decl);
         Decl       : Node_Id;
         State_Elmt : Elmt_Id;

      begin
         --  Collect the abstract states defined in the package (if any)

         if Has_Non_Null_Abstract_State (Pack_Id) then
            State_Elmt := First_Elmt (Abstract_States (Pack_Id));
            while Present (State_Elmt) loop
               Append_New_Elmt (Node (State_Elmt), States_And_Objs);
               Next_Elmt (State_Elmt);
            end loop;
         end if;

         --  Collect all objects that appear in the visible declarations of the
         --  related package.

         if Present (Visible_Declarations (Pack_Spec)) then
            Decl := First (Visible_Declarations (Pack_Spec));
            while Present (Decl) loop
               if Comes_From_Source (Decl)
                 and then Nkind (Decl) in N_Object_Declaration
                                        | N_Object_Renaming_Declaration
               then
                  Append_New_Elmt (Defining_Entity (Decl), States_And_Objs);

               elsif Nkind (Decl) = N_Package_Declaration then
                  Collect_States_And_Objects (Decl);

               elsif Is_Single_Concurrent_Type_Declaration (Decl) then
                  Append_New_Elmt
                    (Anonymous_Object (Defining_Entity (Decl)),
                     States_And_Objs);
               end if;

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

      --  Local variables

      Inits : constant Node_Id := Expression (Get_Argument (N, Pack_Id));
      Init  : Node_Id;

   --  Start of processing for Analyze_Initializes_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Nothing to do when the initialization list is empty

      if Nkind (Inits) = N_Null then
         return;
      end if;

      --  Single and multiple initialization clauses appear as an aggregate. If
      --  this is not the case, then either the parser or the analysis of the
      --  pragma failed to produce an aggregate.

      pragma Assert (Nkind (Inits) = N_Aggregate);

      --  Initialize the various lists used during analysis

      Collect_States_And_Objects (Pack_Decl);

      if Present (Expressions (Inits)) then
         Init := First (Expressions (Inits));
         while Present (Init) loop
            Analyze_Initialization_Item (Init);
            Next (Init);
         end loop;
      end if;

      if Present (Component_Associations (Inits)) then
         Init := First (Component_Associations (Inits));
         while Present (Init) loop
            Analyze_Initialization_Item_With_Inputs (Init);
            Next (Init);
         end loop;
      end if;

      --  Ensure that a state and a corresponding constituent do not appear
      --  together in pragma Initializes.

      Check_State_And_Constituent_Use
        (States   => States_Seen,
         Constits => Constits_Seen,
         Context  => N);

      Set_Is_Analyzed_Pragma (N);
   end Analyze_Initializes_In_Decl_Part;

   ---------------------
   -- Analyze_Part_Of --
   ---------------------

   procedure Analyze_Part_Of
     (Indic    : Node_Id;
      Item_Id  : Entity_Id;
      Encap    : Node_Id;
      Encap_Id : out Entity_Id;
      Legal    : out Boolean)
   is
      procedure Check_Part_Of_Abstract_State;
      pragma Inline (Check_Part_Of_Abstract_State);
      --  Verify the legality of indicator Part_Of when the encapsulator is an
      --  abstract state.

      procedure Check_Part_Of_Concurrent_Type;
      pragma Inline (Check_Part_Of_Concurrent_Type);
      --  Verify the legality of indicator Part_Of when the encapsulator is a
      --  single concurrent type.

      ----------------------------------
      -- Check_Part_Of_Abstract_State --
      ----------------------------------

      procedure Check_Part_Of_Abstract_State is
         Pack_Id     : Entity_Id;
         Placement   : State_Space_Kind;
         Parent_Unit : Entity_Id;

      begin
         --  Determine where the object, package instantiation or state lives
         --  with respect to the enclosing packages or package bodies.

         Find_Placement_In_State_Space
           (Item_Id   => Item_Id,
            Placement => Placement,
            Pack_Id   => Pack_Id);

         --  The item appears in a non-package construct with a declarative
         --  part (subprogram, block, etc). As such, the item is not allowed
         --  to be a part of an encapsulating state because the item is not
         --  visible.

         if Placement = Not_In_Package then
            SPARK_Msg_N
              ("indicator Part_Of cannot appear in this context "
               & "(SPARK RM 7.2.6(5))", Indic);

            Error_Msg_Name_1 := Chars (Scope (Encap_Id));
            SPARK_Msg_NE
              ("\& is not part of the hidden state of package %",
               Indic, Item_Id);
            return;

         --  The item appears in the visible state space of some package. In
         --  general this scenario does not warrant Part_Of except when the
         --  package is a nongeneric private child unit and the encapsulating
         --  state is declared in a parent unit or a public descendant of that
         --  parent unit.

         elsif Placement = Visible_State_Space then
            if Is_Child_Unit (Pack_Id)
              and then not Is_Generic_Unit (Pack_Id)
              and then Is_Private_Descendant (Pack_Id)
            then
               --  A variable or state abstraction which is part of the visible
               --  state of a nongeneric private child unit or its public
               --  descendants must have its Part_Of indicator specified. The
               --  Part_Of indicator must denote a state declared by either the
               --  parent unit of the private unit or by a public descendant of
               --  that parent unit.

               --  Find the nearest private ancestor (which can be the current
               --  unit itself).

               Parent_Unit := Pack_Id;
               while Present (Parent_Unit) loop
                  exit when
                    Private_Present
                      (Parent (Unit_Declaration_Node (Parent_Unit)));
                  Parent_Unit := Scope (Parent_Unit);
               end loop;

               Parent_Unit := Scope (Parent_Unit);

               if not Is_Child_Or_Sibling (Pack_Id, Scope (Encap_Id)) then
                  SPARK_Msg_NE
                    ("indicator Part_Of must denote abstract state of & or of "
                     & "its public descendant (SPARK RM 7.2.6(3))",
                     Indic, Parent_Unit);
                  return;

               elsif Scope (Encap_Id) = Parent_Unit
                 or else
                   (Is_Ancestor_Package (Parent_Unit, Scope (Encap_Id))
                     and then not Is_Private_Descendant (Scope (Encap_Id)))
               then
                  null;

               else
                  SPARK_Msg_NE
                    ("indicator Part_Of must denote abstract state of & or of "
                     & "its public descendant (SPARK RM 7.2.6(3))",
                     Indic, Parent_Unit);
                  return;
               end if;

            --  Indicator Part_Of is not needed when the related package is
            --  not a nongeneric private child unit or a public descendant
            --  thereof.

            else
               SPARK_Msg_N
                 ("indicator Part_Of cannot appear in this context "
                  & "(SPARK RM 7.2.6(5))", Indic);

               Error_Msg_Name_1 := Chars (Pack_Id);
               SPARK_Msg_NE
                 ("\& is declared in the visible part of package %",
                  Indic, Item_Id);
               return;
            end if;

         --  When the item appears in the private state space of a package, the
         --  encapsulating state must be declared in the same package.

         elsif Placement = Private_State_Space then
            if Scope (Encap_Id) /= Pack_Id then
               SPARK_Msg_NE
                 ("indicator Part_Of must denote an abstract state of "
                  & "package & (SPARK RM 7.2.6(2))", Indic, Pack_Id);

               Error_Msg_Name_1 := Chars (Pack_Id);
               SPARK_Msg_NE
                 ("\& is declared in the private part of package %",
                  Indic, Item_Id);
               return;
            end if;

         --  Items declared in the body state space of a package do not need
         --  Part_Of indicators as the refinement has already been seen.

         else
            SPARK_Msg_N
              ("indicator Part_Of cannot appear in this context "
               & "(SPARK RM 7.2.6(5))", Indic);

            if Scope (Encap_Id) = Pack_Id then
               Error_Msg_Name_1 := Chars (Pack_Id);
               SPARK_Msg_NE
                 ("\& is declared in the body of package %", Indic, Item_Id);
            end if;

            return;
         end if;

         --  At this point it is known that the Part_Of indicator is legal

         Legal := True;
      end Check_Part_Of_Abstract_State;

      -----------------------------------
      -- Check_Part_Of_Concurrent_Type --
      -----------------------------------

      procedure Check_Part_Of_Concurrent_Type is
         function In_Proper_Order
           (First  : Node_Id;
            Second : Node_Id) return Boolean;
         pragma Inline (In_Proper_Order);
         --  Determine whether node First precedes node Second

         procedure Placement_Error;
         pragma Inline (Placement_Error);
         --  Emit an error concerning the illegal placement of the item with
         --  respect to the single concurrent type.

         ---------------------
         -- In_Proper_Order --
         ---------------------

         function In_Proper_Order
           (First  : Node_Id;
            Second : Node_Id) return Boolean
         is
            N : Node_Id;

         begin
            if List_Containing (First) = List_Containing (Second) then
               N := First;
               while Present (N) loop
                  if N = Second then
                     return True;
                  end if;

                  Next (N);
               end loop;
            end if;

            return False;
         end In_Proper_Order;

         ---------------------
         -- Placement_Error --
         ---------------------

         procedure Placement_Error is
         begin
            SPARK_Msg_N
              ("indicator Part_Of must denote a previously declared single "
               & "protected type or single task type", Encap);
         end Placement_Error;

         --  Local variables

         Conc_Typ      : constant Entity_Id := Etype (Encap_Id);
         Encap_Decl    : constant Node_Id   := Declaration_Node (Encap_Id);
         Encap_Context : constant Node_Id   := Parent (Encap_Decl);

         Item_Context : Node_Id;
         Item_Decl    : Node_Id;
         Prv_Decls    : List_Id;
         Vis_Decls    : List_Id;

      --  Start of processing for Check_Part_Of_Concurrent_Type

      begin
         --  Only abstract states and variables can act as constituents of an
         --  encapsulating single concurrent type.

         if Ekind (Item_Id) in E_Abstract_State | E_Variable then
            null;

         --  The constituent is a constant

         elsif Ekind (Item_Id) = E_Constant then
            Error_Msg_Name_1 := Chars (Encap_Id);
            SPARK_Msg_NE
              (Fix_Msg (Conc_Typ, "constant & cannot act as constituent of "
               & "single protected type %"), Indic, Item_Id);
            return;

         --  The constituent is a package instantiation

         else
            Error_Msg_Name_1 := Chars (Encap_Id);
            SPARK_Msg_NE
              (Fix_Msg (Conc_Typ, "package instantiation & cannot act as "
               & "constituent of single protected type %"), Indic, Item_Id);
            return;
         end if;

         --  When the item denotes an abstract state of a nested package, use
         --  the declaration of the package to detect proper placement.

         --    package Pack is
         --       task T;
         --       package Nested
         --         with Abstract_State => (State with Part_Of => T)

         if Ekind (Item_Id) = E_Abstract_State then
            Item_Decl := Unit_Declaration_Node (Scope (Item_Id));
         else
            Item_Decl := Declaration_Node (Item_Id);
         end if;

         Item_Context := Parent (Item_Decl);

         --  The item and the single concurrent type must appear in the same
         --  declarative region, with the item following the declaration of
         --  the single concurrent type (SPARK RM 9(3)).

         if Item_Context = Encap_Context then
            if Nkind (Item_Context) in N_Package_Specification
                                     | N_Protected_Definition
                                     | N_Task_Definition
            then
               Prv_Decls := Private_Declarations (Item_Context);
               Vis_Decls := Visible_Declarations (Item_Context);

               --  The placement is OK when the single concurrent type appears
               --  within the visible declarations and the item in the private
               --  declarations.
               --
               --    package Pack is
               --       protected PO ...
               --    private
               --       Constit : ... with Part_Of => PO;
               --    end Pack;

               if List_Containing (Encap_Decl) = Vis_Decls
                 and then List_Containing (Item_Decl) = Prv_Decls
               then
                  null;

               --  The placement is illegal when the item appears within the
               --  visible declarations and the single concurrent type is in
               --  the private declarations.
               --
               --    package Pack is
               --       Constit : ... with Part_Of => PO;
               --    private
               --       protected PO ...
               --    end Pack;

               elsif List_Containing (Item_Decl) = Vis_Decls
                 and then List_Containing (Encap_Decl) = Prv_Decls
               then
                  Placement_Error;
                  return;

               --  Otherwise both the item and the single concurrent type are
               --  in the same list. Ensure that the declaration of the single
               --  concurrent type precedes that of the item.

               elsif not In_Proper_Order
                           (First  => Encap_Decl,
                            Second => Item_Decl)
               then
                  Placement_Error;
                  return;
               end if;

            --  Otherwise both the item and the single concurrent type are
            --  in the same list. Ensure that the declaration of the single
            --  concurrent type precedes that of the item.

            elsif not In_Proper_Order
                        (First  => Encap_Decl,
                         Second => Item_Decl)
            then
               Placement_Error;
               return;
            end if;

         --  Otherwise the item and the single concurrent type reside within
         --  unrelated regions.

         else
            Error_Msg_Name_1 := Chars (Encap_Id);
            SPARK_Msg_NE
              (Fix_Msg (Conc_Typ, "constituent & must be declared "
               & "immediately within the same region as single protected "
               & "type %"), Indic, Item_Id);
            return;
         end if;

         --  At this point it is known that the Part_Of indicator is legal

         Legal := True;
      end Check_Part_Of_Concurrent_Type;

   --  Start of processing for Analyze_Part_Of

   begin
      --  Assume that the indicator is illegal

      Encap_Id := Empty;
      Legal    := False;

      if Nkind (Encap) in
           N_Expanded_Name | N_Identifier | N_Selected_Component
      then
         Analyze       (Encap);
         Resolve_State (Encap);

         Encap_Id := Entity (Encap);

         --  The encapsulator is an abstract state

         if Ekind (Encap_Id) = E_Abstract_State then
            null;

         --  The encapsulator is a single concurrent type (SPARK RM 9.3)

         elsif Is_Single_Concurrent_Object (Encap_Id) then
            null;

         --  Otherwise the encapsulator is not a legal choice

         else
            SPARK_Msg_N
              ("indicator Part_Of must denote abstract state, single "
               & "protected type or single task type", Encap);
            return;
         end if;

      --  This is a syntax error, always report

      else
         Error_Msg_N
           ("indicator Part_Of must denote abstract state, single protected "
            & "type or single task type", Encap);
         return;
      end if;

      --  Catch a case where indicator Part_Of denotes the abstract view of a
      --  variable which appears as an abstract state (SPARK RM 10.1.2 2).

      if From_Limited_With (Encap_Id)
        and then Present (Non_Limited_View (Encap_Id))
        and then Ekind (Non_Limited_View (Encap_Id)) = E_Variable
      then
         SPARK_Msg_N ("indicator Part_Of must denote abstract state", Encap);
         SPARK_Msg_N ("\& denotes abstract view of object", Encap);
         return;
      end if;

      --  The encapsulator is an abstract state

      if Ekind (Encap_Id) = E_Abstract_State then
         Check_Part_Of_Abstract_State;

      --  The encapsulator is a single concurrent type

      else
         Check_Part_Of_Concurrent_Type;
      end if;
   end Analyze_Part_Of;

   ----------------------------------
   -- Analyze_Part_Of_In_Decl_Part --
   ----------------------------------

   procedure Analyze_Part_Of_In_Decl_Part
     (N         : Node_Id;
      Freeze_Id : Entity_Id := Empty)
   is
      Encap    : constant Node_Id   :=
                   Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
      Errors   : constant Nat       := Serious_Errors_Detected;
      Var_Decl : constant Node_Id   := Find_Related_Context (N);
      Var_Id   : constant Entity_Id := Defining_Entity (Var_Decl);
      Constits : Elist_Id;
      Encap_Id : Entity_Id;
      Legal    : Boolean;

   begin
      --  Detect any discrepancies between the placement of the variable with
      --  respect to general state space and the encapsulating state or single
      --  concurrent type.

      Analyze_Part_Of
        (Indic    => N,
         Item_Id  => Var_Id,
         Encap    => Encap,
         Encap_Id => Encap_Id,
         Legal    => Legal);

      --  The Part_Of indicator turns the variable into a constituent of the
      --  encapsulating state or single concurrent type.

      if Legal then
         pragma Assert (Present (Encap_Id));
         Constits := Part_Of_Constituents (Encap_Id);

         if No (Constits) then
            Constits := New_Elmt_List;
            Set_Part_Of_Constituents (Encap_Id, Constits);
         end if;

         Append_Elmt (Var_Id, Constits);
         Set_Encapsulating_State (Var_Id, Encap_Id);

         --  A Part_Of constituent partially refines an abstract state. This
         --  property does not apply to protected or task units.

         if Ekind (Encap_Id) = E_Abstract_State then
            Set_Has_Partial_Visible_Refinement (Encap_Id);
         end if;
      end if;

      --  Emit a clarification message when the encapsulator is undefined,
      --  possibly due to contract freezing.

      if Errors /= Serious_Errors_Detected
        and then Present (Freeze_Id)
        and then Has_Undefined_Reference (Encap)
      then
         Contract_Freeze_Error (Var_Id, Freeze_Id);
      end if;
   end Analyze_Part_Of_In_Decl_Part;

   --------------------
   -- Analyze_Pragma --
   --------------------

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

      Pname : Name_Id := Pragma_Name (N);
      --  Name of the source pragma, or name of the corresponding aspect for
      --  pragmas which originate in a source aspect. In the latter case, the
      --  name may be different from the pragma name.

      Prag_Id : constant Pragma_Id := Get_Pragma_Id (Pname);

      Pragma_Exit : exception;
      --  This exception is used to exit pragma processing completely. It
      --  is used when an error is detected, and no further processing is
      --  required. It is also used if an earlier error has left the tree in
      --  a state where the pragma should not be processed.

      Arg_Count : Nat;
      --  Number of pragma argument associations

      Arg1 : Node_Id;
      Arg2 : Node_Id;
      Arg3 : Node_Id;
      Arg4 : Node_Id;
      Arg5 : Node_Id;
      --  First five pragma arguments (pragma argument association nodes, or
      --  Empty if the corresponding argument does not exist).

      type Name_List is array (Natural range <>) of Name_Id;
      type Args_List is array (Natural range <>) of Node_Id;
      --  Types used for arguments to Check_Arg_Order and Gather_Associations

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

      procedure Ada_2005_Pragma;
      --  Called for pragmas defined in Ada 2005, that are not in Ada 95. In
      --  Ada 95 mode, these are implementation defined pragmas, so should be
      --  caught by the No_Implementation_Pragmas restriction.

      procedure Ada_2012_Pragma;
      --  Called for pragmas defined in Ada 2012, that are not in Ada 95 or 05.
      --  In Ada 95 or 05 mode, these are implementation defined pragmas, so
      --  should be caught by the No_Implementation_Pragmas restriction.

      procedure Analyze_Depends_Global
        (Spec_Id   : out Entity_Id;
         Subp_Decl : out Node_Id;
         Legal     : out Boolean);
      --  Subsidiary to the analysis of pragmas Depends and Global. Verify the
      --  legality of the placement and related context of the pragma. Spec_Id
      --  is the entity of the related subprogram. Subp_Decl is the declaration
      --  of the related subprogram. Sets flag Legal when the pragma is legal.

      procedure Analyze_If_Present (Id : Pragma_Id);
      --  Inspect the remainder of the list containing pragma N and look for
      --  a pragma that matches Id. If found, analyze the pragma.

      procedure Analyze_Pre_Post_Condition;
      --  Subsidiary to the analysis of pragmas Precondition and Postcondition

      procedure Analyze_Refined_Depends_Global_Post
        (Spec_Id : out Entity_Id;
         Body_Id : out Entity_Id;
         Legal   : out Boolean);
      --  Subsidiary routine to the analysis of body pragmas Refined_Depends,
      --  Refined_Global and Refined_Post. Verify the legality of the placement
      --  and related context of the pragma. Spec_Id is the entity of the
      --  related subprogram. Body_Id is the entity of the subprogram body.
      --  Flag Legal is set when the pragma is legal.

      procedure Analyze_Unmodified_Or_Unused (Is_Unused : Boolean := False);
      --  Perform full analysis of pragma Unmodified and the write aspect of
      --  pragma Unused. Flag Is_Unused should be set when verifying the
      --  semantics of pragma Unused.

      procedure Analyze_Unreferenced_Or_Unused (Is_Unused : Boolean := False);
      --  Perform full analysis of pragma Unreferenced and the read aspect of
      --  pragma Unused. Flag Is_Unused should be set when verifying the
      --  semantics of pragma Unused.

      procedure Check_Ada_83_Warning;
      --  Issues a warning message for the current pragma if operating in Ada
      --  83 mode (used for language pragmas that are not a standard part of
      --  Ada 83). This procedure does not raise Pragma_Exit. Also notes use
      --  of 95 pragma.

      procedure Check_Arg_Count (Required : Nat);
      --  Check argument count for pragma is equal to given parameter. If not,
      --  then issue an error message and raise Pragma_Exit.

      --  Note: all routines whose name is Check_Arg_Is_xxx take an argument
      --  Arg which can either be a pragma argument association, in which case
      --  the check is applied to the expression of the association or an
      --  expression directly.

      procedure Check_Arg_Is_External_Name (Arg : Node_Id);
      --  Check that an argument has the right form for an EXTERNAL_NAME
      --  parameter of an extended import/export pragma. The rule is that the
      --  name must be an identifier or string literal (in Ada 83 mode) or a
      --  static string expression (in Ada 95 mode).

      procedure Check_Arg_Is_Identifier (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is an
      --  identifier. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Is_Integer_Literal (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is an integer
      --  literal. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Is_Library_Level_Local_Name (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it has the proper
      --  syntactic form for a local name and meets the semantic requirements
      --  for a local name. The local name is analyzed as part of the
      --  processing for this call. In addition, the local name is required
      --  to represent an entity at the library level.

      procedure Check_Arg_Is_Local_Name (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it has the proper
      --  syntactic form for a local name and meets the semantic requirements
      --  for a local name. The local name is analyzed as part of the
      --  processing for this call.

      procedure Check_Arg_Is_Locking_Policy (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is a valid
      --  locking policy name. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Is_Partition_Elaboration_Policy (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is a valid
      --  elaboration policy name. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2             : Name_Id);
      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2, N3         : Name_Id);
      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2, N3, N4     : Name_Id);
      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2, N3, N4, N5 : Name_Id);
      --  Check the specified argument Arg to make sure that it is an
      --  identifier whose name matches either N1 or N2 (or N3, N4, N5 if
      --  present). If not then give error and raise Pragma_Exit.

      procedure Check_Arg_Is_Queuing_Policy (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is a valid
      --  queuing policy name. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Is_OK_Static_Expression
        (Arg : Node_Id;
         Typ : Entity_Id := Empty);
      --  Check the specified argument Arg to make sure that it is a static
      --  expression of the given type (i.e. it will be analyzed and resolved
      --  using this type, which can be any valid argument to Resolve, e.g.
      --  Any_Integer is OK). If not, given error and raise Pragma_Exit. If
      --  Typ is left Empty, then any static expression is allowed. Includes
      --  checking that the argument does not raise Constraint_Error.

      procedure Check_Arg_Is_Task_Dispatching_Policy (Arg : Node_Id);
      --  Check the specified argument Arg to make sure that it is a valid task
      --  dispatching policy name. If not give error and raise Pragma_Exit.

      procedure Check_Arg_Order (Names : Name_List);
      --  Checks for an instance of two arguments with identifiers for the
      --  current pragma which are not in the sequence indicated by Names,
      --  and if so, generates a fatal message about bad order of arguments.

      procedure Check_At_Least_N_Arguments (N : Nat);
      --  Check there are at least N arguments present

      procedure Check_At_Most_N_Arguments (N : Nat);
      --  Check there are no more than N arguments present

      procedure Check_Component
        (Comp            : Node_Id;
         UU_Typ          : Entity_Id;
         In_Variant_Part : Boolean := False);
      --  Examine an Unchecked_Union component for correct use of per-object
      --  constrained subtypes, and for restrictions on finalizable components.
      --  UU_Typ is the related Unchecked_Union type. Flag In_Variant_Part
      --  should be set when Comp comes from a record variant.

      procedure Check_Duplicate_Pragma (E : Entity_Id);
      --  Check if a rep item of the same name as the current pragma is already
      --  chained as a rep pragma to the given entity. If so give a message
      --  about the duplicate, and then raise Pragma_Exit so does not return.
      --  Note that if E is a type, then this routine avoids flagging a pragma
      --  which applies to a parent type from which E is derived.

      procedure Check_Duplicated_Export_Name (Nam : Node_Id);
      --  Nam is an N_String_Literal node containing the external name set by
      --  an Import or Export pragma (or extended Import or Export pragma).
      --  This procedure checks for possible duplications if this is the export
      --  case, and if found, issues an appropriate error message.

      procedure Check_Expr_Is_OK_Static_Expression
        (Expr : Node_Id;
         Typ  : Entity_Id := Empty);
      --  Check the specified expression Expr to make sure that it is a static
      --  expression of the given type (i.e. it will be analyzed and resolved
      --  using this type, which can be any valid argument to Resolve, e.g.
      --  Any_Integer is OK). If not, given error and raise Pragma_Exit. If
      --  Typ is left Empty, then any static expression is allowed. Includes
      --  checking that the expression does not raise Constraint_Error.

      procedure Check_First_Subtype (Arg : Node_Id);
      --  Checks that Arg, whose expression is an entity name, references a
      --  first subtype.

      procedure Check_Identifier (Arg : Node_Id; Id : Name_Id);
      --  Checks that the given argument has an identifier, and if so, requires
      --  it to match the given identifier name. If there is no identifier, or
      --  a non-matching identifier, then an error message is given and
      --  Pragma_Exit is raised.

      procedure Check_Identifier_Is_One_Of (Arg : Node_Id; N1, N2 : Name_Id);
      --  Checks that the given argument has an identifier, and if so, requires
      --  it to match one of the given identifier names. If there is no
      --  identifier, or a non-matching identifier, then an error message is
      --  given and Pragma_Exit is raised.

      procedure Check_In_Main_Program;
      --  Common checks for pragmas that appear within a main program
      --  (Priority, Main_Storage, Time_Slice, Relative_Deadline, CPU).

      procedure Check_Interrupt_Or_Attach_Handler;
      --  Common processing for first argument of pragma Interrupt_Handler or
      --  pragma Attach_Handler.

      procedure Check_Loop_Pragma_Placement;
      --  Verify whether pragmas Loop_Invariant, Loop_Optimize and Loop_Variant
      --  appear immediately within a construct restricted to loops, and that
      --  pragmas Loop_Invariant and Loop_Variant are grouped together.

      procedure Check_Is_In_Decl_Part_Or_Package_Spec;
      --  Check that pragma appears in a declarative part, or in a package
      --  specification, i.e. that it does not occur in a statement sequence
      --  in a body.

      procedure Check_No_Identifier (Arg : Node_Id);
      --  Checks that the given argument does not have an identifier. If
      --  an identifier is present, then an error message is issued, and
      --  Pragma_Exit is raised.

      procedure Check_No_Identifiers;
      --  Checks that none of the arguments to the pragma has an identifier.
      --  If any argument has an identifier, then an error message is issued,
      --  and Pragma_Exit is raised.

      procedure Check_No_Link_Name;
      --  Checks that no link name is specified

      procedure Check_Optional_Identifier (Arg : Node_Id; Id : Name_Id);
      --  Checks if the given argument has an identifier, and if so, requires
      --  it to match the given identifier name. If there is a non-matching
      --  identifier, then an error message is given and Pragma_Exit is raised.

      procedure Check_Optional_Identifier (Arg : Node_Id; Id : String);
      --  Checks if the given argument has an identifier, and if so, requires
      --  it to match the given identifier name. If there is a non-matching
      --  identifier, then an error message is given and Pragma_Exit is raised.
      --  In this version of the procedure, the identifier name is given as
      --  a string with lower case letters.

      procedure Check_Static_Boolean_Expression (Expr : Node_Id);
      --  Subsidiary to the analysis of pragmas Async_Readers, Async_Writers,
      --  Constant_After_Elaboration, Effective_Reads, Effective_Writes,
      --  Extensions_Visible and Volatile_Function. Ensure that expression Expr
      --  is an OK static boolean expression. Emit an error if this is not the
      --  case.

      procedure Check_Static_Constraint (Constr : Node_Id);
      --  Constr is a constraint from an N_Subtype_Indication node from a
      --  component constraint in an Unchecked_Union type, a range, or a
      --  discriminant association. This routine checks that the constraint
      --  is static as required by the restrictions for Unchecked_Union.

      procedure Check_Valid_Configuration_Pragma;
      --  Legality checks for placement of a configuration pragma

      procedure Check_Valid_Library_Unit_Pragma;
      --  Legality checks for library unit pragmas. A special case arises for
      --  pragmas in generic instances that come from copies of the original
      --  library unit pragmas in the generic templates. In the case of other
      --  than library level instantiations these can appear in contexts which
      --  would normally be invalid (they only apply to the original template
      --  and to library level instantiations), and they are simply ignored,
      --  which is implemented by rewriting them as null statements and
      --  optionally raising Pragma_Exit to terminate analysis. An exception
      --  is not always raised to avoid exception propagation during the
      --  bootstrap, so all callers should check whether N has been rewritten.

      procedure Check_Variant (Variant : Node_Id; UU_Typ : Entity_Id);
      --  Check an Unchecked_Union variant for lack of nested variants and
      --  presence of at least one component. UU_Typ is the related Unchecked_
      --  Union type.

      procedure Ensure_Aggregate_Form (Arg : Node_Id);
      --  Subsidiary routine to the processing of pragmas Abstract_State,
      --  Contract_Cases, Depends, Global, Initializes, Refined_Depends,
      --  Refined_Global, Refined_State and Subprogram_Variant. Transform
      --  argument Arg into an aggregate if not one already. N_Null is never
      --  transformed. Arg may denote an aspect specification or a pragma
      --  argument association.

      procedure Error_Pragma (Msg : String);
      pragma No_Return (Error_Pragma);
      --  Outputs error message for current pragma. The message contains a %
      --  that will be replaced with the pragma name, and the flag is placed
      --  on the pragma itself. Pragma_Exit is then raised. Note: this routine
      --  calls Fix_Error (see spec of that procedure for details).

      procedure Error_Pragma_Arg (Msg : String; Arg : Node_Id);
      pragma No_Return (Error_Pragma_Arg);
      --  Outputs error message for current pragma. The message may contain
      --  a % that will be replaced with the pragma name. The parameter Arg
      --  may either be a pragma argument association, in which case the flag
      --  is placed on the expression of this association, or an expression,
      --  in which case the flag is placed directly on the expression. The
      --  message is placed using Error_Msg_N, so the message may also contain
      --  an & insertion character which will reference the given Arg value.
      --  After placing the message, Pragma_Exit is raised. Note: this routine
      --  calls Fix_Error (see spec of that procedure for details).

      procedure Error_Pragma_Arg (Msg1, Msg2 : String; Arg : Node_Id);
      pragma No_Return (Error_Pragma_Arg);
      --  Similar to above form of Error_Pragma_Arg except that two messages
      --  are provided, the second is a continuation comment starting with \.

      procedure Error_Pragma_Arg_Ident (Msg : String; Arg : Node_Id);
      pragma No_Return (Error_Pragma_Arg_Ident);
      --  Outputs error message for current pragma. The message may contain a %
      --  that will be replaced with the pragma name. The parameter Arg must be
      --  a pragma argument association with a non-empty identifier (i.e. its
      --  Chars field must be set), and the error message is placed on the
      --  identifier. The message is placed using Error_Msg_N so the message
      --  may also contain an & insertion character which will reference
      --  the identifier. After placing the message, Pragma_Exit is raised.
      --  Note: this routine calls Fix_Error (see spec of that procedure for
      --  details).

      procedure Error_Pragma_Ref (Msg : String; Ref : Entity_Id);
      pragma No_Return (Error_Pragma_Ref);
      --  Outputs error message for current pragma. The message may contain
      --  a % that will be replaced with the pragma name. The parameter Ref
      --  must be an entity whose name can be referenced by & and sloc by #.
      --  After placing the message, Pragma_Exit is raised. Note: this routine
      --  calls Fix_Error (see spec of that procedure for details).

      function Find_Lib_Unit_Name return Entity_Id;
      --  Used for a library unit pragma to find the entity to which the
      --  library unit pragma applies, returns the entity found.

      procedure Find_Program_Unit_Name (Id : Node_Id);
      --  If the pragma is a compilation unit pragma, the id must denote the
      --  compilation unit in the same compilation, and the pragma must appear
      --  in the list of preceding or trailing pragmas. If it is a program
      --  unit pragma that is not a compilation unit pragma, then the
      --  identifier must be visible.

      function Find_Unique_Parameterless_Procedure
        (Name : Entity_Id;
         Arg  : Node_Id) return Entity_Id;
      --  Used for a procedure pragma to find the unique parameterless
      --  procedure identified by Name, returns it if it exists, otherwise
      --  errors out and uses Arg as the pragma argument for the message.

      function Fix_Error (Msg : String) return String;
      --  This is called prior to issuing an error message. Msg is the normal
      --  error message issued in the pragma case. This routine checks for the
      --  case of a pragma coming from an aspect in the source, and returns a
      --  message suitable for the aspect case as follows:
      --
      --    Each substring "pragma" is replaced by "aspect"
      --
      --    If "argument of" is at the start of the error message text, it is
      --    replaced by "entity for".
      --
      --    If "argument" is at the start of the error message text, it is
      --    replaced by "entity".
      --
      --  So for example, "argument of pragma X must be discrete type"
      --  returns "entity for aspect X must be a discrete type".

      --  Finally Error_Msg_Name_1 is set to the name of the aspect (which may
      --  be different from the pragma name). If the current pragma results
      --  from rewriting another pragma, then Error_Msg_Name_1 is set to the
      --  original pragma name.

      procedure Gather_Associations
        (Names : Name_List;
         Args  : out Args_List);
      --  This procedure is used to gather the arguments for a pragma that
      --  permits arbitrary ordering of parameters using the normal rules
      --  for named and positional parameters. The Names argument is a list
      --  of Name_Id values that corresponds to the allowed pragma argument
      --  association identifiers in order. The result returned in Args is
      --  a list of corresponding expressions that are the pragma arguments.
      --  Note that this is a list of expressions, not of pragma argument
      --  associations (Gather_Associations has completely checked all the
      --  optional identifiers when it returns). An entry in Args is Empty
      --  on return if the corresponding argument is not present.

      procedure GNAT_Pragma;
      --  Called for all GNAT defined pragmas to check the relevant restriction
      --  (No_Implementation_Pragmas).

      function Is_Before_First_Decl
        (Pragma_Node : Node_Id;
         Decls       : List_Id) return Boolean;
      --  Return True if Pragma_Node is before the first declarative item in
      --  Decls where Decls is the list of declarative items.

      function Is_Configuration_Pragma return Boolean;
      --  Determines if the placement of the current pragma is appropriate
      --  for a configuration pragma.

      function Is_In_Context_Clause return Boolean;
      --  Returns True if pragma appears within the context clause of a unit,
      --  and False for any other placement (does not generate any messages).

      function Is_Static_String_Expression (Arg : Node_Id) return Boolean;
      --  Analyzes the argument, and determines if it is a static string
      --  expression, returns True if so, False if non-static or not String.
      --  A special case is that a string literal returns True in Ada 83 mode
      --  (which has no such thing as static string expressions). Note that
      --  the call analyzes its argument, so this cannot be used for the case
      --  where an identifier might not be declared.

      procedure Pragma_Misplaced;
      pragma No_Return (Pragma_Misplaced);
      --  Issue fatal error message for misplaced pragma

      procedure Process_Atomic_Independent_Shared_Volatile;
      --  Common processing for pragmas Atomic, Independent, Shared, Volatile,
      --  Volatile_Full_Access. Note that Shared is an obsolete Ada 83 pragma
      --  and treated as being identical in effect to pragma Atomic.

      procedure Process_Compile_Time_Warning_Or_Error;
      --  Common processing for Compile_Time_Error and Compile_Time_Warning

      procedure Process_Convention
        (C   : out Convention_Id;
         Ent : out Entity_Id);
      --  Common processing for Convention, Interface, Import and Export.
      --  Checks first two arguments of pragma, and sets the appropriate
      --  convention value in the specified entity or entities. On return
      --  C is the convention, Ent is the referenced entity.

      procedure Process_Disable_Enable_Atomic_Sync (Nam : Name_Id);
      --  Common processing for Disable/Enable_Atomic_Synchronization. Nam is
      --  Name_Suppress for Disable and Name_Unsuppress for Enable.

      procedure Process_Extended_Import_Export_Object_Pragma
        (Arg_Internal : Node_Id;
         Arg_External : Node_Id;
         Arg_Size     : Node_Id);
      --  Common processing for the pragmas Import/Export_Object. The three
      --  arguments correspond to the three named parameters of the pragmas. An
      --  argument is empty if the corresponding parameter is not present in
      --  the pragma.

      procedure Process_Extended_Import_Export_Internal_Arg
        (Arg_Internal : Node_Id := Empty);
      --  Common processing for all extended Import and Export pragmas. The
      --  argument is the pragma parameter for the Internal argument. If
      --  Arg_Internal is empty or inappropriate, an error message is posted.
      --  Otherwise, on normal return, the Entity_Field of Arg_Internal is
      --  set to identify the referenced entity.

      procedure Process_Extended_Import_Export_Subprogram_Pragma
        (Arg_Internal                 : Node_Id;
         Arg_External                 : Node_Id;
         Arg_Parameter_Types          : Node_Id;
         Arg_Result_Type              : Node_Id := Empty;
         Arg_Mechanism                : Node_Id;
         Arg_Result_Mechanism         : Node_Id := Empty);
      --  Common processing for all extended Import and Export pragmas applying
      --  to subprograms. The caller omits any arguments that do not apply to
      --  the pragma in question (for example, Arg_Result_Type can be non-Empty
      --  only in the Import_Function and Export_Function cases). The argument
      --  names correspond to the allowed pragma association identifiers.

      procedure Process_Generic_List;
      --  Common processing for Share_Generic and Inline_Generic

      procedure Process_Import_Or_Interface;
      --  Common processing for Import or Interface

      procedure Process_Import_Predefined_Type;
      --  Processing for completing a type with pragma Import. This is used
      --  to declare types that match predefined C types, especially for cases
      --  without corresponding Ada predefined type.

      type Inline_Status is (Suppressed, Disabled, Enabled);
      --  Inline status of a subprogram, indicated as follows:
      --    Suppressed: inlining is suppressed for the subprogram
      --    Disabled:   no inlining is requested for the subprogram
      --    Enabled:    inlining is requested/required for the subprogram

      procedure Process_Inline (Status : Inline_Status);
      --  Common processing for No_Inline, Inline and Inline_Always. Parameter
      --  indicates the inline status specified by the pragma.

      procedure Process_Interface_Name
        (Subprogram_Def : Entity_Id;
         Ext_Arg        : Node_Id;
         Link_Arg       : Node_Id;
         Prag           : Node_Id);
      --  Given the last two arguments of pragma Import, pragma Export, or
      --  pragma Interface_Name, performs validity checks and sets the
      --  Interface_Name field of the given subprogram entity to the
      --  appropriate external or link name, depending on the arguments given.
      --  Ext_Arg is always present, but Link_Arg may be missing. Note that
      --  Ext_Arg may represent the Link_Name if Link_Arg is missing, and
      --  appropriate named notation is used for Ext_Arg. If neither Ext_Arg
      --  nor Link_Arg is present, the interface name is set to the default
      --  from the subprogram name. In addition, the pragma itself is passed
      --  to analyze any expressions in the case the pragma came from an aspect
      --  specification.

      procedure Process_Interrupt_Or_Attach_Handler;
      --  Common processing for Interrupt and Attach_Handler pragmas

      procedure Process_Restrictions_Or_Restriction_Warnings (Warn : Boolean);
      --  Common processing for Restrictions and Restriction_Warnings pragmas.
      --  Warn is True for Restriction_Warnings, or for Restrictions if the
      --  flag Treat_Restrictions_As_Warnings is set, and False if this flag
      --  is not set in the Restrictions case.

      procedure Process_Suppress_Unsuppress (Suppress_Case : Boolean);
      --  Common processing for Suppress and Unsuppress. The boolean parameter
      --  Suppress_Case is True for the Suppress case, and False for the
      --  Unsuppress case.

      procedure Record_Independence_Check (N : Node_Id; E : Entity_Id);
      --  Subsidiary to the analysis of pragmas Independent[_Components].
      --  Record such a pragma N applied to entity E for future checks.

      procedure Set_Exported (E : Entity_Id; Arg : Node_Id);
      --  This procedure sets the Is_Exported flag for the given entity,
      --  checking that the entity was not previously imported. Arg is
      --  the argument that specified the entity. A check is also made
      --  for exporting inappropriate entities.

      procedure Set_Extended_Import_Export_External_Name
        (Internal_Ent : Entity_Id;
         Arg_External : Node_Id);
      --  Common processing for all extended import export pragmas. The first
      --  argument, Internal_Ent, is the internal entity, which has already
      --  been checked for validity by the caller. Arg_External is from the
      --  Import or Export pragma, and may be null if no External parameter
      --  was present. If Arg_External is present and is a non-null string
      --  (a null string is treated as the default), then the Interface_Name
      --  field of Internal_Ent is set appropriately.

      procedure Set_Imported (E : Entity_Id);
      --  This procedure sets the Is_Imported flag for the given entity,
      --  checking that it is not previously exported or imported.

      procedure Set_Mechanism_Value (Ent : Entity_Id; Mech_Name : Node_Id);
      --  Mech is a parameter passing mechanism (see Import_Function syntax
      --  for MECHANISM_NAME). This routine checks that the mechanism argument
      --  has the right form, and if not issues an error message. If the
      --  argument has the right form then the Mechanism field of Ent is
      --  set appropriately.

      procedure Set_Rational_Profile;
      --  Activate the set of configuration pragmas and permissions that make
      --  up the Rational profile.

      procedure Set_Ravenscar_Profile (Profile : Profile_Name; N : Node_Id);
      --  Activate the set of configuration pragmas and restrictions that make
      --  up the Profile. Profile must be either GNAT_Extended_Ravenscar,
      --  GNAT_Ravenscar_EDF, Jorvik, or Ravenscar. N is the corresponding
      --  pragma node, which is used for error messages on any constructs
      --  violating the profile.

      ---------------------
      -- Ada_2005_Pragma --
      ---------------------

      procedure Ada_2005_Pragma is
      begin
         if Ada_Version <= Ada_95 then
            Check_Restriction (No_Implementation_Pragmas, N);
         end if;
      end Ada_2005_Pragma;

      ---------------------
      -- Ada_2012_Pragma --
      ---------------------

      procedure Ada_2012_Pragma is
      begin
         if Ada_Version <= Ada_2005 then
            Check_Restriction (No_Implementation_Pragmas, N);
         end if;
      end Ada_2012_Pragma;

      ----------------------------
      -- Analyze_Depends_Global --
      ----------------------------

      procedure Analyze_Depends_Global
        (Spec_Id   : out Entity_Id;
         Subp_Decl : out Node_Id;
         Legal     : out Boolean)
      is
      begin
         --  Assume that the pragma is illegal

         Spec_Id   := Empty;
         Subp_Decl := Empty;
         Legal     := False;

         GNAT_Pragma;
         Check_Arg_Count (1);

         --  Ensure the proper placement of the pragma. Depends/Global must be
         --  associated with a subprogram declaration or a body that acts as a
         --  spec.

         Subp_Decl := Find_Related_Declaration_Or_Body (N, Do_Checks => True);

         --  Entry

         if Nkind (Subp_Decl) = N_Entry_Declaration then
            null;

         --  Generic subprogram

         elsif Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
            null;

         --  Object declaration of a single concurrent type

         elsif Nkind (Subp_Decl) = N_Object_Declaration
           and then Is_Single_Concurrent_Object
                      (Unique_Defining_Entity (Subp_Decl))
         then
            null;

         --  Single task type

         elsif Nkind (Subp_Decl) = N_Single_Task_Declaration then
            null;

         --  Subprogram body acts as spec

         elsif Nkind (Subp_Decl) = N_Subprogram_Body
           and then No (Corresponding_Spec (Subp_Decl))
         then
            null;

         --  Subprogram body stub acts as spec

         elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
           and then No (Corresponding_Spec_Of_Stub (Subp_Decl))
         then
            null;

         --  Subprogram declaration

         elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then

            --  Pragmas Global and Depends are forbidden on null procedures
            --  (SPARK RM 6.1.2(2)).

            if Nkind (Specification (Subp_Decl)) = N_Procedure_Specification
              and then Null_Present (Specification (Subp_Decl))
            then
               Error_Msg_N (Fix_Error
                 ("pragma % cannot apply to null procedure"), N);
               return;
            end if;

         --  Task type

         elsif Nkind (Subp_Decl) = N_Task_Type_Declaration then
            null;

         else
            Pragma_Misplaced;
            return;
         end if;

         --  If we get here, then the pragma is legal

         Legal   := True;
         Spec_Id := Unique_Defining_Entity (Subp_Decl);

         --  When the related context is an entry, the entry must belong to a
         --  protected unit (SPARK RM 6.1.4(6)).

         if Is_Entry_Declaration (Spec_Id)
           and then Ekind (Scope (Spec_Id)) /= E_Protected_Type
         then
            Pragma_Misplaced;
            return;

         --  When the related context is an anonymous object created for a
         --  simple concurrent type, the type must be a task
         --  (SPARK RM 6.1.4(6)).

         elsif Is_Single_Concurrent_Object (Spec_Id)
           and then Ekind (Etype (Spec_Id)) /= E_Task_Type
         then
            Pragma_Misplaced;
            return;
         end if;

         --  A pragma that applies to a Ghost entity becomes Ghost for the
         --  purposes of legality checks and removal of ignored Ghost code.

         Mark_Ghost_Pragma (N, Spec_Id);
         Ensure_Aggregate_Form (Get_Argument (N, Spec_Id));
      end Analyze_Depends_Global;

      ------------------------
      -- Analyze_If_Present --
      ------------------------

      procedure Analyze_If_Present (Id : Pragma_Id) is
         Stmt : Node_Id;

      begin
         pragma Assert (Is_List_Member (N));

         --  Inspect the declarations or statements following pragma N looking
         --  for another pragma whose Id matches the caller's request. If it is
         --  available, analyze it.

         Stmt := Next (N);
         while Present (Stmt) loop
            if Nkind (Stmt) = N_Pragma and then Get_Pragma_Id (Stmt) = Id then
               Analyze_Pragma (Stmt);
               exit;

            --  The first source declaration or statement immediately following
            --  N ends the region where a pragma may appear.

            elsif Comes_From_Source (Stmt) then
               exit;
            end if;

            Next (Stmt);
         end loop;
      end Analyze_If_Present;

      --------------------------------
      -- Analyze_Pre_Post_Condition --
      --------------------------------

      procedure Analyze_Pre_Post_Condition is
         Prag_Iden : constant Node_Id := Pragma_Identifier (N);
         Subp_Decl : Node_Id;
         Subp_Id   : Entity_Id;

         Duplicates_OK : Boolean := False;
         --  Flag set when a pre/postcondition allows multiple pragmas of the
         --  same kind.

         In_Body_OK : Boolean := False;
         --  Flag set when a pre/postcondition is allowed to appear on a body
         --  even though the subprogram may have a spec.

         Is_Pre_Post : Boolean := False;
         --  Flag set when the pragma is one of Pre, Pre_Class, Post or
         --  Post_Class.

         function Inherits_Class_Wide_Pre (E : Entity_Id) return Boolean;
         --  Implement rules in AI12-0131: an overriding operation can have
         --  a class-wide precondition only if one of its ancestors has an
         --  explicit class-wide precondition.

         -----------------------------
         -- Inherits_Class_Wide_Pre --
         -----------------------------

         function Inherits_Class_Wide_Pre (E : Entity_Id) return Boolean is
            Typ  : constant Entity_Id := Find_Dispatching_Type (E);
            Cont : Node_Id;
            Prag : Node_Id;
            Prev : Entity_Id := Overridden_Operation (E);

         begin
            --  Check ancestors on the overriding operation to examine the
            --  preconditions that may apply to them.

            while Present (Prev) loop
               Cont := Contract (Prev);
               if Present (Cont) then
                  Prag := Pre_Post_Conditions (Cont);
                  while Present (Prag) loop
                     if Pragma_Name (Prag) = Name_Precondition
                       and then Class_Present (Prag)
                     then
                        return True;
                     end if;

                     Prag := Next_Pragma (Prag);
                  end loop;
               end if;

               --  For a type derived from a generic formal type, the operation
               --  inheriting the condition is a renaming, not an overriding of
               --  the operation of the formal. Ditto for an inherited
               --  operation which has no explicit contracts.

               if Is_Generic_Type (Find_Dispatching_Type (Prev))
                 or else not Comes_From_Source (Prev)
               then
                  Prev := Alias (Prev);
               else
                  Prev := Overridden_Operation (Prev);
               end if;
            end loop;

            --  If the controlling type of the subprogram has progenitors, an
            --  interface operation implemented by the current operation may
            --  have a class-wide precondition.

            if Has_Interfaces (Typ) then
               declare
                  Elmt      : Elmt_Id;
                  Ints      : Elist_Id;
                  Prim      : Entity_Id;
                  Prim_Elmt : Elmt_Id;
                  Prim_List : Elist_Id;

               begin
                  Collect_Interfaces (Typ, Ints);
                  Elmt := First_Elmt (Ints);

                  --  Iterate over the primitive operations of each interface

                  while Present (Elmt) loop
                     Prim_List := Direct_Primitive_Operations (Node (Elmt));
                     Prim_Elmt := First_Elmt (Prim_List);
                     while Present (Prim_Elmt) loop
                        Prim := Node (Prim_Elmt);
                        if Chars (Prim) = Chars (E)
                          and then Present (Contract (Prim))
                          and then Class_Present
                                     (Pre_Post_Conditions (Contract (Prim)))
                        then
                           return True;
                        end if;

                        Next_Elmt (Prim_Elmt);
                     end loop;

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

            return False;
         end Inherits_Class_Wide_Pre;

      --  Start of processing for Analyze_Pre_Post_Condition

      begin
         --  Change the name of pragmas Pre, Pre_Class, Post and Post_Class to
         --  offer uniformity among the various kinds of pre/postconditions by
         --  rewriting the pragma identifier. This allows the retrieval of the
         --  original pragma name by routine Original_Aspect_Pragma_Name.

         if Comes_From_Source (N) then
            if Pname in Name_Pre | Name_Pre_Class then
               Is_Pre_Post := True;
               Set_Class_Present (N, Pname = Name_Pre_Class);
               Rewrite (Prag_Iden, Make_Identifier (Loc, Name_Precondition));

            elsif Pname in Name_Post | Name_Post_Class then
               Is_Pre_Post := True;
               Set_Class_Present (N, Pname = Name_Post_Class);
               Rewrite (Prag_Iden, Make_Identifier (Loc, Name_Postcondition));
            end if;
         end if;

         --  Determine the semantics with respect to duplicates and placement
         --  in a body. Pragmas Precondition and Postcondition were introduced
         --  before aspects and are not subject to the same aspect-like rules.

         if Pname in Name_Precondition | Name_Postcondition then
            Duplicates_OK := True;
            In_Body_OK    := True;
         end if;

         GNAT_Pragma;

         --  Pragmas Pre, Pre_Class, Post and Post_Class allow for a single
         --  argument without an identifier.

         if Is_Pre_Post then
            Check_Arg_Count (1);
            Check_No_Identifiers;

         --  Pragmas Precondition and Postcondition have complex argument
         --  profile.

         else
            Check_At_Least_N_Arguments (1);
            Check_At_Most_N_Arguments  (2);
            Check_Optional_Identifier (Arg1, Name_Check);

            if Present (Arg2) then
               Check_Optional_Identifier (Arg2, Name_Message);
               Preanalyze_Spec_Expression
                 (Get_Pragma_Arg (Arg2), Standard_String);
            end if;
         end if;

         --  For a pragma PPC in the extended main source unit, record enabled
         --  status in SCO.
         --  ??? nothing checks that the pragma is in the main source unit

         if Is_Checked (N) and then not Split_PPC (N) then
            Set_SCO_Pragma_Enabled (Loc);
         end if;

         --  Ensure the proper placement of the pragma

         Subp_Decl :=
           Find_Related_Declaration_Or_Body
             (N, Do_Checks => not Duplicates_OK);

         --  When a pre/postcondition pragma applies to an abstract subprogram,
         --  its original form must be an aspect with 'Class.

         if Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration then
            if not From_Aspect_Specification (N) then
               Error_Pragma
                 ("pragma % cannot be applied to abstract subprogram");

            elsif not Class_Present (N) then
               Error_Pragma
                 ("aspect % requires ''Class for abstract subprogram");
            end if;

         --  Entry declaration

         elsif Nkind (Subp_Decl) = N_Entry_Declaration then
            null;

         --  Generic subprogram declaration

         elsif Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
            null;

         --  Subprogram body

         elsif Nkind (Subp_Decl) = N_Subprogram_Body
           and then (No (Corresponding_Spec (Subp_Decl)) or In_Body_OK)
         then
            null;

         --  Subprogram body stub

         elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
           and then (No (Corresponding_Spec_Of_Stub (Subp_Decl)) or In_Body_OK)
         then
            null;

         --  Subprogram declaration

         elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then

            --  AI05-0230: When a pre/postcondition pragma applies to a null
            --  procedure, its original form must be an aspect with 'Class.

            if Nkind (Specification (Subp_Decl)) = N_Procedure_Specification
              and then Null_Present (Specification (Subp_Decl))
              and then From_Aspect_Specification (N)
              and then not Class_Present (N)
            then
               Error_Pragma ("aspect % requires ''Class for null procedure");
            end if;

            --  Implement the legality checks mandated by AI12-0131:
            --    Pre'Class shall not be specified for an overriding primitive
            --    subprogram of a tagged type T unless the Pre'Class aspect is
            --    specified for the corresponding primitive subprogram of some
            --    ancestor of T.

            declare
               E : constant Entity_Id := Defining_Entity (Subp_Decl);

            begin
               if Class_Present (N)
                 and then Pragma_Name (N) = Name_Precondition
                 and then Present (Overridden_Operation (E))
                 and then not Inherits_Class_Wide_Pre (E)
               then
                  Error_Msg_N
                    ("illegal class-wide precondition on overriding operation",
                     Corresponding_Aspect (N));
               end if;
            end;

         --  A renaming declaration may inherit a generated pragma, its
         --  placement comes from expansion, not from source.

         elsif Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
           and then not Comes_From_Source (N)
         then
            null;

         --  For Ada 2022, pre/postconditions can appear on formal subprograms

         elsif Nkind (Subp_Decl) = N_Formal_Concrete_Subprogram_Declaration
            and then Ada_Version >= Ada_2022
         then
            null;

         --  An access-to-subprogram type can have pre/postconditions, but
         --  these are transferred to the generated subprogram wrapper and
         --  analyzed there.

         --  Otherwise the placement of the pragma is illegal

         else
            Pragma_Misplaced;
            return;
         end if;

         Subp_Id := Defining_Entity (Subp_Decl);

         --  A pragma that applies to a Ghost entity becomes Ghost for the
         --  purposes of legality checks and removal of ignored Ghost code.

         Mark_Ghost_Pragma (N, Subp_Id);

         --  Chain the pragma on the contract for further processing by
         --  Analyze_Pre_Post_Condition_In_Decl_Part.

         Add_Contract_Item (N, Subp_Id);

         --  Fully analyze the pragma when it appears inside an entry or
         --  subprogram body because it cannot benefit from forward references.

         if Nkind (Subp_Decl) in N_Entry_Body
                               | N_Subprogram_Body
                               | N_Subprogram_Body_Stub
         then
            --  The legality checks of pragmas Precondition and Postcondition
            --  are affected by the SPARK mode in effect and the volatility of
            --  the context. Analyze all pragmas in a specific order.

            Analyze_If_Present (Pragma_SPARK_Mode);
            Analyze_If_Present (Pragma_Volatile_Function);
            Analyze_Pre_Post_Condition_In_Decl_Part (N);
         end if;
      end Analyze_Pre_Post_Condition;

      -----------------------------------------
      -- Analyze_Refined_Depends_Global_Post --
      -----------------------------------------

      procedure Analyze_Refined_Depends_Global_Post
        (Spec_Id : out Entity_Id;
         Body_Id : out Entity_Id;
         Legal   : out Boolean)
      is
         Body_Decl : Node_Id;
         Spec_Decl : Node_Id;

      begin
         --  Assume that the pragma is illegal

         Spec_Id := Empty;
         Body_Id := Empty;
         Legal   := False;

         GNAT_Pragma;
         Check_Arg_Count (1);
         Check_No_Identifiers;

         --  Verify the placement of the pragma and check for duplicates. The
         --  pragma must apply to a subprogram body [stub].

         Body_Decl := Find_Related_Declaration_Or_Body (N, Do_Checks => True);

         if Nkind (Body_Decl) not in
              N_Entry_Body | N_Subprogram_Body | N_Subprogram_Body_Stub |
              N_Task_Body  | N_Task_Body_Stub
         then
            Pragma_Misplaced;
            return;
         end if;

         Body_Id := Defining_Entity (Body_Decl);
         Spec_Id := Unique_Defining_Entity (Body_Decl);

         --  The pragma must apply to the second declaration of a subprogram.
         --  In other words, the body [stub] cannot acts as a spec.

         if No (Spec_Id) then
            Error_Pragma ("pragma % cannot apply to a stand alone body");
            return;

         --  Catch the case where the subprogram body is a subunit and acts as
         --  the third declaration of the subprogram.

         elsif Nkind (Parent (Body_Decl)) = N_Subunit then
            Error_Pragma ("pragma % cannot apply to a subunit");
            return;
         end if;

         --  A refined pragma can only apply to the body [stub] of a subprogram
         --  declared in the visible part of a package. Retrieve the context of
         --  the subprogram declaration.

         Spec_Decl := Unit_Declaration_Node (Spec_Id);

         --  When dealing with protected entries or protected subprograms, use
         --  the enclosing protected type as the proper context.

         if Ekind (Spec_Id) in E_Entry
                             | E_Entry_Family
                             | E_Function
                             | E_Procedure
           and then Ekind (Scope (Spec_Id)) = E_Protected_Type
         then
            Spec_Decl := Declaration_Node (Scope (Spec_Id));
         end if;

         if Nkind (Parent (Spec_Decl)) /= N_Package_Specification then
            Error_Pragma
              (Fix_Msg (Spec_Id, "pragma % must apply to the body of "
               & "subprogram declared in a package specification"));
            return;
         end if;

         --  If we get here, then the pragma is legal

         Legal := True;

         --  A pragma that applies to a Ghost entity becomes Ghost for the
         --  purposes of legality checks and removal of ignored Ghost code.

         Mark_Ghost_Pragma (N, Spec_Id);

         if Pname in Name_Refined_Depends | Name_Refined_Global then
            Ensure_Aggregate_Form (Get_Argument (N, Spec_Id));
         end if;
      end Analyze_Refined_Depends_Global_Post;

      ----------------------------------
      -- Analyze_Unmodified_Or_Unused --
      ----------------------------------

      procedure Analyze_Unmodified_Or_Unused (Is_Unused : Boolean := False) is
         Arg      : Node_Id;
         Arg_Expr : Node_Id;
         Arg_Id   : Entity_Id;

         Ghost_Error_Posted : Boolean := False;
         --  Flag set when an error concerning the illegal mix of Ghost and
         --  non-Ghost variables is emitted.

         Ghost_Id : Entity_Id := Empty;
         --  The entity of the first Ghost variable encountered while
         --  processing the arguments of the pragma.

      begin
         GNAT_Pragma;
         Check_At_Least_N_Arguments (1);

         --  Loop through arguments

         Arg := Arg1;
         while Present (Arg) loop
            Check_No_Identifier (Arg);

            --  Note: the analyze call done by Check_Arg_Is_Local_Name will
            --  in fact generate reference, so that the entity will have a
            --  reference, which will inhibit any warnings about it not
            --  being referenced, and also properly show up in the ali file
            --  as a reference. But this reference is recorded before the
            --  Has_Pragma_Unreferenced flag is set, so that no warning is
            --  generated for this reference.

            Check_Arg_Is_Local_Name (Arg);
            Arg_Expr := Get_Pragma_Arg (Arg);

            if Is_Entity_Name (Arg_Expr) then
               Arg_Id := Entity (Arg_Expr);

               --  Skip processing the argument if already flagged

               if Is_Assignable (Arg_Id)
                 and then not Has_Pragma_Unmodified (Arg_Id)
                 and then not Has_Pragma_Unused (Arg_Id)
               then
                  Set_Has_Pragma_Unmodified (Arg_Id);

                  if Is_Unused then
                     Set_Has_Pragma_Unused (Arg_Id);
                  end if;

                  --  A pragma that applies to a Ghost entity becomes Ghost for
                  --  the purposes of legality checks and removal of ignored
                  --  Ghost code.

                  Mark_Ghost_Pragma (N, Arg_Id);

                  --  Capture the entity of the first Ghost variable being
                  --  processed for error detection purposes.

                  if Is_Ghost_Entity (Arg_Id) then
                     if No (Ghost_Id) then
                        Ghost_Id := Arg_Id;
                     end if;

                  --  Otherwise the variable is non-Ghost. It is illegal to mix
                  --  references to Ghost and non-Ghost entities
                  --  (SPARK RM 6.9).

                  elsif Present (Ghost_Id)
                    and then not Ghost_Error_Posted
                  then
                     Ghost_Error_Posted := True;

                     Error_Msg_Name_1 := Pname;
                     Error_Msg_N
                       ("pragma % cannot mention ghost and non-ghost "
                        & "variables", N);

                     Error_Msg_Sloc := Sloc (Ghost_Id);
                     Error_Msg_NE ("\& # declared as ghost", N, Ghost_Id);

                     Error_Msg_Sloc := Sloc (Arg_Id);
                     Error_Msg_NE ("\& # declared as non-ghost", N, Arg_Id);
                  end if;

               --  Warn if already flagged as Unused or Unmodified

               elsif Has_Pragma_Unmodified (Arg_Id) then
                  if Has_Pragma_Unused (Arg_Id) then
                     Error_Msg_NE
                       ("??pragma Unused already given for &!", Arg_Expr,
                         Arg_Id);
                  else
                     Error_Msg_NE
                       ("??pragma Unmodified already given for &!", Arg_Expr,
                         Arg_Id);
                  end if;

               --  Otherwise the pragma referenced an illegal entity

               else
                  Error_Pragma_Arg
                    ("pragma% can only be applied to a variable", Arg_Expr);
               end if;
            end if;

            Next (Arg);
         end loop;
      end Analyze_Unmodified_Or_Unused;

      ------------------------------------
      -- Analyze_Unreferenced_Or_Unused --
      ------------------------------------

      procedure Analyze_Unreferenced_Or_Unused
        (Is_Unused : Boolean := False)
      is
         Arg      : Node_Id;
         Arg_Expr : Node_Id;
         Arg_Id   : Entity_Id;
         Citem    : Node_Id;

         Ghost_Error_Posted : Boolean := False;
         --  Flag set when an error concerning the illegal mix of Ghost and
         --  non-Ghost names is emitted.

         Ghost_Id : Entity_Id := Empty;
         --  The entity of the first Ghost name encountered while processing
         --  the arguments of the pragma.

      begin
         GNAT_Pragma;
         Check_At_Least_N_Arguments (1);

         --  Check case of appearing within context clause

         if not Is_Unused and then Is_In_Context_Clause then

            --  The arguments must all be units mentioned in a with clause in
            --  the same context clause. Note that Par.Prag already checked
            --  that the arguments are either identifiers or selected
            --  components.

            Arg := Arg1;
            while Present (Arg) loop
               Citem := First (List_Containing (N));
               while Citem /= N loop
                  Arg_Expr := Get_Pragma_Arg (Arg);

                  if Nkind (Citem) = N_With_Clause
                    and then Same_Name (Name (Citem), Arg_Expr)
                  then
                     Set_Has_Pragma_Unreferenced
                       (Cunit_Entity
                         (Get_Source_Unit
                           (Library_Unit (Citem))));
                     Set_Elab_Unit_Name (Arg_Expr, Name (Citem));
                     exit;
                  end if;

                  Next (Citem);
               end loop;

               if Citem = N then
                  Error_Pragma_Arg
                    ("argument of pragma% is not withed unit", Arg);
               end if;

               Next (Arg);
            end loop;

         --  Case of not in list of context items

         else
            Arg := Arg1;
            while Present (Arg) loop
               Check_No_Identifier (Arg);

               --  Note: the analyze call done by Check_Arg_Is_Local_Name will
               --  in fact generate reference, so that the entity will have a
               --  reference, which will inhibit any warnings about it not
               --  being referenced, and also properly show up in the ali file
               --  as a reference. But this reference is recorded before the
               --  Has_Pragma_Unreferenced flag is set, so that no warning is
               --  generated for this reference.

               Check_Arg_Is_Local_Name (Arg);
               Arg_Expr := Get_Pragma_Arg (Arg);

               if Is_Entity_Name (Arg_Expr) then
                  Arg_Id := Entity (Arg_Expr);

                  --  Warn if already flagged as Unused or Unreferenced and
                  --  skip processing the argument.

                  if Has_Pragma_Unreferenced (Arg_Id) then
                     if Has_Pragma_Unused (Arg_Id) then
                        Error_Msg_NE
                          ("??pragma Unused already given for &!", Arg_Expr,
                            Arg_Id);
                     else
                        Error_Msg_NE
                          ("??pragma Unreferenced already given for &!",
                            Arg_Expr, Arg_Id);
                     end if;

                  --  Apply Unreferenced to the entity

                  else
                     --  If the entity is overloaded, the pragma applies to the
                     --  most recent overloading, as documented. In this case,
                     --  name resolution does not generate a reference, so it
                     --  must be done here explicitly.

                     if Is_Overloaded (Arg_Expr) then
                        Generate_Reference (Arg_Id, N);
                     end if;

                     Set_Has_Pragma_Unreferenced (Arg_Id);

                     if Is_Unused then
                        Set_Has_Pragma_Unused (Arg_Id);
                     end if;

                     --  A pragma that applies to a Ghost entity becomes Ghost
                     --  for the purposes of legality checks and removal of
                     --  ignored Ghost code.

                     Mark_Ghost_Pragma (N, Arg_Id);

                     --  Capture the entity of the first Ghost name being
                     --  processed for error detection purposes.

                     if Is_Ghost_Entity (Arg_Id) then
                        if No (Ghost_Id) then
                           Ghost_Id := Arg_Id;
                        end if;

                     --  Otherwise the name is non-Ghost. It is illegal to mix
                     --  references to Ghost and non-Ghost entities
                     --  (SPARK RM 6.9).

                     elsif Present (Ghost_Id)
                       and then not Ghost_Error_Posted
                     then
                        Ghost_Error_Posted := True;

                        Error_Msg_Name_1 := Pname;
                        Error_Msg_N
                          ("pragma % cannot mention ghost and non-ghost "
                           & "names", N);

                        Error_Msg_Sloc := Sloc (Ghost_Id);
                        Error_Msg_NE
                          ("\& # declared as ghost", N, Ghost_Id);

                        Error_Msg_Sloc := Sloc (Arg_Id);
                        Error_Msg_NE
                          ("\& # declared as non-ghost", N, Arg_Id);
                     end if;
                  end if;
               end if;

               Next (Arg);
            end loop;
         end if;
      end Analyze_Unreferenced_Or_Unused;

      --------------------------
      -- Check_Ada_83_Warning --
      --------------------------

      procedure Check_Ada_83_Warning is
      begin
         if Ada_Version = Ada_83 and then Comes_From_Source (N) then
            Error_Msg_N ("(Ada 83) pragma& is non-standard??", N);
         end if;
      end Check_Ada_83_Warning;

      ---------------------
      -- Check_Arg_Count --
      ---------------------

      procedure Check_Arg_Count (Required : Nat) is
      begin
         if Arg_Count /= Required then
            Error_Pragma ("wrong number of arguments for pragma%");
         end if;
      end Check_Arg_Count;

      --------------------------------
      -- Check_Arg_Is_External_Name --
      --------------------------------

      procedure Check_Arg_Is_External_Name (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         if Nkind (Argx) = N_Identifier then
            return;

         else
            Analyze_And_Resolve (Argx, Standard_String);

            if Is_OK_Static_Expression (Argx) then
               return;

            elsif Etype (Argx) = Any_Type then
               raise Pragma_Exit;

            --  An interesting special case, if we have a string literal and
            --  we are in Ada 83 mode, then we allow it even though it will
            --  not be flagged as static. This allows expected Ada 83 mode
            --  use of external names which are string literals, even though
            --  technically these are not static in Ada 83.

            elsif Ada_Version = Ada_83
              and then Nkind (Argx) = N_String_Literal
            then
               return;

            --  Here we have a real error (non-static expression)

            else
               Error_Msg_Name_1 := Pname;
               Flag_Non_Static_Expr
                 (Fix_Error ("argument for pragma% must be a identifier or "
                  & "static string expression!"), Argx);

               raise Pragma_Exit;
            end if;
         end if;
      end Check_Arg_Is_External_Name;

      -----------------------------
      -- Check_Arg_Is_Identifier --
      -----------------------------

      procedure Check_Arg_Is_Identifier (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);
      begin
         if Nkind (Argx) /= N_Identifier then
            Error_Pragma_Arg ("argument for pragma% must be identifier", Argx);
         end if;
      end Check_Arg_Is_Identifier;

      ----------------------------------
      -- Check_Arg_Is_Integer_Literal --
      ----------------------------------

      procedure Check_Arg_Is_Integer_Literal (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);
      begin
         if Nkind (Argx) /= N_Integer_Literal then
            Error_Pragma_Arg
              ("argument for pragma% must be integer literal", Argx);
         end if;
      end Check_Arg_Is_Integer_Literal;

      -------------------------------------------
      -- Check_Arg_Is_Library_Level_Local_Name --
      -------------------------------------------

      --  LOCAL_NAME ::=
      --    DIRECT_NAME
      --  | DIRECT_NAME'ATTRIBUTE_DESIGNATOR
      --  | library_unit_NAME

      procedure Check_Arg_Is_Library_Level_Local_Name (Arg : Node_Id) is
      begin
         Check_Arg_Is_Local_Name (Arg);

         --  If it came from an aspect, we want to give the error just as if it
         --  came from source.

         if not Is_Library_Level_Entity (Entity (Get_Pragma_Arg (Arg)))
           and then (Comes_From_Source (N)
                       or else Present (Corresponding_Aspect (Parent (Arg))))
         then
            Error_Pragma_Arg
              ("argument for pragma% must be library level entity", Arg);
         end if;
      end Check_Arg_Is_Library_Level_Local_Name;

      -----------------------------
      -- Check_Arg_Is_Local_Name --
      -----------------------------

      --  LOCAL_NAME ::=
      --    DIRECT_NAME
      --  | DIRECT_NAME'ATTRIBUTE_DESIGNATOR
      --  | library_unit_NAME

      procedure Check_Arg_Is_Local_Name (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         --  If this pragma came from an aspect specification, we don't want to
         --  check for this error, because that would cause spurious errors, in
         --  case a type is frozen in a scope more nested than the type. The
         --  aspect itself of course can't be anywhere but on the declaration
         --  itself.

         if Nkind (Arg) = N_Pragma_Argument_Association then
            if From_Aspect_Specification (Parent (Arg)) then
               return;
            end if;

         --  Arg is the Expression of an N_Pragma_Argument_Association

         else
            if From_Aspect_Specification (Parent (Parent (Arg))) then
               return;
            end if;
         end if;

         Analyze (Argx);

         if Nkind (Argx) not in N_Direct_Name
           and then (Nkind (Argx) /= N_Attribute_Reference
                      or else Present (Expressions (Argx))
                      or else Nkind (Prefix (Argx)) /= N_Identifier)
           and then (not Is_Entity_Name (Argx)
                      or else not Is_Compilation_Unit (Entity (Argx)))
         then
            Error_Pragma_Arg ("argument for pragma% must be local name", Argx);
         end if;

         --  No further check required if not an entity name

         if not Is_Entity_Name (Argx) then
            null;

         else
            declare
               OK   : Boolean;
               Ent  : constant Entity_Id := Entity (Argx);
               Scop : constant Entity_Id := Scope (Ent);

            begin
               --  Case of a pragma applied to a compilation unit: pragma must
               --  occur immediately after the program unit in the compilation.

               if Is_Compilation_Unit (Ent) then
                  declare
                     Decl : constant Node_Id := Unit_Declaration_Node (Ent);

                  begin
                     --  Case of pragma placed immediately after spec

                     if Parent (N) = Aux_Decls_Node (Parent (Decl)) then
                        OK := True;

                     --  Case of pragma placed immediately after body

                     elsif Nkind (Decl) = N_Subprogram_Declaration
                             and then Present (Corresponding_Body (Decl))
                     then
                        OK := Parent (N) =
                                Aux_Decls_Node
                                  (Parent (Unit_Declaration_Node
                                             (Corresponding_Body (Decl))));

                     --  All other cases are illegal

                     else
                        OK := False;
                     end if;
                  end;

               --  Special restricted placement rule from 10.2.1(11.8/2)

               elsif Is_Generic_Formal (Ent)
                       and then Prag_Id = Pragma_Preelaborable_Initialization
               then
                  OK := List_Containing (N) =
                          Generic_Formal_Declarations
                            (Unit_Declaration_Node (Scop));

               --  If this is an aspect applied to a subprogram body, the
               --  pragma is inserted in its declarative part.

               elsif From_Aspect_Specification (N)
                 and then Ent = Current_Scope
                 and then
                   Nkind (Unit_Declaration_Node (Ent)) = N_Subprogram_Body
               then
                  OK := True;

               --  If the aspect is a predicate (possibly others ???) and the
               --  context is a record type, this is a discriminant expression
               --  within a type declaration, that freezes the predicated
               --  subtype.

               elsif From_Aspect_Specification (N)
                 and then Prag_Id = Pragma_Predicate
                 and then Ekind (Current_Scope) = E_Record_Type
                 and then Scop = Scope (Current_Scope)
               then
                  OK := True;

               --  Default case, just check that the pragma occurs in the scope
               --  of the entity denoted by the name.

               else
                  OK := Current_Scope = Scop;
               end if;

               if not OK then
                  Error_Pragma_Arg
                    ("pragma% argument must be in same declarative part", Arg);
               end if;
            end;
         end if;
      end Check_Arg_Is_Local_Name;

      ---------------------------------
      -- Check_Arg_Is_Locking_Policy --
      ---------------------------------

      procedure Check_Arg_Is_Locking_Policy (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if not Is_Locking_Policy_Name (Chars (Argx)) then
            Error_Pragma_Arg ("& is not a valid locking policy name", Argx);
         end if;
      end Check_Arg_Is_Locking_Policy;

      -----------------------------------------------
      -- Check_Arg_Is_Partition_Elaboration_Policy --
      -----------------------------------------------

      procedure Check_Arg_Is_Partition_Elaboration_Policy (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if not Is_Partition_Elaboration_Policy_Name (Chars (Argx)) then
            Error_Pragma_Arg
              ("& is not a valid partition elaboration policy name", Argx);
         end if;
      end Check_Arg_Is_Partition_Elaboration_Policy;

      -------------------------
      -- Check_Arg_Is_One_Of --
      -------------------------

      procedure Check_Arg_Is_One_Of (Arg : Node_Id; N1, N2 : Name_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if Chars (Argx) not in N1 | N2 then
            Error_Msg_Name_2 := N1;
            Error_Msg_Name_3 := N2;
            Error_Pragma_Arg ("argument for pragma% must be% or%", Argx);
         end if;
      end Check_Arg_Is_One_Of;

      procedure Check_Arg_Is_One_Of
        (Arg        : Node_Id;
         N1, N2, N3 : Name_Id)
      is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if Chars (Argx) not in N1 | N2 | N3 then
            Error_Pragma_Arg ("invalid argument for pragma%", Argx);
         end if;
      end Check_Arg_Is_One_Of;

      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2, N3, N4     : Name_Id)
      is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if Chars (Argx) not in N1 | N2 | N3 | N4 then
            Error_Pragma_Arg ("invalid argument for pragma%", Argx);
         end if;
      end Check_Arg_Is_One_Of;

      procedure Check_Arg_Is_One_Of
        (Arg                : Node_Id;
         N1, N2, N3, N4, N5 : Name_Id)
      is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if Chars (Argx) not in N1 | N2 | N3 | N4 | N5 then
            Error_Pragma_Arg ("invalid argument for pragma%", Argx);
         end if;
      end Check_Arg_Is_One_Of;

      ---------------------------------
      -- Check_Arg_Is_Queuing_Policy --
      ---------------------------------

      procedure Check_Arg_Is_Queuing_Policy (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if not Is_Queuing_Policy_Name (Chars (Argx)) then
            Error_Pragma_Arg ("& is not a valid queuing policy name", Argx);
         end if;
      end Check_Arg_Is_Queuing_Policy;

      ---------------------------------------
      -- Check_Arg_Is_OK_Static_Expression --
      ---------------------------------------

      procedure Check_Arg_Is_OK_Static_Expression
        (Arg : Node_Id;
         Typ : Entity_Id := Empty)
      is
      begin
         Check_Expr_Is_OK_Static_Expression (Get_Pragma_Arg (Arg), Typ);
      end Check_Arg_Is_OK_Static_Expression;

      ------------------------------------------
      -- Check_Arg_Is_Task_Dispatching_Policy --
      ------------------------------------------

      procedure Check_Arg_Is_Task_Dispatching_Policy (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         Check_Arg_Is_Identifier (Argx);

         if not Is_Task_Dispatching_Policy_Name (Chars (Argx)) then
            Error_Pragma_Arg
              ("& is not an allowed task dispatching policy name", Argx);
         end if;
      end Check_Arg_Is_Task_Dispatching_Policy;

      ---------------------
      -- Check_Arg_Order --
      ---------------------

      procedure Check_Arg_Order (Names : Name_List) is
         Arg : Node_Id;

         Highest_So_Far : Natural := 0;
         --  Highest index in Names seen do far

      begin
         Arg := Arg1;
         for J in 1 .. Arg_Count loop
            if Chars (Arg) /= No_Name then
               for K in Names'Range loop
                  if Chars (Arg) = Names (K) then
                     if K < Highest_So_Far then
                        Error_Msg_Name_1 := Pname;
                        Error_Msg_N
                          ("parameters out of order for pragma%", Arg);
                        Error_Msg_Name_1 := Names (K);
                        Error_Msg_Name_2 := Names (Highest_So_Far);
                        Error_Msg_N ("\% must appear before %", Arg);
                        raise Pragma_Exit;

                     else
                        Highest_So_Far := K;
                     end if;
                  end if;
               end loop;
            end if;

            Arg := Next (Arg);
         end loop;
      end Check_Arg_Order;

      --------------------------------
      -- Check_At_Least_N_Arguments --
      --------------------------------

      procedure Check_At_Least_N_Arguments (N : Nat) is
      begin
         if Arg_Count < N then
            Error_Pragma ("too few arguments for pragma%");
         end if;
      end Check_At_Least_N_Arguments;

      -------------------------------
      -- Check_At_Most_N_Arguments --
      -------------------------------

      procedure Check_At_Most_N_Arguments (N : Nat) is
         Arg : Node_Id;
      begin
         if Arg_Count > N then
            Arg := Arg1;
            for J in 1 .. N loop
               Next (Arg);
               Error_Pragma_Arg ("too many arguments for pragma%", Arg);
            end loop;
         end if;
      end Check_At_Most_N_Arguments;

      ---------------------
      -- Check_Component --
      ---------------------

      procedure Check_Component
        (Comp            : Node_Id;
         UU_Typ          : Entity_Id;
         In_Variant_Part : Boolean := False)
      is
         Comp_Id : constant Entity_Id := Defining_Identifier (Comp);
         Sindic  : constant Node_Id :=
                     Subtype_Indication (Component_Definition (Comp));
         Typ     : constant Entity_Id := Etype (Comp_Id);

      begin
         --  Ada 2005 (AI-216): If a component subtype is subject to a per-
         --  object constraint, then the component type shall be an Unchecked_
         --  Union.

         if Nkind (Sindic) = N_Subtype_Indication
           and then Has_Per_Object_Constraint (Comp_Id)
           and then not Is_Unchecked_Union (Etype (Subtype_Mark (Sindic)))
         then
            Error_Msg_N
              ("component subtype subject to per-object constraint "
               & "must be an Unchecked_Union", Comp);

         --  Ada 2012 (AI05-0026): For an unchecked union type declared within
         --  the body of a generic unit, or within the body of any of its
         --  descendant library units, no part of the type of a component
         --  declared in a variant_part of the unchecked union type shall be of
         --  a formal private type or formal private extension declared within
         --  the formal part of the generic unit.

         elsif Ada_Version >= Ada_2012
           and then In_Generic_Body (UU_Typ)
           and then In_Variant_Part
           and then Is_Private_Type (Typ)
           and then Is_Generic_Type (Typ)
         then
            Error_Msg_N
              ("component of unchecked union cannot be of generic type", Comp);

         elsif Needs_Finalization (Typ) then
            Error_Msg_N
              ("component of unchecked union cannot be controlled", Comp);

         elsif Has_Task (Typ) then
            Error_Msg_N
              ("component of unchecked union cannot have tasks", Comp);
         end if;
      end Check_Component;

      ----------------------------
      -- Check_Duplicate_Pragma --
      ----------------------------

      procedure Check_Duplicate_Pragma (E : Entity_Id) is
         Id : Entity_Id := E;
         P  : Node_Id;

      begin
         --  Nothing to do if this pragma comes from an aspect specification,
         --  since we could not be duplicating a pragma, and we dealt with the
         --  case of duplicated aspects in Analyze_Aspect_Specifications.

         if From_Aspect_Specification (N) then
            return;
         end if;

         --  Otherwise current pragma may duplicate previous pragma or a
         --  previously given aspect specification or attribute definition
         --  clause for the same pragma.

         P := Get_Rep_Item (E, Pragma_Name (N), Check_Parents => False);

         if Present (P) then

            --  If the entity is a type, then we have to make sure that the
            --  ostensible duplicate is not for a parent type from which this
            --  type is derived.

            if Is_Type (E) then
               if Nkind (P) = N_Pragma then
                  declare
                     Args : constant List_Id :=
                              Pragma_Argument_Associations (P);
                  begin
                     if Present (Args)
                       and then Is_Entity_Name (Expression (First (Args)))
                       and then Is_Type (Entity (Expression (First (Args))))
                       and then Entity (Expression (First (Args))) /= E
                     then
                        return;
                     end if;
                  end;

               elsif Nkind (P) = N_Aspect_Specification
                 and then Is_Type (Entity (P))
                 and then Entity (P) /= E
               then
                  return;
               end if;
            end if;

            --  Here we have a definite duplicate

            Error_Msg_Name_1 := Pragma_Name (N);
            Error_Msg_Sloc := Sloc (P);

            --  For a single protected or a single task object, the error is
            --  issued on the original entity.

            if Ekind (Id) in E_Task_Type | E_Protected_Type then
               Id := Defining_Identifier (Original_Node (Parent (Id)));
            end if;

            if Nkind (P) = N_Aspect_Specification
              or else From_Aspect_Specification (P)
            then
               Error_Msg_NE ("aspect% for & previously given#", N, Id);
            else
               --  If -gnatwr is set, warn in case of a duplicate pragma
               --  [No_]Inline which is suspicious but not an error, generate
               --  an error for other pragmas.

               if Pragma_Name (N) in Name_Inline | Name_No_Inline then
                  if Warn_On_Redundant_Constructs then
                     Error_Msg_NE
                       ("?r?pragma% for & duplicates pragma#", N, Id);
                  end if;
               else
                  Error_Msg_NE ("pragma% for & duplicates pragma#", N, Id);
               end if;
            end if;

            raise Pragma_Exit;
         end if;
      end Check_Duplicate_Pragma;

      ----------------------------------
      -- Check_Duplicated_Export_Name --
      ----------------------------------

      procedure Check_Duplicated_Export_Name (Nam : Node_Id) is
         String_Val : constant String_Id := Strval (Nam);

      begin
         --  We are only interested in the export case, and in the case of
         --  generics, it is the instance, not the template, that is the
         --  problem (the template will generate a warning in any case).

         if not Inside_A_Generic
           and then (Prag_Id = Pragma_Export
                       or else
                     Prag_Id = Pragma_Export_Procedure
                       or else
                     Prag_Id = Pragma_Export_Valued_Procedure
                       or else
                     Prag_Id = Pragma_Export_Function)
         then
            for J in Externals.First .. Externals.Last loop
               if String_Equal (String_Val, Strval (Externals.Table (J))) then
                  Error_Msg_Sloc := Sloc (Externals.Table (J));
                  Error_Msg_N ("external name duplicates name given#", Nam);
                  exit;
               end if;
            end loop;

            Externals.Append (Nam);
         end if;
      end Check_Duplicated_Export_Name;

      ----------------------------------------
      -- Check_Expr_Is_OK_Static_Expression --
      ----------------------------------------

      procedure Check_Expr_Is_OK_Static_Expression
        (Expr : Node_Id;
         Typ  : Entity_Id := Empty)
      is
      begin
         if Present (Typ) then
            Analyze_And_Resolve (Expr, Typ);
         else
            Analyze_And_Resolve (Expr);
         end if;

         --  An expression cannot be considered static if its resolution failed
         --  or if it's erroneous. Stop the analysis of the related pragma.

         if Etype (Expr) = Any_Type or else Error_Posted (Expr) then
            raise Pragma_Exit;

         elsif Is_OK_Static_Expression (Expr) then
            return;

         --  An interesting special case, if we have a string literal and we
         --  are in Ada 83 mode, then we allow it even though it will not be
         --  flagged as static. This allows the use of Ada 95 pragmas like
         --  Import in Ada 83 mode. They will of course be flagged with
         --  warnings as usual, but will not cause errors.

         elsif Ada_Version = Ada_83
           and then Nkind (Expr) = N_String_Literal
         then
            return;

         --  Finally, we have a real error

         else
            Error_Msg_Name_1 := Pname;
            Flag_Non_Static_Expr
              (Fix_Error ("argument for pragma% must be a static expression!"),
               Expr);
            raise Pragma_Exit;
         end if;
      end Check_Expr_Is_OK_Static_Expression;

      -------------------------
      -- Check_First_Subtype --
      -------------------------

      procedure Check_First_Subtype (Arg : Node_Id) is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);
         Ent  : constant Entity_Id := Entity (Argx);

      begin
         if Is_First_Subtype (Ent) then
            null;

         elsif Is_Type (Ent) then
            Error_Pragma_Arg
              ("pragma% cannot apply to subtype", Argx);

         elsif Is_Object (Ent) then
            Error_Pragma_Arg
              ("pragma% cannot apply to object, requires a type", Argx);

         else
            Error_Pragma_Arg
              ("pragma% cannot apply to&, requires a type", Argx);
         end if;
      end Check_First_Subtype;

      ----------------------
      -- Check_Identifier --
      ----------------------

      procedure Check_Identifier (Arg : Node_Id; Id : Name_Id) is
      begin
         if Present (Arg)
           and then Nkind (Arg) = N_Pragma_Argument_Association
         then
            if Chars (Arg) = No_Name or else Chars (Arg) /= Id then
               Error_Msg_Name_1 := Pname;
               Error_Msg_Name_2 := Id;
               Error_Msg_N ("pragma% argument expects identifier%", Arg);
               raise Pragma_Exit;
            end if;
         end if;
      end Check_Identifier;

      --------------------------------
      -- Check_Identifier_Is_One_Of --
      --------------------------------

      procedure Check_Identifier_Is_One_Of (Arg : Node_Id; N1, N2 : Name_Id) is
      begin
         if Present (Arg)
           and then Nkind (Arg) = N_Pragma_Argument_Association
         then
            if Chars (Arg) = No_Name then
               Error_Msg_Name_1 := Pname;
               Error_Msg_N ("pragma% argument expects an identifier", Arg);
               raise Pragma_Exit;

            elsif Chars (Arg) /= N1
              and then Chars (Arg) /= N2
            then
               Error_Msg_Name_1 := Pname;
               Error_Msg_N ("invalid identifier for pragma% argument", Arg);
               raise Pragma_Exit;
            end if;
         end if;
      end Check_Identifier_Is_One_Of;

      ---------------------------
      -- Check_In_Main_Program --
      ---------------------------

      procedure Check_In_Main_Program is
         P : constant Node_Id := Parent (N);

      begin
         --  Must be in subprogram body

         if Nkind (P) /= N_Subprogram_Body then
            Error_Pragma ("% pragma allowed only in subprogram");

         --  Otherwise warn if obviously not main program

         elsif Present (Parameter_Specifications (Specification (P)))
           or else not Is_Compilation_Unit (Defining_Entity (P))
         then
            Error_Msg_Name_1 := Pname;
            Error_Msg_N
              ("??pragma% is only effective in main program", N);
         end if;
      end Check_In_Main_Program;

      ---------------------------------------
      -- Check_Interrupt_Or_Attach_Handler --
      ---------------------------------------

      procedure Check_Interrupt_Or_Attach_Handler is
         Arg1_X : constant Node_Id := Get_Pragma_Arg (Arg1);
         Handler_Proc, Proc_Scope : Entity_Id;

      begin
         Analyze (Arg1_X);

         if Prag_Id = Pragma_Interrupt_Handler then
            Check_Restriction (No_Dynamic_Attachment, N);
         end if;

         Handler_Proc := Find_Unique_Parameterless_Procedure (Arg1_X, Arg1);
         Proc_Scope := Scope (Handler_Proc);

         if Ekind (Proc_Scope) /= E_Protected_Type then
            Error_Pragma_Arg
              ("argument of pragma% must be protected procedure", Arg1);
         end if;

         --  For pragma case (as opposed to access case), check placement.
         --  We don't need to do that for aspects, because we have the
         --  check that they aspect applies an appropriate procedure.

         if not From_Aspect_Specification (N)
           and then Parent (N) /= Protected_Definition (Parent (Proc_Scope))
         then
            Error_Pragma ("pragma% must be in protected definition");
         end if;

         if not Is_Library_Level_Entity (Proc_Scope) then
            Error_Pragma_Arg
              ("argument for pragma% must be library level entity", Arg1);
         end if;

         --  AI05-0033: A pragma cannot appear within a generic body, because
         --  instance can be in a nested scope. The check that protected type
         --  is itself a library-level declaration is done elsewhere.

         --  Note: we omit this check in Relaxed_RM_Semantics mode to properly
         --  handle code prior to AI-0033. Analysis tools typically are not
         --  interested in this pragma in any case, so no need to worry too
         --  much about its placement.

         if Inside_A_Generic then
            if Ekind (Scope (Current_Scope)) = E_Generic_Package
              and then In_Package_Body (Scope (Current_Scope))
              and then not Relaxed_RM_Semantics
            then
               Error_Pragma ("pragma% cannot be used inside a generic");
            end if;
         end if;
      end Check_Interrupt_Or_Attach_Handler;

      ---------------------------------
      -- Check_Loop_Pragma_Placement --
      ---------------------------------

      procedure Check_Loop_Pragma_Placement is
         procedure Check_Loop_Pragma_Grouping (Loop_Stmt : Node_Id);
         --  Verify whether the current pragma is properly grouped with other
         --  pragma Loop_Invariant and/or Loop_Variant. Node Loop_Stmt is the
         --  related loop where the pragma appears.

         function Is_Loop_Pragma (Stmt : Node_Id) return Boolean;
         --  Determine whether an arbitrary statement Stmt denotes pragma
         --  Loop_Invariant or Loop_Variant.

         procedure Placement_Error (Constr : Node_Id);
         pragma No_Return (Placement_Error);
         --  Node Constr denotes the last loop restricted construct before we
         --  encountered an illegal relation between enclosing constructs. Emit
         --  an error depending on what Constr was.

         --------------------------------
         -- Check_Loop_Pragma_Grouping --
         --------------------------------

         procedure Check_Loop_Pragma_Grouping (Loop_Stmt : Node_Id) is
            Stop_Search : exception;
            --  This exception is used to terminate the recursive descent of
            --  routine Check_Grouping.

            procedure Check_Grouping (L : List_Id);
            --  Find the first group of pragmas in list L and if successful,
            --  ensure that the current pragma is part of that group. The
            --  routine raises Stop_Search once such a check is performed to
            --  halt the recursive descent.

            procedure Grouping_Error (Prag : Node_Id);
            pragma No_Return (Grouping_Error);
            --  Emit an error concerning the current pragma indicating that it
            --  should be placed after pragma Prag.

            --------------------
            -- Check_Grouping --
            --------------------

            procedure Check_Grouping (L : List_Id) is
               HSS  : Node_Id;
               Stmt : Node_Id;
               Prag : Node_Id := Empty; -- init to avoid warning

            begin
               --  Inspect the list of declarations or statements looking for
               --  the first grouping of pragmas:

               --    loop
               --       pragma Loop_Invariant ...;
               --       pragma Loop_Variant ...;
               --       . . .                     -- (1)
               --       pragma Loop_Variant ...;  --  current pragma

               --  If the current pragma is not in the grouping, then it must
               --  either appear in a different declarative or statement list
               --  or the construct at (1) is separating the pragma from the
               --  grouping.

               Stmt := First (L);
               while Present (Stmt) loop

                  --  First pragma of the first topmost grouping has been found

                  if Is_Loop_Pragma (Stmt) then

                     --  The group and the current pragma are not in the same
                     --  declarative or statement list.

                     if not In_Same_List (Stmt, N) then
                        Grouping_Error (Stmt);

                     --  Try to reach the current pragma from the first pragma
                     --  of the grouping while skipping other members:

                     --    pragma Loop_Invariant ...;  --  first pragma
                     --    pragma Loop_Variant ...;    --  member
                     --    . . .
                     --    pragma Loop_Variant ...;    --  current pragma

                     else
                        while Present (Stmt) loop
                           --  The current pragma is either the first pragma
                           --  of the group or is a member of the group.
                           --  Stop the search as the placement is legal.

                           if Stmt = N then
                              raise Stop_Search;

                           --  Skip group members, but keep track of the
                           --  last pragma in the group.

                           elsif Is_Loop_Pragma (Stmt) then
                              Prag := Stmt;

                           --  Skip declarations and statements generated by
                           --  the compiler during expansion. Note that some
                           --  source statements (e.g. pragma Assert) may have
                           --  been transformed so that they do not appear as
                           --  coming from source anymore, so we instead look
                           --  at their Original_Node.

                           elsif not Comes_From_Source (Original_Node (Stmt))
                           then
                              null;

                           --  A non-pragma is separating the group from the
                           --  current pragma, the placement is illegal.

                           else
                              Grouping_Error (Prag);
                           end if;

                           Next (Stmt);
                        end loop;

                        --  If the traversal did not reach the current pragma,
                        --  then the list must be malformed.

                        raise Program_Error;
                     end if;

                  --  Pragmas Loop_Invariant and Loop_Variant may only appear
                  --  inside a loop or a block housed inside a loop. Inspect
                  --  the declarations and statements of the block as they may
                  --  contain the first grouping. This case follows the one for
                  --  loop pragmas, as block statements which originate in a
                  --  loop pragma (and so Is_Loop_Pragma will return True on
                  --  that block statement) should be treated in the previous
                  --  case.

                  elsif Nkind (Stmt) = N_Block_Statement then
                     HSS := Handled_Statement_Sequence (Stmt);

                     Check_Grouping (Declarations (Stmt));

                     if Present (HSS) then
                        Check_Grouping (Statements (HSS));
                     end if;
                  end if;

                  Next (Stmt);
               end loop;
            end Check_Grouping;

            --------------------
            -- Grouping_Error --
            --------------------

            procedure Grouping_Error (Prag : Node_Id) is
            begin
               Error_Msg_Sloc := Sloc (Prag);
               Error_Pragma ("pragma% must appear next to pragma#");
            end Grouping_Error;

         --  Start of processing for Check_Loop_Pragma_Grouping

         begin
            --  Inspect the statements of the loop or nested blocks housed
            --  within to determine whether the current pragma is part of the
            --  first topmost grouping of Loop_Invariant and Loop_Variant.

            Check_Grouping (Statements (Loop_Stmt));

         exception
            when Stop_Search => null;
         end Check_Loop_Pragma_Grouping;

         --------------------
         -- Is_Loop_Pragma --
         --------------------

         function Is_Loop_Pragma (Stmt : Node_Id) return Boolean is
            Original_Stmt : constant Node_Id := Original_Node (Stmt);

         begin
            --  Inspect the original node as Loop_Invariant and Loop_Variant
            --  pragmas are rewritten to null when assertions are disabled.

            return Nkind (Original_Stmt) = N_Pragma
             and then Pragma_Name_Unmapped (Original_Stmt)
                   in Name_Loop_Invariant | Name_Loop_Variant;
         end Is_Loop_Pragma;

         ---------------------
         -- Placement_Error --
         ---------------------

         procedure Placement_Error (Constr : Node_Id) is
            LA : constant String := " with Loop_Entry";

         begin
            if Prag_Id = Pragma_Assert then
               Error_Msg_String (1 .. LA'Length) := LA;
               Error_Msg_Strlen := LA'Length;
            else
               Error_Msg_Strlen := 0;
            end if;

            if Nkind (Constr) = N_Pragma then
               Error_Pragma
                 ("pragma %~ must appear immediately within the statements "
                  & "of a loop");
            else
               Error_Pragma_Arg
                 ("block containing pragma %~ must appear immediately within "
                  & "the statements of a loop", Constr);
            end if;
         end Placement_Error;

         --  Local declarations

         Prev : Node_Id;
         Stmt : Node_Id;

      --  Start of processing for Check_Loop_Pragma_Placement

      begin
         --  Check that pragma appears immediately within a loop statement,
         --  ignoring intervening block statements.

         Prev := N;
         Stmt := Parent (N);
         while Present (Stmt) loop

            --  The pragma or previous block must appear immediately within the
            --  current block's declarative or statement part.

            if Nkind (Stmt) = N_Block_Statement then
               if (No (Declarations (Stmt))
                    or else List_Containing (Prev) /= Declarations (Stmt))
                 and then
                   List_Containing (Prev) /=
                     Statements (Handled_Statement_Sequence (Stmt))
               then
                  Placement_Error (Prev);
                  return;

               --  Keep inspecting the parents because we are now within a
               --  chain of nested blocks.

               else
                  Prev := Stmt;
                  Stmt := Parent (Stmt);
               end if;

            --  The pragma or previous block must appear immediately within the
            --  statements of the loop.

            elsif Nkind (Stmt) = N_Loop_Statement then
               if List_Containing (Prev) /= Statements (Stmt) then
                  Placement_Error (Prev);
               end if;

               --  Stop the traversal because we reached the innermost loop
               --  regardless of whether we encountered an error or not.

               exit;

            --  Ignore a handled statement sequence. Note that this node may
            --  be related to a subprogram body in which case we will emit an
            --  error on the next iteration of the search.

            elsif Nkind (Stmt) = N_Handled_Sequence_Of_Statements then
               Stmt := Parent (Stmt);

            --  Any other statement breaks the chain from the pragma to the
            --  loop.

            else
               Placement_Error (Prev);
               return;
            end if;
         end loop;

         --  Check that the current pragma Loop_Invariant or Loop_Variant is
         --  grouped together with other such pragmas.

         if Is_Loop_Pragma (N) then

            --  The previous check should have located the related loop

            pragma Assert (Nkind (Stmt) = N_Loop_Statement);
            Check_Loop_Pragma_Grouping (Stmt);
         end if;
      end Check_Loop_Pragma_Placement;

      -------------------------------------------
      -- Check_Is_In_Decl_Part_Or_Package_Spec --
      -------------------------------------------

      procedure Check_Is_In_Decl_Part_Or_Package_Spec is
         P : Node_Id;

      begin
         P := Parent (N);
         loop
            if No (P) then
               exit;

            elsif Nkind (P) = N_Handled_Sequence_Of_Statements then
               exit;

            elsif Nkind (P) in N_Package_Specification | N_Block_Statement then
               return;

            --  Note: the following tests seem a little peculiar, because
            --  they test for bodies, but if we were in the statement part
            --  of the body, we would already have hit the handled statement
            --  sequence, so the only way we get here is by being in the
            --  declarative part of the body.

            elsif Nkind (P) in
              N_Subprogram_Body | N_Package_Body | N_Task_Body | N_Entry_Body
            then
               return;
            end if;

            P := Parent (P);
         end loop;

         Error_Pragma ("pragma% is not in declarative part or package spec");
      end Check_Is_In_Decl_Part_Or_Package_Spec;

      -------------------------
      -- Check_No_Identifier --
      -------------------------

      procedure Check_No_Identifier (Arg : Node_Id) is
      begin
         if Nkind (Arg) = N_Pragma_Argument_Association
           and then Chars (Arg) /= No_Name
         then
            Error_Pragma_Arg_Ident
              ("pragma% does not permit identifier& here", Arg);
         end if;
      end Check_No_Identifier;

      --------------------------
      -- Check_No_Identifiers --
      --------------------------

      procedure Check_No_Identifiers is
         Arg_Node : Node_Id;
      begin
         Arg_Node := Arg1;
         for J in 1 .. Arg_Count loop
            Check_No_Identifier (Arg_Node);
            Next (Arg_Node);
         end loop;
      end Check_No_Identifiers;

      ------------------------
      -- Check_No_Link_Name --
      ------------------------

      procedure Check_No_Link_Name is
      begin
         if Present (Arg3) and then Chars (Arg3) = Name_Link_Name then
            Arg4 := Arg3;
         end if;

         if Present (Arg4) then
            Error_Pragma_Arg
              ("Link_Name argument not allowed for Import Intrinsic", Arg4);
         end if;
      end Check_No_Link_Name;

      -------------------------------
      -- Check_Optional_Identifier --
      -------------------------------

      procedure Check_Optional_Identifier (Arg : Node_Id; Id : Name_Id) is
      begin
         if Present (Arg)
           and then Nkind (Arg) = N_Pragma_Argument_Association
           and then Chars (Arg) /= No_Name
         then
            if Chars (Arg) /= Id then
               Error_Msg_Name_1 := Pname;
               Error_Msg_Name_2 := Id;
               Error_Msg_N ("pragma% argument expects identifier%", Arg);
               raise Pragma_Exit;
            end if;
         end if;
      end Check_Optional_Identifier;

      procedure Check_Optional_Identifier (Arg : Node_Id; Id : String) is
      begin
         Check_Optional_Identifier (Arg, Name_Find (Id));
      end Check_Optional_Identifier;

      -------------------------------------
      -- Check_Static_Boolean_Expression --
      -------------------------------------

      procedure Check_Static_Boolean_Expression (Expr : Node_Id) is
      begin
         if Present (Expr) then
            Analyze_And_Resolve (Expr, Standard_Boolean);

            if not Is_OK_Static_Expression (Expr) then
               Error_Pragma_Arg
                 ("expression of pragma % must be static", Expr);
            end if;
         end if;
      end Check_Static_Boolean_Expression;

      -----------------------------
      -- Check_Static_Constraint --
      -----------------------------

      procedure Check_Static_Constraint (Constr : Node_Id) is

         procedure Require_Static (E : Node_Id);
         --  Require given expression to be static expression

         --------------------
         -- Require_Static --
         --------------------

         procedure Require_Static (E : Node_Id) is
         begin
            if not Is_OK_Static_Expression (E) then
               Flag_Non_Static_Expr
                 ("non-static constraint not allowed in Unchecked_Union!", E);
               raise Pragma_Exit;
            end if;
         end Require_Static;

      --  Start of processing for Check_Static_Constraint

      begin
         case Nkind (Constr) is
            when N_Discriminant_Association =>
               Require_Static (Expression (Constr));

            when N_Range =>
               Require_Static (Low_Bound (Constr));
               Require_Static (High_Bound (Constr));

            when N_Attribute_Reference =>
               Require_Static (Type_Low_Bound  (Etype (Prefix (Constr))));
               Require_Static (Type_High_Bound (Etype (Prefix (Constr))));

            when N_Range_Constraint =>
               Check_Static_Constraint (Range_Expression (Constr));

            when N_Index_Or_Discriminant_Constraint =>
               declare
                  IDC : Entity_Id;
               begin
                  IDC := First (Constraints (Constr));
                  while Present (IDC) loop
                     Check_Static_Constraint (IDC);
                     Next (IDC);
                  end loop;
               end;

            when others =>
               null;
         end case;
      end Check_Static_Constraint;

      --------------------------------------
      -- Check_Valid_Configuration_Pragma --
      --------------------------------------

      --  A configuration pragma must appear in the context clause of a
      --  compilation unit, and only other pragmas may precede it. Note that
      --  the test also allows use in a configuration pragma file.

      procedure Check_Valid_Configuration_Pragma is
      begin
         if not Is_Configuration_Pragma then
            Error_Pragma ("incorrect placement for configuration pragma%");
         end if;
      end Check_Valid_Configuration_Pragma;

      -------------------------------------
      -- Check_Valid_Library_Unit_Pragma --
      -------------------------------------

      procedure Check_Valid_Library_Unit_Pragma is
         Plist       : List_Id;
         Parent_Node : Node_Id;
         Unit_Name   : Entity_Id;
         Unit_Kind   : Node_Kind;
         Unit_Node   : Node_Id;
         Sindex      : Source_File_Index;

      begin
         if not Is_List_Member (N) then
            Pragma_Misplaced;

         else
            Plist := List_Containing (N);
            Parent_Node := Parent (Plist);

            if Parent_Node = Empty then
               Pragma_Misplaced;

            --  Case of pragma appearing after a compilation unit. In this case
            --  it must have an argument with the corresponding name and must
            --  be part of the following pragmas of its parent.

            elsif Nkind (Parent_Node) = N_Compilation_Unit_Aux then
               if Plist /= Pragmas_After (Parent_Node) then
                  Pragma_Misplaced;

               elsif Arg_Count = 0 then
                  Error_Pragma
                    ("argument required if outside compilation unit");

               else
                  Check_No_Identifiers;
                  Check_Arg_Count (1);
                  Unit_Node := Unit (Parent (Parent_Node));
                  Unit_Kind := Nkind (Unit_Node);

                  Analyze (Get_Pragma_Arg (Arg1));

                  if Unit_Kind = N_Generic_Subprogram_Declaration
                    or else Unit_Kind = N_Subprogram_Declaration
                  then
                     Unit_Name := Defining_Entity (Unit_Node);

                  elsif Unit_Kind in N_Generic_Instantiation then
                     Unit_Name := Defining_Entity (Unit_Node);

                  else
                     Unit_Name := Cunit_Entity (Current_Sem_Unit);
                  end if;

                  if Chars (Unit_Name) /=
                     Chars (Entity (Get_Pragma_Arg (Arg1)))
                  then
                     Error_Pragma_Arg
                       ("pragma% argument is not current unit name", Arg1);
                  end if;

                  if Ekind (Unit_Name) = E_Package
                    and then Present (Renamed_Entity (Unit_Name))
                  then
                     Error_Pragma ("pragma% not allowed for renamed package");
                  end if;
               end if;

            --  Pragma appears other than after a compilation unit

            else
               --  Here we check for the generic instantiation case and also
               --  for the case of processing a generic formal package. We
               --  detect these cases by noting that the Sloc on the node
               --  does not belong to the current compilation unit.

               Sindex := Source_Index (Current_Sem_Unit);

               if Loc not in Source_First (Sindex) .. Source_Last (Sindex) then
                  --  We do not want to raise an exception here since this code
                  --  is part of the bootstrap path where we cannot rely on
                  --  exception proapgation working.
                  --  Instead the caller should check for N being rewritten as
                  --  a null statement.
                  --  This code triggers when compiling a-except.adb.

                  Rewrite (N, Make_Null_Statement (Loc));

               --  If before first declaration, the pragma applies to the
               --  enclosing unit, and the name if present must be this name.

               elsif Is_Before_First_Decl (N, Plist) then
                  Unit_Node := Unit_Declaration_Node (Current_Scope);
                  Unit_Kind := Nkind (Unit_Node);

                  if Nkind (Parent (Unit_Node)) /= N_Compilation_Unit then
                     Pragma_Misplaced;

                  elsif Unit_Kind = N_Subprogram_Body
                    and then not Acts_As_Spec (Unit_Node)
                  then
                     Pragma_Misplaced;

                  elsif Nkind (Parent_Node) = N_Package_Body then
                     Pragma_Misplaced;

                  elsif Nkind (Parent_Node) = N_Package_Specification
                    and then Plist = Private_Declarations (Parent_Node)
                  then
                     Pragma_Misplaced;

                  elsif Nkind (Parent_Node) in N_Generic_Declaration
                    and then Plist = Generic_Formal_Declarations (Parent_Node)
                  then
                     Pragma_Misplaced;

                  elsif Arg_Count > 0 then
                     Analyze (Get_Pragma_Arg (Arg1));

                     if Entity (Get_Pragma_Arg (Arg1)) /= Current_Scope then
                        Error_Pragma_Arg
                          ("name in pragma% must be enclosing unit", Arg1);
                     end if;

                  --  It is legal to have no argument in this context

                  else
                     return;
                  end if;

               --  Error if not before first declaration. This is because a
               --  library unit pragma argument must be the name of a library
               --  unit (RM 10.1.5(7)), but the only names permitted in this
               --  context are (RM 10.1.5(6)) names of subprogram declarations,
               --  generic subprogram declarations or generic instantiations.

               else
                  Error_Pragma
                    ("pragma% misplaced, must be before first declaration");
               end if;
            end if;
         end if;
      end Check_Valid_Library_Unit_Pragma;

      -------------------
      -- Check_Variant --
      -------------------

      procedure Check_Variant (Variant : Node_Id; UU_Typ : Entity_Id) is
         Clist : constant Node_Id := Component_List (Variant);
         Comp  : Node_Id;

      begin
         Comp := First_Non_Pragma (Component_Items (Clist));
         while Present (Comp) loop
            Check_Component (Comp, UU_Typ, In_Variant_Part => True);
            Next_Non_Pragma (Comp);
         end loop;
      end Check_Variant;

      ---------------------------
      -- Ensure_Aggregate_Form --
      ---------------------------

      procedure Ensure_Aggregate_Form (Arg : Node_Id) is
         CFSD    : constant Boolean    := Get_Comes_From_Source_Default;
         Expr    : constant Node_Id    := Expression (Arg);
         Loc     : constant Source_Ptr := Sloc (Expr);
         Comps   : List_Id := No_List;
         Exprs   : List_Id := No_List;
         Nam     : Name_Id := No_Name;
         Nam_Loc : Source_Ptr;

      begin
         --  The pragma argument is in positional form:

         --    pragma Depends (Nam => ...)
         --                    ^
         --                    Chars field

         --  Note that the Sloc of the Chars field is the Sloc of the pragma
         --  argument association.

         if Nkind (Arg) = N_Pragma_Argument_Association then
            Nam     := Chars (Arg);
            Nam_Loc := Sloc (Arg);

            --  Remove the pragma argument name as this will be captured in the
            --  aggregate.

            Set_Chars (Arg, No_Name);
         end if;

         --  The argument is already in aggregate form, but the presence of a
         --  name causes this to be interpreted as named association which in
         --  turn must be converted into an aggregate.

         --    pragma Global (In_Out => (A, B, C))
         --                   ^         ^
         --                   name      aggregate

         --    pragma Global ((In_Out => (A, B, C)))
         --                   ^          ^
         --                   aggregate  aggregate

         if Nkind (Expr) = N_Aggregate then
            if Nam = No_Name then
               return;
            end if;

         --  Do not transform a null argument into an aggregate as N_Null has
         --  special meaning in formal verification pragmas.

         elsif Nkind (Expr) = N_Null then
            return;
         end if;

         --  Everything comes from source if the original comes from source

         Set_Comes_From_Source_Default (Comes_From_Source (Arg));

         --  Positional argument is transformed into an aggregate with an
         --  Expressions list.

         if Nam = No_Name then
            Exprs := New_List (Relocate_Node (Expr));

         --  An associative argument is transformed into an aggregate with
         --  Component_Associations.

         else
            Comps := New_List (
              Make_Component_Association (Loc,
                Choices    => New_List (Make_Identifier (Nam_Loc, Nam)),
                Expression => Relocate_Node (Expr)));
         end if;

         Set_Expression (Arg,
           Make_Aggregate (Loc,
             Component_Associations => Comps,
             Expressions            => Exprs));

         --  Restore Comes_From_Source default

         Set_Comes_From_Source_Default (CFSD);
      end Ensure_Aggregate_Form;

      ------------------
      -- Error_Pragma --
      ------------------

      procedure Error_Pragma (Msg : String) is
      begin
         Error_Msg_Name_1 := Pname;
         Error_Msg_N (Fix_Error (Msg), N);
         raise Pragma_Exit;
      end Error_Pragma;

      ----------------------
      -- Error_Pragma_Arg --
      ----------------------

      procedure Error_Pragma_Arg (Msg : String; Arg : Node_Id) is
      begin
         Error_Msg_Name_1 := Pname;
         Error_Msg_N (Fix_Error (Msg), Get_Pragma_Arg (Arg));
         raise Pragma_Exit;
      end Error_Pragma_Arg;

      procedure Error_Pragma_Arg (Msg1, Msg2 : String; Arg : Node_Id) is
      begin
         Error_Msg_Name_1 := Pname;
         Error_Msg_N (Fix_Error (Msg1), Get_Pragma_Arg (Arg));
         Error_Pragma_Arg (Msg2, Arg);
      end Error_Pragma_Arg;

      ----------------------------
      -- Error_Pragma_Arg_Ident --
      ----------------------------

      procedure Error_Pragma_Arg_Ident (Msg : String; Arg : Node_Id) is
      begin
         Error_Msg_Name_1 := Pname;
         Error_Msg_N (Fix_Error (Msg), Arg);
         raise Pragma_Exit;
      end Error_Pragma_Arg_Ident;

      ----------------------
      -- Error_Pragma_Ref --
      ----------------------

      procedure Error_Pragma_Ref (Msg : String; Ref : Entity_Id) is
      begin
         Error_Msg_Name_1 := Pname;
         Error_Msg_Sloc := Sloc (Ref);
         Error_Msg_NE (Fix_Error (Msg), N, Ref);
         raise Pragma_Exit;
      end Error_Pragma_Ref;

      ------------------------
      -- Find_Lib_Unit_Name --
      ------------------------

      function Find_Lib_Unit_Name return Entity_Id is
      begin
         --  Return inner compilation unit entity, for case of nested
         --  categorization pragmas. This happens in generic unit.

         if Nkind (Parent (N)) = N_Package_Specification
           and then Defining_Entity (Parent (N)) /= Current_Scope
         then
            return Defining_Entity (Parent (N));
         else
            return Current_Scope;
         end if;
      end Find_Lib_Unit_Name;

      ----------------------------
      -- Find_Program_Unit_Name --
      ----------------------------

      procedure Find_Program_Unit_Name (Id : Node_Id) is
         Unit_Name : Entity_Id;
         Unit_Kind : Node_Kind;
         P         : constant Node_Id := Parent (N);

      begin
         if Nkind (P) = N_Compilation_Unit then
            Unit_Kind := Nkind (Unit (P));

            if Unit_Kind in N_Subprogram_Declaration
                          | N_Package_Declaration
                          | N_Generic_Declaration
            then
               Unit_Name := Defining_Entity (Unit (P));

               if Chars (Id) = Chars (Unit_Name) then
                  Set_Entity (Id, Unit_Name);
                  Set_Etype (Id, Etype (Unit_Name));
               else
                  Set_Etype (Id, Any_Type);
                  Error_Pragma
                    ("cannot find program unit referenced by pragma%");
               end if;

            else
               Set_Etype (Id, Any_Type);
               Error_Pragma ("pragma% inapplicable to this unit");
            end if;

         else
            Analyze (Id);
         end if;
      end Find_Program_Unit_Name;

      -----------------------------------------
      -- Find_Unique_Parameterless_Procedure --
      -----------------------------------------

      function Find_Unique_Parameterless_Procedure
        (Name : Entity_Id;
         Arg  : Node_Id) return Entity_Id
      is
         Proc : Entity_Id := Empty;

      begin
         --  Perform sanity checks on Name

         if not Is_Entity_Name (Name) then
            Error_Pragma_Arg
              ("argument of pragma% must be entity name", Arg);

         elsif not Is_Overloaded (Name) then
            Proc := Entity (Name);

            if Ekind (Proc) /= E_Procedure
              or else Present (First_Formal (Proc))
            then
               Error_Pragma_Arg
                 ("argument of pragma% must be parameterless procedure", Arg);
            end if;

         --  Otherwise, search through interpretations looking for one which
         --  has no parameters.

         else
            declare
               Found : Boolean := False;
               It    : Interp;
               Index : Interp_Index;

            begin
               Get_First_Interp (Name, Index, It);
               while Present (It.Nam) loop
                  Proc := It.Nam;

                  if Ekind (Proc) = E_Procedure
                    and then No (First_Formal (Proc))
                  then
                     --  We found an interpretation, note it and continue
                     --  looking looking to verify it is unique.

                     if not Found then
                        Found := True;
                        Set_Entity (Name, Proc);
                        Set_Is_Overloaded (Name, False);

                     --  Two procedures with the same name, log an error
                     --  since the name is ambiguous.

                     else
                        Error_Pragma_Arg
                          ("ambiguous handler name for pragma%", Arg);
                     end if;
                  end if;

                  Get_Next_Interp (Index, It);
               end loop;

               if not Found then
                  --  Issue an error if we haven't found a suitable match for
                  --  Name.

                  Error_Pragma_Arg
                    ("argument of pragma% must be parameterless procedure",
                     Arg);

               else
                  Proc := Entity (Name);
               end if;
            end;
         end if;

         return Proc;
      end Find_Unique_Parameterless_Procedure;

      ---------------
      -- Fix_Error --
      ---------------

      function Fix_Error (Msg : String) return String is
         Res      : String (Msg'Range) := Msg;
         Res_Last : Natural            := Msg'Last;
         J        : Natural;

      begin
         --  If we have a rewriting of another pragma, go to that pragma

         if Is_Rewrite_Substitution (N)
           and then Nkind (Original_Node (N)) = N_Pragma
         then
            Error_Msg_Name_1 := Pragma_Name (Original_Node (N));
         end if;

         --  Case where pragma comes from an aspect specification

         if From_Aspect_Specification (N) then

            --  Change appearence of "pragma" in message to "aspect"

            J := Res'First;
            while J <= Res_Last - 5 loop
               if Res (J .. J + 5) = "pragma" then
                  Res (J .. J + 5) := "aspect";
                  J := J + 6;

               else
                  J := J + 1;
               end if;
            end loop;

            --  Change "argument of" at start of message to "entity for"

            if Res'Length > 11
              and then Res (Res'First .. Res'First + 10) = "argument of"
            then
               Res (Res'First .. Res'First + 9) := "entity for";
               Res (Res'First + 10 .. Res_Last - 1) :=
                 Res (Res'First + 11 .. Res_Last);
               Res_Last := Res_Last - 1;
            end if;

            --  Change "argument" at start of message to "entity"

            if Res'Length > 8
              and then Res (Res'First .. Res'First + 7) = "argument"
            then
               Res (Res'First .. Res'First + 5) := "entity";
               Res (Res'First + 6 .. Res_Last - 2) :=
                 Res (Res'First + 8 .. Res_Last);
               Res_Last := Res_Last - 2;
            end if;

            --  Get name from corresponding aspect

            Error_Msg_Name_1 := Original_Aspect_Pragma_Name (N);
         end if;

         --  Return possibly modified message

         return Res (Res'First .. Res_Last);
      end Fix_Error;

      -------------------------
      -- Gather_Associations --
      -------------------------

      procedure Gather_Associations
        (Names : Name_List;
         Args  : out Args_List)
      is
         Arg : Node_Id;

      begin
         --  Initialize all parameters to Empty

         for J in Args'Range loop
            Args (J) := Empty;
         end loop;

         --  That's all we have to do if there are no argument associations

         if No (Pragma_Argument_Associations (N)) then
            return;
         end if;

         --  Otherwise first deal with any positional parameters present

         Arg := First (Pragma_Argument_Associations (N));
         for Index in Args'Range loop
            exit when No (Arg) or else Chars (Arg) /= No_Name;
            Args (Index) := Get_Pragma_Arg (Arg);
            Next (Arg);
         end loop;

         --  Positional parameters all processed, if any left, then we
         --  have too many positional parameters.

         if Present (Arg) and then Chars (Arg) = No_Name then
            Error_Pragma_Arg
              ("too many positional associations for pragma%", Arg);
         end if;

         --  Process named parameters if any are present

         while Present (Arg) loop
            if Chars (Arg) = No_Name then
               Error_Pragma_Arg
                 ("positional association cannot follow named association",
                  Arg);

            else
               for Index in Names'Range loop
                  if Names (Index) = Chars (Arg) then
                     if Present (Args (Index)) then
                        Error_Pragma_Arg
                          ("duplicate argument association for pragma%", Arg);
                     else
                        Args (Index) := Get_Pragma_Arg (Arg);
                        exit;
                     end if;
                  end if;

                  if Index = Names'Last then
                     Error_Msg_Name_1 := Pname;
                     Error_Msg_N ("pragma% does not allow & argument", Arg);

                     --  Check for possible misspelling

                     for Index1 in Names'Range loop
                        if Is_Bad_Spelling_Of
                             (Chars (Arg), Names (Index1))
                        then
                           Error_Msg_Name_1 := Names (Index1);
                           Error_Msg_N -- CODEFIX
                             ("\possible misspelling of%", Arg);
                           exit;
                        end if;
                     end loop;

                     raise Pragma_Exit;
                  end if;
               end loop;
            end if;

            Next (Arg);
         end loop;
      end Gather_Associations;

      -----------------
      -- GNAT_Pragma --
      -----------------

      procedure GNAT_Pragma is
      begin
         --  We need to check the No_Implementation_Pragmas restriction for
         --  the case of a pragma from source. Note that the case of aspects
         --  generating corresponding pragmas marks these pragmas as not being
         --  from source, so this test also catches that case.

         if Comes_From_Source (N) then
            Check_Restriction (No_Implementation_Pragmas, N);
         end if;
      end GNAT_Pragma;

      --------------------------
      -- Is_Before_First_Decl --
      --------------------------

      function Is_Before_First_Decl
        (Pragma_Node : Node_Id;
         Decls       : List_Id) return Boolean
      is
         Item : Node_Id := First (Decls);

      begin
         --  Only other pragmas can come before this pragma, but they might
         --  have been rewritten so check the original node.

         loop
            if No (Item) or else Nkind (Original_Node (Item)) /= N_Pragma then
               return False;

            elsif Item = Pragma_Node then
               return True;
            end if;

            Next (Item);
         end loop;
      end Is_Before_First_Decl;

      -----------------------------
      -- Is_Configuration_Pragma --
      -----------------------------

      --  A configuration pragma must appear in the context clause of a
      --  compilation unit, and only other pragmas may precede it. Note that
      --  the test below also permits use in a configuration pragma file.

      function Is_Configuration_Pragma return Boolean is
         Lis : constant List_Id := List_Containing (N);
         Par : constant Node_Id := Parent (N);
         Prg : Node_Id;

      begin
         --  If no parent, then we are in the configuration pragma file,
         --  so the placement is definitely appropriate.

         if No (Par) then
            return True;

         --  Otherwise we must be in the context clause of a compilation unit
         --  and the only thing allowed before us in the context list is more
         --  configuration pragmas.

         elsif Nkind (Par) = N_Compilation_Unit
           and then Context_Items (Par) = Lis
         then
            Prg := First (Lis);

            loop
               if Prg = N then
                  return True;
               elsif Nkind (Prg) /= N_Pragma then
                  return False;
               end if;

               Next (Prg);
            end loop;

         else
            return False;
         end if;
      end Is_Configuration_Pragma;

      --------------------------
      -- Is_In_Context_Clause --
      --------------------------

      function Is_In_Context_Clause return Boolean is
         Plist       : List_Id;
         Parent_Node : Node_Id;

      begin
         if not Is_List_Member (N) then
            return False;

         else
            Plist := List_Containing (N);
            Parent_Node := Parent (Plist);

            if Parent_Node = Empty
              or else Nkind (Parent_Node) /= N_Compilation_Unit
              or else Context_Items (Parent_Node) /= Plist
            then
               return False;
            end if;
         end if;

         return True;
      end Is_In_Context_Clause;

      ---------------------------------
      -- Is_Static_String_Expression --
      ---------------------------------

      function Is_Static_String_Expression (Arg : Node_Id) return Boolean is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);
         Lit  : constant Boolean := Nkind (Argx) = N_String_Literal;

      begin
         Analyze_And_Resolve (Argx);

         --  Special case Ada 83, where the expression will never be static,
         --  but we will return true if we had a string literal to start with.

         if Ada_Version = Ada_83 then
            return Lit;

         --  Normal case, true only if we end up with a string literal that
         --  is marked as being the result of evaluating a static expression.

         else
            return Is_OK_Static_Expression (Argx)
              and then Nkind (Argx) = N_String_Literal;
         end if;

      end Is_Static_String_Expression;

      ----------------------
      -- Pragma_Misplaced --
      ----------------------

      procedure Pragma_Misplaced is
      begin
         Error_Pragma ("incorrect placement of pragma%");
      end Pragma_Misplaced;

      ------------------------------------------------
      -- Process_Atomic_Independent_Shared_Volatile --
      ------------------------------------------------

      procedure Process_Atomic_Independent_Shared_Volatile is
         procedure Check_Full_Access_Only (Ent : Entity_Id);
         --  Apply legality checks to type or object Ent subject to the
         --  Full_Access_Only aspect in Ada 2022 (RM C.6(8.2)).

         procedure Mark_Component_Or_Object (Ent : Entity_Id);
         --  Appropriately set flags on the given entity, either an array or
         --  record component, or an object declaration) according to the
         --  current pragma.

         procedure Mark_Type (Ent : Entity_Id);
         --  Appropriately set flags on the given entity, a type

         procedure Set_Atomic_VFA (Ent : Entity_Id);
         --  Set given type as Is_Atomic or Is_Volatile_Full_Access. Also, if
         --  no explicit alignment was given, set alignment to unknown, since
         --  back end knows what the alignment requirements are for atomic and
         --  full access arrays. Note: this is necessary for derived types.

         -------------------------
         -- Check_Full_Access_Only --
         -------------------------

         procedure Check_Full_Access_Only (Ent : Entity_Id) is
            Typ  : Entity_Id;

            Full_Access_Subcomponent : exception;
            --  Exception raised if a full access subcomponent is found

            Generic_Type_Subcomponent : exception;
            --  Exception raised if a subcomponent with generic type is found

            procedure Check_Subcomponents (Typ : Entity_Id);
            --  Apply checks to subcomponents recursively

            -------------------------
            -- Check_Subcomponents --
            -------------------------

            procedure Check_Subcomponents (Typ : Entity_Id) is
               Comp : Entity_Id;

            begin
               if Is_Array_Type (Typ) then
                  Comp := Component_Type (Typ);

                  if Has_Atomic_Components (Typ)
                    or else Is_Full_Access (Comp)
                  then
                     raise Full_Access_Subcomponent;

                  elsif Is_Generic_Type (Comp) then
                     raise Generic_Type_Subcomponent;
                  end if;

                  --  Recurse on the component type

                  Check_Subcomponents (Comp);

               elsif Is_Record_Type (Typ) then
                  Comp := First_Component_Or_Discriminant (Typ);
                  while Present (Comp) loop

                     if Is_Full_Access (Comp)
                       or else Is_Full_Access (Etype (Comp))
                     then
                        raise Full_Access_Subcomponent;

                     elsif Is_Generic_Type (Etype (Comp)) then
                        raise Generic_Type_Subcomponent;
                     end if;

                     --  Recurse on the component type

                     Check_Subcomponents (Etype (Comp));

                     Next_Component_Or_Discriminant (Comp);
                  end loop;
               end if;
            end Check_Subcomponents;

         --  Start of processing for Check_Full_Access_Only

         begin
            --  Fetch the type in case we are dealing with an object or
            --  component.

            if Is_Type (Ent) then
               Typ := Ent;
            else
               pragma Assert (Is_Object (Ent)
                 or else
                   Nkind (Declaration_Node (Ent)) = N_Component_Declaration);

               Typ := Etype (Ent);
            end if;

            if not Is_Volatile (Ent) and then not Is_Volatile (Typ) then
               Error_Pragma
                 ("cannot have Full_Access_Only without Volatile/Atomic "
                  & "(RM C.6(8.2))");
               return;
            end if;

            --  Check all the subcomponents of the type recursively, if any

            Check_Subcomponents (Typ);

         exception
            when Full_Access_Subcomponent =>
               Error_Pragma
                 ("cannot have Full_Access_Only with full access subcomponent "
                  & "(RM C.6(8.2))");

            when Generic_Type_Subcomponent =>
               Error_Pragma
                 ("cannot have Full_Access_Only with subcomponent of generic "
                  & "type (RM C.6(8.2))");

         end Check_Full_Access_Only;

         ------------------------------
         -- Mark_Component_Or_Object --
         ------------------------------

         procedure Mark_Component_Or_Object (Ent : Entity_Id) is
         begin
            if Prag_Id = Pragma_Atomic
              or else Prag_Id = Pragma_Shared
              or else Prag_Id = Pragma_Volatile_Full_Access
            then
               if Prag_Id = Pragma_Volatile_Full_Access then
                  Set_Is_Volatile_Full_Access (Ent);
               else
                  Set_Is_Atomic (Ent);
               end if;

               --  If the object declaration has an explicit initialization, a
               --  temporary may have to be created to hold the expression, to
               --  ensure that access to the object remains atomic.

               if Nkind (Parent (Ent)) = N_Object_Declaration
                 and then Present (Expression (Parent (Ent)))
               then
                  Set_Has_Delayed_Freeze (Ent);
               end if;
            end if;

            --  Atomic/Shared/Volatile_Full_Access imply Independent

            if Prag_Id /= Pragma_Volatile then
               Set_Is_Independent (Ent);

               if Prag_Id = Pragma_Independent then
                  Record_Independence_Check (N, Ent);
               end if;
            end if;

            --  Atomic/Shared/Volatile_Full_Access imply Volatile

            if Prag_Id /= Pragma_Independent then
               Set_Is_Volatile (Ent);
               Set_Treat_As_Volatile (Ent);
            end if;
         end Mark_Component_Or_Object;

         ---------------
         -- Mark_Type --
         ---------------

         procedure Mark_Type (Ent : Entity_Id) is
         begin
            --  Attribute belongs on the base type. If the view of the type is
            --  currently private, it also belongs on the underlying type.

            --  In Ada 2022, the pragma can apply to a formal type, for which
            --  there may be no underlying type.

            if Prag_Id = Pragma_Atomic
              or else Prag_Id = Pragma_Shared
              or else Prag_Id = Pragma_Volatile_Full_Access
            then
               Set_Atomic_VFA (Ent);
               Set_Atomic_VFA (Base_Type (Ent));

               if not Is_Generic_Type (Ent) then
                  Set_Atomic_VFA (Underlying_Type (Ent));
               end if;
            end if;

            --  Atomic/Shared/Volatile_Full_Access imply Independent

            if Prag_Id /= Pragma_Volatile then
               Set_Is_Independent (Ent);
               Set_Is_Independent (Base_Type (Ent));

               if not Is_Generic_Type (Ent) then
                  Set_Is_Independent (Underlying_Type (Ent));

                  if Prag_Id = Pragma_Independent then
                     Record_Independence_Check (N, Base_Type (Ent));
                  end if;
               end if;
            end if;

            --  Atomic/Shared/Volatile_Full_Access imply Volatile

            if Prag_Id /= Pragma_Independent then
               Set_Is_Volatile (Ent);
               Set_Is_Volatile (Base_Type (Ent));

               if not Is_Generic_Type (Ent) then
                  Set_Is_Volatile (Underlying_Type (Ent));
                  Set_Treat_As_Volatile (Underlying_Type (Ent));
               end if;

               Set_Treat_As_Volatile (Ent);
            end if;

            --  Apply Volatile to the composite type's individual components,
            --  (RM C.6(8/3)).

            if Prag_Id = Pragma_Volatile
              and then Is_Record_Type (Etype (Ent))
            then
               declare
                  Comp : Entity_Id;
               begin
                  Comp := First_Component (Ent);
                  while Present (Comp) loop
                     Mark_Component_Or_Object (Comp);

                     Next_Component (Comp);
                  end loop;
               end;
            end if;
         end Mark_Type;

         --------------------
         -- Set_Atomic_VFA --
         --------------------

         procedure Set_Atomic_VFA (Ent : Entity_Id) is
         begin
            if Prag_Id = Pragma_Volatile_Full_Access then
               Set_Is_Volatile_Full_Access (Ent);
            else
               Set_Is_Atomic (Ent);
            end if;

            if not Has_Alignment_Clause (Ent) then
               Reinit_Alignment (Ent);
            end if;
         end Set_Atomic_VFA;

         --  Local variables

         Decl  : Node_Id;
         E     : Entity_Id;
         E_Arg : Node_Id;

      --  Start of processing for Process_Atomic_Independent_Shared_Volatile

      begin
         Check_Ada_83_Warning;
         Check_No_Identifiers;
         Check_Arg_Count (1);
         Check_Arg_Is_Local_Name (Arg1);
         E_Arg := Get_Pragma_Arg (Arg1);

         if Etype (E_Arg) = Any_Type then
            return;
         end if;

         E := Entity (E_Arg);
         Decl := Declaration_Node (E);

         --  A pragma that applies to a Ghost entity becomes Ghost for the
         --  purposes of legality checks and removal of ignored Ghost code.

         Mark_Ghost_Pragma (N, E);

         --  Check duplicate before we chain ourselves

         Check_Duplicate_Pragma (E);

         --  Check the constraints of Full_Access_Only in Ada 2022. Note that
         --  they do not apply to GNAT's Volatile_Full_Access because 1) this
         --  aspect subsumes the Volatile aspect and 2) nesting is supported
         --  for this aspect and the outermost enclosing VFA object prevails.

         --  Note also that we used to forbid specifying both Atomic and VFA on
         --  the same type or object, but the restriction has been lifted in
         --  light of the semantics of Full_Access_Only and Atomic in Ada 2022.

         if Prag_Id = Pragma_Volatile_Full_Access
           and then From_Aspect_Specification (N)
           and then
             Get_Aspect_Id (Corresponding_Aspect (N)) = Aspect_Full_Access_Only
         then
            Check_Full_Access_Only (E);
         end if;

         --  The following check is only relevant when SPARK_Mode is on as
         --  this is not a standard Ada legality rule. Pragma Volatile can
         --  only apply to a full type declaration or an object declaration
         --  (SPARK RM 7.1.3(2)). Original_Node is necessary to account for
         --  untagged derived types that are rewritten as subtypes of their
         --  respective root types.

         if SPARK_Mode = On
           and then Prag_Id = Pragma_Volatile
           and then Nkind (Original_Node (Decl)) not in
                      N_Full_Type_Declaration        |
                      N_Formal_Type_Declaration      |
                      N_Object_Declaration           |
                      N_Single_Protected_Declaration |
                      N_Single_Task_Declaration
         then
            Error_Pragma_Arg
              ("argument of pragma % must denote a full type or object "
               & "declaration", Arg1);
         end if;

         --  Deal with the case where the pragma/attribute is applied to a type

         if Is_Type (E) then
            if Rep_Item_Too_Early (E, N)
              or else Rep_Item_Too_Late (E, N)
            then
               return;
            else
               Check_First_Subtype (Arg1);
            end if;

            Mark_Type (E);

         --  Deal with the case where the pragma/attribute applies to a
         --  component or object declaration.

         elsif Nkind (Decl) = N_Object_Declaration
           or else (Nkind (Decl) = N_Component_Declaration
                     and then Original_Record_Component (E) = E)
         then
            if Rep_Item_Too_Late (E, N) then
               return;
            end if;

            Mark_Component_Or_Object (E);

         --  In other cases give an error

         else
            Error_Pragma_Arg ("inappropriate entity for pragma%", Arg1);
         end if;
      end Process_Atomic_Independent_Shared_Volatile;

      -------------------------------------------
      -- Process_Compile_Time_Warning_Or_Error --
      -------------------------------------------

      procedure Process_Compile_Time_Warning_Or_Error is
         P : Node_Id := Parent (N);
         Arg1x : constant Node_Id := Get_Pragma_Arg (Arg1);

      begin
         Check_Arg_Count (2);
         Check_No_Identifiers;
         Check_Arg_Is_OK_Static_Expression (Arg2, Standard_String);
         Analyze_And_Resolve (Arg1x, Standard_Boolean);

         --  In GNATprove mode, pragma Compile_Time_Error is translated as
         --  a Check pragma in GNATprove mode, handled as an assumption in
         --  GNATprove. This is correct as the compiler will issue an error
         --  if the condition cannot be statically evaluated to False.
         --  Compile_Time_Warning are ignored, as the analyzer may not have the
         --  same information as the compiler (in particular regarding size of
         --  objects decided in gigi) so it makes no sense to issue a warning
         --  in GNATprove.

         if GNATprove_Mode then
            if Prag_Id = Pragma_Compile_Time_Error then
               declare
                  New_Args : List_Id;
               begin
                  --  Implement Compile_Time_Error by generating
                  --  a corresponding Check pragma:

                  --    pragma Check (name, condition);

                  --  where name is the identifier matching the pragma name. So
                  --  rewrite pragma in this manner and analyze the result.

                  New_Args := New_List
                    (Make_Pragma_Argument_Association
                       (Loc,
                        Expression => Make_Identifier (Loc, Pname)),
                     Make_Pragma_Argument_Association
                       (Sloc (Arg1x),
                        Expression => Arg1x));

                  --  Rewrite as Check pragma

                  Rewrite (N,
                           Make_Pragma (Loc,
                             Chars                        => Name_Check,
                             Pragma_Argument_Associations => New_Args));

                  Analyze (N);
               end;

            else
               Rewrite (N, Make_Null_Statement (Loc));
            end if;

            return;
         end if;

         --  If the condition is known at compile time (now), validate it now.
         --  Otherwise, register the expression for validation after the back
         --  end has been called, because it might be known at compile time
         --  then. For example, if the expression is "Record_Type'Size /= 32"
         --  it might be known after the back end has determined the size of
         --  Record_Type. We do not defer validation if we're inside a generic
         --  unit, because we will have more information in the instances.

         if Compile_Time_Known_Value (Arg1x) then
            Validate_Compile_Time_Warning_Or_Error (N, Sloc (Arg1));
         else
            while Present (P) and then Nkind (P) not in N_Generic_Declaration
            loop
               if Nkind (P) in N_Package_Body | N_Subprogram_Body then
                  P := Corresponding_Spec (P);
               else
                  P := Parent (P);
               end if;
            end loop;

            if No (P) then
               Defer_Compile_Time_Warning_Error_To_BE (N);
            end if;
         end if;
      end Process_Compile_Time_Warning_Or_Error;

      ------------------------
      -- Process_Convention --
      ------------------------

      procedure Process_Convention
        (C   : out Convention_Id;
         Ent : out Entity_Id)
      is
         Cname : Name_Id;

         procedure Diagnose_Multiple_Pragmas (S : Entity_Id);
         --  Called if we have more than one Export/Import/Convention pragma.
         --  This is generally illegal, but we have a special case of allowing
         --  Import and Interface to coexist if they specify the convention in
         --  a consistent manner. We are allowed to do this, since Interface is
         --  an implementation defined pragma, and we choose to do it since we
         --  know Rational allows this combination. S is the entity id of the
         --  subprogram in question. This procedure also sets the special flag
         --  Import_Interface_Present in both pragmas in the case where we do
         --  have matching Import and Interface pragmas.

         procedure Set_Convention_From_Pragma (E : Entity_Id);
         --  Set convention in entity E, and also flag that the entity has a
         --  convention pragma. If entity is for a private or incomplete type,
         --  also set convention and flag on underlying type. This procedure
         --  also deals with the special case of C_Pass_By_Copy convention,
         --  and error checks for inappropriate convention specification.

         -------------------------------
         -- Diagnose_Multiple_Pragmas --
         -------------------------------

         procedure Diagnose_Multiple_Pragmas (S : Entity_Id) is
            Pdec : constant Node_Id := Declaration_Node (S);
            Decl : Node_Id;
            Err  : Boolean;

            function Same_Convention (Decl : Node_Id) return Boolean;
            --  Decl is a pragma node. This function returns True if this
            --  pragma has a first argument that is an identifier with a
            --  Chars field corresponding to the Convention_Id C.

            function Same_Name (Decl : Node_Id) return Boolean;
            --  Decl is a pragma node. This function returns True if this
            --  pragma has a second argument that is an identifier with a
            --  Chars field that matches the Chars of the current subprogram.

            ---------------------
            -- Same_Convention --
            ---------------------

            function Same_Convention (Decl : Node_Id) return Boolean is
               Arg1 : constant Node_Id :=
                        First (Pragma_Argument_Associations (Decl));

            begin
               if Present (Arg1) then
                  declare
                     Arg : constant Node_Id := Get_Pragma_Arg (Arg1);
                  begin
                     if Nkind (Arg) = N_Identifier
                       and then Is_Convention_Name (Chars (Arg))
                       and then Get_Convention_Id (Chars (Arg)) = C
                     then
                        return True;
                     end if;
                  end;
               end if;

               return False;
            end Same_Convention;

            ---------------
            -- Same_Name --
            ---------------

            function Same_Name (Decl : Node_Id) return Boolean is
               Arg1 : constant Node_Id :=
                        First (Pragma_Argument_Associations (Decl));
               Arg2 : Node_Id;

            begin
               if No (Arg1) then
                  return False;
               end if;

               Arg2 := Next (Arg1);

               if No (Arg2) then
                  return False;
               end if;

               declare
                  Arg : constant Node_Id := Get_Pragma_Arg (Arg2);
               begin
                  if Nkind (Arg) = N_Identifier
                    and then Chars (Arg) = Chars (S)
                  then
                     return True;
                  end if;
               end;

               return False;
            end Same_Name;

         --  Start of processing for Diagnose_Multiple_Pragmas

         begin
            Err := True;

            --  Definitely give message if we have Convention/Export here

            if Prag_Id = Pragma_Convention or else Prag_Id = Pragma_Export then
               null;

               --  If we have an Import or Export, scan back from pragma to
               --  find any previous pragma applying to the same procedure.
               --  The scan will be terminated by the start of the list, or
               --  hitting the subprogram declaration. This won't allow one
               --  pragma to appear in the public part and one in the private
               --  part, but that seems very unlikely in practice.

            else
               Decl := Prev (N);
               while Present (Decl) and then Decl /= Pdec loop

                  --  Look for pragma with same name as us

                  if Nkind (Decl) = N_Pragma
                    and then Same_Name (Decl)
                  then
                     --  Give error if same as our pragma or Export/Convention

                     if Pragma_Name_Unmapped (Decl)
                          in Name_Export
                           | Name_Convention
                           | Pragma_Name_Unmapped (N)
                     then
                        exit;

                     --  Case of Import/Interface or the other way round

                     elsif Pragma_Name_Unmapped (Decl)
                             in Name_Interface | Name_Import
                     then
                        --  Here we know that we have Import and Interface. It
                        --  doesn't matter which way round they are. See if
                        --  they specify the same convention. If so, all OK,
                        --  and set special flags to stop other messages

                        if Same_Convention (Decl) then
                           Set_Import_Interface_Present (N);
                           Set_Import_Interface_Present (Decl);
                           Err := False;

                        --  If different conventions, special message

                        else
                           Error_Msg_Sloc := Sloc (Decl);
                           Error_Pragma_Arg
                             ("convention differs from that given#", Arg1);
                           return;
                        end if;
                     end if;
                  end if;

                  Next (Decl);
               end loop;
            end if;

            --  Give message if needed if we fall through those tests
            --  except on Relaxed_RM_Semantics where we let go: either this
            --  is a case accepted/ignored by other Ada compilers (e.g.
            --  a mix of Convention and Import), or another error will be
            --  generated later (e.g. using both Import and Export).

            if Err and not Relaxed_RM_Semantics then
               Error_Pragma_Arg
                 ("at most one Convention/Export/Import pragma is allowed",
                  Arg2);
            end if;
         end Diagnose_Multiple_Pragmas;

         --------------------------------
         -- Set_Convention_From_Pragma --
         --------------------------------

         procedure Set_Convention_From_Pragma (E : Entity_Id) is
         begin
            --  Ada 2005 (AI-430): Check invalid attempt to change convention
            --  for an overridden dispatching operation. Technically this is
            --  an amendment and should only be done in Ada 2005 mode. However,
            --  this is clearly a mistake, since the problem that is addressed
            --  by this AI is that there is a clear gap in the RM.

            if Is_Dispatching_Operation (E)
              and then Present (Overridden_Operation (E))
              and then C /= Convention (Overridden_Operation (E))
            then
               Error_Pragma_Arg
                 ("cannot change convention for overridden dispatching "
                  & "operation", Arg1);

            --  Special check for convention Stdcall: a dispatching call is not
            --  allowed. A dispatching subprogram cannot be used to interface
            --  to the Win32 API, so this check actually does not impose any
            --  effective restriction.

            elsif Is_Dispatching_Operation (E)
              and then C = Convention_Stdcall
            then
               --  Note: make this unconditional so that if there is more
               --  than one call to which the pragma applies, we get a
               --  message for each call. Also don't use Error_Pragma,
               --  so that we get multiple messages.

               Error_Msg_Sloc := Sloc (E);
               Error_Msg_N
                 ("dispatching subprogram# cannot use Stdcall convention!",
                  Get_Pragma_Arg (Arg1));
            end if;

            --  Set the convention

            Set_Convention (E, C);
            Set_Has_Convention_Pragma (E);

            --  For the case of a record base type, also set the convention of
            --  any anonymous access types declared in the record which do not
            --  currently have a specified convention.
            --  Similarly for an array base type and anonymous access types
            --  components.

            if Is_Base_Type (E) then
               if Is_Record_Type (E) then
                  declare
                     Comp : Node_Id;

                  begin
                     Comp := First_Component (E);
                     while Present (Comp) loop
                        if Present (Etype (Comp))
                          and then
                            Ekind (Etype (Comp)) in
                              E_Anonymous_Access_Type |
                              E_Anonymous_Access_Subprogram_Type
                          and then not Has_Convention_Pragma (Comp)
                        then
                           Set_Convention (Comp, C);
                        end if;

                        Next_Component (Comp);
                     end loop;
                  end;

               elsif Is_Array_Type (E)
                 and then Ekind (Component_Type (E)) in
                            E_Anonymous_Access_Type |
                            E_Anonymous_Access_Subprogram_Type
               then
                  Set_Convention (Designated_Type (Component_Type (E)), C);
               end if;
            end if;

            --  Deal with incomplete/private type case, where underlying type
            --  is available, so set convention of that underlying type.

            if Is_Incomplete_Or_Private_Type (E)
              and then Present (Underlying_Type (E))
            then
               Set_Convention            (Underlying_Type (E), C);
               Set_Has_Convention_Pragma (Underlying_Type (E), True);
            end if;

            --  A class-wide type should inherit the convention of the specific
            --  root type (although this isn't specified clearly by the RM).

            if Is_Type (E) and then Present (Class_Wide_Type (E)) then
               Set_Convention (Class_Wide_Type (E), C);
            end if;

            --  If the entity is a record type, then check for special case of
            --  C_Pass_By_Copy, which is treated the same as C except that the
            --  special record flag is set. This convention is only permitted
            --  on record types (see AI95-00131).

            if Cname = Name_C_Pass_By_Copy then
               if Is_Record_Type (E) then
                  Set_C_Pass_By_Copy (Base_Type (E));
               elsif Is_Incomplete_Or_Private_Type (E)
                 and then Is_Record_Type (Underlying_Type (E))
               then
                  Set_C_Pass_By_Copy (Base_Type (Underlying_Type (E)));
               else
                  Error_Pragma_Arg
                    ("C_Pass_By_Copy convention allowed only for record type",
                     Arg2);
               end if;
            end if;

            --  If the entity is a derived boolean type, check for the special
            --  case of convention C, C++, or Fortran, where we consider any
            --  nonzero value to represent true.

            if Is_Discrete_Type (E)
              and then Root_Type (Etype (E)) = Standard_Boolean
              and then
                (C = Convention_C
                   or else
                 C = Convention_CPP
                   or else
                 C = Convention_Fortran)
            then
               Set_Nonzero_Is_True (Base_Type (E));
            end if;
         end Set_Convention_From_Pragma;

         --  Local variables

         Comp_Unit : Unit_Number_Type;
         E         : Entity_Id;
         E1        : Entity_Id;
         Id        : Node_Id;
         Subp      : Entity_Id;

      --  Start of processing for Process_Convention

      begin
         Check_At_Least_N_Arguments (2);
         Check_Optional_Identifier (Arg1, Name_Convention);
         Check_Arg_Is_Identifier (Arg1);
         Cname := Chars (Get_Pragma_Arg (Arg1));

         --  C_Pass_By_Copy is treated as a synonym for convention C (this is
         --  tested again below to set the critical flag).

         if Cname = Name_C_Pass_By_Copy then
            C := Convention_C;

         --  Otherwise we must have something in the standard convention list

         elsif Is_Convention_Name (Cname) then
            C := Get_Convention_Id (Chars (Get_Pragma_Arg (Arg1)));

         --  Otherwise warn on unrecognized convention

         else
            if Warn_On_Export_Import then
               Error_Msg_N
                 ("??unrecognized convention name, C assumed",
                  Get_Pragma_Arg (Arg1));
            end if;

            C := Convention_C;
         end if;

         Check_Optional_Identifier (Arg2, Name_Entity);
         Check_Arg_Is_Local_Name (Arg2);

         Id := Get_Pragma_Arg (Arg2);
         Analyze (Id);

         if not Is_Entity_Name (Id) then
            Error_Pragma_Arg ("entity name required", Arg2);
         end if;

         E := Entity (Id);

         --  Set entity to return

         Ent := E;

         --  Ada_Pass_By_Copy special checking

         if C = Convention_Ada_Pass_By_Copy then
            if not Is_First_Subtype (E) then
               Error_Pragma_Arg
                 ("convention `Ada_Pass_By_Copy` only allowed for types",
                  Arg2);
            end if;

            if Is_By_Reference_Type (E) then
               Error_Pragma_Arg
                 ("convention `Ada_Pass_By_Copy` not allowed for by-reference "
                  & "type", Arg1);
            end if;

         --  Ada_Pass_By_Reference special checking

         elsif C = Convention_Ada_Pass_By_Reference then
            if not Is_First_Subtype (E) then
               Error_Pragma_Arg
                 ("convention `Ada_Pass_By_Reference` only allowed for types",
                  Arg2);
            end if;

            if Is_By_Copy_Type (E) then
               Error_Pragma_Arg
                 ("convention `Ada_Pass_By_Reference` not allowed for by-copy "
                  & "type", Arg1);
            end if;
         end if;

         --  Go to renamed subprogram if present, since convention applies to
         --  the actual renamed entity, not to the renaming entity. If the
         --  subprogram is inherited, go to parent subprogram.

         if Is_Subprogram (E)
           and then Present (Alias (E))
         then
            if Nkind (Parent (Declaration_Node (E))) =
                                       N_Subprogram_Renaming_Declaration
            then
               if Scope (E) /= Scope (Alias (E)) then
                  Error_Pragma_Ref
                    ("cannot apply pragma% to non-local entity&#", E);
               end if;

               E := Alias (E);

            elsif Nkind (Parent (E)) in
                    N_Full_Type_Declaration | N_Private_Extension_Declaration
              and then Scope (E) = Scope (Alias (E))
            then
               E := Alias (E);

               --  Return the parent subprogram the entity was inherited from

               Ent := E;
            end if;
         end if;

         --  Check that we are not applying this to a specless body. Relax this
         --  check if Relaxed_RM_Semantics to accommodate other Ada compilers.

         if Is_Subprogram (E)
           and then Nkind (Parent (Declaration_Node (E))) = N_Subprogram_Body
           and then not Relaxed_RM_Semantics
         then
            Error_Pragma
              ("pragma% requires separate spec and must come before body");
         end if;

         --  Check that we are not applying this to a named constant

         if Is_Named_Number (E) then
            Error_Msg_Name_1 := Pname;
            Error_Msg_N
              ("cannot apply pragma% to named constant!",
               Get_Pragma_Arg (Arg2));
            Error_Pragma_Arg
              ("\supply appropriate type for&!", Arg2);
         end if;

         if Ekind (E) = E_Enumeration_Literal then
            Error_Pragma ("enumeration literal not allowed for pragma%");
         end if;

         --  Check for rep item appearing too early or too late

         if Etype (E) = Any_Type
           or else Rep_Item_Too_Early (E, N)
         then
            raise Pragma_Exit;

         elsif Present (Underlying_Type (E)) then
            E := Underlying_Type (E);
         end if;

         if Rep_Item_Too_Late (E, N) then
            raise Pragma_Exit;
         end if;

         if Has_Convention_Pragma (E) then
            Diagnose_Multiple_Pragmas (E);

         elsif Convention (E) = Convention_Protected
           or else Ekind (Scope (E)) = E_Protected_Type
         then
            Error_Pragma_Arg
              ("a protected operation cannot be given a different convention",
                Arg2);
         end if;

         --  For Intrinsic, a subprogram is required

         if C = Convention_Intrinsic
           and then not Is_Subprogram_Or_Generic_Subprogram (E)
         then
            --  Accept Intrinsic Export on types if Relaxed_RM_Semantics

            if not (Is_Type (E) and then Relaxed_RM_Semantics) then
               if From_Aspect_Specification (N) then
                  Error_Pragma_Arg
                     ("entity for aspect% must be a subprogram", Arg2);
               else
                  Error_Pragma_Arg
                     ("second argument of pragma% must be a subprogram", Arg2);
               end if;
            end if;

         --  Special checks for C_Variadic_n

         elsif C in Convention_C_Variadic then

            --  Several allowed cases

            if Is_Subprogram_Or_Generic_Subprogram (E) then
               Subp := E;

            --  An access to subprogram is also allowed

            elsif Is_Access_Type (E)
              and then Ekind (Designated_Type (E)) = E_Subprogram_Type
            then
               Subp := Designated_Type (E);

            --  Allow internal call to set convention of subprogram type

            elsif Ekind (E) = E_Subprogram_Type then
               Subp := E;

            else
               Error_Pragma_Arg
                 ("argument of pragma% must be subprogram or access type",
                  Arg2);
               Subp := Empty;
            end if;

            --  ISO C requires a named parameter before the ellipsis, so a
            --  variadic C function taking 0 fixed parameter cannot exist.

            if C = Convention_C_Variadic_0 then

               Error_Msg_N
                 ("??C_Variadic_0 cannot be used for an 'I'S'O C function",
                  Get_Pragma_Arg (Arg2));

            --  Now check the number of parameters of the subprogram and give
            --  an error if it is lower than n.

            elsif Present (Subp) then
               declare
                  Minimum : constant Nat :=
                    Convention_Id'Pos (C) -
                      Convention_Id'Pos (Convention_C_Variadic_0);

                  Count  : Nat;
                  Formal : Entity_Id;

               begin
                  Count := 0;
                  Formal := First_Formal (Subp);
                  while Present (Formal) loop
                     Count := Count + 1;
                     Next_Formal (Formal);
                  end loop;

                  if Count < Minimum then
                     Error_Msg_Uint_1 := UI_From_Int (Minimum);
                     Error_Pragma_Arg
                       ("argument of pragma% must have at least"
                        & "^ parameters", Arg2);
                  end if;
               end;
            end if;

         --  Special checks for Stdcall

         elsif C = Convention_Stdcall then

            --  Several allowed cases

            if Is_Subprogram_Or_Generic_Subprogram (E)

              --  A variable is OK

              or else Ekind (E) = E_Variable

              --  A component as well. The entity does not have its Ekind
              --  set until the enclosing record declaration is fully
              --  analyzed.

              or else Nkind (Parent (E)) = N_Component_Declaration

              --  An access to subprogram is also allowed

              or else
                (Is_Access_Type (E)
                  and then Ekind (Designated_Type (E)) = E_Subprogram_Type)

              --  Allow internal call to set convention of subprogram type

              or else Ekind (E) = E_Subprogram_Type
            then
               null;

            else
               Error_Pragma_Arg
                 ("argument of pragma% must be subprogram or access type",
                  Arg2);
            end if;
         end if;

         Set_Convention_From_Pragma (E);

         --  Deal with non-subprogram cases

         if not Is_Subprogram_Or_Generic_Subprogram (E) then
            if Is_Type (E) then

               --  The pragma must apply to a first subtype, but it can also
               --  apply to a generic type in a generic formal part, in which
               --  case it will also appear in the corresponding instance.

               if Is_Generic_Type (E) or else In_Instance then
                  null;
               else
                  Check_First_Subtype (Arg2);
               end if;

               Set_Convention_From_Pragma (Base_Type (E));

               --  For access subprograms, we must set the convention on the
               --  internally generated directly designated type as well.

               if Ekind (E) = E_Access_Subprogram_Type then
                  Set_Convention_From_Pragma (Directly_Designated_Type (E));
               end if;
            end if;

         --  For the subprogram case, set proper convention for all homonyms
         --  in same scope and the same declarative part, i.e. the same
         --  compilation unit.

         else
            --  Treat a pragma Import as an implicit body, and pragma import
            --  as implicit reference (for navigation in GNAT Studio).

            if Prag_Id = Pragma_Import then
               Generate_Reference (E, Id, 'b');

            --  For exported entities we restrict the generation of references
            --  to entities exported to foreign languages since entities
            --  exported to Ada do not provide further information to
            --  GNAT Studio and add undesired references to the output of the
            --  gnatxref tool.

            elsif Prag_Id = Pragma_Export
              and then Convention (E) /= Convention_Ada
            then
               Generate_Reference (E, Id, 'i');
            end if;

            --  If the pragma comes from an aspect, it only applies to the
            --  given entity, not its homonyms.

            if From_Aspect_Specification (N) then
               if C = Convention_Intrinsic
                 and then Nkind (Ent) = N_Defining_Operator_Symbol
               then
                  if Is_Fixed_Point_Type (Etype (Ent))
                    or else Is_Fixed_Point_Type (Etype (First_Entity (Ent)))
                    or else Is_Fixed_Point_Type (Etype (Last_Entity (Ent)))
                  then
                     Error_Msg_N
                       ("no intrinsic operator available for this fixed-point "
                        & "operation", N);
                     Error_Msg_N
                       ("\use expression functions with the desired "
                        & "conversions made explicit", N);
                  end if;
               end if;

               return;
            end if;

            --  Otherwise Loop through the homonyms of the pragma argument's
            --  entity, an apply convention to those in the current scope.

            Comp_Unit := Get_Source_Unit (E);
            E1 := Ent;

            loop
               E1 := Homonym (E1);
               exit when No (E1) or else Scope (E1) /= Current_Scope;

               --  Ignore entry for which convention is already set

               if Has_Convention_Pragma (E1) then
                  goto Continue;
               end if;

               if Is_Subprogram (E1)
                 and then Nkind (Parent (Declaration_Node (E1))) =
                            N_Subprogram_Body
                 and then not Relaxed_RM_Semantics
               then
                  Set_Has_Completion (E);  --  to prevent cascaded error
                  Error_Pragma_Ref
                    ("pragma% requires separate spec and must come before "
                     & "body#", E1);
               end if;

               --  Do not set the pragma on inherited operations or on formal
               --  subprograms.

               if Comes_From_Source (E1)
                 and then Comp_Unit = Get_Source_Unit (E1)
                 and then not Is_Formal_Subprogram (E1)
                 and then Nkind (Original_Node (Parent (E1))) /=
                                                    N_Full_Type_Declaration
               then
                  if Present (Alias (E1))
                    and then Scope (E1) /= Scope (Alias (E1))
                  then
                     Error_Pragma_Ref
                       ("cannot apply pragma% to non-local entity& declared#",
                        E1);
                  end if;

                  Set_Convention_From_Pragma (E1);

                  if Prag_Id = Pragma_Import then
                     Generate_Reference (E1, Id, 'b');
                  end if;
               end if;

            <<Continue>>
               null;
            end loop;
         end if;
      end Process_Convention;

      ----------------------------------------
      -- Process_Disable_Enable_Atomic_Sync --
      ----------------------------------------

      procedure Process_Disable_Enable_Atomic_Sync (Nam : Name_Id) is
      begin
         Check_No_Identifiers;
         Check_At_Most_N_Arguments (1);

         --  Modeled internally as
         --    pragma Suppress/Unsuppress (Atomic_Synchronization [,Entity])

         Rewrite (N,
           Make_Pragma (Loc,
             Chars                        => Nam,
             Pragma_Argument_Associations => New_List (
               Make_Pragma_Argument_Association (Loc,
                 Expression =>
                   Make_Identifier (Loc, Name_Atomic_Synchronization)))));

         if Present (Arg1) then
            Append_To (Pragma_Argument_Associations (N), New_Copy (Arg1));
         end if;

         Analyze (N);
      end Process_Disable_Enable_Atomic_Sync;

      -------------------------------------------------
      -- Process_Extended_Import_Export_Internal_Arg --
      -------------------------------------------------

      procedure Process_Extended_Import_Export_Internal_Arg
        (Arg_Internal : Node_Id := Empty)
      is
      begin
         if No (Arg_Internal) then
            Error_Pragma ("Internal parameter required for pragma%");
         end if;

         if Nkind (Arg_Internal) = N_Identifier then
            null;

         elsif Nkind (Arg_Internal) = N_Operator_Symbol
           and then (Prag_Id = Pragma_Import_Function
                       or else
                     Prag_Id = Pragma_Export_Function)
         then
            null;

         else
            Error_Pragma_Arg
              ("wrong form for Internal parameter for pragma%", Arg_Internal);
         end if;

         Check_Arg_Is_Local_Name (Arg_Internal);
      end Process_Extended_Import_Export_Internal_Arg;

      --------------------------------------------------
      -- Process_Extended_Import_Export_Object_Pragma --
      --------------------------------------------------

      procedure Process_Extended_Import_Export_Object_Pragma
        (Arg_Internal : Node_Id;
         Arg_External : Node_Id;
         Arg_Size     : Node_Id)
      is
         Def_Id : Entity_Id;

      begin
         Process_Extended_Import_Export_Internal_Arg (Arg_Internal);
         Def_Id := Entity (Arg_Internal);

         if Ekind (Def_Id) not in E_Constant | E_Variable then
            Error_Pragma_Arg
              ("pragma% must designate an object", Arg_Internal);
         end if;

         if Has_Rep_Pragma (Def_Id, Name_Common_Object)
              or else
            Has_Rep_Pragma (Def_Id, Name_Psect_Object)
         then
            Error_Pragma_Arg
              ("previous Common/Psect_Object applies, pragma % not permitted",
               Arg_Internal);
         end if;

         if Rep_Item_Too_Late (Def_Id, N) then
            raise Pragma_Exit;
         end if;

         Set_Extended_Import_Export_External_Name (Def_Id, Arg_External);

         if Present (Arg_Size) then
            Check_Arg_Is_External_Name (Arg_Size);
         end if;

         --  Export_Object case

         if Prag_Id = Pragma_Export_Object then
            if not Is_Library_Level_Entity (Def_Id) then
               Error_Pragma_Arg
                 ("argument for pragma% must be library level entity",
                  Arg_Internal);
            end if;

            if Ekind (Current_Scope) = E_Generic_Package then
               Error_Pragma ("pragma& cannot appear in a generic unit");
            end if;

            if not Size_Known_At_Compile_Time (Etype (Def_Id)) then
               Error_Pragma_Arg
                 ("exported object must have compile time known size",
                  Arg_Internal);
            end if;

            if Warn_On_Export_Import and then Is_Exported (Def_Id) then
               Error_Msg_N ("??duplicate Export_Object pragma", N);
            else
               Set_Exported (Def_Id, Arg_Internal);
            end if;

         --  Import_Object case

         else
            if Is_Concurrent_Type (Etype (Def_Id)) then
               Error_Pragma_Arg
                 ("cannot use pragma% for task/protected object",
                  Arg_Internal);
            end if;

            if Ekind (Def_Id) = E_Constant then
               Error_Pragma_Arg
                 ("cannot import a constant", Arg_Internal);
            end if;

            if Warn_On_Export_Import
              and then Has_Discriminants (Etype (Def_Id))
            then
               Error_Msg_N
                 ("imported value must be initialized??", Arg_Internal);
            end if;

            if Warn_On_Export_Import
              and then Is_Access_Type (Etype (Def_Id))
            then
               Error_Pragma_Arg
                 ("cannot import object of an access type??", Arg_Internal);
            end if;

            if Warn_On_Export_Import
              and then Is_Imported (Def_Id)
            then
               Error_Msg_N ("??duplicate Import_Object pragma", N);

            --  Check for explicit initialization present. Note that an
            --  initialization generated by the code generator, e.g. for an
            --  access type, does not count here.

            elsif Present (Expression (Parent (Def_Id)))
               and then
                 Comes_From_Source
                   (Original_Node (Expression (Parent (Def_Id))))
            then
               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Pragma_Arg
                 ("imported entities cannot be initialized (RM B.1(24))",
                  "\no initialization allowed for & declared#", Arg1);
            else
               Set_Imported (Def_Id);
               Note_Possible_Modification (Arg_Internal, Sure => False);
            end if;
         end if;
      end Process_Extended_Import_Export_Object_Pragma;

      ------------------------------------------------------
      -- Process_Extended_Import_Export_Subprogram_Pragma --
      ------------------------------------------------------

      procedure Process_Extended_Import_Export_Subprogram_Pragma
        (Arg_Internal                 : Node_Id;
         Arg_External                 : Node_Id;
         Arg_Parameter_Types          : Node_Id;
         Arg_Result_Type              : Node_Id := Empty;
         Arg_Mechanism                : Node_Id;
         Arg_Result_Mechanism         : Node_Id := Empty)
      is
         Ent       : Entity_Id;
         Def_Id    : Entity_Id;
         Hom_Id    : Entity_Id;
         Formal    : Entity_Id;
         Ambiguous : Boolean;
         Match     : Boolean;

         function Same_Base_Type
          (Ptype  : Node_Id;
           Formal : Entity_Id) return Boolean;
         --  Determines if Ptype references the type of Formal. Note that only
         --  the base types need to match according to the spec. Ptype here is
         --  the argument from the pragma, which is either a type name, or an
         --  access attribute.

         --------------------
         -- Same_Base_Type --
         --------------------

         function Same_Base_Type
           (Ptype  : Node_Id;
            Formal : Entity_Id) return Boolean
         is
            Ftyp : constant Entity_Id := Base_Type (Etype (Formal));
            Pref : Node_Id;

         begin
            --  Case where pragma argument is typ'Access

            if Nkind (Ptype) = N_Attribute_Reference
              and then Attribute_Name (Ptype) = Name_Access
            then
               Pref := Prefix (Ptype);
               Find_Type (Pref);

               if not Is_Entity_Name (Pref)
                 or else Entity (Pref) = Any_Type
               then
                  raise Pragma_Exit;
               end if;

               --  We have a match if the corresponding argument is of an
               --  anonymous access type, and its designated type matches the
               --  type of the prefix of the access attribute

               return Ekind (Ftyp) = E_Anonymous_Access_Type
                 and then Base_Type (Entity (Pref)) =
                            Base_Type (Etype (Designated_Type (Ftyp)));

            --  Case where pragma argument is a type name

            else
               Find_Type (Ptype);

               if not Is_Entity_Name (Ptype)
                 or else Entity (Ptype) = Any_Type
               then
                  raise Pragma_Exit;
               end if;

               --  We have a match if the corresponding argument is of the type
               --  given in the pragma (comparing base types)

               return Base_Type (Entity (Ptype)) = Ftyp;
            end if;
         end Same_Base_Type;

      --  Start of processing for
      --  Process_Extended_Import_Export_Subprogram_Pragma

      begin
         Process_Extended_Import_Export_Internal_Arg (Arg_Internal);
         Ent := Empty;
         Ambiguous := False;

         --  Loop through homonyms (overloadings) of the entity

         Hom_Id := Entity (Arg_Internal);
         while Present (Hom_Id) loop
            Def_Id := Get_Base_Subprogram (Hom_Id);

            --  We need a subprogram in the current scope

            if not Is_Subprogram (Def_Id)
              or else Scope (Def_Id) /= Current_Scope
            then
               null;

            else
               Match := True;

               --  Pragma cannot apply to subprogram body

               if Is_Subprogram (Def_Id)
                 and then Nkind (Parent (Declaration_Node (Def_Id))) =
                                                             N_Subprogram_Body
               then
                  Error_Pragma
                    ("pragma% requires separate spec and must come before "
                     & "body");
               end if;

               --  Test result type if given, note that the result type
               --  parameter can only be present for the function cases.

               if Present (Arg_Result_Type)
                 and then not Same_Base_Type (Arg_Result_Type, Def_Id)
               then
                  Match := False;

               elsif Etype (Def_Id) /= Standard_Void_Type
                 and then
                   Pname in Name_Export_Procedure | Name_Import_Procedure
               then
                  Match := False;

               --  Test parameter types if given. Note that this parameter has
               --  not been analyzed (and must not be, since it is semantic
               --  nonsense), so we get it as the parser left it.

               elsif Present (Arg_Parameter_Types) then
                  Check_Matching_Types : declare
                     Formal : Entity_Id;
                     Ptype  : Node_Id;

                  begin
                     Formal := First_Formal (Def_Id);

                     if Nkind (Arg_Parameter_Types) = N_Null then
                        if Present (Formal) then
                           Match := False;
                        end if;

                     --  A list of one type, e.g. (List) is parsed as a
                     --  parenthesized expression.

                     elsif Nkind (Arg_Parameter_Types) /= N_Aggregate
                       and then Paren_Count (Arg_Parameter_Types) = 1
                     then
                        if No (Formal)
                          or else Present (Next_Formal (Formal))
                        then
                           Match := False;
                        else
                           Match :=
                             Same_Base_Type (Arg_Parameter_Types, Formal);
                        end if;

                     --  A list of more than one type is parsed as a aggregate

                     elsif Nkind (Arg_Parameter_Types) = N_Aggregate
                       and then Paren_Count (Arg_Parameter_Types) = 0
                     then
                        Ptype := First (Expressions (Arg_Parameter_Types));
                        while Present (Ptype) or else Present (Formal) loop
                           if No (Ptype)
                             or else No (Formal)
                             or else not Same_Base_Type (Ptype, Formal)
                           then
                              Match := False;
                              exit;
                           else
                              Next_Formal (Formal);
                              Next (Ptype);
                           end if;
                        end loop;

                     --  Anything else is of the wrong form

                     else
                        Error_Pragma_Arg
                          ("wrong form for Parameter_Types parameter",
                           Arg_Parameter_Types);
                     end if;
                  end Check_Matching_Types;
               end if;

               --  Match is now False if the entry we found did not match
               --  either a supplied Parameter_Types or Result_Types argument

               if Match then
                  if No (Ent) then
                     Ent := Def_Id;

                  --  Ambiguous case, the flag Ambiguous shows if we already
                  --  detected this and output the initial messages.

                  else
                     if not Ambiguous then
                        Ambiguous := True;
                        Error_Msg_Name_1 := Pname;
                        Error_Msg_N
                          ("pragma% does not uniquely identify subprogram!",
                           N);
                        Error_Msg_Sloc := Sloc (Ent);
                        Error_Msg_N ("matching subprogram #!", N);
                        Ent := Empty;
                     end if;

                     Error_Msg_Sloc := Sloc (Def_Id);
                     Error_Msg_N ("matching subprogram #!", N);
                  end if;
               end if;
            end if;

            Hom_Id := Homonym (Hom_Id);
         end loop;

         --  See if we found an entry

         if No (Ent) then
            if not Ambiguous then
               if Is_Generic_Subprogram (Entity (Arg_Internal)) then
                  Error_Pragma
                    ("pragma% cannot be given for generic subprogram");
               else
                  Error_Pragma
                    ("pragma% does not identify local subprogram");
               end if;
            end if;

            return;
         end if;

         --  Import pragmas must be for imported entities

         if Prag_Id = Pragma_Import_Function
              or else
            Prag_Id = Pragma_Import_Procedure
              or else
            Prag_Id = Pragma_Import_Valued_Procedure
         then
            if not Is_Imported (Ent) then
               Error_Pragma
                 ("pragma Import or Interface must precede pragma%");
            end if;

         --  Here we have the Export case which can set the entity as exported

         --  But does not do so if the specified external name is null, since
         --  that is taken as a signal in DEC Ada 83 (with which we want to be
         --  compatible) to request no external name.

         elsif Nkind (Arg_External) = N_String_Literal
           and then String_Length (Strval (Arg_External)) = 0
         then
            null;

         --  In all other cases, set entity as exported

         else
            Set_Exported (Ent, Arg_Internal);
         end if;

         --  Special processing for Valued_Procedure cases

         if Prag_Id = Pragma_Import_Valued_Procedure
           or else
            Prag_Id = Pragma_Export_Valued_Procedure
         then
            Formal := First_Formal (Ent);

            if No (Formal) then
               Error_Pragma ("at least one parameter required for pragma%");

            elsif Ekind (Formal) /= E_Out_Parameter then
               Error_Pragma ("first parameter must have mode OUT for pragma%");

            else
               Set_Is_Valued_Procedure (Ent);
            end if;
         end if;

         Set_Extended_Import_Export_External_Name (Ent, Arg_External);

         --  Process Result_Mechanism argument if present. We have already
         --  checked that this is only allowed for the function case.

         if Present (Arg_Result_Mechanism) then
            Set_Mechanism_Value (Ent, Arg_Result_Mechanism);
         end if;

         --  Process Mechanism parameter if present. Note that this parameter
         --  is not analyzed, and must not be analyzed since it is semantic
         --  nonsense, so we get it in exactly as the parser left it.

         if Present (Arg_Mechanism) then
            declare
               Formal : Entity_Id;
               Massoc : Node_Id;
               Mname  : Node_Id;
               Choice : Node_Id;

            begin
               --  A single mechanism association without a formal parameter
               --  name is parsed as a parenthesized expression. All other
               --  cases are parsed as aggregates, so we rewrite the single
               --  parameter case as an aggregate for consistency.

               if Nkind (Arg_Mechanism) /= N_Aggregate
                 and then Paren_Count (Arg_Mechanism) = 1
               then
                  Rewrite (Arg_Mechanism,
                    Make_Aggregate (Sloc (Arg_Mechanism),
                      Expressions => New_List (
                        Relocate_Node (Arg_Mechanism))));
               end if;

               --  Case of only mechanism name given, applies to all formals

               if Nkind (Arg_Mechanism) /= N_Aggregate then
                  Formal := First_Formal (Ent);
                  while Present (Formal) loop
                     Set_Mechanism_Value (Formal, Arg_Mechanism);
                     Next_Formal (Formal);
                  end loop;

               --  Case of list of mechanism associations given

               else
                  if Null_Record_Present (Arg_Mechanism) then
                     Error_Pragma_Arg
                       ("inappropriate form for Mechanism parameter",
                        Arg_Mechanism);
                  end if;

                  --  Deal with positional ones first

                  Formal := First_Formal (Ent);

                  if Present (Expressions (Arg_Mechanism)) then
                     Mname := First (Expressions (Arg_Mechanism));
                     while Present (Mname) loop
                        if No (Formal) then
                           Error_Pragma_Arg
                             ("too many mechanism associations", Mname);
                        end if;

                        Set_Mechanism_Value (Formal, Mname);
                        Next_Formal (Formal);
                        Next (Mname);
                     end loop;
                  end if;

                  --  Deal with named entries

                  if Present (Component_Associations (Arg_Mechanism)) then
                     Massoc := First (Component_Associations (Arg_Mechanism));
                     while Present (Massoc) loop
                        Choice := First (Choices (Massoc));

                        if Nkind (Choice) /= N_Identifier
                          or else Present (Next (Choice))
                        then
                           Error_Pragma_Arg
                             ("incorrect form for mechanism association",
                              Massoc);
                        end if;

                        Formal := First_Formal (Ent);
                        loop
                           if No (Formal) then
                              Error_Pragma_Arg
                                ("parameter name & not present", Choice);
                           end if;

                           if Chars (Choice) = Chars (Formal) then
                              Set_Mechanism_Value
                                (Formal, Expression (Massoc));

                              --  Set entity on identifier for proper tree
                              --  structure.

                              Set_Entity (Choice, Formal);

                              exit;
                           end if;

                           Next_Formal (Formal);
                        end loop;

                        Next (Massoc);
                     end loop;
                  end if;
               end if;
            end;
         end if;
      end Process_Extended_Import_Export_Subprogram_Pragma;

      --------------------------
      -- Process_Generic_List --
      --------------------------

      procedure Process_Generic_List is
         Arg : Node_Id;
         Exp : Node_Id;

      begin
         Check_No_Identifiers;
         Check_At_Least_N_Arguments (1);

         --  Check all arguments are names of generic units or instances

         Arg := Arg1;
         while Present (Arg) loop
            Exp := Get_Pragma_Arg (Arg);
            Analyze (Exp);

            if not Is_Entity_Name (Exp)
              or else
                (not Is_Generic_Instance (Entity (Exp))
                  and then
                 not Is_Generic_Unit (Entity (Exp)))
            then
               Error_Pragma_Arg
                 ("pragma% argument must be name of generic unit/instance",
                  Arg);
            end if;

            Next (Arg);
         end loop;
      end Process_Generic_List;

      ------------------------------------
      -- Process_Import_Predefined_Type --
      ------------------------------------

      procedure Process_Import_Predefined_Type is
         Loc  : constant Source_Ptr := Sloc (N);
         Elmt : Elmt_Id;
         Ftyp : Node_Id := Empty;
         Decl : Node_Id;
         Def  : Node_Id;
         Nam  : Name_Id;

      begin
         Nam := String_To_Name (Strval (Expression (Arg3)));

         Elmt := First_Elmt (Predefined_Float_Types);
         while Present (Elmt) and then Chars (Node (Elmt)) /= Nam loop
            Next_Elmt (Elmt);
         end loop;

         Ftyp := Node (Elmt);

         if Present (Ftyp) then

            --  Don't build a derived type declaration, because predefined C
            --  types have no declaration anywhere, so cannot really be named.
            --  Instead build a full type declaration, starting with an
            --  appropriate type definition is built

            if Is_Floating_Point_Type (Ftyp) then
               Def := Make_Floating_Point_Definition (Loc,
                 Make_Integer_Literal (Loc, Digits_Value (Ftyp)),
                 Make_Real_Range_Specification (Loc,
                   Make_Real_Literal (Loc, Realval (Type_Low_Bound (Ftyp))),
                   Make_Real_Literal (Loc, Realval (Type_High_Bound (Ftyp)))));

            --  Should never have a predefined type we cannot handle

            else
               raise Program_Error;
            end if;

            --  Build and insert a Full_Type_Declaration, which will be
            --  analyzed as soon as this list entry has been analyzed.

            Decl := Make_Full_Type_Declaration (Loc,
              Make_Defining_Identifier (Loc, Chars (Expression (Arg2))),
              Type_Definition => Def);

            Insert_After (N, Decl);
            Mark_Rewrite_Insertion (Decl);

         else
            Error_Pragma_Arg ("no matching type found for pragma%", Arg2);
         end if;
      end Process_Import_Predefined_Type;

      ---------------------------------
      -- Process_Import_Or_Interface --
      ---------------------------------

      procedure Process_Import_Or_Interface is
         C      : Convention_Id;
         Def_Id : Entity_Id;
         Hom_Id : Entity_Id;

      begin
         --  In Relaxed_RM_Semantics, support old Ada 83 style:
         --  pragma Import (Entity, "external name");

         if Relaxed_RM_Semantics
           and then Arg_Count = 2
           and then Prag_Id = Pragma_Import
           and then Nkind (Expression (Arg2)) = N_String_Literal
         then
            C := Convention_C;
            Def_Id := Get_Pragma_Arg (Arg1);
            Analyze (Def_Id);

            if not Is_Entity_Name (Def_Id) then
               Error_Pragma_Arg ("entity name required", Arg1);
            end if;

            Def_Id := Entity (Def_Id);
            Kill_Size_Check_Code (Def_Id);
            if Ekind (Def_Id) /= E_Constant then
               Note_Possible_Modification
                 (Get_Pragma_Arg (Arg1), Sure => False);
            end if;

         else
            Process_Convention (C, Def_Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Def_Id);
            Kill_Size_Check_Code (Def_Id);
            if Ekind (Def_Id) /= E_Constant then
               Note_Possible_Modification
                 (Get_Pragma_Arg (Arg2), Sure => False);
            end if;
         end if;

         --  Various error checks

         if Ekind (Def_Id) in E_Variable | E_Constant then

            --  We do not permit Import to apply to a renaming declaration

            if Present (Renamed_Object (Def_Id)) then
               Error_Pragma_Arg
                 ("pragma% not allowed for object renaming", Arg2);

            --  User initialization is not allowed for imported object, but
            --  the object declaration may contain a default initialization,
            --  that will be discarded. Note that an explicit initialization
            --  only counts if it comes from source, otherwise it is simply
            --  the code generator making an implicit initialization explicit.

            elsif Present (Expression (Parent (Def_Id)))
              and then Comes_From_Source
                         (Original_Node (Expression (Parent (Def_Id))))
            then
               --  Set imported flag to prevent cascaded errors

               Set_Is_Imported (Def_Id);

               Error_Msg_Sloc := Sloc (Def_Id);
               Error_Pragma_Arg
                 ("no initialization allowed for declaration of& #",
                  "\imported entities cannot be initialized (RM B.1(24))",
                  Arg2);

            else
               --  If the pragma comes from an aspect specification the
               --  Is_Imported flag has already been set.

               if not From_Aspect_Specification (N) then
                  Set_Imported (Def_Id);
               end if;

               Process_Interface_Name (Def_Id, Arg3, Arg4, N);

               --  Note that we do not set Is_Public here. That's because we
               --  only want to set it if there is no address clause, and we
               --  don't know that yet, so we delay that processing till
               --  freeze time.

               --  pragma Import completes deferred constants

               if Ekind (Def_Id) = E_Constant then
                  Set_Has_Completion (Def_Id);
               end if;

               --  It is not possible to import a constant of an unconstrained
               --  array type (e.g. string) because there is no simple way to
               --  write a meaningful subtype for it.

               if Is_Array_Type (Etype (Def_Id))
                 and then not Is_Constrained (Etype (Def_Id))
               then
                  Error_Msg_NE
                    ("imported constant& must have a constrained subtype",
                      N, Def_Id);
               end if;
            end if;

         elsif Is_Subprogram_Or_Generic_Subprogram (Def_Id) then

            --  If the name is overloaded, pragma applies to all of the denoted
            --  entities in the same declarative part, unless the pragma comes
            --  from an aspect specification or was generated by the compiler
            --  (such as for pragma Provide_Shift_Operators).

            Hom_Id := Def_Id;
            while Present (Hom_Id) loop

               Def_Id := Get_Base_Subprogram (Hom_Id);

               --  Ignore inherited subprograms because the pragma will apply
               --  to the parent operation, which is the one called.

               if Is_Overloadable (Def_Id)
                 and then Present (Alias (Def_Id))
               then
                  null;

               --  If it is not a subprogram, it must be in an outer scope and
               --  pragma does not apply.

               elsif not Is_Subprogram_Or_Generic_Subprogram (Def_Id) then
                  null;

               --  The pragma does not apply to primitives of interfaces

               elsif Is_Dispatching_Operation (Def_Id)
                 and then Present (Find_Dispatching_Type (Def_Id))
                 and then Is_Interface (Find_Dispatching_Type (Def_Id))
               then
                  null;

               --  Verify that the homonym is in the same declarative part (not
               --  just the same scope). If the pragma comes from an aspect
               --  specification we know that it is part of the declaration.

               elsif (No (Unit_Declaration_Node (Def_Id))
                        or else Parent (Unit_Declaration_Node (Def_Id)) /=
                                Parent (N))
                 and then Nkind (Parent (N)) /= N_Compilation_Unit_Aux
                 and then not From_Aspect_Specification (N)
               then
                  exit;

               else
                  --  If the pragma comes from an aspect specification the
                  --  Is_Imported flag has already been set.

                  if not From_Aspect_Specification (N) then
                     Set_Imported (Def_Id);
                  end if;

                  --  Reject an Import applied to an abstract subprogram

                  if Is_Subprogram (Def_Id)
                    and then Is_Abstract_Subprogram (Def_Id)
                  then
                     Error_Msg_Sloc := Sloc (Def_Id);
                     Error_Msg_NE
                       ("cannot import abstract subprogram& declared#",
                        Arg2, Def_Id);
                  end if;

                  --  Special processing for Convention_Intrinsic

                  if C = Convention_Intrinsic then

                     --  Link_Name argument not allowed for intrinsic

                     Check_No_Link_Name;

                     Set_Is_Intrinsic_Subprogram (Def_Id);

                     --  If no external name is present, then check that this
                     --  is a valid intrinsic subprogram. If an external name
                     --  is present, then this is handled by the back end.

                     if No (Arg3) then
                        Check_Intrinsic_Subprogram
                          (Def_Id, Get_Pragma_Arg (Arg2));
                     end if;
                  end if;

                  --  Verify that the subprogram does not have a completion
                  --  through a renaming declaration. For other completions the
                  --  pragma appears as a too late representation.

                  declare
                     Decl : constant Node_Id := Unit_Declaration_Node (Def_Id);

                  begin
                     if Present (Decl)
                       and then Nkind (Decl) = N_Subprogram_Declaration
                       and then Present (Corresponding_Body (Decl))
                       and then Nkind (Unit_Declaration_Node
                                        (Corresponding_Body (Decl))) =
                                             N_Subprogram_Renaming_Declaration
                     then
                        Error_Msg_Sloc := Sloc (Def_Id);
                        Error_Msg_NE
                          ("cannot import&, renaming already provided for "
                           & "declaration #", N, Def_Id);
                     end if;
                  end;

                  --  If the pragma comes from an aspect specification, there
                  --  must be an Import aspect specified as well. In the rare
                  --  case where Import is set to False, the suprogram needs to
                  --  have a local completion.

                  declare
                     Imp_Aspect : constant Node_Id :=
                                    Find_Aspect (Def_Id, Aspect_Import);
                     Expr       : Node_Id;

                  begin
                     if Present (Imp_Aspect)
                       and then Present (Expression (Imp_Aspect))
                     then
                        Expr := Expression (Imp_Aspect);
                        Analyze_And_Resolve (Expr, Standard_Boolean);

                        if Is_Entity_Name (Expr)
                          and then Entity (Expr) = Standard_True
                        then
                           Set_Has_Completion (Def_Id);
                        end if;

                     --  If there is no expression, the default is True, as for
                     --  all boolean aspects. Same for the older pragma.

                     else
                        Set_Has_Completion (Def_Id);
                     end if;
                  end;

                  Process_Interface_Name (Def_Id, Arg3, Arg4, N);
               end if;

               if Is_Compilation_Unit (Hom_Id) then

                  --  Its possible homonyms are not affected by the pragma.
                  --  Such homonyms might be present in the context of other
                  --  units being compiled.

                  exit;

               elsif From_Aspect_Specification (N) then
                  exit;

               --  If the pragma was created by the compiler, then we don't
               --  want it to apply to other homonyms. This kind of case can
               --  occur when using pragma Provide_Shift_Operators, which
               --  generates implicit shift and rotate operators with Import
               --  pragmas that might apply to earlier explicit or implicit
               --  declarations marked with Import (for example, coming from
               --  an earlier pragma Provide_Shift_Operators for another type),
               --  and we don't generally want other homonyms being treated
               --  as imported or the pragma flagged as an illegal duplicate.

               elsif not Comes_From_Source (N) then
                  exit;

               else
                  Hom_Id := Homonym (Hom_Id);
               end if;
            end loop;

         --  Import a CPP class

         elsif C = Convention_CPP
           and then (Is_Record_Type (Def_Id)
                      or else Ekind (Def_Id) = E_Incomplete_Type)
         then
            if Ekind (Def_Id) = E_Incomplete_Type then
               if Present (Full_View (Def_Id)) then
                  Def_Id := Full_View (Def_Id);

               else
                  Error_Msg_N
                    ("cannot import 'C'P'P type before full declaration seen",
                     Get_Pragma_Arg (Arg2));

                  --  Although we have reported the error we decorate it as
                  --  CPP_Class to avoid reporting spurious errors

                  Set_Is_CPP_Class (Def_Id);
                  return;
               end if;
            end if;

            --  Types treated as CPP classes must be declared limited (note:
            --  this used to be a warning but there is no real benefit to it
            --  since we did effectively intend to treat the type as limited
            --  anyway).

            if not Is_Limited_Type (Def_Id) then
               Error_Msg_N
                 ("imported 'C'P'P type must be limited",
                  Get_Pragma_Arg (Arg2));
            end if;

            if Etype (Def_Id) /= Def_Id
              and then not Is_CPP_Class (Root_Type (Def_Id))
            then
               Error_Msg_N ("root type must be a 'C'P'P type", Arg1);
            end if;

            Set_Is_CPP_Class (Def_Id);

            --  Imported CPP types must not have discriminants (because C++
            --  classes do not have discriminants).

            if Has_Discriminants (Def_Id) then
               Error_Msg_N
                 ("imported 'C'P'P type cannot have discriminants",
                  First (Discriminant_Specifications
                          (Declaration_Node (Def_Id))));
            end if;

            --  Check that components of imported CPP types do not have default
            --  expressions. For private types this check is performed when the
            --  full view is analyzed (see Process_Full_View).

            if not Is_Private_Type (Def_Id) then
               Check_CPP_Type_Has_No_Defaults (Def_Id);
            end if;

         --  Import a CPP exception

         elsif C = Convention_CPP
           and then Ekind (Def_Id) = E_Exception
         then
            if No (Arg3) then
               Error_Pragma_Arg
                 ("'External_'Name arguments is required for 'Cpp exception",
                  Arg3);
            else
               --  As only a string is allowed, Check_Arg_Is_External_Name
               --  isn't called.

               Check_Arg_Is_OK_Static_Expression (Arg3, Standard_String);
            end if;

            if Present (Arg4) then
               Error_Pragma_Arg
                 ("Link_Name argument not allowed for imported Cpp exception",
                  Arg4);
            end if;

            --  Do not call Set_Interface_Name as the name of the exception
            --  shouldn't be modified (and in particular it shouldn't be
            --  the External_Name). For exceptions, the External_Name is the
            --  name of the RTTI structure.

            --  ??? Emit an error if pragma Import/Export_Exception is present

         elsif Nkind (Parent (Def_Id)) = N_Incomplete_Type_Declaration then
            Check_No_Link_Name;
            Check_Arg_Count (3);
            Check_Arg_Is_OK_Static_Expression (Arg3, Standard_String);

            Process_Import_Predefined_Type;

         --  Emit an error unless Relaxed_RM_Semantics since some legacy Ada
         --  compilers may accept more cases, e.g. JGNAT allowed importing
         --  a Java package.

         elsif not Relaxed_RM_Semantics then
            if From_Aspect_Specification (N) then
               Error_Pragma_Arg
                  ("entity for aspect% must be object, subprogram "
                     & "or incomplete type",
                   Arg2);
            else
               Error_Pragma_Arg
                  ("second argument of pragma% must be object, subprogram "
                     & "or incomplete type",
                   Arg2);
            end if;
         end if;

         --  If this pragma applies to a compilation unit, then the unit, which
         --  is a subprogram, does not require (or allow) a body. We also do
         --  not need to elaborate imported procedures.

         if Nkind (Parent (N)) = N_Compilation_Unit_Aux then
            declare
               Cunit : constant Node_Id := Parent (Parent (N));
            begin
               Set_Body_Required (Cunit, False);
            end;
         end if;
      end Process_Import_Or_Interface;

      --------------------
      -- Process_Inline --
      --------------------

      procedure Process_Inline (Status : Inline_Status) is
         Applies : Boolean;
         Assoc   : Node_Id;
         Decl    : Node_Id;
         Subp    : Entity_Id;
         Subp_Id : Node_Id;

         Ghost_Error_Posted : Boolean := False;
         --  Flag set when an error concerning the illegal mix of Ghost and
         --  non-Ghost subprograms is emitted.

         Ghost_Id : Entity_Id := Empty;
         --  The entity of the first Ghost subprogram encountered while
         --  processing the arguments of the pragma.

         procedure Check_Inline_Always_Placement (Spec_Id : Entity_Id);
         --  Verify the placement of pragma Inline_Always with respect to the
         --  initial declaration of subprogram Spec_Id.

         function Inlining_Not_Possible (Subp : Entity_Id) return Boolean;
         --  Returns True if it can be determined at this stage that inlining
         --  is not possible, for example if the body is available and contains
         --  exception handlers, we prevent inlining, since otherwise we can
         --  get undefined symbols at link time. This function also emits a
         --  warning if the pragma appears too late.
         --
         --  ??? is business with link symbols still valid, or does it relate
         --  to front end ZCX which is being phased out ???

         procedure Make_Inline (Subp : Entity_Id);
         --  Subp is the defining unit name of the subprogram declaration. If
         --  the pragma is valid, call Set_Inline_Flags on Subp, as well as on
         --  the corresponding body, if there is one present.

         procedure Set_Inline_Flags (Subp : Entity_Id);
         --  Set Has_Pragma_{No_Inline,Inline,Inline_Always} flag on Subp.
         --  Also set or clear Is_Inlined flag on Subp depending on Status.

         -----------------------------------
         -- Check_Inline_Always_Placement --
         -----------------------------------

         procedure Check_Inline_Always_Placement (Spec_Id : Entity_Id) is
            Spec_Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);

            function Compilation_Unit_OK return Boolean;
            pragma Inline (Compilation_Unit_OK);
            --  Determine whether pragma Inline_Always applies to a compatible
            --  compilation unit denoted by Spec_Id.

            function Declarative_List_OK return Boolean;
            pragma Inline (Declarative_List_OK);
            --  Determine whether the initial declaration of subprogram Spec_Id
            --  and the pragma appear in compatible declarative lists.

            function Subprogram_Body_OK return Boolean;
            pragma Inline (Subprogram_Body_OK);
            --  Determine whether pragma Inline_Always applies to a compatible
            --  subprogram body denoted by Spec_Id.

            -------------------------
            -- Compilation_Unit_OK --
            -------------------------

            function Compilation_Unit_OK return Boolean is
               Comp_Unit : constant Node_Id := Parent (Spec_Decl);

            begin
               --  The pragma appears after the initial declaration of a
               --  compilation unit.

               --    procedure Comp_Unit;
               --    pragma Inline_Always (Comp_Unit);

               --  Note that for compatibility reasons, the following case is
               --  also accepted.

               --    procedure Stand_Alone_Body_Comp_Unit is
               --       ...
               --    end Stand_Alone_Body_Comp_Unit;
               --    pragma Inline_Always (Stand_Alone_Body_Comp_Unit);

               return
                 Nkind (Comp_Unit) = N_Compilation_Unit
                   and then Present (Aux_Decls_Node (Comp_Unit))
                   and then Is_List_Member (N)
                   and then List_Containing (N) =
                              Pragmas_After (Aux_Decls_Node (Comp_Unit));
            end Compilation_Unit_OK;

            -------------------------
            -- Declarative_List_OK --
            -------------------------

            function Declarative_List_OK return Boolean is
               Context : constant Node_Id := Parent (Spec_Decl);

               Init_Decl : Node_Id;
               Init_List : List_Id;
               Prag_List : List_Id;

            begin
               --  Determine the proper initial declaration. In general this is
               --  the declaration node of the subprogram except when the input
               --  denotes a generic instantiation.

               --    procedure Inst is new Gen;
               --    pragma Inline_Always (Inst);

               --  In this case the original subprogram is moved inside an
               --  anonymous package while pragma Inline_Always remains at the
               --  level of the anonymous package. Use the declaration of the
               --  package because it reflects the placement of the original
               --  instantiation.

               --    package Anon_Pack is
               --       procedure Inst is ... end Inst;  --  original
               --    end Anon_Pack;

               --    procedure Inst renames Anon_Pack.Inst;
               --    pragma Inline_Always (Inst);

               if Is_Generic_Instance (Spec_Id) then
                  Init_Decl := Parent (Parent (Spec_Decl));
                  pragma Assert (Nkind (Init_Decl) = N_Package_Declaration);
               else
                  Init_Decl := Spec_Decl;
               end if;

               if Is_List_Member (Init_Decl) and then Is_List_Member (N) then
                  Init_List := List_Containing (Init_Decl);
                  Prag_List := List_Containing (N);

                  --  The pragma and then initial declaration appear within the
                  --  same declarative list.

                  if Init_List = Prag_List then
                     return True;

                  --  A special case of the above is when both the pragma and
                  --  the initial declaration appear in different lists of a
                  --  package spec, protected definition, or a task definition.

                  --    package Pack is
                  --       procedure Proc;
                  --    private
                  --       pragma Inline_Always (Proc);
                  --    end Pack;

                  elsif Nkind (Context) in N_Package_Specification
                                         | N_Protected_Definition
                                         | N_Task_Definition
                    and then Init_List = Visible_Declarations (Context)
                    and then Prag_List = Private_Declarations (Context)
                  then
                     return True;
                  end if;
               end if;

               return False;
            end Declarative_List_OK;

            ------------------------
            -- Subprogram_Body_OK --
            ------------------------

            function Subprogram_Body_OK return Boolean is
               Body_Decl : Node_Id;

            begin
               --  The pragma appears within the declarative list of a stand-
               --  alone subprogram body.

               --    procedure Stand_Alone_Body is
               --       pragma Inline_Always (Stand_Alone_Body);
               --    begin
               --       ...
               --    end Stand_Alone_Body;

               --  The compiler creates a dummy spec in this case, however the
               --  pragma remains within the declarative list of the body.

               if Nkind (Spec_Decl) = N_Subprogram_Declaration
                 and then not Comes_From_Source (Spec_Decl)
                 and then Present (Corresponding_Body (Spec_Decl))
               then
                  Body_Decl :=
                    Unit_Declaration_Node (Corresponding_Body (Spec_Decl));

                  if Present (Declarations (Body_Decl))
                    and then Is_List_Member (N)
                    and then List_Containing (N) = Declarations (Body_Decl)
                  then
                     return True;
                  end if;
               end if;

               return False;
            end Subprogram_Body_OK;

         --  Start of processing for Check_Inline_Always_Placement

         begin
            --  This check is relevant only for pragma Inline_Always

            if Pname /= Name_Inline_Always then
               return;

            --  Nothing to do when the pragma is internally generated on the
            --  assumption that it is properly placed.

            elsif not Comes_From_Source (N) then
               return;

            --  Nothing to do for internally generated subprograms that act
            --  as accidental homonyms of a source subprogram being inlined.

            elsif not Comes_From_Source (Spec_Id) then
               return;

            --  Nothing to do for generic formal subprograms that act as
            --  homonyms of another source subprogram being inlined.

            elsif Is_Formal_Subprogram (Spec_Id) then
               return;

            elsif Compilation_Unit_OK
              or else Declarative_List_OK
              or else Subprogram_Body_OK
            then
               return;
            end if;

            --  At this point it is known that the pragma applies to or appears
            --  within a completing body, a completing stub, or a subunit.

            Error_Msg_Name_1 := Pname;
            Error_Msg_Name_2 := Chars (Spec_Id);
            Error_Msg_Sloc   := Sloc (Spec_Id);

            Error_Msg_N
              ("pragma % must appear on initial declaration of subprogram "
               & "% defined #", N);
         end Check_Inline_Always_Placement;

         ---------------------------
         -- Inlining_Not_Possible --
         ---------------------------

         function Inlining_Not_Possible (Subp : Entity_Id) return Boolean is
            Decl  : constant Node_Id := Unit_Declaration_Node (Subp);
            Stats : Node_Id;

         begin
            if Nkind (Decl) = N_Subprogram_Body then
               Stats := Handled_Statement_Sequence (Decl);
               return Present (Exception_Handlers (Stats))
                 or else Present (At_End_Proc (Stats));

            elsif Nkind (Decl) = N_Subprogram_Declaration
              and then Present (Corresponding_Body (Decl))
            then
               if Analyzed (Corresponding_Body (Decl)) then
                  Error_Msg_N ("pragma appears too late, ignored??", N);
                  return True;

               --  If the subprogram is a renaming as body, the body is just a
               --  call to the renamed subprogram, and inlining is trivially
               --  possible.

               elsif
                 Nkind (Unit_Declaration_Node (Corresponding_Body (Decl))) =
                                             N_Subprogram_Renaming_Declaration
               then
                  return False;

               else
                  Stats :=
                    Handled_Statement_Sequence
                        (Unit_Declaration_Node (Corresponding_Body (Decl)));

                  return
                    Present (Exception_Handlers (Stats))
                      or else Present (At_End_Proc (Stats));
               end if;

            else
               --  If body is not available, assume the best, the check is
               --  performed again when compiling enclosing package bodies.

               return False;
            end if;
         end Inlining_Not_Possible;

         -----------------
         -- Make_Inline --
         -----------------

         procedure Make_Inline (Subp : Entity_Id) is
            Kind       : constant Entity_Kind := Ekind (Subp);
            Inner_Subp : Entity_Id   := Subp;

         begin
            --  Ignore if bad type, avoid cascaded error

            if Etype (Subp) = Any_Type then
               Applies := True;
               return;

            --  If inlining is not possible, for now do not treat as an error

            elsif Status /= Suppressed
              and then Front_End_Inlining
              and then Inlining_Not_Possible (Subp)
            then
               Applies := True;
               return;

            --  Here we have a candidate for inlining, but we must exclude
            --  derived operations. Otherwise we would end up trying to inline
            --  a phantom declaration, and the result would be to drag in a
            --  body which has no direct inlining associated with it. That
            --  would not only be inefficient but would also result in the
            --  backend doing cross-unit inlining in cases where it was
            --  definitely inappropriate to do so.

            --  However, a simple Comes_From_Source test is insufficient, since
            --  we do want to allow inlining of generic instances which also do
            --  not come from source. We also need to recognize specs generated
            --  by the front-end for bodies that carry the pragma. Finally,
            --  predefined operators do not come from source but are not
            --  inlineable either.

            elsif Is_Generic_Instance (Subp)
              or else Parent_Kind (Parent (Subp)) = N_Subprogram_Declaration
            then
               null;

            elsif not Comes_From_Source (Subp)
              and then Scope (Subp) /= Standard_Standard
            then
               Applies := True;
               return;
            end if;

            --  The referenced entity must either be the enclosing entity, or
            --  an entity declared within the current open scope.

            if Present (Scope (Subp))
              and then Scope (Subp) /= Current_Scope
              and then Subp /= Current_Scope
            then
               Error_Pragma_Arg
                 ("argument of% must be entity in current scope", Assoc);
               return;
            end if;

            --  Processing for procedure, operator or function. If subprogram
            --  is aliased (as for an instance) indicate that the renamed
            --  entity (if declared in the same unit) is inlined.
            --  If this is the anonymous subprogram created for a subprogram
            --  instance, the inlining applies to it directly. Otherwise we
            --  retrieve it as the alias of the visible subprogram instance.

            if Is_Subprogram (Subp) then

               --  Ensure that pragma Inline_Always is associated with the
               --  initial declaration of the subprogram.

               Check_Inline_Always_Placement (Subp);

               if Is_Wrapper_Package (Scope (Subp)) then
                  Inner_Subp := Subp;
               else
                  Inner_Subp := Ultimate_Alias (Inner_Subp);
               end if;

               if In_Same_Source_Unit (Subp, Inner_Subp) then
                  Set_Inline_Flags (Inner_Subp);

                  if Present (Parent (Inner_Subp)) then
                     Decl := Parent (Parent (Inner_Subp));
                  else
                     Decl := Empty;
                  end if;

                  if Nkind (Decl) = N_Subprogram_Declaration
                    and then Present (Corresponding_Body (Decl))
                  then
                     Set_Inline_Flags (Corresponding_Body (Decl));

                  elsif Is_Generic_Instance (Subp)
                    and then Comes_From_Source (Subp)
                  then
                     --  Indicate that the body needs to be created for
                     --  inlining subsequent calls. The instantiation node
                     --  follows the declaration of the wrapper package
                     --  created for it. The subprogram that requires the
                     --  body is the anonymous one in the wrapper package.

                     if Scope (Subp) /= Standard_Standard
                       and then
                         Need_Subprogram_Instance_Body
                           (Next (Unit_Declaration_Node
                             (Scope (Alias (Subp)))), Subp)
                     then
                        null;
                     end if;

                  --  Inline is a program unit pragma (RM 10.1.5) and cannot
                  --  appear in a formal part to apply to a formal subprogram.
                  --  Do not apply check within an instance or a formal package
                  --  the test will have been applied to the original generic.

                  elsif Nkind (Decl) in N_Formal_Subprogram_Declaration
                    and then In_Same_List (Decl, N)
                    and then not In_Instance
                  then
                     Error_Msg_N
                       ("Inline cannot apply to a formal subprogram", N);
                  end if;
               end if;

               Applies := True;

            --  For a generic subprogram set flag as well, for use at the point
            --  of instantiation, to determine whether the body should be
            --  generated.

            elsif Is_Generic_Subprogram (Subp) then
               Set_Inline_Flags (Subp);
               Applies := True;

            --  Literals are by definition inlined

            elsif Kind = E_Enumeration_Literal then
               null;

            --  Anything else is an error

            else
               Error_Pragma_Arg
                 ("expect subprogram name for pragma%", Assoc);
            end if;
         end Make_Inline;

         ----------------------
         -- Set_Inline_Flags --
         ----------------------

         procedure Set_Inline_Flags (Subp : Entity_Id) is
         begin
            --  First set the Has_Pragma_XXX flags and issue the appropriate
            --  errors and warnings for suspicious combinations.

            if Prag_Id = Pragma_No_Inline then
               if Has_Pragma_Inline_Always (Subp) then
                  Error_Msg_N
                    ("Inline_Always and No_Inline are mutually exclusive", N);
               elsif Has_Pragma_Inline (Subp) then
                  Error_Msg_NE
                    ("Inline and No_Inline both specified for& ??",
                     N, Entity (Subp_Id));
               end if;

               Set_Has_Pragma_No_Inline (Subp);
            else
               if Prag_Id = Pragma_Inline_Always then
                  if Has_Pragma_No_Inline (Subp) then
                     Error_Msg_N
                       ("Inline_Always and No_Inline are mutually exclusive",
                        N);
                  end if;

                  Set_Has_Pragma_Inline_Always (Subp);
               else
                  if Has_Pragma_No_Inline (Subp) then
                     Error_Msg_NE
                       ("Inline and No_Inline both specified for& ??",
                        N, Entity (Subp_Id));
                  end if;
               end if;

               Set_Has_Pragma_Inline (Subp);
            end if;

            --  Then adjust the Is_Inlined flag. It can never be set if the
            --  subprogram is subject to pragma No_Inline.

            case Status is
               when Suppressed =>
                  Set_Is_Inlined (Subp, False);

               when Disabled =>
                  null;

               when Enabled =>
                  if not Has_Pragma_No_Inline (Subp) then
                     Set_Is_Inlined (Subp, True);
                  end if;
            end case;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Subp);

            --  Capture the entity of the first Ghost subprogram being
            --  processed for error detection purposes.

            if Is_Ghost_Entity (Subp) then
               if No (Ghost_Id) then
                  Ghost_Id := Subp;
               end if;

            --  Otherwise the subprogram is non-Ghost. It is illegal to mix
            --  references to Ghost and non-Ghost entities (SPARK RM 6.9).

            elsif Present (Ghost_Id) and then not Ghost_Error_Posted then
               Ghost_Error_Posted := True;

               Error_Msg_Name_1 := Pname;
               Error_Msg_N
                 ("pragma % cannot mention ghost and non-ghost subprograms",
                  N);

               Error_Msg_Sloc := Sloc (Ghost_Id);
               Error_Msg_NE ("\& # declared as ghost", N, Ghost_Id);

               Error_Msg_Sloc := Sloc (Subp);
               Error_Msg_NE ("\& # declared as non-ghost", N, Subp);
            end if;
         end Set_Inline_Flags;

      --  Start of processing for Process_Inline

      begin
         --  An inlined subprogram may grant access to its private enclosing
         --  context depending on the placement of its body. From elaboration
         --  point of view, the flow of execution may enter this private
         --  context, and then reach an external unit, thus producing a
         --  dependency on that external unit. For such a path to be properly
         --  discovered and encoded in the ALI file of the main unit, let the
         --  ABE mechanism process the body of the main unit, and encode all
         --  relevant invocation constructs and the relations between them.

         Mark_Save_Invocation_Graph_Of_Body;

         Check_No_Identifiers;
         Check_At_Least_N_Arguments (1);

         if Status = Enabled then
            Inline_Processing_Required := True;
         end if;

         Assoc := Arg1;
         while Present (Assoc) loop
            Subp_Id := Get_Pragma_Arg (Assoc);
            Analyze (Subp_Id);
            Applies := False;

            if Is_Entity_Name (Subp_Id) then
               Subp := Entity (Subp_Id);

               if Subp = Any_Id then

                  --  If previous error, avoid cascaded errors

                  Check_Error_Detected;
                  Applies := True;

               else
                  --  Check for RM 13.1(9.2/4): If a [...] aspect_specification
                  --  is given that directly specifies an aspect of an entity,
                  --  then it is illegal to give another [...]
                  --  aspect_specification that directly specifies the same
                  --  aspect of the entity.
                  --  We only check Subp directly as per "directly specifies"
                  --  above and because the case of pragma Inline is really
                  --  special given its pre aspect usage.

                  Check_Duplicate_Pragma (Subp);
                  Record_Rep_Item (Subp, N);

                  Make_Inline (Subp);

                  --  For the pragma case, climb homonym chain. This is
                  --  what implements allowing the pragma in the renaming
                  --  case, with the result applying to the ancestors, and
                  --  also allows Inline to apply to all previous homonyms.

                  if not From_Aspect_Specification (N) then
                     while Present (Homonym (Subp))
                       and then Scope (Homonym (Subp)) = Current_Scope
                     loop
                        Subp := Homonym (Subp);
                        Make_Inline (Subp);
                     end loop;
                  end if;
               end if;
            end if;

            if not Applies then
               Error_Pragma_Arg ("inappropriate argument for pragma%", Assoc);
            end if;

            Next (Assoc);
         end loop;

         --  If the context is a package declaration, the pragma indicates
         --  that inlining will require the presence of the corresponding
         --  body. (this may be further refined).

         if not In_Instance
           and then Nkind (Unit (Cunit (Current_Sem_Unit))) =
                      N_Package_Declaration
         then
            Set_Body_Needed_For_Inlining (Cunit_Entity (Current_Sem_Unit));
         end if;
      end Process_Inline;

      ----------------------------
      -- Process_Interface_Name --
      ----------------------------

      procedure Process_Interface_Name
        (Subprogram_Def : Entity_Id;
         Ext_Arg        : Node_Id;
         Link_Arg       : Node_Id;
         Prag           : Node_Id)
      is
         Ext_Nam    : Node_Id;
         Link_Nam   : Node_Id;
         String_Val : String_Id;

         procedure Check_Form_Of_Interface_Name (SN : Node_Id);
         --  SN is a string literal node for an interface name. This routine
         --  performs some minimal checks that the name is reasonable. In
         --  particular that no spaces or other obviously incorrect characters
         --  appear. This is only a warning, since any characters are allowed.

         ----------------------------------
         -- Check_Form_Of_Interface_Name --
         ----------------------------------

         procedure Check_Form_Of_Interface_Name (SN : Node_Id) is
            S  : constant String_Id := Strval (Expr_Value_S (SN));
            SL : constant Nat       := String_Length (S);
            C  : Char_Code;

         begin
            if SL = 0 then
               Error_Msg_N ("interface name cannot be null string", SN);
            end if;

            for J in 1 .. SL loop
               C := Get_String_Char (S, J);

               --  Look for dubious character and issue unconditional warning.
               --  Definitely dubious if not in character range.

               if not In_Character_Range (C)

                 --  Commas, spaces and (back)slashes are dubious

                 or else Get_Character (C) = ','
                 or else Get_Character (C) = '\'
                 or else Get_Character (C) = ' '
                 or else Get_Character (C) = '/'
               then
                  Error_Msg
                    ("??interface name contains illegal character",
                     Sloc (SN) + Source_Ptr (J));
               end if;
            end loop;
         end Check_Form_Of_Interface_Name;

      --  Start of processing for Process_Interface_Name

      begin
         --  If we are looking at a pragma that comes from an aspect then it
         --  needs to have its corresponding aspect argument expressions
         --  analyzed in addition to the generated pragma so that aspects
         --  within generic units get properly resolved.

         if Present (Prag) and then From_Aspect_Specification (Prag) then
            declare
               Asp     : constant Node_Id := Corresponding_Aspect (Prag);
               Dummy_1 : Node_Id;
               Dummy_2 : Node_Id;
               Dummy_3 : Node_Id;
               EN      : Node_Id;
               LN      : Node_Id;

            begin
               --  Obtain all interfacing aspects used to construct the pragma

               Get_Interfacing_Aspects
                 (Asp, Dummy_1, EN, Dummy_2, Dummy_3, LN);

               --  Analyze the expression of aspect External_Name

               if Present (EN) then
                  Analyze (Expression (EN));
               end if;

               --  Analyze the expressio of aspect Link_Name

               if Present (LN) then
                  Analyze (Expression (LN));
               end if;
            end;
         end if;

         if No (Link_Arg) then
            if No (Ext_Arg) then
               return;

            elsif Chars (Ext_Arg) = Name_Link_Name then
               Ext_Nam  := Empty;
               Link_Nam := Expression (Ext_Arg);

            else
               Check_Optional_Identifier (Ext_Arg, Name_External_Name);
               Ext_Nam  := Expression (Ext_Arg);
               Link_Nam := Empty;
            end if;

         else
            Check_Optional_Identifier (Ext_Arg,  Name_External_Name);
            Check_Optional_Identifier (Link_Arg, Name_Link_Name);
            Ext_Nam  := Expression (Ext_Arg);
            Link_Nam := Expression (Link_Arg);
         end if;

         --  Check expressions for external name and link name are static

         if Present (Ext_Nam) then
            Check_Arg_Is_OK_Static_Expression (Ext_Nam, Standard_String);
            Check_Form_Of_Interface_Name (Ext_Nam);

            --  Verify that external name is not the name of a local entity,
            --  which would hide the imported one and could lead to run-time
            --  surprises. The problem can only arise for entities declared in
            --  a package body (otherwise the external name is fully qualified
            --  and will not conflict).

            declare
               Nam : Name_Id;
               E   : Entity_Id;
               Par : Node_Id;

            begin
               if Prag_Id = Pragma_Import then
                  Nam := String_To_Name (Strval (Expr_Value_S (Ext_Nam)));
                  E   := Entity_Id (Get_Name_Table_Int (Nam));

                  if Nam /= Chars (Subprogram_Def)
                    and then Present (E)
                    and then not Is_Overloadable (E)
                    and then Is_Immediately_Visible (E)
                    and then not Is_Imported (E)
                    and then Ekind (Scope (E)) = E_Package
                  then
                     Par := Parent (E);
                     while Present (Par) loop
                        if Nkind (Par) = N_Package_Body then
                           Error_Msg_Sloc := Sloc (E);
                           Error_Msg_NE
                             ("imported entity is hidden by & declared#",
                              Ext_Arg, E);
                           exit;
                        end if;

                        Par := Parent (Par);
                     end loop;
                  end if;
               end if;
            end;
         end if;

         if Present (Link_Nam) then
            Check_Arg_Is_OK_Static_Expression (Link_Nam, Standard_String);
            Check_Form_Of_Interface_Name (Link_Nam);
         end if;

         --  If there is no link name, just set the external name

         if No (Link_Nam) then
            Link_Nam := Adjust_External_Name_Case (Expr_Value_S (Ext_Nam));

         --  For the Link_Name case, the given literal is preceded by an
         --  asterisk, which indicates to GCC that the given name should be
         --  taken literally, and in particular that no prepending of
         --  underlines should occur, even in systems where this is the
         --  normal default.

         else
            Start_String;
            Store_String_Char (Get_Char_Code ('*'));
            String_Val := Strval (Expr_Value_S (Link_Nam));
            Store_String_Chars (String_Val);
            Link_Nam :=
              Make_String_Literal (Sloc (Link_Nam),
                Strval => End_String);
         end if;

         --  Set the interface name. If the entity is a generic instance, use
         --  its alias, which is the callable entity.

         if Is_Generic_Instance (Subprogram_Def) then
            Set_Encoded_Interface_Name
              (Alias (Get_Base_Subprogram (Subprogram_Def)), Link_Nam);
         else
            Set_Encoded_Interface_Name
              (Get_Base_Subprogram (Subprogram_Def), Link_Nam);
         end if;

         Check_Duplicated_Export_Name (Link_Nam);
      end Process_Interface_Name;

      -----------------------------------------
      -- Process_Interrupt_Or_Attach_Handler --
      -----------------------------------------

      procedure Process_Interrupt_Or_Attach_Handler is
         Handler  : constant Entity_Id := Entity (Get_Pragma_Arg (Arg1));
         Prot_Typ : constant Entity_Id := Scope (Handler);

      begin
         --  A pragma that applies to a Ghost entity becomes Ghost for the
         --  purposes of legality checks and removal of ignored Ghost code.

         Mark_Ghost_Pragma (N, Handler);
         Set_Is_Interrupt_Handler (Handler);

         pragma Assert (Ekind (Prot_Typ) = E_Protected_Type);

         Record_Rep_Item (Prot_Typ, N);

         --  Chain the pragma on the contract for completeness

         Add_Contract_Item (N, Handler);
      end Process_Interrupt_Or_Attach_Handler;

      --------------------------------------------------
      -- Process_Restrictions_Or_Restriction_Warnings --
      --------------------------------------------------

      --  Note: some of the simple identifier cases were handled in par-prag,
      --  but it is harmless (and more straightforward) to simply handle all
      --  cases here, even if it means we repeat a bit of work in some cases.

      procedure Process_Restrictions_Or_Restriction_Warnings
        (Warn : Boolean)
      is
         Arg   : Node_Id;
         R_Id  : Restriction_Id;
         Id    : Name_Id;
         Expr  : Node_Id;
         Val   : Uint;

      begin
         --  Ignore all Restrictions pragmas in CodePeer mode

         if CodePeer_Mode then
            return;
         end if;

         Check_Ada_83_Warning;
         Check_At_Least_N_Arguments (1);
         Check_Valid_Configuration_Pragma;

         Arg := Arg1;
         while Present (Arg) loop
            Id := Chars (Arg);
            Expr := Get_Pragma_Arg (Arg);

            --  Case of no restriction identifier present

            if Id = No_Name then
               if Nkind (Expr) /= N_Identifier then
                  Error_Pragma_Arg
                    ("invalid form for restriction", Arg);
               end if;

               R_Id :=
                 Get_Restriction_Id
                   (Process_Restriction_Synonyms (Expr));

               if R_Id not in All_Boolean_Restrictions then
                  Error_Msg_Name_1 := Pname;
                  Error_Msg_N
                    ("invalid restriction identifier&", Get_Pragma_Arg (Arg));

                  --  Check for possible misspelling

                  for J in Restriction_Id loop
                     declare
                        Rnm : constant String := Restriction_Id'Image (J);

                     begin
                        Name_Buffer (1 .. Rnm'Length) := Rnm;
                        Name_Len := Rnm'Length;
                        Set_Casing (All_Lower_Case);

                        if Is_Bad_Spelling_Of (Chars (Expr), Name_Enter) then
                           Set_Casing
                             (Identifier_Casing
                               (Source_Index (Current_Sem_Unit)));
                           Error_Msg_String (1 .. Rnm'Length) :=
                             Name_Buffer (1 .. Name_Len);
                           Error_Msg_Strlen := Rnm'Length;
                           Error_Msg_N -- CODEFIX
                             ("\possible misspelling of ""~""",
                              Get_Pragma_Arg (Arg));
                           exit;
                        end if;
                     end;
                  end loop;

                  raise Pragma_Exit;
               end if;

               if Implementation_Restriction (R_Id) then
                  Check_Restriction (No_Implementation_Restrictions, Arg);
               end if;

               --  Special processing for No_Elaboration_Code restriction

               if R_Id = No_Elaboration_Code then

                  --  Restriction is only recognized within a configuration
                  --  pragma file, or within a unit of the main extended
                  --  program. Note: the test for Main_Unit is needed to
                  --  properly include the case of configuration pragma files.

                  if not (Current_Sem_Unit = Main_Unit
                           or else In_Extended_Main_Source_Unit (N))
                  then
                     return;

                  --  Don't allow in a subunit unless already specified in
                  --  body or spec.

                  elsif Nkind (Parent (N)) = N_Compilation_Unit
                    and then Nkind (Unit (Parent (N))) = N_Subunit
                    and then not Restriction_Active (No_Elaboration_Code)
                  then
                     Error_Msg_N
                       ("invalid specification of ""No_Elaboration_Code""",
                        N);
                     Error_Msg_N
                       ("\restriction cannot be specified in a subunit", N);
                     Error_Msg_N
                       ("\unless also specified in body or spec", N);
                     return;

                  --  If we accept a No_Elaboration_Code restriction, then it
                  --  needs to be added to the configuration restriction set so
                  --  that we get proper application to other units in the main
                  --  extended source as required.

                  else
                     Add_To_Config_Boolean_Restrictions (No_Elaboration_Code);
                  end if;

               --  Special processing for No_Dynamic_Accessibility_Checks to
               --  disallow exclusive specification in a body or subunit.

               elsif R_Id = No_Dynamic_Accessibility_Checks
                 --  Check if the restriction is within configuration pragma
                 --  in a similar way to No_Elaboration_Code.

                 and then not (Current_Sem_Unit = Main_Unit
                                or else In_Extended_Main_Source_Unit (N))

                 and then Nkind (Unit (Parent (N))) = N_Compilation_Unit

                 and then (Nkind (Unit (Parent (N))) = N_Package_Body
                            or else Nkind (Unit (Parent (N))) = N_Subunit)

                 and then not Restriction_Active
                                (No_Dynamic_Accessibility_Checks)
               then
                  Error_Msg_N
                    ("invalid specification of " &
                     """No_Dynamic_Accessibility_Checks""", N);

                  if Nkind (Unit (Parent (N))) = N_Package_Body then
                     Error_Msg_N
                       ("\restriction cannot be specified in a package " &
                         "body", N);

                  elsif Nkind (Unit (Parent (N))) = N_Subunit then
                     Error_Msg_N
                       ("\restriction cannot be specified in a subunit", N);
                  end if;

                  Error_Msg_N
                    ("\unless also specified in spec", N);

               --  Special processing for No_Tasking restriction (not just a
               --  warning) when it appears as a configuration pragma.

               elsif R_Id = No_Tasking
                 and then No (Cunit (Main_Unit))
                 and then not Warn
               then
                  Set_Global_No_Tasking;
               end if;

               Set_Restriction (R_Id, N, Warn);

               if R_Id = No_Dynamic_CPU_Assignment
                 or else R_Id = No_Tasks_Unassigned_To_CPU
               then
                  --  These imply No_Dependence =>
                  --     "System.Multiprocessors.Dispatching_Domains".
                  --  This is not strictly what the AI says, but it eliminates
                  --  the need for run-time checks, which are undesirable in
                  --  this context.

                  Set_Restriction_No_Dependence
                    (Sel_Comp
                       (Sel_Comp ("system", "multiprocessors", Loc),
                        "dispatching_domains"),
                     Warn);
               end if;

               if R_Id = No_Tasks_Unassigned_To_CPU then
                  --  Likewise, imply No_Dynamic_CPU_Assignment

                  Set_Restriction (No_Dynamic_CPU_Assignment, N, Warn);
               end if;

               --  Check for obsolescent restrictions in Ada 2005 mode

               if not Warn
                 and then Ada_Version >= Ada_2005
                 and then (R_Id = No_Asynchronous_Control
                            or else
                           R_Id = No_Unchecked_Deallocation
                            or else
                           R_Id = No_Unchecked_Conversion)
               then
                  Check_Restriction (No_Obsolescent_Features, N);
               end if;

               --  A very special case that must be processed here: pragma
               --  Restrictions (No_Exceptions) turns off all run-time
               --  checking. This is a bit dubious in terms of the formal
               --  language definition, but it is what is intended by RM
               --  H.4(12). Restriction_Warnings never affects generated code
               --  so this is done only in the real restriction case.

               --  Atomic_Synchronization is not a real check, so it is not
               --  affected by this processing).

               --  Ignore the effect of pragma Restrictions (No_Exceptions) on
               --  run-time checks in CodePeer and GNATprove modes: we want to
               --  generate checks for analysis purposes, as set respectively
               --  by -gnatC and -gnatd.F

               if not Warn
                 and then not (CodePeer_Mode or GNATprove_Mode)
                 and then R_Id = No_Exceptions
               then
                  for J in Scope_Suppress.Suppress'Range loop
                     if J /= Atomic_Synchronization then
                        Scope_Suppress.Suppress (J) := True;
                     end if;
                  end loop;
               end if;

            --  Case of No_Dependence => unit-name. Note that the parser
            --  already made the necessary entry in the No_Dependence table.

            elsif Id = Name_No_Dependence then
               if not OK_No_Dependence_Unit_Name (Expr) then
                  raise Pragma_Exit;
               end if;

            --  Case of No_Specification_Of_Aspect => aspect-identifier

            elsif Id = Name_No_Specification_Of_Aspect then
               declare
                  A_Id : Aspect_Id;

               begin
                  if Nkind (Expr) /= N_Identifier then
                     A_Id := No_Aspect;
                  else
                     A_Id := Get_Aspect_Id (Chars (Expr));
                  end if;

                  if A_Id = No_Aspect then
                     Error_Pragma_Arg ("invalid restriction name", Arg);
                  else
                     Set_Restriction_No_Specification_Of_Aspect (Expr, Warn);
                  end if;
               end;

            --  Case of No_Use_Of_Attribute => attribute-identifier

            elsif Id = Name_No_Use_Of_Attribute then
               if Nkind (Expr) /= N_Identifier
                 or else not Is_Attribute_Name (Chars (Expr))
               then
                  Error_Msg_N ("unknown attribute name??", Expr);

               else
                  Set_Restriction_No_Use_Of_Attribute (Expr, Warn);
               end if;

            --  Case of No_Use_Of_Entity => fully-qualified-name

            elsif Id = Name_No_Use_Of_Entity then

               --  Restriction is only recognized within a configuration
               --  pragma file, or within a unit of the main extended
               --  program. Note: the test for Main_Unit is needed to
               --  properly include the case of configuration pragma files.

               if Current_Sem_Unit = Main_Unit
                 or else In_Extended_Main_Source_Unit (N)
               then
                  if not OK_No_Dependence_Unit_Name (Expr) then
                     Error_Msg_N ("wrong form for entity name", Expr);
                  else
                     Set_Restriction_No_Use_Of_Entity
                       (Expr, Warn, No_Profile);
                  end if;
               end if;

            --  Case of No_Use_Of_Pragma => pragma-identifier

            elsif Id = Name_No_Use_Of_Pragma then
               if Nkind (Expr) /= N_Identifier
                 or else not Is_Pragma_Name (Chars (Expr))
               then
                  Error_Msg_N ("unknown pragma name??", Expr);
               else
                  Set_Restriction_No_Use_Of_Pragma (Expr, Warn);
               end if;

            --  All other cases of restriction identifier present

            else
               R_Id := Get_Restriction_Id (Process_Restriction_Synonyms (Arg));
               Analyze_And_Resolve (Expr, Any_Integer);

               if R_Id not in All_Parameter_Restrictions then
                  Error_Pragma_Arg
                    ("invalid restriction parameter identifier", Arg);

               elsif not Is_OK_Static_Expression (Expr) then
                  Flag_Non_Static_Expr
                    ("value must be static expression!", Expr);
                  raise Pragma_Exit;

               elsif not Is_Integer_Type (Etype (Expr))
                 or else Expr_Value (Expr) < 0
               then
                  Error_Pragma_Arg
                    ("value must be non-negative integer", Arg);
               end if;

               --  Restriction pragma is active

               Val := Expr_Value (Expr);

               if not UI_Is_In_Int_Range (Val) then
                  Error_Pragma_Arg
                    ("pragma ignored, value too large??", Arg);
               end if;

               Set_Restriction (R_Id, N, Warn, Integer (UI_To_Int (Val)));
            end if;

            Next (Arg);
         end loop;
      end Process_Restrictions_Or_Restriction_Warnings;

      ---------------------------------
      -- Process_Suppress_Unsuppress --
      ---------------------------------

      --  Note: this procedure makes entries in the check suppress data
      --  structures managed by Sem. See spec of package Sem for full
      --  details on how we handle recording of check suppression.

      procedure Process_Suppress_Unsuppress (Suppress_Case : Boolean) is
         C    : Check_Id;
         E    : Entity_Id;
         E_Id : Node_Id;

         In_Package_Spec : constant Boolean :=
                             Is_Package_Or_Generic_Package (Current_Scope)
                               and then not In_Package_Body (Current_Scope);

         procedure Suppress_Unsuppress_Echeck (E : Entity_Id; C : Check_Id);
         --  Used to suppress a single check on the given entity

         --------------------------------
         -- Suppress_Unsuppress_Echeck --
         --------------------------------

         procedure Suppress_Unsuppress_Echeck (E : Entity_Id; C : Check_Id) is
         begin
            --  Check for error of trying to set atomic synchronization for
            --  a non-atomic variable.

            if C = Atomic_Synchronization
              and then not (Is_Atomic (E) or else Has_Atomic_Components (E))
            then
               Error_Msg_N
                 ("pragma & requires atomic type or variable",
                  Pragma_Identifier (Original_Node (N)));
            end if;

            Set_Checks_May_Be_Suppressed (E);

            if In_Package_Spec then
               Push_Global_Suppress_Stack_Entry
                 (Entity   => E,
                  Check    => C,
                  Suppress => Suppress_Case);
            else
               Push_Local_Suppress_Stack_Entry
                 (Entity   => E,
                  Check    => C,
                  Suppress => Suppress_Case);
            end if;

            --  If this is a first subtype, and the base type is distinct,
            --  then also set the suppress flags on the base type.

            if Is_First_Subtype (E) and then Etype (E) /= E then
               Suppress_Unsuppress_Echeck (Etype (E), C);
            end if;
         end Suppress_Unsuppress_Echeck;

      --  Start of processing for Process_Suppress_Unsuppress

      begin
         --  Ignore pragma Suppress/Unsuppress in CodePeer and GNATprove modes
         --  on user code: we want to generate checks for analysis purposes, as
         --  set respectively by -gnatC and -gnatd.F

         if Comes_From_Source (N)
           and then (CodePeer_Mode or GNATprove_Mode)
         then
            return;
         end if;

         --  Suppress/Unsuppress can appear as a configuration pragma, or in a
         --  declarative part or a package spec (RM 11.5(5)).

         if not Is_Configuration_Pragma then
            Check_Is_In_Decl_Part_Or_Package_Spec;
         end if;

         Check_At_Least_N_Arguments (1);
         Check_At_Most_N_Arguments (2);
         Check_No_Identifier (Arg1);
         Check_Arg_Is_Identifier (Arg1);

         C := Get_Check_Id (Chars (Get_Pragma_Arg (Arg1)));

         if C = No_Check_Id then
            Error_Pragma_Arg
              ("argument of pragma% is not valid check name", Arg1);
         end if;

         --  Warn that suppress of Elaboration_Check has no effect in SPARK

         if C = Elaboration_Check and then SPARK_Mode = On then
            Error_Pragma_Arg
              ("Suppress of Elaboration_Check ignored in SPARK??",
               "\elaboration checking rules are statically enforced "
               & "(SPARK RM 7.7)", Arg1);
         end if;

         --  One-argument case

         if Arg_Count = 1 then

            --  Make an entry in the local scope suppress table. This is the
            --  table that directly shows the current value of the scope
            --  suppress check for any check id value.

            if C = All_Checks then

               --  For All_Checks, we set all specific predefined checks with
               --  the exception of Elaboration_Check, which is handled
               --  specially because of not wanting All_Checks to have the
               --  effect of deactivating static elaboration order processing.
               --  Atomic_Synchronization is also not affected, since this is
               --  not a real check.

               for J in Scope_Suppress.Suppress'Range loop
                  if J /= Elaboration_Check
                       and then
                     J /= Atomic_Synchronization
                  then
                     Scope_Suppress.Suppress (J) := Suppress_Case;
                  end if;
               end loop;

            --  If not All_Checks, and predefined check, then set appropriate
            --  scope entry. Note that we will set Elaboration_Check if this
            --  is explicitly specified. Atomic_Synchronization is allowed
            --  only if internally generated and entity is atomic.

            elsif C in Predefined_Check_Id
              and then (not Comes_From_Source (N)
                         or else C /= Atomic_Synchronization)
            then
               Scope_Suppress.Suppress (C) := Suppress_Case;
            end if;

            --  Also make an entry in the Local_Entity_Suppress table

            Push_Local_Suppress_Stack_Entry
              (Entity   => Empty,
               Check    => C,
               Suppress => Suppress_Case);

         --  Case of two arguments present, where the check is suppressed for
         --  a specified entity (given as the second argument of the pragma)

         else
            --  This is obsolescent in Ada 2005 mode

            if Ada_Version >= Ada_2005 then
               Check_Restriction (No_Obsolescent_Features, Arg2);
            end if;

            Check_Optional_Identifier (Arg2, Name_On);
            E_Id := Get_Pragma_Arg (Arg2);
            Analyze (E_Id);

            if not Is_Entity_Name (E_Id) then
               Error_Pragma_Arg
                 ("second argument of pragma% must be entity name", Arg2);
            end if;

            E := Entity (E_Id);

            if E = Any_Id then
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            --  Enforce RM 11.5(7) which requires that for a pragma that
            --  appears within a package spec, the named entity must be
            --  within the package spec. We allow the package name itself
            --  to be mentioned since that makes sense, although it is not
            --  strictly allowed by 11.5(7).

            if In_Package_Spec
              and then E /= Current_Scope
              and then Scope (E) /= Current_Scope
            then
               Error_Pragma_Arg
                 ("entity in pragma% is not in package spec (RM 11.5(7))",
                  Arg2);
            end if;

            --  Loop through homonyms. As noted below, in the case of a package
            --  spec, only homonyms within the package spec are considered.

            loop
               Suppress_Unsuppress_Echeck (E, C);

               if Is_Generic_Instance (E)
                 and then Is_Subprogram (E)
                 and then Present (Alias (E))
               then
                  Suppress_Unsuppress_Echeck (Alias (E), C);
               end if;

               --  Move to next homonym if not aspect spec case

               exit when From_Aspect_Specification (N);
               E := Homonym (E);
               exit when No (E);

               --  If we are within a package specification, the pragma only
               --  applies to homonyms in the same scope.

               exit when In_Package_Spec
                 and then Scope (E) /= Current_Scope;
            end loop;
         end if;
      end Process_Suppress_Unsuppress;

      -------------------------------
      -- Record_Independence_Check --
      -------------------------------

      procedure Record_Independence_Check (N : Node_Id; E : Entity_Id) is
         pragma Unreferenced (N, E);
      begin
         --  For GCC back ends the validation is done a priori. This code is
         --  dead, but might be useful in the future.

         --  if not AAMP_On_Target then
         --     return;
         --  end if;

         --  Independence_Checks.Append ((N, E));

         return;
      end Record_Independence_Check;

      ------------------
      -- Set_Exported --
      ------------------

      procedure Set_Exported (E : Entity_Id; Arg : Node_Id) is
      begin
         if Is_Imported (E) then
            Error_Pragma_Arg
              ("cannot export entity& that was previously imported", Arg);

         elsif Present (Address_Clause (E))
           and then not Relaxed_RM_Semantics
         then
            Error_Pragma_Arg
              ("cannot export entity& that has an address clause", Arg);
         end if;

         Set_Is_Exported (E);

         --  Generate a reference for entity explicitly, because the
         --  identifier may be overloaded and name resolution will not
         --  generate one.

         Generate_Reference (E, Arg);

         --  Deal with exporting non-library level entity

         if not Is_Library_Level_Entity (E) then

            --  Not allowed at all for subprograms

            if Is_Subprogram (E) then
               Error_Pragma_Arg ("local subprogram& cannot be exported", Arg);

            --  Otherwise set public and statically allocated

            else
               Set_Is_Public (E);
               Set_Is_Statically_Allocated (E);

               --  Warn if the corresponding W flag is set

               if Warn_On_Export_Import

                 --  Only do this for something that was in the source. Not
                 --  clear if this can be False now (there used for sure to be
                 --  cases on some systems where it was False), but anyway the
                 --  test is harmless if not needed, so it is retained.

                 and then Comes_From_Source (Arg)
               then
                  Error_Msg_NE
                    ("?x?& has been made static as a result of Export",
                     Arg, E);
                  Error_Msg_N
                    ("\?x?this usage is non-standard and non-portable",
                     Arg);
               end if;
            end if;
         end if;

         if Warn_On_Export_Import and Inside_A_Generic then
            Error_Msg_NE
              ("all instances of& will have the same external name?x?",
               Arg, E);
         end if;
      end Set_Exported;

      ----------------------------------------------
      -- Set_Extended_Import_Export_External_Name --
      ----------------------------------------------

      procedure Set_Extended_Import_Export_External_Name
        (Internal_Ent : Entity_Id;
         Arg_External : Node_Id)
      is
         Old_Name : constant Node_Id := Interface_Name (Internal_Ent);
         New_Name : Node_Id;

      begin
         if No (Arg_External) then
            return;
         end if;

         Check_Arg_Is_External_Name (Arg_External);

         if Nkind (Arg_External) = N_String_Literal then
            if String_Length (Strval (Arg_External)) = 0 then
               return;
            else
               New_Name := Adjust_External_Name_Case (Arg_External);
            end if;

         elsif Nkind (Arg_External) = N_Identifier then
            New_Name := Get_Default_External_Name (Arg_External);

         --  Check_Arg_Is_External_Name should let through only identifiers and
         --  string literals or static string expressions (which are folded to
         --  string literals).

         else
            raise Program_Error;
         end if;

         --  If we already have an external name set (by a prior normal Import
         --  or Export pragma), then the external names must match

         if Present (Interface_Name (Internal_Ent)) then

            --  Ignore mismatching names in CodePeer mode, to support some
            --  old compilers which would export the same procedure under
            --  different names, e.g:
            --     procedure P;
            --     pragma Export_Procedure (P, "a");
            --     pragma Export_Procedure (P, "b");

            if CodePeer_Mode then
               return;
            end if;

            Check_Matching_Internal_Names : declare
               S1 : constant String_Id := Strval (Old_Name);
               S2 : constant String_Id := Strval (New_Name);

               procedure Mismatch;
               pragma No_Return (Mismatch);
               --  Called if names do not match

               --------------
               -- Mismatch --
               --------------

               procedure Mismatch is
               begin
                  Error_Msg_Sloc := Sloc (Old_Name);
                  Error_Pragma_Arg
                    ("external name does not match that given #",
                     Arg_External);
               end Mismatch;

            --  Start of processing for Check_Matching_Internal_Names

            begin
               if String_Length (S1) /= String_Length (S2) then
                  Mismatch;

               else
                  for J in 1 .. String_Length (S1) loop
                     if Get_String_Char (S1, J) /= Get_String_Char (S2, J) then
                        Mismatch;
                     end if;
                  end loop;
               end if;
            end Check_Matching_Internal_Names;

         --  Otherwise set the given name

         else
            Set_Encoded_Interface_Name (Internal_Ent, New_Name);
            Check_Duplicated_Export_Name (New_Name);
         end if;
      end Set_Extended_Import_Export_External_Name;

      ------------------
      -- Set_Imported --
      ------------------

      procedure Set_Imported (E : Entity_Id) is
      begin
         --  Error message if already imported or exported

         if Is_Exported (E) or else Is_Imported (E) then

            --  Error if being set Exported twice

            if Is_Exported (E) then
               Error_Msg_NE ("entity& was previously exported", N, E);

            --  Ignore error in CodePeer mode where we treat all imported
            --  subprograms as unknown.

            elsif CodePeer_Mode then
               goto OK;

            --  OK if Import/Interface case

            elsif Import_Interface_Present (N) then
               goto OK;

            --  Error if being set Imported twice

            else
               Error_Msg_NE ("entity& was previously imported", N, E);
            end if;

            Error_Msg_Name_1 := Pname;
            Error_Msg_N
              ("\(pragma% applies to all previous entities)", N);

            Error_Msg_Sloc  := Sloc (E);
            Error_Msg_NE ("\import not allowed for& declared#", N, E);

         --  Here if not previously imported or exported, OK to import

         else
            Set_Is_Imported (E);

            --  For subprogram, set Import_Pragma field

            if Is_Subprogram (E) then
               Set_Import_Pragma (E, N);
            end if;

            --  If the entity is an object that is not at the library level,
            --  then it is statically allocated. We do not worry about objects
            --  with address clauses in this context since they are not really
            --  imported in the linker sense.

            if Is_Object (E)
              and then not Is_Library_Level_Entity (E)
              and then No (Address_Clause (E))
            then
               Set_Is_Statically_Allocated (E);
            end if;
         end if;

         <<OK>> null;
      end Set_Imported;

      -------------------------
      -- Set_Mechanism_Value --
      -------------------------

      --  Note: the mechanism name has not been analyzed (and cannot indeed be
      --  analyzed, since it is semantic nonsense), so we get it in the exact
      --  form created by the parser.

      procedure Set_Mechanism_Value (Ent : Entity_Id; Mech_Name : Node_Id) is
         procedure Bad_Mechanism;
         pragma No_Return (Bad_Mechanism);
         --  Signal bad mechanism name

         -------------------
         -- Bad_Mechanism --
         -------------------

         procedure Bad_Mechanism is
         begin
            Error_Pragma_Arg ("unrecognized mechanism name", Mech_Name);
         end Bad_Mechanism;

      --  Start of processing for Set_Mechanism_Value

      begin
         if Mechanism (Ent) /= Default_Mechanism then
            Error_Msg_NE
              ("mechanism for & has already been set", Mech_Name, Ent);
         end if;

         --  MECHANISM_NAME ::= value | reference

         if Nkind (Mech_Name) = N_Identifier then
            if Chars (Mech_Name) = Name_Value then
               Set_Mechanism (Ent, By_Copy);
               return;

            elsif Chars (Mech_Name) = Name_Reference then
               Set_Mechanism (Ent, By_Reference);
               return;

            elsif Chars (Mech_Name) = Name_Copy then
               Error_Pragma_Arg
                 ("bad mechanism name, Value assumed", Mech_Name);

            else
               Bad_Mechanism;
            end if;

         else
            Bad_Mechanism;
         end if;
      end Set_Mechanism_Value;

      --------------------------
      -- Set_Rational_Profile --
      --------------------------

      --  The Rational profile includes Implicit_Packing, Use_Vads_Size, and
      --  extension to the semantics of renaming declarations.

      procedure Set_Rational_Profile is
      begin
         Implicit_Packing     := True;
         Overriding_Renamings := True;
         Use_VADS_Size        := True;
      end Set_Rational_Profile;

      ---------------------------
      -- Set_Ravenscar_Profile --
      ---------------------------

      --  The tasks to be done here are

      --    Set required policies

      --      pragma Task_Dispatching_Policy (FIFO_Within_Priorities)
      --        (For Ravenscar, Jorvik, and GNAT_Extended_Ravenscar profiles)
      --      pragma Task_Dispatching_Policy (EDF_Across_Priorities)
      --        (For GNAT_Ravenscar_EDF profile)
      --      pragma Locking_Policy (Ceiling_Locking)

      --    Set Detect_Blocking mode

      --    Set required restrictions (see System.Rident for detailed list)

      --    Set the No_Dependence rules
      --      No_Dependence => Ada.Asynchronous_Task_Control
      --      No_Dependence => Ada.Calendar
      --      No_Dependence => Ada.Execution_Time.Group_Budget
      --      No_Dependence => Ada.Execution_Time.Timers
      --      No_Dependence => Ada.Task_Attributes
      --      No_Dependence => System.Multiprocessors.Dispatching_Domains

      procedure Set_Ravenscar_Profile (Profile : Profile_Name; N : Node_Id) is
         procedure Set_Error_Msg_To_Profile_Name;
         --  Set Error_Msg_String and Error_Msg_Strlen to the name of the
         --  profile.

         -----------------------------------
         -- Set_Error_Msg_To_Profile_Name --
         -----------------------------------

         procedure Set_Error_Msg_To_Profile_Name is
            Prof_Nam : constant Node_Id :=
                         Get_Pragma_Arg
                           (First (Pragma_Argument_Associations (N)));

         begin
            Get_Name_String (Chars (Prof_Nam));
            Adjust_Name_Case (Global_Name_Buffer, Sloc (Prof_Nam));
            Error_Msg_Strlen := Name_Len;
            Error_Msg_String (1 .. Name_Len) := Name_Buffer (1 .. Name_Len);
         end Set_Error_Msg_To_Profile_Name;

         Profile_Dispatching_Policy : Character;

      --  Start of processing for Set_Ravenscar_Profile

      begin
         --  pragma Task_Dispatching_Policy (EDF_Across_Priorities)

         if Profile = GNAT_Ravenscar_EDF then
            Profile_Dispatching_Policy := 'E';

         --  pragma Task_Dispatching_Policy (FIFO_Within_Priorities)

         else
            Profile_Dispatching_Policy := 'F';
         end if;

         if Task_Dispatching_Policy /= ' '
           and then Task_Dispatching_Policy /= Profile_Dispatching_Policy
         then
            Error_Msg_Sloc := Task_Dispatching_Policy_Sloc;
            Set_Error_Msg_To_Profile_Name;
            Error_Pragma ("Profile (~) incompatible with policy#");

         --  Set the FIFO_Within_Priorities policy, but always preserve
         --  System_Location since we like the error message with the run time
         --  name.

         else
            Task_Dispatching_Policy := Profile_Dispatching_Policy;

            if Task_Dispatching_Policy_Sloc /= System_Location then
               Task_Dispatching_Policy_Sloc := Loc;
            end if;
         end if;

         --  pragma Locking_Policy (Ceiling_Locking)

         if Locking_Policy /= ' '
           and then Locking_Policy /= 'C'
         then
            Error_Msg_Sloc := Locking_Policy_Sloc;
            Set_Error_Msg_To_Profile_Name;
            Error_Pragma ("Profile (~) incompatible with policy#");

         --  Set the Ceiling_Locking policy, but preserve System_Location since
         --  we like the error message with the run time name.

         else
            Locking_Policy := 'C';

            if Locking_Policy_Sloc /= System_Location then
               Locking_Policy_Sloc := Loc;
            end if;
         end if;

         --  pragma Detect_Blocking

         Detect_Blocking := True;

         --  Set the corresponding restrictions

         Set_Profile_Restrictions
           (Profile, N, Warn => Treat_Restrictions_As_Warnings);

         --  Set the No_Dependence restrictions

         --  The following No_Dependence restrictions:
         --    No_Dependence => Ada.Asynchronous_Task_Control
         --    No_Dependence => Ada.Calendar
         --    No_Dependence => Ada.Task_Attributes
         --  are already set by previous call to Set_Profile_Restrictions.
         --  Really???

         --  Set the following restrictions which were added to Ada 2005:
         --    No_Dependence => Ada.Execution_Time.Group_Budget
         --    No_Dependence => Ada.Execution_Time.Timers

         if Ada_Version >= Ada_2005 then
            declare
               Execution_Time : constant Node_Id :=
                 Sel_Comp ("ada", "execution_time", Loc);
               Group_Budgets : constant Node_Id :=
                 Sel_Comp (Execution_Time, "group_budgets");
               Timers : constant Node_Id :=
                 Sel_Comp (Execution_Time, "timers");
            begin
               Set_Restriction_No_Dependence
                 (Unit    => Group_Budgets,
                  Warn    => Treat_Restrictions_As_Warnings,
                  Profile => Ravenscar);
               Set_Restriction_No_Dependence
                 (Unit    => Timers,
                  Warn    => Treat_Restrictions_As_Warnings,
                  Profile => Ravenscar);
            end;
         end if;

         --  Set the following restriction which was added to Ada 2012 (see
         --  AI05-0171):
         --    No_Dependence => System.Multiprocessors.Dispatching_Domains

         if Ada_Version >= Ada_2012 then
            Set_Restriction_No_Dependence
              (Sel_Comp
                 (Sel_Comp ("system", "multiprocessors", Loc),
                  "dispatching_domains"),
               Warn    => Treat_Restrictions_As_Warnings,
               Profile => Ravenscar);

            --  Set the following restriction which was added to Ada 2022,
            --  but as a binding interpretation:
            --     No_Dependence => Ada.Synchronous_Barriers
            --  for Ravenscar (and therefore for Ravenscar variants) but not
            --  for Jorvik. The unit Ada.Synchronous_Barriers was introduced
            --  in Ada2012 (AI05-0174).

            if Profile /= Jorvik then
               Set_Restriction_No_Dependence
                 (Sel_Comp ("ada", "synchronous_barriers", Loc),
                  Warn    => Treat_Restrictions_As_Warnings,
                  Profile => Ravenscar);
            end if;
         end if;

      end Set_Ravenscar_Profile;

   --  Start of processing for Analyze_Pragma

   begin
      --  The following code is a defense against recursion. Not clear that
      --  this can happen legitimately, but perhaps some error situations can
      --  cause it, and we did see this recursion during testing.

      if Analyzed (N) then
         return;
      else
         Set_Analyzed (N);
      end if;

      Check_Restriction_No_Use_Of_Pragma (N);

      if Get_Aspect_Id (Chars (Pragma_Identifier (N))) /= No_Aspect then
         --  6.1/3 No_Specification_of_Aspect: Identifies an aspect for which
         --    no aspect_specification, attribute_definition_clause, or pragma
         --    is given.
         Check_Restriction_No_Specification_Of_Aspect (N);
      end if;

      --  Ignore pragma if Ignore_Pragma applies. Also ignore pragma
      --  Default_Scalar_Storage_Order if the -gnatI switch was given.

      if Should_Ignore_Pragma_Sem (N)
        or else (Prag_Id = Pragma_Default_Scalar_Storage_Order
                  and then Ignore_Rep_Clauses)
      then
         return;
      end if;

      --  Deal with unrecognized pragma

      if not Is_Pragma_Name (Pname) then
         declare
            Msg_Issued : Boolean := False;
         begin
            Check_Restriction
              (Msg_Issued, No_Unrecognized_Pragmas, Pragma_Identifier (N));
            if not Msg_Issued and then Warn_On_Unrecognized_Pragma then
               Error_Msg_Name_1 := Pname;
               Error_Msg_N ("?g?unrecognized pragma%!", Pragma_Identifier (N));

               for PN in First_Pragma_Name .. Last_Pragma_Name loop
                  if Is_Bad_Spelling_Of (Pname, PN) then
                     Error_Msg_Name_1 := PN;
                     Error_Msg_N -- CODEFIX
                       ("\?g?possible misspelling of %!",
                        Pragma_Identifier (N));
                     exit;
                  end if;
               end loop;
            end if;
         end;

         return;
      end if;

      --  Here to start processing for recognized pragma

      Pname := Original_Aspect_Pragma_Name (N);

      --  Capture setting of Opt.Uneval_Old

      case Opt.Uneval_Old is
         when 'A' =>
            Set_Uneval_Old_Accept (N);

         when 'E' =>
            null;

         when 'W' =>
            Set_Uneval_Old_Warn (N);

         when others =>
            raise Program_Error;
      end case;

      --  Check applicable policy. We skip this if Is_Checked or Is_Ignored
      --  is already set, indicating that we have already checked the policy
      --  at the right point. This happens for example in the case of a pragma
      --  that is derived from an Aspect.

      if Is_Ignored (N) or else Is_Checked (N) then
         null;

      --  For a pragma that is a rewriting of another pragma, copy the
      --  Is_Checked/Is_Ignored status from the rewritten pragma.

      elsif Is_Rewrite_Substitution (N)
        and then Nkind (Original_Node (N)) = N_Pragma
      then
         Set_Is_Ignored (N, Is_Ignored (Original_Node (N)));
         Set_Is_Checked (N, Is_Checked (Original_Node (N)));

      --  Otherwise query the applicable policy at this point

      else
         Check_Applicable_Policy (N);

         --  If pragma is disabled, rewrite as NULL and skip analysis

         if Is_Disabled (N) then
            Rewrite (N, Make_Null_Statement (Loc));
            Analyze (N);
            raise Pragma_Exit;
         end if;
      end if;

      --  Mark assertion pragmas as Ghost depending on their enclosing context

      if Assertion_Expression_Pragma (Prag_Id) then
         Mark_Ghost_Pragma (N, Current_Scope);
      end if;

      --  Preset arguments

      Arg_Count := 0;
      Arg1      := Empty;
      Arg2      := Empty;
      Arg3      := Empty;
      Arg4      := Empty;
      Arg5      := Empty;

      if Present (Pragma_Argument_Associations (N)) then
         Arg_Count := List_Length (Pragma_Argument_Associations (N));
         Arg1 := First (Pragma_Argument_Associations (N));

         if Present (Arg1) then
            Arg2 := Next (Arg1);

            if Present (Arg2) then
               Arg3 := Next (Arg2);

               if Present (Arg3) then
                  Arg4 := Next (Arg3);

                  if Present (Arg4) then
                     Arg5 := Next (Arg4);
                  end if;
               end if;
            end if;
         end if;
      end if;

      --  An enumeration type defines the pragmas that are supported by the
      --  implementation. Get_Pragma_Id (in package Prag) transforms a name
      --  into the corresponding enumeration value for the following case.

      case Prag_Id is

         -----------------
         -- Abort_Defer --
         -----------------

         --  pragma Abort_Defer;

         when Pragma_Abort_Defer =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            --  The only required semantic processing is to check the
            --  placement. This pragma must appear at the start of the
            --  statement sequence of a handled sequence of statements.

            if Nkind (Parent (N)) /= N_Handled_Sequence_Of_Statements
              or else N /= First (Statements (Parent (N)))
            then
               Pragma_Misplaced;
            end if;

         --------------------
         -- Abstract_State --
         --------------------

         --  pragma Abstract_State (ABSTRACT_STATE_LIST);

         --  ABSTRACT_STATE_LIST ::=
         --     null
         --  |  STATE_NAME_WITH_OPTIONS
         --  | (STATE_NAME_WITH_OPTIONS {, STATE_NAME_WITH_OPTIONS})

         --  STATE_NAME_WITH_OPTIONS ::=
         --     STATE_NAME
         --  | (STATE_NAME with OPTION_LIST)

         --  OPTION_LIST ::= OPTION {, OPTION}

         --  OPTION ::=
         --    SIMPLE_OPTION
         --  | NAME_VALUE_OPTION

         --  SIMPLE_OPTION ::= Ghost | Relaxed_Initialization | Synchronous

         --  NAME_VALUE_OPTION ::=
         --    Part_Of => ABSTRACT_STATE
         --  | External [=> EXTERNAL_PROPERTY_LIST]

         --  EXTERNAL_PROPERTY_LIST ::=
         --     EXTERNAL_PROPERTY
         --  | (EXTERNAL_PROPERTY {, EXTERNAL_PROPERTY})

         --  EXTERNAL_PROPERTY ::=
         --    Async_Readers    [=> boolean_EXPRESSION]
         --  | Async_Writers    [=> boolean_EXPRESSION]
         --  | Effective_Reads  [=> boolean_EXPRESSION]
         --  | Effective_Writes [=> boolean_EXPRESSION]
         --    others            => boolean_EXPRESSION

         --  STATE_NAME ::= defining_identifier

         --  ABSTRACT_STATE ::= name

         --  Characteristics:

         --    * Analysis - The annotation is fully analyzed immediately upon
         --    elaboration as it cannot forward reference entities.

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related package declaration.

         --    * Globals - The annotation cannot reference global entities.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic package is instantiated.

         when Pragma_Abstract_State => Abstract_State : declare
            Missing_Parentheses : Boolean := False;
            --  Flag set when a state declaration with options is not properly
            --  parenthesized.

            --  Flags used to verify the consistency of states

            Non_Null_Seen : Boolean := False;
            Null_Seen     : Boolean := False;

            procedure Analyze_Abstract_State
              (State   : Node_Id;
               Pack_Id : Entity_Id);
            --  Verify the legality of a single state declaration. Create and
            --  decorate a state abstraction entity and introduce it into the
            --  visibility chain. Pack_Id denotes the entity or the related
            --  package where pragma Abstract_State appears.

            procedure Malformed_State_Error (State : Node_Id);
            --  Emit an error concerning the illegal declaration of abstract
            --  state State. This routine diagnoses syntax errors that lead to
            --  a different parse tree. The error is issued regardless of the
            --  SPARK mode in effect.

            ----------------------------
            -- Analyze_Abstract_State --
            ----------------------------

            procedure Analyze_Abstract_State
              (State   : Node_Id;
               Pack_Id : Entity_Id)
            is
               --  Flags used to verify the consistency of options

               AR_Seen                     : Boolean := False;
               AW_Seen                     : Boolean := False;
               ER_Seen                     : Boolean := False;
               EW_Seen                     : Boolean := False;
               External_Seen               : Boolean := False;
               Ghost_Seen                  : Boolean := False;
               Others_Seen                 : Boolean := False;
               Part_Of_Seen                : Boolean := False;
               Relaxed_Initialization_Seen : Boolean := False;
               Synchronous_Seen            : Boolean := False;

               --  Flags used to store the static value of all external states'
               --  expressions.

               AR_Val : Boolean := False;
               AW_Val : Boolean := False;
               ER_Val : Boolean := False;
               EW_Val : Boolean := False;

               State_Id : Entity_Id := Empty;
               --  The entity to be generated for the current state declaration

               procedure Analyze_External_Option (Opt : Node_Id);
               --  Verify the legality of option External

               procedure Analyze_External_Property
                 (Prop : Node_Id;
                  Expr : Node_Id := Empty);
               --  Verify the legailty of a single external property. Prop
               --  denotes the external property. Expr is the expression used
               --  to set the property.

               procedure Analyze_Part_Of_Option (Opt : Node_Id);
               --  Verify the legality of option Part_Of

               procedure Check_Duplicate_Option
                 (Opt    : Node_Id;
                  Status : in out Boolean);
               --  Flag Status denotes whether a particular option has been
               --  seen while processing a state. This routine verifies that
               --  Opt is not a duplicate option and sets the flag Status
               --  (SPARK RM 7.1.4(1)).

               procedure Check_Duplicate_Property
                 (Prop   : Node_Id;
                  Status : in out Boolean);
               --  Flag Status denotes whether a particular property has been
               --  seen while processing option External. This routine verifies
               --  that Prop is not a duplicate property and sets flag Status.
               --  Opt is not a duplicate property and sets the flag Status.
               --  (SPARK RM 7.1.4(2))

               procedure Check_Ghost_Synchronous;
               --  Ensure that the abstract state is not subject to both Ghost
               --  and Synchronous simple options. Emit an error if this is the
               --  case.

               procedure Create_Abstract_State
                 (Nam     : Name_Id;
                  Decl    : Node_Id;
                  Loc     : Source_Ptr;
                  Is_Null : Boolean);
               --  Generate an abstract state entity with name Nam and enter it
               --  into visibility. Decl is the "declaration" of the state as
               --  it appears in pragma Abstract_State. Loc is the location of
               --  the related state "declaration". Flag Is_Null should be set
               --  when the associated Abstract_State pragma defines a null
               --  state.

               -----------------------------
               -- Analyze_External_Option --
               -----------------------------

               procedure Analyze_External_Option (Opt : Node_Id) is
                  Errors : constant Nat := Serious_Errors_Detected;
                  Prop   : Node_Id;
                  Props  : Node_Id := Empty;

               begin
                  if Nkind (Opt) = N_Component_Association then
                     Props := Expression (Opt);
                  end if;

                  --  External state with properties

                  if Present (Props) then

                     --  Multiple properties appear as an aggregate

                     if Nkind (Props) = N_Aggregate then

                        --  Simple property form

                        Prop := First (Expressions (Props));
                        while Present (Prop) loop
                           Analyze_External_Property (Prop);
                           Next (Prop);
                        end loop;

                        --  Property with expression form

                        Prop := First (Component_Associations (Props));
                        while Present (Prop) loop
                           Analyze_External_Property
                             (Prop => First (Choices (Prop)),
                              Expr => Expression (Prop));

                           Next (Prop);
                        end loop;

                     --  Single property

                     else
                        Analyze_External_Property (Props);
                     end if;

                  --  An external state defined without any properties defaults
                  --  all properties to True.

                  else
                     AR_Val := True;
                     AW_Val := True;
                     ER_Val := True;
                     EW_Val := True;
                  end if;

                  --  Once all external properties have been processed, verify
                  --  their mutual interaction. Do not perform the check when
                  --  at least one of the properties is illegal as this will
                  --  produce a bogus error.

                  if Errors = Serious_Errors_Detected then
                     Check_External_Properties
                       (State, AR_Val, AW_Val, ER_Val, EW_Val);
                  end if;
               end Analyze_External_Option;

               -------------------------------
               -- Analyze_External_Property --
               -------------------------------

               procedure Analyze_External_Property
                 (Prop : Node_Id;
                  Expr : Node_Id := Empty)
               is
                  Expr_Val : Boolean;

               begin
                  --  Check the placement of "others" (if available)

                  if Nkind (Prop) = N_Others_Choice then
                     if Others_Seen then
                        SPARK_Msg_N
                          ("only one OTHERS choice allowed in option External",
                           Prop);
                     else
                        Others_Seen := True;
                     end if;

                  elsif Others_Seen then
                     SPARK_Msg_N
                       ("OTHERS must be the last property in option External",
                        Prop);

                  --  The only remaining legal options are the four predefined
                  --  external properties.

                  elsif Nkind (Prop) = N_Identifier
                    and then Chars (Prop) in Name_Async_Readers
                                           | Name_Async_Writers
                                           | Name_Effective_Reads
                                           | Name_Effective_Writes
                  then
                     null;

                  --  Otherwise the construct is not a valid property

                  else
                     SPARK_Msg_N ("invalid external state property", Prop);
                     return;
                  end if;

                  --  Ensure that the expression of the external state property
                  --  is static Boolean (if applicable) (SPARK RM 7.1.2(5)).

                  if Present (Expr) then
                     Analyze_And_Resolve (Expr, Standard_Boolean);

                     if Is_OK_Static_Expression (Expr) then
                        Expr_Val := Is_True (Expr_Value (Expr));
                     else
                        SPARK_Msg_N
                          ("expression of external state property must be "
                           & "static", Expr);
                        return;
                     end if;

                  --  The lack of expression defaults the property to True

                  else
                     Expr_Val := True;
                  end if;

                  --  Named properties

                  if Nkind (Prop) = N_Identifier then
                     if Chars (Prop) = Name_Async_Readers then
                        Check_Duplicate_Property (Prop, AR_Seen);
                        AR_Val := Expr_Val;

                     elsif Chars (Prop) = Name_Async_Writers then
                        Check_Duplicate_Property (Prop, AW_Seen);
                        AW_Val := Expr_Val;

                     elsif Chars (Prop) = Name_Effective_Reads then
                        Check_Duplicate_Property (Prop, ER_Seen);
                        ER_Val := Expr_Val;

                     else
                        Check_Duplicate_Property (Prop, EW_Seen);
                        EW_Val := Expr_Val;
                     end if;

                  --  The handling of property "others" must take into account
                  --  all other named properties that have been encountered so
                  --  far. Only those that have not been seen are affected by
                  --  "others".

                  else
                     if not AR_Seen then
                        AR_Val := Expr_Val;
                     end if;

                     if not AW_Seen then
                        AW_Val := Expr_Val;
                     end if;

                     if not ER_Seen then
                        ER_Val := Expr_Val;
                     end if;

                     if not EW_Seen then
                        EW_Val := Expr_Val;
                     end if;
                  end if;
               end Analyze_External_Property;

               ----------------------------
               -- Analyze_Part_Of_Option --
               ----------------------------

               procedure Analyze_Part_Of_Option (Opt : Node_Id) is
                  Encap    : constant Node_Id := Expression (Opt);
                  Constits : Elist_Id;
                  Encap_Id : Entity_Id;
                  Legal    : Boolean;

               begin
                  Check_Duplicate_Option (Opt, Part_Of_Seen);

                  Analyze_Part_Of
                    (Indic    => First (Choices (Opt)),
                     Item_Id  => State_Id,
                     Encap    => Encap,
                     Encap_Id => Encap_Id,
                     Legal    => Legal);

                  --  The Part_Of indicator transforms the abstract state into
                  --  a constituent of the encapsulating state or single
                  --  concurrent type.

                  if Legal then
                     pragma Assert (Present (Encap_Id));
                     Constits := Part_Of_Constituents (Encap_Id);

                     if No (Constits) then
                        Constits := New_Elmt_List;
                        Set_Part_Of_Constituents (Encap_Id, Constits);
                     end if;

                     Append_Elmt (State_Id, Constits);
                     Set_Encapsulating_State (State_Id, Encap_Id);
                  end if;
               end Analyze_Part_Of_Option;

               ----------------------------
               -- Check_Duplicate_Option --
               ----------------------------

               procedure Check_Duplicate_Option
                 (Opt    : Node_Id;
                  Status : in out Boolean)
               is
               begin
                  if Status then
                     SPARK_Msg_N ("duplicate state option", Opt);
                  end if;

                  Status := True;
               end Check_Duplicate_Option;

               ------------------------------
               -- Check_Duplicate_Property --
               ------------------------------

               procedure Check_Duplicate_Property
                 (Prop   : Node_Id;
                  Status : in out Boolean)
               is
               begin
                  if Status then
                     SPARK_Msg_N ("duplicate external property", Prop);
                  end if;

                  Status := True;
               end Check_Duplicate_Property;

               -----------------------------
               -- Check_Ghost_Synchronous --
               -----------------------------

               procedure Check_Ghost_Synchronous is
               begin
                  --  A synchronized abstract state cannot be Ghost and vice
                  --  versa (SPARK RM 6.9(19)).

                  if Ghost_Seen and Synchronous_Seen then
                     SPARK_Msg_N ("synchronized state cannot be ghost", State);
                  end if;
               end Check_Ghost_Synchronous;

               ---------------------------
               -- Create_Abstract_State --
               ---------------------------

               procedure Create_Abstract_State
                 (Nam     : Name_Id;
                  Decl    : Node_Id;
                  Loc     : Source_Ptr;
                  Is_Null : Boolean)
               is
               begin
                  --  The abstract state may be semi-declared when the related
                  --  package was withed through a limited with clause. In that
                  --  case reuse the entity to fully declare the state.

                  if Present (Decl) and then Present (Entity (Decl)) then
                     State_Id := Entity (Decl);

                  --  Otherwise the elaboration of pragma Abstract_State
                  --  declares the state.

                  else
                     State_Id := Make_Defining_Identifier (Loc, Nam);

                     if Present (Decl) then
                        Set_Entity (Decl, State_Id);
                     end if;
                  end if;

                  --  Null states never come from source

                  Set_Comes_From_Source   (State_Id, not Is_Null);
                  Set_Parent              (State_Id, State);
                  Mutate_Ekind            (State_Id, E_Abstract_State);
                  Set_Etype               (State_Id, Standard_Void_Type);
                  Set_Encapsulating_State (State_Id, Empty);

                  --  Set the SPARK mode from the current context

                  Set_SPARK_Pragma           (State_Id, SPARK_Mode_Pragma);
                  Set_SPARK_Pragma_Inherited (State_Id);

                  --  An abstract state declared within a Ghost region becomes
                  --  Ghost (SPARK RM 6.9(2)).

                  if Ghost_Mode > None or else Is_Ghost_Entity (Pack_Id) then
                     Set_Is_Ghost_Entity (State_Id);
                  end if;

                  --  Establish a link between the state declaration and the
                  --  abstract state entity. Note that a null state remains as
                  --  N_Null and does not carry any linkages.

                  if not Is_Null then
                     if Present (Decl) then
                        Set_Entity (Decl, State_Id);
                        Set_Etype  (Decl, Standard_Void_Type);
                     end if;

                     --  Every non-null state must be defined, nameable and
                     --  resolvable.

                     Push_Scope (Pack_Id);
                     Generate_Definition (State_Id);
                     Enter_Name (State_Id);
                     Pop_Scope;
                  end if;
               end Create_Abstract_State;

               --  Local variables

               Opt     : Node_Id;
               Opt_Nam : Node_Id;

            --  Start of processing for Analyze_Abstract_State

            begin
               --  A package with a null abstract state is not allowed to
               --  declare additional states.

               if Null_Seen then
                  SPARK_Msg_NE
                    ("package & has null abstract state", State, Pack_Id);

               --  Null states appear as internally generated entities

               elsif Nkind (State) = N_Null then
                  Create_Abstract_State
                    (Nam     => New_Internal_Name ('S'),
                     Decl    => Empty,
                     Loc     => Sloc (State),
                     Is_Null => True);
                  Null_Seen := True;

                  --  Catch a case where a null state appears in a list of
                  --  non-null states.

                  if Non_Null_Seen then
                     SPARK_Msg_NE
                       ("package & has non-null abstract state",
                        State, Pack_Id);
                  end if;

               --  Simple state declaration

               elsif Nkind (State) = N_Identifier then
                  Create_Abstract_State
                    (Nam     => Chars (State),
                     Decl    => State,
                     Loc     => Sloc (State),
                     Is_Null => False);
                  Non_Null_Seen := True;

               --  State declaration with various options. This construct
               --  appears as an extension aggregate in the tree.

               elsif Nkind (State) = N_Extension_Aggregate then
                  if Nkind (Ancestor_Part (State)) = N_Identifier then
                     Create_Abstract_State
                       (Nam     => Chars (Ancestor_Part (State)),
                        Decl    => Ancestor_Part (State),
                        Loc     => Sloc (Ancestor_Part (State)),
                        Is_Null => False);
                     Non_Null_Seen := True;
                  else
                     SPARK_Msg_N
                       ("state name must be an identifier",
                        Ancestor_Part (State));
                  end if;

                  --  Options External, Ghost and Synchronous appear as
                  --  expressions.

                  Opt := First (Expressions (State));
                  while Present (Opt) loop
                     if Nkind (Opt) = N_Identifier then

                        --  External

                        if Chars (Opt) = Name_External then
                           Check_Duplicate_Option (Opt, External_Seen);
                           Analyze_External_Option (Opt);

                        --  Ghost

                        elsif Chars (Opt) = Name_Ghost then
                           Check_Duplicate_Option (Opt, Ghost_Seen);
                           Check_Ghost_Synchronous;

                           if Present (State_Id) then
                              Set_Is_Ghost_Entity (State_Id);
                           end if;

                        --  Synchronous

                        elsif Chars (Opt) = Name_Synchronous then
                           Check_Duplicate_Option (Opt, Synchronous_Seen);
                           Check_Ghost_Synchronous;

                        --  Relaxed_Initialization

                        elsif Chars (Opt) = Name_Relaxed_Initialization then
                           Check_Duplicate_Option
                             (Opt, Relaxed_Initialization_Seen);

                        --  Option Part_Of without an encapsulating state is
                        --  illegal (SPARK RM 7.1.4(8)).

                        elsif Chars (Opt) = Name_Part_Of then
                           SPARK_Msg_N
                             ("indicator Part_Of must denote abstract state, "
                              & "single protected type or single task type",
                              Opt);

                        --  Do not emit an error message when a previous state
                        --  declaration with options was not parenthesized as
                        --  the option is actually another state declaration.
                        --
                        --    with Abstract_State
                        --      (State_1 with ...,   --  missing parentheses
                        --      (State_2 with ...),
                        --       State_3)            --  ok state declaration

                        elsif Missing_Parentheses then
                           null;

                        --  Otherwise the option is not allowed. Note that it
                        --  is not possible to distinguish between an option
                        --  and a state declaration when a previous state with
                        --  options not properly parentheses.
                        --
                        --    with Abstract_State
                        --      (State_1 with ...,  --  missing parentheses
                        --       State_2);          --  could be an option

                        else
                           SPARK_Msg_N
                             ("simple option not allowed in state declaration",
                              Opt);
                        end if;

                     --  Catch a case where missing parentheses around a state
                     --  declaration with options cause a subsequent state
                     --  declaration with options to be treated as an option.
                     --
                     --    with Abstract_State
                     --      (State_1 with ...,   --  missing parentheses
                     --      (State_2 with ...))

                     elsif Nkind (Opt) = N_Extension_Aggregate then
                        Missing_Parentheses := True;
                        SPARK_Msg_N
                          ("state declaration must be parenthesized",
                           Ancestor_Part (State));

                     --  Otherwise the option is malformed

                     else
                        SPARK_Msg_N ("malformed option", Opt);
                     end if;

                     Next (Opt);
                  end loop;

                  --  Options External and Part_Of appear as component
                  --  associations.

                  Opt := First (Component_Associations (State));
                  while Present (Opt) loop
                     Opt_Nam := First (Choices (Opt));

                     if Nkind (Opt_Nam) = N_Identifier then
                        if Chars (Opt_Nam) = Name_External then
                           Analyze_External_Option (Opt);

                        elsif Chars (Opt_Nam) = Name_Part_Of then
                           Analyze_Part_Of_Option (Opt);

                        else
                           SPARK_Msg_N ("invalid state option", Opt);
                        end if;
                     else
                        SPARK_Msg_N ("invalid state option", Opt);
                     end if;

                     Next (Opt);
                  end loop;

               --  Any other attempt to declare a state is illegal

               else
                  Malformed_State_Error (State);
                  return;
               end if;

               --  Guard against a junk state. In such cases no entity is
               --  generated and the subsequent checks cannot be applied.

               if Present (State_Id) then

                  --  Verify whether the state does not introduce an illegal
                  --  hidden state within a package subject to a null abstract
                  --  state.

                  Check_No_Hidden_State (State_Id);

                  --  Check whether the lack of option Part_Of agrees with the
                  --  placement of the abstract state with respect to the state
                  --  space.

                  if not Part_Of_Seen then
                     Check_Missing_Part_Of (State_Id);
                  end if;

                  --  Associate the state with its related package

                  if No (Abstract_States (Pack_Id)) then
                     Set_Abstract_States (Pack_Id, New_Elmt_List);
                  end if;

                  Append_Elmt (State_Id, Abstract_States (Pack_Id));
               end if;
            end Analyze_Abstract_State;

            ---------------------------
            -- Malformed_State_Error --
            ---------------------------

            procedure Malformed_State_Error (State : Node_Id) is
            begin
               Error_Msg_N ("malformed abstract state declaration", State);

               --  An abstract state with a simple option is being declared
               --  with "=>" rather than the legal "with". The state appears
               --  as a component association.

               if Nkind (State) = N_Component_Association then
                  Error_Msg_N ("\use WITH to specify simple option", State);
               end if;
            end Malformed_State_Error;

            --  Local variables

            Pack_Decl : Node_Id;
            Pack_Id   : Entity_Id;
            State     : Node_Id;
            States    : Node_Id;

         --  Start of processing for Abstract_State

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Pack_Decl := Find_Related_Package_Or_Body (N, Do_Checks => True);

            if Nkind (Pack_Decl) not in
                 N_Generic_Package_Declaration | N_Package_Declaration
            then
               Pragma_Misplaced;
               return;
            end if;

            Pack_Id := Defining_Entity (Pack_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Pack_Id);
            Ensure_Aggregate_Form (Get_Argument (N, Pack_Id));

            --  Chain the pragma on the contract for completeness

            Add_Contract_Item (N, Pack_Id);

            --  The legality checks of pragmas Abstract_State, Initializes, and
            --  Initial_Condition are affected by the SPARK mode in effect. In
            --  addition, these three pragmas are subject to an inherent order:

            --    1) Abstract_State
            --    2) Initializes
            --    3) Initial_Condition

            --  Analyze all these pragmas in the order outlined above

            Analyze_If_Present (Pragma_SPARK_Mode);
            States := Expression (Get_Argument (N, Pack_Id));

            --  Multiple non-null abstract states appear as an aggregate

            if Nkind (States) = N_Aggregate then
               State := First (Expressions (States));
               while Present (State) loop
                  Analyze_Abstract_State (State, Pack_Id);
                  Next (State);
               end loop;

               --  An abstract state with a simple option is being illegaly
               --  declared with "=>" rather than "with". In this case the
               --  state declaration appears as a component association.

               if Present (Component_Associations (States)) then
                  State := First (Component_Associations (States));
                  while Present (State) loop
                     Malformed_State_Error (State);
                     Next (State);
                  end loop;
               end if;

            --  Various forms of a single abstract state. Note that these may
            --  include malformed state declarations.

            else
               Analyze_Abstract_State (States, Pack_Id);
            end if;

            Analyze_If_Present (Pragma_Initializes);
            Analyze_If_Present (Pragma_Initial_Condition);
         end Abstract_State;

         ------------
         -- Ada_83 --
         ------------

         --  pragma Ada_83;

         --  Note: this pragma also has some specific processing in Par.Prag
         --  because we want to set the Ada version mode during parsing.

         when Pragma_Ada_83 =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            --  We really should check unconditionally for proper configuration
            --  pragma placement, since we really don't want mixed Ada modes
            --  within a single unit, and the GNAT reference manual has always
            --  said this was a configuration pragma, but we did not check and
            --  are hesitant to add the check now.

            --  However, we really cannot tolerate mixing Ada 2005 or Ada 2012
            --  with Ada 83 or Ada 95, so we must check if we are in Ada 2005
            --  or Ada 2012 mode.

            if Ada_Version >= Ada_2005 then
               Check_Valid_Configuration_Pragma;
            end if;

            --  Now set Ada 83 mode

            if Latest_Ada_Only then
               Error_Pragma ("??pragma% ignored");
            else
               Ada_Version          := Ada_83;
               Ada_Version_Explicit := Ada_83;
               Ada_Version_Pragma   := N;
            end if;

         ------------
         -- Ada_95 --
         ------------

         --  pragma Ada_95;

         --  Note: this pragma also has some specific processing in Par.Prag
         --  because we want to set the Ada 83 version mode during parsing.

         when Pragma_Ada_95 =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            --  We really should check unconditionally for proper configuration
            --  pragma placement, since we really don't want mixed Ada modes
            --  within a single unit, and the GNAT reference manual has always
            --  said this was a configuration pragma, but we did not check and
            --  are hesitant to add the check now.

            --  However, we really cannot tolerate mixing Ada 2005 with Ada 83
            --  or Ada 95, so we must check if we are in Ada 2005 mode.

            if Ada_Version >= Ada_2005 then
               Check_Valid_Configuration_Pragma;
            end if;

            --  Now set Ada 95 mode

            if Latest_Ada_Only then
               Error_Pragma ("??pragma% ignored");
            else
               Ada_Version          := Ada_95;
               Ada_Version_Explicit := Ada_95;
               Ada_Version_Pragma   := N;
            end if;

         ---------------------
         -- Ada_05/Ada_2005 --
         ---------------------

         --  pragma Ada_05;
         --  pragma Ada_05 (LOCAL_NAME);

         --  pragma Ada_2005;
         --  pragma Ada_2005 (LOCAL_NAME):

         --  Note: these pragmas also have some specific processing in Par.Prag
         --  because we want to set the Ada 2005 version mode during parsing.

         --  The one argument form is used for managing the transition from
         --  Ada 95 to Ada 2005 in the run-time library. If an entity is marked
         --  as Ada_2005 only, then referencing the entity in Ada_83 or Ada_95
         --  mode will generate a warning. In addition, in Ada_83 or Ada_95
         --  mode, a preference rule is established which does not choose
         --  such an entity unless it is unambiguously specified. This avoids
         --  extra subprograms marked this way from generating ambiguities in
         --  otherwise legal pre-Ada_2005 programs. The one argument form is
         --  intended for exclusive use in the GNAT run-time library.

         when Pragma_Ada_05
            | Pragma_Ada_2005
         =>
         declare
            E_Id : Node_Id;

         begin
            GNAT_Pragma;

            if Arg_Count = 1 then
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               Set_Is_Ada_2005_Only (Entity (E_Id));
               Record_Rep_Item (Entity (E_Id), N);

            else
               Check_Arg_Count (0);

               --  For Ada_2005 we unconditionally enforce the documented
               --  configuration pragma placement, since we do not want to
               --  tolerate mixed modes in a unit involving Ada 2005. That
               --  would cause real difficulties for those cases where there
               --  are incompatibilities between Ada 95 and Ada 2005.

               Check_Valid_Configuration_Pragma;

               --  Now set appropriate Ada mode

               if Latest_Ada_Only then
                  Error_Pragma ("??pragma% ignored");
               else
                  Ada_Version          := Ada_2005;
                  Ada_Version_Explicit := Ada_2005;
                  Ada_Version_Pragma   := N;
               end if;
            end if;
         end;

         ---------------------
         -- Ada_12/Ada_2012 --
         ---------------------

         --  pragma Ada_12;
         --  pragma Ada_12 (LOCAL_NAME);

         --  pragma Ada_2012;
         --  pragma Ada_2012 (LOCAL_NAME):

         --  Note: these pragmas also have some specific processing in Par.Prag
         --  because we want to set the Ada 2012 version mode during parsing.

         --  The one argument form is used for managing the transition from Ada
         --  2005 to Ada 2012 in the run-time library. If an entity is marked
         --  as Ada_2012 only, then referencing the entity in any pre-Ada_2012
         --  mode will generate a warning. In addition, in any pre-Ada_2012
         --  mode, a preference rule is established which does not choose
         --  such an entity unless it is unambiguously specified. This avoids
         --  extra subprograms marked this way from generating ambiguities in
         --  otherwise legal pre-Ada_2012 programs. The one argument form is
         --  intended for exclusive use in the GNAT run-time library.

         when Pragma_Ada_12
            | Pragma_Ada_2012
         =>
         declare
            E_Id : Node_Id;

         begin
            GNAT_Pragma;

            if Arg_Count = 1 then
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               Set_Is_Ada_2012_Only (Entity (E_Id));
               Record_Rep_Item (Entity (E_Id), N);

            else
               Check_Arg_Count (0);

               --  For Ada_2012 we unconditionally enforce the documented
               --  configuration pragma placement, since we do not want to
               --  tolerate mixed modes in a unit involving Ada 2012. That
               --  would cause real difficulties for those cases where there
               --  are incompatibilities between Ada 95 and Ada 2012. We could
               --  allow mixing of Ada 2005 and Ada 2012 but it's not worth it.

               Check_Valid_Configuration_Pragma;

               --  Now set appropriate Ada mode

               Ada_Version          := Ada_2012;
               Ada_Version_Explicit := Ada_2012;
               Ada_Version_Pragma   := N;
            end if;
         end;

         --------------
         -- Ada_2022 --
         --------------

         --  pragma Ada_2022;
         --  pragma Ada_2022 (LOCAL_NAME):

         --  Note: this pragma also has some specific processing in Par.Prag
         --  because we want to set the Ada 2022 version mode during parsing.

         --  The one argument form is used for managing the transition from Ada
         --  2012 to Ada 2022 in the run-time library. If an entity is marked
         --  as Ada_2022 only, then referencing the entity in any pre-Ada_2022
         --  mode will generate a warning;for calls to Ada_2022 only primitives
         --  that require overriding an error will be reported. In addition, in
         --  any pre-Ada_2022 mode, a preference rule is established which does
         --  not choose such an entity unless it is unambiguously specified.
         --  This avoids extra subprograms marked this way from generating
         --  ambiguities in otherwise legal pre-Ada 2022 programs. The one
         --  argument form is intended for exclusive use in the GNAT run-time
         --  library.

         when Pragma_Ada_2022 =>
         declare
            E_Id : Node_Id;

         begin
            GNAT_Pragma;

            if Arg_Count = 1 then
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               Set_Is_Ada_2022_Only (Entity (E_Id));
               Record_Rep_Item (Entity (E_Id), N);

            else
               Check_Arg_Count (0);

               --  For Ada_2022 we unconditionally enforce the documented
               --  configuration pragma placement, since we do not want to
               --  tolerate mixed modes in a unit involving Ada 2022. That
               --  would cause real difficulties for those cases where there
               --  are incompatibilities between Ada 2012 and Ada 2022. We
               --  could allow mixing of Ada 2012 and Ada 2022 but it's not
               --  worth it.

               Check_Valid_Configuration_Pragma;

               --  Now set appropriate Ada mode

               Ada_Version          := Ada_2022;
               Ada_Version_Explicit := Ada_2022;
               Ada_Version_Pragma   := N;
            end if;
         end;

         -------------------------------------
         -- Aggregate_Individually_Assign --
         -------------------------------------

         --  pragma Aggregate_Individually_Assign;

         when Pragma_Aggregate_Individually_Assign =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Aggregate_Individually_Assign := True;

         ----------------------
         -- All_Calls_Remote --
         ----------------------

         --  pragma All_Calls_Remote [(library_package_NAME)];

         when Pragma_All_Calls_Remote => All_Calls_Remote : declare
            Lib_Entity : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Lib_Entity := Find_Lib_Unit_Name;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Lib_Entity);

            --  This pragma should only apply to a RCI unit (RM E.2.3(23))

            if Present (Lib_Entity) and then not Debug_Flag_U then
               if not Is_Remote_Call_Interface (Lib_Entity) then
                  Error_Pragma ("pragma% only apply to rci unit");

               --  Set flag for entity of the library unit

               else
                  Set_Has_All_Calls_Remote (Lib_Entity);
               end if;
            end if;
         end All_Calls_Remote;

         ---------------------------
         -- Allow_Integer_Address --
         ---------------------------

         --  pragma Allow_Integer_Address;

         when Pragma_Allow_Integer_Address =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (0);

            --  If Address is a private type, then set the flag to allow
            --  integer address values. If Address is not private, then this
            --  pragma has no purpose, so it is simply ignored. Not clear if
            --  there are any such targets now.

            if Opt.Address_Is_Private then
               Opt.Allow_Integer_Address := True;
            end if;

         --------------
         -- Annotate --
         --------------

         --  pragma Annotate
         --    (IDENTIFIER [, IDENTIFIER {, ARG}] [,Entity => local_NAME]);
         --  ARG ::= NAME | EXPRESSION

         --  The first two arguments are by convention intended to refer to an
         --  external tool and a tool-specific function. These arguments are
         --  not analyzed.

         when Pragma_Annotate | Pragma_GNAT_Annotate => Annotate : declare
            Arg     : Node_Id;
            Expr    : Node_Id;
            Nam_Arg : Node_Id;

            --------------------------
            -- Inferred_String_Type --
            --------------------------

            function Preferred_String_Type (Expr : Node_Id) return Entity_Id;
            --  Infer the type to use for a string literal or a concatentation
            --  of operands whose types can be inferred. For such expressions,
            --  returns the "narrowest" of the three predefined string types
            --  that can represent the characters occurring in the expression.
            --  For other expressions, returns Empty.

            function Preferred_String_Type (Expr : Node_Id) return Entity_Id is
            begin
               case Nkind (Expr) is
                  when N_String_Literal =>
                     if Has_Wide_Wide_Character (Expr) then
                        return Standard_Wide_Wide_String;
                     elsif Has_Wide_Character (Expr) then
                        return Standard_Wide_String;
                     else
                        return Standard_String;
                     end if;

                  when N_Op_Concat =>
                     declare
                        L_Type : constant Entity_Id
                          := Preferred_String_Type (Left_Opnd (Expr));
                        R_Type : constant Entity_Id
                          := Preferred_String_Type (Right_Opnd (Expr));

                        Type_Table : constant array (1 .. 4) of Entity_Id
                          := (Empty,
                              Standard_Wide_Wide_String,
                              Standard_Wide_String,
                              Standard_String);
                     begin
                        for Idx in Type_Table'Range loop
                           if (L_Type = Type_Table (Idx)) or
                              (R_Type = Type_Table (Idx))
                           then
                              return Type_Table (Idx);
                           end if;
                        end loop;
                        raise Program_Error;
                     end;

                  when others =>
                     return Empty;
               end case;
            end Preferred_String_Type;
         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);

            Nam_Arg := Last (Pragma_Argument_Associations (N));

            --  Determine whether the last argument is "Entity => local_NAME"
            --  and if it is, perform the required semantic checks. Remove the
            --  argument from further processing.

            if Nkind (Nam_Arg) = N_Pragma_Argument_Association
              and then Chars (Nam_Arg) = Name_Entity
            then
               Check_Arg_Is_Local_Name (Nam_Arg);
               Arg_Count := Arg_Count - 1;

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               if Is_Entity_Name (Get_Pragma_Arg (Nam_Arg))
                 and then Present (Entity (Get_Pragma_Arg (Nam_Arg)))
               then
                  Mark_Ghost_Pragma (N, Entity (Get_Pragma_Arg (Nam_Arg)));
               end if;

               --  Not allowed in compiler units (bootstrap issues)

               Check_Compiler_Unit ("Entity for pragma Annotate", N);
            end if;

            --  Continue the processing with last argument removed for now

            Check_Arg_Is_Identifier (Arg1);
            Check_No_Identifiers;
            Store_Note (N);

            --  The second parameter is optional, it is never analyzed

            if No (Arg2) then
               null;

            --  Otherwise there is a second parameter

            else
               --  The second parameter must be an identifier

               Check_Arg_Is_Identifier (Arg2);

               --  Process the remaining parameters (if any)

               Arg := Next (Arg2);
               while Present (Arg) loop
                  Expr := Get_Pragma_Arg (Arg);
                  Analyze (Expr);

                  if Is_Entity_Name (Expr) then
                     null;

                  --  For string literals and concatenations of string literals
                  --  we assume Standard_String as the type, unless the string
                  --  contains wide or wide_wide characters.

                  elsif Present (Preferred_String_Type (Expr)) then
                     Resolve (Expr, Preferred_String_Type (Expr));

                  elsif Is_Overloaded (Expr) then
                     Error_Pragma_Arg ("ambiguous argument for pragma%", Expr);

                  else
                     Resolve (Expr);
                  end if;

                  Next (Arg);
               end loop;
            end if;
         end Annotate;

         -------------------------------------------------
         -- Assert/Assert_And_Cut/Assume/Loop_Invariant --
         -------------------------------------------------

         --  pragma Assert
         --    (   [Check => ]  Boolean_EXPRESSION
         --     [, [Message =>] Static_String_EXPRESSION]);

         --  pragma Assert_And_Cut
         --    (   [Check => ]  Boolean_EXPRESSION
         --     [, [Message =>] Static_String_EXPRESSION]);

         --  pragma Assume
         --    (   [Check => ]  Boolean_EXPRESSION
         --     [, [Message =>] Static_String_EXPRESSION]);

         --  pragma Loop_Invariant
         --    (   [Check => ]  Boolean_EXPRESSION
         --     [, [Message =>] Static_String_EXPRESSION]);

         when Pragma_Assert
            | Pragma_Assert_And_Cut
            | Pragma_Assume
            | Pragma_Loop_Invariant
         =>
         Assert : declare
            function Contains_Loop_Entry (Expr : Node_Id) return Boolean;
            --  Determine whether expression Expr contains a Loop_Entry
            --  attribute reference.

            -------------------------
            -- Contains_Loop_Entry --
            -------------------------

            function Contains_Loop_Entry (Expr : Node_Id) return Boolean is
               Has_Loop_Entry : Boolean := False;

               function Process (N : Node_Id) return Traverse_Result;
               --  Process function for traversal to look for Loop_Entry

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

               function Process (N : Node_Id) return Traverse_Result is
               begin
                  if Nkind (N) = N_Attribute_Reference
                    and then Attribute_Name (N) = Name_Loop_Entry
                  then
                     Has_Loop_Entry := True;
                     return Abandon;
                  else
                     return OK;
                  end if;
               end Process;

               procedure Traverse is new Traverse_Proc (Process);

            --  Start of processing for Contains_Loop_Entry

            begin
               Traverse (Expr);
               return Has_Loop_Entry;
            end Contains_Loop_Entry;

            --  Local variables

            Expr     : Node_Id;
            New_Args : List_Id;

         --  Start of processing for Assert

         begin
            --  Assert is an Ada 2005 RM-defined pragma

            if Prag_Id = Pragma_Assert then
               Ada_2005_Pragma;

            --  The remaining ones are GNAT pragmas

            else
               GNAT_Pragma;
            end if;

            Check_At_Least_N_Arguments (1);
            Check_At_Most_N_Arguments (2);
            Check_Arg_Order ((Name_Check, Name_Message));
            Check_Optional_Identifier (Arg1, Name_Check);
            Expr := Get_Pragma_Arg (Arg1);

            --  Special processing for Loop_Invariant, Loop_Variant or for
            --  other cases where a Loop_Entry attribute is present. If the
            --  assertion pragma contains attribute Loop_Entry, ensure that
            --  the related pragma is within a loop.

            if        Prag_Id = Pragma_Loop_Invariant
              or else Prag_Id = Pragma_Loop_Variant
              or else Contains_Loop_Entry (Expr)
            then
               Check_Loop_Pragma_Placement;

               --  Perform preanalysis to deal with embedded Loop_Entry
               --  attributes.

               Preanalyze_Assert_Expression (Expr, Any_Boolean);
            end if;

            --  Implement Assert[_And_Cut]/Assume/Loop_Invariant by generating
            --  a corresponding Check pragma:

            --    pragma Check (name, condition [, msg]);

            --  Where name is the identifier matching the pragma name. So
            --  rewrite pragma in this manner, transfer the message argument
            --  if present, and analyze the result

            --  Note: When dealing with a semantically analyzed tree, the
            --  information that a Check node N corresponds to a source Assert,
            --  Assume, or Assert_And_Cut pragma can be retrieved from the
            --  pragma kind of Original_Node(N).

            New_Args := New_List (
              Make_Pragma_Argument_Association (Loc,
                Expression => Make_Identifier (Loc, Pname)),
              Make_Pragma_Argument_Association (Sloc (Expr),
                Expression => Expr));

            if Arg_Count > 1 then
               Check_Optional_Identifier (Arg2, Name_Message);

               --  Provide semantic annotations for optional argument, for
               --  ASIS use, before rewriting.
               --  Is this still needed???

               Preanalyze_And_Resolve (Expression (Arg2), Standard_String);
               Append_To (New_Args, New_Copy_Tree (Arg2));
            end if;

            --  Rewrite as Check pragma

            Rewrite (N,
              Make_Pragma (Loc,
                Chars                        => Name_Check,
                Pragma_Argument_Associations => New_Args));

            Analyze (N);
         end Assert;

         ----------------------
         -- Assertion_Policy --
         ----------------------

         --  pragma Assertion_Policy (POLICY_IDENTIFIER);

         --  The following form is Ada 2012 only, but we allow it in all modes

         --  Pragma Assertion_Policy (
         --      ASSERTION_KIND => POLICY_IDENTIFIER
         --   {, ASSERTION_KIND => POLICY_IDENTIFIER});

         --  ASSERTION_KIND ::= RM_ASSERTION_KIND | ID_ASSERTION_KIND

         --  RM_ASSERTION_KIND ::= Assert                     |
         --                        Static_Predicate           |
         --                        Dynamic_Predicate          |
         --                        Pre                        |
         --                        Pre'Class                  |
         --                        Post                       |
         --                        Post'Class                 |
         --                        Type_Invariant             |
         --                        Type_Invariant'Class       |
         --                        Default_Initial_Condition

         --  ID_ASSERTION_KIND ::= Assert_And_Cut       |
         --                        Assume               |
         --                        Contract_Cases       |
         --                        Debug                |
         --                        Ghost                |
         --                        Initial_Condition    |
         --                        Loop_Invariant       |
         --                        Loop_Variant         |
         --                        Postcondition        |
         --                        Precondition         |
         --                        Predicate            |
         --                        Refined_Post         |
         --                        Statement_Assertions |
         --                        Subprogram_Variant

         --  Note: The RM_ASSERTION_KIND list is language-defined, and the
         --  ID_ASSERTION_KIND list contains implementation-defined additions
         --  recognized by GNAT. The effect is to control the behavior of
         --  identically named aspects and pragmas, depending on the specified
         --  policy identifier:

         --  POLICY_IDENTIFIER ::= Check | Disable | Ignore | Suppressible

         --  Note: Check and Ignore are language-defined. Disable is a GNAT
         --  implementation-defined addition that results in totally ignoring
         --  the corresponding assertion. If Disable is specified, then the
         --  argument of the assertion is not even analyzed. This is useful
         --  when the aspect/pragma argument references entities in a with'ed
         --  package that is replaced by a dummy package in the final build.

         --  Note: the attribute forms Pre'Class, Post'Class, Invariant'Class,
         --  and Type_Invariant'Class were recognized by the parser and
         --  transformed into references to the special internal identifiers
         --  _Pre, _Post, _Invariant, and _Type_Invariant, so no special
         --  processing is required here.

         when Pragma_Assertion_Policy => Assertion_Policy : declare
            procedure Resolve_Suppressible (Policy : Node_Id);
            --  Converts the assertion policy 'Suppressible' to either Check or
            --  Ignore based on whether checks are suppressed via -gnatp.

            --------------------------
            -- Resolve_Suppressible --
            --------------------------

            procedure Resolve_Suppressible (Policy : Node_Id) is
               Arg : constant Node_Id := Get_Pragma_Arg (Policy);
               Nam : Name_Id;

            begin
               --  Transform policy argument Suppressible into either Ignore or
               --  Check depending on whether checks are enabled or suppressed.

               if Chars (Arg) = Name_Suppressible then
                  if Suppress_Checks then
                     Nam := Name_Ignore;
                  else
                     Nam := Name_Check;
                  end if;

                  Rewrite (Arg, Make_Identifier (Sloc (Arg), Nam));
               end if;
            end Resolve_Suppressible;

            --  Local variables

            Arg    : Node_Id;
            Kind   : Name_Id;
            LocP   : Source_Ptr;
            Policy : Node_Id;

         begin
            Ada_2005_Pragma;

            --  This can always appear as a configuration pragma

            if Is_Configuration_Pragma then
               null;

            --  It can also appear in a declarative part or package spec in Ada
            --  2012 mode. We allow this in other modes, but in that case we
            --  consider that we have an Ada 2012 pragma on our hands.

            else
               Check_Is_In_Decl_Part_Or_Package_Spec;
               Ada_2012_Pragma;
            end if;

            --  One argument case with no identifier (first form above)

            if Arg_Count = 1
              and then (Nkind (Arg1) /= N_Pragma_Argument_Association
                         or else Chars (Arg1) = No_Name)
            then
               Check_Arg_Is_One_Of (Arg1,
                 Name_Check, Name_Disable, Name_Ignore, Name_Suppressible);

               Resolve_Suppressible (Arg1);

               --  Treat one argument Assertion_Policy as equivalent to:

               --    pragma Check_Policy (Assertion, policy)

               --  So rewrite pragma in that manner and link on to the chain
               --  of Check_Policy pragmas, marking the pragma as analyzed.

               Policy := Get_Pragma_Arg (Arg1);

               Rewrite (N,
                 Make_Pragma (Loc,
                   Chars                        => Name_Check_Policy,
                   Pragma_Argument_Associations => New_List (
                     Make_Pragma_Argument_Association (Loc,
                       Expression => Make_Identifier (Loc, Name_Assertion)),

                     Make_Pragma_Argument_Association (Loc,
                       Expression =>
                         Make_Identifier (Sloc (Policy), Chars (Policy))))));
               Analyze (N);

            --  Here if we have two or more arguments

            else
               Check_At_Least_N_Arguments (1);
               Ada_2012_Pragma;

               --  Loop through arguments

               Arg := Arg1;
               while Present (Arg) loop
                  LocP := Sloc (Arg);

                  --  Kind must be specified

                  if Nkind (Arg) /= N_Pragma_Argument_Association
                    or else Chars (Arg) = No_Name
                  then
                     Error_Pragma_Arg
                       ("missing assertion kind for pragma%", Arg);
                  end if;

                  --  Check Kind and Policy have allowed forms

                  Kind   := Chars (Arg);
                  Policy := Get_Pragma_Arg (Arg);

                  if not Is_Valid_Assertion_Kind (Kind) then
                     Error_Pragma_Arg
                       ("invalid assertion kind for pragma%", Arg);
                  end if;

                  Check_Arg_Is_One_Of (Arg,
                    Name_Check, Name_Disable, Name_Ignore, Name_Suppressible);

                  Resolve_Suppressible (Arg);

                  if Kind = Name_Ghost then

                     --  The Ghost policy must be either Check or Ignore
                     --  (SPARK RM 6.9(6)).

                     if Chars (Policy) not in Name_Check | Name_Ignore then
                        Error_Pragma_Arg
                          ("argument of pragma % Ghost must be Check or "
                           & "Ignore", Policy);
                     end if;

                     --  Pragma Assertion_Policy specifying a Ghost policy
                     --  cannot occur within a Ghost subprogram or package
                     --  (SPARK RM 6.9(14)).

                     if Ghost_Mode > None then
                        Error_Pragma
                          ("pragma % cannot appear within ghost subprogram or "
                           & "package");
                     end if;
                  end if;

                  --  Rewrite the Assertion_Policy pragma as a series of
                  --  Check_Policy pragmas of the form:

                  --    Check_Policy (Kind, Policy);

                  --  Note: the insertion of the pragmas cannot be done with
                  --  Insert_Action because in the configuration case, there
                  --  are no scopes on the scope stack and the mechanism will
                  --  fail.

                  Insert_Before_And_Analyze (N,
                    Make_Pragma (LocP,
                      Chars                        => Name_Check_Policy,
                      Pragma_Argument_Associations => New_List (
                         Make_Pragma_Argument_Association (LocP,
                           Expression => Make_Identifier (LocP, Kind)),
                         Make_Pragma_Argument_Association (LocP,
                           Expression => Policy))));

                  Arg := Next (Arg);
               end loop;

               --  Rewrite the Assertion_Policy pragma as null since we have
               --  now inserted all the equivalent Check pragmas.

               Rewrite (N, Make_Null_Statement (Loc));
               Analyze (N);
            end if;
         end Assertion_Policy;

         ------------------------------
         -- Assume_No_Invalid_Values --
         ------------------------------

         --  pragma Assume_No_Invalid_Values (On | Off);

         when Pragma_Assume_No_Invalid_Values =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);

            if Chars (Get_Pragma_Arg (Arg1)) = Name_On then
               Assume_No_Invalid_Values := True;
            else
               Assume_No_Invalid_Values := False;
            end if;

         --------------------------
         -- Attribute_Definition --
         --------------------------

         --  pragma Attribute_Definition
         --    ([Attribute  =>] ATTRIBUTE_DESIGNATOR,
         --     [Entity     =>] LOCAL_NAME,
         --     [Expression =>] EXPRESSION | NAME);

         when Pragma_Attribute_Definition => Attribute_Definition : declare
            Attribute_Designator : constant Node_Id := Get_Pragma_Arg (Arg1);
            Aname                : Name_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (3);
            Check_Optional_Identifier (Arg1, "attribute");
            Check_Optional_Identifier (Arg2, "entity");
            Check_Optional_Identifier (Arg3, "expression");

            if Nkind (Attribute_Designator) /= N_Identifier then
               Error_Msg_N ("attribute name expected", Attribute_Designator);
               return;
            end if;

            Check_Arg_Is_Local_Name (Arg2);

            --  If the attribute is not recognized, then issue a warning (not
            --  an error), and ignore the pragma.

            Aname := Chars (Attribute_Designator);

            if not Is_Attribute_Name (Aname) then
               Bad_Attribute (Attribute_Designator, Aname, Warn => True);
               return;
            end if;

            --  Otherwise, rewrite the pragma as an attribute definition clause

            Rewrite (N,
              Make_Attribute_Definition_Clause (Loc,
                Name       => Get_Pragma_Arg (Arg2),
                Chars      => Aname,
                Expression => Get_Pragma_Arg (Arg3)));
            Analyze (N);
         end Attribute_Definition;

         ------------------------------------------------------------------
         -- Async_Readers/Async_Writers/Effective_Reads/Effective_Writes --
         --                          No_Caching                          --
         ------------------------------------------------------------------

         --  pragma Async_Readers    [ (boolean_EXPRESSION) ];
         --  pragma Async_Writers    [ (boolean_EXPRESSION) ];
         --  pragma Effective_Reads  [ (boolean_EXPRESSION) ];
         --  pragma Effective_Writes [ (boolean_EXPRESSION) ];
         --  pragma No_Caching       [ (boolean_EXPRESSION) ];

         when Pragma_Async_Readers
            | Pragma_Async_Writers
            | Pragma_Effective_Reads
            | Pragma_Effective_Writes
            | Pragma_No_Caching
         =>
         Async_Effective : declare
            Obj_Or_Type_Decl : Node_Id;
            Obj_Or_Type_Id   : Entity_Id;
         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments  (1);

            Obj_Or_Type_Decl := Find_Related_Context (N, Do_Checks => True);

            --  Pragma must apply to a object declaration or to a type
            --  declaration (only the former in the No_Caching case).
            --  Original_Node is necessary to account for untagged derived
            --  types that are rewritten as subtypes of their
            --  respective root types.

            if Nkind (Obj_Or_Type_Decl) /= N_Object_Declaration then
               if Prag_Id = Pragma_No_Caching
                  or else Nkind (Original_Node (Obj_Or_Type_Decl)) not in
                            N_Full_Type_Declaration    |
                            N_Private_Type_Declaration |
                            N_Formal_Type_Declaration  |
                            N_Task_Type_Declaration    |
                            N_Protected_Type_Declaration
               then
                  Pragma_Misplaced;
                  return;
               end if;
            end if;

            Obj_Or_Type_Id := Defining_Entity (Obj_Or_Type_Decl);

            --  Perform minimal verification to ensure that the argument is at
            --  least an object or a type. Subsequent finer grained checks will
            --  be done at the end of the declarative region that contains the
            --  pragma.

            if Ekind (Obj_Or_Type_Id) in E_Constant | E_Variable
              or else Is_Type (Obj_Or_Type_Id)
            then

               --  In the case of a type, pragma is a type-related
               --  representation item and so requires checks common to
               --  all type-related representation items.

               if Is_Type (Obj_Or_Type_Id)
                 and then Rep_Item_Too_Late (Obj_Or_Type_Id, N)
               then
                  return;
               end if;

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               Mark_Ghost_Pragma (N, Obj_Or_Type_Id);

               --  Chain the pragma on the contract for further processing by
               --  Analyze_External_Property_In_Decl_Part.

               Add_Contract_Item (N, Obj_Or_Type_Id);

               --  Analyze the Boolean expression (if any)

               if Present (Arg1) then
                  Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
               end if;

            --  Otherwise the external property applies to a constant

            else
               Error_Pragma
                 ("pragma % must apply to a volatile type or object");
            end if;
         end Async_Effective;

         ------------------
         -- Asynchronous --
         ------------------

         --  pragma Asynchronous (LOCAL_NAME);

         when Pragma_Asynchronous => Asynchronous : declare
            C_Ent  : Entity_Id;
            Decl   : Node_Id;
            Formal : Entity_Id;
            L      : List_Id;
            Nm     : Entity_Id;
            S      : Node_Id;

            procedure Process_Async_Pragma;
            --  Common processing for procedure and access-to-procedure case

            --------------------------
            -- Process_Async_Pragma --
            --------------------------

            procedure Process_Async_Pragma is
            begin
               if No (L) then
                  Set_Is_Asynchronous (Nm);
                  return;
               end if;

               --  The formals should be of mode IN (RM E.4.1(6))

               S := First (L);
               while Present (S) loop
                  Formal := Defining_Identifier (S);

                  if Nkind (Formal) = N_Defining_Identifier
                    and then Ekind (Formal) /= E_In_Parameter
                  then
                     Error_Pragma_Arg
                       ("pragma% procedure can only have IN parameter",
                        Arg1);
                  end if;

                  Next (S);
               end loop;

               Set_Is_Asynchronous (Nm);
            end Process_Async_Pragma;

         --  Start of processing for pragma Asynchronous

         begin
            Check_Ada_83_Warning;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);

            if Debug_Flag_U then
               return;
            end if;

            C_Ent := Cunit_Entity (Current_Sem_Unit);
            Analyze (Get_Pragma_Arg (Arg1));
            Nm := Entity (Get_Pragma_Arg (Arg1));

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Nm);

            if not Is_Remote_Call_Interface (C_Ent)
              and then not Is_Remote_Types (C_Ent)
            then
               --  This pragma should only appear in an RCI or Remote Types
               --  unit (RM E.4.1(4)).

               Error_Pragma
                 ("pragma% not in Remote_Call_Interface or Remote_Types unit");
            end if;

            if Ekind (Nm) = E_Procedure
              and then Nkind (Parent (Nm)) = N_Procedure_Specification
            then
               if not Is_Remote_Call_Interface (Nm) then
                  Error_Pragma_Arg
                    ("pragma% cannot be applied on non-remote procedure",
                     Arg1);
               end if;

               L := Parameter_Specifications (Parent (Nm));
               Process_Async_Pragma;
               return;

            elsif Ekind (Nm) = E_Function then
               Error_Pragma_Arg
                 ("pragma% cannot be applied to function", Arg1);

            elsif Is_Remote_Access_To_Subprogram_Type (Nm) then
               if Is_Record_Type (Nm) then

                  --  A record type that is the Equivalent_Type for a remote
                  --  access-to-subprogram type.

                  Decl := Declaration_Node (Corresponding_Remote_Type (Nm));

               else
                  --  A non-expanded RAS type (distribution is not enabled)

                  Decl := Declaration_Node (Nm);
               end if;

               if Nkind (Decl) = N_Full_Type_Declaration
                 and then Nkind (Type_Definition (Decl)) =
                                     N_Access_Procedure_Definition
               then
                  L := Parameter_Specifications (Type_Definition (Decl));
                  Process_Async_Pragma;

                  if Is_Asynchronous (Nm)
                    and then Expander_Active
                    and then Get_PCS_Name /= Name_No_DSA
                  then
                     RACW_Type_Is_Asynchronous (Underlying_RACW_Type (Nm));
                  end if;

               else
                  Error_Pragma_Arg
                    ("pragma% cannot reference access-to-function type",
                    Arg1);
               end if;

            --  Only other possibility is access-to-class-wide type

            elsif Is_Access_Type (Nm)
              and then Is_Class_Wide_Type (Designated_Type (Nm))
            then
               Check_First_Subtype (Arg1);
               Set_Is_Asynchronous (Nm);
               if Expander_Active then
                  RACW_Type_Is_Asynchronous (Nm);
               end if;

            else
               Error_Pragma_Arg ("inappropriate argument for pragma%", Arg1);
            end if;
         end Asynchronous;

         ------------
         -- Atomic --
         ------------

         --  pragma Atomic (LOCAL_NAME);

         when Pragma_Atomic =>
            Process_Atomic_Independent_Shared_Volatile;

         -----------------------
         -- Atomic_Components --
         -----------------------

         --  pragma Atomic_Components (array_LOCAL_NAME);

         --  This processing is shared by Volatile_Components

         when Pragma_Atomic_Components
            | Pragma_Volatile_Components
         =>
         Atomic_Components : declare
            D    : Node_Id;
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            Check_Ada_83_Warning;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);
            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            E := Entity (E_Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);
            Check_Duplicate_Pragma (E);

            if Rep_Item_Too_Early (E, N)
                 or else
               Rep_Item_Too_Late (E, N)
            then
               return;
            end if;

            D := Declaration_Node (E);

            if (Nkind (D) = N_Full_Type_Declaration and then Is_Array_Type (E))
              or else
                (Nkind (D) = N_Object_Declaration
                   and then Ekind (E) in E_Constant | E_Variable
                   and then Nkind (Object_Definition (D)) =
                                       N_Constrained_Array_Definition)
              or else
                 (Ada_Version >= Ada_2022
                   and then Nkind (D) = N_Formal_Type_Declaration)
            then
               --  The flag is set on the base type, or on the object

               if Nkind (D) = N_Full_Type_Declaration then
                  E := Base_Type (E);
               end if;

               --  Atomic implies both Independent and Volatile

               if Prag_Id = Pragma_Atomic_Components then
                  Set_Has_Atomic_Components (E);
                  Set_Has_Independent_Components (E);
               end if;

               Set_Has_Volatile_Components (E);

            else
               Error_Pragma_Arg ("inappropriate entity for pragma%", Arg1);
            end if;
         end Atomic_Components;

         --------------------
         -- Attach_Handler --
         --------------------

         --  pragma Attach_Handler (handler_NAME, EXPRESSION);

         when Pragma_Attach_Handler =>
            Check_Ada_83_Warning;
            Check_No_Identifiers;
            Check_Arg_Count (2);

            if No_Run_Time_Mode then
               Error_Msg_CRT ("Attach_Handler pragma", N);
            else
               Check_Interrupt_Or_Attach_Handler;

               --  The expression that designates the attribute may depend on a
               --  discriminant, and is therefore a per-object expression, to
               --  be expanded in the init proc. If expansion is enabled, then
               --  perform semantic checks on a copy only.

               declare
                  Temp  : Node_Id;
                  Typ   : Node_Id;
                  Parg2 : constant Node_Id := Get_Pragma_Arg (Arg2);

               begin
                  --  In Relaxed_RM_Semantics mode, we allow any static
                  --  integer value, for compatibility with other compilers.

                  if Relaxed_RM_Semantics
                    and then Nkind (Parg2) = N_Integer_Literal
                  then
                     Typ := Standard_Integer;
                  else
                     Typ := RTE (RE_Interrupt_ID);
                  end if;

                  if Expander_Active then
                     Temp := New_Copy_Tree (Parg2);
                     Set_Parent (Temp, N);
                     Preanalyze_And_Resolve (Temp, Typ);
                  else
                     Analyze (Parg2);
                     Resolve (Parg2, Typ);
                  end if;
               end;

               Process_Interrupt_Or_Attach_Handler;
            end if;

         --------------------
         -- C_Pass_By_Copy --
         --------------------

         --  pragma C_Pass_By_Copy ([Max_Size =>] static_integer_EXPRESSION);

         when Pragma_C_Pass_By_Copy => C_Pass_By_Copy : declare
            Arg : Node_Id;
            Val : Uint;

         begin
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, "max_size");

            Arg := Get_Pragma_Arg (Arg1);
            Check_Arg_Is_OK_Static_Expression (Arg, Any_Integer);

            Val := Expr_Value (Arg);

            if Val <= 0 then
               Error_Pragma_Arg
                 ("maximum size for pragma% must be positive", Arg1);

            elsif UI_Is_In_Int_Range (Val) then
               Default_C_Record_Mechanism := UI_To_Int (Val);

            --  If a giant value is given, Int'Last will do well enough.
            --  If sometime someone complains that a record larger than
            --  two gigabytes is not copied, we will worry about it then.

            else
               Default_C_Record_Mechanism := Mechanism_Type'Last;
            end if;
         end C_Pass_By_Copy;

         -----------
         -- Check --
         -----------

         --  pragma Check ([Name    =>] CHECK_KIND,
         --                [Check   =>] Boolean_EXPRESSION
         --              [,[Message =>] String_EXPRESSION]);

         --  CHECK_KIND ::= IDENTIFIER           |
         --                 Pre'Class            |
         --                 Post'Class           |
         --                 Invariant'Class      |
         --                 Type_Invariant'Class

         --  The identifiers Assertions and Statement_Assertions are not
         --  allowed, since they have special meaning for Check_Policy.

         --  WARNING: The code below manages Ghost regions. Return statements
         --  must be replaced by gotos which jump to the end of the code and
         --  restore the Ghost mode.

         when Pragma_Check => Check : declare
            Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
            Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
            --  Save the Ghost-related attributes to restore on exit

            Cname : Name_Id;
            Eloc  : Source_Ptr;
            Expr  : Node_Id;
            Str   : Node_Id;
            pragma Warnings (Off, Str);

         begin
            --  Pragma Check is Ghost when it applies to a Ghost entity. Set
            --  the mode now to ensure that any nodes generated during analysis
            --  and expansion are marked as Ghost.

            Set_Ghost_Mode (N);

            GNAT_Pragma;
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments (3);
            Check_Optional_Identifier (Arg1, Name_Name);
            Check_Optional_Identifier (Arg2, Name_Check);

            if Arg_Count = 3 then
               Check_Optional_Identifier (Arg3, Name_Message);
               Str := Get_Pragma_Arg (Arg3);
            end if;

            Rewrite_Assertion_Kind (Get_Pragma_Arg (Arg1));
            Check_Arg_Is_Identifier (Arg1);
            Cname := Chars (Get_Pragma_Arg (Arg1));

            --  Check forbidden name Assertions or Statement_Assertions

            case Cname is
               when Name_Assertions =>
                  Error_Pragma_Arg
                    ("""Assertions"" is not allowed as a check kind for "
                     & "pragma%", Arg1);

               when Name_Statement_Assertions =>
                  Error_Pragma_Arg
                    ("""Statement_Assertions"" is not allowed as a check kind "
                     & "for pragma%", Arg1);

               when others =>
                  null;
            end case;

            --  Check applicable policy. We skip this if Checked/Ignored status
            --  is already set (e.g. in the case of a pragma from an aspect).

            if Is_Checked (N) or else Is_Ignored (N) then
               null;

            --  For a non-source pragma that is a rewriting of another pragma,
            --  copy the Is_Checked/Ignored status from the rewritten pragma.

            elsif Is_Rewrite_Substitution (N)
              and then Nkind (Original_Node (N)) = N_Pragma
            then
               Set_Is_Ignored (N, Is_Ignored (Original_Node (N)));
               Set_Is_Checked (N, Is_Checked (Original_Node (N)));

            --  Otherwise query the applicable policy at this point

            else
               case Check_Kind (Cname) is
                  when Name_Ignore =>
                     Set_Is_Ignored (N, True);
                     Set_Is_Checked (N, False);

                  when Name_Check =>
                     Set_Is_Ignored (N, False);
                     Set_Is_Checked (N, True);

                  --  For disable, rewrite pragma as null statement and skip
                  --  rest of the analysis of the pragma.

                  when Name_Disable =>
                     Rewrite (N, Make_Null_Statement (Loc));
                     Analyze (N);
                     raise Pragma_Exit;

                  --  No other possibilities

                  when others =>
                     raise Program_Error;
               end case;
            end if;

            --  If check kind was not Disable, then continue pragma analysis

            Expr := Get_Pragma_Arg (Arg2);

            --  Mark the pragma (or, if rewritten from an aspect, the original
            --  aspect) as enabled. Nothing to do for an internally generated
            --  check for a dynamic predicate.

            if Is_Checked (N)
              and then not Split_PPC (N)
              and then Cname /= Name_Dynamic_Predicate
            then
               Set_SCO_Pragma_Enabled (Loc);
            end if;

            --  Deal with analyzing the string argument. If checks are not
            --  on we don't want any expansion (since such expansion would
            --  not get properly deleted) but we do want to analyze (to get
            --  proper references). The Preanalyze_And_Resolve routine does
            --  just what we want. Ditto if pragma is active, because it will
            --  be rewritten as an if-statement whose analysis will complete
            --  analysis and expansion of the string message. This makes a
            --  difference in the unusual case where the expression for the
            --  string may have a side effect, such as raising an exception.
            --  This is mandated by RM 11.4.2, which specifies that the string
            --  expression is only evaluated if the check fails and
            --  Assertion_Error is to be raised.

            if Arg_Count = 3 then
               Preanalyze_And_Resolve (Str, Standard_String);
            end if;

            --  Now you might think we could just do the same with the Boolean
            --  expression if checks are off (and expansion is on) and then
            --  rewrite the check as a null statement. This would work but we
            --  would lose the useful warnings about an assertion being bound
            --  to fail even if assertions are turned off.

            --  So instead we wrap the boolean expression in an if statement
            --  that looks like:

            --    if False and then condition then
            --       null;
            --    end if;

            --  The reason we do this rewriting during semantic analysis rather
            --  than as part of normal expansion is that we cannot analyze and
            --  expand the code for the boolean expression directly, or it may
            --  cause insertion of actions that would escape the attempt to
            --  suppress the check code.

            --  Note that the Sloc for the if statement corresponds to the
            --  argument condition, not the pragma itself. The reason for
            --  this is that we may generate a warning if the condition is
            --  False at compile time, and we do not want to delete this
            --  warning when we delete the if statement.

            if Expander_Active and Is_Ignored (N) then
               Eloc := Sloc (Expr);

               Rewrite (N,
                 Make_If_Statement (Eloc,
                   Condition =>
                     Make_And_Then (Eloc,
                       Left_Opnd  => Make_Identifier (Eloc, Name_False),
                       Right_Opnd => Expr),
                   Then_Statements => New_List (
                     Make_Null_Statement (Eloc))));

               --  Now go ahead and analyze the if statement

               In_Assertion_Expr := In_Assertion_Expr + 1;

               --  One rather special treatment. If we are now in Eliminated
               --  overflow mode, then suppress overflow checking since we do
               --  not want to drag in the bignum stuff if we are in Ignore
               --  mode anyway. This is particularly important if we are using
               --  a configurable run time that does not support bignum ops.

               if Scope_Suppress.Overflow_Mode_Assertions = Eliminated then
                  declare
                     Svo : constant Boolean :=
                             Scope_Suppress.Suppress (Overflow_Check);
                  begin
                     Scope_Suppress.Overflow_Mode_Assertions  := Strict;
                     Scope_Suppress.Suppress (Overflow_Check) := True;
                     Analyze (N);
                     Scope_Suppress.Suppress (Overflow_Check) := Svo;
                     Scope_Suppress.Overflow_Mode_Assertions  := Eliminated;
                  end;

               --  Not that special case

               else
                  Analyze (N);
               end if;

               --  All done with this check

               In_Assertion_Expr := In_Assertion_Expr - 1;

            --  Check is active or expansion not active. In these cases we can
            --  just go ahead and analyze the boolean with no worries.

            else
               In_Assertion_Expr := In_Assertion_Expr + 1;
               Analyze_And_Resolve (Expr, Any_Boolean);
               In_Assertion_Expr := In_Assertion_Expr - 1;
            end if;

            Restore_Ghost_Region (Saved_GM, Saved_IGR);
         end Check;

         --------------------------
         -- Check_Float_Overflow --
         --------------------------

         --  pragma Check_Float_Overflow;

         when Pragma_Check_Float_Overflow =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (0);
            Check_Float_Overflow := not Machine_Overflows_On_Target;

         ----------------
         -- Check_Name --
         ----------------

         --  pragma Check_Name (check_IDENTIFIER);

         when Pragma_Check_Name =>
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (1);
            Check_Arg_Is_Identifier (Arg1);

            declare
               Nam : constant Name_Id := Chars (Get_Pragma_Arg (Arg1));

            begin
               for J in Check_Names.First .. Check_Names.Last loop
                  if Check_Names.Table (J) = Nam then
                     return;
                  end if;
               end loop;

               Check_Names.Append (Nam);
            end;

         ------------------
         -- Check_Policy --
         ------------------

         --  This is the old style syntax, which is still allowed in all modes:

         --  pragma Check_Policy ([Name   =>] CHECK_KIND
         --                       [Policy =>] POLICY_IDENTIFIER);

         --  POLICY_IDENTIFIER ::= On | Off | Check | Disable | Ignore

         --  CHECK_KIND ::= IDENTIFIER           |
         --                 Pre'Class            |
         --                 Post'Class           |
         --                 Type_Invariant'Class |
         --                 Invariant'Class

         --  This is the new style syntax, compatible with Assertion_Policy
         --  and also allowed in all modes.

         --  Pragma Check_Policy (
         --      CHECK_KIND => POLICY_IDENTIFIER
         --   {, CHECK_KIND => POLICY_IDENTIFIER});

         --  Note: the identifiers Name and Policy are not allowed as
         --  Check_Kind values. This avoids ambiguities between the old and
         --  new form syntax.

         when Pragma_Check_Policy => Check_Policy : declare
            Kind : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);

            --  A Check_Policy pragma can appear either as a configuration
            --  pragma, or in a declarative part or a package spec (see RM
            --  11.5(5) for rules for Suppress/Unsuppress which are also
            --  followed for Check_Policy).

            if not Is_Configuration_Pragma then
               Check_Is_In_Decl_Part_Or_Package_Spec;
            end if;

            --  Figure out if we have the old or new syntax. We have the
            --  old syntax if the first argument has no identifier, or the
            --  identifier is Name.

            if Nkind (Arg1) /= N_Pragma_Argument_Association
              or else Chars (Arg1) in No_Name | Name_Name
            then
               --  Old syntax

               Check_Arg_Count (2);
               Check_Optional_Identifier (Arg1, Name_Name);
               Kind := Get_Pragma_Arg (Arg1);
               Rewrite_Assertion_Kind (Kind,
                 From_Policy => Comes_From_Source (N));
               Check_Arg_Is_Identifier (Arg1);

               --  Check forbidden check kind

               if Chars (Kind) in Name_Name | Name_Policy then
                  Error_Msg_Name_2 := Chars (Kind);
                  Error_Pragma_Arg
                    ("pragma% does not allow% as check name", Arg1);
               end if;

               --  Check policy

               Check_Optional_Identifier (Arg2, Name_Policy);
               Check_Arg_Is_One_Of
                 (Arg2,
                  Name_On, Name_Off, Name_Check, Name_Disable, Name_Ignore);

               --  And chain pragma on the Check_Policy_List for search

               Set_Next_Pragma (N, Opt.Check_Policy_List);
               Opt.Check_Policy_List := N;

            --  For the new syntax, what we do is to convert each argument to
            --  an old syntax equivalent. We do that because we want to chain
            --  old style Check_Policy pragmas for the search (we don't want
            --  to have to deal with multiple arguments in the search).

            else
               declare
                  Arg   : Node_Id;
                  Argx  : Node_Id;
                  LocP  : Source_Ptr;
                  New_P : Node_Id;

               begin
                  Arg := Arg1;
                  while Present (Arg) loop
                     LocP := Sloc (Arg);
                     Argx := Get_Pragma_Arg (Arg);

                     --  Kind must be specified

                     if Nkind (Arg) /= N_Pragma_Argument_Association
                       or else Chars (Arg) = No_Name
                     then
                        Error_Pragma_Arg
                          ("missing assertion kind for pragma%", Arg);
                     end if;

                     --  Construct equivalent old form syntax Check_Policy
                     --  pragma and insert it to get remaining checks.

                     New_P :=
                       Make_Pragma (LocP,
                         Chars                        => Name_Check_Policy,
                         Pragma_Argument_Associations => New_List (
                           Make_Pragma_Argument_Association (LocP,
                             Expression =>
                               Make_Identifier (LocP, Chars (Arg))),
                           Make_Pragma_Argument_Association (Sloc (Argx),
                             Expression => Argx)));

                     Arg := Next (Arg);

                     --  For a configuration pragma, insert old form in
                     --  the corresponding file.

                     if Is_Configuration_Pragma then
                        Insert_After (N, New_P);
                        Analyze (New_P);

                     else
                        Insert_Action (N, New_P);
                     end if;
                  end loop;

                  --  Rewrite original Check_Policy pragma to null, since we
                  --  have converted it into a series of old syntax pragmas.

                  Rewrite (N, Make_Null_Statement (Loc));
                  Analyze (N);
               end;
            end if;
         end Check_Policy;

         -------------
         -- Comment --
         -------------

         --  pragma Comment (static_string_EXPRESSION)

         --  Processing for pragma Comment shares the circuitry for pragma
         --  Ident. The only differences are that Ident enforces a limit of 31
         --  characters on its argument, and also enforces limitations on
         --  placement for DEC compatibility. Pragma Comment shares neither of
         --  these restrictions.

         -------------------
         -- Common_Object --
         -------------------

         --  pragma Common_Object (
         --        [Internal =>] LOCAL_NAME
         --     [, [External =>] EXTERNAL_SYMBOL]
         --     [, [Size     =>] EXTERNAL_SYMBOL]);

         --  Processing for this pragma is shared with Psect_Object

         ----------------------------------------------
         -- Compile_Time_Error, Compile_Time_Warning --
         ----------------------------------------------

         --  pragma Compile_Time_Error
         --    (boolean_EXPRESSION, static_string_EXPRESSION);

         --  pragma Compile_Time_Warning
         --    (boolean_EXPRESSION, static_string_EXPRESSION);

         when Pragma_Compile_Time_Error | Pragma_Compile_Time_Warning =>
            GNAT_Pragma;

            --  These pragmas rely on the context. In adc files they raise
            --  Constraint_Error. Ban them from use as configuration pragmas
            --  even in cases where such a use could work.

            if Is_Configuration_Pragma then
               Error_Pragma
                  ("pragma% is not allowed as a configuration pragma");
            end if;

            Process_Compile_Time_Warning_Or_Error;

         ---------------------------
         -- Compiler_Unit_Warning --
         ---------------------------

         --  pragma Compiler_Unit_Warning;

         --  Historical note

         --  Originally, we had only pragma Compiler_Unit, and it resulted in
         --  errors not warnings. This means that we had introduced a big extra
         --  inertia to compiler changes, since even if we implemented a new
         --  feature, and even if all versions to be used for bootstrapping
         --  implemented this new feature, we could not use it, since old
         --  compilers would give errors for using this feature in units
         --  having Compiler_Unit pragmas.

         --  By changing Compiler_Unit to Compiler_Unit_Warning, we solve the
         --  problem. We no longer have any units mentioning Compiler_Unit,
         --  so old compilers see Compiler_Unit_Warning which is unrecognized,
         --  and thus generates a warning which can be ignored. So that deals
         --  with the problem of old compilers not implementing the newer form
         --  of the pragma.

         --  Newer compilers recognize the new pragma, but generate warning
         --  messages instead of errors, which again can be ignored in the
         --  case of an old compiler which implements a wanted new feature
         --  but at the time felt like warning about it for older compilers.

         --  We retain Compiler_Unit so that new compilers can be used to build
         --  older run-times that use this pragma. That's an unusual case, but
         --  it's easy enough to handle, so why not?

         when Pragma_Compiler_Unit
            | Pragma_Compiler_Unit_Warning
         =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            --  Only recognized in main unit

            if Current_Sem_Unit = Main_Unit then
               Compiler_Unit := True;
            end if;

         -----------------------------
         -- Complete_Representation --
         -----------------------------

         --  pragma Complete_Representation;

         when Pragma_Complete_Representation =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            if Nkind (Parent (N)) /= N_Record_Representation_Clause then
               Error_Pragma
                 ("pragma & must appear within record representation clause");
            end if;

         ----------------------------
         -- Complex_Representation --
         ----------------------------

         --  pragma Complex_Representation ([Entity =>] LOCAL_NAME);

         when Pragma_Complex_Representation => Complex_Representation : declare
            E_Id : Node_Id;
            E    : Entity_Id;
            Ent  : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);
            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            E := Entity (E_Id);

            if not Is_Record_Type (E) then
               Error_Pragma_Arg
                 ("argument for pragma% must be record type", Arg1);
            end if;

            Ent := First_Entity (E);

            if No (Ent)
              or else No (Next_Entity (Ent))
              or else Present (Next_Entity (Next_Entity (Ent)))
              or else not Is_Floating_Point_Type (Etype (Ent))
              or else Etype (Ent) /= Etype (Next_Entity (Ent))
            then
               Error_Pragma_Arg
                 ("record for pragma% must have two fields of the same "
                  & "floating-point type", Arg1);

            else
               Set_Has_Complex_Representation (Base_Type (E));

               --  We need to treat the type has having a non-standard
               --  representation, for back-end purposes, even though in
               --  general a complex will have the default representation
               --  of a record with two real components.

               Set_Has_Non_Standard_Rep (Base_Type (E));
            end if;
         end Complex_Representation;

         -------------------------
         -- Component_Alignment --
         -------------------------

         --  pragma Component_Alignment (
         --        [Form =>] ALIGNMENT_CHOICE
         --     [, [Name =>] type_LOCAL_NAME]);
         --
         --   ALIGNMENT_CHOICE ::=
         --     Component_Size
         --   | Component_Size_4
         --   | Storage_Unit
         --   | Default

         when Pragma_Component_Alignment => Component_AlignmentP : declare
            Args  : Args_List (1 .. 2);
            Names : constant Name_List (1 .. 2) := (
                      Name_Form,
                      Name_Name);

            Form  : Node_Id renames Args (1);
            Name  : Node_Id renames Args (2);

            Atype : Component_Alignment_Kind;
            Typ   : Entity_Id;

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);

            if No (Form) then
               Error_Pragma ("missing Form argument for pragma%");
            end if;

            Check_Arg_Is_Identifier (Form);

            --  Get proper alignment, note that Default = Component_Size on all
            --  machines we have so far, and we want to set this value rather
            --  than the default value to indicate that it has been explicitly
            --  set (and thus will not get overridden by the default component
            --  alignment for the current scope)

            if Chars (Form) = Name_Component_Size then
               Atype := Calign_Component_Size;

            elsif Chars (Form) = Name_Component_Size_4 then
               Atype := Calign_Component_Size_4;

            elsif Chars (Form) = Name_Default then
               Atype := Calign_Component_Size;

            elsif Chars (Form) = Name_Storage_Unit then
               Atype := Calign_Storage_Unit;

            else
               Error_Pragma_Arg
                 ("invalid Form parameter for pragma%", Form);
            end if;

            --  The pragma appears in a configuration file

            if No (Parent (N)) then
               Check_Valid_Configuration_Pragma;

               --  Capture the component alignment in a global variable when
               --  the pragma appears in a configuration file. Note that the
               --  scope stack is empty at this point and cannot be used to
               --  store the alignment value.

               Configuration_Component_Alignment := Atype;

            --  Case with no name, supplied, affects scope table entry

            elsif No (Name) then
               Scope_Stack.Table
                 (Scope_Stack.Last).Component_Alignment_Default := Atype;

            --  Case of name supplied

            else
               Check_Arg_Is_Local_Name (Name);
               Find_Type (Name);
               Typ := Entity (Name);

               if Typ = Any_Type
                 or else Rep_Item_Too_Early (Typ, N)
               then
                  return;
               else
                  Typ := Underlying_Type (Typ);
               end if;

               if not Is_Record_Type (Typ)
                 and then not Is_Array_Type (Typ)
               then
                  Error_Pragma_Arg
                    ("Name parameter of pragma% must identify record or "
                     & "array type", Name);
               end if;

               --  An explicit Component_Alignment pragma overrides an
               --  implicit pragma Pack, but not an explicit one.

               if not Has_Pragma_Pack (Base_Type (Typ)) then
                  Set_Is_Packed (Base_Type (Typ), False);
                  Set_Component_Alignment (Base_Type (Typ), Atype);
               end if;
            end if;
         end Component_AlignmentP;

         --------------------------------
         -- Constant_After_Elaboration --
         --------------------------------

         --  pragma Constant_After_Elaboration [ (boolean_EXPRESSION) ];

         when Pragma_Constant_After_Elaboration => Constant_After_Elaboration :
         declare
            Obj_Decl : Node_Id;
            Obj_Id   : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            Obj_Decl := Find_Related_Context (N, Do_Checks => True);

            if Nkind (Obj_Decl) /= N_Object_Declaration then
               Pragma_Misplaced;
               return;
            end if;

            Obj_Id := Defining_Entity (Obj_Decl);

            --  The object declaration must be a library-level variable which
            --  is either explicitly initialized or obtains a value during the
            --  elaboration of a package body (SPARK RM 3.3.1).

            if Ekind (Obj_Id) = E_Variable then
               if not Is_Library_Level_Entity (Obj_Id) then
                  Error_Pragma
                    ("pragma % must apply to a library level variable");
                  return;
               end if;

            --  Otherwise the pragma applies to a constant, which is illegal

            else
               Error_Pragma ("pragma % must apply to a variable declaration");
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Obj_Id);

            --  Chain the pragma on the contract for completeness

            Add_Contract_Item (N, Obj_Id);

            --  Analyze the Boolean expression (if any)

            if Present (Arg1) then
               Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
            end if;
         end Constant_After_Elaboration;

         --------------------
         -- Contract_Cases --
         --------------------

         --  pragma Contract_Cases ((CONTRACT_CASE {, CONTRACT_CASE));

         --  CONTRACT_CASE ::= CASE_GUARD => CONSEQUENCE

         --  CASE_GUARD ::= boolean_EXPRESSION | others

         --  CONSEQUENCE ::= boolean_EXPRESSION

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expressions in:

         --       Analyze_Contract_Cases_In_Decl_Part

         --    * Expansion - The annotation is expanded during the expansion of
         --    the related subprogram [body] contract as performed in:

         --       Expand_Subprogram_Contract

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Contract_Cases => Contract_Cases : declare
            Spec_Id   : Entity_Id;
            Subp_Decl : Node_Id;
            Subp_Spec : Node_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            --  Ensure the proper placement of the pragma. Contract_Cases must
            --  be associated with a subprogram declaration or a body that acts
            --  as a spec.

            Subp_Decl :=
              Find_Related_Declaration_Or_Body (N, Do_Checks => True);

            --  Entry

            if Nkind (Subp_Decl) = N_Entry_Declaration then
               null;

            --  Generic subprogram

            elsif Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
               null;

            --  Body acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body
              and then No (Corresponding_Spec (Subp_Decl))
            then
               null;

            --  Body stub acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
              and then No (Corresponding_Spec_Of_Stub (Subp_Decl))
            then
               null;

            --  Subprogram

            elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then
               Subp_Spec := Specification (Subp_Decl);

               --  Pragma Contract_Cases is forbidden on null procedures, as
               --  this may lead to potential ambiguities in behavior when
               --  interface null procedures are involved.

               if Nkind (Subp_Spec) = N_Procedure_Specification
                 and then Null_Present (Subp_Spec)
               then
                  Error_Msg_N (Fix_Error
                    ("pragma % cannot apply to null procedure"), N);
                  return;
               end if;

            else
               Pragma_Misplaced;
               return;
            end if;

            Spec_Id := Unique_Defining_Entity (Subp_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Spec_Id);
            Ensure_Aggregate_Form (Get_Argument (N, Spec_Id));

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Contract_Cases_In_Decl_Part.

            Add_Contract_Item (N, Defining_Entity (Subp_Decl));

            --  Fully analyze the pragma when it appears inside an entry
            --  or subprogram body because it cannot benefit from forward
            --  references.

            if Nkind (Subp_Decl) in N_Entry_Body
                                  | N_Subprogram_Body
                                  | N_Subprogram_Body_Stub
            then
               --  The legality checks of pragma Contract_Cases are affected by
               --  the SPARK mode in effect and the volatility of the context.
               --  Analyze all pragmas in a specific order.

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_Contract_Cases_In_Decl_Part (N);
            end if;
         end Contract_Cases;

         ----------------
         -- Controlled --
         ----------------

         --  pragma Controlled (first_subtype_LOCAL_NAME);

         when Pragma_Controlled => Controlled : declare
            Arg : Node_Id;

         begin
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);
            Arg := Get_Pragma_Arg (Arg1);

            if not Is_Entity_Name (Arg)
              or else not Is_Access_Type (Entity (Arg))
            then
               Error_Pragma_Arg ("pragma% requires access type", Arg1);
            else
               Set_Has_Pragma_Controlled (Base_Type (Entity (Arg)));
            end if;
         end Controlled;

         ----------------
         -- Convention --
         ----------------

         --  pragma Convention ([Convention =>] convention_IDENTIFIER,
         --    [Entity =>] LOCAL_NAME);

         when Pragma_Convention => Convention : declare
            C : Convention_Id;
            E : Entity_Id;
            pragma Warnings (Off, C);
            pragma Warnings (Off, E);

         begin
            Check_Arg_Order ((Name_Convention, Name_Entity));
            Check_Ada_83_Warning;
            Check_Arg_Count (2);
            Process_Convention (C, E);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);
         end Convention;

         ---------------------------
         -- Convention_Identifier --
         ---------------------------

         --  pragma Convention_Identifier ([Name =>] IDENTIFIER,
         --    [Convention =>] convention_IDENTIFIER);

         when Pragma_Convention_Identifier => Convention_Identifier : declare
            Idnam : Name_Id;
            Cname : Name_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Order ((Name_Name, Name_Convention));
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_Name);
            Check_Optional_Identifier (Arg2, Name_Convention);
            Check_Arg_Is_Identifier (Arg1);
            Check_Arg_Is_Identifier (Arg2);
            Idnam := Chars (Get_Pragma_Arg (Arg1));
            Cname := Chars (Get_Pragma_Arg (Arg2));

            if Is_Convention_Name (Cname) then
               Record_Convention_Identifier
                 (Idnam, Get_Convention_Id (Cname));
            else
               Error_Pragma_Arg
                 ("second arg for % pragma must be convention", Arg2);
            end if;
         end Convention_Identifier;

         ---------------
         -- CPP_Class --
         ---------------

         --  pragma CPP_Class ([Entity =>] LOCAL_NAME)

         when Pragma_CPP_Class =>
            GNAT_Pragma;

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("'G'N'A'T pragma cpp'_class is now obsolete and has no "
                  & "effect; replace it by pragma import?j?", N);
            end if;

            Check_Arg_Count (1);

            Rewrite (N,
              Make_Pragma (Loc,
                Chars                        => Name_Import,
                Pragma_Argument_Associations => New_List (
                  Make_Pragma_Argument_Association (Loc,
                    Expression => Make_Identifier (Loc, Name_CPP)),
                  New_Copy (First (Pragma_Argument_Associations (N))))));
            Analyze (N);

         ---------------------
         -- CPP_Constructor --
         ---------------------

         --  pragma CPP_Constructor ([Entity =>] LOCAL_NAME
         --    [, [External_Name =>] static_string_EXPRESSION ]
         --    [, [Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_CPP_Constructor => CPP_Constructor : declare
            Id      : Entity_Id;
            Def_Id  : Entity_Id;
            Tag_Typ : Entity_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);
            Check_At_Most_N_Arguments (3);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);

            Id := Get_Pragma_Arg (Arg1);
            Find_Program_Unit_Name (Id);

            --  If we did not find the name, we are done

            if Etype (Id) = Any_Type then
               return;
            end if;

            Def_Id := Entity (Id);

            --  Check if already defined as constructor

            if Is_Constructor (Def_Id) then
               Error_Msg_N
                 ("??duplicate argument for pragma 'C'P'P_Constructor", Arg1);
               return;
            end if;

            if Ekind (Def_Id) = E_Function
              and then (Is_CPP_Class (Etype (Def_Id))
                         or else (Is_Class_Wide_Type (Etype (Def_Id))
                                   and then
                                  Is_CPP_Class (Root_Type (Etype (Def_Id)))))
            then
               if Scope (Def_Id) /= Scope (Etype (Def_Id)) then
                  Error_Msg_N
                    ("'C'P'P constructor must be defined in the scope of "
                     & "its returned type", Arg1);
               end if;

               if Arg_Count >= 2 then
                  Set_Imported (Def_Id);
                  Set_Is_Public (Def_Id);
                  Process_Interface_Name (Def_Id, Arg2, Arg3, N);
               end if;

               Set_Has_Completion (Def_Id);
               Set_Is_Constructor (Def_Id);
               Set_Convention (Def_Id, Convention_CPP);

               --  Imported C++ constructors are not dispatching primitives
               --  because in C++ they don't have a dispatch table slot.
               --  However, in Ada the constructor has the profile of a
               --  function that returns a tagged type and therefore it has
               --  been treated as a primitive operation during semantic
               --  analysis. We now remove it from the list of primitive
               --  operations of the type.

               if Is_Tagged_Type (Etype (Def_Id))
                 and then not Is_Class_Wide_Type (Etype (Def_Id))
                 and then Is_Dispatching_Operation (Def_Id)
               then
                  Tag_Typ := Etype (Def_Id);

                  Remove (Primitive_Operations (Tag_Typ), Def_Id);
                  Set_Is_Dispatching_Operation (Def_Id, False);
               end if;

               --  For backward compatibility, if the constructor returns a
               --  class wide type, and we internally change the return type to
               --  the corresponding root type.

               if Is_Class_Wide_Type (Etype (Def_Id)) then
                  Set_Etype (Def_Id, Root_Type (Etype (Def_Id)));
               end if;
            else
               Error_Pragma_Arg
                 ("pragma% requires function returning a 'C'P'P_Class type",
                   Arg1);
            end if;
         end CPP_Constructor;

         -----------------
         -- CPP_Virtual --
         -----------------

         when Pragma_CPP_Virtual =>
            GNAT_Pragma;

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("'G'N'A'T pragma Cpp'_Virtual is now obsolete and has no "
                  & "effect?j?", N);
            end if;

         -----------------
         -- CUDA_Device --
         -----------------

         when Pragma_CUDA_Device => CUDA_Device : declare
            Arg_Node      : Node_Id;
            Device_Entity : Entity_Id;
         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);

            Arg_Node := Get_Pragma_Arg (Arg1);
            Device_Entity := Entity (Arg_Node);

            if Ekind (Device_Entity) in E_Variable
                                      | E_Constant
                                      | E_Procedure
                                      | E_Function
            then
               Add_CUDA_Device_Entity
                 (Package_Specification_Of_Scope (Scope (Device_Entity)),
                  Device_Entity);

            else
               Error_Msg_NE ("& must be constant, variable or subprogram",
                 N,
                 Device_Entity);
            end if;

         end CUDA_Device;

         ------------------
         -- CUDA_Execute --
         ------------------

         --    pragma CUDA_Execute (PROCEDURE_CALL_STATEMENT,
         --                         EXPRESSION,
         --                         EXPRESSION,
         --                         [, EXPRESSION
         --                         [, EXPRESSION]]);

         when Pragma_CUDA_Execute => CUDA_Execute : declare

            function Is_Acceptable_Dim3 (N : Node_Id) return Boolean;
            --  Returns True if N is an acceptable argument for CUDA_Execute,
            --  False otherwise.

            ------------------------
            -- Is_Acceptable_Dim3 --
            ------------------------

            function Is_Acceptable_Dim3 (N : Node_Id) return Boolean is
               Expr : Node_Id;
            begin
               if Is_RTE (Etype (N), RE_Dim3)
                 or else Is_Integer_Type (Etype (N))
               then
                  return True;
               end if;

               if Nkind (N) = N_Aggregate
                 and then not Null_Record_Present (N)
                 and then No (Component_Associations (N))
                 and then List_Length (Expressions (N)) = 3
               then
                  Expr := First (Expressions (N));
                  while Present (Expr) loop
                     Analyze_And_Resolve (Expr, Any_Integer);
                     Next (Expr);
                  end loop;
                  return True;
               end if;

               return False;
            end Is_Acceptable_Dim3;

            --  Local variables

            Block_Dimensions : constant Node_Id := Get_Pragma_Arg (Arg3);
            Grid_Dimensions  : constant Node_Id := Get_Pragma_Arg (Arg2);
            Kernel_Call      : constant Node_Id := Get_Pragma_Arg (Arg1);
            Shared_Memory    : Node_Id;
            Stream           : Node_Id;

         --  Start of processing for CUDA_Execute

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (3);
            Check_At_Most_N_Arguments (5);

            Analyze_And_Resolve (Kernel_Call);
            if Nkind (Kernel_Call) /= N_Function_Call
              or else Etype (Kernel_Call) /= Standard_Void_Type
            then
               --  In `pragma CUDA_Execute (Kernel_Call (...), ...)`,
               --  GNAT sees Kernel_Call as an N_Function_Call since
               --  Kernel_Call "looks" like an expression. However, only
               --  procedures can be kernels, so to make things easier for the
               --  user the error message complains about Kernel_Call not being
               --  a procedure call.

               Error_Msg_N ("first argument of & must be a procedure call", N);
            end if;

            Analyze (Grid_Dimensions);
            if not Is_Acceptable_Dim3 (Grid_Dimensions) then
               Error_Msg_N
                 ("second argument of & must be an Integer, Dim3 or aggregate "
                  & "containing 3 Integers", N);
            end if;

            Analyze (Block_Dimensions);
            if not Is_Acceptable_Dim3 (Block_Dimensions) then
               Error_Msg_N
                 ("third argument of & must be an Integer, Dim3 or aggregate "
                  & "containing 3 Integers", N);
            end if;

            if Present (Arg4) then
               Shared_Memory := Get_Pragma_Arg (Arg4);
               Analyze_And_Resolve (Shared_Memory, Any_Integer);

               if Present (Arg5) then
                  Stream := Get_Pragma_Arg (Arg5);
                  Analyze_And_Resolve (Stream, RTE (RE_Stream_T));
               end if;
            end if;
         end CUDA_Execute;

         -----------------
         -- CUDA_Global --
         -----------------

         --  pragma CUDA_Global ([Entity =>] IDENTIFIER);

         when Pragma_CUDA_Global => CUDA_Global : declare
            Arg_Node    : Node_Id;
            Kernel_Proc : Entity_Id;
            Pack_Id     : Entity_Id;
         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);

            Arg_Node := Get_Pragma_Arg (Arg1);
            Analyze (Arg_Node);

            Kernel_Proc := Entity (Arg_Node);
            Pack_Id := Scope (Kernel_Proc);

            if Ekind (Kernel_Proc) /= E_Procedure then
               Error_Msg_NE ("& must be a procedure", N, Kernel_Proc);

            elsif Ekind (Pack_Id) /= E_Package
              or else not Is_Library_Level_Entity (Pack_Id)
            then
               Error_Msg_NE
                  ("& must reside in a library-level package", N, Kernel_Proc);

            else
               Set_Is_CUDA_Kernel (Kernel_Proc);
               Add_CUDA_Kernel (Pack_Id, Kernel_Proc);
            end if;
         end CUDA_Global;

         ----------------
         -- CPP_Vtable --
         ----------------

         when Pragma_CPP_Vtable =>
            GNAT_Pragma;

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("'G'N'A'T pragma Cpp'_Vtable is now obsolete and has no "
                  & "effect?j?", N);
            end if;

         ---------
         -- CPU --
         ---------

         --  pragma CPU (EXPRESSION);

         when Pragma_CPU => CPU : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            Ada_2012_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Arg := Get_Pragma_Arg (Arg1);

            --  Subprogram case

            if Nkind (P) = N_Subprogram_Body then
               Check_In_Main_Program;

               Analyze_And_Resolve (Arg, Any_Integer);

               Ent := Defining_Unit_Name (Specification (P));

               if Nkind (Ent) = N_Defining_Program_Unit_Name then
                  Ent := Defining_Identifier (Ent);
               end if;

               --  Must be static

               if not Is_OK_Static_Expression (Arg) then
                  Flag_Non_Static_Expr
                    ("main subprogram affinity is not static!", Arg);
                  raise Pragma_Exit;

               --  If constraint error, then we already signalled an error

               elsif Raises_Constraint_Error (Arg) then
                  null;

               --  Otherwise check in range

               else
                  declare
                     CPU_Id : constant Entity_Id := RTE (RE_CPU_Range);
                     --  This is the entity System.Multiprocessors.CPU_Range;

                     Val : constant Uint := Expr_Value (Arg);

                  begin
                     if Val < Expr_Value (Type_Low_Bound (CPU_Id))
                          or else
                        Val > Expr_Value (Type_High_Bound (CPU_Id))
                     then
                        Error_Pragma_Arg
                          ("main subprogram CPU is out of range", Arg1);
                     end if;
                  end;
               end if;

               Set_Main_CPU
                    (Current_Sem_Unit, UI_To_Int (Expr_Value (Arg)));

            --  Task case

            elsif Nkind (P) = N_Task_Definition then
               Ent := Defining_Identifier (Parent (P));

               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               Preanalyze_Spec_Expression (Arg, RTE (RE_CPU_Range));

               --  See comment in Sem_Ch13 about the following restrictions

               if Is_OK_Static_Expression (Arg) then
                  if Expr_Value (Arg) = Uint_0 then
                     Check_Restriction (No_Tasks_Unassigned_To_CPU, N);
                  end if;
               else
                  Check_Restriction (No_Dynamic_CPU_Assignment, N);
               end if;

            --  Anything else is incorrect

            else
               Pragma_Misplaced;
            end if;

            --  Check duplicate pragma before we chain the pragma in the Rep
            --  Item chain of Ent.

            Check_Duplicate_Pragma (Ent);
            Record_Rep_Item (Ent, N);
         end CPU;

         --------------------
         -- Deadline_Floor --
         --------------------

         --  pragma Deadline_Floor (time_span_EXPRESSION);

         when Pragma_Deadline_Floor => Deadline_Floor : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Arg := Get_Pragma_Arg (Arg1);

            --  The expression must be analyzed in the special manner described
            --  in "Handling of Default and Per-Object Expressions" in sem.ads.

            Preanalyze_Spec_Expression (Arg, RTE (RE_Time_Span));

            --  Only protected types allowed

            if Nkind (P) /= N_Protected_Definition then
               Pragma_Misplaced;

            else
               Ent := Defining_Identifier (Parent (P));

               --  Check duplicate pragma before we chain the pragma in the Rep
               --  Item chain of Ent.

               Check_Duplicate_Pragma (Ent);
               Record_Rep_Item (Ent, N);
            end if;
         end Deadline_Floor;

         -----------
         -- Debug --
         -----------

         --  pragma Debug ([boolean_EXPRESSION,] PROCEDURE_CALL_STATEMENT);

         when Pragma_Debug => Debug : declare
            Cond : Node_Id;
            Call : Node_Id;

         begin
            GNAT_Pragma;

            --  The condition for executing the call is that the expander
            --  is active and that we are not ignoring this debug pragma.

            Cond :=
              New_Occurrence_Of
                (Boolean_Literals
                  (Expander_Active and then not Is_Ignored (N)),
                 Loc);

            if not Is_Ignored (N) then
               Set_SCO_Pragma_Enabled (Loc);
            end if;

            if Arg_Count = 2 then
               Cond :=
                 Make_And_Then (Loc,
                   Left_Opnd  => Relocate_Node (Cond),
                   Right_Opnd => Get_Pragma_Arg (Arg1));
               Call := Get_Pragma_Arg (Arg2);
            else
               Call := Get_Pragma_Arg (Arg1);
            end if;

            if Nkind (Call) in N_Expanded_Name
                             | N_Function_Call
                             | N_Identifier
                             | N_Indexed_Component
                             | N_Selected_Component
            then
               --  If this pragma Debug comes from source, its argument was
               --  parsed as a name form (which is syntactically identical).
               --  In a generic context a parameterless call will be left as
               --  an expanded name (if global) or selected_component if local.
               --  Change it to a procedure call statement now.

               Change_Name_To_Procedure_Call_Statement (Call);

            elsif Nkind (Call) = N_Procedure_Call_Statement then

               --  Already in the form of a procedure call statement: nothing
               --  to do (could happen in case of an internally generated
               --  pragma Debug).

               null;

            else
               --  All other cases: diagnose error

               Error_Msg_N
                 ("argument of pragma ""Debug"" is not procedure call", Call);
               return;
            end if;

            --  Rewrite into a conditional with an appropriate condition. We
            --  wrap the procedure call in a block so that overhead from e.g.
            --  use of the secondary stack does not generate execution overhead
            --  for suppressed conditions.

            --  Normally the analysis that follows will freeze the subprogram
            --  being called. However, if the call is to a null procedure,
            --  we want to freeze it before creating the block, because the
            --  analysis that follows may be done with expansion disabled, in
            --  which case the body will not be generated, leading to spurious
            --  errors.

            if Nkind (Call) = N_Procedure_Call_Statement
              and then Is_Entity_Name (Name (Call))
            then
               Analyze (Name (Call));
               Freeze_Before (N, Entity (Name (Call)));
            end if;

            Rewrite (N,
              Make_Implicit_If_Statement (N,
                Condition       => Cond,
                Then_Statements => New_List (
                  Make_Block_Statement (Loc,
                    Handled_Statement_Sequence =>
                      Make_Handled_Sequence_Of_Statements (Loc,
                        Statements => New_List (Relocate_Node (Call)))))));
            Analyze (N);

            --  Ignore pragma Debug in GNATprove mode. Do this rewriting
            --  after analysis of the normally rewritten node, to capture all
            --  references to entities, which avoids issuing wrong warnings
            --  about unused entities.

            if GNATprove_Mode then
               Rewrite (N, Make_Null_Statement (Loc));
            end if;
         end Debug;

         ------------------
         -- Debug_Policy --
         ------------------

         --  pragma Debug_Policy (On | Off | Check | Disable | Ignore)

         when Pragma_Debug_Policy =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Identifier (Arg1);

            --  Exactly equivalent to pragma Check_Policy (Debug, arg), so
            --  rewrite it that way, and let the rest of the checking come
            --  from analyzing the rewritten pragma.

            Rewrite (N,
              Make_Pragma (Loc,
                Chars                        => Name_Check_Policy,
                Pragma_Argument_Associations => New_List (
                  Make_Pragma_Argument_Association (Loc,
                    Expression => Make_Identifier (Loc, Name_Debug)),

                  Make_Pragma_Argument_Association (Loc,
                    Expression => Get_Pragma_Arg (Arg1)))));
            Analyze (N);

         -------------------------------
         -- Default_Initial_Condition --
         -------------------------------

         --  pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];

         when Pragma_Default_Initial_Condition => DIC : declare
            Discard : Boolean;
            Stmt    : Node_Id;
            Typ     : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (2);  -- Accounts for implicit type arg

            Typ  := Empty;
            Stmt := Prev (N);
            while Present (Stmt) loop

               --  Skip prior pragmas, but check for duplicates

               if Nkind (Stmt) = N_Pragma then
                  if Pragma_Name (Stmt) = Pname then
                     Duplication_Error
                       (Prag => N,
                        Prev => Stmt);
                     raise Pragma_Exit;
                  end if;

               --  Skip internally generated code. Note that derived type
               --  declarations of untagged types with discriminants are
               --  rewritten as private type declarations.

               elsif not Comes_From_Source (Stmt)
                 and then Nkind (Stmt) /= N_Private_Type_Declaration
               then
                  null;

               --  The associated private type [extension] has been found, stop
               --  the search.

               elsif Nkind (Stmt) in N_Private_Extension_Declaration
                                   | N_Private_Type_Declaration
               then
                  Typ := Defining_Entity (Stmt);
                  exit;

               --  The pragma does not apply to a legal construct, issue an
               --  error and stop the analysis.

               else
                  Pragma_Misplaced;
                  return;
               end if;

               Stmt := Prev (Stmt);
            end loop;

            --  The pragma does not apply to a legal construct, issue an error
            --  and stop the analysis.

            if No (Typ) then
               Pragma_Misplaced;
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  The pragma signals that the type defines its own DIC assertion
            --  expression.

            Set_Has_Own_DIC (Typ);

            --  A type entity argument is appended to facilitate inheriting the
            --  aspect/pragma from parent types (see Build_DIC_Procedure_Body),
            --  though that extra argument isn't documented for the pragma.

            if not Present (Arg2) then
               --  When the pragma has no arguments, create an argument with
               --  the value Empty, so the type name argument can be appended
               --  following it (since it's expected as the second argument).

               if not Present (Arg1) then
                  Set_Pragma_Argument_Associations (N, New_List (
                    Make_Pragma_Argument_Association (Sloc (Typ),
                      Expression => Empty)));
               end if;

               Append_To
                 (Pragma_Argument_Associations (N),
                  Make_Pragma_Argument_Association (Sloc (Typ),
                    Expression => New_Occurrence_Of (Typ, Sloc (Typ))));
            end if;

            --  Chain the pragma on the rep item chain for further processing

            Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);

            --  Create the declaration of the procedure which verifies the
            --  assertion expression of pragma DIC at runtime.

            Build_DIC_Procedure_Declaration (Typ);
         end DIC;

         ----------------------------------
         -- Default_Scalar_Storage_Order --
         ----------------------------------

         --  pragma Default_Scalar_Storage_Order
         --           (High_Order_First | Low_Order_First);

         when Pragma_Default_Scalar_Storage_Order => DSSO : declare
            Default : Character;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);

            --  Default_Scalar_Storage_Order can appear as a configuration
            --  pragma, or in a declarative part of a package spec.

            if not Is_Configuration_Pragma then
               Check_Is_In_Decl_Part_Or_Package_Spec;
            end if;

            Check_No_Identifiers;
            Check_Arg_Is_One_Of
              (Arg1, Name_High_Order_First, Name_Low_Order_First);
            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
            Default := Fold_Upper (Name_Buffer (1));

            if not Support_Nondefault_SSO_On_Target
              and then (Ttypes.Bytes_Big_Endian /= (Default = 'H'))
            then
               if Warn_On_Unrecognized_Pragma then
                  Error_Msg_N
                    ("non-default Scalar_Storage_Order not supported "
                     & "on target?g?", N);
                  Error_Msg_N
                    ("\pragma Default_Scalar_Storage_Order ignored?g?", N);
               end if;

            --  Here set the specified default

            else
               Opt.Default_SSO := Default;
            end if;
         end DSSO;

         --------------------------
         -- Default_Storage_Pool --
         --------------------------

         --  pragma Default_Storage_Pool (storage_pool_NAME | null | Standard);

         when Pragma_Default_Storage_Pool => Default_Storage_Pool : declare
            Pool : Node_Id;

         begin
            Ada_2012_Pragma;
            Check_Arg_Count (1);

            --  Default_Storage_Pool can appear as a configuration pragma, or
            --  in a declarative part of a package spec.

            if not Is_Configuration_Pragma then
               Check_Is_In_Decl_Part_Or_Package_Spec;
            end if;

            if From_Aspect_Specification (N) then
               declare
                  E : constant Entity_Id := Entity (Corresponding_Aspect (N));
               begin
                  if not In_Open_Scopes (E) then
                     Error_Msg_N
                       ("aspect must apply to package or subprogram", N);
                  end if;
               end;
            end if;

            if Present (Arg1) then
               Pool := Get_Pragma_Arg (Arg1);

               --  Case of Default_Storage_Pool (null);

               if Nkind (Pool) = N_Null then
                  Analyze (Pool);

                  --  This is an odd case, this is not really an expression,
                  --  so we don't have a type for it. So just set the type to
                  --  Empty.

                  Set_Etype (Pool, Empty);

               --  Case of Default_Storage_Pool (Standard);

               elsif Nkind (Pool) = N_Identifier
                 and then Chars (Pool) = Name_Standard
               then
                  Analyze (Pool);

                  if Entity (Pool) /= Standard_Standard then
                     Error_Pragma_Arg
                       ("package Standard is not directly visible", Arg1);
                  end if;

               --  Case of Default_Storage_Pool (storage_pool_NAME);

               else
                  --  If it's a configuration pragma, then the only allowed
                  --  argument is "null".

                  if Is_Configuration_Pragma then
                     Error_Pragma_Arg ("NULL or Standard expected", Arg1);
                  end if;

                  --  The expected type for a non-"null" argument is
                  --  Root_Storage_Pool'Class, and the pool must be a variable.

                  Analyze_And_Resolve
                    (Pool, Class_Wide_Type (RTE (RE_Root_Storage_Pool)));

                  if Is_Variable (Pool) then

                     --  A pragma that applies to a Ghost entity becomes Ghost
                     --  for the purposes of legality checks and removal of
                     --  ignored Ghost code.

                     Mark_Ghost_Pragma (N, Entity (Pool));

                  else
                     Error_Pragma_Arg
                       ("default storage pool must be a variable", Arg1);
                  end if;
               end if;

               --  Record the pool name (or null). Freeze.Freeze_Entity for an
               --  access type will use this information to set the appropriate
               --  attributes of the access type. If the pragma appears in a
               --  generic unit it is ignored, given that it may refer to a
               --  local entity.

               if not Inside_A_Generic then
                  Default_Pool := Pool;
               end if;
            end if;
         end Default_Storage_Pool;

         -------------
         -- Depends --
         -------------

         --  pragma Depends (DEPENDENCY_RELATION);

         --  DEPENDENCY_RELATION ::=
         --     null
         --  | (DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE})

         --  DEPENDENCY_CLAUSE ::=
         --    OUTPUT_LIST =>[+] INPUT_LIST
         --  | NULL_DEPENDENCY_CLAUSE

         --  NULL_DEPENDENCY_CLAUSE ::= null => INPUT_LIST

         --  OUTPUT_LIST ::= OUTPUT | (OUTPUT {, OUTPUT})

         --  INPUT_LIST ::= null | INPUT | (INPUT {, INPUT})

         --  OUTPUT ::= NAME | FUNCTION_RESULT
         --  INPUT  ::= NAME

         --  where FUNCTION_RESULT is a function Result attribute_reference

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks fully analyze
         --    the dependency clauses in:

         --       Analyze_Depends_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Depends => Depends : declare
            Legal     : Boolean;
            Spec_Id   : Entity_Id;
            Subp_Decl : Node_Id;

         begin
            Analyze_Depends_Global (Spec_Id, Subp_Decl, Legal);

            if Legal then

               --  Chain the pragma on the contract for further processing by
               --  Analyze_Depends_In_Decl_Part.

               Add_Contract_Item (N, Spec_Id);

               --  Fully analyze the pragma when it appears inside an entry
               --  or subprogram body because it cannot benefit from forward
               --  references.

               if Nkind (Subp_Decl) in N_Entry_Body
                                     | N_Subprogram_Body
                                     | N_Subprogram_Body_Stub
               then
                  --  The legality checks of pragmas Depends and Global are
                  --  affected by the SPARK mode in effect and the volatility
                  --  of the context. In addition these two pragmas are subject
                  --  to an inherent order:

                  --    1) Global
                  --    2) Depends

                  --  Analyze all these pragmas in the order outlined above

                  Analyze_If_Present (Pragma_SPARK_Mode);
                  Analyze_If_Present (Pragma_Volatile_Function);
                  Analyze_If_Present (Pragma_Global);
                  Analyze_Depends_In_Decl_Part (N);
               end if;
            end if;
         end Depends;

         ---------------------
         -- Detect_Blocking --
         ---------------------

         --  pragma Detect_Blocking;

         when Pragma_Detect_Blocking =>
            Ada_2005_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Detect_Blocking := True;

         ------------------------------------
         -- Disable_Atomic_Synchronization --
         ------------------------------------

         --  pragma Disable_Atomic_Synchronization [(Entity)];

         when Pragma_Disable_Atomic_Synchronization =>
            GNAT_Pragma;
            Process_Disable_Enable_Atomic_Sync (Name_Suppress);

         -------------------
         -- Discard_Names --
         -------------------

         --  pragma Discard_Names [([On =>] LOCAL_NAME)];

         when Pragma_Discard_Names => Discard_Names : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            Check_Ada_83_Warning;

            --  Deal with configuration pragma case

            if Arg_Count = 0 and then Is_Configuration_Pragma then
               Global_Discard_Names := True;
               return;

            --  Otherwise, check correct appropriate context

            else
               Check_Is_In_Decl_Part_Or_Package_Spec;

               if Arg_Count = 0 then

                  --  If there is no parameter, then from now on this pragma
                  --  applies to any enumeration, exception or tagged type
                  --  defined in the current declarative part, and recursively
                  --  to any nested scope.

                  Set_Discard_Names (Current_Scope);
                  return;

               else
                  Check_Arg_Count (1);
                  Check_Optional_Identifier (Arg1, Name_On);
                  Check_Arg_Is_Local_Name (Arg1);

                  E_Id := Get_Pragma_Arg (Arg1);

                  if Etype (E_Id) = Any_Type then
                     return;
                  end if;

                  E := Entity (E_Id);

                  --  A pragma that applies to a Ghost entity becomes Ghost for
                  --  the purposes of legality checks and removal of ignored
                  --  Ghost code.

                  Mark_Ghost_Pragma (N, E);

                  if (Is_First_Subtype (E)
                      and then
                        (Is_Enumeration_Type (E) or else Is_Tagged_Type (E)))
                    or else Ekind (E) = E_Exception
                  then
                     Set_Discard_Names (E);
                     Record_Rep_Item (E, N);

                  else
                     Error_Pragma_Arg
                       ("inappropriate entity for pragma%", Arg1);
                  end if;
               end if;
            end if;
         end Discard_Names;

         ------------------------
         -- Dispatching_Domain --
         ------------------------

         --  pragma Dispatching_Domain (EXPRESSION);

         when Pragma_Dispatching_Domain => Dispatching_Domain : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            Ada_2012_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            --  This pragma is born obsolete, but not the aspect

            if not From_Aspect_Specification (N) then
               Check_Restriction
                 (No_Obsolescent_Features, Pragma_Identifier (N));
            end if;

            if Nkind (P) = N_Task_Definition then
               Arg := Get_Pragma_Arg (Arg1);
               Ent := Defining_Identifier (Parent (P));

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               Mark_Ghost_Pragma (N, Ent);

               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               Preanalyze_Spec_Expression (Arg, RTE (RE_Dispatching_Domain));

               --  Check duplicate pragma before we chain the pragma in the Rep
               --  Item chain of Ent.

               Check_Duplicate_Pragma (Ent);
               Record_Rep_Item (Ent, N);

            --  Anything else is incorrect

            else
               Pragma_Misplaced;
            end if;
         end Dispatching_Domain;

         ---------------
         -- Elaborate --
         ---------------

         --  pragma Elaborate (library_unit_NAME {, library_unit_NAME});

         when Pragma_Elaborate => Elaborate : declare
            Arg   : Node_Id;
            Citem : Node_Id;

         begin
            --  Pragma must be in context items list of a compilation unit

            if not Is_In_Context_Clause then
               Pragma_Misplaced;
            end if;

            --  Must be at least one argument

            if Arg_Count = 0 then
               Error_Pragma ("pragma% requires at least one argument");
            end if;

            --  In Ada 83 mode, there can be no items following it in the
            --  context list except other pragmas and implicit with clauses
            --  (e.g. those added by use of Rtsfind). In Ada 95 mode, this
            --  placement rule does not apply.

            if Ada_Version = Ada_83 and then Comes_From_Source (N) then
               Citem := Next (N);
               while Present (Citem) loop
                  if Nkind (Citem) = N_Pragma
                    or else (Nkind (Citem) = N_With_Clause
                              and then Implicit_With (Citem))
                  then
                     null;
                  else
                     Error_Pragma
                       ("(Ada 83) pragma% must be at end of context clause");
                  end if;

                  Next (Citem);
               end loop;
            end if;

            --  Finally, the arguments must all be units mentioned in a with
            --  clause in the same context clause. Note we already checked (in
            --  Par.Prag) that the arguments are all identifiers or selected
            --  components.

            Arg := Arg1;
            Outer : while Present (Arg) loop
               Citem := First (List_Containing (N));
               Inner : while Citem /= N loop
                  if Nkind (Citem) = N_With_Clause
                    and then Same_Name (Name (Citem), Get_Pragma_Arg (Arg))
                  then
                     Set_Elaborate_Present (Citem, True);
                     Set_Elab_Unit_Name (Get_Pragma_Arg (Arg), Name (Citem));

                     --  With the pragma present, elaboration calls on
                     --  subprograms from the named unit need no further
                     --  checks, as long as the pragma appears in the current
                     --  compilation unit. If the pragma appears in some unit
                     --  in the context, there might still be a need for an
                     --  Elaborate_All_Desirable from the current compilation
                     --  to the named unit, so we keep the check enabled. This
                     --  does not apply in SPARK mode, where we allow pragma
                     --  Elaborate, but we don't trust it to be right so we
                     --  will still insist on the Elaborate_All.

                     if Legacy_Elaboration_Checks
                       and then In_Extended_Main_Source_Unit (N)
                       and then SPARK_Mode /= On
                     then
                        Set_Suppress_Elaboration_Warnings
                          (Entity (Name (Citem)));
                     end if;

                     exit Inner;
                  end if;

                  Next (Citem);
               end loop Inner;

               if Citem = N then
                  Error_Pragma_Arg
                    ("argument of pragma% is not withed unit", Arg);
               end if;

               Next (Arg);
            end loop Outer;
         end Elaborate;

         -------------------
         -- Elaborate_All --
         -------------------

         --  pragma Elaborate_All (library_unit_NAME {, library_unit_NAME});

         when Pragma_Elaborate_All => Elaborate_All : declare
            Arg   : Node_Id;
            Citem : Node_Id;

         begin
            Check_Ada_83_Warning;

            --  Pragma must be in context items list of a compilation unit

            if not Is_In_Context_Clause then
               Pragma_Misplaced;
            end if;

            --  Must be at least one argument

            if Arg_Count = 0 then
               Error_Pragma ("pragma% requires at least one argument");
            end if;

            --  Note: unlike pragma Elaborate, pragma Elaborate_All does not
            --  have to appear at the end of the context clause, but may
            --  appear mixed in with other items, even in Ada 83 mode.

            --  Final check: the arguments must all be units mentioned in
            --  a with clause in the same context clause. Note that we
            --  already checked (in Par.Prag) that all the arguments are
            --  either identifiers or selected components.

            Arg := Arg1;
            Outr : while Present (Arg) loop
               Citem := First (List_Containing (N));
               Innr : while Citem /= N loop
                  if Nkind (Citem) = N_With_Clause
                    and then Same_Name (Name (Citem), Get_Pragma_Arg (Arg))
                  then
                     Set_Elaborate_All_Present (Citem, True);
                     Set_Elab_Unit_Name (Get_Pragma_Arg (Arg), Name (Citem));

                     --  Suppress warnings and elaboration checks on the named
                     --  unit if the pragma is in the current compilation, as
                     --  for pragma Elaborate.

                     if Legacy_Elaboration_Checks
                       and then In_Extended_Main_Source_Unit (N)
                     then
                        Set_Suppress_Elaboration_Warnings
                          (Entity (Name (Citem)));
                     end if;

                     exit Innr;
                  end if;

                  Next (Citem);
               end loop Innr;

               if Citem = N then
                  Set_Error_Posted (N);
                  Error_Pragma_Arg
                    ("argument of pragma% is not withed unit", Arg);
               end if;

               Next (Arg);
            end loop Outr;
         end Elaborate_All;

         --------------------
         -- Elaborate_Body --
         --------------------

         --  pragma Elaborate_Body [( library_unit_NAME )];

         when Pragma_Elaborate_Body => Elaborate_Body : declare
            Cunit_Node : Node_Id;
            Cunit_Ent  : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Cunit_Node := Cunit (Current_Sem_Unit);
            Cunit_Ent  := Cunit_Entity (Current_Sem_Unit);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Cunit_Ent);

            if Nkind (Unit (Cunit_Node)) in
                 N_Package_Body | N_Subprogram_Body
            then
               Error_Pragma ("pragma% must refer to a spec, not a body");
            else
               Set_Body_Required (Cunit_Node);
               Set_Has_Pragma_Elaborate_Body (Cunit_Ent);

               --  If we are in dynamic elaboration mode, then we suppress
               --  elaboration warnings for the unit, since it is definitely
               --  fine NOT to do dynamic checks at the first level (and such
               --  checks will be suppressed because no elaboration boolean
               --  is created for Elaborate_Body packages).
               --
               --  But in the static model of elaboration, Elaborate_Body is
               --  definitely NOT good enough to ensure elaboration safety on
               --  its own, since the body may WITH other units that are not
               --  safe from an elaboration point of view, so a client must
               --  still do an Elaborate_All on such units.
               --
               --  Debug flag -gnatdD restores the old behavior of 3.13, where
               --  Elaborate_Body always suppressed elab warnings.

               if Legacy_Elaboration_Checks
                 and then (Dynamic_Elaboration_Checks or Debug_Flag_DD)
               then
                  Set_Suppress_Elaboration_Warnings (Cunit_Ent);
               end if;
            end if;
         end Elaborate_Body;

         ------------------------
         -- Elaboration_Checks --
         ------------------------

         --  pragma Elaboration_Checks (Static | Dynamic);

         when Pragma_Elaboration_Checks => Elaboration_Checks : declare
            procedure Check_Duplicate_Elaboration_Checks_Pragma;
            --  Emit an error if the current context list already contains
            --  a previous Elaboration_Checks pragma. This routine raises
            --  Pragma_Exit if a duplicate is found.

            procedure Ignore_Elaboration_Checks_Pragma;
            --  Warn that the effects of the pragma are ignored. This routine
            --  raises Pragma_Exit.

            -----------------------------------------------
            -- Check_Duplicate_Elaboration_Checks_Pragma --
            -----------------------------------------------

            procedure Check_Duplicate_Elaboration_Checks_Pragma is
               Item : Node_Id;

            begin
               Item := Prev (N);
               while Present (Item) loop
                  if Nkind (Item) = N_Pragma
                    and then Pragma_Name (Item) = Name_Elaboration_Checks
                  then
                     Duplication_Error
                       (Prag => N,
                        Prev => Item);
                     raise Pragma_Exit;
                  end if;

                  Prev (Item);
               end loop;
            end Check_Duplicate_Elaboration_Checks_Pragma;

            --------------------------------------
            -- Ignore_Elaboration_Checks_Pragma --
            --------------------------------------

            procedure Ignore_Elaboration_Checks_Pragma is
            begin
               Error_Msg_Name_1 := Pname;
               Error_Msg_N ("??effects of pragma % are ignored", N);
               Error_Msg_N
                 ("\place pragma on initial declaration of library unit", N);

               raise Pragma_Exit;
            end Ignore_Elaboration_Checks_Pragma;

            --  Local variables

            Context : constant Node_Id := Parent (N);
            Unt     : Node_Id;

         --  Start of processing for Elaboration_Checks

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Arg_Is_One_Of (Arg1, Name_Static, Name_Dynamic);

            --  The pragma appears in a configuration file

            if No (Context) then
               Check_Valid_Configuration_Pragma;
               Check_Duplicate_Elaboration_Checks_Pragma;

            --  The pragma acts as a configuration pragma in a compilation unit

            --    pragma Elaboration_Checks (...);
            --    package Pack is ...;

            elsif Nkind (Context) = N_Compilation_Unit
              and then List_Containing (N) = Context_Items (Context)
            then
               Check_Valid_Configuration_Pragma;
               Check_Duplicate_Elaboration_Checks_Pragma;

               Unt := Unit (Context);

               --  The pragma must appear on the initial declaration of a unit.
               --  If this is not the case, warn that the effects of the pragma
               --  are ignored.

               if Nkind (Unt) = N_Package_Body then
                  Ignore_Elaboration_Checks_Pragma;

               --  Check the Acts_As_Spec flag of the compilation units itself
               --  to determine whether the subprogram body completes since it
               --  has not been analyzed yet. This is safe because compilation
               --  units are not overloadable.

               elsif Nkind (Unt) = N_Subprogram_Body
                 and then not Acts_As_Spec (Context)
               then
                  Ignore_Elaboration_Checks_Pragma;

               elsif Nkind (Unt) = N_Subunit then
                  Ignore_Elaboration_Checks_Pragma;
               end if;

            --  Otherwise the pragma does not appear at the configuration level
            --  and is illegal.

            else
               Pragma_Misplaced;
            end if;

            --  At this point the pragma is not a duplicate, and appears in the
            --  proper context. Set the elaboration model in effect.

            Dynamic_Elaboration_Checks :=
              Chars (Get_Pragma_Arg (Arg1)) = Name_Dynamic;
         end Elaboration_Checks;

         ---------------
         -- Eliminate --
         ---------------

         --  pragma Eliminate (
         --      [Unit_Name        =>] IDENTIFIER | SELECTED_COMPONENT,
         --      [Entity           =>] IDENTIFIER |
         --                            SELECTED_COMPONENT |
         --                            STRING_LITERAL]
         --      [, Source_Location => SOURCE_TRACE]);

         --  SOURCE_LOCATION ::= Source_Location => SOURCE_TRACE
         --  SOURCE_TRACE    ::= STRING_LITERAL

         when Pragma_Eliminate => Eliminate : declare
            Args  : Args_List (1 .. 5);
            Names : constant Name_List (1 .. 5) := (
                      Name_Unit_Name,
                      Name_Entity,
                      Name_Parameter_Types,
                      Name_Result_Type,
                      Name_Source_Location);

            --  Note : Parameter_Types and Result_Type are leftovers from
            --  prior implementations of the pragma. They are not generated
            --  by the gnatelim tool, and play no role in selecting which
            --  of a set of overloaded names is chosen for elimination.

            Unit_Name       : Node_Id renames Args (1);
            Entity          : Node_Id renames Args (2);
            Parameter_Types : Node_Id renames Args (3);
            Result_Type     : Node_Id renames Args (4);
            Source_Location : Node_Id renames Args (5);

         begin
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Gather_Associations (Names, Args);

            if No (Unit_Name) then
               Error_Pragma ("missing Unit_Name argument for pragma%");
            end if;

            if No (Entity)
              and then (Present (Parameter_Types)
                          or else
                        Present (Result_Type)
                          or else
                        Present (Source_Location))
            then
               Error_Pragma ("missing Entity argument for pragma%");
            end if;

            if (Present (Parameter_Types)
                  or else
                Present (Result_Type))
              and then
                Present (Source_Location)
            then
               Error_Pragma
                 ("parameter profile and source location cannot be used "
                  & "together in pragma%");
            end if;

            Process_Eliminate_Pragma
              (N,
               Unit_Name,
               Entity,
               Parameter_Types,
               Result_Type,
               Source_Location);
         end Eliminate;

         -----------------------------------
         -- Enable_Atomic_Synchronization --
         -----------------------------------

         --  pragma Enable_Atomic_Synchronization [(Entity)];

         when Pragma_Enable_Atomic_Synchronization =>
            GNAT_Pragma;
            Process_Disable_Enable_Atomic_Sync (Name_Unsuppress);

         ------------
         -- Export --
         ------------

         --  pragma Export (
         --    [   Convention    =>] convention_IDENTIFIER,
         --    [   Entity        =>] LOCAL_NAME
         --    [, [External_Name =>] static_string_EXPRESSION ]
         --    [, [Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_Export => Export : declare
            C      : Convention_Id;
            Def_Id : Entity_Id;

            pragma Warnings (Off, C);

         begin
            Check_Ada_83_Warning;
            Check_Arg_Order
              ((Name_Convention,
                Name_Entity,
                Name_External_Name,
                Name_Link_Name));

            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (4);

            --  In Relaxed_RM_Semantics, support old Ada 83 style:
            --  pragma Export (Entity, "external name");

            if Relaxed_RM_Semantics
              and then Arg_Count = 2
              and then Nkind (Expression (Arg2)) = N_String_Literal
            then
               C := Convention_C;
               Def_Id := Get_Pragma_Arg (Arg1);
               Analyze (Def_Id);

               if not Is_Entity_Name (Def_Id) then
                  Error_Pragma_Arg ("entity name required", Arg1);
               end if;

               Def_Id := Entity (Def_Id);
               Set_Exported (Def_Id, Arg1);

            else
               Process_Convention (C, Def_Id);

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               Mark_Ghost_Pragma (N, Def_Id);

               if Ekind (Def_Id) /= E_Constant then
                  Note_Possible_Modification
                    (Get_Pragma_Arg (Arg2), Sure => False);
               end if;

               Process_Interface_Name (Def_Id, Arg3, Arg4, N);
               Set_Exported (Def_Id, Arg2);
            end if;

            --  If the entity is a deferred constant, propagate the information
            --  to the full view, because gigi elaborates the full view only.

            if Ekind (Def_Id) = E_Constant
              and then Present (Full_View (Def_Id))
            then
               declare
                  Id2 : constant Entity_Id := Full_View (Def_Id);
               begin
                  Set_Is_Exported    (Id2, Is_Exported          (Def_Id));
                  Set_First_Rep_Item (Id2, First_Rep_Item       (Def_Id));
                  Set_Interface_Name
                    (Id2, Einfo.Entities.Interface_Name (Def_Id));
               end;
            end if;
         end Export;

         ---------------------
         -- Export_Function --
         ---------------------

         --  pragma Export_Function (
         --        [Internal         =>] LOCAL_NAME
         --     [, [External         =>] EXTERNAL_SYMBOL]
         --     [, [Parameter_Types  =>] (PARAMETER_TYPES)]
         --     [, [Result_Type      =>] TYPE_DESIGNATOR]
         --     [, [Mechanism        =>] MECHANISM]
         --     [, [Result_Mechanism =>] MECHANISM_NAME]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Export_Function => Export_Function : declare
            Args  : Args_List (1 .. 6);
            Names : constant Name_List (1 .. 6) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Result_Type,
                      Name_Mechanism,
                      Name_Result_Mechanism);

            Internal         : Node_Id renames Args (1);
            External         : Node_Id renames Args (2);
            Parameter_Types  : Node_Id renames Args (3);
            Result_Type      : Node_Id renames Args (4);
            Mechanism        : Node_Id renames Args (5);
            Result_Mechanism : Node_Id renames Args (6);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal         => Internal,
              Arg_External         => External,
              Arg_Parameter_Types  => Parameter_Types,
              Arg_Result_Type      => Result_Type,
              Arg_Mechanism        => Mechanism,
              Arg_Result_Mechanism => Result_Mechanism);
         end Export_Function;

         -------------------
         -- Export_Object --
         -------------------

         --  pragma Export_Object (
         --        [Internal =>] LOCAL_NAME
         --     [, [External =>] EXTERNAL_SYMBOL]
         --     [, [Size     =>] EXTERNAL_SYMBOL]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Export_Object => Export_Object : declare
            Args  : Args_List (1 .. 3);
            Names : constant Name_List (1 .. 3) := (
                      Name_Internal,
                      Name_External,
                      Name_Size);

            Internal : Node_Id renames Args (1);
            External : Node_Id renames Args (2);
            Size     : Node_Id renames Args (3);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Object_Pragma (
              Arg_Internal => Internal,
              Arg_External => External,
              Arg_Size     => Size);
         end Export_Object;

         ----------------------
         -- Export_Procedure --
         ----------------------

         --  pragma Export_Procedure (
         --        [Internal         =>] LOCAL_NAME
         --     [, [External         =>] EXTERNAL_SYMBOL]
         --     [, [Parameter_Types  =>] (PARAMETER_TYPES)]
         --     [, [Mechanism        =>] MECHANISM]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Export_Procedure => Export_Procedure : declare
            Args  : Args_List (1 .. 4);
            Names : constant Name_List (1 .. 4) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Mechanism);

            Internal        : Node_Id renames Args (1);
            External        : Node_Id renames Args (2);
            Parameter_Types : Node_Id renames Args (3);
            Mechanism       : Node_Id renames Args (4);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal        => Internal,
              Arg_External        => External,
              Arg_Parameter_Types => Parameter_Types,
              Arg_Mechanism       => Mechanism);
         end Export_Procedure;

         -----------------------------
         -- Export_Valued_Procedure --
         -----------------------------

         --  pragma Export_Valued_Procedure (
         --        [Internal         =>] LOCAL_NAME
         --     [, [External         =>] EXTERNAL_SYMBOL,]
         --     [, [Parameter_Types  =>] (PARAMETER_TYPES)]
         --     [, [Mechanism        =>] MECHANISM]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Export_Valued_Procedure =>
         Export_Valued_Procedure : declare
            Args  : Args_List (1 .. 4);
            Names : constant Name_List (1 .. 4) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Mechanism);

            Internal        : Node_Id renames Args (1);
            External        : Node_Id renames Args (2);
            Parameter_Types : Node_Id renames Args (3);
            Mechanism       : Node_Id renames Args (4);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal        => Internal,
              Arg_External        => External,
              Arg_Parameter_Types => Parameter_Types,
              Arg_Mechanism       => Mechanism);
         end Export_Valued_Procedure;

         -------------------
         -- Extend_System --
         -------------------

         --  pragma Extend_System ([Name =>] Identifier);

         when Pragma_Extend_System =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Name);
            Check_Arg_Is_Identifier (Arg1);

            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));

            if Name_Len > 4
              and then Name_Buffer (1 .. 4) = "aux_"
            then
               if Present (System_Extend_Pragma_Arg) then
                  if Chars (Get_Pragma_Arg (Arg1)) =
                     Chars (Expression (System_Extend_Pragma_Arg))
                  then
                     null;
                  else
                     Error_Msg_Sloc := Sloc (System_Extend_Pragma_Arg);
                     Error_Pragma ("pragma% conflicts with that #");
                  end if;

               else
                  System_Extend_Pragma_Arg := Arg1;

                  if not GNAT_Mode then
                     System_Extend_Unit := Arg1;
                  end if;
               end if;
            else
               Error_Pragma ("incorrect name for pragma%, must be Aux_xxx");
            end if;

         ------------------------
         -- Extensions_Allowed --
         ------------------------

         --  pragma Extensions_Allowed (ON | OFF);

         when Pragma_Extensions_Allowed =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);

            if Chars (Get_Pragma_Arg (Arg1)) = Name_On then
               Ada_Version := Ada_With_Extensions;
            else
               Ada_Version := Ada_Version_Explicit;
               Ada_Version_Pragma := Empty;
            end if;

         ------------------------
         -- Extensions_Visible --
         ------------------------

         --  pragma Extensions_Visible [ (boolean_EXPRESSION) ];

         --  Characteristics:

         --    * Analysis - The annotation is fully analyzed immediately upon
         --    elaboration as its expression must be static.

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Extensions_Visible => Extensions_Visible : declare
            Formal        : Entity_Id;
            Has_OK_Formal : Boolean := False;
            Spec_Id       : Entity_Id;
            Subp_Decl     : Node_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            Subp_Decl :=
              Find_Related_Declaration_Or_Body (N, Do_Checks => True);

            --  Abstract subprogram declaration

            if Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration then
               null;

            --  Generic subprogram declaration

            elsif Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
               null;

            --  Body acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body
              and then No (Corresponding_Spec (Subp_Decl))
            then
               null;

            --  Body stub acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
              and then No (Corresponding_Spec_Of_Stub (Subp_Decl))
            then
               null;

            --  Subprogram declaration

            elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then
               null;

            --  Otherwise the pragma is associated with an illegal construct

            else
               Error_Pragma ("pragma % must apply to a subprogram");
               return;
            end if;

            --  Mark the pragma as Ghost if the related subprogram is also
            --  Ghost. This also ensures that any expansion performed further
            --  below will produce Ghost nodes.

            Spec_Id := Unique_Defining_Entity (Subp_Decl);
            Mark_Ghost_Pragma (N, Spec_Id);

            --  Chain the pragma on the contract for completeness

            Add_Contract_Item (N, Defining_Entity (Subp_Decl));

            --  The legality checks of pragma Extension_Visible are affected
            --  by the SPARK mode in effect. Analyze all pragmas in specific
            --  order.

            Analyze_If_Present (Pragma_SPARK_Mode);

            --  Examine the formals of the related subprogram

            Formal := First_Formal (Spec_Id);
            while Present (Formal) loop

               --  At least one of the formals is of a specific tagged type,
               --  the pragma is legal.

               if Is_Specific_Tagged_Type (Etype (Formal)) then
                  Has_OK_Formal := True;
                  exit;

               --  A generic subprogram with at least one formal of a private
               --  type ensures the legality of the pragma because the actual
               --  may be specifically tagged. Note that this is verified by
               --  the check above at instantiation time.

               elsif Is_Private_Type (Etype (Formal))
                 and then Is_Generic_Type (Etype (Formal))
               then
                  Has_OK_Formal := True;
                  exit;
               end if;

               Next_Formal (Formal);
            end loop;

            if not Has_OK_Formal then
               Error_Msg_Name_1 := Pname;
               Error_Msg_N (Fix_Error ("incorrect placement of pragma %"), N);
               Error_Msg_NE
                 ("\subprogram & lacks parameter of specific tagged or "
                  & "generic private type", N, Spec_Id);

               return;
            end if;

            --  Analyze the Boolean expression (if any)

            if Present (Arg1) then
               Check_Static_Boolean_Expression
                 (Expression (Get_Argument (N, Spec_Id)));
            end if;
         end Extensions_Visible;

         --------------
         -- External --
         --------------

         --  pragma External (
         --    [   Convention    =>] convention_IDENTIFIER,
         --    [   Entity        =>] LOCAL_NAME
         --    [, [External_Name =>] static_string_EXPRESSION ]
         --    [, [Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_External => External : declare
            C : Convention_Id;
            E : Entity_Id;
            pragma Warnings (Off, C);

         begin
            GNAT_Pragma;
            Check_Arg_Order
              ((Name_Convention,
                Name_Entity,
                Name_External_Name,
                Name_Link_Name));
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (4);
            Process_Convention (C, E);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            Note_Possible_Modification
              (Get_Pragma_Arg (Arg2), Sure => False);
            Process_Interface_Name (E, Arg3, Arg4, N);
            Set_Exported (E, Arg2);
         end External;

         --------------------------
         -- External_Name_Casing --
         --------------------------

         --  pragma External_Name_Casing (
         --    UPPERCASE | LOWERCASE
         --    [, AS_IS | UPPERCASE | LOWERCASE]);

         when Pragma_External_Name_Casing =>
            GNAT_Pragma;
            Check_No_Identifiers;

            if Arg_Count = 2 then
               Check_Arg_Is_One_Of
                 (Arg2, Name_As_Is, Name_Uppercase, Name_Lowercase);

               case Chars (Get_Pragma_Arg (Arg2)) is
                  when Name_As_Is     =>
                     Opt.External_Name_Exp_Casing := As_Is;

                  when Name_Uppercase =>
                     Opt.External_Name_Exp_Casing := Uppercase;

                  when Name_Lowercase =>
                     Opt.External_Name_Exp_Casing := Lowercase;

                  when others =>
                     null;
               end case;

            else
               Check_Arg_Count (1);
            end if;

            Check_Arg_Is_One_Of (Arg1, Name_Uppercase, Name_Lowercase);

            case Chars (Get_Pragma_Arg (Arg1)) is
               when Name_Uppercase =>
                  Opt.External_Name_Imp_Casing := Uppercase;

               when Name_Lowercase =>
                  Opt.External_Name_Imp_Casing := Lowercase;

               when others =>
                  null;
            end case;

         ---------------
         -- Fast_Math --
         ---------------

         --  pragma Fast_Math;

         when Pragma_Fast_Math =>
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Valid_Configuration_Pragma;
            Fast_Math := True;

         --------------------------
         -- Favor_Top_Level --
         --------------------------

         --  pragma Favor_Top_Level (type_NAME);

         when Pragma_Favor_Top_Level => Favor_Top_Level : declare
            Typ : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);
            Typ := Entity (Get_Pragma_Arg (Arg1));

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  If it's an access-to-subprogram type (in particular, not a
            --  subtype), set the flag on that type.

            if Is_Access_Subprogram_Type (Typ) then
               Set_Can_Use_Internal_Rep (Typ, False);

            --  Otherwise it's an error (name denotes the wrong sort of entity)

            else
               Error_Pragma_Arg
                 ("access-to-subprogram type expected",
                  Get_Pragma_Arg (Arg1));
            end if;
         end Favor_Top_Level;

         ---------------------------
         -- Finalize_Storage_Only --
         ---------------------------

         --  pragma Finalize_Storage_Only (first_subtype_LOCAL_NAME);

         when Pragma_Finalize_Storage_Only => Finalize_Storage : declare
            Assoc   : constant Node_Id := Arg1;
            Type_Id : constant Node_Id := Get_Pragma_Arg (Assoc);
            Typ     : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);

            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type
              or else Rep_Item_Too_Early (Typ, N)
            then
               return;
            else
               Typ := Underlying_Type (Typ);
            end if;

            if not Is_Controlled (Typ) then
               Error_Pragma ("pragma% must specify controlled type");
            end if;

            Check_First_Subtype (Arg1);

            if Finalize_Storage_Only (Typ) then
               Error_Pragma ("duplicate pragma%, only one allowed");

            elsif not Rep_Item_Too_Late (Typ, N) then
               Set_Finalize_Storage_Only (Base_Type (Typ), True);
            end if;
         end Finalize_Storage;

         -----------
         -- Ghost --
         -----------

         --  pragma Ghost [ (boolean_EXPRESSION) ];

         when Pragma_Ghost => Ghost : declare
            Context   : Node_Id;
            Expr      : Node_Id;
            Id        : Entity_Id;
            Orig_Stmt : Node_Id;
            Prev_Id   : Entity_Id;
            Stmt      : Node_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            Id   := Empty;
            Stmt := Prev (N);
            while Present (Stmt) loop

               --  Skip prior pragmas, but check for duplicates

               if Nkind (Stmt) = N_Pragma then
                  if Pragma_Name (Stmt) = Pname then
                     Duplication_Error
                       (Prag => N,
                        Prev => Stmt);
                     raise Pragma_Exit;
                  end if;

               --  Task unit declared without a definition cannot be subject to
               --  pragma Ghost (SPARK RM 6.9(19)).

               elsif Nkind (Stmt) in
                       N_Single_Task_Declaration | N_Task_Type_Declaration
               then
                  Error_Pragma ("pragma % cannot apply to a task type");
                  return;

               --  Skip internally generated code

               elsif not Comes_From_Source (Stmt) then
                  Orig_Stmt := Original_Node (Stmt);

                  --  When pragma Ghost applies to an untagged derivation, the
                  --  derivation is transformed into a [sub]type declaration.

                  if Nkind (Stmt) in
                       N_Full_Type_Declaration | N_Subtype_Declaration
                    and then Comes_From_Source (Orig_Stmt)
                    and then Nkind (Orig_Stmt) = N_Full_Type_Declaration
                    and then Nkind (Type_Definition (Orig_Stmt)) =
                               N_Derived_Type_Definition
                  then
                     Id := Defining_Entity (Stmt);
                     exit;

                  --  When pragma Ghost applies to an object declaration which
                  --  is initialized by means of a function call that returns
                  --  on the secondary stack, the object declaration becomes a
                  --  renaming.

                  elsif Nkind (Stmt) = N_Object_Renaming_Declaration
                    and then Comes_From_Source (Orig_Stmt)
                    and then Nkind (Orig_Stmt) = N_Object_Declaration
                  then
                     Id := Defining_Entity (Stmt);
                     exit;

                  --  When pragma Ghost applies to an expression function, the
                  --  expression function is transformed into a subprogram.

                  elsif Nkind (Stmt) = N_Subprogram_Declaration
                    and then Comes_From_Source (Orig_Stmt)
                    and then Nkind (Orig_Stmt) = N_Expression_Function
                  then
                     Id := Defining_Entity (Stmt);
                     exit;
                  end if;

               --  The pragma applies to a legal construct, stop the traversal

               elsif Nkind (Stmt) in N_Abstract_Subprogram_Declaration
                                   | N_Full_Type_Declaration
                                   | N_Generic_Subprogram_Declaration
                                   | N_Object_Declaration
                                   | N_Private_Extension_Declaration
                                   | N_Private_Type_Declaration
                                   | N_Subprogram_Declaration
                                   | N_Subtype_Declaration
               then
                  Id := Defining_Entity (Stmt);
                  exit;

               --  The pragma does not apply to a legal construct, issue an
               --  error and stop the analysis.

               else
                  Error_Pragma
                    ("pragma % must apply to an object, package, subprogram "
                     & "or type");
                  return;
               end if;

               Stmt := Prev (Stmt);
            end loop;

            Context := Parent (N);

            --  Handle compilation units

            if Nkind (Context) = N_Compilation_Unit_Aux then
               Context := Unit (Parent (Context));
            end if;

            --  Protected and task types cannot be subject to pragma Ghost
            --  (SPARK RM 6.9(19)).

            if Nkind (Context) in N_Protected_Body | N_Protected_Definition
            then
               Error_Pragma ("pragma % cannot apply to a protected type");
               return;

            elsif Nkind (Context) in N_Task_Body | N_Task_Definition then
               Error_Pragma ("pragma % cannot apply to a task type");
               return;
            end if;

            if No (Id) then

               --  When pragma Ghost is associated with a [generic] package, it
               --  appears in the visible declarations.

               if Nkind (Context) = N_Package_Specification
                 and then Present (Visible_Declarations (Context))
                 and then List_Containing (N) = Visible_Declarations (Context)
               then
                  Id := Defining_Entity (Context);

               --  Pragma Ghost applies to a stand-alone subprogram body

               elsif Nkind (Context) = N_Subprogram_Body
                 and then No (Corresponding_Spec (Context))
               then
                  Id := Defining_Entity (Context);

               --  Pragma Ghost applies to a subprogram declaration that acts
               --  as a compilation unit.

               elsif Nkind (Context) = N_Subprogram_Declaration then
                  Id := Defining_Entity (Context);

               --  Pragma Ghost applies to a generic subprogram

               elsif Nkind (Context) = N_Generic_Subprogram_Declaration then
                  Id := Defining_Entity (Specification (Context));
               end if;
            end if;

            if No (Id) then
               Error_Pragma
                 ("pragma % must apply to an object, package, subprogram or "
                  & "type");
               return;
            end if;

            --  Handle completions of types and constants that are subject to
            --  pragma Ghost.

            if Is_Record_Type (Id) or else Ekind (Id) = E_Constant then
               Prev_Id := Incomplete_Or_Partial_View (Id);

               if Present (Prev_Id) and then not Is_Ghost_Entity (Prev_Id) then
                  Error_Msg_Name_1 := Pname;

                  --  The full declaration of a deferred constant cannot be
                  --  subject to pragma Ghost unless the deferred declaration
                  --  is also Ghost (SPARK RM 6.9(9)).

                  if Ekind (Prev_Id) = E_Constant then
                     Error_Msg_Name_1 := Pname;
                     Error_Msg_NE (Fix_Error
                       ("pragma % must apply to declaration of deferred "
                        & "constant &"), N, Id);
                     return;

                  --  Pragma Ghost may appear on the full view of an incomplete
                  --  type because the incomplete declaration lacks aspects and
                  --  cannot be subject to pragma Ghost.

                  elsif Ekind (Prev_Id) = E_Incomplete_Type then
                     null;

                  --  The full declaration of a type cannot be subject to
                  --  pragma Ghost unless the partial view is also Ghost
                  --  (SPARK RM 6.9(9)).

                  else
                     Error_Msg_NE (Fix_Error
                       ("pragma % must apply to partial view of type &"),
                        N, Id);
                     return;
                  end if;
               end if;

            --  A synchronized object cannot be subject to pragma Ghost
            --  (SPARK RM 6.9(19)).

            elsif Ekind (Id) = E_Variable then
               if Is_Protected_Type (Etype (Id)) then
                  Error_Pragma ("pragma % cannot apply to a protected object");
                  return;

               elsif Is_Task_Type (Etype (Id)) then
                  Error_Pragma ("pragma % cannot apply to a task object");
                  return;
               end if;
            end if;

            --  Analyze the Boolean expression (if any)

            if Present (Arg1) then
               Expr := Get_Pragma_Arg (Arg1);

               Analyze_And_Resolve (Expr, Standard_Boolean);

               if Is_OK_Static_Expression (Expr) then

                  --  "Ghostness" cannot be turned off once enabled within a
                  --  region (SPARK RM 6.9(6)).

                  if Is_False (Expr_Value (Expr))
                    and then Ghost_Mode > None
                  then
                     Error_Pragma
                       ("pragma % with value False cannot appear in enabled "
                        & "ghost region");
                     return;
                  end if;

               --  Otherwise the expression is not static

               else
                  Error_Pragma_Arg
                    ("expression of pragma % must be static", Expr);
                  return;
               end if;
            end if;

            Set_Is_Ghost_Entity (Id);
         end Ghost;

         ------------
         -- Global --
         ------------

         --  pragma Global (GLOBAL_SPECIFICATION);

         --  GLOBAL_SPECIFICATION ::=
         --     null
         --  | (GLOBAL_LIST)
         --  | (MODED_GLOBAL_LIST {, MODED_GLOBAL_LIST})

         --  MODED_GLOBAL_LIST ::= MODE_SELECTOR => GLOBAL_LIST

         --  MODE_SELECTOR ::= In_Out | Input | Output | Proof_In
         --  GLOBAL_LIST   ::= GLOBAL_ITEM | (GLOBAL_ITEM {, GLOBAL_ITEM})
         --  GLOBAL_ITEM   ::= NAME

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks fully analyze
         --    the dependency clauses in:

         --       Analyze_Global_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Global => Global : declare
            Legal     : Boolean;
            Spec_Id   : Entity_Id;
            Subp_Decl : Node_Id;

         begin
            Analyze_Depends_Global (Spec_Id, Subp_Decl, Legal);

            if Legal then

               --  Chain the pragma on the contract for further processing by
               --  Analyze_Global_In_Decl_Part.

               Add_Contract_Item (N, Spec_Id);

               --  Fully analyze the pragma when it appears inside an entry
               --  or subprogram body because it cannot benefit from forward
               --  references.

               if Nkind (Subp_Decl) in N_Entry_Body
                                     | N_Subprogram_Body
                                     | N_Subprogram_Body_Stub
               then
                  --  The legality checks of pragmas Depends and Global are
                  --  affected by the SPARK mode in effect and the volatility
                  --  of the context. In addition these two pragmas are subject
                  --  to an inherent order:

                  --    1) Global
                  --    2) Depends

                  --  Analyze all these pragmas in the order outlined above

                  Analyze_If_Present (Pragma_SPARK_Mode);
                  Analyze_If_Present (Pragma_Volatile_Function);
                  Analyze_Global_In_Decl_Part (N);
                  Analyze_If_Present (Pragma_Depends);
               end if;
            end if;
         end Global;

         -----------
         -- Ident --
         -----------

         --  pragma Ident (static_string_EXPRESSION)

         --  Note: pragma Comment shares this processing. Pragma Ident is
         --  identical in effect to pragma Commment.

         when Pragma_Comment
            | Pragma_Ident
         =>
         Ident : declare
            Str : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);
            Store_Note (N);

            Str := Expr_Value_S (Get_Pragma_Arg (Arg1));

            declare
               CS : Node_Id;
               GP : Node_Id;

            begin
               GP := Parent (Parent (N));

               if Nkind (GP) in
                    N_Package_Declaration | N_Generic_Package_Declaration
               then
                  GP := Parent (GP);
               end if;

               --  If we have a compilation unit, then record the ident value,
               --  checking for improper duplication.

               if Nkind (GP) = N_Compilation_Unit then
                  CS := Ident_String (Current_Sem_Unit);

                  if Present (CS) then

                     --  If we have multiple instances, concatenate them.

                     Start_String (Strval (CS));
                     Store_String_Char (' ');
                     Store_String_Chars (Strval (Str));
                     Set_Strval (CS, End_String);

                  else
                     Set_Ident_String (Current_Sem_Unit, Str);
                  end if;

               --  For subunits, we just ignore the Ident, since in GNAT these
               --  are not separate object files, and hence not separate units
               --  in the unit table.

               elsif Nkind (GP) = N_Subunit then
                  null;
               end if;
            end;
         end Ident;

         -------------------
         -- Ignore_Pragma --
         -------------------

         --  pragma Ignore_Pragma (pragma_IDENTIFIER);

         --  Entirely handled in the parser, nothing to do here

         when Pragma_Ignore_Pragma =>
            null;

         ----------------------------
         -- Implementation_Defined --
         ----------------------------

         --  pragma Implementation_Defined (LOCAL_NAME);

         --  Marks previously declared entity as implementation defined. For
         --  an overloaded entity, applies to the most recent homonym.

         --  pragma Implementation_Defined;

         --  The form with no arguments appears anywhere within a scope, most
         --  typically a package spec, and indicates that all entities that are
         --  defined within the package spec are Implementation_Defined.

         when Pragma_Implementation_Defined => Implementation_Defined : declare
            Ent : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;

            --  Form with no arguments

            if Arg_Count = 0 then
               Set_Is_Implementation_Defined (Current_Scope);

            --  Form with one argument

            else
               Check_Arg_Count (1);
               Check_Arg_Is_Local_Name (Arg1);
               Ent := Entity (Get_Pragma_Arg (Arg1));
               Set_Is_Implementation_Defined (Ent);
            end if;
         end Implementation_Defined;

         -----------------
         -- Implemented --
         -----------------

         --  pragma Implemented (procedure_LOCAL_NAME, IMPLEMENTATION_KIND);

         --  IMPLEMENTATION_KIND ::=
         --    By_Entry | By_Protected_Procedure | By_Any | Optional

         --  "By_Any" and "Optional" are treated as synonyms in order to
         --  support Ada 2012 aspect Synchronization.

         when Pragma_Implemented => Implemented : declare
            Proc_Id : Entity_Id;
            Typ     : Entity_Id;

         begin
            Ada_2012_Pragma;
            Check_Arg_Count (2);
            Check_No_Identifiers;
            Check_Arg_Is_Identifier (Arg1);
            Check_Arg_Is_Local_Name (Arg1);
            Check_Arg_Is_One_Of (Arg2,
              Name_By_Any,
              Name_By_Entry,
              Name_By_Protected_Procedure,
              Name_Optional);

            --  Extract the name of the local procedure

            Proc_Id := Entity (Get_Pragma_Arg (Arg1));

            --  Ada 2012 (AI05-0030): The procedure_LOCAL_NAME must denote a
            --  primitive procedure of a synchronized tagged type.

            if Ekind (Proc_Id) = E_Procedure
              and then Is_Primitive (Proc_Id)
              and then Present (First_Formal (Proc_Id))
            then
               Typ := Etype (First_Formal (Proc_Id));

               if Is_Tagged_Type (Typ)
                 and then

                  --  Check for a protected, a synchronized or a task interface

                   ((Is_Interface (Typ)
                       and then Is_Synchronized_Interface (Typ))

                  --  Check for a protected type or a task type that implements
                  --  an interface.

                   or else
                    (Is_Concurrent_Record_Type (Typ)
                       and then Present (Interfaces (Typ)))

                  --  In analysis-only mode, examine original protected type

                  or else
                    (Nkind (Parent (Typ)) = N_Protected_Type_Declaration
                      and then Present (Interface_List (Parent (Typ))))

                  --  Check for a private record extension with keyword
                  --  "synchronized".

                   or else
                    (Ekind (Typ) in E_Record_Type_With_Private
                                  | E_Record_Subtype_With_Private
                       and then Synchronized_Present (Parent (Typ))))
               then
                  null;
               else
                  Error_Pragma_Arg
                    ("controlling formal must be of synchronized tagged type",
                     Arg1);
                  return;
               end if;

               --  Ada 2012 (AI05-0030): Cannot apply the implementation_kind
               --  By_Protected_Procedure to the primitive procedure of a task
               --  interface.

               if Chars (Get_Pragma_Arg (Arg2)) = Name_By_Protected_Procedure
                 and then Is_Interface (Typ)
                 and then Is_Task_Interface (Typ)
               then
                  Error_Pragma_Arg
                    ("implementation kind By_Protected_Procedure cannot be "
                     & "applied to a task interface primitive", Arg2);
                  return;
               end if;

            --  Procedures declared inside a protected type must be accepted

            elsif Ekind (Proc_Id) = E_Procedure
              and then Is_Protected_Type (Scope (Proc_Id))
            then
               null;

            --  The first argument is not a primitive procedure

            else
               Error_Pragma_Arg
                 ("pragma % must be applied to a primitive procedure", Arg1);
               return;
            end if;

            --  Ada 2012 (AI12-0279): Cannot apply the implementation_kind
            --  By_Protected_Procedure to a procedure that has aspect Yield

            if Chars (Get_Pragma_Arg (Arg2)) = Name_By_Protected_Procedure
              and then Has_Yield_Aspect (Proc_Id)
            then
               Error_Pragma_Arg
                 ("implementation kind By_Protected_Procedure cannot be "
                  & "applied to entities with aspect 'Yield", Arg2);
               return;
            end if;

            Record_Rep_Item (Proc_Id, N);
         end Implemented;

         ----------------------
         -- Implicit_Packing --
         ----------------------

         --  pragma Implicit_Packing;

         when Pragma_Implicit_Packing =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Implicit_Packing := True;

         ------------
         -- Import --
         ------------

         --  pragma Import (
         --       [Convention    =>] convention_IDENTIFIER,
         --       [Entity        =>] LOCAL_NAME
         --    [, [External_Name =>] static_string_EXPRESSION ]
         --    [, [Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_Import =>
            Check_Ada_83_Warning;
            Check_Arg_Order
              ((Name_Convention,
                Name_Entity,
                Name_External_Name,
                Name_Link_Name));

            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (4);
            Process_Import_Or_Interface;

         ---------------------
         -- Import_Function --
         ---------------------

         --  pragma Import_Function (
         --        [Internal                 =>] LOCAL_NAME,
         --     [, [External                 =>] EXTERNAL_SYMBOL]
         --     [, [Parameter_Types          =>] (PARAMETER_TYPES)]
         --     [, [Result_Type              =>] SUBTYPE_MARK]
         --     [, [Mechanism                =>] MECHANISM]
         --     [, [Result_Mechanism         =>] MECHANISM_NAME]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Import_Function => Import_Function : declare
            Args  : Args_List (1 .. 6);
            Names : constant Name_List (1 .. 6) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Result_Type,
                      Name_Mechanism,
                      Name_Result_Mechanism);

            Internal                 : Node_Id renames Args (1);
            External                 : Node_Id renames Args (2);
            Parameter_Types          : Node_Id renames Args (3);
            Result_Type              : Node_Id renames Args (4);
            Mechanism                : Node_Id renames Args (5);
            Result_Mechanism         : Node_Id renames Args (6);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal                 => Internal,
              Arg_External                 => External,
              Arg_Parameter_Types          => Parameter_Types,
              Arg_Result_Type              => Result_Type,
              Arg_Mechanism                => Mechanism,
              Arg_Result_Mechanism         => Result_Mechanism);
         end Import_Function;

         -------------------
         -- Import_Object --
         -------------------

         --  pragma Import_Object (
         --        [Internal =>] LOCAL_NAME
         --     [, [External =>] EXTERNAL_SYMBOL]
         --     [, [Size     =>] EXTERNAL_SYMBOL]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         when Pragma_Import_Object => Import_Object : declare
            Args  : Args_List (1 .. 3);
            Names : constant Name_List (1 .. 3) := (
                      Name_Internal,
                      Name_External,
                      Name_Size);

            Internal : Node_Id renames Args (1);
            External : Node_Id renames Args (2);
            Size     : Node_Id renames Args (3);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Object_Pragma (
              Arg_Internal => Internal,
              Arg_External => External,
              Arg_Size     => Size);
         end Import_Object;

         ----------------------
         -- Import_Procedure --
         ----------------------

         --  pragma Import_Procedure (
         --        [Internal                 =>] LOCAL_NAME
         --     [, [External                 =>] EXTERNAL_SYMBOL]
         --     [, [Parameter_Types          =>] (PARAMETER_TYPES)]
         --     [, [Mechanism                =>] MECHANISM]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Import_Procedure => Import_Procedure : declare
            Args  : Args_List (1 .. 4);
            Names : constant Name_List (1 .. 4) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Mechanism);

            Internal                 : Node_Id renames Args (1);
            External                 : Node_Id renames Args (2);
            Parameter_Types          : Node_Id renames Args (3);
            Mechanism                : Node_Id renames Args (4);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal                 => Internal,
              Arg_External                 => External,
              Arg_Parameter_Types          => Parameter_Types,
              Arg_Mechanism                => Mechanism);
         end Import_Procedure;

         -----------------------------
         -- Import_Valued_Procedure --
         -----------------------------

         --  pragma Import_Valued_Procedure (
         --        [Internal                 =>] LOCAL_NAME
         --     [, [External                 =>] EXTERNAL_SYMBOL]
         --     [, [Parameter_Types          =>] (PARAMETER_TYPES)]
         --     [, [Mechanism                =>] MECHANISM]);

         --  EXTERNAL_SYMBOL ::=
         --    IDENTIFIER
         --  | static_string_EXPRESSION

         --  PARAMETER_TYPES ::=
         --    null
         --  | TYPE_DESIGNATOR @{, TYPE_DESIGNATOR@}

         --  TYPE_DESIGNATOR ::=
         --    subtype_NAME
         --  | subtype_Name ' Access

         --  MECHANISM ::=
         --    MECHANISM_NAME
         --  | (MECHANISM_ASSOCIATION @{, MECHANISM_ASSOCIATION@})

         --  MECHANISM_ASSOCIATION ::=
         --    [formal_parameter_NAME =>] MECHANISM_NAME

         --  MECHANISM_NAME ::=
         --    Value
         --  | Reference

         when Pragma_Import_Valued_Procedure =>
         Import_Valued_Procedure : declare
            Args  : Args_List (1 .. 4);
            Names : constant Name_List (1 .. 4) := (
                      Name_Internal,
                      Name_External,
                      Name_Parameter_Types,
                      Name_Mechanism);

            Internal                 : Node_Id renames Args (1);
            External                 : Node_Id renames Args (2);
            Parameter_Types          : Node_Id renames Args (3);
            Mechanism                : Node_Id renames Args (4);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Subprogram_Pragma (
              Arg_Internal                 => Internal,
              Arg_External                 => External,
              Arg_Parameter_Types          => Parameter_Types,
              Arg_Mechanism                => Mechanism);
         end Import_Valued_Procedure;

         -----------------
         -- Independent --
         -----------------

         --  pragma Independent (LOCAL_NAME);

         when Pragma_Independent =>
            Process_Atomic_Independent_Shared_Volatile;

         ----------------------------
         -- Independent_Components --
         ----------------------------

         --  pragma Independent_Components (array_or_record_LOCAL_NAME);

         when Pragma_Independent_Components => Independent_Components : declare
            C    : Node_Id;
            D    : Node_Id;
            E_Id : Node_Id;
            E    : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Ada_2012_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);
            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            E := Entity (E_Id);

            --  A record type with a self-referential component of anonymous
            --  access type is given an incomplete view in order to handle the
            --  self reference:
            --
            --    type Rec is record
            --       Self : access Rec;
            --    end record;
            --
            --  becomes
            --
            --    type Rec;
            --    type Ptr is access Rec;
            --    type Rec is record
            --       Self : Ptr;
            --    end record;
            --
            --  Since the incomplete view is now the initial view of the type,
            --  the argument of the pragma will reference the incomplete view,
            --  but this view is illegal according to the semantics of the
            --  pragma.
            --
            --  Obtain the full view of an internally-generated incomplete type
            --  only. This way an attempt to associate the pragma with a source
            --  incomplete type is still caught.

            if Ekind (E) = E_Incomplete_Type
              and then not Comes_From_Source (E)
              and then Present (Full_View (E))
            then
               E := Full_View (E);
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            --  Check duplicate before we chain ourselves

            Check_Duplicate_Pragma (E);

            --  Check appropriate entity

            if Rep_Item_Too_Early (E, N)
                 or else
               Rep_Item_Too_Late (E, N)
            then
               return;
            end if;

            D := Declaration_Node (E);

            --  The flag is set on the base type, or on the object

            if Nkind (D) = N_Full_Type_Declaration
              and then (Is_Array_Type (E) or else Is_Record_Type (E))
            then
               Set_Has_Independent_Components (Base_Type (E));
               Record_Independence_Check (N, Base_Type (E));

               --  For record type, set all components independent

               if Is_Record_Type (E) then
                  C := First_Component (E);
                  while Present (C) loop
                     Set_Is_Independent (C);
                     Next_Component (C);
                  end loop;
               end if;

            elsif (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
              and then Nkind (D) = N_Object_Declaration
              and then Nkind (Object_Definition (D)) =
                                           N_Constrained_Array_Definition
            then
               Set_Has_Independent_Components (E);
               Record_Independence_Check (N, E);

            else
               Error_Pragma_Arg ("inappropriate entity for pragma%", Arg1);
            end if;
         end Independent_Components;

         -----------------------
         -- Initial_Condition --
         -----------------------

         --  pragma Initial_Condition (boolean_EXPRESSION);

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expression in:

         --       Analyze_Initial_Condition_In_Decl_Part

         --    * Expansion - The annotation is expanded during the expansion of
         --    the package body whose declaration is subject to the annotation
         --    as done in:

         --       Expand_Pragma_Initial_Condition

         --    * Template - The annotation utilizes the generic template of the
         --    related package declaration.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic package is instantiated.

         when Pragma_Initial_Condition => Initial_Condition : declare
            Pack_Decl : Node_Id;
            Pack_Id   : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Pack_Decl := Find_Related_Package_Or_Body (N, Do_Checks => True);

            if Nkind (Pack_Decl) not in
                 N_Generic_Package_Declaration | N_Package_Declaration
            then
               Pragma_Misplaced;
               return;
            end if;

            Pack_Id := Defining_Entity (Pack_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Pack_Id);

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Initial_Condition_In_Decl_Part.

            Add_Contract_Item (N, Pack_Id);

            --  The legality checks of pragmas Abstract_State, Initializes, and
            --  Initial_Condition are affected by the SPARK mode in effect. In
            --  addition, these three pragmas are subject to an inherent order:

            --    1) Abstract_State
            --    2) Initializes
            --    3) Initial_Condition

            --  Analyze all these pragmas in the order outlined above

            Analyze_If_Present (Pragma_SPARK_Mode);
            Analyze_If_Present (Pragma_Abstract_State);
            Analyze_If_Present (Pragma_Initializes);
         end Initial_Condition;

         ------------------------
         -- Initialize_Scalars --
         ------------------------

         --  pragma Initialize_Scalars
         --    [ ( TYPE_VALUE_PAIR {, TYPE_VALUE_PAIR} ) ];

         --  TYPE_VALUE_PAIR ::=
         --    SCALAR_TYPE => static_EXPRESSION

         --  SCALAR_TYPE :=
         --    Short_Float
         --  | Float
         --  | Long_Float
         --  | Long_Long_Float
         --  | Signed_8
         --  | Signed_16
         --  | Signed_32
         --  | Signed_64
         --  | Signed_128
         --  | Unsigned_8
         --  | Unsigned_16
         --  | Unsigned_32
         --  | Unsigned_64
         --  | Unsigned_128

         when Pragma_Initialize_Scalars => Do_Initialize_Scalars : declare
            Seen : array (Scalar_Id) of Node_Id := (others => Empty);
            --  This collection holds the individual pairs which specify the
            --  invalid values of their respective scalar types.

            procedure Analyze_Float_Value
              (Scal_Typ : Float_Scalar_Id;
               Val_Expr : Node_Id);
            --  Analyze a type value pair associated with float type Scal_Typ
            --  and expression Val_Expr.

            procedure Analyze_Integer_Value
              (Scal_Typ : Integer_Scalar_Id;
               Val_Expr : Node_Id);
            --  Analyze a type value pair associated with integer type Scal_Typ
            --  and expression Val_Expr.

            procedure Analyze_Type_Value_Pair (Pair : Node_Id);
            --  Analyze type value pair Pair

            -------------------------
            -- Analyze_Float_Value --
            -------------------------

            procedure Analyze_Float_Value
              (Scal_Typ : Float_Scalar_Id;
               Val_Expr : Node_Id)
            is
            begin
               Analyze_And_Resolve (Val_Expr, Any_Real);

               if Is_OK_Static_Expression (Val_Expr) then
                  Set_Invalid_Scalar_Value (Scal_Typ, Expr_Value_R (Val_Expr));

               else
                  Error_Msg_Name_1 := Scal_Typ;
                  Error_Msg_N ("value for type % must be static", Val_Expr);
               end if;
            end Analyze_Float_Value;

            ---------------------------
            -- Analyze_Integer_Value --
            ---------------------------

            procedure Analyze_Integer_Value
              (Scal_Typ : Integer_Scalar_Id;
               Val_Expr : Node_Id)
            is
            begin
               Analyze_And_Resolve (Val_Expr, Any_Integer);

               if (Scal_Typ = Name_Signed_128
                    or else Scal_Typ = Name_Unsigned_128)
                 and then Ttypes.System_Max_Integer_Size < 128
               then
                  Error_Msg_Name_1 := Scal_Typ;
                  Error_Msg_N ("value cannot be set for type %", Val_Expr);

               elsif Is_OK_Static_Expression (Val_Expr) then
                  Set_Invalid_Scalar_Value (Scal_Typ, Expr_Value (Val_Expr));

               else
                  Error_Msg_Name_1 := Scal_Typ;
                  Error_Msg_N ("value for type % must be static", Val_Expr);
               end if;
            end Analyze_Integer_Value;

            -----------------------------
            -- Analyze_Type_Value_Pair --
            -----------------------------

            procedure Analyze_Type_Value_Pair (Pair : Node_Id) is
               Scal_Typ  : constant Name_Id := Chars (Pair);
               Val_Expr  : constant Node_Id := Expression (Pair);
               Prev_Pair : Node_Id;

            begin
               if Scal_Typ in Scalar_Id then
                  Prev_Pair := Seen (Scal_Typ);

                  --  Prevent multiple attempts to set a value for a scalar
                  --  type.

                  if Present (Prev_Pair) then
                     Error_Msg_Name_1 := Scal_Typ;
                     Error_Msg_N
                       ("cannot specify multiple invalid values for type %",
                        Pair);

                     Error_Msg_Sloc := Sloc (Prev_Pair);
                     Error_Msg_N ("previous value set #", Pair);

                     --  Ignore the effects of the pair, but do not halt the
                     --  analysis of the pragma altogether.

                     return;

                  --  Otherwise capture the first pair for this scalar type

                  else
                     Seen (Scal_Typ) := Pair;
                  end if;

                  if Scal_Typ in Float_Scalar_Id then
                     Analyze_Float_Value (Scal_Typ, Val_Expr);

                  else pragma Assert (Scal_Typ in Integer_Scalar_Id);
                     Analyze_Integer_Value (Scal_Typ, Val_Expr);
                  end if;

               --  Otherwise the scalar family is illegal

               else
                  Error_Msg_Name_1 := Pname;
                  Error_Msg_N
                    ("argument of pragma % must denote valid scalar family",
                     Pair);
               end if;
            end Analyze_Type_Value_Pair;

            --  Local variables

            Pairs : constant List_Id := Pragma_Argument_Associations (N);
            Pair  : Node_Id;

         --  Start of processing for Do_Initialize_Scalars

         begin
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Restriction (No_Initialize_Scalars, N);

            --  Ignore the effects of the pragma when No_Initialize_Scalars is
            --  in effect.

            if Restriction_Active (No_Initialize_Scalars) then
               null;

            --  Initialize_Scalars creates false positives in CodePeer, and
            --  incorrect negative results in GNATprove mode, so ignore this
            --  pragma in these modes.

            elsif CodePeer_Mode or GNATprove_Mode then
               null;

            --  Otherwise analyze the pragma

            else
               if Present (Pairs) then

                  --  Install Standard in order to provide access to primitive
                  --  types in case the expressions contain attributes such as
                  --  Integer'Last.

                  Push_Scope (Standard_Standard);

                  Pair := First (Pairs);
                  while Present (Pair) loop
                     Analyze_Type_Value_Pair (Pair);
                     Next (Pair);
                  end loop;

                  --  Remove Standard

                  Pop_Scope;
               end if;

               Init_Or_Norm_Scalars := True;
               Initialize_Scalars   := True;
            end if;
         end Do_Initialize_Scalars;

         -----------------
         -- Initializes --
         -----------------

         --  pragma Initializes (INITIALIZATION_LIST);

         --  INITIALIZATION_LIST ::=
         --     null
         --  | (INITIALIZATION_ITEM {, INITIALIZATION_ITEM})

         --  INITIALIZATION_ITEM ::= name [=> INPUT_LIST]

         --  INPUT_LIST ::=
         --     null
         --  |  INPUT
         --  | (INPUT {, INPUT})

         --  INPUT ::= name

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expression in:

         --       Analyze_Initializes_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related package declaration.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic package is instantiated.

         when Pragma_Initializes => Initializes : declare
            Pack_Decl : Node_Id;
            Pack_Id   : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Pack_Decl := Find_Related_Package_Or_Body (N, Do_Checks => True);

            if Nkind (Pack_Decl) not in
                 N_Generic_Package_Declaration | N_Package_Declaration
            then
               Pragma_Misplaced;
               return;
            end if;

            Pack_Id := Defining_Entity (Pack_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Pack_Id);
            Ensure_Aggregate_Form (Get_Argument (N, Pack_Id));

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Initializes_In_Decl_Part.

            Add_Contract_Item (N, Pack_Id);

            --  The legality checks of pragmas Abstract_State, Initializes, and
            --  Initial_Condition are affected by the SPARK mode in effect. In
            --  addition, these three pragmas are subject to an inherent order:

            --    1) Abstract_State
            --    2) Initializes
            --    3) Initial_Condition

            --  Analyze all these pragmas in the order outlined above

            Analyze_If_Present (Pragma_SPARK_Mode);
            Analyze_If_Present (Pragma_Abstract_State);
            Analyze_If_Present (Pragma_Initial_Condition);
         end Initializes;

         ------------
         -- Inline --
         ------------

         --  pragma Inline ( NAME {, NAME} );

         when Pragma_Inline =>

            --  Pragma always active unless in GNATprove mode. It is disabled
            --  in GNATprove mode because frontend inlining is applied
            --  independently of pragmas Inline and Inline_Always for
            --  formal verification, see Can_Be_Inlined_In_GNATprove_Mode
            --  in inline.ads.

            if not GNATprove_Mode then

               --  Inline status is Enabled if option -gnatn is specified.
               --  However this status determines only the value of the
               --  Is_Inlined flag on the subprogram and does not prevent
               --  the pragma itself from being recorded for later use,
               --  in particular for a later modification of Is_Inlined
               --  independently of the -gnatn option.

               --  In other words, if -gnatn is specified for a unit, then
               --  all Inline pragmas processed for the compilation of this
               --  unit, including those in the spec of other units, are
               --  activated, so subprograms will be inlined across units.

               --  If -gnatn is not specified, no Inline pragma is activated
               --  here, which means that subprograms will not be inlined
               --  across units. The Is_Inlined flag will nevertheless be
               --  set later when bodies are analyzed, so subprograms will
               --  be inlined within the unit.

               if Inline_Active then
                  Process_Inline (Enabled);
               else
                  Process_Inline (Disabled);
               end if;
            end if;

         -------------------
         -- Inline_Always --
         -------------------

         --  pragma Inline_Always ( NAME {, NAME} );

         when Pragma_Inline_Always =>
            GNAT_Pragma;

            --  Pragma always active unless in CodePeer mode or GNATprove
            --  mode. It is disabled in CodePeer mode because inlining is
            --  not helpful, and enabling it caused walk order issues. It
            --  is disabled in GNATprove mode because frontend inlining is
            --  applied independently of pragmas Inline and Inline_Always for
            --  formal verification, see Can_Be_Inlined_In_GNATprove_Mode in
            --  inline.ads.

            if not CodePeer_Mode and not GNATprove_Mode then
               Process_Inline (Enabled);
            end if;

         --------------------
         -- Inline_Generic --
         --------------------

         --  pragma Inline_Generic (NAME {, NAME});

         when Pragma_Inline_Generic =>
            GNAT_Pragma;
            Process_Generic_List;

         ----------------------
         -- Inspection_Point --
         ----------------------

         --  pragma Inspection_Point [(object_NAME {, object_NAME})];

         when Pragma_Inspection_Point => Inspection_Point : declare
            Arg : Node_Id;
            Exp : Node_Id;

         begin
            ip;

            if Arg_Count > 0 then
               Arg := Arg1;
               loop
                  Exp := Get_Pragma_Arg (Arg);
                  Analyze (Exp);

                  if not Is_Entity_Name (Exp)
                    or else not Is_Object (Entity (Exp))
                  then
                     Error_Pragma_Arg ("object name required", Arg);
                  end if;

                  Next (Arg);
                  exit when No (Arg);
               end loop;
            end if;
         end Inspection_Point;

         ---------------
         -- Interface --
         ---------------

         --  pragma Interface (
         --    [   Convention    =>] convention_IDENTIFIER,
         --    [   Entity        =>] LOCAL_NAME
         --    [, [External_Name =>] static_string_EXPRESSION ]
         --    [, [Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_Interface =>
            GNAT_Pragma;
            Check_Arg_Order
              ((Name_Convention,
                Name_Entity,
                Name_External_Name,
                Name_Link_Name));
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (4);
            Process_Import_Or_Interface;

            --  In Ada 2005, the permission to use Interface (a reserved word)
            --  as a pragma name is considered an obsolescent feature, and this
            --  pragma was already obsolescent in Ada 95.

            if Ada_Version >= Ada_95 then
               Check_Restriction
                 (No_Obsolescent_Features, Pragma_Identifier (N));

               if Warn_On_Obsolescent_Feature then
                  Error_Msg_N
                    ("pragma Interface is an obsolescent feature?j?", N);
                  Error_Msg_N
                    ("|use pragma Import instead?j?", N);
               end if;
            end if;

         --------------------
         -- Interface_Name --
         --------------------

         --  pragma Interface_Name (
         --    [  Entity        =>] LOCAL_NAME
         --    [,[External_Name =>] static_string_EXPRESSION ]
         --    [,[Link_Name     =>] static_string_EXPRESSION ]);

         when Pragma_Interface_Name => Interface_Name : declare
            Id     : Node_Id;
            Def_Id : Entity_Id;
            Hom_Id : Entity_Id;
            Found  : Boolean;

         begin
            GNAT_Pragma;
            Check_Arg_Order
              ((Name_Entity, Name_External_Name, Name_Link_Name));
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (3);
            Id := Get_Pragma_Arg (Arg1);
            Analyze (Id);

            --  This is obsolete from Ada 95 on, but it is an implementation
            --  defined pragma, so we do not consider that it violates the
            --  restriction (No_Obsolescent_Features).

            if Ada_Version >= Ada_95 then
               if Warn_On_Obsolescent_Feature then
                  Error_Msg_N
                    ("pragma Interface_Name is an obsolescent feature?j?", N);
                  Error_Msg_N
                    ("|use pragma Import instead?j?", N);
               end if;
            end if;

            if not Is_Entity_Name (Id) then
               Error_Pragma_Arg
                 ("first argument for pragma% must be entity name", Arg1);
            elsif Etype (Id) = Any_Type then
               return;
            else
               Def_Id := Entity (Id);
            end if;

            --  Special DEC-compatible processing for the object case, forces
            --  object to be imported.

            if Ekind (Def_Id) = E_Variable then
               Kill_Size_Check_Code (Def_Id);
               Note_Possible_Modification (Id, Sure => False);

               --  Initialization is not allowed for imported variable

               if Present (Expression (Parent (Def_Id)))
                 and then Comes_From_Source (Expression (Parent (Def_Id)))
               then
                  Error_Msg_Sloc := Sloc (Def_Id);
                  Error_Pragma_Arg
                    ("no initialization allowed for declaration of& #",
                     Arg2);

               else
                  --  For compatibility, support VADS usage of providing both
                  --  pragmas Interface and Interface_Name to obtain the effect
                  --  of a single Import pragma.

                  if Is_Imported (Def_Id)
                    and then Present (First_Rep_Item (Def_Id))
                    and then Nkind (First_Rep_Item (Def_Id)) = N_Pragma
                    and then Pragma_Name (First_Rep_Item (Def_Id)) =
                      Name_Interface
                  then
                     null;
                  else
                     Set_Imported (Def_Id);
                  end if;

                  Set_Is_Public (Def_Id);
                  Process_Interface_Name (Def_Id, Arg2, Arg3, N);
               end if;

            --  Otherwise must be subprogram

            elsif not Is_Subprogram (Def_Id) then
               Error_Pragma_Arg
                 ("argument of pragma% is not subprogram", Arg1);

            else
               Check_At_Most_N_Arguments (3);
               Hom_Id := Def_Id;
               Found := False;

               --  Loop through homonyms

               loop
                  Def_Id := Get_Base_Subprogram (Hom_Id);

                  if Is_Imported (Def_Id) then
                     Process_Interface_Name (Def_Id, Arg2, Arg3, N);
                     Found := True;
                  end if;

                  exit when From_Aspect_Specification (N);
                  Hom_Id := Homonym (Hom_Id);

                  exit when No (Hom_Id)
                    or else Scope (Hom_Id) /= Current_Scope;
               end loop;

               if not Found then
                  Error_Pragma_Arg
                    ("argument of pragma% is not imported subprogram",
                     Arg1);
               end if;
            end if;
         end Interface_Name;

         -----------------------
         -- Interrupt_Handler --
         -----------------------

         --  pragma Interrupt_Handler (handler_NAME);

         when Pragma_Interrupt_Handler =>
            Check_Ada_83_Warning;
            Check_Arg_Count (1);
            Check_No_Identifiers;

            if No_Run_Time_Mode then
               Error_Msg_CRT ("Interrupt_Handler pragma", N);
            else
               Check_Interrupt_Or_Attach_Handler;
               Process_Interrupt_Or_Attach_Handler;
            end if;

         ------------------------
         -- Interrupt_Priority --
         ------------------------

         --  pragma Interrupt_Priority [(EXPRESSION)];

         when Pragma_Interrupt_Priority => Interrupt_Priority : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            Check_Ada_83_Warning;

            if Arg_Count /= 0 then
               Arg := Get_Pragma_Arg (Arg1);
               Check_Arg_Count (1);
               Check_No_Identifiers;

               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               Preanalyze_Spec_Expression (Arg, RTE (RE_Interrupt_Priority));
            end if;

            if Nkind (P) not in N_Task_Definition | N_Protected_Definition then
               Pragma_Misplaced;
               return;

            else
               Ent := Defining_Identifier (Parent (P));

               --  Check duplicate pragma before we chain the pragma in the Rep
               --  Item chain of Ent.

               Check_Duplicate_Pragma (Ent);
               Record_Rep_Item (Ent, N);

               --  Check the No_Task_At_Interrupt_Priority restriction

               if Nkind (P) = N_Task_Definition then
                  Check_Restriction (No_Task_At_Interrupt_Priority, N);
               end if;
            end if;
         end Interrupt_Priority;

         ---------------------
         -- Interrupt_State --
         ---------------------

         --  pragma Interrupt_State (
         --    [Name  =>] INTERRUPT_ID,
         --    [State =>] INTERRUPT_STATE);

         --  INTERRUPT_ID => IDENTIFIER | static_integer_EXPRESSION
         --  INTERRUPT_STATE => System | Runtime | User

         --  Note: if the interrupt id is given as an identifier, then it must
         --  be one of the identifiers in Ada.Interrupts.Names. Otherwise it is
         --  given as a static integer expression which must be in the range of
         --  Ada.Interrupts.Interrupt_ID.

         when Pragma_Interrupt_State => Interrupt_State : declare
            Int_Id : constant Entity_Id := RTE (RE_Interrupt_ID);
            --  This is the entity Ada.Interrupts.Interrupt_ID;

            State_Type : Character;
            --  Set to 's'/'r'/'u' for System/Runtime/User

            IST_Num : Pos;
            --  Index to entry in Interrupt_States table

            Int_Val : Uint;
            --  Value of interrupt

            Arg1X : constant Node_Id := Get_Pragma_Arg (Arg1);
            --  The first argument to the pragma

            Int_Ent : Entity_Id;
            --  Interrupt entity in Ada.Interrupts.Names

         begin
            GNAT_Pragma;
            Check_Arg_Order ((Name_Name, Name_State));
            Check_Arg_Count (2);

            Check_Optional_Identifier (Arg1, Name_Name);
            Check_Optional_Identifier (Arg2, Name_State);
            Check_Arg_Is_Identifier (Arg2);

            --  First argument is identifier

            if Nkind (Arg1X) = N_Identifier then

               --  Search list of names in Ada.Interrupts.Names

               Int_Ent := First_Entity (RTE (RE_Names));
               loop
                  if No (Int_Ent) then
                     Error_Pragma_Arg ("invalid interrupt name", Arg1);

                  elsif Chars (Int_Ent) = Chars (Arg1X) then
                     Int_Val := Expr_Value (Constant_Value (Int_Ent));
                     exit;
                  end if;

                  Next_Entity (Int_Ent);
               end loop;

            --  First argument is not an identifier, so it must be a static
            --  expression of type Ada.Interrupts.Interrupt_ID.

            else
               Check_Arg_Is_OK_Static_Expression (Arg1, Any_Integer);
               Int_Val := Expr_Value (Arg1X);

               if Int_Val < Expr_Value (Type_Low_Bound (Int_Id))
                    or else
                  Int_Val > Expr_Value (Type_High_Bound (Int_Id))
               then
                  Error_Pragma_Arg
                    ("value not in range of type "
                     & """Ada.Interrupts.Interrupt_'I'D""", Arg1);
               end if;
            end if;

            --  Check OK state

            case Chars (Get_Pragma_Arg (Arg2)) is
               when Name_Runtime => State_Type := 'r';
               when Name_System  => State_Type := 's';
               when Name_User    => State_Type := 'u';

               when others =>
                  Error_Pragma_Arg ("invalid interrupt state", Arg2);
            end case;

            --  Check if entry is already stored

            IST_Num := Interrupt_States.First;
            loop
               --  If entry not found, add it

               if IST_Num > Interrupt_States.Last then
                  Interrupt_States.Append
                    ((Interrupt_Number => UI_To_Int (Int_Val),
                      Interrupt_State  => State_Type,
                      Pragma_Loc       => Loc));
                  exit;

               --  Case of entry for the same entry

               elsif Int_Val = Interrupt_States.Table (IST_Num).
                                                           Interrupt_Number
               then
                  --  If state matches, done, no need to make redundant entry

                  exit when
                    State_Type = Interrupt_States.Table (IST_Num).
                                                           Interrupt_State;

                  --  Otherwise if state does not match, error

                  Error_Msg_Sloc :=
                    Interrupt_States.Table (IST_Num).Pragma_Loc;
                  Error_Pragma_Arg
                    ("state conflicts with that given #", Arg2);
                  exit;
               end if;

               IST_Num := IST_Num + 1;
            end loop;
         end Interrupt_State;

         ---------------
         -- Invariant --
         ---------------

         --  pragma Invariant
         --    ([Entity =>]    type_LOCAL_NAME,
         --     [Check  =>]    EXPRESSION
         --     [,[Message =>] String_Expression]);

         when Pragma_Invariant => Invariant : declare
            Discard : Boolean;
            Typ     : Entity_Id;
            Typ_Arg : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments  (3);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Check);

            if Arg_Count = 3 then
               Check_Optional_Identifier (Arg3, Name_Message);
               Check_Arg_Is_OK_Static_Expression (Arg3, Standard_String);
            end if;

            Check_Arg_Is_Local_Name (Arg1);

            Typ_Arg := Get_Pragma_Arg (Arg1);
            Find_Type (Typ_Arg);
            Typ := Entity (Typ_Arg);

            --  Nothing to do of the related type is erroneous in some way

            if Typ = Any_Type then
               return;

            --  AI12-0041: Invariants are allowed in interface types

            elsif Is_Interface (Typ) then
               null;

            --  An invariant must apply to a private type, or appear in the
            --  private part of a package spec and apply to a completion.
            --  a class-wide invariant can only appear on a private declaration
            --  or private extension, not a completion.

            --  A [class-wide] invariant may be associated a [limited] private
            --  type or a private extension.

            elsif Ekind (Typ) in E_Limited_Private_Type
                               | E_Private_Type
                               | E_Record_Type_With_Private
            then
               null;

            --  A non-class-wide invariant may be associated with the full view
            --  of a [limited] private type or a private extension.

            elsif Has_Private_Declaration (Typ)
              and then not Class_Present (N)
            then
               null;

            --  A class-wide invariant may appear on the partial view only

            elsif Class_Present (N) then
               Error_Pragma_Arg
                 ("pragma % only allowed for private type", Arg1);
               return;

            --  A regular invariant may appear on both views

            else
               Error_Pragma_Arg
                 ("pragma % only allowed for private type or corresponding "
                  & "full view", Arg1);
               return;
            end if;

            --  An invariant associated with an abstract type (this includes
            --  interfaces) must be class-wide.

            if Is_Abstract_Type (Typ) and then not Class_Present (N) then
               Error_Pragma_Arg
                 ("pragma % not allowed for abstract type", Arg1);
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  The pragma defines a type-specific invariant, the type is said
            --  to have invariants of its "own".

            Set_Has_Own_Invariants (Base_Type (Typ));

            --  If the invariant is class-wide, then it can be inherited by
            --  derived or interface implementing types. The type is said to
            --  have "inheritable" invariants.

            if Class_Present (N) then
               Set_Has_Inheritable_Invariants (Typ);
            end if;

            --  Chain the pragma on to the rep item chain, for processing when
            --  the type is frozen.

            Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);

            --  Create the declaration of the invariant procedure that will
            --  verify the invariant at run time. Interfaces are treated as the
            --  partial view of a private type in order to achieve uniformity
            --  with the general case. As a result, an interface receives only
            --  a "partial" invariant procedure, which is never called.

            Build_Invariant_Procedure_Declaration
              (Typ               => Typ,
               Partial_Invariant => Is_Interface (Typ));
         end Invariant;

         ----------------
         -- Keep_Names --
         ----------------

         --  pragma Keep_Names ([On => ] LOCAL_NAME);

         when Pragma_Keep_Names => Keep_Names : declare
            Arg : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_On);
            Check_Arg_Is_Local_Name (Arg1);

            Arg := Get_Pragma_Arg (Arg1);
            Analyze (Arg);

            if Etype (Arg) = Any_Type then
               return;
            end if;

            if not Is_Entity_Name (Arg)
              or else Ekind (Entity (Arg)) /= E_Enumeration_Type
            then
               Error_Pragma_Arg
                 ("pragma% requires a local enumeration type", Arg1);
            end if;

            Set_Discard_Names (Entity (Arg), False);
         end Keep_Names;

         -------------
         -- License --
         -------------

         --  pragma License (RESTRICTED | UNRESTRICTED | GPL | MODIFIED_GPL);

         when Pragma_License =>
            GNAT_Pragma;

            --  Do not analyze pragma any further in CodePeer mode, to avoid
            --  extraneous errors in this implementation-dependent pragma,
            --  which has a different profile on other compilers.

            if CodePeer_Mode then
               return;
            end if;

            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Is_Identifier (Arg1);

            declare
               Sind : constant Source_File_Index :=
                        Source_Index (Current_Sem_Unit);

            begin
               case Chars (Get_Pragma_Arg (Arg1)) is
                  when Name_GPL =>
                     Set_License (Sind, GPL);

                  when Name_Modified_GPL =>
                     Set_License (Sind, Modified_GPL);

                  when Name_Restricted =>
                     Set_License (Sind, Restricted);

                  when Name_Unrestricted =>
                     Set_License (Sind, Unrestricted);

                  when others =>
                     Error_Pragma_Arg ("invalid license name", Arg1);
               end case;
            end;

         ---------------
         -- Link_With --
         ---------------

         --  pragma Link_With (string_EXPRESSION {, string_EXPRESSION});

         when Pragma_Link_With => Link_With : declare
            Arg : Node_Id;

         begin
            GNAT_Pragma;

            if Operating_Mode = Generate_Code
              and then In_Extended_Main_Source_Unit (N)
            then
               Check_At_Least_N_Arguments (1);
               Check_No_Identifiers;
               Check_Is_In_Decl_Part_Or_Package_Spec;
               Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);
               Start_String;

               Arg := Arg1;
               while Present (Arg) loop
                  Check_Arg_Is_OK_Static_Expression (Arg, Standard_String);

                  --  Store argument, converting sequences of spaces to a
                  --  single null character (this is one of the differences
                  --  in processing between Link_With and Linker_Options).

                  Arg_Store : declare
                     C : constant Char_Code := Get_Char_Code (' ');
                     S : constant String_Id :=
                           Strval (Expr_Value_S (Get_Pragma_Arg (Arg)));
                     L : constant Nat := String_Length (S);
                     F : Nat := 1;

                     procedure Skip_Spaces;
                     --  Advance F past any spaces

                     -----------------
                     -- Skip_Spaces --
                     -----------------

                     procedure Skip_Spaces is
                     begin
                        while F <= L and then Get_String_Char (S, F) = C loop
                           F := F + 1;
                        end loop;
                     end Skip_Spaces;

                  --  Start of processing for Arg_Store

                  begin
                     Skip_Spaces; -- skip leading spaces

                     --  Loop through characters, changing any embedded
                     --  sequence of spaces to a single null character (this
                     --  is how Link_With/Linker_Options differ)

                     while F <= L loop
                        if Get_String_Char (S, F) = C then
                           Skip_Spaces;
                           exit when F > L;
                           Store_String_Char (ASCII.NUL);

                        else
                           Store_String_Char (Get_String_Char (S, F));
                           F := F + 1;
                        end if;
                     end loop;
                  end Arg_Store;

                  Arg := Next (Arg);

                  if Present (Arg) then
                     Store_String_Char (ASCII.NUL);
                  end if;
               end loop;

               Store_Linker_Option_String (End_String);
            end if;
         end Link_With;

         ------------------
         -- Linker_Alias --
         ------------------

         --  pragma Linker_Alias (
         --      [Entity =>]  LOCAL_NAME
         --      [Target =>]  static_string_EXPRESSION);

         when Pragma_Linker_Alias =>
            GNAT_Pragma;
            Check_Arg_Order ((Name_Entity, Name_Target));
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Target);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);
            Check_Arg_Is_OK_Static_Expression (Arg2, Standard_String);

            --  The only processing required is to link this item on to the
            --  list of rep items for the given entity. This is accomplished
            --  by the call to Rep_Item_Too_Late (when no error is detected
            --  and False is returned).

            if Rep_Item_Too_Late (Entity (Get_Pragma_Arg (Arg1)), N) then
               return;
            else
               Set_Has_Gigi_Rep_Item (Entity (Get_Pragma_Arg (Arg1)));
            end if;

         ------------------------
         -- Linker_Constructor --
         ------------------------

         --  pragma Linker_Constructor (procedure_LOCAL_NAME);

         --  Code is shared with Linker_Destructor

         -----------------------
         -- Linker_Destructor --
         -----------------------

         --  pragma Linker_Destructor (procedure_LOCAL_NAME);

         when Pragma_Linker_Constructor
            | Pragma_Linker_Destructor
         =>
         Linker_Constructor : declare
            Arg1_X : Node_Id;
            Proc   : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Local_Name (Arg1);
            Arg1_X := Get_Pragma_Arg (Arg1);
            Analyze (Arg1_X);
            Proc := Find_Unique_Parameterless_Procedure (Arg1_X, Arg1);

            if not Is_Library_Level_Entity (Proc) then
               Error_Pragma_Arg
                ("argument for pragma% must be library level entity", Arg1);
            end if;

            --  The only processing required is to link this item on to the
            --  list of rep items for the given entity. This is accomplished
            --  by the call to Rep_Item_Too_Late (when no error is detected
            --  and False is returned).

            if Rep_Item_Too_Late (Proc, N) then
               return;
            else
               Set_Has_Gigi_Rep_Item (Proc);
            end if;
         end Linker_Constructor;

         --------------------
         -- Linker_Options --
         --------------------

         --  pragma Linker_Options (string_EXPRESSION {, string_EXPRESSION});

         when Pragma_Linker_Options => Linker_Options : declare
            Arg : Node_Id;

         begin
            Check_Ada_83_Warning;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Is_In_Decl_Part_Or_Package_Spec;
            Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);
            Start_String (Strval (Expr_Value_S (Get_Pragma_Arg (Arg1))));

            Arg := Arg2;
            while Present (Arg) loop
               Check_Arg_Is_OK_Static_Expression (Arg, Standard_String);
               Store_String_Char (ASCII.NUL);
               Store_String_Chars
                 (Strval (Expr_Value_S (Get_Pragma_Arg (Arg))));
               Arg := Next (Arg);
            end loop;

            if Operating_Mode = Generate_Code
              and then In_Extended_Main_Source_Unit (N)
            then
               Store_Linker_Option_String (End_String);
            end if;
         end Linker_Options;

         --------------------
         -- Linker_Section --
         --------------------

         --  pragma Linker_Section (
         --      [Entity  =>] LOCAL_NAME
         --      [Section =>] static_string_EXPRESSION);

         when Pragma_Linker_Section => Linker_Section : declare
            Arg : Node_Id;
            Ent : Entity_Id;
            LPE : Node_Id;

            Ghost_Error_Posted : Boolean := False;
            --  Flag set when an error concerning the illegal mix of Ghost and
            --  non-Ghost subprograms is emitted.

            Ghost_Id : Entity_Id := Empty;
            --  The entity of the first Ghost subprogram encountered while
            --  processing the arguments of the pragma.

         begin
            GNAT_Pragma;
            Check_Arg_Order ((Name_Entity, Name_Section));
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Section);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);
            Check_Arg_Is_OK_Static_Expression (Arg2, Standard_String);

            --  Check kind of entity

            Arg := Get_Pragma_Arg (Arg1);
            Ent := Entity (Arg);

            case Ekind (Ent) is

               --  Objects (constants and variables) and types. For these cases
               --  all we need to do is to set the Linker_Section_pragma field,
               --  checking that we do not have a duplicate.

               when Type_Kind
                  | E_Constant
                  | E_Variable
               =>
                  LPE := Linker_Section_Pragma (Ent);

                  if Present (LPE) then
                     Error_Msg_Sloc := Sloc (LPE);
                     Error_Msg_NE
                       ("Linker_Section already specified for &#", Arg1, Ent);
                  end if;

                  Set_Linker_Section_Pragma (Ent, N);

                  --  A pragma that applies to a Ghost entity becomes Ghost for
                  --  the purposes of legality checks and removal of ignored
                  --  Ghost code.

                  Mark_Ghost_Pragma (N, Ent);

               --  Subprograms

               when Subprogram_Kind =>

                  --  Aspect case, entity already set

                  if From_Aspect_Specification (N) then
                     Set_Linker_Section_Pragma
                       (Entity (Corresponding_Aspect (N)), N);

                     --  Propagate it to its ultimate aliased entity to
                     --  facilitate the backend processing this attribute
                     --  in instantiations of generic subprograms.

                     if Present (Alias (Entity (Corresponding_Aspect (N))))
                     then
                        Set_Linker_Section_Pragma
                          (Ultimate_Alias
                            (Entity (Corresponding_Aspect (N))), N);
                     end if;

                  --  Pragma case, we must climb the homonym chain, but skip
                  --  any for which the linker section is already set.

                  else
                     loop
                        if No (Linker_Section_Pragma (Ent)) then
                           Set_Linker_Section_Pragma (Ent, N);

                           --  Propagate it to its ultimate aliased entity to
                           --  facilitate the backend processing this attribute
                           --  in instantiations of generic subprograms.

                           if Present (Alias (Ent)) then
                              Set_Linker_Section_Pragma
                                (Ultimate_Alias (Ent), N);
                           end if;

                           --  A pragma that applies to a Ghost entity becomes
                           --  Ghost for the purposes of legality checks and
                           --  removal of ignored Ghost code.

                           Mark_Ghost_Pragma (N, Ent);

                           --  Capture the entity of the first Ghost subprogram
                           --  being processed for error detection purposes.

                           if Is_Ghost_Entity (Ent) then
                              if No (Ghost_Id) then
                                 Ghost_Id := Ent;
                              end if;

                           --  Otherwise the subprogram is non-Ghost. It is
                           --  illegal to mix references to Ghost and non-Ghost
                           --  entities (SPARK RM 6.9).

                           elsif Present (Ghost_Id)
                             and then not Ghost_Error_Posted
                           then
                              Ghost_Error_Posted := True;

                              Error_Msg_Name_1 := Pname;
                              Error_Msg_N
                                ("pragma % cannot mention ghost and "
                                 & "non-ghost subprograms", N);

                              Error_Msg_Sloc := Sloc (Ghost_Id);
                              Error_Msg_NE
                                ("\& # declared as ghost", N, Ghost_Id);

                              Error_Msg_Sloc := Sloc (Ent);
                              Error_Msg_NE
                                ("\& # declared as non-ghost", N, Ent);
                           end if;
                        end if;

                        Ent := Homonym (Ent);
                        exit when No (Ent)
                          or else Scope (Ent) /= Current_Scope;
                     end loop;
                  end if;

               --  All other cases are illegal

               when others =>
                  Error_Pragma_Arg
                    ("pragma% applies only to objects, subprograms, and types",
                     Arg1);
            end case;
         end Linker_Section;

         ----------
         -- List --
         ----------

         --  pragma List (On | Off)

         --  There is nothing to do here, since we did all the processing for
         --  this pragma in Par.Prag (so that it works properly even in syntax
         --  only mode).

         when Pragma_List =>
            null;

         ---------------
         -- Lock_Free --
         ---------------

         --  pragma Lock_Free [(Boolean_EXPRESSION)];

         when Pragma_Lock_Free => Lock_Free : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;
            Val : Boolean;

         begin
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            --  Protected definition case

            if Nkind (P) = N_Protected_Definition then
               Ent := Defining_Identifier (Parent (P));

               --  One argument

               if Arg_Count = 1 then
                  Arg := Get_Pragma_Arg (Arg1);
                  Val := Is_True (Static_Boolean (Arg));

               --  No arguments (expression is considered to be True)

               else
                  Val := True;
               end if;

               --  Check duplicate pragma before we chain the pragma in the Rep
               --  Item chain of Ent.

               Check_Duplicate_Pragma (Ent);
               Record_Rep_Item        (Ent, N);
               Set_Uses_Lock_Free     (Ent, Val);

            --  Anything else is incorrect placement

            else
               Pragma_Misplaced;
            end if;
         end Lock_Free;

         --------------------
         -- Locking_Policy --
         --------------------

         --  pragma Locking_Policy (policy_IDENTIFIER);

         when Pragma_Locking_Policy => declare
            subtype LP_Range is Name_Id
              range First_Locking_Policy_Name .. Last_Locking_Policy_Name;
            LP_Val : LP_Range;
            LP     : Character;

         begin
            Check_Ada_83_Warning;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Locking_Policy (Arg1);
            Check_Valid_Configuration_Pragma;
            LP_Val := Chars (Get_Pragma_Arg (Arg1));

            case LP_Val is
               when Name_Ceiling_Locking            => LP := 'C';
               when Name_Concurrent_Readers_Locking => LP := 'R';
               when Name_Inheritance_Locking        => LP := 'I';
            end case;

            if Locking_Policy /= ' '
              and then Locking_Policy /= LP
            then
               Error_Msg_Sloc := Locking_Policy_Sloc;
               Error_Pragma ("locking policy incompatible with policy#");

            --  Set new policy, but always preserve System_Location since we
            --  like the error message with the run time name.

            else
               Locking_Policy := LP;

               if Locking_Policy_Sloc /= System_Location then
                  Locking_Policy_Sloc := Loc;
               end if;
            end if;
         end;

         -------------------
         -- Loop_Optimize --
         -------------------

         --  pragma Loop_Optimize ( OPTIMIZATION_HINT {, OPTIMIZATION_HINT } );

         --  OPTIMIZATION_HINT ::=
         --    Ivdep | No_Unroll | Unroll | No_Vector | Vector

         when Pragma_Loop_Optimize => Loop_Optimize : declare
            Hint : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);
            Check_No_Identifiers;

            Hint := First (Pragma_Argument_Associations (N));
            while Present (Hint) loop
               Check_Arg_Is_One_Of (Hint, Name_Ivdep,
                                          Name_No_Unroll,
                                          Name_Unroll,
                                          Name_No_Vector,
                                          Name_Vector);
               Next (Hint);
            end loop;

            Check_Loop_Pragma_Placement;
         end Loop_Optimize;

         ------------------
         -- Loop_Variant --
         ------------------

         --  pragma Loop_Variant
         --         ( LOOP_VARIANT_ITEM {, LOOP_VARIANT_ITEM } );

         --  LOOP_VARIANT_ITEM ::= CHANGE_DIRECTION => discrete_EXPRESSION

         --  CHANGE_DIRECTION ::= Increases | Decreases

         when Pragma_Loop_Variant => Loop_Variant : declare
            Variant : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);
            Check_Loop_Pragma_Placement;

            --  Process all increasing / decreasing expressions

            Variant := First (Pragma_Argument_Associations (N));
            while Present (Variant) loop
               if Chars (Variant) = No_Name then
                  Error_Pragma_Arg_Ident ("expect name `Increases`", Variant);

               elsif Chars (Variant) not in Name_Decreases | Name_Increases
               then
                  declare
                     Name : String := Get_Name_String (Chars (Variant));

                  begin
                     --  It is a common mistake to write "Increasing" for
                     --  "Increases" or "Decreasing" for "Decreases". Recognize
                     --  specially names starting with "incr" or "decr" to
                     --  suggest the corresponding name.

                     System.Case_Util.To_Lower (Name);

                     if Name'Length >= 4
                       and then Name (1 .. 4) = "incr"
                     then
                        Error_Pragma_Arg_Ident
                          ("expect name `Increases`", Variant);

                     elsif Name'Length >= 4
                       and then Name (1 .. 4) = "decr"
                     then
                        Error_Pragma_Arg_Ident
                          ("expect name `Decreases`", Variant);

                     else
                        Error_Pragma_Arg_Ident
                          ("expect name `Increases` or `Decreases`", Variant);
                     end if;
                  end;
               end if;

               Preanalyze_Assert_Expression
                 (Expression (Variant), Any_Discrete);

               Next (Variant);
            end loop;
         end Loop_Variant;

         -----------------------
         -- Machine_Attribute --
         -----------------------

         --  pragma Machine_Attribute (
         --     [Entity         =>] LOCAL_NAME,
         --     [Attribute_Name =>] static_string_EXPRESSION
         --  [, [Info           =>] static_EXPRESSION {, static_EXPRESSION}] );

         when Pragma_Machine_Attribute => Machine_Attribute : declare
            Arg : Node_Id;
            Def_Id : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Order ((Name_Entity, Name_Attribute_Name, Name_Info));

            if Arg_Count >= 3 then
               Check_Optional_Identifier (Arg3, Name_Info);
               Arg := Arg3;
               while Present (Arg) loop
                  Check_Arg_Is_OK_Static_Expression (Arg);
                  Arg := Next (Arg);
               end loop;
            else
               Check_Arg_Count (2);
            end if;

            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Attribute_Name);
            Check_Arg_Is_Local_Name (Arg1);
            Check_Arg_Is_OK_Static_Expression (Arg2, Standard_String);
            Def_Id := Entity (Get_Pragma_Arg (Arg1));

            if Is_Access_Type (Def_Id) then
               Def_Id := Designated_Type (Def_Id);
            end if;

            if Rep_Item_Too_Early (Def_Id, N) then
               return;
            end if;

            Def_Id := Underlying_Type (Def_Id);

            --  The only processing required is to link this item on to the
            --  list of rep items for the given entity. This is accomplished
            --  by the call to Rep_Item_Too_Late (when no error is detected
            --  and False is returned).

            if Rep_Item_Too_Late (Def_Id, N) then
               return;
            else
               Set_Has_Gigi_Rep_Item (Entity (Get_Pragma_Arg (Arg1)));
            end if;
         end Machine_Attribute;

         ----------
         -- Main --
         ----------

         --  pragma Main
         --   (MAIN_OPTION [, MAIN_OPTION]);

         --  MAIN_OPTION ::=
         --    [STACK_SIZE              =>] static_integer_EXPRESSION
         --  | [TASK_STACK_SIZE_DEFAULT =>] static_integer_EXPRESSION
         --  | [TIME_SLICING_ENABLED    =>] static_boolean_EXPRESSION

         when Pragma_Main => Main : declare
            Args  : Args_List (1 .. 3);
            Names : constant Name_List (1 .. 3) := (
                      Name_Stack_Size,
                      Name_Task_Stack_Size_Default,
                      Name_Time_Slicing_Enabled);

            Nod : Node_Id;

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);

            for J in 1 .. 2 loop
               if Present (Args (J)) then
                  Check_Arg_Is_OK_Static_Expression (Args (J), Any_Integer);
               end if;
            end loop;

            if Present (Args (3)) then
               Check_Arg_Is_OK_Static_Expression (Args (3), Standard_Boolean);
            end if;

            Nod := Next (N);
            while Present (Nod) loop
               if Nkind (Nod) = N_Pragma
                 and then Pragma_Name (Nod) = Name_Main
               then
                  Error_Msg_Name_1 := Pname;
                  Error_Msg_N ("duplicate pragma% not permitted", Nod);
               end if;

               Next (Nod);
            end loop;
         end Main;

         ------------------
         -- Main_Storage --
         ------------------

         --  pragma Main_Storage
         --   (MAIN_STORAGE_OPTION [, MAIN_STORAGE_OPTION]);

         --  MAIN_STORAGE_OPTION ::=
         --    [WORKING_STORAGE =>] static_SIMPLE_EXPRESSION
         --  | [TOP_GUARD =>] static_SIMPLE_EXPRESSION

         when Pragma_Main_Storage => Main_Storage : declare
            Args  : Args_List (1 .. 2);
            Names : constant Name_List (1 .. 2) := (
                      Name_Working_Storage,
                      Name_Top_Guard);

            Nod : Node_Id;

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);

            for J in 1 .. 2 loop
               if Present (Args (J)) then
                  Check_Arg_Is_OK_Static_Expression (Args (J), Any_Integer);
               end if;
            end loop;

            Check_In_Main_Program;

            Nod := Next (N);
            while Present (Nod) loop
               if Nkind (Nod) = N_Pragma
                 and then Pragma_Name (Nod) = Name_Main_Storage
               then
                  Error_Msg_Name_1 := Pname;
                  Error_Msg_N ("duplicate pragma% not permitted", Nod);
               end if;

               Next (Nod);
            end loop;
         end Main_Storage;

         ----------------------------
         -- Max_Entry_Queue_Length --
         ----------------------------

         --  pragma Max_Entry_Queue_Length (static_integer_EXPRESSION);

         --  This processing is shared by Pragma_Max_Entry_Queue_Depth and
         --  Pragma_Max_Queue_Length.

         when Pragma_Max_Entry_Queue_Length
            | Pragma_Max_Entry_Queue_Depth
            | Pragma_Max_Queue_Length
         =>
         Max_Entry_Queue_Length : declare
            Arg        : Node_Id;
            Entry_Decl : Node_Id;
            Entry_Id   : Entity_Id;
            Val        : Uint;

         begin
            if Prag_Id = Pragma_Max_Entry_Queue_Depth
              or else Prag_Id = Pragma_Max_Queue_Length
            then
               GNAT_Pragma;
            end if;

            Check_Arg_Count (1);

            Entry_Decl :=
              Find_Related_Declaration_Or_Body (N, Do_Checks => True);

            --  Entry declaration

            if Nkind (Entry_Decl) = N_Entry_Declaration then

               --  Entry illegally within a task

               if Nkind (Parent (N)) = N_Task_Definition then
                  Error_Pragma ("pragma % cannot apply to task entries");
                  return;
               end if;

               Entry_Id := Defining_Entity (Entry_Decl);

            --  Otherwise the pragma is associated with an illegal construct

            else
               Error_Pragma
                 ("pragma % must apply to a protected entry declaration");
               return;
            end if;

            --  Mark the pragma as Ghost if the related subprogram is also
            --  Ghost. This also ensures that any expansion performed further
            --  below will produce Ghost nodes.

            Mark_Ghost_Pragma (N, Entry_Id);

            --  Analyze the Integer expression

            Arg := Get_Pragma_Arg (Arg1);
            Check_Arg_Is_OK_Static_Expression (Arg, Any_Integer);

            Val := Expr_Value (Arg);

            if Val < -1 then
               Error_Pragma_Arg
                 ("argument for pragma% cannot be less than -1", Arg1);

            elsif not UI_Is_In_Int_Range (Val) then
               Error_Pragma_Arg
                 ("argument for pragma% out of range of Integer", Arg1);

            end if;

            Record_Rep_Item (Entry_Id, N);
         end Max_Entry_Queue_Length;

         -----------------
         -- Memory_Size --
         -----------------

         --  pragma Memory_Size (NUMERIC_LITERAL)

         when Pragma_Memory_Size =>
            GNAT_Pragma;

            --  Memory size is simply ignored

            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Integer_Literal (Arg1);

         -------------
         -- No_Body --
         -------------

         --  pragma No_Body;

         --  The only correct use of this pragma is on its own in a file, in
         --  which case it is specially processed (see Gnat1drv.Check_Bad_Body
         --  and Frontend, which use Sinput.L.Source_File_Is_Pragma_No_Body to
         --  check for a file containing nothing but a No_Body pragma). If we
         --  attempt to process it during normal semantics processing, it means
         --  it was misplaced.

         when Pragma_No_Body =>
            GNAT_Pragma;
            Pragma_Misplaced;

         -----------------------------
         -- No_Elaboration_Code_All --
         -----------------------------

         --  pragma No_Elaboration_Code_All;

         when Pragma_No_Elaboration_Code_All =>
            GNAT_Pragma;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            --  Must appear for a spec or generic spec

            if Nkind (Unit (Cunit (Current_Sem_Unit))) not in
                 N_Generic_Package_Declaration    |
                 N_Generic_Subprogram_Declaration |
                 N_Package_Declaration            |
                 N_Subprogram_Declaration
            then
               Error_Pragma
                 (Fix_Error
                    ("pragma% can only occur for package "
                     & "or subprogram spec"));
            end if;

            --  Set flag in unit table

            Set_No_Elab_Code_All (Current_Sem_Unit);

            --  Set restriction No_Elaboration_Code if this is the main unit

            if Current_Sem_Unit = Main_Unit then
               Set_Restriction (No_Elaboration_Code, N);
            end if;

            --  If we are in the main unit or in an extended main source unit,
            --  then we also add it to the configuration restrictions so that
            --  it will apply to all units in the extended main source.

            if Current_Sem_Unit = Main_Unit
              or else In_Extended_Main_Source_Unit (N)
            then
               Add_To_Config_Boolean_Restrictions (No_Elaboration_Code);
            end if;

            --  If in main extended unit, activate transitive with test

            if In_Extended_Main_Source_Unit (N) then
               Opt.No_Elab_Code_All_Pragma := N;
            end if;

         -----------------------------
         -- No_Component_Reordering --
         -----------------------------

         --  pragma No_Component_Reordering [([Entity =>] type_LOCAL_NAME)];

         when Pragma_No_Component_Reordering => No_Comp_Reordering : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Most_N_Arguments (1);

            if Arg_Count = 0 then
               Check_Valid_Configuration_Pragma;
               Opt.No_Component_Reordering := True;

            else
               Check_Optional_Identifier (Arg2, Name_Entity);
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               E := Entity (E_Id);

               if not Is_Record_Type (E) then
                  Error_Pragma_Arg ("pragma% requires record type", Arg1);
               end if;

               Set_No_Reordering (Base_Type (E));
            end if;
         end No_Comp_Reordering;

         --------------------------
         -- No_Heap_Finalization --
         --------------------------

         --  pragma No_Heap_Finalization [ (first_subtype_LOCAL_NAME) ];

         when Pragma_No_Heap_Finalization => No_Heap_Finalization : declare
            Context : constant Node_Id := Parent (N);
            Typ_Arg : constant Node_Id := Get_Pragma_Arg (Arg1);
            Prev    : Node_Id;
            Typ     : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;

            --  The pragma appears in a configuration file

            if No (Context) then
               Check_Arg_Count (0);
               Check_Valid_Configuration_Pragma;

               --  Detect a duplicate pragma

               if Present (No_Heap_Finalization_Pragma) then
                  Duplication_Error
                    (Prag => N,
                     Prev => No_Heap_Finalization_Pragma);
                  raise Pragma_Exit;
               end if;

               No_Heap_Finalization_Pragma := N;

            --  Otherwise the pragma should be associated with a library-level
            --  named access-to-object type.

            else
               Check_Arg_Count (1);
               Check_Arg_Is_Local_Name (Arg1);

               Find_Type (Typ_Arg);
               Typ := Entity (Typ_Arg);

               --  The type being subjected to the pragma is erroneous

               if Typ = Any_Type then
                  Error_Pragma ("cannot find type referenced by pragma %");

               --  The pragma is applied to an incomplete or generic formal
               --  type way too early.

               elsif Rep_Item_Too_Early (Typ, N) then
                  return;

               else
                  Typ := Underlying_Type (Typ);
               end if;

               --  The pragma must apply to an access-to-object type

               if Ekind (Typ) in E_Access_Type | E_General_Access_Type then
                  null;

               --  Give a detailed error message on all other access type kinds

               elsif Ekind (Typ) = E_Access_Protected_Subprogram_Type then
                  Error_Pragma
                    ("pragma % cannot apply to access protected subprogram "
                     & "type");

               elsif Ekind (Typ) = E_Access_Subprogram_Type then
                  Error_Pragma
                    ("pragma % cannot apply to access subprogram type");

               elsif Is_Anonymous_Access_Type (Typ) then
                  Error_Pragma
                    ("pragma % cannot apply to anonymous access type");

               --  Give a general error message in case the pragma applies to a
               --  non-access type.

               else
                  Error_Pragma
                    ("pragma % must apply to library level access type");
               end if;

               --  At this point the argument denotes an access-to-object type.
               --  Ensure that the type is declared at the library level.

               if Is_Library_Level_Entity (Typ) then
                  null;

               --  Quietly ignore an access-to-object type originally declared
               --  at the library level within a generic, but instantiated at
               --  a non-library level. As a result the access-to-object type
               --  "loses" its No_Heap_Finalization property.

               elsif In_Instance then
                  raise Pragma_Exit;

               else
                  Error_Pragma
                    ("pragma % must apply to library level access type");
               end if;

               --  Detect a duplicate pragma

               if Present (No_Heap_Finalization_Pragma) then
                  Duplication_Error
                    (Prag => N,
                     Prev => No_Heap_Finalization_Pragma);
                  raise Pragma_Exit;

               else
                  Prev := Get_Pragma (Typ, Pragma_No_Heap_Finalization);

                  if Present (Prev) then
                     Duplication_Error
                       (Prag => N,
                        Prev => Prev);
                     raise Pragma_Exit;
                  end if;
               end if;

               Record_Rep_Item (Typ, N);
            end if;
         end No_Heap_Finalization;

         ---------------
         -- No_Inline --
         ---------------

         --  pragma No_Inline ( NAME {, NAME} );

         when Pragma_No_Inline =>
            GNAT_Pragma;
            Process_Inline (Suppressed);

         ---------------
         -- No_Return --
         ---------------

         --  pragma No_Return (procedure_LOCAL_NAME {, procedure_Local_Name});

         when Pragma_No_Return => Prag_No_Return : declare

            function Check_No_Return
               (E : Entity_Id;
                N : Node_Id) return Boolean;
            --  Check rule 6.5.1(4/3) of the Ada RM. If the rule is violated,
            --  emit an error message and return False, otherwise return True.
            --  6.5.1 Nonreturning procedures:
            --  4/3 "Aspect No_Return shall not be specified for a null
            --  procedure nor an instance of a generic unit."

            ---------------------
            -- Check_No_Return --
            ---------------------

            function Check_No_Return
               (E : Entity_Id;
                N : Node_Id) return Boolean
            is
            begin
               if Ekind (E) = E_Procedure then

                  --  If E is a generic instance, marking it with No_Return
                  --  is forbidden, but having it inherit the No_Return of
                  --  the generic is allowed. We check if E is inheriting its
                  --  No_Return flag from the generic by checking if No_Return
                  --  is already set.

                  if Is_Generic_Instance (E) and then not No_Return (E) then
                     Error_Msg_NE
                       ("generic instance & is marked as No_Return", N, E);
                     Error_Msg_NE
                       ("\generic procedure & must be marked No_Return",
                        N,
                        Generic_Parent (Parent (E)));
                     return False;

                  elsif Null_Present (Subprogram_Specification (E)) then
                     Error_Msg_NE
                       ("null procedure & cannot be marked No_Return", N, E);
                     return False;
                  end if;
               end if;

               return True;
            end Check_No_Return;

            Arg   : Node_Id;
            E     : Entity_Id;
            Found : Boolean;
            Id    : Node_Id;

            Ghost_Error_Posted : Boolean := False;
            --  Flag set when an error concerning the illegal mix of Ghost and
            --  non-Ghost subprograms is emitted.

            Ghost_Id : Entity_Id := Empty;
            --  The entity of the first Ghost procedure encountered while
            --  processing the arguments of the pragma.

         begin
            Ada_2005_Pragma;
            Check_At_Least_N_Arguments (1);

            --  Loop through arguments of pragma

            Arg := Arg1;
            while Present (Arg) loop
               Check_Arg_Is_Local_Name (Arg);
               Id := Get_Pragma_Arg (Arg);
               Analyze (Id);

               if not Is_Entity_Name (Id) then
                  Error_Pragma_Arg ("entity name required", Arg);
               end if;

               if Etype (Id) = Any_Type then
                  raise Pragma_Exit;
               end if;

               --  Loop to find matching procedures or functions (Ada 2022)

               E := Entity (Id);

               Found := False;
               while Present (E)
                 and then Scope (E) = Current_Scope
               loop
                  --  Ada 2022 (AI12-0269): A function can be No_Return

                  if Ekind (E) in E_Generic_Procedure | E_Procedure
                    or else (Ada_Version >= Ada_2022
                              and then
                             Ekind (E) in E_Generic_Function | E_Function)
                  then
                     --  Check that the pragma is not applied to a body.
                     --  First check the specless body case, to give a
                     --  different error message. These checks do not apply
                     --  if Relaxed_RM_Semantics, to accommodate other Ada
                     --  compilers. Disable these checks under -gnatd.J.

                     if not Debug_Flag_Dot_JJ then
                        if Nkind (Parent (Declaration_Node (E))) =
                            N_Subprogram_Body
                          and then not Relaxed_RM_Semantics
                        then
                           Error_Pragma
                             ("pragma% requires separate spec and must come "
                              & "before body");
                        end if;

                        --  Now the "specful" body case

                        if Rep_Item_Too_Late (E, N) then
                           raise Pragma_Exit;
                        end if;
                     end if;

                     if Check_No_Return (E, N) then
                        Set_No_Return (E);
                     end if;

                     --  A pragma that applies to a Ghost entity becomes Ghost
                     --  for the purposes of legality checks and removal of
                     --  ignored Ghost code.

                     Mark_Ghost_Pragma (N, E);

                     --  Capture the entity of the first Ghost procedure being
                     --  processed for error detection purposes.

                     if Is_Ghost_Entity (E) then
                        if No (Ghost_Id) then
                           Ghost_Id := E;
                        end if;

                     --  Otherwise the subprogram is non-Ghost. It is illegal
                     --  to mix references to Ghost and non-Ghost entities
                     --  (SPARK RM 6.9).

                     elsif Present (Ghost_Id)
                       and then not Ghost_Error_Posted
                     then
                        Ghost_Error_Posted := True;

                        Error_Msg_Name_1 := Pname;
                        Error_Msg_N
                          ("pragma % cannot mention ghost and non-ghost "
                           & "procedures", N);

                        Error_Msg_Sloc := Sloc (Ghost_Id);
                        Error_Msg_NE ("\& # declared as ghost", N, Ghost_Id);

                        Error_Msg_Sloc := Sloc (E);
                        Error_Msg_NE ("\& # declared as non-ghost", N, E);
                     end if;

                     --  Set flag on any alias as well

                     if Is_Overloadable (E)
                       and then Present (Alias (E))
                       and then Check_No_Return (Alias (E), N)
                     then
                        Set_No_Return (Alias (E));
                     end if;

                     Found := True;
                  end if;

                  exit when From_Aspect_Specification (N);
                  E := Homonym (E);
               end loop;

               --  If entity in not in current scope it may be the enclosing
               --  suprogram body to which the aspect applies.

               if not Found then
                  if Entity (Id) = Current_Scope
                    and then From_Aspect_Specification (N)
                    and then Check_No_Return (Entity (Id), N)
                  then
                     Set_No_Return (Entity (Id));

                  elsif Ada_Version >= Ada_2022 then
                     Error_Pragma_Arg
                       ("no subprogram& found for pragma%", Arg);

                  else
                     Error_Pragma_Arg ("no procedure& found for pragma%", Arg);
                  end if;
               end if;

               Next (Arg);
            end loop;
         end Prag_No_Return;

         -----------------
         -- No_Run_Time --
         -----------------

         --  pragma No_Run_Time;

         --  Note: this pragma is retained for backwards compatibility. See
         --  body of Rtsfind for full details on its handling.

         when Pragma_No_Run_Time =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (0);

            --  Remove backward compatibility if Build_Type is FSF or GPL and
            --  generate a warning.

            declare
               Ignore : constant Boolean := Build_Type in FSF .. GPL;
            begin
               if Ignore then
                  Error_Pragma ("pragma% is ignored, has no effect??");
               else
                  No_Run_Time_Mode           := True;
                  Configurable_Run_Time_Mode := True;

                  --  Set Duration to 32 bits if word size is 32

                  if Ttypes.System_Word_Size = 32 then
                     Duration_32_Bits_On_Target := True;
                  end if;

                  --  Set appropriate restrictions

                  Set_Restriction (No_Finalization, N);
                  Set_Restriction (No_Exception_Handlers, N);
                  Set_Restriction (Max_Tasks, N, 0);
                  Set_Restriction (No_Tasking, N);
               end if;
            end;

         -----------------------
         -- No_Tagged_Streams --
         -----------------------

         --  pragma No_Tagged_Streams [([Entity => ]tagged_type_local_NAME)];

         when Pragma_No_Tagged_Streams => No_Tagged_Strms : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Most_N_Arguments (1);

            --  One argument case

            if Arg_Count = 1 then
               Check_Optional_Identifier (Arg1, Name_Entity);
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               E := Entity (E_Id);

               Check_Duplicate_Pragma (E);

               if not Is_Tagged_Type (E) or else Is_Derived_Type (E) then
                  Error_Pragma_Arg
                    ("argument for pragma% must be root tagged type", Arg1);
               end if;

               if Rep_Item_Too_Early (E, N)
                    or else
                  Rep_Item_Too_Late (E, N)
               then
                  return;
               else
                  Set_No_Tagged_Streams_Pragma (E, N);
               end if;

            --  Zero argument case

            else
               Check_Is_In_Decl_Part_Or_Package_Spec;
               No_Tagged_Streams := N;
            end if;
         end No_Tagged_Strms;

         ------------------------
         -- No_Strict_Aliasing --
         ------------------------

         --  pragma No_Strict_Aliasing [([Entity =>] type_LOCAL_NAME)];

         when Pragma_No_Strict_Aliasing => No_Strict_Aliasing : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Most_N_Arguments (1);

            if Arg_Count = 0 then
               Check_Valid_Configuration_Pragma;
               Opt.No_Strict_Aliasing := True;

            else
               Check_Optional_Identifier (Arg2, Name_Entity);
               Check_Arg_Is_Local_Name (Arg1);
               E_Id := Get_Pragma_Arg (Arg1);

               if Etype (E_Id) = Any_Type then
                  return;
               end if;

               E := Entity (E_Id);

               if not Is_Access_Type (E) then
                  Error_Pragma_Arg ("pragma% requires access type", Arg1);
               end if;

               Set_No_Strict_Aliasing (Base_Type (E));
            end if;
         end No_Strict_Aliasing;

         -----------------------
         -- Normalize_Scalars --
         -----------------------

         --  pragma Normalize_Scalars;

         when Pragma_Normalize_Scalars =>
            Check_Ada_83_Warning;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;

            --  Normalize_Scalars creates false positives in CodePeer, and
            --  incorrect negative results in GNATprove mode, so ignore this
            --  pragma in these modes.

            if not (CodePeer_Mode or GNATprove_Mode) then
               Normalize_Scalars := True;
               Init_Or_Norm_Scalars := True;
            end if;

         -----------------
         -- Obsolescent --
         -----------------

         --  pragma Obsolescent;

         --  pragma Obsolescent (
         --    [Message =>] static_string_EXPRESSION
         --  [,[Version =>] Ada_05]]);

         --  pragma Obsolescent (
         --    [Entity  =>] NAME
         --  [,[Message =>] static_string_EXPRESSION
         --  [,[Version =>] Ada_05]] );

         when Pragma_Obsolescent => Obsolescent : declare
            Decl  : Node_Id;
            Ename : Node_Id;

            procedure Set_Obsolescent (E : Entity_Id);
            --  Given an entity Ent, mark it as obsolescent if appropriate

            ---------------------
            -- Set_Obsolescent --
            ---------------------

            procedure Set_Obsolescent (E : Entity_Id) is
               Active : Boolean;
               Ent    : Entity_Id;
               S      : String_Id;

            begin
               Active := True;
               Ent    := E;

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               Mark_Ghost_Pragma (N, E);

               --  Entity name was given

               if Present (Ename) then

                  --  If entity name matches, we are fine.

                  if Chars (Ename) = Chars (Ent) then
                     Set_Entity (Ename, Ent);
                     Generate_Reference (Ent, Ename);

                  --  If entity name does not match, only possibility is an
                  --  enumeration literal from an enumeration type declaration.

                  elsif Ekind (Ent) /= E_Enumeration_Type then
                     Error_Pragma
                       ("pragma % entity name does not match declaration");

                  else
                     Ent := First_Literal (E);
                     loop
                        if No (Ent) then
                           Error_Pragma
                             ("pragma % entity name does not match any "
                              & "enumeration literal");

                        elsif Chars (Ent) = Chars (Ename) then
                           Set_Entity (Ename, Ent);
                           Generate_Reference (Ent, Ename);
                           exit;

                        else
                           Next_Literal (Ent);
                        end if;
                     end loop;
                  end if;
               end if;

               --  Ent points to entity to be marked

               if Arg_Count >= 1 then

                  --  Deal with static string argument

                  Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);
                  S := Strval (Get_Pragma_Arg (Arg1));

                  for J in 1 .. String_Length (S) loop
                     if not In_Character_Range (Get_String_Char (S, J)) then
                        Error_Pragma_Arg
                          ("pragma% argument does not allow wide characters",
                           Arg1);
                     end if;
                  end loop;

                  Obsolescent_Warnings.Append
                    ((Ent => Ent, Msg => Strval (Get_Pragma_Arg (Arg1))));

                  --  Check for Ada_05 parameter

                  if Arg_Count /= 1 then
                     Check_Arg_Count (2);

                     declare
                        Argx : constant Node_Id := Get_Pragma_Arg (Arg2);

                     begin
                        Check_Arg_Is_Identifier (Argx);

                        if Chars (Argx) /= Name_Ada_05 then
                           Error_Msg_Name_2 := Name_Ada_05;
                           Error_Pragma_Arg
                             ("only allowed argument for pragma% is %", Argx);
                        end if;

                        if Ada_Version_Explicit < Ada_2005
                          or else not Warn_On_Ada_2005_Compatibility
                        then
                           Active := False;
                        end if;
                     end;
                  end if;
               end if;

               --  Set flag if pragma active

               if Active then
                  Set_Is_Obsolescent (Ent);
               end if;

               return;
            end Set_Obsolescent;

         --  Start of processing for pragma Obsolescent

         begin
            GNAT_Pragma;

            Check_At_Most_N_Arguments (3);

            --  See if first argument specifies an entity name

            if Arg_Count >= 1
              and then
                (Chars (Arg1) = Name_Entity
                   or else
                     Nkind (Get_Pragma_Arg (Arg1)) in
                       N_Character_Literal | N_Identifier | N_Operator_Symbol)
            then
               Ename := Get_Pragma_Arg (Arg1);

               --  Eliminate first argument, so we can share processing

               Arg1 := Arg2;
               Arg2 := Arg3;
               Arg_Count := Arg_Count - 1;

            --  No Entity name argument given

            else
               Ename := Empty;
            end if;

            if Arg_Count >= 1 then
               Check_Optional_Identifier (Arg1, Name_Message);

               if Arg_Count = 2 then
                  Check_Optional_Identifier (Arg2, Name_Version);
               end if;
            end if;

            --  Get immediately preceding declaration

            Decl := Prev (N);
            while Present (Decl) and then Nkind (Decl) = N_Pragma loop
               Prev (Decl);
            end loop;

            --  Cases where we do not follow anything other than another pragma

            if No (Decl) then

               --  First case: library level compilation unit declaration with
               --  the pragma immediately following the declaration.

               if Nkind (Parent (N)) = N_Compilation_Unit_Aux then
                  Set_Obsolescent
                    (Defining_Entity (Unit (Parent (Parent (N)))));
                  return;

               --  Case 2: library unit placement for package

               else
                  declare
                     Ent : constant Entity_Id := Find_Lib_Unit_Name;
                  begin
                     if Is_Package_Or_Generic_Package (Ent) then
                        Set_Obsolescent (Ent);
                        return;
                     end if;
                  end;
               end if;

            --  Cases where we must follow a declaration, including an
            --  abstract subprogram declaration, which is not in the
            --  other node subtypes.

            else
               if         Nkind (Decl) not in N_Declaration
                 and then Nkind (Decl) not in N_Later_Decl_Item
                 and then Nkind (Decl) not in N_Generic_Declaration
                 and then Nkind (Decl) not in N_Renaming_Declaration
                 and then Nkind (Decl) /= N_Abstract_Subprogram_Declaration
               then
                  Error_Pragma
                    ("pragma% misplaced, "
                     & "must immediately follow a declaration");

               else
                  Set_Obsolescent (Defining_Entity (Decl));
                  return;
               end if;
            end if;
         end Obsolescent;

         --------------
         -- Optimize --
         --------------

         --  pragma Optimize (Time | Space | Off);

         --  The actual check for optimize is done in Gigi. Note that this
         --  pragma does not actually change the optimization setting, it
         --  simply checks that it is consistent with the pragma.

         when Pragma_Optimize =>
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_One_Of (Arg1, Name_Time, Name_Space, Name_Off);

         ------------------------
         -- Optimize_Alignment --
         ------------------------

         --  pragma Optimize_Alignment (Time | Space | Off);

         when Pragma_Optimize_Alignment => Optimize_Alignment : begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Valid_Configuration_Pragma;

            declare
               Nam : constant Name_Id := Chars (Get_Pragma_Arg (Arg1));
            begin
               case Nam is
                  when Name_Off   => Opt.Optimize_Alignment := 'O';
                  when Name_Space => Opt.Optimize_Alignment := 'S';
                  when Name_Time  => Opt.Optimize_Alignment := 'T';

                  when others =>
                     Error_Pragma_Arg ("invalid argument for pragma%", Arg1);
               end case;
            end;

            --  Set indication that mode is set locally. If we are in fact in a
            --  configuration pragma file, this setting is harmless since the
            --  switch will get reset anyway at the start of each unit.

            Optimize_Alignment_Local := True;
         end Optimize_Alignment;

         -------------
         -- Ordered --
         -------------

         --  pragma Ordered (first_enumeration_subtype_LOCAL_NAME);

         when Pragma_Ordered => Ordered : declare
            Assoc   : constant Node_Id := Arg1;
            Type_Id : Node_Id;
            Typ     : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);

            Type_Id := Get_Pragma_Arg (Assoc);
            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type then
               return;
            else
               Typ := Underlying_Type (Typ);
            end if;

            if not Is_Enumeration_Type (Typ) then
               Error_Pragma ("pragma% must specify enumeration type");
            end if;

            Check_First_Subtype (Arg1);
            Set_Has_Pragma_Ordered (Base_Type (Typ));
         end Ordered;

         -------------------
         -- Overflow_Mode --
         -------------------

         --  pragma Overflow_Mode
         --    ([General => ] MODE [, [Assertions => ] MODE]);

         --  MODE := STRICT | MINIMIZED | ELIMINATED

         --  Note: ELIMINATED is allowed only if Long_Long_Integer'Size is 64
         --  since System.Bignums makes this assumption. This is true of nearly
         --  all (all?) targets.

         when Pragma_Overflow_Mode => Overflow_Mode : declare
            function Get_Overflow_Mode
              (Name : Name_Id;
               Arg  : Node_Id) return Overflow_Mode_Type;
            --  Function to process one pragma argument, Arg. If an identifier
            --  is present, it must be Name. Mode type is returned if a valid
            --  argument exists, otherwise an error is signalled.

            -----------------------
            -- Get_Overflow_Mode --
            -----------------------

            function Get_Overflow_Mode
              (Name : Name_Id;
               Arg  : Node_Id) return Overflow_Mode_Type
            is
               Argx : constant Node_Id := Get_Pragma_Arg (Arg);

            begin
               Check_Optional_Identifier (Arg, Name);
               Check_Arg_Is_Identifier (Argx);

               if Chars (Argx) = Name_Strict then
                  return Strict;

               elsif Chars (Argx) = Name_Minimized then
                  return Minimized;

               elsif Chars (Argx) = Name_Eliminated then
                  if Ttypes.Standard_Long_Long_Integer_Size /= 64 then
                     Error_Pragma_Arg
                       ("Eliminated requires Long_Long_Integer'Size = 64",
                        Argx);
                  else
                     return Eliminated;
                  end if;

               else
                  Error_Pragma_Arg ("invalid argument for pragma%", Argx);
               end if;
            end Get_Overflow_Mode;

         --  Start of processing for Overflow_Mode

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);
            Check_At_Most_N_Arguments  (2);

            --  Process first argument

            Scope_Suppress.Overflow_Mode_General :=
              Get_Overflow_Mode (Name_General, Arg1);

            --  Case of only one argument

            if Arg_Count = 1 then
               Scope_Suppress.Overflow_Mode_Assertions :=
                 Scope_Suppress.Overflow_Mode_General;

            --  Case of two arguments present

            else
               Scope_Suppress.Overflow_Mode_Assertions  :=
                 Get_Overflow_Mode (Name_Assertions, Arg2);
            end if;
         end Overflow_Mode;

         --------------------------
         -- Overriding Renamings --
         --------------------------

         --  pragma Overriding_Renamings;

         when Pragma_Overriding_Renamings =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Overriding_Renamings := True;

         ----------
         -- Pack --
         ----------

         --  pragma Pack (first_subtype_LOCAL_NAME);

         when Pragma_Pack => Pack : declare
            Assoc   : constant Node_Id := Arg1;
            Ctyp    : Entity_Id;
            Ignore  : Boolean := False;
            Typ     : Entity_Id;
            Type_Id : Node_Id;

         begin
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);
            Type_Id := Get_Pragma_Arg (Assoc);

            if not Is_Entity_Name (Type_Id)
              or else not Is_Type (Entity (Type_Id))
            then
               Error_Pragma_Arg
                 ("argument for pragma% must be type or subtype", Arg1);
            end if;

            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type
              or else Rep_Item_Too_Early (Typ, N)
            then
               return;
            else
               Typ := Underlying_Type (Typ);
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            if not Is_Array_Type (Typ) and then not Is_Record_Type (Typ) then
               Error_Pragma ("pragma% must specify array or record type");
            end if;

            Check_First_Subtype (Arg1);
            Check_Duplicate_Pragma (Typ);

            --  Array type

            if Is_Array_Type (Typ) then
               Ctyp := Component_Type (Typ);

               --  Ignore pack that does nothing

               if Known_Static_Esize (Ctyp)
                 and then Known_Static_RM_Size (Ctyp)
                 and then Esize (Ctyp) = RM_Size (Ctyp)
                 and then Addressable (Esize (Ctyp))
               then
                  Ignore := True;
               end if;

               --  Process OK pragma Pack. Note that if there is a separate
               --  component clause present, the Pack will be cancelled. This
               --  processing is in Freeze.

               if not Rep_Item_Too_Late (Typ, N) then

                  --  In CodePeer mode, we do not need complex front-end
                  --  expansions related to pragma Pack, so disable handling
                  --  of pragma Pack.

                  if CodePeer_Mode then
                     null;

                  --  Normal case where we do the pack action

                  else
                     if not Ignore then
                        Set_Is_Packed            (Base_Type (Typ));
                        Set_Has_Non_Standard_Rep (Base_Type (Typ));
                     end if;

                     Set_Has_Pragma_Pack (Base_Type (Typ));
                  end if;
               end if;

            --  For record types, the pack is always effective

            else pragma Assert (Is_Record_Type (Typ));
               if not Rep_Item_Too_Late (Typ, N) then
                  Set_Is_Packed            (Base_Type (Typ));
                  Set_Has_Pragma_Pack      (Base_Type (Typ));
                  Set_Has_Non_Standard_Rep (Base_Type (Typ));
               end if;
            end if;
         end Pack;

         ----------
         -- Page --
         ----------

         --  pragma Page;

         --  There is nothing to do here, since we did all the processing for
         --  this pragma in Par.Prag (so that it works properly even in syntax
         --  only mode).

         when Pragma_Page =>
            null;

         -------------
         -- Part_Of --
         -------------

         --  pragma Part_Of (ABSTRACT_STATE);

         --  ABSTRACT_STATE ::= NAME

         when Pragma_Part_Of => Part_Of : declare
            procedure Propagate_Part_Of
              (Pack_Id  : Entity_Id;
               State_Id : Entity_Id;
               Instance : Node_Id);
            --  Propagate the Part_Of indicator to all abstract states and
            --  objects declared in the visible state space of a package
            --  denoted by Pack_Id. State_Id is the encapsulating state.
            --  Instance is the package instantiation node.

            -----------------------
            -- Propagate_Part_Of --
            -----------------------

            procedure Propagate_Part_Of
              (Pack_Id  : Entity_Id;
               State_Id : Entity_Id;
               Instance : Node_Id)
            is
               Has_Item : Boolean := False;
               --  Flag set when the visible state space contains at least one
               --  abstract state or variable.

               procedure Propagate_Part_Of (Pack_Id : Entity_Id);
               --  Propagate the Part_Of indicator to all abstract states and
               --  objects declared in the visible state space of a package
               --  denoted by Pack_Id.

               -----------------------
               -- Propagate_Part_Of --
               -----------------------

               procedure Propagate_Part_Of (Pack_Id : Entity_Id) is
                  Constits : Elist_Id;
                  Item_Id  : Entity_Id;

               begin
                  --  Traverse the entity chain of the package and set relevant
                  --  attributes of abstract states and objects declared in the
                  --  visible state space of the package.

                  Item_Id := First_Entity (Pack_Id);
                  while Present (Item_Id)
                    and then not In_Private_Part (Item_Id)
                  loop
                     --  Do not consider internally generated items

                     if not Comes_From_Source (Item_Id) then
                        null;

                     --  Do not consider generic formals or their corresponding
                     --  actuals because they are not part of a visible state.
                     --  Note that both entities are marked as hidden.

                     elsif Is_Hidden (Item_Id) then
                        null;

                     --  The Part_Of indicator turns an abstract state or an
                     --  object into a constituent of the encapsulating state.
                     --  Note that constants are considered here even though
                     --  they may not depend on variable input. This check is
                     --  left to the SPARK prover.

                     elsif Ekind (Item_Id) in
                             E_Abstract_State | E_Constant | E_Variable
                     then
                        Has_Item := True;
                        Constits := Part_Of_Constituents (State_Id);

                        if No (Constits) then
                           Constits := New_Elmt_List;
                           Set_Part_Of_Constituents (State_Id, Constits);
                        end if;

                        Append_Elmt (Item_Id, Constits);
                        Set_Encapsulating_State (Item_Id, State_Id);

                     --  Recursively handle nested packages and instantiations

                     elsif Ekind (Item_Id) = E_Package then
                        Propagate_Part_Of (Item_Id);
                     end if;

                     Next_Entity (Item_Id);
                  end loop;
               end Propagate_Part_Of;

            --  Start of processing for Propagate_Part_Of

            begin
               Propagate_Part_Of (Pack_Id);

               --  Detect a package instantiation that is subject to a Part_Of
               --  indicator, but has no visible state.

               if not Has_Item then
                  SPARK_Msg_NE
                    ("package instantiation & has Part_Of indicator but "
                     & "lacks visible state", Instance, Pack_Id);
               end if;
            end Propagate_Part_Of;

            --  Local variables

            Constits : Elist_Id;
            Encap    : Node_Id;
            Encap_Id : Entity_Id;
            Item_Id  : Entity_Id;
            Legal    : Boolean;
            Stmt     : Node_Id;

         --  Start of processing for Part_Of

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Stmt := Find_Related_Context (N, Do_Checks => True);

            --  Object declaration

            if Nkind (Stmt) = N_Object_Declaration then
               null;

            --  Package instantiation

            elsif Nkind (Stmt) = N_Package_Instantiation then
               null;

            --  Single concurrent type declaration

            elsif Is_Single_Concurrent_Type_Declaration (Stmt) then
               null;

            --  Otherwise the pragma is associated with an illegal construct

            else
               Pragma_Misplaced;
               return;
            end if;

            --  Extract the entity of the related object declaration or package
            --  instantiation. In the case of the instantiation, use the entity
            --  of the instance spec.

            if Nkind (Stmt) = N_Package_Instantiation then
               Stmt := Instance_Spec (Stmt);
            end if;

            Item_Id := Defining_Entity (Stmt);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Item_Id);

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Part_Of_In_Decl_Part or for completeness.

            Add_Contract_Item (N, Item_Id);

            --  A variable may act as constituent of a single concurrent type
            --  which in turn could be declared after the variable. Due to this
            --  discrepancy, the full analysis of indicator Part_Of is delayed
            --  until the end of the enclosing declarative region (see routine
            --  Analyze_Part_Of_In_Decl_Part).

            if Ekind (Item_Id) = E_Variable then
               null;

            --  Otherwise indicator Part_Of applies to a constant or a package
            --  instantiation.

            else
               Encap := Get_Pragma_Arg (Arg1);

               --  Detect any discrepancies between the placement of the
               --  constant or package instantiation with respect to state
               --  space and the encapsulating state.

               Analyze_Part_Of
                 (Indic    => N,
                  Item_Id  => Item_Id,
                  Encap    => Encap,
                  Encap_Id => Encap_Id,
                  Legal    => Legal);

               if Legal then
                  pragma Assert (Present (Encap_Id));

                  if Ekind (Item_Id) = E_Constant then
                     Constits := Part_Of_Constituents (Encap_Id);

                     if No (Constits) then
                        Constits := New_Elmt_List;
                        Set_Part_Of_Constituents (Encap_Id, Constits);
                     end if;

                     Append_Elmt (Item_Id, Constits);
                     Set_Encapsulating_State (Item_Id, Encap_Id);

                  --  Propagate the Part_Of indicator to the visible state
                  --  space of the package instantiation.

                  else
                     Propagate_Part_Of
                       (Pack_Id  => Item_Id,
                        State_Id => Encap_Id,
                        Instance => Stmt);
                  end if;
               end if;
            end if;
         end Part_Of;

         ----------------------------------
         -- Partition_Elaboration_Policy --
         ----------------------------------

         --  pragma Partition_Elaboration_Policy (policy_IDENTIFIER);

         when Pragma_Partition_Elaboration_Policy => PEP : declare
            subtype PEP_Range is Name_Id
              range First_Partition_Elaboration_Policy_Name
                 .. Last_Partition_Elaboration_Policy_Name;
            PEP_Val : PEP_Range;
            PEP     : Character;

         begin
            Ada_2005_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Partition_Elaboration_Policy (Arg1);
            Check_Valid_Configuration_Pragma;
            PEP_Val := Chars (Get_Pragma_Arg (Arg1));

            case PEP_Val is
               when Name_Concurrent => PEP := 'C';
               when Name_Sequential => PEP := 'S';
            end case;

            if Partition_Elaboration_Policy /= ' '
              and then Partition_Elaboration_Policy /= PEP
            then
               Error_Msg_Sloc := Partition_Elaboration_Policy_Sloc;
               Error_Pragma
                 ("partition elaboration policy incompatible with policy#");

            --  Set new policy, but always preserve System_Location since we
            --  like the error message with the run time name.

            else
               Partition_Elaboration_Policy := PEP;

               if Partition_Elaboration_Policy_Sloc /= System_Location then
                  Partition_Elaboration_Policy_Sloc := Loc;
               end if;
            end if;
         end PEP;

         -------------
         -- Passive --
         -------------

         --  pragma Passive [(PASSIVE_FORM)];

         --  PASSIVE_FORM ::= Semaphore | No

         when Pragma_Passive =>
            GNAT_Pragma;

            if Nkind (Parent (N)) /= N_Task_Definition then
               Error_Pragma ("pragma% must be within task definition");
            end if;

            if Arg_Count /= 0 then
               Check_Arg_Count (1);
               Check_Arg_Is_One_Of (Arg1, Name_Semaphore, Name_No);
            end if;

         ----------------------------------
         -- Preelaborable_Initialization --
         ----------------------------------

         --  pragma Preelaborable_Initialization (DIRECT_NAME);

         when Pragma_Preelaborable_Initialization => Preelab_Init : declare
            Ent : Entity_Id;

         begin
            Ada_2005_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Identifier (Arg1);
            Check_Arg_Is_Local_Name (Arg1);
            Check_First_Subtype (Arg1);
            Ent := Entity (Get_Pragma_Arg (Arg1));

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Ent);

            --  The pragma may come from an aspect on a private declaration,
            --  even if the freeze point at which this is analyzed in the
            --  private part after the full view.

            if Has_Private_Declaration (Ent)
              and then From_Aspect_Specification (N)
            then
               null;

            --  Check appropriate type argument

            elsif Is_Private_Type (Ent)
              or else Is_Protected_Type (Ent)
              or else (Is_Generic_Type (Ent) and then Is_Derived_Type (Ent))

              --  AI05-0028: The pragma applies to all composite types. Note
              --  that we apply this binding interpretation to earlier versions
              --  of Ada, so there is no Ada 2012 guard. Seems a reasonable
              --  choice since there are other compilers that do the same.

              or else Is_Composite_Type (Ent)
            then
               null;

            else
               Error_Pragma_Arg
                 ("pragma % can only be applied to private, formal derived, "
                  & "protected, or composite type", Arg1);
            end if;

            --  Give an error if the pragma is applied to a protected type that
            --  does not qualify (due to having entries, or due to components
            --  that do not qualify).

            if Is_Protected_Type (Ent)
              and then not Has_Preelaborable_Initialization (Ent)
            then
               Error_Msg_N
                 ("protected type & does not have preelaborable "
                  & "initialization", Ent);

            --  Otherwise mark the type as definitely having preelaborable
            --  initialization.

            else
               Set_Known_To_Have_Preelab_Init (Ent);
            end if;

            if Has_Pragma_Preelab_Init (Ent)
              and then Warn_On_Redundant_Constructs
            then
               Error_Pragma ("?r?duplicate pragma%!");
            else
               Set_Has_Pragma_Preelab_Init (Ent);
            end if;
         end Preelab_Init;

         --------------------
         -- Persistent_BSS --
         --------------------

         --  pragma Persistent_BSS [(object_NAME)];

         when Pragma_Persistent_BSS => Persistent_BSS :  declare
            Decl : Node_Id;
            Ent  : Entity_Id;
            Prag : Node_Id;

         begin
            GNAT_Pragma;
            Check_At_Most_N_Arguments (1);

            --  Case of application to specific object (one argument)

            if Arg_Count = 1 then
               Check_Arg_Is_Library_Level_Local_Name (Arg1);

               if not Is_Entity_Name (Get_Pragma_Arg (Arg1))
                 or else
                   Ekind (Entity (Get_Pragma_Arg (Arg1))) not in
                     E_Variable | E_Constant
               then
                  Error_Pragma_Arg ("pragma% only applies to objects", Arg1);
               end if;

               Ent := Entity (Get_Pragma_Arg (Arg1));

               --  A pragma that applies to a Ghost entity becomes Ghost for
               --  the purposes of legality checks and removal of ignored Ghost
               --  code.

               Mark_Ghost_Pragma (N, Ent);

               --  Check for duplication before inserting in list of
               --  representation items.

               Check_Duplicate_Pragma (Ent);

               if Rep_Item_Too_Late (Ent, N) then
                  return;
               end if;

               Decl := Parent (Ent);

               if Present (Expression (Decl)) then
                  --  Variables in Persistent_BSS cannot be initialized, so
                  --  turn off any initialization that might be caused by
                  --  pragmas Initialize_Scalars or Normalize_Scalars.

                  if Kill_Range_Check (Expression (Decl)) then
                     Prag :=
                       Make_Pragma (Loc,
                         Name_Suppress_Initialization,
                         Pragma_Argument_Associations => New_List (
                           Make_Pragma_Argument_Association (Loc,
                             Expression => New_Occurrence_Of (Ent, Loc))));
                     Insert_Before (N, Prag);
                     Analyze (Prag);

                  else
                     Error_Pragma_Arg
                       ("object for pragma% cannot have initialization", Arg1);
                  end if;
               end if;

               if not Is_Potentially_Persistent_Type (Etype (Ent)) then
                  Error_Pragma_Arg
                    ("object type for pragma% is not potentially persistent",
                     Arg1);
               end if;

               Prag :=
                 Make_Linker_Section_Pragma
                   (Ent, Loc, ".persistent.bss");
               Insert_After (N, Prag);
               Analyze (Prag);

            --  Case of use as configuration pragma with no arguments

            else
               Check_Valid_Configuration_Pragma;
               Persistent_BSS_Mode := True;
            end if;
         end Persistent_BSS;

         --------------------
         -- Rename_Pragma --
         --------------------

         --  pragma Rename_Pragma (
         --           [New_Name =>] IDENTIFIER,
         --           [Renamed  =>] pragma_IDENTIFIER);

         when Pragma_Rename_Pragma => Rename_Pragma : declare
            New_Name : constant Node_Id := Get_Pragma_Arg (Arg1);
            Old_Name : constant Node_Id := Get_Pragma_Arg (Arg2);

         begin
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_New_Name);
            Check_Optional_Identifier (Arg2, Name_Renamed);

            if Nkind (New_Name) /= N_Identifier then
               Error_Pragma_Arg ("identifier expected", Arg1);
            end if;

            if Nkind (Old_Name) /= N_Identifier then
               Error_Pragma_Arg ("identifier expected", Arg2);
            end if;

            --  The New_Name arg should not be an existing pragma (but we allow
            --  it; it's just a warning). The Old_Name arg must be an existing
            --  pragma.

            if Is_Pragma_Name (Chars (New_Name)) then
               Error_Pragma_Arg ("??pragma is already defined", Arg1);
            end if;

            if not Is_Pragma_Name (Chars (Old_Name)) then
               Error_Pragma_Arg ("existing pragma name expected", Arg1);
            end if;

            Map_Pragma_Name (From => Chars (New_Name), To => Chars (Old_Name));
         end Rename_Pragma;

         -----------------------------------
         -- Post/Post_Class/Postcondition --
         -----------------------------------

         --  pragma Post (Boolean_EXPRESSION);
         --  pragma Post_Class (Boolean_EXPRESSION);
         --  pragma Postcondition ([Check   =>] Boolean_EXPRESSION
         --                      [,[Message =>] String_EXPRESSION]);

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expression in:

         --       Analyze_Pre_Post_Condition_In_Decl_Part

         --    * Expansion - The annotation is expanded during the expansion of
         --    the related subprogram [body] contract as performed in:

         --       Expand_Subprogram_Contract

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Post
            | Pragma_Post_Class
            | Pragma_Postcondition
         =>
            Analyze_Pre_Post_Condition;

         --------------------------------
         -- Pre/Pre_Class/Precondition --
         --------------------------------

         --  pragma Pre (Boolean_EXPRESSION);
         --  pragma Pre_Class (Boolean_EXPRESSION);
         --  pragma Precondition ([Check   =>] Boolean_EXPRESSION
         --                     [,[Message =>] String_EXPRESSION]);

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expression in:

         --       Analyze_Pre_Post_Condition_In_Decl_Part

         --    * Expansion - The annotation is expanded during the expansion of
         --    the related subprogram [body] contract as performed in:

         --       Expand_Subprogram_Contract

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Pre
            | Pragma_Pre_Class
            | Pragma_Precondition
         =>
            Analyze_Pre_Post_Condition;

         ---------------
         -- Predicate --
         ---------------

         --  pragma Predicate
         --    ([Entity =>] type_LOCAL_NAME,
         --     [Check  =>] boolean_EXPRESSION);

         when Pragma_Predicate => Predicate : declare
            Discard : Boolean;
            Typ     : Entity_Id;
            Type_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Check);

            Check_Arg_Is_Local_Name (Arg1);

            Type_Id := Get_Pragma_Arg (Arg1);
            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type then
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  The remaining processing is simply to link the pragma on to
            --  the rep item chain, for processing when the type is frozen.
            --  This is accomplished by a call to Rep_Item_Too_Late. We also
            --  mark the type as having predicates.

            --  If the current policy for predicate checking is Ignore mark the
            --  subtype accordingly. In the case of predicates we consider them
            --  enabled unless Ignore is specified (either directly or with a
            --  general Assertion_Policy pragma) to preserve existing warnings.

            Set_Has_Predicates (Typ);

            --  Indicate that the pragma must be processed at the point the
            --  type is frozen, as is done for the corresponding aspect.

            Set_Has_Delayed_Aspects (Typ);
            Set_Has_Delayed_Freeze (Typ);

            Set_Predicates_Ignored (Typ,
              Policy_In_Effect (Name_Dynamic_Predicate) = Name_Ignore);
            Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);
         end Predicate;

         -----------------------
         -- Predicate_Failure --
         -----------------------

         --  pragma Predicate_Failure
         --    ([Entity  =>] type_LOCAL_NAME,
         --     [Message =>] string_EXPRESSION);

         when Pragma_Predicate_Failure => Predicate_Failure : declare
            Discard : Boolean;
            Typ     : Entity_Id;
            Type_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (2);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Message);

            Check_Arg_Is_Local_Name (Arg1);

            Type_Id := Get_Pragma_Arg (Arg1);
            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type then
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  The remaining processing is simply to link the pragma on to
            --  the rep item chain, for processing when the type is frozen.
            --  This is accomplished by a call to Rep_Item_Too_Late.

            Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);
         end Predicate_Failure;

         ------------------
         -- Preelaborate --
         ------------------

         --  pragma Preelaborate [(library_unit_NAME)];

         --  Set the flag Is_Preelaborated of program unit name entity

         when Pragma_Preelaborate => Preelaborate : declare
            Pa  : constant Node_Id   := Parent (N);
            Pk  : constant Node_Kind := Nkind (Pa);
            Ent : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Ent := Find_Lib_Unit_Name;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Ent);
            Check_Duplicate_Pragma (Ent);

            --  This filters out pragmas inside generic parents that show up
            --  inside instantiations. Pragmas that come from aspects in the
            --  unit are not ignored.

            if Present (Ent) then
               if Pk = N_Package_Specification
                 and then Present (Generic_Parent (Pa))
                 and then not From_Aspect_Specification (N)
               then
                  null;

               else
                  if not Debug_Flag_U then
                     Set_Is_Preelaborated (Ent);

                     if Legacy_Elaboration_Checks then
                        Set_Suppress_Elaboration_Warnings (Ent);
                     end if;
                  end if;
               end if;
            end if;
         end Preelaborate;

         -------------------------------
         -- Prefix_Exception_Messages --
         -------------------------------

         --  pragma Prefix_Exception_Messages;

         when Pragma_Prefix_Exception_Messages =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;
            Check_Arg_Count (0);
            Prefix_Exception_Messages := True;

         --------------
         -- Priority --
         --------------

         --  pragma Priority (EXPRESSION);

         when Pragma_Priority => Priority : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            Check_No_Identifiers;
            Check_Arg_Count (1);

            --  Subprogram case

            if Nkind (P) = N_Subprogram_Body then
               Check_In_Main_Program;

               Ent := Defining_Unit_Name (Specification (P));

               if Nkind (Ent) = N_Defining_Program_Unit_Name then
                  Ent := Defining_Identifier (Ent);
               end if;

               Arg := Get_Pragma_Arg (Arg1);
               Analyze_And_Resolve (Arg, Standard_Integer);

               --  Must be static

               if not Is_OK_Static_Expression (Arg) then
                  Flag_Non_Static_Expr
                    ("main subprogram priority is not static!", Arg);
                  raise Pragma_Exit;

               --  If constraint error, then we already signalled an error

               elsif Raises_Constraint_Error (Arg) then
                  null;

               --  Otherwise check in range except if Relaxed_RM_Semantics
               --  where we ignore the value if out of range.

               else
                  if not Relaxed_RM_Semantics
                    and then not Is_In_Range (Arg, RTE (RE_Priority))
                  then
                     Error_Pragma_Arg
                       ("main subprogram priority is out of range", Arg1);
                  else
                     Set_Main_Priority
                       (Current_Sem_Unit, UI_To_Int (Expr_Value (Arg)));
                  end if;
               end if;

               --  Load an arbitrary entity from System.Tasking.Stages or
               --  System.Tasking.Restricted.Stages (depending on the
               --  supported profile) to make sure that one of these packages
               --  is implicitly with'ed, since we need to have the tasking
               --  run time active for the pragma Priority to have any effect.
               --  Previously we with'ed the package System.Tasking, but this
               --  package does not trigger the required initialization of the
               --  run-time library.

               if Restricted_Profile then
                  Discard_Node (RTE (RE_Activate_Restricted_Tasks));
               else
                  Discard_Node (RTE (RE_Activate_Tasks));
               end if;

            --  Task or Protected, must be of type Integer

            elsif Nkind (P) in N_Protected_Definition | N_Task_Definition then
               Arg := Get_Pragma_Arg (Arg1);
               Ent := Defining_Identifier (Parent (P));

               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default and Per-Object
               --  Expressions" in sem.ads.

               Preanalyze_Spec_Expression (Arg, RTE (RE_Any_Priority));

               if not Is_OK_Static_Expression (Arg) then
                  Check_Restriction (Static_Priorities, Arg);
               end if;

            --  Anything else is incorrect

            else
               Pragma_Misplaced;
            end if;

            --  Check duplicate pragma before we chain the pragma in the Rep
            --  Item chain of Ent.

            Check_Duplicate_Pragma (Ent);
            Record_Rep_Item (Ent, N);
         end Priority;

         -----------------------------------
         -- Priority_Specific_Dispatching --
         -----------------------------------

         --  pragma Priority_Specific_Dispatching (
         --    policy_IDENTIFIER,
         --    first_priority_EXPRESSION,
         --    last_priority_EXPRESSION);

         when Pragma_Priority_Specific_Dispatching =>
         Priority_Specific_Dispatching : declare
            Prio_Id : constant Entity_Id := RTE (RE_Any_Priority);
            --  This is the entity System.Any_Priority;

            DP          : Character;
            Lower_Bound : Node_Id;
            Upper_Bound : Node_Id;
            Lower_Val   : Uint;
            Upper_Val   : Uint;

         begin
            Ada_2005_Pragma;
            Check_Arg_Count (3);
            Check_No_Identifiers;
            Check_Arg_Is_Task_Dispatching_Policy (Arg1);
            Check_Valid_Configuration_Pragma;
            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
            DP := Fold_Upper (Name_Buffer (1));

            Lower_Bound := Get_Pragma_Arg (Arg2);
            Check_Arg_Is_OK_Static_Expression (Lower_Bound, Standard_Integer);
            Lower_Val := Expr_Value (Lower_Bound);

            Upper_Bound := Get_Pragma_Arg (Arg3);
            Check_Arg_Is_OK_Static_Expression (Upper_Bound, Standard_Integer);
            Upper_Val := Expr_Value (Upper_Bound);

            --  It is not allowed to use Task_Dispatching_Policy and
            --  Priority_Specific_Dispatching in the same partition.

            if Task_Dispatching_Policy /= ' ' then
               Error_Msg_Sloc := Task_Dispatching_Policy_Sloc;
               Error_Pragma
                 ("pragma% incompatible with Task_Dispatching_Policy#");

            --  Check lower bound in range

            elsif Lower_Val < Expr_Value (Type_Low_Bound (Prio_Id))
                    or else
                  Lower_Val > Expr_Value (Type_High_Bound (Prio_Id))
            then
               Error_Pragma_Arg
                 ("first_priority is out of range", Arg2);

            --  Check upper bound in range

            elsif Upper_Val < Expr_Value (Type_Low_Bound (Prio_Id))
                    or else
                  Upper_Val > Expr_Value (Type_High_Bound (Prio_Id))
            then
               Error_Pragma_Arg
                 ("last_priority is out of range", Arg3);

            --  Check that the priority range is valid

            elsif Lower_Val > Upper_Val then
               Error_Pragma
                 ("last_priority_expression must be greater than or equal to "
                  & "first_priority_expression");

            --  Store the new policy, but always preserve System_Location since
            --  we like the error message with the run-time name.

            else
               --  Check overlapping in the priority ranges specified in other
               --  Priority_Specific_Dispatching pragmas within the same
               --  partition. We can only check those we know about.

               for J in
                  Specific_Dispatching.First .. Specific_Dispatching.Last
               loop
                  if Specific_Dispatching.Table (J).First_Priority in
                    UI_To_Int (Lower_Val) .. UI_To_Int (Upper_Val)
                  or else Specific_Dispatching.Table (J).Last_Priority in
                    UI_To_Int (Lower_Val) .. UI_To_Int (Upper_Val)
                  then
                     Error_Msg_Sloc :=
                       Specific_Dispatching.Table (J).Pragma_Loc;
                        Error_Pragma
                          ("priority range overlaps with "
                           & "Priority_Specific_Dispatching#");
                  end if;
               end loop;

               --  The use of Priority_Specific_Dispatching is incompatible
               --  with Task_Dispatching_Policy.

               if Task_Dispatching_Policy /= ' ' then
                  Error_Msg_Sloc := Task_Dispatching_Policy_Sloc;
                     Error_Pragma
                       ("Priority_Specific_Dispatching incompatible "
                        & "with Task_Dispatching_Policy#");
               end if;

               --  The use of Priority_Specific_Dispatching forces ceiling
               --  locking policy.

               if Locking_Policy /= ' ' and then Locking_Policy /= 'C' then
                  Error_Msg_Sloc := Locking_Policy_Sloc;
                     Error_Pragma
                       ("Priority_Specific_Dispatching incompatible "
                        & "with Locking_Policy#");

               --  Set the Ceiling_Locking policy, but preserve System_Location
               --  since we like the error message with the run time name.

               else
                  Locking_Policy := 'C';

                  if Locking_Policy_Sloc /= System_Location then
                     Locking_Policy_Sloc := Loc;
                  end if;
               end if;

               --  Add entry in the table

               Specific_Dispatching.Append
                    ((Dispatching_Policy => DP,
                      First_Priority     => UI_To_Int (Lower_Val),
                      Last_Priority      => UI_To_Int (Upper_Val),
                      Pragma_Loc         => Loc));
            end if;
         end Priority_Specific_Dispatching;

         -------------
         -- Profile --
         -------------

         --  pragma Profile (profile_IDENTIFIER);

         --  profile_IDENTIFIER => Restricted | Ravenscar | Rational

         when Pragma_Profile =>
            Ada_2005_Pragma;
            Check_Arg_Count (1);
            Check_Valid_Configuration_Pragma;
            Check_No_Identifiers;

            declare
               Argx : constant Node_Id := Get_Pragma_Arg (Arg1);

            begin
               if Nkind (Argx) /= N_Identifier then
                  Error_Msg_N
                    ("argument of pragma Profile must be an identifier", N);

               elsif Chars (Argx) = Name_Ravenscar then
                  Set_Ravenscar_Profile (Ravenscar, N);

               elsif Chars (Argx) = Name_Jorvik then
                  Set_Ravenscar_Profile (Jorvik, N);

               elsif Chars (Argx) = Name_Gnat_Extended_Ravenscar then
                  Set_Ravenscar_Profile (GNAT_Extended_Ravenscar, N);

               elsif Chars (Argx) = Name_Gnat_Ravenscar_EDF then
                  Set_Ravenscar_Profile (GNAT_Ravenscar_EDF, N);

               elsif Chars (Argx) = Name_Restricted then
                  Set_Profile_Restrictions
                    (Restricted,
                     N, Warn => Treat_Restrictions_As_Warnings);

               elsif Chars (Argx) = Name_Rational then
                  Set_Rational_Profile;

               elsif Chars (Argx) = Name_No_Implementation_Extensions then
                  Set_Profile_Restrictions
                    (No_Implementation_Extensions,
                     N, Warn => Treat_Restrictions_As_Warnings);

               else
                  Error_Pragma_Arg ("& is not a valid profile", Argx);
               end if;
            end;

         ----------------------
         -- Profile_Warnings --
         ----------------------

         --  pragma Profile_Warnings (profile_IDENTIFIER);

         --  profile_IDENTIFIER => Restricted | Ravenscar

         when Pragma_Profile_Warnings =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Valid_Configuration_Pragma;
            Check_No_Identifiers;

            declare
               Argx : constant Node_Id := Get_Pragma_Arg (Arg1);

            begin
               if Chars (Argx) = Name_Ravenscar then
                  Set_Profile_Restrictions (Ravenscar, N, Warn => True);

               elsif Chars (Argx) = Name_Restricted then
                  Set_Profile_Restrictions (Restricted, N, Warn => True);

               elsif Chars (Argx) = Name_No_Implementation_Extensions then
                  Set_Profile_Restrictions
                    (No_Implementation_Extensions, N, Warn => True);

               else
                  Error_Pragma_Arg ("& is not a valid profile", Argx);
               end if;
            end;

         --------------------------
         -- Propagate_Exceptions --
         --------------------------

         --  pragma Propagate_Exceptions;

         --  Note: this pragma is obsolete and has no effect

         when Pragma_Propagate_Exceptions =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("'G'N'A'T pragma Propagate'_Exceptions is now obsolete " &
                  "and has no effect?j?", N);
            end if;

         -----------------------------
         -- Provide_Shift_Operators --
         -----------------------------

         --  pragma Provide_Shift_Operators (integer_subtype_LOCAL_NAME);

         when Pragma_Provide_Shift_Operators =>
         Provide_Shift_Operators : declare
            Ent : Entity_Id;

            procedure Declare_Shift_Operator (Nam : Name_Id);
            --  Insert declaration and pragma Instrinsic for named shift op

            ----------------------------
            -- Declare_Shift_Operator --
            ----------------------------

            procedure Declare_Shift_Operator (Nam : Name_Id) is
               Func   : Node_Id;
               Import : Node_Id;

            begin
               Func :=
                 Make_Subprogram_Declaration (Loc,
                   Make_Function_Specification (Loc,
                     Defining_Unit_Name       =>
                       Make_Defining_Identifier (Loc, Chars => Nam),

                     Result_Definition        =>
                       Make_Identifier (Loc, Chars => Chars (Ent)),

                     Parameter_Specifications => New_List (
                       Make_Parameter_Specification (Loc,
                         Defining_Identifier  =>
                           Make_Defining_Identifier (Loc, Name_Value),
                         Parameter_Type       =>
                           Make_Identifier (Loc, Chars => Chars (Ent))),

                       Make_Parameter_Specification (Loc,
                         Defining_Identifier  =>
                           Make_Defining_Identifier (Loc, Name_Amount),
                         Parameter_Type       =>
                           New_Occurrence_Of (Standard_Natural, Loc)))));

               Import :=
                 Make_Pragma (Loc,
                   Chars => Name_Import,
                   Pragma_Argument_Associations => New_List (
                     Make_Pragma_Argument_Association (Loc,
                       Expression => Make_Identifier (Loc, Name_Intrinsic)),
                     Make_Pragma_Argument_Association (Loc,
                       Expression => Make_Identifier (Loc, Nam))));

               Insert_After (N, Import);
               Insert_After (N, Func);
            end Declare_Shift_Operator;

         --  Start of processing for Provide_Shift_Operators

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);

            Arg1 := Get_Pragma_Arg (Arg1);

            --  We must have an entity name

            if not Is_Entity_Name (Arg1) then
               Error_Pragma_Arg
                 ("pragma % must apply to integer first subtype", Arg1);
            end if;

            --  If no Entity, means there was a prior error so ignore

            if Present (Entity (Arg1)) then
               Ent := Entity (Arg1);

               --  Apply error checks

               if not Is_First_Subtype (Ent) then
                  Error_Pragma_Arg
                    ("cannot apply pragma %",
                     "\& is not a first subtype",
                     Arg1);

               elsif not Is_Integer_Type (Ent) then
                  Error_Pragma_Arg
                    ("cannot apply pragma %",
                     "\& is not an integer type",
                     Arg1);

               elsif Has_Shift_Operator (Ent) then
                  Error_Pragma_Arg
                    ("cannot apply pragma %",
                     "\& already has declared shift operators",
                     Arg1);

               elsif Is_Frozen (Ent) then
                  Error_Pragma_Arg
                    ("pragma % appears too late",
                     "\& is already frozen",
                     Arg1);
               end if;

               --  Now declare the operators. We do this during analysis rather
               --  than expansion, since we want the operators available if we
               --  are operating in -gnatc mode.

               Declare_Shift_Operator (Name_Rotate_Left);
               Declare_Shift_Operator (Name_Rotate_Right);
               Declare_Shift_Operator (Name_Shift_Left);
               Declare_Shift_Operator (Name_Shift_Right);
               Declare_Shift_Operator (Name_Shift_Right_Arithmetic);
            end if;
         end Provide_Shift_Operators;

         ------------------
         -- Psect_Object --
         ------------------

         --  pragma Psect_Object (
         --        [Internal =>] LOCAL_NAME,
         --     [, [External =>] EXTERNAL_SYMBOL]
         --     [, [Size     =>] EXTERNAL_SYMBOL]);

         when Pragma_Common_Object
            | Pragma_Psect_Object
         =>
         Psect_Object : declare
            Args  : Args_List (1 .. 3);
            Names : constant Name_List (1 .. 3) := (
                      Name_Internal,
                      Name_External,
                      Name_Size);

            Internal : Node_Id renames Args (1);
            External : Node_Id renames Args (2);
            Size     : Node_Id renames Args (3);

            Def_Id : Entity_Id;

            procedure Check_Arg (Arg : Node_Id);
            --  Checks that argument is either a string literal or an
            --  identifier, and posts error message if not.

            ---------------
            -- Check_Arg --
            ---------------

            procedure Check_Arg (Arg : Node_Id) is
            begin
               if Nkind (Original_Node (Arg)) not in
                    N_String_Literal | N_Identifier
               then
                  Error_Pragma_Arg
                    ("inappropriate argument for pragma %", Arg);
               end if;
            end Check_Arg;

         --  Start of processing for Common_Object/Psect_Object

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Process_Extended_Import_Export_Internal_Arg (Internal);

            Def_Id := Entity (Internal);

            if Ekind (Def_Id) not in E_Constant | E_Variable then
               Error_Pragma_Arg
                 ("pragma% must designate an object", Internal);
            end if;

            Check_Arg (Internal);

            if Is_Imported (Def_Id) or else Is_Exported (Def_Id) then
               Error_Pragma_Arg
                 ("cannot use pragma% for imported/exported object",
                  Internal);
            end if;

            if Is_Concurrent_Type (Etype (Internal)) then
               Error_Pragma_Arg
                 ("cannot specify pragma % for task/protected object",
                  Internal);
            end if;

            if Has_Rep_Pragma (Def_Id, Name_Common_Object)
                 or else
               Has_Rep_Pragma (Def_Id, Name_Psect_Object)
            then
               Error_Msg_N ("??duplicate Common/Psect_Object pragma", N);
            end if;

            if Ekind (Def_Id) = E_Constant then
               Error_Pragma_Arg
                 ("cannot specify pragma % for a constant", Internal);
            end if;

            if Is_Record_Type (Etype (Internal)) then
               declare
                  Ent  : Entity_Id;
                  Decl : Entity_Id;

               begin
                  Ent := First_Entity (Etype (Internal));
                  while Present (Ent) loop
                     Decl := Declaration_Node (Ent);

                     if Ekind (Ent) = E_Component
                       and then Nkind (Decl) = N_Component_Declaration
                       and then Present (Expression (Decl))
                       and then Warn_On_Export_Import
                     then
                        Error_Msg_N
                          ("?x?object for pragma % has defaults", Internal);
                        exit;

                     else
                        Next_Entity (Ent);
                     end if;
                  end loop;
               end;
            end if;

            if Present (Size) then
               Check_Arg (Size);
            end if;

            if Present (External) then
               Check_Arg_Is_External_Name (External);
            end if;

            --  If all error tests pass, link pragma on to the rep item chain

            Record_Rep_Item (Def_Id, N);
         end Psect_Object;

         ----------
         -- Pure --
         ----------

         --  pragma Pure [(library_unit_NAME)];

         when Pragma_Pure => Pure : declare
            Ent : Entity_Id;

         begin
            Check_Ada_83_Warning;

            --  If the pragma comes from a subprogram instantiation, nothing to
            --  check, this can happen at any level of nesting.

            if Is_Wrapper_Package (Current_Scope) then
               return;
            end if;

            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Ent := Find_Lib_Unit_Name;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Ent);

            if not Debug_Flag_U then
               Set_Is_Pure (Ent);
               Set_Has_Pragma_Pure (Ent);

               if Legacy_Elaboration_Checks then
                  Set_Suppress_Elaboration_Warnings (Ent);
               end if;
            end if;
         end Pure;

         -------------------
         -- Pure_Function --
         -------------------

         --  pragma Pure_Function ([Entity =>] function_LOCAL_NAME);

         when Pragma_Pure_Function => Pure_Function : declare
            Def_Id    : Entity_Id;
            E         : Entity_Id;
            E_Id      : Node_Id;
            Effective : Boolean := False;
            Orig_Def  : Entity_Id;
            Same_Decl : Boolean := False;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);
            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            --  Loop through homonyms (overloadings) of referenced entity

            E := Entity (E_Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            if Present (E) then
               loop
                  Def_Id := Get_Base_Subprogram (E);

                  if Ekind (Def_Id) not in
                       E_Function | E_Generic_Function | E_Operator
                  then
                     Error_Pragma_Arg
                       ("pragma% requires a function name", Arg1);
                  end if;

                  --  When we have a generic function we must jump up a level
                  --  to the declaration of the wrapper package itself.

                  Orig_Def := Def_Id;

                  if Is_Generic_Instance (Def_Id) then
                     while Nkind (Orig_Def) /= N_Package_Declaration loop
                        Orig_Def := Parent (Orig_Def);
                     end loop;
                  end if;

                  if In_Same_Declarative_Part (Parent (N), Orig_Def) then
                     Same_Decl := True;
                     Set_Is_Pure (Def_Id);

                     if not Has_Pragma_Pure_Function (Def_Id) then
                        Set_Has_Pragma_Pure_Function (Def_Id);
                        Effective := True;
                     end if;
                  end if;

                  exit when From_Aspect_Specification (N);
                  E := Homonym (E);
                  exit when No (E) or else Scope (E) /= Current_Scope;
               end loop;

               if not Effective
                 and then Warn_On_Redundant_Constructs
               then
                  Error_Msg_NE
                    ("pragma Pure_Function on& is redundant?r?",
                     N, Entity (E_Id));

               elsif not Same_Decl then
                  Error_Pragma_Arg
                    ("pragma% argument must be in same declarative part",
                     Arg1);
               end if;
            end if;
         end Pure_Function;

         --------------------
         -- Queuing_Policy --
         --------------------

         --  pragma Queuing_Policy (policy_IDENTIFIER);

         when Pragma_Queuing_Policy => declare
            QP : Character;

         begin
            Check_Ada_83_Warning;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Queuing_Policy (Arg1);
            Check_Valid_Configuration_Pragma;
            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
            QP := Fold_Upper (Name_Buffer (1));

            if Queuing_Policy /= ' '
              and then Queuing_Policy /= QP
            then
               Error_Msg_Sloc := Queuing_Policy_Sloc;
               Error_Pragma ("queuing policy incompatible with policy#");

            --  Set new policy, but always preserve System_Location since we
            --  like the error message with the run time name.

            else
               Queuing_Policy := QP;

               if Queuing_Policy_Sloc /= System_Location then
                  Queuing_Policy_Sloc := Loc;
               end if;
            end if;
         end;

         --------------
         -- Rational --
         --------------

         --  pragma Rational, for compatibility with foreign compiler

         when Pragma_Rational =>
            Set_Rational_Profile;

         ---------------------
         -- Refined_Depends --
         ---------------------

         --  pragma Refined_Depends (DEPENDENCY_RELATION);

         --  DEPENDENCY_RELATION ::=
         --     null
         --  | (DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE})

         --  DEPENDENCY_CLAUSE ::=
         --    OUTPUT_LIST =>[+] INPUT_LIST
         --  | NULL_DEPENDENCY_CLAUSE

         --  NULL_DEPENDENCY_CLAUSE ::= null => INPUT_LIST

         --  OUTPUT_LIST ::= OUTPUT | (OUTPUT {, OUTPUT})

         --  INPUT_LIST ::= null | INPUT | (INPUT {, INPUT})

         --  OUTPUT ::= NAME | FUNCTION_RESULT
         --  INPUT  ::= NAME

         --  where FUNCTION_RESULT is a function Result attribute_reference

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks fully analyze
         --    the dependency clauses/global list in:

         --       Analyze_Refined_Depends_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram body.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram body is instantiated.

         when Pragma_Refined_Depends => Refined_Depends : declare
            Body_Id : Entity_Id;
            Legal   : Boolean;
            Spec_Id : Entity_Id;

         begin
            Analyze_Refined_Depends_Global_Post (Spec_Id, Body_Id, Legal);

            if Legal then

               --  Chain the pragma on the contract for further processing by
               --  Analyze_Refined_Depends_In_Decl_Part.

               Add_Contract_Item (N, Body_Id);

               --  The legality checks of pragmas Refined_Depends and
               --  Refined_Global are affected by the SPARK mode in effect and
               --  the volatility of the context. In addition these two pragmas
               --  are subject to an inherent order:

               --    1) Refined_Global
               --    2) Refined_Depends

               --  Analyze all these pragmas in the order outlined above

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_If_Present (Pragma_Refined_Global);
               Analyze_Refined_Depends_In_Decl_Part (N);
            end if;
         end Refined_Depends;

         --------------------
         -- Refined_Global --
         --------------------

         --  pragma Refined_Global (GLOBAL_SPECIFICATION);

         --  GLOBAL_SPECIFICATION ::=
         --     null
         --  | (GLOBAL_LIST)
         --  | (MODED_GLOBAL_LIST {, MODED_GLOBAL_LIST})

         --  MODED_GLOBAL_LIST ::= MODE_SELECTOR => GLOBAL_LIST

         --  MODE_SELECTOR ::= In_Out | Input | Output | Proof_In
         --  GLOBAL_LIST   ::= GLOBAL_ITEM | (GLOBAL_ITEM {, GLOBAL_ITEM})
         --  GLOBAL_ITEM   ::= NAME

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks fully analyze
         --    the dependency clauses/global list in:

         --       Analyze_Refined_Global_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram body.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram body is instantiated.

         when Pragma_Refined_Global => Refined_Global : declare
            Body_Id : Entity_Id;
            Legal   : Boolean;
            Spec_Id : Entity_Id;

         begin
            Analyze_Refined_Depends_Global_Post (Spec_Id, Body_Id, Legal);

            if Legal then

               --  Chain the pragma on the contract for further processing by
               --  Analyze_Refined_Global_In_Decl_Part.

               Add_Contract_Item (N, Body_Id);

               --  The legality checks of pragmas Refined_Depends and
               --  Refined_Global are affected by the SPARK mode in effect and
               --  the volatility of the context. In addition these two pragmas
               --  are subject to an inherent order:

               --    1) Refined_Global
               --    2) Refined_Depends

               --  Analyze all these pragmas in the order outlined above

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_Refined_Global_In_Decl_Part (N);
               Analyze_If_Present (Pragma_Refined_Depends);
            end if;
         end Refined_Global;

         ------------------
         -- Refined_Post --
         ------------------

         --  pragma Refined_Post (boolean_EXPRESSION);

         --  Characteristics:

         --    * Analysis - The annotation is fully analyzed immediately upon
         --    elaboration as it cannot forward reference entities.

         --    * Expansion - The annotation is expanded during the expansion of
         --    the related subprogram body contract as performed in:

         --       Expand_Subprogram_Contract

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram body.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram body is instantiated.

         when Pragma_Refined_Post => Refined_Post : declare
            Body_Id : Entity_Id;
            Legal   : Boolean;
            Spec_Id : Entity_Id;

         begin
            Analyze_Refined_Depends_Global_Post (Spec_Id, Body_Id, Legal);

            --  Fully analyze the pragma when it appears inside a subprogram
            --  body because it cannot benefit from forward references.

            if Legal then

               --  Chain the pragma on the contract for completeness

               Add_Contract_Item (N, Body_Id);

               --  The legality checks of pragma Refined_Post are affected by
               --  the SPARK mode in effect and the volatility of the context.
               --  Analyze all pragmas in a specific order.

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_Pre_Post_Condition_In_Decl_Part (N);

               --  Currently it is not possible to inline pre/postconditions on
               --  a subprogram subject to pragma Inline_Always.

               Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);
            end if;
         end Refined_Post;

         -------------------
         -- Refined_State --
         -------------------

         --  pragma Refined_State (REFINEMENT_LIST);

         --  REFINEMENT_LIST ::=
         --    (REFINEMENT_CLAUSE {, REFINEMENT_CLAUSE})

         --  REFINEMENT_CLAUSE ::= state_NAME => CONSTITUENT_LIST

         --  CONSTITUENT_LIST ::=
         --     null
         --  |  CONSTITUENT
         --  | (CONSTITUENT {, CONSTITUENT})

         --  CONSTITUENT ::= object_NAME | state_NAME

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    refinement clauses in:

         --       Analyze_Refined_State_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the template of the related
         --    package body.

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic package body is instantiated.

         when Pragma_Refined_State => Refined_State : declare
            Pack_Decl : Node_Id;
            Spec_Id   : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Pack_Decl := Find_Related_Package_Or_Body (N, Do_Checks => True);

            if Nkind (Pack_Decl) /= N_Package_Body then
               Pragma_Misplaced;
               return;
            end if;

            Spec_Id := Corresponding_Spec (Pack_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Spec_Id);

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Refined_State_In_Decl_Part.

            Add_Contract_Item (N, Defining_Entity (Pack_Decl));

            --  The legality checks of pragma Refined_State are affected by the
            --  SPARK mode in effect. Analyze all pragmas in a specific order.

            Analyze_If_Present (Pragma_SPARK_Mode);

            --  State refinement is allowed only when the corresponding package
            --  declaration has non-null pragma Abstract_State. Refinement not
            --  enforced when SPARK checks are suppressed (SPARK RM 7.2.2(3)).

            if SPARK_Mode /= Off
              and then
                (No (Abstract_States (Spec_Id))
                  or else Has_Null_Abstract_State (Spec_Id))
            then
               Error_Msg_NE
                 ("useless refinement, package & does not define abstract "
                  & "states", N, Spec_Id);
               return;
            end if;
         end Refined_State;

         -----------------------
         -- Relative_Deadline --
         -----------------------

         --  pragma Relative_Deadline (time_span_EXPRESSION);

         when Pragma_Relative_Deadline => Relative_Deadline : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;

         begin
            Ada_2005_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Arg := Get_Pragma_Arg (Arg1);

            --  The expression must be analyzed in the special manner described
            --  in "Handling of Default and Per-Object Expressions" in sem.ads.

            Preanalyze_Spec_Expression (Arg, RTE (RE_Time_Span));

            --  Subprogram case

            if Nkind (P) = N_Subprogram_Body then
               Check_In_Main_Program;

            --  Only Task and subprogram cases allowed

            elsif Nkind (P) /= N_Task_Definition then
               Pragma_Misplaced;
            end if;

            --  Check duplicate pragma before we set the corresponding flag

            if Has_Relative_Deadline_Pragma (P) then
               Error_Pragma ("duplicate pragma% not allowed");
            end if;

            --  Set Has_Relative_Deadline_Pragma only for tasks. Note that
            --  Relative_Deadline pragma node cannot be inserted in the Rep
            --  Item chain of Ent since it is rewritten by the expander as a
            --  procedure call statement that will break the chain.

            Set_Has_Relative_Deadline_Pragma (P);
         end Relative_Deadline;

         ------------------------
         -- Remote_Access_Type --
         ------------------------

         --  pragma Remote_Access_Type ([Entity =>] formal_type_LOCAL_NAME);

         when Pragma_Remote_Access_Type => Remote_Access_Type : declare
            E : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);

            E := Entity (Get_Pragma_Arg (Arg1));

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            if Nkind (Parent (E)) = N_Formal_Type_Declaration
              and then Ekind (E) = E_General_Access_Type
              and then Is_Class_Wide_Type (Directly_Designated_Type (E))
              and then Scope (Root_Type (Directly_Designated_Type (E)))
                         = Scope (E)
              and then Is_Valid_Remote_Object_Type
                         (Root_Type (Directly_Designated_Type (E)))
            then
               Set_Is_Remote_Types (E);

            else
               Error_Pragma_Arg
                 ("pragma% applies only to formal access-to-class-wide types",
                  Arg1);
            end if;
         end Remote_Access_Type;

         ---------------------------
         -- Remote_Call_Interface --
         ---------------------------

         --  pragma Remote_Call_Interface [(library_unit_NAME)];

         when Pragma_Remote_Call_Interface => Remote_Call_Interface : declare
            Cunit_Node : Node_Id;
            Cunit_Ent  : Entity_Id;
            K          : Node_Kind;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Cunit_Node := Cunit (Current_Sem_Unit);
            K          := Nkind (Unit (Cunit_Node));
            Cunit_Ent  := Cunit_Entity (Current_Sem_Unit);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Cunit_Ent);

            if K = N_Package_Declaration
              or else K = N_Generic_Package_Declaration
              or else K = N_Subprogram_Declaration
              or else K = N_Generic_Subprogram_Declaration
              or else (K = N_Subprogram_Body
                         and then Acts_As_Spec (Unit (Cunit_Node)))
            then
               null;
            else
               Error_Pragma (
                 "pragma% must apply to package or subprogram declaration");
            end if;

            Set_Is_Remote_Call_Interface (Cunit_Ent);
         end Remote_Call_Interface;

         ------------------
         -- Remote_Types --
         ------------------

         --  pragma Remote_Types [(library_unit_NAME)];

         when Pragma_Remote_Types => Remote_Types : declare
            Cunit_Node : Node_Id;
            Cunit_Ent  : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Cunit_Node := Cunit (Current_Sem_Unit);
            Cunit_Ent  := Cunit_Entity (Current_Sem_Unit);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Cunit_Ent);

            if Nkind (Unit (Cunit_Node)) not in
                 N_Package_Declaration | N_Generic_Package_Declaration
            then
               Error_Pragma
                 ("pragma% can only apply to a package declaration");
            end if;

            Set_Is_Remote_Types (Cunit_Ent);
         end Remote_Types;

         ---------------
         -- Ravenscar --
         ---------------

         --  pragma Ravenscar;

         when Pragma_Ravenscar =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Set_Ravenscar_Profile (Ravenscar, N);

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("pragma Ravenscar is an obsolescent feature?j?", N);
               Error_Msg_N
                 ("|use pragma Profile (Ravenscar) instead?j?", N);
            end if;

         -------------------------
         -- Restricted_Run_Time --
         -------------------------

         --  pragma Restricted_Run_Time;

         when Pragma_Restricted_Run_Time =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Set_Profile_Restrictions
              (Restricted, N, Warn => Treat_Restrictions_As_Warnings);

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("pragma Restricted_Run_Time is an obsolescent feature?j?",
                  N);
               Error_Msg_N
                 ("|use pragma Profile (Restricted) instead?j?", N);
            end if;

         ------------------
         -- Restrictions --
         ------------------

         --  pragma Restrictions (RESTRICTION {, RESTRICTION});

         --  RESTRICTION ::=
         --    restriction_IDENTIFIER
         --  | restriction_parameter_IDENTIFIER => EXPRESSION

         when Pragma_Restrictions =>
            Process_Restrictions_Or_Restriction_Warnings
              (Warn => Treat_Restrictions_As_Warnings);

         --------------------------
         -- Restriction_Warnings --
         --------------------------

         --  pragma Restriction_Warnings (RESTRICTION {, RESTRICTION});

         --  RESTRICTION ::=
         --    restriction_IDENTIFIER
         --  | restriction_parameter_IDENTIFIER => EXPRESSION

         when Pragma_Restriction_Warnings =>
            GNAT_Pragma;
            Process_Restrictions_Or_Restriction_Warnings (Warn => True);

         ----------------
         -- Reviewable --
         ----------------

         --  pragma Reviewable;

         when Pragma_Reviewable =>
            Check_Ada_83_Warning;
            Check_Arg_Count (0);

            --  Call dummy debugging function rv. This is done to assist front
            --  end debugging. By placing a Reviewable pragma in the source
            --  program, a breakpoint on rv catches this place in the source,
            --  allowing convenient stepping to the point of interest.

            rv;

         --------------------------
         -- Secondary_Stack_Size --
         --------------------------

         --  pragma Secondary_Stack_Size (EXPRESSION);

         when Pragma_Secondary_Stack_Size => Secondary_Stack_Size : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            if Nkind (P) = N_Task_Definition then
               Arg := Get_Pragma_Arg (Arg1);
               Ent := Defining_Identifier (Parent (P));

               --  The expression must be analyzed in the special manner
               --  described in "Handling of Default Expressions" in sem.ads.

               Preanalyze_Spec_Expression (Arg, Any_Integer);

               --  The pragma cannot appear if the No_Secondary_Stack
               --  restriction is in effect.

               Check_Restriction (No_Secondary_Stack, Arg);

            --  Anything else is incorrect

            else
               Pragma_Misplaced;
            end if;

            --  Check duplicate pragma before we chain the pragma in the Rep
            --  Item chain of Ent.

            Check_Duplicate_Pragma (Ent);
            Record_Rep_Item (Ent, N);
         end Secondary_Stack_Size;

         --------------------------
         -- Short_Circuit_And_Or --
         --------------------------

         --  pragma Short_Circuit_And_Or;

         when Pragma_Short_Circuit_And_Or =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Short_Circuit_And_Or := True;

         -------------------
         -- Share_Generic --
         -------------------

         --  pragma Share_Generic (GNAME {, GNAME});

         --  GNAME ::= generic_unit_NAME | generic_instance_NAME

         when Pragma_Share_Generic =>
            GNAT_Pragma;
            Process_Generic_List;

         ------------
         -- Shared --
         ------------

         --  pragma Shared (LOCAL_NAME);

         when Pragma_Shared =>
            GNAT_Pragma;
            Process_Atomic_Independent_Shared_Volatile;

         --------------------
         -- Shared_Passive --
         --------------------

         --  pragma Shared_Passive [(library_unit_NAME)];

         --  Set the flag Is_Shared_Passive of program unit name entity

         when Pragma_Shared_Passive => Shared_Passive : declare
            Cunit_Node : Node_Id;
            Cunit_Ent  : Entity_Id;

         begin
            Check_Ada_83_Warning;
            Check_Valid_Library_Unit_Pragma;

            --  If N was rewritten as a null statement there is nothing more
            --  to do.

            if Nkind (N) = N_Null_Statement then
               return;
            end if;

            Cunit_Node := Cunit (Current_Sem_Unit);
            Cunit_Ent  := Cunit_Entity (Current_Sem_Unit);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Cunit_Ent);

            if Nkind (Unit (Cunit_Node)) not in
                 N_Package_Declaration | N_Generic_Package_Declaration
            then
               Error_Pragma
                 ("pragma% can only apply to a package declaration");
            end if;

            Set_Is_Shared_Passive (Cunit_Ent);
         end Shared_Passive;

         -----------------------
         -- Short_Descriptors --
         -----------------------

         --  pragma Short_Descriptors;

         --  Recognize and validate, but otherwise ignore

         when Pragma_Short_Descriptors =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;

         ------------------------------
         -- Simple_Storage_Pool_Type --
         ------------------------------

         --  pragma Simple_Storage_Pool_Type (type_LOCAL_NAME);

         when Pragma_Simple_Storage_Pool_Type =>
         Simple_Storage_Pool_Type : declare
            Typ     : Entity_Id;
            Type_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);

            Type_Id := Get_Pragma_Arg (Arg1);
            Find_Type (Type_Id);
            Typ := Entity (Type_Id);

            if Typ = Any_Type then
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            --  We require the pragma to apply to a type declared in a package
            --  declaration, but not (immediately) within a package body.

            if Ekind (Current_Scope) /= E_Package
              or else In_Package_Body (Current_Scope)
            then
               Error_Pragma
                 ("pragma% can only apply to type declared immediately "
                  & "within a package declaration");
            end if;

            --  A simple storage pool type must be an immutably limited record
            --  or private type. If the pragma is given for a private type,
            --  the full type is similarly restricted (which is checked later
            --  in Freeze_Entity).

            if Is_Record_Type (Typ)
              and then not Is_Limited_View (Typ)
            then
               Error_Pragma
                 ("pragma% can only apply to explicitly limited record type");

            elsif Is_Private_Type (Typ) and then not Is_Limited_Type (Typ) then
               Error_Pragma
                 ("pragma% can only apply to a private type that is limited");

            elsif not Is_Record_Type (Typ)
              and then not Is_Private_Type (Typ)
            then
               Error_Pragma
                 ("pragma% can only apply to limited record or private type");
            end if;

            Record_Rep_Item (Typ, N);
         end Simple_Storage_Pool_Type;

         ----------------------
         -- Source_File_Name --
         ----------------------

         --  There are five forms for this pragma:

         --  pragma Source_File_Name (
         --    [UNIT_NAME      =>] unit_NAME,
         --     BODY_FILE_NAME =>  STRING_LITERAL
         --    [, [INDEX =>] INTEGER_LITERAL]);

         --  pragma Source_File_Name (
         --    [UNIT_NAME      =>] unit_NAME,
         --     SPEC_FILE_NAME =>  STRING_LITERAL
         --    [, [INDEX =>] INTEGER_LITERAL]);

         --  pragma Source_File_Name (
         --     BODY_FILE_NAME  => STRING_LITERAL
         --  [, DOT_REPLACEMENT => STRING_LITERAL]
         --  [, CASING          => CASING_SPEC]);

         --  pragma Source_File_Name (
         --     SPEC_FILE_NAME  => STRING_LITERAL
         --  [, DOT_REPLACEMENT => STRING_LITERAL]
         --  [, CASING          => CASING_SPEC]);

         --  pragma Source_File_Name (
         --     SUBUNIT_FILE_NAME  => STRING_LITERAL
         --  [, DOT_REPLACEMENT    => STRING_LITERAL]
         --  [, CASING             => CASING_SPEC]);

         --  CASING_SPEC ::= Uppercase | Lowercase | Mixedcase

         --  Pragma Source_File_Name_Project (SFNP) is equivalent to pragma
         --  Source_File_Name (SFN), however their usage is exclusive: SFN can
         --  only be used when no project file is used, while SFNP can only be
         --  used when a project file is used.

         --  No processing here. Processing was completed during parsing, since
         --  we need to have file names set as early as possible. Units are
         --  loaded well before semantic processing starts.

         --  The only processing we defer to this point is the check for
         --  correct placement.

         when Pragma_Source_File_Name =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;

         ------------------------------
         -- Source_File_Name_Project --
         ------------------------------

         --  See Source_File_Name for syntax

         --  No processing here. Processing was completed during parsing, since
         --  we need to have file names set as early as possible. Units are
         --  loaded well before semantic processing starts.

         --  The only processing we defer to this point is the check for
         --  correct placement.

         when Pragma_Source_File_Name_Project =>
            GNAT_Pragma;
            Check_Valid_Configuration_Pragma;

            --  Check that a pragma Source_File_Name_Project is used only in a
            --  configuration pragmas file.

            --  Pragmas Source_File_Name_Project should only be generated by
            --  the Project Manager in configuration pragmas files.

            --  This is really an ugly test. It seems to depend on some
            --  accidental and undocumented property. At the very least it
            --  needs to be documented, but it would be better to have a
            --  clean way of testing if we are in a configuration file???

            if Present (Parent (N)) then
               Error_Pragma
                 ("pragma% can only appear in a configuration pragmas file");
            end if;

         ----------------------
         -- Source_Reference --
         ----------------------

         --  pragma Source_Reference (INTEGER_LITERAL [, STRING_LITERAL]);

         --  Nothing to do, all processing completed in Par.Prag, since we need
         --  the information for possible parser messages that are output.

         when Pragma_Source_Reference =>
            GNAT_Pragma;

         ----------------
         -- SPARK_Mode --
         ----------------

         --  pragma SPARK_Mode [(On | Off)];

         when Pragma_SPARK_Mode => Do_SPARK_Mode : declare
            Mode_Id : SPARK_Mode_Type;

            procedure Check_Pragma_Conformance
              (Context_Pragma : Node_Id;
               Entity         : Entity_Id;
               Entity_Pragma  : Node_Id);
            --  Subsidiary to routines Process_xxx. Verify the SPARK_Mode
            --  conformance of pragma N depending the following scenarios:
            --
            --  If pragma Context_Pragma is not Empty, verify that pragma N is
            --  compatible with the pragma Context_Pragma that was inherited
            --  from the context:
            --    * If the mode of Context_Pragma is ON, then the new mode can
            --      be anything.
            --    * If the mode of Context_Pragma is OFF, then the only allowed
            --      new mode is also OFF. Emit error if this is not the case.
            --
            --  If Entity is not Empty, verify that pragma N is compatible with
            --  pragma Entity_Pragma that belongs to Entity.
            --    * If Entity_Pragma is Empty, always issue an error as this
            --      corresponds to the case where a previous section of Entity
            --      has no SPARK_Mode set.
            --    * If the mode of Entity_Pragma is ON, then the new mode can
            --      be anything.
            --    * If the mode of Entity_Pragma is OFF, then the only allowed
            --      new mode is also OFF. Emit error if this is not the case.

            procedure Check_Library_Level_Entity (E : Entity_Id);
            --  Subsidiary to routines Process_xxx. Verify that the related
            --  entity E subject to pragma SPARK_Mode is library-level.

            procedure Process_Body (Decl : Node_Id);
            --  Verify the legality of pragma SPARK_Mode when it appears as the
            --  top of the body declarations of entry, package, protected unit,
            --  subprogram or task unit body denoted by Decl.

            procedure Process_Overloadable (Decl : Node_Id);
            --  Verify the legality of pragma SPARK_Mode when it applies to an
            --  entry or [generic] subprogram declaration denoted by Decl.

            procedure Process_Private_Part (Decl : Node_Id);
            --  Verify the legality of pragma SPARK_Mode when it appears at the
            --  top of the private declarations of a package spec, protected or
            --  task unit declaration denoted by Decl.

            procedure Process_Statement_Part (Decl : Node_Id);
            --  Verify the legality of pragma SPARK_Mode when it appears at the
            --  top of the statement sequence of a package body denoted by node
            --  Decl.

            procedure Process_Visible_Part (Decl : Node_Id);
            --  Verify the legality of pragma SPARK_Mode when it appears at the
            --  top of the visible declarations of a package spec, protected or
            --  task unit declaration denoted by Decl. The routine is also used
            --  on protected or task units declared without a definition.

            procedure Set_SPARK_Context;
            --  Subsidiary to routines Process_xxx. Set the global variables
            --  which represent the mode of the context from pragma N. Ensure
            --  that Dynamic_Elaboration_Checks are off if the new mode is On.

            ------------------------------
            -- Check_Pragma_Conformance --
            ------------------------------

            procedure Check_Pragma_Conformance
              (Context_Pragma : Node_Id;
               Entity         : Entity_Id;
               Entity_Pragma  : Node_Id)
            is
               Err_Id : Entity_Id;
               Err_N  : Node_Id;

            begin
               --  The current pragma may appear without an argument. If this
               --  is the case, associate all error messages with the pragma
               --  itself.

               if Present (Arg1) then
                  Err_N := Arg1;
               else
                  Err_N := N;
               end if;

               --  The mode of the current pragma is compared against that of
               --  an enclosing context.

               if Present (Context_Pragma) then
                  pragma Assert (Nkind (Context_Pragma) = N_Pragma);

                  --  Issue an error if the new mode is less restrictive than
                  --  that of the context.

                  if Get_SPARK_Mode_From_Annotation (Context_Pragma) = Off
                    and then Get_SPARK_Mode_From_Annotation (N) = On
                  then
                     Error_Msg_N
                       ("cannot change SPARK_Mode from Off to On", Err_N);
                     Error_Msg_Sloc := Sloc (SPARK_Mode_Pragma);
                     Error_Msg_N ("\SPARK_Mode was set to Off#", Err_N);
                     raise Pragma_Exit;
                  end if;
               end if;

               --  The mode of the current pragma is compared against that of
               --  an initial package, protected type, subprogram or task type
               --  declaration.

               if Present (Entity) then

                  --  A simple protected or task type is transformed into an
                  --  anonymous type whose name cannot be used to issue error
                  --  messages. Recover the original entity of the type.

                  if Ekind (Entity) in E_Protected_Type | E_Task_Type then
                     Err_Id :=
                       Defining_Entity
                         (Original_Node (Unit_Declaration_Node (Entity)));
                  else
                     Err_Id := Entity;
                  end if;

                  --  Both the initial declaration and the completion carry
                  --  SPARK_Mode pragmas.

                  if Present (Entity_Pragma) then
                     pragma Assert (Nkind (Entity_Pragma) = N_Pragma);

                     --  Issue an error if the new mode is less restrictive
                     --  than that of the initial declaration.

                     if Get_SPARK_Mode_From_Annotation (Entity_Pragma) = Off
                       and then Get_SPARK_Mode_From_Annotation (N) = On
                     then
                        Error_Msg_N ("incorrect use of SPARK_Mode", Err_N);
                        Error_Msg_Sloc := Sloc (Entity_Pragma);
                        Error_Msg_NE
                          ("\value Off was set for SPARK_Mode on&#",
                           Err_N, Err_Id);
                        raise Pragma_Exit;
                     end if;

                  --  Otherwise the initial declaration lacks a SPARK_Mode
                  --  pragma in which case the current pragma is illegal as
                  --  it cannot "complete".

                  elsif Get_SPARK_Mode_From_Annotation (N) = Off
                    and then (Is_Generic_Unit (Entity) or else In_Instance)
                  then
                     null;

                  else
                     Error_Msg_N ("incorrect use of SPARK_Mode", Err_N);
                     Error_Msg_Sloc := Sloc (Err_Id);
                     Error_Msg_NE
                       ("\no value was set for SPARK_Mode on&#",
                        Err_N, Err_Id);
                     raise Pragma_Exit;
                  end if;
               end if;
            end Check_Pragma_Conformance;

            --------------------------------
            -- Check_Library_Level_Entity --
            --------------------------------

            procedure Check_Library_Level_Entity (E : Entity_Id) is
               procedure Add_Entity_To_Name_Buffer;
               --  Add the E_Kind of entity E to the name buffer

               -------------------------------
               -- Add_Entity_To_Name_Buffer --
               -------------------------------

               procedure Add_Entity_To_Name_Buffer is
               begin
                  if Ekind (E) in E_Entry | E_Entry_Family then
                     Add_Str_To_Name_Buffer ("entry");

                  elsif Ekind (E) in E_Generic_Package
                                   | E_Package
                                   | E_Package_Body
                  then
                     Add_Str_To_Name_Buffer ("package");

                  elsif Ekind (E) in E_Protected_Body | E_Protected_Type then
                     Add_Str_To_Name_Buffer ("protected type");

                  elsif Ekind (E) in E_Function
                                   | E_Generic_Function
                                   | E_Generic_Procedure
                                   | E_Procedure
                                   | E_Subprogram_Body
                  then
                     Add_Str_To_Name_Buffer ("subprogram");

                  else
                     pragma Assert (Ekind (E) in E_Task_Body | E_Task_Type);
                     Add_Str_To_Name_Buffer ("task type");
                  end if;
               end Add_Entity_To_Name_Buffer;

               --  Local variables

               Msg_1 : constant String := "incorrect placement of pragma%";
               Msg_2 : Name_Id;

            --  Start of processing for Check_Library_Level_Entity

            begin
               --  A SPARK_Mode of On shall only apply to library-level
               --  entities, except for those in generic instances, which are
               --  ignored (even if the entity gets SPARK_Mode pragma attached
               --  in the AST, its effect is not taken into account unless the
               --  context already provides SPARK_Mode of On in GNATprove).

               if Get_SPARK_Mode_From_Annotation (N) = On
                 and then not Is_Library_Level_Entity (E)
                 and then Instantiation_Location (Sloc (N)) = No_Location
               then
                  Error_Msg_Name_1 := Pname;
                  Error_Msg_N (Fix_Error (Msg_1), N);

                  Name_Len := 0;
                  Add_Str_To_Name_Buffer ("\& is not a library-level ");
                  Add_Entity_To_Name_Buffer;

                  Msg_2 := Name_Find;
                  Error_Msg_NE (Get_Name_String (Msg_2), N, E);

                  raise Pragma_Exit;
               end if;
            end Check_Library_Level_Entity;

            ------------------
            -- Process_Body --
            ------------------

            procedure Process_Body (Decl : Node_Id) is
               Body_Id : constant Entity_Id := Defining_Entity (Decl);
               Spec_Id : constant Entity_Id := Unique_Defining_Entity (Decl);

            begin
               --  Ignore pragma when applied to the special body created for
               --  inlining, recognized by its internal name _Parent.

               if Chars (Body_Id) = Name_uParent then
                  return;
               end if;

               Check_Library_Level_Entity (Body_Id);

               --  For entry bodies, verify the legality against:
               --    * The mode of the context
               --    * The mode of the spec (if any)

               if Nkind (Decl) in N_Entry_Body | N_Subprogram_Body then

                  --  A stand-alone subprogram body

                  if Body_Id = Spec_Id then
                     Check_Pragma_Conformance
                       (Context_Pragma => SPARK_Pragma (Body_Id),
                        Entity         => Empty,
                        Entity_Pragma  => Empty);

                  --  An entry or subprogram body that completes a previous
                  --  declaration.

                  else
                     Check_Pragma_Conformance
                       (Context_Pragma => SPARK_Pragma (Body_Id),
                        Entity         => Spec_Id,
                        Entity_Pragma  => SPARK_Pragma (Spec_Id));
                  end if;

                  Set_SPARK_Context;
                  Set_SPARK_Pragma           (Body_Id, N);
                  Set_SPARK_Pragma_Inherited (Body_Id, False);

               --  For package bodies, verify the legality against:
               --    * The mode of the context
               --    * The mode of the private part

               --  This case is separated from protected and task bodies
               --  because the statement part of the package body inherits
               --  the mode of the body declarations.

               elsif Nkind (Decl) = N_Package_Body then
                  Check_Pragma_Conformance
                    (Context_Pragma => SPARK_Pragma (Body_Id),
                     Entity         => Spec_Id,
                     Entity_Pragma  => SPARK_Aux_Pragma (Spec_Id));

                  Set_SPARK_Context;
                  Set_SPARK_Pragma               (Body_Id, N);
                  Set_SPARK_Pragma_Inherited     (Body_Id, False);
                  Set_SPARK_Aux_Pragma           (Body_Id, N);
                  Set_SPARK_Aux_Pragma_Inherited (Body_Id, True);

               --  For protected and task bodies, verify the legality against:
               --    * The mode of the context
               --    * The mode of the private part

               else
                  pragma Assert
                    (Nkind (Decl) in N_Protected_Body | N_Task_Body);

                  Check_Pragma_Conformance
                    (Context_Pragma => SPARK_Pragma (Body_Id),
                     Entity         => Spec_Id,
                     Entity_Pragma  => SPARK_Aux_Pragma (Spec_Id));

                  Set_SPARK_Context;
                  Set_SPARK_Pragma           (Body_Id, N);
                  Set_SPARK_Pragma_Inherited (Body_Id, False);
               end if;
            end Process_Body;

            --------------------------
            -- Process_Overloadable --
            --------------------------

            procedure Process_Overloadable (Decl : Node_Id) is
               Spec_Id  : constant Entity_Id := Defining_Entity (Decl);
               Spec_Typ : constant Entity_Id := Etype (Spec_Id);

            begin
               Check_Library_Level_Entity (Spec_Id);

               --  Verify the legality against:
               --    * The mode of the context

               Check_Pragma_Conformance
                 (Context_Pragma => SPARK_Pragma (Spec_Id),
                  Entity         => Empty,
                  Entity_Pragma  => Empty);

               Set_SPARK_Pragma           (Spec_Id, N);
               Set_SPARK_Pragma_Inherited (Spec_Id, False);

               --  When the pragma applies to the anonymous object created for
               --  a single task type, decorate the type as well. This scenario
               --  arises when the single task type lacks a task definition,
               --  therefore there is no issue with respect to a potential
               --  pragma SPARK_Mode in the private part.

               --    task type Anon_Task_Typ;
               --    Obj : Anon_Task_Typ;
               --    pragma SPARK_Mode ...;

               if Is_Single_Task_Object (Spec_Id) then
                  Set_SPARK_Pragma               (Spec_Typ, N);
                  Set_SPARK_Pragma_Inherited     (Spec_Typ, False);
                  Set_SPARK_Aux_Pragma           (Spec_Typ, N);
                  Set_SPARK_Aux_Pragma_Inherited (Spec_Typ, True);
               end if;
            end Process_Overloadable;

            --------------------------
            -- Process_Private_Part --
            --------------------------

            procedure Process_Private_Part (Decl : Node_Id) is
               Spec_Id : constant Entity_Id := Defining_Entity (Decl);

            begin
               Check_Library_Level_Entity (Spec_Id);

               --  Verify the legality against:
               --    * The mode of the visible declarations

               Check_Pragma_Conformance
                 (Context_Pragma => Empty,
                  Entity         => Spec_Id,
                  Entity_Pragma  => SPARK_Pragma (Spec_Id));

               Set_SPARK_Context;
               Set_SPARK_Aux_Pragma           (Spec_Id, N);
               Set_SPARK_Aux_Pragma_Inherited (Spec_Id, False);
            end Process_Private_Part;

            ----------------------------
            -- Process_Statement_Part --
            ----------------------------

            procedure Process_Statement_Part (Decl : Node_Id) is
               Body_Id : constant Entity_Id := Defining_Entity (Decl);

            begin
               Check_Library_Level_Entity (Body_Id);

               --  Verify the legality against:
               --    * The mode of the body declarations

               Check_Pragma_Conformance
                 (Context_Pragma => Empty,
                  Entity         => Body_Id,
                  Entity_Pragma  => SPARK_Pragma (Body_Id));

               Set_SPARK_Context;
               Set_SPARK_Aux_Pragma           (Body_Id, N);
               Set_SPARK_Aux_Pragma_Inherited (Body_Id, False);
            end Process_Statement_Part;

            --------------------------
            -- Process_Visible_Part --
            --------------------------

            procedure Process_Visible_Part (Decl : Node_Id) is
               Spec_Id : constant Entity_Id := Defining_Entity (Decl);
               Obj_Id  : Entity_Id;

            begin
               Check_Library_Level_Entity (Spec_Id);

               --  Verify the legality against:
               --    * The mode of the context

               Check_Pragma_Conformance
                 (Context_Pragma => SPARK_Pragma (Spec_Id),
                  Entity         => Empty,
                  Entity_Pragma  => Empty);

               --  A task unit declared without a definition does not set the
               --  SPARK_Mode of the context because the task does not have any
               --  entries that could inherit the mode.

               if Nkind (Decl) not in
                    N_Single_Task_Declaration | N_Task_Type_Declaration
               then
                  Set_SPARK_Context;
               end if;

               Set_SPARK_Pragma               (Spec_Id, N);
               Set_SPARK_Pragma_Inherited     (Spec_Id, False);
               Set_SPARK_Aux_Pragma           (Spec_Id, N);
               Set_SPARK_Aux_Pragma_Inherited (Spec_Id, True);

               --  When the pragma applies to a single protected or task type,
               --  decorate the corresponding anonymous object as well.

               --    protected Anon_Prot_Typ is
               --       pragma SPARK_Mode ...;
               --       ...
               --    end Anon_Prot_Typ;

               --    Obj : Anon_Prot_Typ;

               if Is_Single_Concurrent_Type (Spec_Id) then
                  Obj_Id := Anonymous_Object (Spec_Id);

                  Set_SPARK_Pragma           (Obj_Id, N);
                  Set_SPARK_Pragma_Inherited (Obj_Id, False);
               end if;
            end Process_Visible_Part;

            -----------------------
            -- Set_SPARK_Context --
            -----------------------

            procedure Set_SPARK_Context is
            begin
               SPARK_Mode        := Mode_Id;
               SPARK_Mode_Pragma := N;
            end Set_SPARK_Context;

            --  Local variables

            Context : Node_Id;
            Mode    : Name_Id;
            Stmt    : Node_Id;

         --  Start of processing for Do_SPARK_Mode

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            --  Check the legality of the mode (no argument = ON)

            if Arg_Count = 1 then
               Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);
               Mode := Chars (Get_Pragma_Arg (Arg1));
            else
               Mode := Name_On;
            end if;

            Mode_Id := Get_SPARK_Mode_Type (Mode);
            Context := Parent (N);

            --  When a SPARK_Mode pragma appears inside an instantiation whose
            --  enclosing context has SPARK_Mode set to "off", the pragma has
            --  no semantic effect.

            if Ignore_SPARK_Mode_Pragmas_In_Instance
              and then Mode_Id /= Off
            then
               Rewrite (N, Make_Null_Statement (Loc));
               Analyze (N);
               return;
            end if;

            --  The pragma appears in a configuration file

            if No (Context) then
               Check_Valid_Configuration_Pragma;

               if Present (SPARK_Mode_Pragma) then
                  Duplication_Error
                    (Prag => N,
                     Prev => SPARK_Mode_Pragma);
                  raise Pragma_Exit;
               end if;

               Set_SPARK_Context;

            --  The pragma acts as a configuration pragma in a compilation unit

            --    pragma SPARK_Mode ...;
            --    package Pack is ...;

            elsif Nkind (Context) = N_Compilation_Unit
              and then List_Containing (N) = Context_Items (Context)
            then
               Check_Valid_Configuration_Pragma;
               Set_SPARK_Context;

            --  Otherwise the placement of the pragma within the tree dictates
            --  its associated construct. Inspect the declarative list where
            --  the pragma resides to find a potential construct.

            else
               Stmt := Prev (N);
               while Present (Stmt) loop

                  --  Skip prior pragmas, but check for duplicates. Note that
                  --  this also takes care of pragmas generated for aspects.

                  if Nkind (Stmt) = N_Pragma then
                     if Pragma_Name (Stmt) = Pname then
                        Duplication_Error
                          (Prag => N,
                           Prev => Stmt);
                        raise Pragma_Exit;
                     end if;

                  --  The pragma applies to an expression function that has
                  --  already been rewritten into a subprogram declaration.

                  --    function Expr_Func return ... is (...);
                  --    pragma SPARK_Mode ...;

                  elsif Nkind (Stmt) = N_Subprogram_Declaration
                    and then Nkind (Original_Node (Stmt)) =
                               N_Expression_Function
                  then
                     Process_Overloadable (Stmt);
                     return;

                  --  The pragma applies to the anonymous object created for a
                  --  single concurrent type.

                  --    protected type Anon_Prot_Typ ...;
                  --    Obj : Anon_Prot_Typ;
                  --    pragma SPARK_Mode ...;

                  elsif Nkind (Stmt) = N_Object_Declaration
                    and then Is_Single_Concurrent_Object
                               (Defining_Entity (Stmt))
                  then
                     Process_Overloadable (Stmt);
                     return;

                  --  Skip internally generated code

                  elsif not Comes_From_Source (Stmt) then
                     null;

                  --  The pragma applies to an entry or [generic] subprogram
                  --  declaration.

                  --    entry Ent ...;
                  --    pragma SPARK_Mode ...;

                  --    [generic]
                  --    procedure Proc ...;
                  --    pragma SPARK_Mode ...;

                  elsif Nkind (Stmt) in N_Generic_Subprogram_Declaration
                                      | N_Subprogram_Declaration
                    or else (Nkind (Stmt) = N_Entry_Declaration
                              and then Is_Protected_Type
                                         (Scope (Defining_Entity (Stmt))))
                  then
                     Process_Overloadable (Stmt);
                     return;

                  --  Otherwise the pragma does not apply to a legal construct
                  --  or it does not appear at the top of a declarative or a
                  --  statement list. Issue an error and stop the analysis.

                  else
                     Pragma_Misplaced;
                     exit;
                  end if;

                  Prev (Stmt);
               end loop;

               --  The pragma applies to a package or a subprogram that acts as
               --  a compilation unit.

               --    procedure Proc ...;
               --    pragma SPARK_Mode ...;

               if Nkind (Context) = N_Compilation_Unit_Aux then
                  Context := Unit (Parent (Context));
               end if;

               --  The pragma appears at the top of entry, package, protected
               --  unit, subprogram or task unit body declarations.

               --    entry Ent when ... is
               --       pragma SPARK_Mode ...;

               --    package body Pack is
               --       pragma SPARK_Mode ...;

               --    procedure Proc ... is
               --       pragma SPARK_Mode;

               --    protected body Prot is
               --       pragma SPARK_Mode ...;

               if Nkind (Context) in N_Entry_Body
                                   | N_Package_Body
                                   | N_Protected_Body
                                   | N_Subprogram_Body
                                   | N_Task_Body
               then
                  Process_Body (Context);

               --  The pragma appears at the top of the visible or private
               --  declaration of a package spec, protected or task unit.

               --    package Pack is
               --       pragma SPARK_Mode ...;
               --    private
               --       pragma SPARK_Mode ...;

               --    protected [type] Prot is
               --       pragma SPARK_Mode ...;
               --    private
               --       pragma SPARK_Mode ...;

               elsif Nkind (Context) in N_Package_Specification
                                      | N_Protected_Definition
                                      | N_Task_Definition
               then
                  if List_Containing (N) = Visible_Declarations (Context) then
                     Process_Visible_Part (Parent (Context));
                  else
                     Process_Private_Part (Parent (Context));
                  end if;

               --  The pragma appears at the top of package body statements

               --    package body Pack is
               --    begin
               --       pragma SPARK_Mode;

               elsif Nkind (Context) = N_Handled_Sequence_Of_Statements
                 and then Nkind (Parent (Context)) = N_Package_Body
               then
                  Process_Statement_Part (Parent (Context));

               --  The pragma appeared as an aspect of a [generic] subprogram
               --  declaration that acts as a compilation unit.

               --    [generic]
               --    procedure Proc ...;
               --    pragma SPARK_Mode ...;

               elsif Nkind (Context) in N_Generic_Subprogram_Declaration
                                      | N_Subprogram_Declaration
               then
                  Process_Overloadable (Context);

               --  The pragma does not apply to a legal construct, issue error

               else
                  Pragma_Misplaced;
               end if;
            end if;
         end Do_SPARK_Mode;

         --------------------------------
         -- Static_Elaboration_Desired --
         --------------------------------

         --  pragma Static_Elaboration_Desired (DIRECT_NAME);

         when Pragma_Static_Elaboration_Desired =>
            GNAT_Pragma;
            Check_At_Most_N_Arguments (1);

            if Is_Compilation_Unit (Current_Scope)
              and then Ekind (Current_Scope) = E_Package
            then
               Set_Static_Elaboration_Desired (Current_Scope, True);
            else
               Error_Pragma ("pragma% must apply to a library-level package");
            end if;

         ------------------
         -- Storage_Size --
         ------------------

         --  pragma Storage_Size (EXPRESSION);

         when Pragma_Storage_Size => Storage_Size : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;

         begin
            Check_No_Identifiers;
            Check_Arg_Count (1);

            --  The expression must be analyzed in the special manner described
            --  in "Handling of Default Expressions" in sem.ads.

            Arg := Get_Pragma_Arg (Arg1);
            Preanalyze_Spec_Expression (Arg, Any_Integer);

            if not Is_OK_Static_Expression (Arg) then
               Check_Restriction (Static_Storage_Size, Arg);
            end if;

            if Nkind (P) /= N_Task_Definition then
               Pragma_Misplaced;
               return;

            else
               if Has_Storage_Size_Pragma (P) then
                  Error_Pragma ("duplicate pragma% not allowed");
               else
                  Set_Has_Storage_Size_Pragma (P, True);
               end if;

               Record_Rep_Item (Defining_Identifier (Parent (P)), N);
            end if;
         end Storage_Size;

         ------------------
         -- Storage_Unit --
         ------------------

         --  pragma Storage_Unit (NUMERIC_LITERAL);

         --  Only permitted argument is System'Storage_Unit value

         when Pragma_Storage_Unit =>
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Integer_Literal (Arg1);

            if Intval (Get_Pragma_Arg (Arg1)) /=
              UI_From_Int (Ttypes.System_Storage_Unit)
            then
               Error_Msg_Uint_1 := UI_From_Int (Ttypes.System_Storage_Unit);
               Error_Pragma_Arg
                 ("the only allowed argument for pragma% is ^", Arg1);
            end if;

         --------------------
         -- Stream_Convert --
         --------------------

         --  pragma Stream_Convert (
         --    [Entity =>] type_LOCAL_NAME,
         --    [Read   =>] function_NAME,
         --    [Write  =>] function NAME);

         when Pragma_Stream_Convert => Stream_Convert : declare
            procedure Check_OK_Stream_Convert_Function (Arg : Node_Id);
            --  Check that the given argument is the name of a local function
            --  of one argument that is not overloaded earlier in the current
            --  local scope. A check is also made that the argument is a
            --  function with one parameter.

            --------------------------------------
            -- Check_OK_Stream_Convert_Function --
            --------------------------------------

            procedure Check_OK_Stream_Convert_Function (Arg : Node_Id) is
               Ent : Entity_Id;

            begin
               Check_Arg_Is_Local_Name (Arg);
               Ent := Entity (Get_Pragma_Arg (Arg));

               if Has_Homonym (Ent) then
                  Error_Pragma_Arg
                    ("argument for pragma% may not be overloaded", Arg);
               end if;

               if Ekind (Ent) /= E_Function
                 or else No (First_Formal (Ent))
                 or else Present (Next_Formal (First_Formal (Ent)))
               then
                  Error_Pragma_Arg
                    ("argument for pragma% must be function of one argument",
                     Arg);
               elsif Is_Abstract_Subprogram (Ent) then
                  Error_Pragma_Arg
                    ("argument for pragma% cannot be abstract", Arg);
               end if;
            end Check_OK_Stream_Convert_Function;

         --  Start of processing for Stream_Convert

         begin
            GNAT_Pragma;
            Check_Arg_Order ((Name_Entity, Name_Read, Name_Write));
            Check_Arg_Count (3);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Optional_Identifier (Arg2, Name_Read);
            Check_Optional_Identifier (Arg3, Name_Write);
            Check_Arg_Is_Local_Name (Arg1);
            Check_OK_Stream_Convert_Function (Arg2);
            Check_OK_Stream_Convert_Function (Arg3);

            declare
               Typ   : constant Entity_Id :=
                         Underlying_Type (Entity (Get_Pragma_Arg (Arg1)));
               Read  : constant Entity_Id := Entity (Get_Pragma_Arg (Arg2));
               Write : constant Entity_Id := Entity (Get_Pragma_Arg (Arg3));

            begin
               Check_First_Subtype (Arg1);

               --  Check for too early or too late. Note that we don't enforce
               --  the rule about primitive operations in this case, since, as
               --  is the case for explicit stream attributes themselves, these
               --  restrictions are not appropriate. Note that the chaining of
               --  the pragma by Rep_Item_Too_Late is actually the critical
               --  processing done for this pragma.

               if Rep_Item_Too_Early (Typ, N)
                    or else
                  Rep_Item_Too_Late (Typ, N, FOnly => True)
               then
                  return;
               end if;

               --  Return if previous error

               if Etype (Typ) = Any_Type
                    or else
                  Etype (Read) = Any_Type
                    or else
                  Etype (Write) = Any_Type
               then
                  return;
               end if;

               --  Error checks

               if Underlying_Type (Etype (Read)) /= Typ then
                  Error_Pragma_Arg
                    ("incorrect return type for function&", Arg2);
               end if;

               if Underlying_Type (Etype (First_Formal (Write))) /= Typ then
                  Error_Pragma_Arg
                    ("incorrect parameter type for function&", Arg3);
               end if;

               if Underlying_Type (Etype (First_Formal (Read))) /=
                  Underlying_Type (Etype (Write))
               then
                  Error_Pragma_Arg
                    ("result type of & does not match Read parameter type",
                     Arg3);
               end if;
            end;
         end Stream_Convert;

         ------------------
         -- Style_Checks --
         ------------------

         --  pragma Style_Checks (On | Off | ALL_CHECKS | STRING_LITERAL);

         --  This is processed by the parser since some of the style checks
         --  take place during source scanning and parsing. This means that
         --  we don't need to issue error messages here.

         when Pragma_Style_Checks => Style_Checks : declare
            A  : constant Node_Id   := Get_Pragma_Arg (Arg1);
            S  : String_Id;
            C  : Char_Code;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;

            --  Two argument form

            if Arg_Count = 2 then
               Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);

               declare
                  E_Id : Node_Id;
                  E    : Entity_Id;

               begin
                  E_Id := Get_Pragma_Arg (Arg2);
                  Analyze (E_Id);

                  if not Is_Entity_Name (E_Id) then
                     Error_Pragma_Arg
                       ("second argument of pragma% must be entity name",
                        Arg2);
                  end if;

                  E := Entity (E_Id);

                  if not Ignore_Style_Checks_Pragmas then
                     if E = Any_Id then
                        return;
                     else
                        loop
                           Set_Suppress_Style_Checks
                             (E, Chars (Get_Pragma_Arg (Arg1)) = Name_Off);
                           exit when No (Homonym (E));
                           E := Homonym (E);
                        end loop;
                     end if;
                  end if;
               end;

            --  One argument form

            else
               Check_Arg_Count (1);

               if Nkind (A) = N_String_Literal then
                  S := Strval (A);

                  declare
                     Slen    : constant Natural := Natural (String_Length (S));
                     Options : String (1 .. Slen);
                     J       : Positive;

                  begin
                     J := 1;
                     loop
                        C := Get_String_Char (S, Pos (J));
                        exit when not In_Character_Range (C);
                        Options (J) := Get_Character (C);

                        --  If at end of string, set options. As per discussion
                        --  above, no need to check for errors, since we issued
                        --  them in the parser.

                        if J = Slen then
                           if not Ignore_Style_Checks_Pragmas then
                              Set_Style_Check_Options (Options);
                           end if;

                           exit;
                        end if;

                        J := J + 1;
                     end loop;
                  end;

               elsif Nkind (A) = N_Identifier then
                  if Chars (A) = Name_All_Checks then
                     if not Ignore_Style_Checks_Pragmas then
                        if GNAT_Mode then
                           Set_GNAT_Style_Check_Options;
                        else
                           Set_Default_Style_Check_Options;
                        end if;
                     end if;

                  elsif Chars (A) = Name_On then
                     if not Ignore_Style_Checks_Pragmas then
                        Style_Check := True;
                     end if;

                  elsif Chars (A) = Name_Off then
                     if not Ignore_Style_Checks_Pragmas then
                        Style_Check := False;
                     end if;
                  end if;
               end if;
            end if;
         end Style_Checks;

         ------------------------
         -- Subprogram_Variant --
         ------------------------

         --  pragma Subprogram_Variant ( SUBPROGRAM_VARIANT_ITEM
         --                           {, SUBPROGRAM_VARIANT_ITEM } );

         --  SUBPROGRAM_VARIANT_ITEM ::=
         --    CHANGE_DIRECTION => discrete_EXPRESSION

         --  CHANGE_DIRECTION ::= Increases | Decreases

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expressions in:

         --       Analyze_Subprogram_Variant_In_Decl_Part

         --    * Expansion - The annotation is expanded during the expansion of
         --    the related subprogram [body] contract as performed in:

         --       Expand_Subprogram_Contract

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram [body] when it is:

         --       aspect on subprogram declaration
         --       aspect on stand-alone subprogram body
         --       pragma on stand-alone subprogram body

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram [body] is instantiated except for
         --    the "pragma on subprogram declaration" case. In that scenario
         --    the annotation must instantiate itself.

         when Pragma_Subprogram_Variant => Subprogram_Variant : declare
            Spec_Id   : Entity_Id;
            Subp_Decl : Node_Id;
            Subp_Spec : Node_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);

            --  Ensure the proper placement of the pragma. Subprogram_Variant
            --  must be associated with a subprogram declaration or a body that
            --  acts as a spec.

            Subp_Decl :=
              Find_Related_Declaration_Or_Body (N, Do_Checks => True);

            --  Generic subprogram

            if Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
               null;

            --  Body acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body
              and then No (Corresponding_Spec (Subp_Decl))
            then
               null;

            --  Body stub acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
              and then No (Corresponding_Spec_Of_Stub (Subp_Decl))
            then
               null;

            --  Subprogram

            elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then
               Subp_Spec := Specification (Subp_Decl);

               --  Pragma Subprogram_Variant is forbidden on null procedures,
               --  as this may lead to potential ambiguities in behavior when
               --  interface null procedures are involved. Also, it just
               --  wouldn't make sense, because null procedure is not
               --  recursive.

               if Nkind (Subp_Spec) = N_Procedure_Specification
                 and then Null_Present (Subp_Spec)
               then
                  Error_Msg_N (Fix_Error
                    ("pragma % cannot apply to null procedure"), N);
                  return;
               end if;

            else
               Pragma_Misplaced;
               return;
            end if;

            Spec_Id := Unique_Defining_Entity (Subp_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Spec_Id);
            Ensure_Aggregate_Form (Get_Argument (N, Spec_Id));

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Subprogram_Variant_In_Decl_Part.

            Add_Contract_Item (N, Defining_Entity (Subp_Decl));

            --  Fully analyze the pragma when it appears inside a subprogram
            --  body because it cannot benefit from forward references.

            if Nkind (Subp_Decl) in N_Subprogram_Body
                                  | N_Subprogram_Body_Stub
            then
               --  The legality checks of pragma Subprogram_Variant are
               --  affected by the SPARK mode in effect and the volatility
               --  of the context. Analyze all pragmas in a specific order.

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_Subprogram_Variant_In_Decl_Part (N);
            end if;
         end Subprogram_Variant;

         --------------
         -- Subtitle --
         --------------

         --  pragma Subtitle ([Subtitle =>] STRING_LITERAL);

         when Pragma_Subtitle =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Subtitle);
            Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);
            Store_Note (N);

         --------------
         -- Suppress --
         --------------

         --  pragma Suppress (IDENTIFIER [, [On =>] NAME]);

         when Pragma_Suppress =>
            Process_Suppress_Unsuppress (Suppress_Case => True);

         ------------------
         -- Suppress_All --
         ------------------

         --  pragma Suppress_All;

         --  The only check made here is that the pragma has no arguments.
         --  There are no placement rules, and the processing required (setting
         --  the Has_Pragma_Suppress_All flag in the compilation unit node was
         --  taken care of by the parser). Process_Compilation_Unit_Pragmas
         --  then creates and inserts a pragma Suppress (All_Checks).

         when Pragma_Suppress_All =>
            GNAT_Pragma;
            Check_Arg_Count (0);

         -------------------------
         -- Suppress_Debug_Info --
         -------------------------

         --  pragma Suppress_Debug_Info ([Entity =>] LOCAL_NAME);

         when Pragma_Suppress_Debug_Info => Suppress_Debug_Info : declare
            Nam_Id : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);

            Nam_Id := Entity (Get_Pragma_Arg (Arg1));

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Nam_Id);
            Set_Debug_Info_Off (Nam_Id);
         end Suppress_Debug_Info;

         ----------------------------------
         -- Suppress_Exception_Locations --
         ----------------------------------

         --  pragma Suppress_Exception_Locations;

         when Pragma_Suppress_Exception_Locations =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Exception_Locations_Suppressed := True;

         -----------------------------
         -- Suppress_Initialization --
         -----------------------------

         --  pragma Suppress_Initialization ([Entity =>] type_Name);

         when Pragma_Suppress_Initialization => Suppress_Init : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);

            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            E := Entity (E_Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            if not Is_Type (E) and then Ekind (E) /= E_Variable then
               Error_Pragma_Arg
                 ("pragma% requires variable, type or subtype", Arg1);
            end if;

            if Rep_Item_Too_Early (E, N)
                 or else
               Rep_Item_Too_Late (E, N, FOnly => True)
            then
               return;
            end if;

            --  For incomplete/private type, set flag on full view

            if Is_Incomplete_Or_Private_Type (E) then
               if No (Full_View (Base_Type (E))) then
                  Error_Pragma_Arg
                    ("argument of pragma% cannot be an incomplete type", Arg1);
               else
                  Set_Suppress_Initialization (Full_View (E));
               end if;

            --  For first subtype, set flag on base type

            elsif Is_First_Subtype (E) then
               Set_Suppress_Initialization (Base_Type (E));

            --  For other than first subtype, set flag on subtype or variable

            else
               Set_Suppress_Initialization (E);
            end if;
         end Suppress_Init;

         -----------------
         -- System_Name --
         -----------------

         --  pragma System_Name (DIRECT_NAME);

         --  Syntax check: one argument, which must be the identifier GNAT or
         --  the identifier GCC, no other identifiers are acceptable.

         when Pragma_System_Name =>
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_One_Of (Arg1, Name_Gcc, Name_Gnat);

         -----------------------------
         -- Task_Dispatching_Policy --
         -----------------------------

         --  pragma Task_Dispatching_Policy (policy_IDENTIFIER);

         when Pragma_Task_Dispatching_Policy => declare
            DP : Character;

         begin
            Check_Ada_83_Warning;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_Task_Dispatching_Policy (Arg1);
            Check_Valid_Configuration_Pragma;
            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
            DP := Fold_Upper (Name_Buffer (1));

            if Task_Dispatching_Policy /= ' '
              and then Task_Dispatching_Policy /= DP
            then
               Error_Msg_Sloc := Task_Dispatching_Policy_Sloc;
               Error_Pragma
                 ("task dispatching policy incompatible with policy#");

            --  Set new policy, but always preserve System_Location since we
            --  like the error message with the run time name.

            else
               Task_Dispatching_Policy := DP;

               if Task_Dispatching_Policy_Sloc /= System_Location then
                  Task_Dispatching_Policy_Sloc := Loc;
               end if;
            end if;
         end;

         ---------------
         -- Task_Info --
         ---------------

         --  pragma Task_Info (EXPRESSION);

         when Pragma_Task_Info => Task_Info : declare
            P   : constant Node_Id := Parent (N);
            Ent : Entity_Id;

         begin
            GNAT_Pragma;

            if Warn_On_Obsolescent_Feature then
               Error_Msg_N
                 ("'G'N'A'T pragma Task_Info is now obsolete, use 'C'P'U "
                  & "instead?j?", N);
            end if;

            if Nkind (P) /= N_Task_Definition then
               Error_Pragma ("pragma% must appear in task definition");
            end if;

            Check_No_Identifiers;
            Check_Arg_Count (1);

            Analyze_And_Resolve
              (Get_Pragma_Arg (Arg1), RTE (RE_Task_Info_Type));

            if Etype (Get_Pragma_Arg (Arg1)) = Any_Type then
               return;
            end if;

            Ent := Defining_Identifier (Parent (P));

            --  Check duplicate pragma before we chain the pragma in the Rep
            --  Item chain of Ent.

            if Has_Rep_Pragma
                 (Ent, Name_Task_Info, Check_Parents => False)
            then
               Error_Pragma ("duplicate pragma% not allowed");
            end if;

            Record_Rep_Item (Ent, N);
         end Task_Info;

         ---------------
         -- Task_Name --
         ---------------

         --  pragma Task_Name (string_EXPRESSION);

         when Pragma_Task_Name => Task_Name : declare
            P   : constant Node_Id := Parent (N);
            Arg : Node_Id;
            Ent : Entity_Id;

         begin
            Check_No_Identifiers;
            Check_Arg_Count (1);

            Arg := Get_Pragma_Arg (Arg1);

            --  The expression is used in the call to Create_Task, and must be
            --  expanded there, not in the context of the current spec. It must
            --  however be analyzed to capture global references, in case it
            --  appears in a generic context.

            Preanalyze_And_Resolve (Arg, Standard_String);

            if Nkind (P) /= N_Task_Definition then
               Pragma_Misplaced;
            end if;

            Ent := Defining_Identifier (Parent (P));

            --  Check duplicate pragma before we chain the pragma in the Rep
            --  Item chain of Ent.

            if Has_Rep_Pragma
                 (Ent, Name_Task_Name, Check_Parents => False)
            then
               Error_Pragma ("duplicate pragma% not allowed");
            end if;

            Record_Rep_Item (Ent, N);
         end Task_Name;

         ------------------
         -- Task_Storage --
         ------------------

         --  pragma Task_Storage (
         --     [Task_Type =>] LOCAL_NAME,
         --     [Top_Guard =>] static_integer_EXPRESSION);

         when Pragma_Task_Storage => Task_Storage : declare
            Args  : Args_List (1 .. 2);
            Names : constant Name_List (1 .. 2) := (
                      Name_Task_Type,
                      Name_Top_Guard);

            Task_Type : Node_Id renames Args (1);
            Top_Guard : Node_Id renames Args (2);

            Ent : Entity_Id;

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);

            if No (Task_Type) then
               Error_Pragma
                 ("missing task_type argument for pragma%");
            end if;

            Check_Arg_Is_Local_Name (Task_Type);

            Ent := Entity (Task_Type);

            if not Is_Task_Type (Ent) then
               Error_Pragma_Arg
                 ("argument for pragma% must be task type", Task_Type);
            end if;

            if No (Top_Guard) then
               Error_Pragma_Arg
                 ("pragma% takes two arguments", Task_Type);
            else
               Check_Arg_Is_OK_Static_Expression (Top_Guard, Any_Integer);
            end if;

            Check_First_Subtype (Task_Type);

            if Rep_Item_Too_Late (Ent, N) then
               raise Pragma_Exit;
            end if;
         end Task_Storage;

         ---------------
         -- Test_Case --
         ---------------

         --  pragma Test_Case
         --    ([Name     =>] Static_String_EXPRESSION
         --    ,[Mode     =>] MODE_TYPE
         --   [, Requires =>  Boolean_EXPRESSION]
         --   [, Ensures  =>  Boolean_EXPRESSION]);

         --  MODE_TYPE ::= Nominal | Robustness

         --  Characteristics:

         --    * Analysis - The annotation undergoes initial checks to verify
         --    the legal placement and context. Secondary checks preanalyze the
         --    expressions in:

         --       Analyze_Test_Case_In_Decl_Part

         --    * Expansion - None.

         --    * Template - The annotation utilizes the generic template of the
         --    related subprogram when it is:

         --       aspect on subprogram declaration

         --    The annotation must prepare its own template when it is:

         --       pragma on subprogram declaration

         --    * Globals - Capture of global references must occur after full
         --    analysis.

         --    * Instance - The annotation is instantiated automatically when
         --    the related generic subprogram is instantiated except for the
         --    "pragma on subprogram declaration" case. In that scenario the
         --    annotation must instantiate itself.

         when Pragma_Test_Case => Test_Case : declare
            procedure Check_Distinct_Name (Subp_Id : Entity_Id);
            --  Ensure that the contract of subprogram Subp_Id does not contain
            --  another Test_Case pragma with the same Name as the current one.

            -------------------------
            -- Check_Distinct_Name --
            -------------------------

            procedure Check_Distinct_Name (Subp_Id : Entity_Id) is
               Items : constant Node_Id   := Contract (Subp_Id);
               Name  : constant String_Id := Get_Name_From_CTC_Pragma (N);
               Prag  : Node_Id;

            begin
               --  Inspect all Test_Case pragma of the related subprogram
               --  looking for one with a duplicate "Name" argument.

               if Present (Items) then
                  Prag := Contract_Test_Cases (Items);
                  while Present (Prag) loop
                     if Pragma_Name (Prag) = Name_Test_Case
                       and then Prag /= N
                       and then String_Equal
                                  (Name, Get_Name_From_CTC_Pragma (Prag))
                     then
                        Error_Msg_Sloc := Sloc (Prag);
                        Error_Pragma ("name for pragma % is already used #");
                     end if;

                     Prag := Next_Pragma (Prag);
                  end loop;
               end if;
            end Check_Distinct_Name;

            --  Local variables

            Pack_Decl : constant Node_Id := Unit (Cunit (Current_Sem_Unit));
            Asp_Arg   : Node_Id;
            Context   : Node_Id;
            Subp_Decl : Node_Id;
            Subp_Id   : Entity_Id;

         --  Start of processing for Test_Case

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (2);
            Check_At_Most_N_Arguments (4);
            Check_Arg_Order
              ((Name_Name, Name_Mode, Name_Requires, Name_Ensures));

            --  Argument "Name"

            Check_Optional_Identifier (Arg1, Name_Name);
            Check_Arg_Is_OK_Static_Expression (Arg1, Standard_String);

            --  Argument "Mode"

            Check_Optional_Identifier (Arg2, Name_Mode);
            Check_Arg_Is_One_Of (Arg2, Name_Nominal, Name_Robustness);

            --  Arguments "Requires" and "Ensures"

            if Present (Arg3) then
               if Present (Arg4) then
                  Check_Identifier (Arg3, Name_Requires);
                  Check_Identifier (Arg4, Name_Ensures);
               else
                  Check_Identifier_Is_One_Of
                    (Arg3, Name_Requires, Name_Ensures);
               end if;
            end if;

            --  Pragma Test_Case must be associated with a subprogram declared
            --  in a library-level package. First determine whether the current
            --  compilation unit is a legal context.

            if Nkind (Pack_Decl) in N_Package_Declaration
                                  | N_Generic_Package_Declaration
            then
               null;

            --  Otherwise the placement is illegal

            else
               Error_Pragma
                 ("pragma % must be specified within a package declaration");
               return;
            end if;

            Subp_Decl := Find_Related_Declaration_Or_Body (N);

            --  Find the enclosing context

            Context := Parent (Subp_Decl);

            if Present (Context) then
               Context := Parent (Context);
            end if;

            --  Verify the placement of the pragma

            if Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration then
               Error_Pragma
                 ("pragma % cannot be applied to abstract subprogram");
               return;

            elsif Nkind (Subp_Decl) = N_Entry_Declaration then
               Error_Pragma ("pragma % cannot be applied to entry");
               return;

            --  The context is a [generic] subprogram declared at the top level
            --  of the [generic] package unit.

            elsif Nkind (Subp_Decl) in N_Generic_Subprogram_Declaration
                                     | N_Subprogram_Declaration
              and then Present (Context)
              and then Nkind (Context) in N_Generic_Package_Declaration
                                        | N_Package_Declaration
            then
               null;

            --  Otherwise the placement is illegal

            else
               Error_Pragma
                 ("pragma % must be applied to a library-level subprogram "
                  & "declaration");
               return;
            end if;

            Subp_Id := Defining_Entity (Subp_Decl);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Subp_Id);

            --  Chain the pragma on the contract for further processing by
            --  Analyze_Test_Case_In_Decl_Part.

            Add_Contract_Item (N, Subp_Id);

            --  Preanalyze the original aspect argument "Name" for a generic
            --  subprogram to properly capture global references.

            if Is_Generic_Subprogram (Subp_Id) then
               Asp_Arg := Test_Case_Arg (N, Name_Name, From_Aspect => True);

               if Present (Asp_Arg) then

                  --  The argument appears with an identifier in association
                  --  form.

                  if Nkind (Asp_Arg) = N_Component_Association then
                     Asp_Arg := Expression (Asp_Arg);
                  end if;

                  Check_Expr_Is_OK_Static_Expression
                    (Asp_Arg, Standard_String);
               end if;
            end if;

            --  Ensure that the all Test_Case pragmas of the related subprogram
            --  have distinct names.

            Check_Distinct_Name (Subp_Id);

            --  Fully analyze the pragma when it appears inside an entry
            --  or subprogram body because it cannot benefit from forward
            --  references.

            if Nkind (Subp_Decl) in N_Entry_Body
                                  | N_Subprogram_Body
                                  | N_Subprogram_Body_Stub
            then
               --  The legality checks of pragma Test_Case are affected by the
               --  SPARK mode in effect and the volatility of the context.
               --  Analyze all pragmas in a specific order.

               Analyze_If_Present (Pragma_SPARK_Mode);
               Analyze_If_Present (Pragma_Volatile_Function);
               Analyze_Test_Case_In_Decl_Part (N);
            end if;
         end Test_Case;

         --------------------------
         -- Thread_Local_Storage --
         --------------------------

         --  pragma Thread_Local_Storage ([Entity =>] LOCAL_NAME);

         when Pragma_Thread_Local_Storage => Thread_Local_Storage : declare
            E  : Entity_Id;
            Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);

            Id := Get_Pragma_Arg (Arg1);
            Analyze (Id);

            if not Is_Entity_Name (Id)
              or else Ekind (Entity (Id)) /= E_Variable
            then
               Error_Pragma_Arg ("local variable name required", Arg1);
            end if;

            E := Entity (Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);

            if Rep_Item_Too_Early (E, N)
                 or else
               Rep_Item_Too_Late (E, N)
            then
               raise Pragma_Exit;
            end if;

            Set_Has_Pragma_Thread_Local_Storage (E);
            Set_Has_Gigi_Rep_Item (E);
         end Thread_Local_Storage;

         ----------------
         -- Time_Slice --
         ----------------

         --  pragma Time_Slice (static_duration_EXPRESSION);

         when Pragma_Time_Slice => Time_Slice : declare
            Val : Ureal;
            Nod : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_In_Main_Program;
            Check_Arg_Is_OK_Static_Expression (Arg1, Standard_Duration);

            if not Error_Posted (Arg1) then
               Nod := Next (N);
               while Present (Nod) loop
                  if Nkind (Nod) = N_Pragma
                    and then Pragma_Name (Nod) = Name_Time_Slice
                  then
                     Error_Msg_Name_1 := Pname;
                     Error_Msg_N ("duplicate pragma% not permitted", Nod);
                  end if;

                  Next (Nod);
               end loop;
            end if;

            --  Process only if in main unit

            if Get_Source_Unit (Loc) = Main_Unit then
               Opt.Time_Slice_Set := True;
               Val := Expr_Value_R (Get_Pragma_Arg (Arg1));

               if Val <= Ureal_0 then
                  Opt.Time_Slice_Value := 0;

               elsif Val > UR_From_Uint (UI_From_Int (1000)) then
                  Opt.Time_Slice_Value := 1_000_000_000;

               else
                  Opt.Time_Slice_Value :=
                    UI_To_Int (UR_To_Uint (Val * UI_From_Int (1_000_000)));
               end if;
            end if;
         end Time_Slice;

         -----------
         -- Title --
         -----------

         --  pragma Title (TITLING_OPTION [, TITLING OPTION]);

         --   TITLING_OPTION ::=
         --     [Title =>] STRING_LITERAL
         --   | [Subtitle =>] STRING_LITERAL

         when Pragma_Title => Title : declare
            Args  : Args_List (1 .. 2);
            Names : constant Name_List (1 .. 2) := (
                      Name_Title,
                      Name_Subtitle);

         begin
            GNAT_Pragma;
            Gather_Associations (Names, Args);
            Store_Note (N);

            for J in 1 .. 2 loop
               if Present (Args (J)) then
                  Check_Arg_Is_OK_Static_Expression
                    (Args (J), Standard_String);
               end if;
            end loop;
         end Title;

         ----------------------------
         -- Type_Invariant[_Class] --
         ----------------------------

         --  pragma Type_Invariant[_Class]
         --    ([Entity =>] type_LOCAL_NAME,
         --     [Check  =>] EXPRESSION);

         when Pragma_Type_Invariant
            | Pragma_Type_Invariant_Class
         =>
         Type_Invariant : declare
            I_Pragma : Node_Id;

         begin
            Check_Arg_Count (2);

            --  Rewrite Type_Invariant[_Class] pragma as an Invariant pragma,
            --  setting Class_Present for the Type_Invariant_Class case.

            Set_Class_Present (N, Prag_Id = Pragma_Type_Invariant_Class);
            I_Pragma := New_Copy (N);
            Set_Pragma_Identifier
              (I_Pragma, Make_Identifier (Loc, Name_Invariant));
            Rewrite (N, I_Pragma);
            Set_Analyzed (N, False);
            Analyze (N);
         end Type_Invariant;

         ---------------------
         -- Unchecked_Union --
         ---------------------

         --  pragma Unchecked_Union (first_subtype_LOCAL_NAME)

         when Pragma_Unchecked_Union => Unchecked_Union : declare
            Assoc   : constant Node_Id := Arg1;
            Type_Id : constant Node_Id := Get_Pragma_Arg (Assoc);
            Clist   : Node_Id;
            Comp    : Node_Id;
            Tdef    : Node_Id;
            Typ     : Entity_Id;
            Variant : Node_Id;
            Vpart   : Node_Id;

         begin
            Ada_2005_Pragma;
            Check_No_Identifiers;
            Check_Arg_Count (1);
            Check_Arg_Is_Local_Name (Arg1);

            Find_Type (Type_Id);

            Typ := Entity (Type_Id);

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Typ);

            if Typ = Any_Type
              or else Rep_Item_Too_Early (Typ, N)
            then
               return;
            else
               Typ := Underlying_Type (Typ);
            end if;

            if Rep_Item_Too_Late (Typ, N) then
               return;
            end if;

            Check_First_Subtype (Arg1);

            --  Note remaining cases are references to a type in the current
            --  declarative part. If we find an error, we post the error on
            --  the relevant type declaration at an appropriate point.

            if not Is_Record_Type (Typ) then
               Error_Msg_N ("unchecked union must be record type", Typ);
               return;

            elsif Is_Tagged_Type (Typ) then
               Error_Msg_N ("unchecked union must not be tagged", Typ);
               return;

            elsif not Has_Discriminants (Typ) then
               Error_Msg_N
                 ("unchecked union must have one discriminant", Typ);
               return;

            --  Note: in previous versions of GNAT we used to check for limited
            --  types and give an error, but in fact the standard does allow
            --  Unchecked_Union on limited types, so this check was removed.

            --  Similarly, GNAT used to require that all discriminants have
            --  default values, but this is not mandated by the RM.

            --  Proceed with basic error checks completed

            else
               Tdef  := Type_Definition (Declaration_Node (Typ));
               Clist := Component_List (Tdef);

               --  Check presence of component list and variant part

               if No (Clist) or else No (Variant_Part (Clist)) then
                  Error_Msg_N
                    ("unchecked union must have variant part", Tdef);
                  return;
               end if;

               --  Check components

               Comp := First_Non_Pragma (Component_Items (Clist));
               while Present (Comp) loop
                  Check_Component (Comp, Typ);
                  Next_Non_Pragma (Comp);
               end loop;

               --  Check variant part

               Vpart := Variant_Part (Clist);

               Variant := First_Non_Pragma (Variants (Vpart));
               while Present (Variant) loop
                  Check_Variant (Variant, Typ);
                  Next_Non_Pragma (Variant);
               end loop;
            end if;

            Set_Is_Unchecked_Union  (Typ);
            Set_Convention (Typ, Convention_C);
            Set_Has_Unchecked_Union (Base_Type (Typ));
            Set_Is_Unchecked_Union  (Base_Type (Typ));
         end Unchecked_Union;

         ----------------------------
         -- Unevaluated_Use_Of_Old --
         ----------------------------

         --  pragma Unevaluated_Use_Of_Old (Error | Warn | Allow);

         when Pragma_Unevaluated_Use_Of_Old =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Arg_Is_One_Of (Arg1, Name_Error, Name_Warn, Name_Allow);

            --  Suppress/Unsuppress can appear as a configuration pragma, or in
            --  a declarative part or a package spec.

            if not Is_Configuration_Pragma then
               Check_Is_In_Decl_Part_Or_Package_Spec;
            end if;

            --  Store proper setting of Uneval_Old

            Get_Name_String (Chars (Get_Pragma_Arg (Arg1)));
            Uneval_Old := Fold_Upper (Name_Buffer (1));

         ------------------------
         -- Unimplemented_Unit --
         ------------------------

         --  pragma Unimplemented_Unit;

         --  Note: this only gives an error if we are generating code, or if
         --  we are in a generic library unit (where the pragma appears in the
         --  body, not in the spec).

         when Pragma_Unimplemented_Unit => Unimplemented_Unit : declare
            Cunitent : constant Entity_Id :=
                         Cunit_Entity (Get_Source_Unit (Loc));

         begin
            GNAT_Pragma;
            Check_Arg_Count (0);

            if Operating_Mode = Generate_Code
              or else Is_Generic_Unit (Cunitent)
            then
               Get_Name_String (Chars (Cunitent));
               Set_Casing (Mixed_Case);
               Write_Str (Name_Buffer (1 .. Name_Len));
               Write_Str (" is not supported in this configuration");
               Write_Eol;
               raise Unrecoverable_Error;
            end if;
         end Unimplemented_Unit;

         ------------------------
         -- Universal_Aliasing --
         ------------------------

         --  pragma Universal_Aliasing [([Entity =>] type_LOCAL_NAME)];

         when Pragma_Universal_Aliasing => Universal_Alias : declare
            E    : Entity_Id;
            E_Id : Node_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg2, Name_Entity);
            Check_Arg_Is_Local_Name (Arg1);
            E_Id := Get_Pragma_Arg (Arg1);

            if Etype (E_Id) = Any_Type then
               return;
            end if;

            E := Entity (E_Id);

            if not Is_Type (E) then
               Error_Pragma_Arg ("pragma% requires type", Arg1);
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, E);
            Set_Universal_Aliasing (Base_Type (E));
            Record_Rep_Item (E, N);
         end Universal_Alias;

         ----------------
         -- Unmodified --
         ----------------

         --  pragma Unmodified (LOCAL_NAME {, LOCAL_NAME});

         when Pragma_Unmodified =>
            Analyze_Unmodified_Or_Unused;

         ------------------
         -- Unreferenced --
         ------------------

         --  pragma Unreferenced (LOCAL_NAME {, LOCAL_NAME});

         --    or when used in a context clause:

         --  pragma Unreferenced (library_unit_NAME {, library_unit_NAME}

         when Pragma_Unreferenced =>
            Analyze_Unreferenced_Or_Unused;

         --------------------------
         -- Unreferenced_Objects --
         --------------------------

         --  pragma Unreferenced_Objects (LOCAL_NAME {, LOCAL_NAME});

         when Pragma_Unreferenced_Objects => Unreferenced_Objects : declare
            Arg      : Node_Id;
            Arg_Expr : Node_Id;
            Arg_Id   : Entity_Id;

            Ghost_Error_Posted : Boolean := False;
            --  Flag set when an error concerning the illegal mix of Ghost and
            --  non-Ghost types is emitted.

            Ghost_Id : Entity_Id := Empty;
            --  The entity of the first Ghost type encountered while processing
            --  the arguments of the pragma.

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);

            Arg := Arg1;
            while Present (Arg) loop
               Check_No_Identifier (Arg);
               Check_Arg_Is_Local_Name (Arg);
               Arg_Expr := Get_Pragma_Arg (Arg);

               if Is_Entity_Name (Arg_Expr) then
                  Arg_Id := Entity (Arg_Expr);

                  if Is_Type (Arg_Id) then
                     Set_Has_Pragma_Unreferenced_Objects (Arg_Id);

                     --  A pragma that applies to a Ghost entity becomes Ghost
                     --  for the purposes of legality checks and removal of
                     --  ignored Ghost code.

                     Mark_Ghost_Pragma (N, Arg_Id);

                     --  Capture the entity of the first Ghost type being
                     --  processed for error detection purposes.

                     if Is_Ghost_Entity (Arg_Id) then
                        if No (Ghost_Id) then
                           Ghost_Id := Arg_Id;
                        end if;

                     --  Otherwise the type is non-Ghost. It is illegal to mix
                     --  references to Ghost and non-Ghost entities
                     --  (SPARK RM 6.9).

                     elsif Present (Ghost_Id)
                       and then not Ghost_Error_Posted
                     then
                        Ghost_Error_Posted := True;

                        Error_Msg_Name_1 := Pname;
                        Error_Msg_N
                          ("pragma % cannot mention ghost and non-ghost types",
                           N);

                        Error_Msg_Sloc := Sloc (Ghost_Id);
                        Error_Msg_NE ("\& # declared as ghost", N, Ghost_Id);

                        Error_Msg_Sloc := Sloc (Arg_Id);
                        Error_Msg_NE ("\& # declared as non-ghost", N, Arg_Id);
                     end if;
                  else
                     Error_Pragma_Arg
                       ("argument for pragma% must be type or subtype", Arg);
                  end if;
               else
                  Error_Pragma_Arg
                    ("argument for pragma% must be type or subtype", Arg);
               end if;

               Next (Arg);
            end loop;
         end Unreferenced_Objects;

         ------------------------------
         -- Unreserve_All_Interrupts --
         ------------------------------

         --  pragma Unreserve_All_Interrupts;

         when Pragma_Unreserve_All_Interrupts =>
            GNAT_Pragma;
            Check_Arg_Count (0);

            if In_Extended_Main_Code_Unit (Main_Unit_Entity) then
               Unreserve_All_Interrupts := True;
            end if;

         ----------------
         -- Unsuppress --
         ----------------

         --  pragma Unsuppress (IDENTIFIER [, [On =>] NAME]);

         when Pragma_Unsuppress =>
            Ada_2005_Pragma;
            Process_Suppress_Unsuppress (Suppress_Case => False);

         ------------
         -- Unused --
         ------------

         --  pragma Unused (LOCAL_NAME {, LOCAL_NAME});

         when Pragma_Unused =>
            Analyze_Unmodified_Or_Unused   (Is_Unused => True);
            Analyze_Unreferenced_Or_Unused (Is_Unused => True);

         -------------------
         -- Use_VADS_Size --
         -------------------

         --  pragma Use_VADS_Size;

         when Pragma_Use_VADS_Size =>
            GNAT_Pragma;
            Check_Arg_Count (0);
            Check_Valid_Configuration_Pragma;
            Use_VADS_Size := True;

         ---------------------
         -- Validity_Checks --
         ---------------------

         --  pragma Validity_Checks (On | Off | ALL_CHECKS | STRING_LITERAL);

         when Pragma_Validity_Checks => Validity_Checks : declare
            A  : constant Node_Id := Get_Pragma_Arg (Arg1);
            S  : String_Id;
            C  : Char_Code;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;

            --  Pragma always active unless in CodePeer or GNATprove modes,
            --  which use a fixed configuration of validity checks.

            if not (CodePeer_Mode or GNATprove_Mode) then
               if Nkind (A) = N_String_Literal then
                  S := Strval (A);

                  declare
                     Slen    : constant Natural := Natural (String_Length (S));
                     Options : String (1 .. Slen);
                     J       : Positive;

                  begin
                     --  Couldn't we use a for loop here over Options'Range???

                     J := 1;
                     loop
                        C := Get_String_Char (S, Pos (J));

                        --  This is a weird test, it skips setting validity
                        --  checks entirely if any element of S is out of
                        --  range of Character, what is that about ???

                        exit when not In_Character_Range (C);
                        Options (J) := Get_Character (C);

                        if J = Slen then
                           Set_Validity_Check_Options (Options);
                           exit;
                        else
                           J := J + 1;
                        end if;
                     end loop;
                  end;

               elsif Nkind (A) = N_Identifier then
                  if Chars (A) = Name_All_Checks then
                     Set_Validity_Check_Options ("a");
                  elsif Chars (A) = Name_On then
                     Validity_Checks_On := True;
                  elsif Chars (A) = Name_Off then
                     Validity_Checks_On := False;
                  end if;
               end if;
            end if;
         end Validity_Checks;

         --------------
         -- Volatile --
         --------------

         --  pragma Volatile (LOCAL_NAME);

         when Pragma_Volatile =>
            Process_Atomic_Independent_Shared_Volatile;

         -------------------------
         -- Volatile_Components --
         -------------------------

         --  pragma Volatile_Components (array_LOCAL_NAME);

         --  Volatile is handled by the same circuit as Atomic_Components

         --------------------------
         -- Volatile_Full_Access --
         --------------------------

         --  pragma Volatile_Full_Access (LOCAL_NAME);

         when Pragma_Volatile_Full_Access =>
            GNAT_Pragma;
            Process_Atomic_Independent_Shared_Volatile;

         -----------------------
         -- Volatile_Function --
         -----------------------

         --  pragma Volatile_Function [ (boolean_EXPRESSION) ];

         when Pragma_Volatile_Function => Volatile_Function : declare
            Over_Id   : Entity_Id;
            Spec_Id   : Entity_Id;
            Subp_Decl : Node_Id;

         begin
            GNAT_Pragma;
            Check_No_Identifiers;
            Check_At_Most_N_Arguments (1);

            Subp_Decl :=
              Find_Related_Declaration_Or_Body (N, Do_Checks => True);

            --  Generic subprogram

            if Nkind (Subp_Decl) = N_Generic_Subprogram_Declaration then
               null;

            --  Body acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body
              and then No (Corresponding_Spec (Subp_Decl))
            then
               null;

            --  Body stub acts as spec

            elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub
              and then No (Corresponding_Spec_Of_Stub (Subp_Decl))
            then
               null;

            --  Subprogram

            elsif Nkind (Subp_Decl) = N_Subprogram_Declaration then
               null;

            else
               Pragma_Misplaced;
               return;
            end if;

            Spec_Id := Unique_Defining_Entity (Subp_Decl);

            if Ekind (Spec_Id) not in E_Function | E_Generic_Function then
               Pragma_Misplaced;
               return;
            end if;

            --  A pragma that applies to a Ghost entity becomes Ghost for the
            --  purposes of legality checks and removal of ignored Ghost code.

            Mark_Ghost_Pragma (N, Spec_Id);

            --  Chain the pragma on the contract for completeness

            Add_Contract_Item (N, Spec_Id);

            --  The legality checks of pragma Volatile_Function are affected by
            --  the SPARK mode in effect. Analyze all pragmas in a specific
            --  order.

            Analyze_If_Present (Pragma_SPARK_Mode);

            --  A volatile function cannot override a non-volatile function
            --  (SPARK RM 7.1.2(15)). Overriding checks are usually performed
            --  in New_Overloaded_Entity, however at that point the pragma has
            --  not been processed yet.

            Over_Id := Overridden_Operation (Spec_Id);

            if Present (Over_Id)
              and then not Is_Volatile_Function (Over_Id)
            then
               Error_Msg_N
                 ("incompatible volatile function values in effect", Spec_Id);

               Error_Msg_Sloc := Sloc (Over_Id);
               Error_Msg_N
                 ("\& declared # with Volatile_Function value False",
                  Spec_Id);

               Error_Msg_Sloc := Sloc (Spec_Id);
               Error_Msg_N
                 ("\overridden # with Volatile_Function value True",
                  Spec_Id);
            end if;

            --  Analyze the Boolean expression (if any)

            if Present (Arg1) then
               Check_Static_Boolean_Expression (Get_Pragma_Arg (Arg1));
            end if;
         end Volatile_Function;

         ----------------------
         -- Warning_As_Error --
         ----------------------

         --  pragma Warning_As_Error (static_string_EXPRESSION);

         when Pragma_Warning_As_Error =>
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_No_Identifiers;
            Check_Valid_Configuration_Pragma;

            if not Is_Static_String_Expression (Arg1) then
               Error_Pragma_Arg
                 ("argument of pragma% must be static string expression",
                  Arg1);

            --  OK static string expression

            else
               Warnings_As_Errors_Count := Warnings_As_Errors_Count + 1;
               Warnings_As_Errors (Warnings_As_Errors_Count) :=
                 new String'(Acquire_Warning_Match_String
                               (Expr_Value_S (Get_Pragma_Arg (Arg1))));
            end if;

         --------------
         -- Warnings --
         --------------

         --  pragma Warnings ([TOOL_NAME,] DETAILS [, REASON]);

         --  DETAILS ::= On | Off
         --  DETAILS ::= On | Off, local_NAME
         --  DETAILS ::= static_string_EXPRESSION
         --  DETAILS ::= On | Off, static_string_EXPRESSION

         --  TOOL_NAME ::= GNAT | GNATprove

         --  REASON ::= Reason => STRING_LITERAL {& STRING_LITERAL}

         --  Note: If the first argument matches an allowed tool name, it is
         --  always considered to be a tool name, even if there is a string
         --  variable of that name.

         --  Note if the second argument of DETAILS is a local_NAME then the
         --  second form is always understood. If the intention is to use
         --  the fourth form, then you can write NAME & "" to force the
         --  intepretation as a static_string_EXPRESSION.

         when Pragma_Warnings => Warnings : declare
            Reason : String_Id;

         begin
            GNAT_Pragma;
            Check_At_Least_N_Arguments (1);

            --  See if last argument is labeled Reason. If so, make sure we
            --  have a string literal or a concatenation of string literals,
            --  and acquire the REASON string. Then remove the REASON argument
            --  by decreasing Num_Args by one; Remaining processing looks only
            --  at first Num_Args arguments).

            declare
               Last_Arg : constant Node_Id :=
                            Last (Pragma_Argument_Associations (N));

            begin
               if Nkind (Last_Arg) = N_Pragma_Argument_Association
                 and then Chars (Last_Arg) = Name_Reason
               then
                  Start_String;
                  Get_Reason_String (Get_Pragma_Arg (Last_Arg));
                  Reason := End_String;
                  Arg_Count := Arg_Count - 1;

                  --  Not allowed in compiler units (bootstrap issues)

                  Check_Compiler_Unit ("Reason for pragma Warnings", N);

               --  No REASON string, set null string as reason

               else
                  Reason := Null_String_Id;
               end if;
            end;

            --  Now proceed with REASON taken care of and eliminated

            Check_No_Identifiers;

            --  If debug flag -gnatd.i is set, pragma is ignored

            if Debug_Flag_Dot_I then
               return;
            end if;

            --  Process various forms of the pragma

            declare
               Argx : constant Node_Id := Get_Pragma_Arg (Arg1);
               Shifted_Args : List_Id;

            begin
               --  See if first argument is a tool name, currently either
               --  GNAT or GNATprove. If so, either ignore the pragma if the
               --  tool used does not match, or continue as if no tool name
               --  was given otherwise, by shifting the arguments.

               if Nkind (Argx) = N_Identifier
                 and then Chars (Argx) in Name_Gnat | Name_Gnatprove
               then
                  if Chars (Argx) = Name_Gnat then
                     if CodePeer_Mode or GNATprove_Mode then
                        Rewrite (N, Make_Null_Statement (Loc));
                        Analyze (N);
                        raise Pragma_Exit;
                     end if;

                  elsif Chars (Argx) = Name_Gnatprove then
                     if not GNATprove_Mode then
                        Rewrite (N, Make_Null_Statement (Loc));
                        Analyze (N);
                        raise Pragma_Exit;
                     end if;

                  else
                     raise Program_Error;
                  end if;

                  --  At this point, the pragma Warnings applies to the tool,
                  --  so continue with shifted arguments.

                  Arg_Count := Arg_Count - 1;

                  if Arg_Count = 1 then
                     Shifted_Args := New_List (New_Copy (Arg2));
                  elsif Arg_Count = 2 then
                     Shifted_Args := New_List (New_Copy (Arg2),
                                               New_Copy (Arg3));
                  elsif Arg_Count = 3 then
                     Shifted_Args := New_List (New_Copy (Arg2),
                                               New_Copy (Arg3),
                                               New_Copy (Arg4));
                  else
                     raise Program_Error;
                  end if;

                  Rewrite (N,
                    Make_Pragma (Loc,
                      Chars                        => Name_Warnings,
                      Pragma_Argument_Associations => Shifted_Args));
                  Analyze (N);
                  raise Pragma_Exit;
               end if;

               --  One argument case

               if Arg_Count = 1 then

                  --  On/Off one argument case was processed by parser

                  if Nkind (Argx) = N_Identifier
                    and then Chars (Argx) in Name_On | Name_Off
                  then
                     null;

                  --  One argument case must be ON/OFF or static string expr

                  elsif not Is_Static_String_Expression (Arg1) then
                     Error_Pragma_Arg
                       ("argument of pragma% must be On/Off or static string "
                        & "expression", Arg1);

                  --  One argument string expression case

                  else
                     declare
                        Lit : constant Node_Id   := Expr_Value_S (Argx);
                        Str : constant String_Id := Strval (Lit);
                        Len : constant Nat       := String_Length (Str);
                        C   : Char_Code;
                        J   : Nat;
                        OK  : Boolean;
                        Chr : Character;

                     begin
                        J := 1;
                        while J <= Len loop
                           C := Get_String_Char (Str, J);
                           OK := In_Character_Range (C);

                           if OK then
                              Chr := Get_Character (C);

                              --  Dash case: only -Wxxx is accepted

                              if J = 1
                                and then J < Len
                                and then Chr = '-'
                              then
                                 J := J + 1;
                                 C := Get_String_Char (Str, J);
                                 Chr := Get_Character (C);
                                 exit when Chr = 'W';
                                 OK := False;

                              --  Dot case

                              elsif J < Len and then Chr = '.' then
                                 J := J + 1;
                                 C := Get_String_Char (Str, J);
                                 Chr := Get_Character (C);

                                 if not Set_Dot_Warning_Switch (Chr) then
                                    Error_Pragma_Arg
                                      ("invalid warning switch character "
                                       & '.' & Chr, Arg1);
                                 end if;

                              --  Non-Dot case

                              else
                                 OK := Set_Warning_Switch (Chr);
                              end if;

                              if not OK then
                                 Error_Pragma_Arg
                                   ("invalid warning switch character " & Chr,
                                    Arg1);
                              end if;

                           else
                              Error_Pragma_Arg
                                ("invalid wide character in warning switch ",
                                 Arg1);
                           end if;

                           J := J + 1;
                        end loop;
                     end;
                  end if;

               --  Two or more arguments (must be two)

               else
                  Check_Arg_Is_One_Of (Arg1, Name_On, Name_Off);
                  Check_Arg_Count (2);

                  declare
                     E_Id : Node_Id;
                     E    : Entity_Id;
                     Err  : Boolean;

                  begin
                     E_Id := Get_Pragma_Arg (Arg2);
                     Analyze (E_Id);

                     --  In the expansion of an inlined body, a reference to
                     --  the formal may be wrapped in a conversion if the
                     --  actual is a conversion. Retrieve the real entity name.

                     if (In_Instance_Body or In_Inlined_Body)
                       and then Nkind (E_Id) = N_Unchecked_Type_Conversion
                     then
                        E_Id := Expression (E_Id);
                     end if;

                     --  Entity name case

                     if Is_Entity_Name (E_Id) then
                        E := Entity (E_Id);

                        if E = Any_Id then
                           return;
                        else
                           loop
                              Set_Warnings_Off
                                (E, (Chars (Get_Pragma_Arg (Arg1)) =
                                      Name_Off));

                              --  Suppress elaboration warnings if the entity
                              --  denotes an elaboration target.

                              if Is_Elaboration_Target (E) then
                                 Set_Is_Elaboration_Warnings_OK_Id (E, False);
                              end if;

                              --  For OFF case, make entry in warnings off
                              --  pragma table for later processing. But we do
                              --  not do that within an instance, since these
                              --  warnings are about what is needed in the
                              --  template, not an instance of it.

                              if Chars (Get_Pragma_Arg (Arg1)) = Name_Off
                                and then Warn_On_Warnings_Off
                                and then not In_Instance
                              then
                                 Warnings_Off_Pragmas.Append ((N, E, Reason));
                              end if;

                              if Is_Enumeration_Type (E) then
                                 declare
                                    Lit : Entity_Id;
                                 begin
                                    Lit := First_Literal (E);
                                    while Present (Lit) loop
                                       Set_Warnings_Off (Lit);
                                       Next_Literal (Lit);
                                    end loop;
                                 end;
                              end if;

                              exit when No (Homonym (E));
                              E := Homonym (E);
                           end loop;
                        end if;

                     --  Error if not entity or static string expression case

                     elsif not Is_Static_String_Expression (Arg2) then
                        Error_Pragma_Arg
                          ("second argument of pragma% must be entity name "
                           & "or static string expression", Arg2);

                     --  Static string expression case

                     else
                        --  Note on configuration pragma case: If this is a
                        --  configuration pragma, then for an OFF pragma, we
                        --  just set Config True in the call, which is all
                        --  that needs to be done. For the case of ON, this
                        --  is normally an error, unless it is canceling the
                        --  effect of a previous OFF pragma in the same file.
                        --  In any other case, an error will be signalled (ON
                        --  with no matching OFF).

                        --  Note: We set Used if we are inside a generic to
                        --  disable the test that the non-config case actually
                        --  cancels a warning. That's because we can't be sure
                        --  there isn't an instantiation in some other unit
                        --  where a warning is suppressed.

                        --  We could do a little better here by checking if the
                        --  generic unit we are inside is public, but for now
                        --  we don't bother with that refinement.

                        declare
                           Message : constant String :=
                             Acquire_Warning_Match_String
                               (Expr_Value_S (Get_Pragma_Arg (Arg2)));
                        begin
                           if Chars (Argx) = Name_Off then
                              Set_Specific_Warning_Off
                                (Loc, Message, Reason,
                                 Config => Is_Configuration_Pragma,
                                 Used => Inside_A_Generic or else In_Instance);

                           elsif Chars (Argx) = Name_On then
                              Set_Specific_Warning_On (Loc, Message, Err);

                              if Err then
                                 Error_Msg_N
                                   ("??pragma Warnings On with no matching "
                                    & "Warnings Off", N);
                              end if;
                           end if;
                        end;
                     end if;
                  end;
               end if;
            end;
         end Warnings;

         -------------------
         -- Weak_External --
         -------------------

         --  pragma Weak_External ([Entity =>] LOCAL_NAME);

         when Pragma_Weak_External => Weak_External : declare
            Ent : Entity_Id;

         begin
            GNAT_Pragma;
            Check_Arg_Count (1);
            Check_Optional_Identifier (Arg1, Name_Entity);
            Check_Arg_Is_Library_Level_Local_Name (Arg1);
            Ent := Entity (Get_Pragma_Arg (Arg1));

            if Rep_Item_Too_Early (Ent, N) then
               return;
            else
               Ent := Underlying_Type (Ent);
            end if;

            --  The pragma applies to entities with addresses

            if Is_Type (Ent) then
               Error_Pragma ("pragma applies to objects and subprograms");
            end if;

            --  The only processing required is to link this item on to the
            --  list of rep items for the given entity. This is accomplished
            --  by the call to Rep_Item_Too_Late (when no error is detected
            --  and False is returned).

            if Rep_Item_Too_Late (Ent, N) then
               return;
            else
               Set_Has_Gigi_Rep_Item (Ent);
            end if;
         end Weak_External;

         -----------------------------
         -- Wide_Character_Encoding --
         -----------------------------

         --  pragma Wide_Character_Encoding (IDENTIFIER);

         when Pragma_Wide_Character_Encoding =>
            GNAT_Pragma;

            --  Nothing to do, handled in parser. Note that we do not enforce
            --  configuration pragma placement, this pragma can appear at any
            --  place in the source, allowing mixed encodings within a single
            --  source program.

            null;

         --------------------
         -- Unknown_Pragma --
         --------------------

         --  Should be impossible, since the case of an unknown pragma is
         --  separately processed before the case statement is entered.

         when Unknown_Pragma =>
            raise Program_Error;
      end case;

      --  AI05-0144: detect dangerous order dependence. Disabled for now,
      --  until AI is formally approved.

      --  Check_Order_Dependence;

   exception
      when Pragma_Exit => null;
   end Analyze_Pragma;

   ---------------------------------------------
   -- Analyze_Pre_Post_Condition_In_Decl_Part --
   ---------------------------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Pre_Post_Condition_In_Decl_Part
     (N         : Node_Id;
      Freeze_Id : Entity_Id := Empty)
   is
      Subp_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id := Unique_Defining_Entity (Subp_Decl);

      Disp_Typ : Entity_Id;
      --  The dispatching type of the subprogram subject to the pre- or
      --  postcondition.

      function Check_References (Nod : Node_Id) return Traverse_Result;
      --  Check that expression Nod does not mention non-primitives of the
      --  type, global objects of the type, or other illegalities described
      --  and implied by AI12-0113.

      ----------------------
      -- Check_References --
      ----------------------

      function Check_References (Nod : Node_Id) return Traverse_Result is
      begin
         if Nkind (Nod) = N_Function_Call
           and then Is_Entity_Name (Name (Nod))
         then
            declare
               Func : constant Entity_Id := Entity (Name (Nod));
               Form : Entity_Id;

            begin
               --  An operation of the type must be a primitive

               if No (Find_Dispatching_Type (Func)) then
                  Form := First_Formal (Func);
                  while Present (Form) loop
                     if Etype (Form) = Disp_Typ then
                        Error_Msg_NE
                          ("operation in class-wide condition must be "
                           & "primitive of &", Nod, Disp_Typ);
                     end if;

                     Next_Formal (Form);
                  end loop;

                  --  A return object of the type is illegal as well

                  if Etype (Func) = Disp_Typ
                    or else Etype (Func) = Class_Wide_Type (Disp_Typ)
                  then
                     Error_Msg_NE
                       ("operation in class-wide condition must be primitive "
                        & "of &", Nod, Disp_Typ);
                  end if;
               end if;
            end;

         elsif Is_Entity_Name (Nod)
           and then
             (Etype (Nod) = Disp_Typ
               or else Etype (Nod) = Class_Wide_Type (Disp_Typ))
           and then Ekind (Entity (Nod)) in E_Constant | E_Variable
         then
            Error_Msg_NE
              ("object in class-wide condition must be formal of type &",
                Nod, Disp_Typ);

         elsif Nkind (Nod) = N_Explicit_Dereference
           and then (Etype (Nod) = Disp_Typ
                      or else Etype (Nod) = Class_Wide_Type (Disp_Typ))
           and then (not Is_Entity_Name (Prefix (Nod))
                      or else not Is_Formal (Entity (Prefix (Nod))))
         then
            Error_Msg_NE
              ("operation in class-wide condition must be primitive of &",
               Nod, Disp_Typ);
         end if;

         return OK;
      end Check_References;

      procedure Check_Class_Wide_Condition is
        new Traverse_Proc (Check_References);

      --  Local variables

      Expr : constant Node_Id := Expression (Get_Argument (N, Spec_Id));

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      Errors        : Nat;
      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Pre_Post_Condition_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Set the Ghost mode in effect from the pragma. Due to the delayed
      --  analysis of the pragma, the Ghost mode at point of declaration and
      --  point of analysis may not necessarily be the same. Use the mode in
      --  effect at the point of declaration.

      Set_Ghost_Mode (N);

      --  Ensure that the subprogram and its formals are visible when analyzing
      --  the expression of the pragma.

      if not In_Open_Scopes (Spec_Id) then
         Restore_Scope := True;
         Push_Scope (Spec_Id);

         if Is_Generic_Subprogram (Spec_Id) then
            Install_Generic_Formals (Spec_Id);
         else
            Install_Formals (Spec_Id);
         end if;
      end if;

      Errors := Serious_Errors_Detected;
      Preanalyze_Assert_Expression (Expr, Standard_Boolean);

      --  Emit a clarification message when the expression contains at least
      --  one undefined reference, possibly due to contract freezing.

      if Errors /= Serious_Errors_Detected
        and then Present (Freeze_Id)
        and then Has_Undefined_Reference (Expr)
      then
         Contract_Freeze_Error (Spec_Id, Freeze_Id);
      end if;

      if Class_Present (N) then

         --  Verify that a class-wide condition is legal, i.e. the operation is
         --  a primitive of a tagged type. Note that a generic subprogram is
         --  not a primitive operation.

         Disp_Typ := Find_Dispatching_Type (Spec_Id);

         if No (Disp_Typ) or else Is_Generic_Subprogram (Spec_Id) then
            Error_Msg_Name_1 := Original_Aspect_Pragma_Name (N);

            if From_Aspect_Specification (N) then
               Error_Msg_N
                 ("aspect % can only be specified for a primitive operation "
                  & "of a tagged type", Corresponding_Aspect (N));

            --  The pragma is a source construct

            else
               Error_Msg_N
                 ("pragma % can only be specified for a primitive operation "
                  & "of a tagged type", N);
            end if;

         --  Remaining semantic checks require a full tree traversal

         else
            Check_Class_Wide_Condition (Expr);
         end if;

      end if;

      if Restore_Scope then
         End_Scope;
      end if;

      --  Currently it is not possible to inline pre/postconditions on a
      --  subprogram subject to pragma Inline_Always.

      Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);
      Set_Is_Analyzed_Pragma (N);

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Pre_Post_Condition_In_Decl_Part;

   ------------------------------------------
   -- Analyze_Refined_Depends_In_Decl_Part --
   ------------------------------------------

   procedure Analyze_Refined_Depends_In_Decl_Part (N : Node_Id) is
      procedure Check_Dependency_Clause
        (Spec_Id       : Entity_Id;
         Dep_Clause    : Node_Id;
         Dep_States    : Elist_Id;
         Refinements   : List_Id;
         Matched_Items : in out Elist_Id);
      --  Try to match a single dependency clause Dep_Clause against one or
      --  more refinement clauses found in list Refinements. Each successful
      --  match eliminates at least one refinement clause from Refinements.
      --  Spec_Id denotes the entity of the related subprogram. Dep_States
      --  denotes the entities of all abstract states which appear in pragma
      --  Depends. Matched_Items contains the entities of all successfully
      --  matched items found in pragma Depends.

      procedure Check_Output_States
        (Spec_Inputs  : Elist_Id;
         Spec_Outputs : Elist_Id;
         Body_Inputs  : Elist_Id;
         Body_Outputs : Elist_Id);
      --  Determine whether pragma Depends contains an output state with a
      --  visible refinement and if so, ensure that pragma Refined_Depends
      --  mentions all its constituents as outputs. Spec_Inputs and
      --  Spec_Outputs denote the inputs and outputs of the subprogram spec
      --  synthesized from pragma Depends. Body_Inputs and Body_Outputs denote
      --  the inputs and outputs of the subprogram body synthesized from pragma
      --  Refined_Depends.

      function Collect_States (Clauses : List_Id) return Elist_Id;
      --  Given a normalized list of dependencies obtained from calling
      --  Normalize_Clauses, return a list containing the entities of all
      --  states appearing in dependencies. It helps in checking refinements
      --  involving a state and a corresponding constituent which is not a
      --  direct constituent of the state.

      procedure Normalize_Clauses (Clauses : List_Id);
      --  Given a list of dependence or refinement clauses Clauses, normalize
      --  each clause by creating multiple dependencies with exactly one input
      --  and one output.

      procedure Remove_Extra_Clauses
        (Clauses       : List_Id;
         Matched_Items : Elist_Id);
      --  Given a list of refinement clauses Clauses, remove all clauses whose
      --  inputs and/or outputs have been previously matched. See the body for
      --  all special cases. Matched_Items contains the entities of all matched
      --  items found in pragma Depends.

      procedure Report_Extra_Clauses (Clauses : List_Id);
      --  Emit an error for each extra clause found in list Clauses

      -----------------------------
      -- Check_Dependency_Clause --
      -----------------------------

      procedure Check_Dependency_Clause
        (Spec_Id       : Entity_Id;
         Dep_Clause    : Node_Id;
         Dep_States    : Elist_Id;
         Refinements   : List_Id;
         Matched_Items : in out Elist_Id)
      is
         Dep_Input  : constant Node_Id := Expression (Dep_Clause);
         Dep_Output : constant Node_Id := First (Choices (Dep_Clause));

         function Is_Already_Matched (Dep_Item : Node_Id) return Boolean;
         --  Determine whether dependency item Dep_Item has been matched in a
         --  previous clause.

         function Is_In_Out_State_Clause return Boolean;
         --  Determine whether dependence clause Dep_Clause denotes an abstract
         --  state that depends on itself (State => State).

         function Is_Null_Refined_State (Item : Node_Id) return Boolean;
         --  Determine whether item Item denotes an abstract state with visible
         --  null refinement.

         procedure Match_Items
           (Dep_Item : Node_Id;
            Ref_Item : Node_Id;
            Matched  : out Boolean);
         --  Try to match dependence item Dep_Item against refinement item
         --  Ref_Item. To match against a possible null refinement (see 2, 9),
         --  set Ref_Item to Empty. Flag Matched is set to True when one of
         --  the following conformance scenarios is in effect:
         --    1) Both items denote null
         --    2) Dep_Item denotes null and Ref_Item is Empty (special case)
         --    3) Both items denote attribute 'Result
         --    4) Both items denote the same object
         --    5) Both items denote the same formal parameter
         --    6) Both items denote the same current instance of a type
         --    7) Both items denote the same discriminant
         --    8) Dep_Item is an abstract state with visible null refinement
         --       and Ref_Item denotes null.
         --    9) Dep_Item is an abstract state with visible null refinement
         --       and Ref_Item is Empty (special case).
         --   10) Dep_Item is an abstract state with full or partial visible
         --       non-null refinement and Ref_Item denotes one of its
         --       constituents.
         --   11) Dep_Item is an abstract state without a full visible
         --       refinement and Ref_Item denotes the same state.
         --  When scenario 10 is in effect, the entity of the abstract state
         --  denoted by Dep_Item is added to list Refined_States.

         procedure Record_Item (Item_Id : Entity_Id);
         --  Store the entity of an item denoted by Item_Id in Matched_Items

         ------------------------
         -- Is_Already_Matched --
         ------------------------

         function Is_Already_Matched (Dep_Item : Node_Id) return Boolean is
            Item_Id : Entity_Id := Empty;

         begin
            --  When the dependency item denotes attribute 'Result, check for
            --  the entity of the related subprogram.

            if Is_Attribute_Result (Dep_Item) then
               Item_Id := Spec_Id;

            elsif Is_Entity_Name (Dep_Item) then
               Item_Id := Available_View (Entity_Of (Dep_Item));
            end if;

            return
              Present (Item_Id) and then Contains (Matched_Items, Item_Id);
         end Is_Already_Matched;

         ----------------------------
         -- Is_In_Out_State_Clause --
         ----------------------------

         function Is_In_Out_State_Clause return Boolean is
            Dep_Input_Id  : Entity_Id;
            Dep_Output_Id : Entity_Id;

         begin
            --  Detect the following clause:
            --    State => State

            if Is_Entity_Name (Dep_Input)
              and then Is_Entity_Name (Dep_Output)
            then
               --  Handle abstract views generated for limited with clauses

               Dep_Input_Id  := Available_View (Entity_Of (Dep_Input));
               Dep_Output_Id := Available_View (Entity_Of (Dep_Output));

               return
                 Ekind (Dep_Input_Id) = E_Abstract_State
                   and then Dep_Input_Id = Dep_Output_Id;
            else
               return False;
            end if;
         end Is_In_Out_State_Clause;

         ---------------------------
         -- Is_Null_Refined_State --
         ---------------------------

         function Is_Null_Refined_State (Item : Node_Id) return Boolean is
            Item_Id : Entity_Id;

         begin
            if Is_Entity_Name (Item) then

               --  Handle abstract views generated for limited with clauses

               Item_Id := Available_View (Entity_Of (Item));

               return
                 Ekind (Item_Id) = E_Abstract_State
                   and then Has_Null_Visible_Refinement (Item_Id);
            else
               return False;
            end if;
         end Is_Null_Refined_State;

         -----------------
         -- Match_Items --
         -----------------

         procedure Match_Items
           (Dep_Item : Node_Id;
            Ref_Item : Node_Id;
            Matched  : out Boolean)
         is
            Dep_Item_Id : Entity_Id;
            Ref_Item_Id : Entity_Id;

         begin
            --  Assume that the two items do not match

            Matched := False;

            --  A null matches null or Empty (special case)

            if Nkind (Dep_Item) = N_Null
              and then (No (Ref_Item) or else Nkind (Ref_Item) = N_Null)
            then
               Matched := True;

            --  Attribute 'Result matches attribute 'Result

            elsif Is_Attribute_Result (Dep_Item)
              and then Is_Attribute_Result (Ref_Item)
            then
               --  Put the entity of the related function on the list of
               --  matched items because attribute 'Result does not carry
               --  an entity similar to states and constituents.

               Record_Item (Spec_Id);
               Matched := True;

            --  Abstract states, current instances of concurrent types,
            --  discriminants, formal parameters and objects.

            elsif Is_Entity_Name (Dep_Item) then

               --  Handle abstract views generated for limited with clauses

               Dep_Item_Id := Available_View (Entity_Of (Dep_Item));

               if Ekind (Dep_Item_Id) = E_Abstract_State then

                  --  An abstract state with visible null refinement matches
                  --  null or Empty (special case).

                  if Has_Null_Visible_Refinement (Dep_Item_Id)
                    and then (No (Ref_Item) or else Nkind (Ref_Item) = N_Null)
                  then
                     Record_Item (Dep_Item_Id);
                     Matched := True;

                  --  An abstract state with visible non-null refinement
                  --  matches one of its constituents, or itself for an
                  --  abstract state with partial visible refinement.

                  elsif Has_Non_Null_Visible_Refinement (Dep_Item_Id) then
                     if Is_Entity_Name (Ref_Item) then
                        Ref_Item_Id := Entity_Of (Ref_Item);

                        if Ekind (Ref_Item_Id) in
                             E_Abstract_State | E_Constant | E_Variable
                          and then Present (Encapsulating_State (Ref_Item_Id))
                          and then Find_Encapsulating_State
                                     (Dep_States, Ref_Item_Id) = Dep_Item_Id
                        then
                           Record_Item (Dep_Item_Id);
                           Matched := True;

                        elsif not Has_Visible_Refinement (Dep_Item_Id)
                          and then Ref_Item_Id = Dep_Item_Id
                        then
                           Record_Item (Dep_Item_Id);
                           Matched := True;
                        end if;
                     end if;

                  --  An abstract state without a visible refinement matches
                  --  itself.

                  elsif Is_Entity_Name (Ref_Item)
                    and then Entity_Of (Ref_Item) = Dep_Item_Id
                  then
                     Record_Item (Dep_Item_Id);
                     Matched := True;
                  end if;

               --  A current instance of a concurrent type, discriminant,
               --  formal parameter or an object matches itself.

               elsif Is_Entity_Name (Ref_Item)
                 and then Entity_Of (Ref_Item) = Dep_Item_Id
               then
                  Record_Item (Dep_Item_Id);
                  Matched := True;
               end if;
            end if;
         end Match_Items;

         -----------------
         -- Record_Item --
         -----------------

         procedure Record_Item (Item_Id : Entity_Id) is
         begin
            if No (Matched_Items) then
               Matched_Items := New_Elmt_List;
            end if;

            Append_Unique_Elmt (Item_Id, Matched_Items);
         end Record_Item;

         --  Local variables

         Clause_Matched  : Boolean := False;
         Dummy           : Boolean := False;
         Inputs_Match    : Boolean;
         Next_Ref_Clause : Node_Id;
         Outputs_Match   : Boolean;
         Ref_Clause      : Node_Id;
         Ref_Input       : Node_Id;
         Ref_Output      : Node_Id;

      --  Start of processing for Check_Dependency_Clause

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            return;
         end if;

         --  Examine all refinement clauses and compare them against the
         --  dependence clause.

         Ref_Clause := First (Refinements);
         while Present (Ref_Clause) loop
            Next_Ref_Clause := Next (Ref_Clause);

            --  Obtain the attributes of the current refinement clause

            Ref_Input  := Expression (Ref_Clause);
            Ref_Output := First (Choices (Ref_Clause));

            --  The current refinement clause matches the dependence clause
            --  when both outputs match and both inputs match. See routine
            --  Match_Items for all possible conformance scenarios.

            --    Depends           Dep_Output => Dep_Input
            --                          ^             ^
            --                        match ?       match ?
            --                          v             v
            --    Refined_Depends   Ref_Output => Ref_Input

            Match_Items
              (Dep_Item => Dep_Input,
               Ref_Item => Ref_Input,
               Matched  => Inputs_Match);

            Match_Items
              (Dep_Item => Dep_Output,
               Ref_Item => Ref_Output,
               Matched  => Outputs_Match);

            --  An In_Out state clause may be matched against a refinement with
            --  a null input or null output as long as the non-null side of the
            --  relation contains a valid constituent of the In_Out_State.

            if Is_In_Out_State_Clause then

               --  Depends         => (State => State)
               --  Refined_Depends => (null => Constit)  --  OK

               if Inputs_Match
                 and then not Outputs_Match
                 and then Nkind (Ref_Output) = N_Null
               then
                  Outputs_Match := True;
               end if;

               --  Depends         => (State => State)
               --  Refined_Depends => (Constit => null)  --  OK

               if not Inputs_Match
                 and then Outputs_Match
                 and then Nkind (Ref_Input) = N_Null
               then
                  Inputs_Match := True;
               end if;
            end if;

            --  The current refinement clause is legally constructed following
            --  the rules in SPARK RM 7.2.5, therefore it can be removed from
            --  the pool of candidates. The seach continues because a single
            --  dependence clause may have multiple matching refinements.

            if Inputs_Match and Outputs_Match then
               Clause_Matched := True;
               Remove (Ref_Clause);
            end if;

            Ref_Clause := Next_Ref_Clause;
         end loop;

         --  Depending on the order or composition of refinement clauses, an
         --  In_Out state clause may not be directly refinable.

         --    Refined_State   => (State => (Constit_1, Constit_2))
         --    Depends         => ((Output, State) => (Input, State))
         --    Refined_Depends => (Constit_1 => Input, Output => Constit_2)

         --  Matching normalized clause (State => State) fails because there is
         --  no direct refinement capable of satisfying this relation. Another
         --  similar case arises when clauses (Constit_1 => Input) and (Output
         --  => Constit_2) are matched first, leaving no candidates for clause
         --  (State => State). Both scenarios are legal as long as one of the
         --  previous clauses mentioned a valid constituent of State.

         if not Clause_Matched
           and then Is_In_Out_State_Clause
           and then Is_Already_Matched (Dep_Input)
         then
            Clause_Matched := True;
         end if;

         --  A clause where the input is an abstract state with visible null
         --  refinement or a 'Result attribute is implicitly matched when the
         --  output has already been matched in a previous clause.

         --    Refined_State   => (State => null)
         --    Depends         => (Output => State)      --  implicitly OK
         --    Refined_Depends => (Output => ...)
         --    Depends         => (...'Result => State)  --  implicitly OK
         --    Refined_Depends => (...'Result => ...)

         if not Clause_Matched
           and then Is_Null_Refined_State (Dep_Input)
           and then Is_Already_Matched (Dep_Output)
         then
            Clause_Matched := True;
         end if;

         --  A clause where the output is an abstract state with visible null
         --  refinement is implicitly matched when the input has already been
         --  matched in a previous clause.

         --    Refined_State     => (State => null)
         --    Depends           => (State => Input)  --  implicitly OK
         --    Refined_Depends   => (... => Input)

         if not Clause_Matched
           and then Is_Null_Refined_State (Dep_Output)
           and then Is_Already_Matched (Dep_Input)
         then
            Clause_Matched := True;
         end if;

         --  At this point either all refinement clauses have been examined or
         --  pragma Refined_Depends contains a solitary null. Only an abstract
         --  state with null refinement can possibly match these cases.

         --    Refined_State   => (State => null)
         --    Depends         => (State => null)
         --    Refined_Depends =>  null            --  OK

         if not Clause_Matched then
            Match_Items
              (Dep_Item => Dep_Input,
               Ref_Item => Empty,
               Matched  => Inputs_Match);

            Match_Items
              (Dep_Item => Dep_Output,
               Ref_Item => Empty,
               Matched  => Outputs_Match);

            Clause_Matched := Inputs_Match and Outputs_Match;
         end if;

         --  If the contents of Refined_Depends are legal, then the current
         --  dependence clause should be satisfied either by an explicit match
         --  or by one of the special cases.

         if not Clause_Matched then
            SPARK_Msg_NE
              (Fix_Msg (Spec_Id, "dependence clause of subprogram & has no "
               & "matching refinement in body"), Dep_Clause, Spec_Id);
         end if;
      end Check_Dependency_Clause;

      -------------------------
      -- Check_Output_States --
      -------------------------

      procedure Check_Output_States
        (Spec_Inputs  : Elist_Id;
         Spec_Outputs : Elist_Id;
         Body_Inputs  : Elist_Id;
         Body_Outputs : Elist_Id)
      is
         procedure Check_Constituent_Usage (State_Id : Entity_Id);
         --  Determine whether all constituents of state State_Id with full
         --  visible refinement are used as outputs in pragma Refined_Depends.
         --  Emit an error if this is not the case (SPARK RM 7.2.4(5)).

         -----------------------------
         -- Check_Constituent_Usage --
         -----------------------------

         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
            Constits     : constant Elist_Id :=
                             Partial_Refinement_Constituents (State_Id);
            Constit_Elmt : Elmt_Id;
            Constit_Id   : Entity_Id;
            Only_Partial : constant Boolean :=
                             not Has_Visible_Refinement (State_Id);
            Posted       : Boolean := False;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  --  Issue an error when a constituent of State_Id is used,
                  --  and State_Id has only partial visible refinement
                  --  (SPARK RM 7.2.4(3d)).

                  if Only_Partial then
                     if (Present (Body_Inputs)
                          and then Appears_In (Body_Inputs, Constit_Id))
                       or else
                        (Present (Body_Outputs)
                          and then Appears_In (Body_Outputs, Constit_Id))
                     then
                        Error_Msg_Name_1 := Chars (State_Id);
                        SPARK_Msg_NE
                          ("constituent & of state % cannot be used in "
                           & "dependence refinement", N, Constit_Id);
                        Error_Msg_Name_1 := Chars (State_Id);
                        SPARK_Msg_N ("\use state % instead", N);
                     end if;

                  --  The constituent acts as an input (SPARK RM 7.2.5(3))

                  elsif Present (Body_Inputs)
                    and then Appears_In (Body_Inputs, Constit_Id)
                  then
                     Error_Msg_Name_1 := Chars (State_Id);
                     SPARK_Msg_NE
                       ("constituent & of state % must act as output in "
                        & "dependence refinement", N, Constit_Id);

                  --  The constituent is altogether missing (SPARK RM 7.2.5(3))

                  elsif No (Body_Outputs)
                    or else not Appears_In (Body_Outputs, Constit_Id)
                  then
                     if not Posted then
                        Posted := True;
                        SPARK_Msg_NE
                          ("output state & must be replaced by all its "
                           & "constituents in dependence refinement",
                           N, State_Id);
                     end if;

                     SPARK_Msg_NE
                       ("\constituent & is missing in output list",
                        N, Constit_Id);
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;
         end Check_Constituent_Usage;

         --  Local variables

         Item      : Node_Id;
         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      --  Start of processing for Check_Output_States

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         --  Inspect the outputs of pragma Depends looking for a state with a
         --  visible refinement.

         elsif Present (Spec_Outputs) then
            Item_Elmt := First_Elmt (Spec_Outputs);
            while Present (Item_Elmt) loop
               Item := Node (Item_Elmt);

               --  Deal with the mixed nature of the input and output lists

               if Nkind (Item) = N_Defining_Identifier then
                  Item_Id := Item;
               else
                  Item_Id := Available_View (Entity_Of (Item));
               end if;

               if Ekind (Item_Id) = E_Abstract_State then

                  --  The state acts as an input-output, skip it

                  if Present (Spec_Inputs)
                    and then Appears_In (Spec_Inputs, Item_Id)
                  then
                     null;

                  --  Ensure that all of the constituents are utilized as
                  --  outputs in pragma Refined_Depends.

                  elsif Has_Non_Null_Visible_Refinement (Item_Id) then
                     Check_Constituent_Usage (Item_Id);
                  end if;
               end if;

               Next_Elmt (Item_Elmt);
            end loop;
         end if;
      end Check_Output_States;

      --------------------
      -- Collect_States --
      --------------------

      function Collect_States (Clauses : List_Id) return Elist_Id is
         procedure Collect_State
           (Item   : Node_Id;
            States : in out Elist_Id);
         --  Add the entity of Item to list States when it denotes to a state

         -------------------
         -- Collect_State --
         -------------------

         procedure Collect_State
           (Item   : Node_Id;
            States : in out Elist_Id)
         is
            Id : Entity_Id;

         begin
            if Is_Entity_Name (Item) then
               Id := Entity_Of (Item);

               if Ekind (Id) = E_Abstract_State then
                  if No (States) then
                     States := New_Elmt_List;
                  end if;

                  Append_Unique_Elmt (Id, States);
               end if;
            end if;
         end Collect_State;

         --  Local variables

         Clause : Node_Id;
         Input  : Node_Id;
         Output : Node_Id;
         States : Elist_Id := No_Elist;

      --  Start of processing for Collect_States

      begin
         Clause := First (Clauses);
         while Present (Clause) loop
            Input  := Expression (Clause);
            Output := First (Choices (Clause));

            Collect_State (Input,  States);
            Collect_State (Output, States);

            Next (Clause);
         end loop;

         return States;
      end Collect_States;

      -----------------------
      -- Normalize_Clauses --
      -----------------------

      procedure Normalize_Clauses (Clauses : List_Id) is
         procedure Normalize_Inputs (Clause : Node_Id);
         --  Normalize clause Clause by creating multiple clauses for each
         --  input item of Clause. It is assumed that Clause has exactly one
         --  output. The transformation is as follows:
         --
         --    Output => (Input_1, Input_2)      --  original
         --
         --    Output => Input_1                 --  normalizations
         --    Output => Input_2

         procedure Normalize_Outputs (Clause : Node_Id);
         --  Normalize clause Clause by creating multiple clause for each
         --  output item of Clause. The transformation is as follows:
         --
         --    (Output_1, Output_2) => Input     --  original
         --
         --     Output_1 => Input                --  normalization
         --     Output_2 => Input

         ----------------------
         -- Normalize_Inputs --
         ----------------------

         procedure Normalize_Inputs (Clause : Node_Id) is
            Inputs     : constant Node_Id    := Expression (Clause);
            Loc        : constant Source_Ptr := Sloc (Clause);
            Output     : constant List_Id    := Choices (Clause);
            Last_Input : Node_Id;
            Input      : Node_Id;
            New_Clause : Node_Id;
            Next_Input : Node_Id;

         begin
            --  Normalization is performed only when the original clause has
            --  more than one input. Multiple inputs appear as an aggregate.

            if Nkind (Inputs) = N_Aggregate then
               Last_Input := Last (Expressions (Inputs));

               --  Create a new clause for each input

               Input := First (Expressions (Inputs));
               while Present (Input) loop
                  Next_Input := Next (Input);

                  --  Unhook the current input from the original input list
                  --  because it will be relocated to a new clause.

                  Remove (Input);

                  --  Special processing for the last input. At this point the
                  --  original aggregate has been stripped down to one element.
                  --  Replace the aggregate by the element itself.

                  if Input = Last_Input then
                     Rewrite (Inputs, Input);

                  --  Generate a clause of the form:
                  --    Output => Input

                  else
                     New_Clause :=
                       Make_Component_Association (Loc,
                         Choices    => New_Copy_List_Tree (Output),
                         Expression => Input);

                     --  The new clause contains replicated content that has
                     --  already been analyzed, mark the clause as analyzed.

                     Set_Analyzed (New_Clause);
                     Insert_After (Clause, New_Clause);
                  end if;

                  Input := Next_Input;
               end loop;
            end if;
         end Normalize_Inputs;

         -----------------------
         -- Normalize_Outputs --
         -----------------------

         procedure Normalize_Outputs (Clause : Node_Id) is
            Inputs      : constant Node_Id    := Expression (Clause);
            Loc         : constant Source_Ptr := Sloc (Clause);
            Outputs     : constant Node_Id    := First (Choices (Clause));
            Last_Output : Node_Id;
            New_Clause  : Node_Id;
            Next_Output : Node_Id;
            Output      : Node_Id;

         begin
            --  Multiple outputs appear as an aggregate. Nothing to do when
            --  the clause has exactly one output.

            if Nkind (Outputs) = N_Aggregate then
               Last_Output := Last (Expressions (Outputs));

               --  Create a clause for each output. Note that each time a new
               --  clause is created, the original output list slowly shrinks
               --  until there is one item left.

               Output := First (Expressions (Outputs));
               while Present (Output) loop
                  Next_Output := Next (Output);

                  --  Unhook the output from the original output list as it
                  --  will be relocated to a new clause.

                  Remove (Output);

                  --  Special processing for the last output. At this point
                  --  the original aggregate has been stripped down to one
                  --  element. Replace the aggregate by the element itself.

                  if Output = Last_Output then
                     Rewrite (Outputs, Output);

                  else
                     --  Generate a clause of the form:
                     --    (Output => Inputs)

                     New_Clause :=
                       Make_Component_Association (Loc,
                         Choices    => New_List (Output),
                         Expression => New_Copy_Tree (Inputs));

                     --  The new clause contains replicated content that has
                     --  already been analyzed. There is not need to reanalyze
                     --  them.

                     Set_Analyzed (New_Clause);
                     Insert_After (Clause, New_Clause);
                  end if;

                  Output := Next_Output;
               end loop;
            end if;
         end Normalize_Outputs;

         --  Local variables

         Clause : Node_Id;

      --  Start of processing for Normalize_Clauses

      begin
         Clause := First (Clauses);
         while Present (Clause) loop
            Normalize_Outputs (Clause);
            Next (Clause);
         end loop;

         Clause := First (Clauses);
         while Present (Clause) loop
            Normalize_Inputs (Clause);
            Next (Clause);
         end loop;
      end Normalize_Clauses;

      --------------------------
      -- Remove_Extra_Clauses --
      --------------------------

      procedure Remove_Extra_Clauses
        (Clauses       : List_Id;
         Matched_Items : Elist_Id)
      is
         Clause      : Node_Id;
         Input       : Node_Id;
         Input_Id    : Entity_Id;
         Next_Clause : Node_Id;
         Output      : Node_Id;
         State_Id    : Entity_Id;

      begin
         Clause := First (Clauses);
         while Present (Clause) loop
            Next_Clause := Next (Clause);

            Input  := Expression (Clause);
            Output := First (Choices (Clause));

            --  Recognize a clause of the form

            --    null => Input

            --  where Input is a constituent of a state which was already
            --  successfully matched. This clause must be removed because it
            --  simply indicates that some of the constituents of the state
            --  are not used.

            --    Refined_State   => (State => (Constit_1, Constit_2))
            --    Depends         => (Output => State)
            --    Refined_Depends => ((Output => Constit_1),  --  State matched
            --                        (null => Constit_2))    --  OK

            if Nkind (Output) = N_Null and then Is_Entity_Name (Input) then

               --  Handle abstract views generated for limited with clauses

               Input_Id := Available_View (Entity_Of (Input));

               --  The input must be a constituent of a state

               if Ekind (Input_Id) in
                    E_Abstract_State | E_Constant | E_Variable
                 and then Present (Encapsulating_State (Input_Id))
               then
                  State_Id := Encapsulating_State (Input_Id);

                  --  The state must have a non-null visible refinement and be
                  --  matched in a previous clause.

                  if Has_Non_Null_Visible_Refinement (State_Id)
                    and then Contains (Matched_Items, State_Id)
                  then
                     Remove (Clause);
                  end if;
               end if;

            --  Recognize a clause of the form

            --    Output => null

            --  where Output is an arbitrary item. This clause must be removed
            --  because a null input legitimately matches anything.

            elsif Nkind (Input) = N_Null then
               Remove (Clause);
            end if;

            Clause := Next_Clause;
         end loop;
      end Remove_Extra_Clauses;

      --------------------------
      -- Report_Extra_Clauses --
      --------------------------

      procedure Report_Extra_Clauses (Clauses : List_Id) is
         Clause : Node_Id;

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         elsif Present (Clauses) then
            Clause := First (Clauses);
            while Present (Clause) loop
               SPARK_Msg_N
                 ("unmatched or extra clause in dependence refinement",
                  Clause);

               Next (Clause);
            end loop;
         end if;
      end Report_Extra_Clauses;

      --  Local variables

      Body_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Body_Id   : constant Entity_Id := Defining_Entity (Body_Decl);
      Errors    : constant Nat       := Serious_Errors_Detected;

      Clause : Node_Id;
      Deps   : Node_Id;
      Dummy  : Boolean;
      Refs   : Node_Id;

      Body_Inputs  : Elist_Id := No_Elist;
      Body_Outputs : Elist_Id := No_Elist;
      --  The inputs and outputs of the subprogram body synthesized from pragma
      --  Refined_Depends.

      Dependencies : List_Id := No_List;
      Depends      : Node_Id;
      --  The corresponding Depends pragma along with its clauses

      Matched_Items : Elist_Id := No_Elist;
      --  A list containing the entities of all successfully matched items
      --  found in pragma Depends.

      Refinements : List_Id := No_List;
      --  The clauses of pragma Refined_Depends

      Spec_Id : Entity_Id;
      --  The entity of the subprogram subject to pragma Refined_Depends

      Spec_Inputs  : Elist_Id := No_Elist;
      Spec_Outputs : Elist_Id := No_Elist;
      --  The inputs and outputs of the subprogram spec synthesized from pragma
      --  Depends.

      States : Elist_Id := No_Elist;
      --  A list containing the entities of all states whose constituents
      --  appear in pragma Depends.

   --  Start of processing for Analyze_Refined_Depends_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      Spec_Id := Unique_Defining_Entity (Body_Decl);

      --  Use the anonymous object as the proper spec when Refined_Depends
      --  applies to the body of a single task type. The object carries the
      --  proper Chars as well as all non-refined versions of pragmas.

      if Is_Single_Concurrent_Type (Spec_Id) then
         Spec_Id := Anonymous_Object (Spec_Id);
      end if;

      Depends := Get_Pragma (Spec_Id, Pragma_Depends);

      --  Subprogram declarations lacks pragma Depends. Refined_Depends is
      --  rendered useless as there is nothing to refine (SPARK RM 7.2.5(2)).

      if No (Depends) then
         SPARK_Msg_NE
           (Fix_Msg (Spec_Id, "useless refinement, declaration of subprogram "
            & "& lacks aspect or pragma Depends"), N, Spec_Id);
         goto Leave;
      end if;

      Deps := Expression (Get_Argument (Depends, Spec_Id));

      --  A null dependency relation renders the refinement useless because it
      --  cannot possibly mention abstract states with visible refinement. Note
      --  that the inverse is not true as states may be refined to null
      --  (SPARK RM 7.2.5(2)).

      if Nkind (Deps) = N_Null then
         SPARK_Msg_NE
           (Fix_Msg (Spec_Id, "useless refinement, subprogram & does not "
            & "depend on abstract state with visible refinement"), N, Spec_Id);
         goto Leave;
      end if;

      --  Analyze Refined_Depends as if it behaved as a regular pragma Depends.
      --  This ensures that the categorization of all refined dependency items
      --  is consistent with their role.

      Analyze_Depends_In_Decl_Part (N);

      --  Do not match dependencies against refinements if Refined_Depends is
      --  illegal to avoid emitting misleading error.

      if Serious_Errors_Detected = Errors then

         --  The related subprogram lacks pragma [Refined_]Global. Synthesize
         --  the inputs and outputs of the subprogram spec and body to verify
         --  the use of states with visible refinement and their constituents.

         if No (Get_Pragma (Spec_Id, Pragma_Global))
           or else No (Get_Pragma (Body_Id, Pragma_Refined_Global))
         then
            Collect_Subprogram_Inputs_Outputs
              (Subp_Id      => Spec_Id,
               Synthesize   => True,
               Subp_Inputs  => Spec_Inputs,
               Subp_Outputs => Spec_Outputs,
               Global_Seen  => Dummy);

            Collect_Subprogram_Inputs_Outputs
              (Subp_Id      => Body_Id,
               Synthesize   => True,
               Subp_Inputs  => Body_Inputs,
               Subp_Outputs => Body_Outputs,
               Global_Seen  => Dummy);

            --  For an output state with a visible refinement, ensure that all
            --  constituents appear as outputs in the dependency refinement.

            Check_Output_States
              (Spec_Inputs  => Spec_Inputs,
               Spec_Outputs => Spec_Outputs,
               Body_Inputs  => Body_Inputs,
               Body_Outputs => Body_Outputs);
         end if;

         --  Multiple dependency clauses appear as component associations of an
         --  aggregate. Note that the clauses are copied because the algorithm
         --  modifies them and this should not be visible in Depends.

         pragma Assert (Nkind (Deps) = N_Aggregate);
         Dependencies := New_Copy_List_Tree (Component_Associations (Deps));
         Normalize_Clauses (Dependencies);

         --  Gather all states which appear in Depends

         States := Collect_States (Dependencies);

         Refs := Expression (Get_Argument (N, Spec_Id));

         if Nkind (Refs) = N_Null then
            Refinements := No_List;

         --  Multiple dependency clauses appear as component associations of an
         --  aggregate. Note that the clauses are copied because the algorithm
         --  modifies them and this should not be visible in Refined_Depends.

         else pragma Assert (Nkind (Refs) = N_Aggregate);
            Refinements := New_Copy_List_Tree (Component_Associations (Refs));
            Normalize_Clauses (Refinements);
         end if;

         --  At this point the clauses of pragmas Depends and Refined_Depends
         --  have been normalized into simple dependencies between one output
         --  and one input. Examine all clauses of pragma Depends looking for
         --  matching clauses in pragma Refined_Depends.

         Clause := First (Dependencies);
         while Present (Clause) loop
            Check_Dependency_Clause
              (Spec_Id       => Spec_Id,
               Dep_Clause    => Clause,
               Dep_States    => States,
               Refinements   => Refinements,
               Matched_Items => Matched_Items);

            Next (Clause);
         end loop;

         --  Pragma Refined_Depends may contain multiple clarification clauses
         --  which indicate that certain constituents do not influence the data
         --  flow in any way. Such clauses must be removed as long as the state
         --  has been matched, otherwise they will be incorrectly flagged as
         --  unmatched.

         --    Refined_State   => (State => (Constit_1, Constit_2))
         --    Depends         => (Output => State)
         --    Refined_Depends => ((Output => Constit_1),  --  State matched
         --                        (null => Constit_2))    --  must be removed

         Remove_Extra_Clauses (Refinements, Matched_Items);

         if Serious_Errors_Detected = Errors then
            Report_Extra_Clauses (Refinements);
         end if;
      end if;

      <<Leave>>
      Set_Is_Analyzed_Pragma (N);
   end Analyze_Refined_Depends_In_Decl_Part;

   -----------------------------------------
   -- Analyze_Refined_Global_In_Decl_Part --
   -----------------------------------------

   procedure Analyze_Refined_Global_In_Decl_Part (N : Node_Id) is
      Global : Node_Id;
      --  The corresponding Global pragma

      Has_In_State       : Boolean := False;
      Has_In_Out_State   : Boolean := False;
      Has_Out_State      : Boolean := False;
      Has_Proof_In_State : Boolean := False;
      --  These flags are set when the corresponding Global pragma has a state
      --  of mode Input, In_Out, Output or Proof_In respectively with a visible
      --  refinement.

      Has_Null_State : Boolean := False;
      --  This flag is set when the corresponding Global pragma has at least
      --  one state with a null refinement.

      In_Constits       : Elist_Id := No_Elist;
      In_Out_Constits   : Elist_Id := No_Elist;
      Out_Constits      : Elist_Id := No_Elist;
      Proof_In_Constits : Elist_Id := No_Elist;
      --  These lists contain the entities of all Input, In_Out, Output and
      --  Proof_In constituents that appear in Refined_Global and participate
      --  in state refinement.

      In_Items       : Elist_Id := No_Elist;
      In_Out_Items   : Elist_Id := No_Elist;
      Out_Items      : Elist_Id := No_Elist;
      Proof_In_Items : Elist_Id := No_Elist;
      --  These lists contain the entities of all Input, In_Out, Output and
      --  Proof_In items defined in the corresponding Global pragma.

      Repeat_Items : Elist_Id := No_Elist;
      --  A list of all global items without full visible refinement found
      --  in pragma Global. These states should be repeated in the global
      --  refinement (SPARK RM 7.2.4(3c)) unless they have a partial visible
      --  refinement, in which case they may be repeated (SPARK RM 7.2.4(3d)).

      Spec_Id : Entity_Id;
      --  The entity of the subprogram subject to pragma Refined_Global

      States : Elist_Id := No_Elist;
      --  A list of all states with full or partial visible refinement found in
      --  pragma Global.

      procedure Check_In_Out_States;
      --  Determine whether the corresponding Global pragma mentions In_Out
      --  states with visible refinement and if so, ensure that one of the
      --  following completions apply to the constituents of the state:
      --    1) there is at least one constituent of mode In_Out
      --    2) there is at least one Input and one Output constituent
      --    3) not all constituents are present and one of them is of mode
      --       Output.
      --  This routine may remove elements from In_Constits, In_Out_Constits,
      --  Out_Constits and Proof_In_Constits.

      procedure Check_Input_States;
      --  Determine whether the corresponding Global pragma mentions Input
      --  states with visible refinement and if so, ensure that at least one of
      --  its constituents appears as an Input item in Refined_Global.
      --  This routine may remove elements from In_Constits, In_Out_Constits,
      --  Out_Constits and Proof_In_Constits.

      procedure Check_Output_States;
      --  Determine whether the corresponding Global pragma mentions Output
      --  states with visible refinement and if so, ensure that all of its
      --  constituents appear as Output items in Refined_Global.
      --  This routine may remove elements from In_Constits, In_Out_Constits,
      --  Out_Constits and Proof_In_Constits.

      procedure Check_Proof_In_States;
      --  Determine whether the corresponding Global pragma mentions Proof_In
      --  states with visible refinement and if so, ensure that at least one of
      --  its constituents appears as a Proof_In item in Refined_Global.
      --  This routine may remove elements from In_Constits, In_Out_Constits,
      --  Out_Constits and Proof_In_Constits.

      procedure Check_Refined_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input);
      --  Verify the legality of a single global list declaration. Global_Mode
      --  denotes the current mode in effect.

      procedure Collect_Global_Items
        (List : Node_Id;
         Mode : Name_Id := Name_Input);
      --  Gather all Input, In_Out, Output and Proof_In items from node List
      --  and separate them in lists In_Items, In_Out_Items, Out_Items and
      --  Proof_In_Items. Flags Has_In_State, Has_In_Out_State, Has_Out_State
      --  and Has_Proof_In_State are set when there is at least one abstract
      --  state with full or partial visible refinement available in the
      --  corresponding mode. Flag Has_Null_State is set when at least state
      --  has a null refinement. Mode denotes the current global mode in
      --  effect.

      function Present_Then_Remove
        (List : Elist_Id;
         Item : Entity_Id) return Boolean;
      --  Search List for a particular entity Item. If Item has been found,
      --  remove it from List. This routine is used to strip lists In_Constits,
      --  In_Out_Constits and Out_Constits of valid constituents.

      procedure Present_Then_Remove (List : Elist_Id; Item : Entity_Id);
      --  Same as function Present_Then_Remove, but do not report the presence
      --  of Item in List.

      procedure Report_Extra_Constituents;
      --  Emit an error for each constituent found in lists In_Constits,
      --  In_Out_Constits and Out_Constits.

      procedure Report_Missing_Items;
      --  Emit an error for each global item not repeated found in list
      --  Repeat_Items.

      -------------------------
      -- Check_In_Out_States --
      -------------------------

      procedure Check_In_Out_States is
         procedure Check_Constituent_Usage (State_Id : Entity_Id);
         --  Determine whether one of the following coverage scenarios is in
         --  effect:
         --    1) there is at least one constituent of mode In_Out or Output
         --    2) there is at least one pair of constituents with modes Input
         --       and Output, or Proof_In and Output.
         --    3) there is at least one constituent of mode Output and not all
         --       constituents are present.
         --  If this is not the case, emit an error (SPARK RM 7.2.4(5)).

         -----------------------------
         -- Check_Constituent_Usage --
         -----------------------------

         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
            Constits      : constant Elist_Id :=
                              Partial_Refinement_Constituents (State_Id);
            Constit_Elmt  : Elmt_Id;
            Constit_Id    : Entity_Id;
            Has_Missing   : Boolean := False;
            In_Out_Seen   : Boolean := False;
            Input_Seen    : Boolean := False;
            Output_Seen   : Boolean := False;
            Proof_In_Seen : Boolean := False;

         begin
            --  Process all the constituents of the state and note their modes
            --  within the global refinement.

            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  if Present_Then_Remove (In_Constits, Constit_Id) then
                     Input_Seen := True;

                  elsif Present_Then_Remove (In_Out_Constits, Constit_Id) then
                     In_Out_Seen := True;

                  elsif Present_Then_Remove (Out_Constits, Constit_Id) then
                     Output_Seen := True;

                  elsif Present_Then_Remove (Proof_In_Constits, Constit_Id)
                  then
                     Proof_In_Seen := True;

                  else
                     Has_Missing := True;
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;

            --  An In_Out constituent is a valid completion

            if In_Out_Seen then
               null;

            --  A pair of one Input/Proof_In and one Output constituent is a
            --  valid completion.

            elsif (Input_Seen or Proof_In_Seen) and Output_Seen then
               null;

            elsif Output_Seen then

               --  A single Output constituent is a valid completion only when
               --  some of the other constituents are missing.

               if Has_Missing then
                  null;

               --  Otherwise all constituents are of mode Output

               else
                  SPARK_Msg_NE
                    ("global refinement of state & must include at least one "
                     & "constituent of mode `In_Out`, `Input`, or `Proof_In`",
                     N, State_Id);
               end if;

            --  The state lacks a completion. When full refinement is visible,
            --  always emit an error (SPARK RM 7.2.4(3a)). When only partial
            --  refinement is visible, emit an error if the abstract state
            --  itself is not utilized (SPARK RM 7.2.4(3d)). In the case where
            --  both are utilized, Check_State_And_Constituent_Use. will issue
            --  the error.

            elsif not Input_Seen
              and then not In_Out_Seen
              and then not Output_Seen
              and then not Proof_In_Seen
            then
               if Has_Visible_Refinement (State_Id)
                 or else Contains (Repeat_Items, State_Id)
               then
                  SPARK_Msg_NE
                    ("missing global refinement of state &", N, State_Id);
               end if;

            --  Otherwise the state has a malformed completion where at least
            --  one of the constituents has a different mode.

            else
               SPARK_Msg_NE
                 ("global refinement of state & redefines the mode of its "
                  & "constituents", N, State_Id);
            end if;
         end Check_Constituent_Usage;

         --  Local variables

         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      --  Start of processing for Check_In_Out_States

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         --  Inspect the In_Out items of the corresponding Global pragma
         --  looking for a state with a visible refinement.

         elsif Has_In_Out_State and then Present (In_Out_Items) then
            Item_Elmt := First_Elmt (In_Out_Items);
            while Present (Item_Elmt) loop
               Item_Id := Node (Item_Elmt);

               --  Ensure that one of the three coverage variants is satisfied

               if Ekind (Item_Id) = E_Abstract_State
                 and then Has_Non_Null_Visible_Refinement (Item_Id)
               then
                  Check_Constituent_Usage (Item_Id);
               end if;

               Next_Elmt (Item_Elmt);
            end loop;
         end if;
      end Check_In_Out_States;

      ------------------------
      -- Check_Input_States --
      ------------------------

      procedure Check_Input_States is
         procedure Check_Constituent_Usage (State_Id : Entity_Id);
         --  Determine whether at least one constituent of state State_Id with
         --  full or partial visible refinement is used and has mode Input.
         --  Ensure that the remaining constituents do not have In_Out or
         --  Output modes. Emit an error if this is not the case
         --  (SPARK RM 7.2.4(5)).

         -----------------------------
         -- Check_Constituent_Usage --
         -----------------------------

         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
            Constits     : constant Elist_Id :=
                             Partial_Refinement_Constituents (State_Id);
            Constit_Elmt : Elmt_Id;
            Constit_Id   : Entity_Id;
            In_Seen      : Boolean := False;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  --  At least one of the constituents appears as an Input

                  if Present_Then_Remove (In_Constits, Constit_Id) then
                     In_Seen := True;

                  --  A Proof_In constituent can refine an Input state as long
                  --  as there is at least one Input constituent present.

                  elsif Present_Then_Remove (Proof_In_Constits, Constit_Id)
                  then
                     null;

                  --  The constituent appears in the global refinement, but has
                  --  mode In_Out or Output (SPARK RM 7.2.4(5)).

                  elsif Present_Then_Remove (In_Out_Constits, Constit_Id)
                    or else Present_Then_Remove (Out_Constits, Constit_Id)
                  then
                     Error_Msg_Name_1 := Chars (State_Id);
                     SPARK_Msg_NE
                       ("constituent & of state % must have mode `Input` in "
                        & "global refinement", N, Constit_Id);
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;

            --  Not one of the constituents appeared as Input. Always emit an
            --  error when the full refinement is visible (SPARK RM 7.2.4(3a)).
            --  When only partial refinement is visible, emit an error if the
            --  abstract state itself is not utilized (SPARK RM 7.2.4(3d)). In
            --  the case where both are utilized, an error will be issued in
            --  Check_State_And_Constituent_Use.

            if not In_Seen
              and then (Has_Visible_Refinement (State_Id)
                         or else Contains (Repeat_Items, State_Id))
            then
               SPARK_Msg_NE
                 ("global refinement of state & must include at least one "
                  & "constituent of mode `Input`", N, State_Id);
            end if;
         end Check_Constituent_Usage;

         --  Local variables

         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      --  Start of processing for Check_Input_States

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         --  Inspect the Input items of the corresponding Global pragma looking
         --  for a state with a visible refinement.

         elsif Has_In_State and then Present (In_Items) then
            Item_Elmt := First_Elmt (In_Items);
            while Present (Item_Elmt) loop
               Item_Id := Node (Item_Elmt);

               --  When full refinement is visible, ensure that at least one of
               --  the constituents is utilized and is of mode Input. When only
               --  partial refinement is visible, ensure that either one of
               --  the constituents is utilized and is of mode Input, or the
               --  abstract state is repeated and no constituent is utilized.

               if Ekind (Item_Id) = E_Abstract_State
                 and then Has_Non_Null_Visible_Refinement (Item_Id)
               then
                  Check_Constituent_Usage (Item_Id);
               end if;

               Next_Elmt (Item_Elmt);
            end loop;
         end if;
      end Check_Input_States;

      -------------------------
      -- Check_Output_States --
      -------------------------

      procedure Check_Output_States is
         procedure Check_Constituent_Usage (State_Id : Entity_Id);
         --  Determine whether all constituents of state State_Id with full
         --  visible refinement are used and have mode Output. Emit an error
         --  if this is not the case (SPARK RM 7.2.4(5)).

         -----------------------------
         -- Check_Constituent_Usage --
         -----------------------------

         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
            Constits     : constant Elist_Id :=
                             Partial_Refinement_Constituents (State_Id);
            Only_Partial : constant Boolean :=
                             not Has_Visible_Refinement (State_Id);
            Constit_Elmt : Elmt_Id;
            Constit_Id   : Entity_Id;
            Posted       : Boolean := False;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  --  Issue an error when a constituent of State_Id is utilized
                  --  and State_Id has only partial visible refinement
                  --  (SPARK RM 7.2.4(3d)).

                  if Only_Partial then
                     if Present_Then_Remove (Out_Constits, Constit_Id)
                       or else Present_Then_Remove (In_Constits, Constit_Id)
                       or else
                         Present_Then_Remove (In_Out_Constits, Constit_Id)
                       or else
                         Present_Then_Remove (Proof_In_Constits, Constit_Id)
                     then
                        Error_Msg_Name_1 := Chars (State_Id);
                        SPARK_Msg_NE
                          ("constituent & of state % cannot be used in global "
                           & "refinement", N, Constit_Id);
                        Error_Msg_Name_1 := Chars (State_Id);
                        SPARK_Msg_N ("\use state % instead", N);
                     end if;

                  elsif Present_Then_Remove (Out_Constits, Constit_Id) then
                     null;

                  --  The constituent appears in the global refinement, but has
                  --  mode Input, In_Out or Proof_In (SPARK RM 7.2.4(5)).

                  elsif Present_Then_Remove (In_Constits, Constit_Id)
                    or else Present_Then_Remove (In_Out_Constits, Constit_Id)
                    or else Present_Then_Remove (Proof_In_Constits, Constit_Id)
                  then
                     Error_Msg_Name_1 := Chars (State_Id);
                     SPARK_Msg_NE
                       ("constituent & of state % must have mode `Output` in "
                        & "global refinement", N, Constit_Id);

                  --  The constituent is altogether missing (SPARK RM 7.2.5(3))

                  else
                     if not Posted then
                        Posted := True;
                        SPARK_Msg_NE
                          ("`Output` state & must be replaced by all its "
                           & "constituents in global refinement", N, State_Id);
                     end if;

                     SPARK_Msg_NE
                       ("\constituent & is missing in output list",
                        N, Constit_Id);
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;
         end Check_Constituent_Usage;

         --  Local variables

         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      --  Start of processing for Check_Output_States

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         --  Inspect the Output items of the corresponding Global pragma
         --  looking for a state with a visible refinement.

         elsif Has_Out_State and then Present (Out_Items) then
            Item_Elmt := First_Elmt (Out_Items);
            while Present (Item_Elmt) loop
               Item_Id := Node (Item_Elmt);

               --  When full refinement is visible, ensure that all of the
               --  constituents are utilized and they have mode Output. When
               --  only partial refinement is visible, ensure that no
               --  constituent is utilized.

               if Ekind (Item_Id) = E_Abstract_State
                 and then Has_Non_Null_Visible_Refinement (Item_Id)
               then
                  Check_Constituent_Usage (Item_Id);
               end if;

               Next_Elmt (Item_Elmt);
            end loop;
         end if;
      end Check_Output_States;

      ---------------------------
      -- Check_Proof_In_States --
      ---------------------------

      procedure Check_Proof_In_States is
         procedure Check_Constituent_Usage (State_Id : Entity_Id);
         --  Determine whether at least one constituent of state State_Id with
         --  full or partial visible refinement is used and has mode Proof_In.
         --  Ensure that the remaining constituents do not have Input, In_Out,
         --  or Output modes. Emit an error if this is not the case
         --  (SPARK RM 7.2.4(5)).

         -----------------------------
         -- Check_Constituent_Usage --
         -----------------------------

         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
            Constits      : constant Elist_Id :=
                              Partial_Refinement_Constituents (State_Id);
            Constit_Elmt  : Elmt_Id;
            Constit_Id    : Entity_Id;
            Proof_In_Seen : Boolean := False;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  --  At least one of the constituents appears as Proof_In

                  if Present_Then_Remove (Proof_In_Constits, Constit_Id) then
                     Proof_In_Seen := True;

                  --  The constituent appears in the global refinement, but has
                  --  mode Input, In_Out or Output (SPARK RM 7.2.4(5)).

                  elsif Present_Then_Remove (In_Constits, Constit_Id)
                    or else Present_Then_Remove (In_Out_Constits, Constit_Id)
                    or else Present_Then_Remove (Out_Constits, Constit_Id)
                  then
                     Error_Msg_Name_1 := Chars (State_Id);
                     SPARK_Msg_NE
                       ("constituent & of state % must have mode `Proof_In` "
                        & "in global refinement", N, Constit_Id);
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;

            --  Not one of the constituents appeared as Proof_In. Always emit
            --  an error when full refinement is visible (SPARK RM 7.2.4(3a)).
            --  When only partial refinement is visible, emit an error if the
            --  abstract state itself is not utilized (SPARK RM 7.2.4(3d)). In
            --  the case where both are utilized, an error will be issued by
            --  Check_State_And_Constituent_Use.

            if not Proof_In_Seen
              and then (Has_Visible_Refinement (State_Id)
                         or else Contains (Repeat_Items, State_Id))
            then
               SPARK_Msg_NE
                 ("global refinement of state & must include at least one "
                  & "constituent of mode `Proof_In`", N, State_Id);
            end if;
         end Check_Constituent_Usage;

         --  Local variables

         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      --  Start of processing for Check_Proof_In_States

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         --  Inspect the Proof_In items of the corresponding Global pragma
         --  looking for a state with a visible refinement.

         elsif Has_Proof_In_State and then Present (Proof_In_Items) then
            Item_Elmt := First_Elmt (Proof_In_Items);
            while Present (Item_Elmt) loop
               Item_Id := Node (Item_Elmt);

               --  Ensure that at least one of the constituents is utilized
               --  and is of mode Proof_In. When only partial refinement is
               --  visible, ensure that either one of the constituents is
               --  utilized and is of mode Proof_In, or the abstract state
               --  is repeated and no constituent is utilized.

               if Ekind (Item_Id) = E_Abstract_State
                 and then Has_Non_Null_Visible_Refinement (Item_Id)
               then
                  Check_Constituent_Usage (Item_Id);
               end if;

               Next_Elmt (Item_Elmt);
            end loop;
         end if;
      end Check_Proof_In_States;

      -------------------------------
      -- Check_Refined_Global_List --
      -------------------------------

      procedure Check_Refined_Global_List
        (List        : Node_Id;
         Global_Mode : Name_Id := Name_Input)
      is
         procedure Check_Refined_Global_Item
           (Item        : Node_Id;
            Global_Mode : Name_Id);
         --  Verify the legality of a single global item declaration. Parameter
         --  Global_Mode denotes the current mode in effect.

         -------------------------------
         -- Check_Refined_Global_Item --
         -------------------------------

         procedure Check_Refined_Global_Item
           (Item        : Node_Id;
            Global_Mode : Name_Id)
         is
            Item_Id : constant Entity_Id := Entity_Of (Item);

            procedure Inconsistent_Mode_Error (Expect : Name_Id);
            --  Issue a common error message for all mode mismatches. Expect
            --  denotes the expected mode.

            -----------------------------
            -- Inconsistent_Mode_Error --
            -----------------------------

            procedure Inconsistent_Mode_Error (Expect : Name_Id) is
            begin
               SPARK_Msg_NE
                 ("global item & has inconsistent modes", Item, Item_Id);

               Error_Msg_Name_1 := Global_Mode;
               Error_Msg_Name_2 := Expect;
               SPARK_Msg_N ("\expected mode %, found mode %", Item);
            end Inconsistent_Mode_Error;

            --  Local variables

            Enc_State : Entity_Id := Empty;
            --  Encapsulating state for constituent, Empty otherwise

         --  Start of processing for Check_Refined_Global_Item

         begin
            if Ekind (Item_Id) in E_Abstract_State | E_Constant | E_Variable
            then
               Enc_State := Find_Encapsulating_State (States, Item_Id);
            end if;

            --  When the state or object acts as a constituent of another
            --  state with a visible refinement, collect it for the state
            --  completeness checks performed later on. Note that the item
            --  acts as a constituent only when the encapsulating state is
            --  present in pragma Global.

            if Present (Enc_State)
              and then (Has_Visible_Refinement (Enc_State)
                         or else Has_Partial_Visible_Refinement (Enc_State))
              and then Contains (States, Enc_State)
            then
               --  If the state has only partial visible refinement, remove it
               --  from the list of items that should be repeated from pragma
               --  Global.

               if not Has_Visible_Refinement (Enc_State) then
                  Present_Then_Remove (Repeat_Items, Enc_State);
               end if;

               if Global_Mode = Name_Input then
                  Append_New_Elmt (Item_Id, In_Constits);

               elsif Global_Mode = Name_In_Out then
                  Append_New_Elmt (Item_Id, In_Out_Constits);

               elsif Global_Mode = Name_Output then
                  Append_New_Elmt (Item_Id, Out_Constits);

               elsif Global_Mode = Name_Proof_In then
                  Append_New_Elmt (Item_Id, Proof_In_Constits);
               end if;

            --  When not a constituent, ensure that both occurrences of the
            --  item in pragmas Global and Refined_Global match. Also remove
            --  it when present from the list of items that should be repeated
            --  from pragma Global.

            else
               Present_Then_Remove (Repeat_Items, Item_Id);

               if Contains (In_Items, Item_Id) then
                  if Global_Mode /= Name_Input then
                     Inconsistent_Mode_Error (Name_Input);
                  end if;

               elsif Contains (In_Out_Items, Item_Id) then
                  if Global_Mode /= Name_In_Out then
                     Inconsistent_Mode_Error (Name_In_Out);
                  end if;

               elsif Contains (Out_Items, Item_Id) then
                  if Global_Mode /= Name_Output then
                     Inconsistent_Mode_Error (Name_Output);
                  end if;

               elsif Contains (Proof_In_Items, Item_Id) then
                  null;

               --  The item does not appear in the corresponding Global pragma,
               --  it must be an extra (SPARK RM 7.2.4(3)).

               else
                  pragma Assert (Present (Global));
                  Error_Msg_Sloc := Sloc (Global);
                  SPARK_Msg_NE
                    ("extra global item & does not refine or repeat any "
                     & "global item #", Item, Item_Id);
               end if;
            end if;
         end Check_Refined_Global_Item;

         --  Local variables

         Item : Node_Id;

      --  Start of processing for Check_Refined_Global_List

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         elsif Nkind (List) = N_Null then
            null;

         --  Single global item declaration

         elsif Nkind (List) in N_Expanded_Name
                             | N_Identifier
                             | N_Selected_Component
         then
            Check_Refined_Global_Item (List, Global_Mode);

         --  Simple global list or moded global list declaration

         elsif Nkind (List) = N_Aggregate then

            --  The declaration of a simple global list appear as a collection
            --  of expressions.

            if Present (Expressions (List)) then
               Item := First (Expressions (List));
               while Present (Item) loop
                  Check_Refined_Global_Item (Item, Global_Mode);
                  Next (Item);
               end loop;

            --  The declaration of a moded global list appears as a collection
            --  of component associations where individual choices denote
            --  modes.

            elsif Present (Component_Associations (List)) then
               Item := First (Component_Associations (List));
               while Present (Item) loop
                  Check_Refined_Global_List
                    (List        => Expression (Item),
                     Global_Mode => Chars (First (Choices (Item))));

                  Next (Item);
               end loop;

            --  Invalid tree

            else
               raise Program_Error;
            end if;

         --  Invalid list

         else
            raise Program_Error;
         end if;
      end Check_Refined_Global_List;

      --------------------------
      -- Collect_Global_Items --
      --------------------------

      procedure Collect_Global_Items
        (List : Node_Id;
         Mode : Name_Id := Name_Input)
      is
         procedure Collect_Global_Item
           (Item      : Node_Id;
            Item_Mode : Name_Id);
         --  Add a single item to the appropriate list. Item_Mode denotes the
         --  current mode in effect.

         -------------------------
         -- Collect_Global_Item --
         -------------------------

         procedure Collect_Global_Item
           (Item      : Node_Id;
            Item_Mode : Name_Id)
         is
            Item_Id : constant Entity_Id := Available_View (Entity_Of (Item));
            --  The above handles abstract views of variables and states built
            --  for limited with clauses.

         begin
            --  Signal that the global list contains at least one abstract
            --  state with a visible refinement. Note that the refinement may
            --  be null in which case there are no constituents.

            if Ekind (Item_Id) = E_Abstract_State then
               if Has_Null_Visible_Refinement (Item_Id) then
                  Has_Null_State := True;

               elsif Has_Non_Null_Visible_Refinement (Item_Id) then
                  Append_New_Elmt (Item_Id, States);

                  if Item_Mode = Name_Input then
                     Has_In_State := True;
                  elsif Item_Mode = Name_In_Out then
                     Has_In_Out_State := True;
                  elsif Item_Mode = Name_Output then
                     Has_Out_State := True;
                  elsif Item_Mode = Name_Proof_In then
                     Has_Proof_In_State := True;
                  end if;
               end if;
            end if;

            --  Record global items without full visible refinement found in
            --  pragma Global which should be repeated in the global refinement
            --  (SPARK RM 7.2.4(3c), SPARK RM 7.2.4(3d)).

            if Ekind (Item_Id) /= E_Abstract_State
              or else not Has_Visible_Refinement (Item_Id)
            then
               Append_New_Elmt (Item_Id, Repeat_Items);
            end if;

            --  Add the item to the proper list

            if Item_Mode = Name_Input then
               Append_New_Elmt (Item_Id, In_Items);
            elsif Item_Mode = Name_In_Out then
               Append_New_Elmt (Item_Id, In_Out_Items);
            elsif Item_Mode = Name_Output then
               Append_New_Elmt (Item_Id, Out_Items);
            elsif Item_Mode = Name_Proof_In then
               Append_New_Elmt (Item_Id, Proof_In_Items);
            end if;
         end Collect_Global_Item;

         --  Local variables

         Item : Node_Id;

      --  Start of processing for Collect_Global_Items

      begin
         if Nkind (List) = N_Null then
            null;

         --  Single global item declaration

         elsif Nkind (List) in N_Expanded_Name
                             | N_Identifier
                             | N_Selected_Component
         then
            Collect_Global_Item (List, Mode);

         --  Single global list or moded global list declaration

         elsif Nkind (List) = N_Aggregate then

            --  The declaration of a simple global list appear as a collection
            --  of expressions.

            if Present (Expressions (List)) then
               Item := First (Expressions (List));
               while Present (Item) loop
                  Collect_Global_Item (Item, Mode);
                  Next (Item);
               end loop;

            --  The declaration of a moded global list appears as a collection
            --  of component associations where individual choices denote mode.

            elsif Present (Component_Associations (List)) then
               Item := First (Component_Associations (List));
               while Present (Item) loop
                  Collect_Global_Items
                    (List => Expression (Item),
                     Mode => Chars (First (Choices (Item))));

                  Next (Item);
               end loop;

            --  Invalid tree

            else
               raise Program_Error;
            end if;

         --  To accommodate partial decoration of disabled SPARK features, this
         --  routine may be called with illegal input. If this is the case, do
         --  not raise Program_Error.

         else
            null;
         end if;
      end Collect_Global_Items;

      -------------------------
      -- Present_Then_Remove --
      -------------------------

      function Present_Then_Remove
        (List : Elist_Id;
         Item : Entity_Id) return Boolean
      is
         Elmt : Elmt_Id;

      begin
         if Present (List) then
            Elmt := First_Elmt (List);
            while Present (Elmt) loop
               if Node (Elmt) = Item then
                  Remove_Elmt (List, Elmt);
                  return True;
               end if;

               Next_Elmt (Elmt);
            end loop;
         end if;

         return False;
      end Present_Then_Remove;

      procedure Present_Then_Remove (List : Elist_Id; Item : Entity_Id) is
         Ignore : Boolean;
      begin
         Ignore := Present_Then_Remove (List, Item);
      end Present_Then_Remove;

      -------------------------------
      -- Report_Extra_Constituents --
      -------------------------------

      procedure Report_Extra_Constituents is
         procedure Report_Extra_Constituents_In_List (List : Elist_Id);
         --  Emit an error for every element of List

         ---------------------------------------
         -- Report_Extra_Constituents_In_List --
         ---------------------------------------

         procedure Report_Extra_Constituents_In_List (List : Elist_Id) is
            Constit_Elmt : Elmt_Id;

         begin
            if Present (List) then
               Constit_Elmt := First_Elmt (List);
               while Present (Constit_Elmt) loop
                  SPARK_Msg_NE ("extra constituent &", N, Node (Constit_Elmt));
                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;
         end Report_Extra_Constituents_In_List;

      --  Start of processing for Report_Extra_Constituents

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         else
            Report_Extra_Constituents_In_List (In_Constits);
            Report_Extra_Constituents_In_List (In_Out_Constits);
            Report_Extra_Constituents_In_List (Out_Constits);
            Report_Extra_Constituents_In_List (Proof_In_Constits);
         end if;
      end Report_Extra_Constituents;

      --------------------------
      -- Report_Missing_Items --
      --------------------------

      procedure Report_Missing_Items is
         Item_Elmt : Elmt_Id;
         Item_Id   : Entity_Id;

      begin
         --  Do not perform this check in an instance because it was already
         --  performed successfully in the generic template.

         if In_Instance then
            null;

         else
            if Present (Repeat_Items) then
               Item_Elmt := First_Elmt (Repeat_Items);
               while Present (Item_Elmt) loop
                  Item_Id := Node (Item_Elmt);
                  SPARK_Msg_NE ("missing global item &", N, Item_Id);
                  Next_Elmt (Item_Elmt);
               end loop;
            end if;
         end if;
      end Report_Missing_Items;

      --  Local variables

      Body_Decl  : constant Node_Id := Find_Related_Declaration_Or_Body (N);
      Errors     : constant Nat     := Serious_Errors_Detected;
      Items      : Node_Id;
      No_Constit : Boolean;

   --  Start of processing for Analyze_Refined_Global_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      Spec_Id := Unique_Defining_Entity (Body_Decl);

      --  Use the anonymous object as the proper spec when Refined_Global
      --  applies to the body of a single task type. The object carries the
      --  proper Chars as well as all non-refined versions of pragmas.

      if Is_Single_Concurrent_Type (Spec_Id) then
         Spec_Id := Anonymous_Object (Spec_Id);
      end if;

      Global := Get_Pragma (Spec_Id, Pragma_Global);
      Items  := Expression (Get_Argument (N, Spec_Id));

      --  The subprogram declaration lacks pragma Global. This renders
      --  Refined_Global useless as there is nothing to refine.

      if No (Global) then
         SPARK_Msg_NE
           (Fix_Msg (Spec_Id, "useless refinement, declaration of subprogram "
            & "& lacks aspect or pragma Global"), N, Spec_Id);
         goto Leave;
      end if;

      --  Extract all relevant items from the corresponding Global pragma

      Collect_Global_Items (Expression (Get_Argument (Global, Spec_Id)));

      --  Package and subprogram bodies are instantiated individually in
      --  a separate compiler pass. Due to this mode of instantiation, the
      --  refinement of a state may no longer be visible when a subprogram
      --  body contract is instantiated. Since the generic template is legal,
      --  do not perform this check in the instance to circumvent this oddity.

      if In_Instance then
         null;

      --  Non-instance case

      else
         --  The corresponding Global pragma must mention at least one
         --  state with a visible refinement at the point Refined_Global
         --  is processed. States with null refinements need Refined_Global
         --  pragma (SPARK RM 7.2.4(2)).

         if not Has_In_State
           and then not Has_In_Out_State
           and then not Has_Out_State
           and then not Has_Proof_In_State
           and then not Has_Null_State
         then
            SPARK_Msg_NE
              (Fix_Msg (Spec_Id, "useless refinement, subprogram & does not "
               & "depend on abstract state with visible refinement"),
               N, Spec_Id);
            goto Leave;

         --  The global refinement of inputs and outputs cannot be null when
         --  the corresponding Global pragma contains at least one item except
         --  in the case where we have states with null refinements.

         elsif Nkind (Items) = N_Null
           and then
             (Present (In_Items)
               or else Present (In_Out_Items)
               or else Present (Out_Items)
               or else Present (Proof_In_Items))
           and then not Has_Null_State
         then
            SPARK_Msg_NE
              (Fix_Msg (Spec_Id, "refinement cannot be null, subprogram & has "
               & "global items"), N, Spec_Id);
            goto Leave;
         end if;
      end if;

      --  Analyze Refined_Global as if it behaved as a regular pragma Global.
      --  This ensures that the categorization of all refined global items is
      --  consistent with their role.

      Analyze_Global_In_Decl_Part (N);

      --  Perform all refinement checks with respect to completeness and mode
      --  matching.

      if Serious_Errors_Detected = Errors then
         Check_Refined_Global_List (Items);
      end if;

      --  Store the information that no constituent is used in the global
      --  refinement, prior to calling checking procedures which remove items
      --  from the list of constituents.

      No_Constit :=
        No (In_Constits)
          and then No (In_Out_Constits)
          and then No (Out_Constits)
          and then No (Proof_In_Constits);

      --  For Input states with visible refinement, at least one constituent
      --  must be used as an Input in the global refinement.

      if Serious_Errors_Detected = Errors then
         Check_Input_States;
      end if;

      --  Verify all possible completion variants for In_Out states with
      --  visible refinement.

      if Serious_Errors_Detected = Errors then
         Check_In_Out_States;
      end if;

      --  For Output states with visible refinement, all constituents must be
      --  used as Outputs in the global refinement.

      if Serious_Errors_Detected = Errors then
         Check_Output_States;
      end if;

      --  For Proof_In states with visible refinement, at least one constituent
      --  must be used as Proof_In in the global refinement.

      if Serious_Errors_Detected = Errors then
         Check_Proof_In_States;
      end if;

      --  Emit errors for all constituents that belong to other states with
      --  visible refinement that do not appear in Global.

      if Serious_Errors_Detected = Errors then
         Report_Extra_Constituents;
      end if;

      --  Emit errors for all items in Global that are not repeated in the
      --  global refinement and for which there is no full visible refinement
      --  and, in the case of states with partial visible refinement, no
      --  constituent is mentioned in the global refinement.

      if Serious_Errors_Detected = Errors then
         Report_Missing_Items;
      end if;

      --  Emit an error if no constituent is used in the global refinement
      --  (SPARK RM 7.2.4(3f)). Emit this error last, in case a more precise
      --  one may be issued by the checking procedures. Do not perform this
      --  check in an instance because it was already performed successfully
      --  in the generic template.

      if Serious_Errors_Detected = Errors
        and then not In_Instance
        and then not Has_Null_State
        and then No_Constit
      then
         SPARK_Msg_N ("missing refinement", N);
      end if;

      <<Leave>>
      Set_Is_Analyzed_Pragma (N);
   end Analyze_Refined_Global_In_Decl_Part;

   ----------------------------------------
   -- Analyze_Refined_State_In_Decl_Part --
   ----------------------------------------

   procedure Analyze_Refined_State_In_Decl_Part
     (N         : Node_Id;
      Freeze_Id : Entity_Id := Empty)
   is
      Body_Decl : constant Node_Id   := Find_Related_Package_Or_Body (N);
      Body_Id   : constant Entity_Id := Defining_Entity (Body_Decl);
      Spec_Id   : constant Entity_Id := Corresponding_Spec (Body_Decl);

      Available_States : Elist_Id := No_Elist;
      --  A list of all abstract states defined in the package declaration that
      --  are available for refinement. The list is used to report unrefined
      --  states.

      Body_States : Elist_Id := No_Elist;
      --  A list of all hidden states that appear in the body of the related
      --  package. The list is used to report unused hidden states.

      Constituents_Seen : Elist_Id := No_Elist;
      --  A list that contains all constituents processed so far. The list is
      --  used to detect multiple uses of the same constituent.

      Freeze_Posted : Boolean := False;
      --  A flag that controls the output of a freezing-related error (see use
      --  below).

      Refined_States_Seen : Elist_Id := No_Elist;
      --  A list that contains all refined states processed so far. The list is
      --  used to detect duplicate refinements.

      procedure Analyze_Refinement_Clause (Clause : Node_Id);
      --  Perform full analysis of a single refinement clause

      procedure Report_Unrefined_States (States : Elist_Id);
      --  Emit errors for all unrefined abstract states found in list States

      -------------------------------
      -- Analyze_Refinement_Clause --
      -------------------------------

      procedure Analyze_Refinement_Clause (Clause : Node_Id) is
         AR_Constit : Entity_Id := Empty;
         AW_Constit : Entity_Id := Empty;
         ER_Constit : Entity_Id := Empty;
         EW_Constit : Entity_Id := Empty;
         --  The entities of external constituents that contain one of the
         --  following enabled properties: Async_Readers, Async_Writers,
         --  Effective_Reads and Effective_Writes.

         External_Constit_Seen : Boolean := False;
         --  Flag used to mark when at least one external constituent is part
         --  of the state refinement.

         Non_Null_Seen : Boolean := False;
         Null_Seen     : Boolean := False;
         --  Flags used to detect multiple uses of null in a single clause or a
         --  mixture of null and non-null constituents.

         Part_Of_Constits : Elist_Id := No_Elist;
         --  A list of all candidate constituents subject to indicator Part_Of
         --  where the encapsulating state is the current state.

         State    : Node_Id;
         State_Id : Entity_Id;
         --  The current state being refined

         procedure Analyze_Constituent (Constit : Node_Id);
         --  Perform full analysis of a single constituent

         procedure Check_External_Property
           (Prop_Nam : Name_Id;
            Enabled  : Boolean;
            Constit  : Entity_Id);
         --  Determine whether a property denoted by name Prop_Nam is present
         --  in the refined state. Emit an error if this is not the case. Flag
         --  Enabled should be set when the property applies to the refined
         --  state. Constit denotes the constituent (if any) which introduces
         --  the property in the refinement.

         procedure Match_State;
         --  Determine whether the state being refined appears in list
         --  Available_States. Emit an error when attempting to re-refine the
         --  state or when the state is not defined in the package declaration,
         --  otherwise remove the state from Available_States.

         procedure Report_Unused_Constituents (Constits : Elist_Id);
         --  Emit errors for all unused Part_Of constituents in list Constits

         -------------------------
         -- Analyze_Constituent --
         -------------------------

         procedure Analyze_Constituent (Constit : Node_Id) is
            procedure Match_Constituent (Constit_Id : Entity_Id);
            --  Determine whether constituent Constit denoted by its entity
            --  Constit_Id appears in Body_States. Emit an error when the
            --  constituent is not a valid hidden state of the related package
            --  or when it is used more than once. Otherwise remove the
            --  constituent from Body_States.

            -----------------------
            -- Match_Constituent --
            -----------------------

            procedure Match_Constituent (Constit_Id : Entity_Id) is
               procedure Collect_Constituent;
               --  Verify the legality of constituent Constit_Id and add it to
               --  the refinements of State_Id.

               -------------------------
               -- Collect_Constituent --
               -------------------------

               procedure Collect_Constituent is
                  Constits : Elist_Id;

               begin
                  --  The Ghost policy in effect at the point of abstract state
                  --  declaration and constituent must match (SPARK RM 6.9(15))

                  Check_Ghost_Refinement
                    (State, State_Id, Constit, Constit_Id);

                  --  A synchronized state must be refined by a synchronized
                  --  object or another synchronized state (SPARK RM 9.6).

                  if Is_Synchronized_State (State_Id)
                    and then not Is_Synchronized_Object (Constit_Id)
                    and then not Is_Synchronized_State (Constit_Id)
                  then
                     SPARK_Msg_NE
                       ("constituent of synchronized state & must be "
                        & "synchronized", Constit, State_Id);
                  end if;

                  --  Add the constituent to the list of processed items to aid
                  --  with the detection of duplicates.

                  Append_New_Elmt (Constit_Id, Constituents_Seen);

                  --  Collect the constituent in the list of refinement items
                  --  and establish a relation between the refined state and
                  --  the item.

                  Constits := Refinement_Constituents (State_Id);

                  if No (Constits) then
                     Constits := New_Elmt_List;
                     Set_Refinement_Constituents (State_Id, Constits);
                  end if;

                  Append_Elmt (Constit_Id, Constits);
                  Set_Encapsulating_State (Constit_Id, State_Id);

                  --  The state has at least one legal constituent, mark the
                  --  start of the refinement region. The region ends when the
                  --  body declarations end (see routine Analyze_Declarations).

                  Set_Has_Visible_Refinement (State_Id);

                  --  When the constituent is external, save its relevant
                  --  property for further checks.

                  if Async_Readers_Enabled (Constit_Id) then
                     AR_Constit := Constit_Id;
                     External_Constit_Seen := True;
                  end if;

                  if Async_Writers_Enabled (Constit_Id) then
                     AW_Constit := Constit_Id;
                     External_Constit_Seen := True;
                  end if;

                  if Effective_Reads_Enabled (Constit_Id) then
                     ER_Constit := Constit_Id;
                     External_Constit_Seen := True;
                  end if;

                  if Effective_Writes_Enabled (Constit_Id) then
                     EW_Constit := Constit_Id;
                     External_Constit_Seen := True;
                  end if;
               end Collect_Constituent;

               --  Local variables

               State_Elmt : Elmt_Id;

            --  Start of processing for Match_Constituent

            begin
               --  Detect a duplicate use of a constituent

               if Contains (Constituents_Seen, Constit_Id) then
                  SPARK_Msg_NE
                    ("duplicate use of constituent &", Constit, Constit_Id);
                  return;
               end if;

               --  The constituent is subject to a Part_Of indicator

               if Present (Encapsulating_State (Constit_Id)) then
                  if Encapsulating_State (Constit_Id) = State_Id then
                     Remove (Part_Of_Constits, Constit_Id);
                     Collect_Constituent;

                  --  The constituent is part of another state and is used
                  --  incorrectly in the refinement of the current state.

                  else
                     Error_Msg_Name_1 := Chars (State_Id);
                     SPARK_Msg_NE
                       ("& cannot act as constituent of state %",
                        Constit, Constit_Id);
                     SPARK_Msg_NE
                       ("\Part_Of indicator specifies encapsulator &",
                        Constit, Encapsulating_State (Constit_Id));
                  end if;

               else
                  declare
                     Pack_Id   : Entity_Id;
                     Placement : State_Space_Kind;
                  begin
                     --  Find where the constituent lives with respect to the
                     --  state space.

                     Find_Placement_In_State_Space
                       (Item_Id   => Constit_Id,
                        Placement => Placement,
                        Pack_Id   => Pack_Id);

                     --  The constituent is part of the visible state of a
                     --  private child package, but lacks a Part_Of indicator.

                     if Placement = Visible_State_Space
                       and then Is_Child_Unit (Pack_Id)
                       and then not Is_Generic_Unit (Pack_Id)
                       and then Is_Private_Descendant (Pack_Id)
                     then
                        Error_Msg_Name_1 := Chars (State_Id);
                        SPARK_Msg_NE
                          ("& cannot act as constituent of state %",
                           Constit, Constit_Id);
                        Error_Msg_Sloc :=
                          Sloc (Enclosing_Declaration (Constit_Id));
                        SPARK_Msg_NE
                          ("\missing Part_Of indicator # should specify "
                           & "encapsulator &",
                           Constit, State_Id);

                     --  The only other source of legal constituents is the
                     --  body state space of the related package.

                     else
                        if Present (Body_States) then
                           State_Elmt := First_Elmt (Body_States);
                           while Present (State_Elmt) loop

                              --  Consume a valid constituent to signal that it
                              --  has been encountered.

                              if Node (State_Elmt) = Constit_Id then
                                 Remove_Elmt (Body_States, State_Elmt);
                                 Collect_Constituent;
                                 return;
                              end if;

                              Next_Elmt (State_Elmt);
                           end loop;
                        end if;

                        --  At this point it is known that the constituent is
                        --  not part of the package hidden state and cannot be
                        --  used in a refinement (SPARK RM 7.2.2(9)).

                        Error_Msg_Name_1 := Chars (Spec_Id);
                        SPARK_Msg_NE
                          ("cannot use & in refinement, constituent is not a "
                           & "hidden state of package %", Constit, Constit_Id);
                     end if;
                  end;
               end if;
            end Match_Constituent;

            --  Local variables

            Constit_Id : Entity_Id;
            Constits   : Elist_Id;

         --  Start of processing for Analyze_Constituent

         begin
            --  Detect multiple uses of null in a single refinement clause or a
            --  mixture of null and non-null constituents.

            if Nkind (Constit) = N_Null then
               if Null_Seen then
                  SPARK_Msg_N
                    ("multiple null constituents not allowed", Constit);

               elsif Non_Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null constituents", Constit);

               else
                  Null_Seen := True;

                  --  Collect the constituent in the list of refinement items

                  Constits := Refinement_Constituents (State_Id);

                  if No (Constits) then
                     Constits := New_Elmt_List;
                     Set_Refinement_Constituents (State_Id, Constits);
                  end if;

                  Append_Elmt (Constit, Constits);

                  --  The state has at least one legal constituent, mark the
                  --  start of the refinement region. The region ends when the
                  --  body declarations end (see Analyze_Declarations).

                  Set_Has_Visible_Refinement (State_Id);
               end if;

            --  Non-null constituents

            else
               Non_Null_Seen := True;

               if Null_Seen then
                  SPARK_Msg_N
                    ("cannot mix null and non-null constituents", Constit);
               end if;

               Analyze       (Constit);
               Resolve_State (Constit);

               --  Ensure that the constituent denotes a valid state or a
               --  whole object (SPARK RM 7.2.2(5)).

               if Is_Entity_Name (Constit) then
                  Constit_Id := Entity_Of (Constit);

                  --  When a constituent is declared after a subprogram body
                  --  that caused freezing of the related contract where
                  --  pragma Refined_State resides, the constituent appears
                  --  undefined and carries Any_Id as its entity.

                  --    package body Pack
                  --      with Refined_State => (State => Constit)
                  --    is
                  --       procedure Proc
                  --         with Refined_Global => (Input => Constit)
                  --       is
                  --          ...
                  --       end Proc;

                  --       Constit : ...;
                  --    end Pack;

                  if Constit_Id = Any_Id then
                     SPARK_Msg_NE ("& is undefined", Constit, Constit_Id);

                     --  Emit a specialized info message when the contract of
                     --  the related package body was "frozen" by another body.
                     --  Note that it is not possible to precisely identify why
                     --  the constituent is undefined because it is not visible
                     --  when pragma Refined_State is analyzed. This message is
                     --  a reasonable approximation.

                     if Present (Freeze_Id) and then not Freeze_Posted then
                        Freeze_Posted := True;

                        Error_Msg_Name_1 := Chars (Body_Id);
                        Error_Msg_Sloc   := Sloc (Freeze_Id);
                        SPARK_Msg_NE
                          ("body & declared # freezes the contract of %",
                           N, Freeze_Id);
                        SPARK_Msg_N
                          ("\all constituents must be declared before body #",
                           N);

                        --  A misplaced constituent is a critical error because
                        --  pragma Refined_Depends or Refined_Global depends on
                        --  the proper link between a state and a constituent.
                        --  Stop the compilation, as this leads to a multitude
                        --  of misleading cascaded errors.

                        raise Unrecoverable_Error;
                     end if;

                  --  The constituent is a valid state or object

                  elsif Ekind (Constit_Id) in
                          E_Abstract_State | E_Constant | E_Variable
                  then
                     Match_Constituent (Constit_Id);

                     --  The variable may eventually become a constituent of a
                     --  single protected/task type. Record the reference now
                     --  and verify its legality when analyzing the contract of
                     --  the variable (SPARK RM 9.3).

                     if Ekind (Constit_Id) = E_Variable then
                        Record_Possible_Part_Of_Reference
                          (Var_Id => Constit_Id,
                           Ref    => Constit);
                     end if;

                  --  Otherwise the constituent is illegal

                  else
                     SPARK_Msg_NE
                       ("constituent & must denote object or state",
                        Constit, Constit_Id);
                  end if;

               --  The constituent is illegal

               else
                  SPARK_Msg_N ("malformed constituent", Constit);
               end if;
            end if;
         end Analyze_Constituent;

         -----------------------------
         -- Check_External_Property --
         -----------------------------

         procedure Check_External_Property
           (Prop_Nam : Name_Id;
            Enabled  : Boolean;
            Constit  : Entity_Id)
         is
         begin
            --  The property is missing in the declaration of the state, but
            --  a constituent is introducing it in the state refinement
            --  (SPARK RM 7.2.8(2)).

            if not Enabled and then Present (Constit) then
               Error_Msg_Name_1 := Prop_Nam;
               Error_Msg_Name_2 := Chars (State_Id);
               SPARK_Msg_NE
                 ("constituent & introduces external property % in refinement "
                  & "of state %", State, Constit);

               Error_Msg_Sloc := Sloc (State_Id);
               SPARK_Msg_N
                 ("\property is missing in abstract state declaration #",
                  State);
            end if;
         end Check_External_Property;

         -----------------
         -- Match_State --
         -----------------

         procedure Match_State is
            State_Elmt : Elmt_Id;

         begin
            --  Detect a duplicate refinement of a state (SPARK RM 7.2.2(8))

            if Contains (Refined_States_Seen, State_Id) then
               SPARK_Msg_NE
                 ("duplicate refinement of state &", State, State_Id);
               return;
            end if;

            --  Inspect the abstract states defined in the package declaration
            --  looking for a match.

            State_Elmt := First_Elmt (Available_States);
            while Present (State_Elmt) loop

               --  A valid abstract state is being refined in the body. Add
               --  the state to the list of processed refined states to aid
               --  with the detection of duplicate refinements. Remove the
               --  state from Available_States to signal that it has already
               --  been refined.

               if Node (State_Elmt) = State_Id then
                  Append_New_Elmt (State_Id, Refined_States_Seen);
                  Remove_Elmt (Available_States, State_Elmt);
                  return;
               end if;

               Next_Elmt (State_Elmt);
            end loop;

            --  If we get here, we are refining a state that is not defined in
            --  the package declaration.

            Error_Msg_Name_1 := Chars (Spec_Id);
            SPARK_Msg_NE
              ("cannot refine state, & is not defined in package %",
               State, State_Id);
         end Match_State;

         --------------------------------
         -- Report_Unused_Constituents --
         --------------------------------

         procedure Report_Unused_Constituents (Constits : Elist_Id) is
            Constit_Elmt : Elmt_Id;
            Constit_Id   : Entity_Id;
            Posted       : Boolean := False;

         begin
            if Present (Constits) then
               Constit_Elmt := First_Elmt (Constits);
               while Present (Constit_Elmt) loop
                  Constit_Id := Node (Constit_Elmt);

                  --  Generate an error message of the form:

                  --    state ... has unused Part_Of constituents
                  --      abstract state ... defined at ...
                  --      constant ... defined at ...
                  --      variable ... defined at ...

                  if not Posted then
                     Posted := True;
                     SPARK_Msg_NE
                       ("state & has unused Part_Of constituents",
                        State, State_Id);
                  end if;

                  Error_Msg_Sloc := Sloc (Constit_Id);

                  if Ekind (Constit_Id) = E_Abstract_State then
                     SPARK_Msg_NE
                       ("\abstract state & defined #", State, Constit_Id);

                  elsif Ekind (Constit_Id) = E_Constant then
                     SPARK_Msg_NE
                       ("\constant & defined #", State, Constit_Id);

                  else
                     pragma Assert (Ekind (Constit_Id) = E_Variable);
                     SPARK_Msg_NE ("\variable & defined #", State, Constit_Id);
                  end if;

                  Next_Elmt (Constit_Elmt);
               end loop;
            end if;
         end Report_Unused_Constituents;

         --  Local declarations

         Body_Ref      : Node_Id;
         Body_Ref_Elmt : Elmt_Id;
         Constit       : Node_Id;
         Extra_State   : Node_Id;

      --  Start of processing for Analyze_Refinement_Clause

      begin
         --  A refinement clause appears as a component association where the
         --  sole choice is the state and the expressions are the constituents.
         --  This is a syntax error, always report.

         if Nkind (Clause) /= N_Component_Association then
            Error_Msg_N ("malformed state refinement clause", Clause);
            return;
         end if;

         --  Analyze the state name of a refinement clause

         State := First (Choices (Clause));

         Analyze       (State);
         Resolve_State (State);

         --  Ensure that the state name denotes a valid abstract state that is
         --  defined in the spec of the related package.

         if Is_Entity_Name (State) then
            State_Id := Entity_Of (State);

            --  When the abstract state is undefined, it appears as Any_Id. Do
            --  not continue with the analysis of the clause.

            if State_Id = Any_Id then
               return;

            --  Catch any attempts to re-refine a state or refine a state that
            --  is not defined in the package declaration.

            elsif Ekind (State_Id) = E_Abstract_State then
               Match_State;

            else
               SPARK_Msg_NE ("& must denote abstract state", State, State_Id);
               return;
            end if;

            --  References to a state with visible refinement are illegal.
            --  When nested packages are involved, detecting such references is
            --  tricky because pragma Refined_State is analyzed later than the
            --  offending pragma Depends or Global. References that occur in
            --  such nested context are stored in a list. Emit errors for all
            --  references found in Body_References (SPARK RM 6.1.4(8)).

            if Present (Body_References (State_Id)) then
               Body_Ref_Elmt := First_Elmt (Body_References (State_Id));
               while Present (Body_Ref_Elmt) loop
                  Body_Ref := Node (Body_Ref_Elmt);

                  SPARK_Msg_N ("reference to & not allowed", Body_Ref);
                  Error_Msg_Sloc := Sloc (State);
                  SPARK_Msg_N ("\refinement of & is visible#", Body_Ref);

                  Next_Elmt (Body_Ref_Elmt);
               end loop;
            end if;

         --  The state name is illegal. This is a syntax error, always report.

         else
            Error_Msg_N ("malformed state name in refinement clause", State);
            return;
         end if;

         --  A refinement clause may only refine one state at a time

         Extra_State := Next (State);

         if Present (Extra_State) then
            SPARK_Msg_N
              ("refinement clause cannot cover multiple states", Extra_State);
         end if;

         --  Replicate the Part_Of constituents of the refined state because
         --  the algorithm will consume items.

         Part_Of_Constits := New_Copy_Elist (Part_Of_Constituents (State_Id));

         --  Analyze all constituents of the refinement. Multiple constituents
         --  appear as an aggregate.

         Constit := Expression (Clause);

         if Nkind (Constit) = N_Aggregate then
            if Present (Component_Associations (Constit)) then
               SPARK_Msg_N
                 ("constituents of refinement clause must appear in "
                  & "positional form", Constit);

            else pragma Assert (Present (Expressions (Constit)));
               Constit := First (Expressions (Constit));
               while Present (Constit) loop
                  Analyze_Constituent (Constit);
                  Next (Constit);
               end loop;
            end if;

         --  Various forms of a single constituent. Note that these may include
         --  malformed constituents.

         else
            Analyze_Constituent (Constit);
         end if;

         --  Verify that external constituents do not introduce new external
         --  property in the state refinement (SPARK RM 7.2.8(2)).

         if Is_External_State (State_Id) then
            Check_External_Property
              (Prop_Nam => Name_Async_Readers,
               Enabled  => Async_Readers_Enabled (State_Id),
               Constit  => AR_Constit);

            Check_External_Property
              (Prop_Nam => Name_Async_Writers,
               Enabled  => Async_Writers_Enabled (State_Id),
               Constit  => AW_Constit);

            Check_External_Property
              (Prop_Nam => Name_Effective_Reads,
               Enabled  => Effective_Reads_Enabled (State_Id),
               Constit  => ER_Constit);

            Check_External_Property
              (Prop_Nam => Name_Effective_Writes,
               Enabled  => Effective_Writes_Enabled (State_Id),
               Constit  => EW_Constit);

         --  When a refined state is not external, it should not have external
         --  constituents (SPARK RM 7.2.8(1)).

         elsif External_Constit_Seen then
            SPARK_Msg_NE
              ("non-external state & cannot contain external constituents in "
               & "refinement", State, State_Id);
         end if;

         --  Ensure that all Part_Of candidate constituents have been mentioned
         --  in the refinement clause.

         Report_Unused_Constituents (Part_Of_Constits);

         --  Avoid a cascading error reporting a missing refinement by adding a
         --  dummy constituent.

         if No (Refinement_Constituents (State_Id)) then
            Set_Refinement_Constituents (State_Id, New_Elmt_List (Any_Id));
         end if;

         --  At this point the refinement might be dummy, but must be
         --  well-formed, to prevent cascaded errors.

         pragma Assert (Has_Null_Refinement (State_Id)
                          xor
                        Has_Non_Null_Refinement (State_Id));
      end Analyze_Refinement_Clause;

      -----------------------------
      -- Report_Unrefined_States --
      -----------------------------

      procedure Report_Unrefined_States (States : Elist_Id) is
         State_Elmt : Elmt_Id;

      begin
         if Present (States) then
            State_Elmt := First_Elmt (States);
            while Present (State_Elmt) loop
               SPARK_Msg_N
                 ("abstract state & must be refined", Node (State_Elmt));

               Next_Elmt (State_Elmt);
            end loop;
         end if;
      end Report_Unrefined_States;

      --  Local declarations

      Clauses : constant Node_Id := Expression (Get_Argument (N, Spec_Id));
      Clause  : Node_Id;

   --  Start of processing for Analyze_Refined_State_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Save the scenario for examination by the ABE Processing phase

      Record_Elaboration_Scenario (N);

      --  Replicate the abstract states declared by the package because the
      --  matching algorithm will consume states.

      Available_States := New_Copy_Elist (Abstract_States (Spec_Id));

      --  Gather all abstract states and objects declared in the visible
      --  state space of the package body. These items must be utilized as
      --  constituents in a state refinement.

      Body_States := Collect_Body_States (Body_Id);

      --  Multiple non-null state refinements appear as an aggregate

      if Nkind (Clauses) = N_Aggregate then
         if Present (Expressions (Clauses)) then
            SPARK_Msg_N
              ("state refinements must appear as component associations",
               Clauses);

         else pragma Assert (Present (Component_Associations (Clauses)));
            Clause := First (Component_Associations (Clauses));
            while Present (Clause) loop
               Analyze_Refinement_Clause (Clause);
               Next (Clause);
            end loop;
         end if;

      --  Various forms of a single state refinement. Note that these may
      --  include malformed refinements.

      else
         Analyze_Refinement_Clause (Clauses);
      end if;

      --  List all abstract states that were left unrefined

      Report_Unrefined_States (Available_States);

      Set_Is_Analyzed_Pragma (N);
   end Analyze_Refined_State_In_Decl_Part;

   ---------------------------------------------
   -- Analyze_Subprogram_Variant_In_Decl_Part --
   ---------------------------------------------

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   procedure Analyze_Subprogram_Variant_In_Decl_Part
     (N         : Node_Id;
      Freeze_Id : Entity_Id := Empty)
   is
      Subp_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id := Unique_Defining_Entity (Subp_Decl);

      procedure Analyze_Variant (Variant : Node_Id);
      --  Verify the legality of a single contract case

      ---------------------
      -- Analyze_Variant --
      ---------------------

      procedure Analyze_Variant (Variant : Node_Id) is
         Direction       : Node_Id;
         Expr            : Node_Id;
         Errors          : Nat;
         Extra_Direction : Node_Id;

      begin
         if Nkind (Variant) /= N_Component_Association then
            Error_Msg_N ("wrong syntax in subprogram variant", Variant);
            return;
         end if;

         Direction := First (Choices (Variant));
         Expr      := Expression (Variant);

         --  Each variant must have exactly one direction

         Extra_Direction := Next (Direction);

         if Present (Extra_Direction) then
            Error_Msg_N
              ("subprogram variant case must have exactly one direction",
               Extra_Direction);
         end if;

         --  Check placement of OTHERS if available (SPARK RM 6.1.3(1))

         if Nkind (Direction) = N_Identifier then
            if Chars (Direction) /= Name_Decreases
                 and then
               Chars (Direction) /= Name_Increases
            then
               Error_Msg_N ("wrong direction", Direction);
            end if;
         else
            Error_Msg_N ("wrong syntax", Direction);
         end if;

         Errors := Serious_Errors_Detected;
         Preanalyze_Assert_Expression (Expr, Any_Discrete);

         --  Emit a clarification message when the variant expression
         --  contains at least one undefined reference, possibly due
         --  to contract freezing.

         if Errors /= Serious_Errors_Detected
           and then Present (Freeze_Id)
           and then Has_Undefined_Reference (Expr)
         then
            Contract_Freeze_Error (Spec_Id, Freeze_Id);
         end if;
      end Analyze_Variant;

      --  Local variables

      Variants : constant Node_Id := Expression (Get_Argument (N, Spec_Id));

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      Variant       : Node_Id;
      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Subprogram_Variant_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Set the Ghost mode in effect from the pragma. Due to the delayed
      --  analysis of the pragma, the Ghost mode at point of declaration and
      --  point of analysis may not necessarily be the same. Use the mode in
      --  effect at the point of declaration.

      Set_Ghost_Mode (N);

      --  Single and multiple contract cases must appear in aggregate form. If
      --  this is not the case, then either the parser of the analysis of the
      --  pragma failed to produce an aggregate, e.g. when the contract is
      --  "null" or a "(null record)".

      pragma Assert
        (if Nkind (Variants) = N_Aggregate
         then Null_Record_Present (Variants)
           xor (Present (Component_Associations (Variants))
                  or
                Present (Expressions (Variants)))
         else Nkind (Variants) = N_Null);

      --  Only "change_direction => discrete_expression" clauses are allowed

      if Nkind (Variants) = N_Aggregate
        and then Present (Component_Associations (Variants))
        and then No (Expressions (Variants))
      then

         --  Check that the expression is a proper aggregate (no parentheses)

         if Paren_Count (Variants) /= 0 then
            Error_Msg_F -- CODEFIX
              ("redundant parentheses", Variants);
         end if;

         --  Ensure that the formal parameters are visible when analyzing all
         --  clauses. This falls out of the general rule of aspects pertaining
         --  to subprogram declarations.

         if not In_Open_Scopes (Spec_Id) then
            Restore_Scope := True;
            Push_Scope (Spec_Id);

            if Is_Generic_Subprogram (Spec_Id) then
               Install_Generic_Formals (Spec_Id);
            else
               Install_Formals (Spec_Id);
            end if;
         end if;

         Variant := First (Component_Associations (Variants));
         while Present (Variant) loop
            Analyze_Variant (Variant);
            Next (Variant);
         end loop;

         if Restore_Scope then
            End_Scope;
         end if;

      --  Otherwise the pragma is illegal

      else
         Error_Msg_N ("wrong syntax for subprogram variant", N);
      end if;

      Set_Is_Analyzed_Pragma (N);

      Restore_Ghost_Region (Saved_GM, Saved_IGR);
   end Analyze_Subprogram_Variant_In_Decl_Part;

   ------------------------------------
   -- Analyze_Test_Case_In_Decl_Part --
   ------------------------------------

   procedure Analyze_Test_Case_In_Decl_Part (N : Node_Id) is
      Subp_Decl : constant Node_Id   := Find_Related_Declaration_Or_Body (N);
      Spec_Id   : constant Entity_Id := Unique_Defining_Entity (Subp_Decl);

      procedure Preanalyze_Test_Case_Arg (Arg_Nam : Name_Id);
      --  Preanalyze one of the optional arguments "Requires" or "Ensures"
      --  denoted by Arg_Nam.

      ------------------------------
      -- Preanalyze_Test_Case_Arg --
      ------------------------------

      procedure Preanalyze_Test_Case_Arg (Arg_Nam : Name_Id) is
         Arg : Node_Id;

      begin
         --  Preanalyze the original aspect argument for a generic subprogram
         --  to properly capture global references.

         if Is_Generic_Subprogram (Spec_Id) then
            Arg :=
              Test_Case_Arg
                (Prag        => N,
                 Arg_Nam     => Arg_Nam,
                 From_Aspect => True);

            if Present (Arg) then
               Preanalyze_Assert_Expression
                 (Expression (Arg), Standard_Boolean);
            end if;
         end if;

         Arg := Test_Case_Arg (N, Arg_Nam);

         if Present (Arg) then
            Preanalyze_Assert_Expression (Expression (Arg), Standard_Boolean);
         end if;
      end Preanalyze_Test_Case_Arg;

      --  Local variables

      Restore_Scope : Boolean := False;

   --  Start of processing for Analyze_Test_Case_In_Decl_Part

   begin
      --  Do not analyze the pragma multiple times

      if Is_Analyzed_Pragma (N) then
         return;
      end if;

      --  Ensure that the formal parameters are visible when analyzing all
      --  clauses. This falls out of the general rule of aspects pertaining
      --  to subprogram declarations.

      if not In_Open_Scopes (Spec_Id) then
         Restore_Scope := True;
         Push_Scope (Spec_Id);

         if Is_Generic_Subprogram (Spec_Id) then
            Install_Generic_Formals (Spec_Id);
         else
            Install_Formals (Spec_Id);
         end if;
      end if;

      Preanalyze_Test_Case_Arg (Name_Requires);
      Preanalyze_Test_Case_Arg (Name_Ensures);

      if Restore_Scope then
         End_Scope;
      end if;

      --  Currently it is not possible to inline pre/postconditions on a
      --  subprogram subject to pragma Inline_Always.

      Check_Postcondition_Use_In_Inlined_Subprogram (N, Spec_Id);

      Set_Is_Analyzed_Pragma (N);
   end Analyze_Test_Case_In_Decl_Part;

   ----------------
   -- Appears_In --
   ----------------

   function Appears_In (List : Elist_Id; Item_Id : Entity_Id) return Boolean is
      Elmt : Elmt_Id;
      Id   : Entity_Id;

   begin
      if Present (List) then
         Elmt := First_Elmt (List);
         while Present (Elmt) loop
            if Nkind (Node (Elmt)) = N_Defining_Identifier then
               Id := Node (Elmt);
            else
               Id := Entity_Of (Node (Elmt));
            end if;

            if Id = Item_Id then
               return True;
            end if;

            Next_Elmt (Elmt);
         end loop;
      end if;

      return False;
   end Appears_In;

   -----------------------------------
   -- Build_Pragma_Check_Equivalent --
   -----------------------------------

   function Build_Pragma_Check_Equivalent
     (Prag           : Node_Id;
      Subp_Id        : Entity_Id := Empty;
      Inher_Id       : Entity_Id := Empty;
      Keep_Pragma_Id : Boolean := False) return Node_Id
   is
      function Suppress_Reference (N : Node_Id) return Traverse_Result;
      --  Detect whether node N references a formal parameter subject to
      --  pragma Unreferenced. If this is the case, set Comes_From_Source
      --  to False to suppress the generation of a reference when analyzing
      --  N later on.

      ------------------------
      -- Suppress_Reference --
      ------------------------

      function Suppress_Reference (N : Node_Id) return Traverse_Result is
         Formal : Entity_Id;

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

            --  The formal parameter is subject to pragma Unreferenced. Prevent
            --  the generation of references by resetting the Comes_From_Source
            --  flag.

            if Is_Formal (Formal)
              and then Has_Pragma_Unreferenced (Formal)
            then
               Set_Comes_From_Source (N, False);
            end if;
         end if;

         return OK;
      end Suppress_Reference;

      procedure Suppress_References is
        new Traverse_Proc (Suppress_Reference);

      --  Local variables

      Loc        : constant Source_Ptr := Sloc (Prag);
      Prag_Nam   : constant Name_Id    := Pragma_Name (Prag);
      Check_Prag : Node_Id;
      Msg_Arg    : Node_Id;
      Nam        : Name_Id;

   --  Start of processing for Build_Pragma_Check_Equivalent

   begin
      --  When the pre- or postcondition is inherited, map the formals of the
      --  inherited subprogram to those of the current subprogram. In addition,
      --  map primitive operations of the parent type into the corresponding
      --  primitive operations of the descendant.

      if Present (Inher_Id) then
         pragma Assert (Present (Subp_Id));

         Update_Primitives_Mapping (Inher_Id, Subp_Id);

         --  Use generic machinery to copy inherited pragma, as if it were an
         --  instantiation, resetting source locations appropriately, so that
         --  expressions inside the inherited pragma use chained locations.
         --  This is used in particular in GNATprove to locate precisely
         --  messages on a given inherited pragma.

         Set_Copied_Sloc_For_Inherited_Pragma
           (Unit_Declaration_Node (Subp_Id), Inher_Id);
         Check_Prag := New_Copy_Tree (Source => Prag);

         --  Build the inherited class-wide condition

         Build_Class_Wide_Expression
           (Pragma_Or_Expr => Check_Prag,
            Subp           => Subp_Id,
            Par_Subp       => Inher_Id,
            Adjust_Sloc    => True);

      --  If not an inherited condition simply copy the original pragma

      else
         Check_Prag := New_Copy_Tree (Source => Prag);
      end if;

      --  Mark the pragma as being internally generated and reset the Analyzed
      --  flag.

      Set_Analyzed          (Check_Prag, False);
      Set_Comes_From_Source (Check_Prag, False);

      --  The tree of the original pragma may contain references to the
      --  formal parameters of the related subprogram. At the same time
      --  the corresponding body may mark the formals as unreferenced:

      --     procedure Proc (Formal : ...)
      --       with Pre => Formal ...;

      --     procedure Proc (Formal : ...) is
      --        pragma Unreferenced (Formal);
      --     ...

      --  This creates problems because all pragma Check equivalents are
      --  analyzed at the end of the body declarations. Since all source
      --  references have already been accounted for, reset any references
      --  to such formals in the generated pragma Check equivalent.

      Suppress_References (Check_Prag);

      if Present (Corresponding_Aspect (Prag)) then
         Nam := Chars (Identifier (Corresponding_Aspect (Prag)));
      else
         Nam := Prag_Nam;
      end if;

      --  Unless Keep_Pragma_Id is True in order to keep the identifier of
      --  the copied pragma in the newly created pragma, convert the copy into
      --  pragma Check by correcting the name and adding a check_kind argument.

      if not Keep_Pragma_Id then
         Set_Class_Present (Check_Prag, False);

         Set_Pragma_Identifier
           (Check_Prag, Make_Identifier (Loc, Name_Check));

         Prepend_To (Pragma_Argument_Associations (Check_Prag),
           Make_Pragma_Argument_Association (Loc,
             Expression => Make_Identifier (Loc, Nam)));
      end if;

      --  Update the error message when the pragma is inherited

      if Present (Inher_Id) then
         Msg_Arg := Last (Pragma_Argument_Associations (Check_Prag));

         if Chars (Msg_Arg) = Name_Message then
            String_To_Name_Buffer (Strval (Expression (Msg_Arg)));

            --  Insert "inherited" to improve the error message

            if Name_Buffer (1 .. 8) = "failed p" then
               Insert_Str_In_Name_Buffer ("inherited ", 8);
               Set_Strval (Expression (Msg_Arg), String_From_Name_Buffer);
            end if;
         end if;
      end if;

      return Check_Prag;
   end Build_Pragma_Check_Equivalent;

   -----------------------------
   -- Check_Applicable_Policy --
   -----------------------------

   procedure Check_Applicable_Policy (N : Node_Id) is
      PP     : Node_Id;
      Policy : Name_Id;

      Ename : constant Name_Id := Original_Aspect_Pragma_Name (N);

   begin
      --  No effect if not valid assertion kind name

      if not Is_Valid_Assertion_Kind (Ename) then
         return;
      end if;

      --  Loop through entries in check policy list

      PP := Opt.Check_Policy_List;
      while Present (PP) loop
         declare
            PPA : constant List_Id := Pragma_Argument_Associations (PP);
            Pnm : constant Name_Id := Chars (Get_Pragma_Arg (First (PPA)));

         begin
            if Ename = Pnm
              or else Pnm = Name_Assertion
              or else (Pnm = Name_Statement_Assertions
                        and then Ename in Name_Assert
                                        | Name_Assert_And_Cut
                                        | Name_Assume
                                        | Name_Loop_Invariant
                                        | Name_Loop_Variant)
            then
               Policy := Chars (Get_Pragma_Arg (Last (PPA)));

               case Policy is
                  when Name_Ignore
                     | Name_Off
                  =>
                     --  In CodePeer mode and GNATprove mode, we need to
                     --  consider all assertions, unless they are disabled.
                     --  Force Is_Checked on ignored assertions, in particular
                     --  because transformations of the AST may depend on
                     --  assertions being checked (e.g. the translation of
                     --  attribute 'Loop_Entry).

                     if CodePeer_Mode or GNATprove_Mode then
                        Set_Is_Checked (N, True);
                        Set_Is_Ignored (N, False);
                     else
                        Set_Is_Checked (N, False);
                        Set_Is_Ignored (N, True);
                     end if;

                  when Name_Check
                     | Name_On
                  =>
                     Set_Is_Checked (N, True);
                     Set_Is_Ignored (N, False);

                  when Name_Disable =>
                     Set_Is_Ignored  (N, True);
                     Set_Is_Checked  (N, False);
                     Set_Is_Disabled (N, True);

                  --  That should be exhaustive, the null here is a defence
                  --  against a malformed tree from previous errors.

                  when others =>
                     null;
               end case;

               return;
            end if;

            PP := Next_Pragma (PP);
         end;
      end loop;

      --  If there are no specific entries that matched, then we let the
      --  setting of assertions govern. Note that this provides the needed
      --  compatibility with the RM for the cases of assertion, invariant,
      --  precondition, predicate, and postcondition. Note also that
      --  Assertions_Enabled is forced in CodePeer mode and GNATprove mode.

      if Assertions_Enabled then
         Set_Is_Checked (N, True);
         Set_Is_Ignored (N, False);
      else
         Set_Is_Checked (N, False);
         Set_Is_Ignored (N, True);
      end if;
   end Check_Applicable_Policy;

   -------------------------------
   -- Check_External_Properties --
   -------------------------------

   procedure Check_External_Properties
     (Item : Node_Id;
      AR   : Boolean;
      AW   : Boolean;
      ER   : Boolean;
      EW   : Boolean)
   is
      type Properties is array (Positive range 1 .. 4) of Boolean;
      type Combinations is array (Positive range <>) of Properties;
      --  Arrays of Async_Readers, Async_Writers, Effective_Writes and
      --  Effective_Reads properties and their combinations, respectively.

      Specified : constant Properties := (AR, AW, EW, ER);
      --  External properties, as given by the Item pragma

      Allowed : constant Combinations :=
        (1 => (True,  False, True,  False),
         2 => (False, True,  False, True),
         3 => (True,  False, False, False),
         4 => (False, True,  False, False),
         5 => (True,  True,  True,  False),
         6 => (True,  True,  False, True),
         7 => (True,  True,  False, False),
         8 => (True,  True,  True,  True));
      --  Allowed combinations, as listed in the SPARK RM 7.1.2(6) table

   begin
      --  Check if the specified properties match any of the allowed
      --  combination; if not, then emit an error.

      for J in Allowed'Range loop
         if Specified = Allowed (J) then
            return;
         end if;
      end loop;

      SPARK_Msg_N
        ("illegal combination of external properties (SPARK RM 7.1.2(6))",
         Item);
   end Check_External_Properties;

   ----------------
   -- Check_Kind --
   ----------------

   function Check_Kind (Nam : Name_Id) return Name_Id is
      PP : Node_Id;

   begin
      --  Loop through entries in check policy list

      PP := Opt.Check_Policy_List;
      while Present (PP) loop
         declare
            PPA : constant List_Id := Pragma_Argument_Associations (PP);
            Pnm : constant Name_Id := Chars (Get_Pragma_Arg (First (PPA)));

         begin
            if Nam = Pnm
              or else (Pnm = Name_Assertion
                        and then Is_Valid_Assertion_Kind (Nam))
              or else (Pnm = Name_Statement_Assertions
                        and then Nam in Name_Assert
                                      | Name_Assert_And_Cut
                                      | Name_Assume
                                      | Name_Loop_Invariant
                                      | Name_Loop_Variant)
            then
               case (Chars (Get_Pragma_Arg (Last (PPA)))) is
                  when Name_Check
                     | Name_On
                  =>
                     return Name_Check;

                  when Name_Ignore
                     | Name_Off
                  =>
                     return Name_Ignore;

                  when Name_Disable =>
                     return Name_Disable;

                  when others =>
                     raise Program_Error;
               end case;

            else
               PP := Next_Pragma (PP);
            end if;
         end;
      end loop;

      --  If there are no specific entries that matched, then we let the
      --  setting of assertions govern. Note that this provides the needed
      --  compatibility with the RM for the cases of assertion, invariant,
      --  precondition, predicate, and postcondition.

      if Assertions_Enabled then
         return Name_Check;
      else
         return Name_Ignore;
      end if;
   end Check_Kind;

   ---------------------------
   -- Check_Missing_Part_Of --
   ---------------------------

   procedure Check_Missing_Part_Of (Item_Id : Entity_Id) is
      function Has_Visible_State (Pack_Id : Entity_Id) return Boolean;
      --  Determine whether a package denoted by Pack_Id declares at least one
      --  visible state.

      -----------------------
      -- Has_Visible_State --
      -----------------------

      function Has_Visible_State (Pack_Id : Entity_Id) return Boolean is
         Item_Id : Entity_Id;

      begin
         --  Traverse the entity chain of the package trying to find at least
         --  one visible abstract state, variable or a package [instantiation]
         --  that declares a visible state.

         Item_Id := First_Entity (Pack_Id);
         while Present (Item_Id)
           and then not In_Private_Part (Item_Id)
         loop
            --  Do not consider internally generated items

            if not Comes_From_Source (Item_Id) then
               null;

            --  Do not consider generic formals or their corresponding actuals
            --  because they are not part of a visible state. Note that both
            --  entities are marked as hidden.

            elsif Is_Hidden (Item_Id) then
               null;

            --  A visible state has been found. Note that constants are not
            --  considered here because it is not possible to determine whether
            --  they depend on variable input. This check is left to the SPARK
            --  prover.

            elsif Ekind (Item_Id) in E_Abstract_State | E_Variable then
               return True;

            --  Recursively peek into nested packages and instantiations

            elsif Ekind (Item_Id) = E_Package
              and then Has_Visible_State (Item_Id)
            then
               return True;
            end if;

            Next_Entity (Item_Id);
         end loop;

         return False;
      end Has_Visible_State;

      --  Local variables

      Pack_Id   : Entity_Id;
      Placement : State_Space_Kind;

   --  Start of processing for Check_Missing_Part_Of

   begin
      --  Do not consider abstract states, variables or package instantiations
      --  coming from an instance as those always inherit the Part_Of indicator
      --  of the instance itself.

      if In_Instance then
         return;

      --  Do not consider internally generated entities as these can never
      --  have a Part_Of indicator.

      elsif not Comes_From_Source (Item_Id) then
         return;

      --  Perform these checks only when SPARK_Mode is enabled as they will
      --  interfere with standard Ada rules and produce false positives.

      elsif SPARK_Mode /= On then
         return;

      --  Do not consider constants, because the compiler cannot accurately
      --  determine whether they have variable input (SPARK RM 7.1.1(2)) and
      --  act as a hidden state of a package.

      elsif Ekind (Item_Id) = E_Constant then
         return;
      end if;

      --  Find where the abstract state, variable or package instantiation
      --  lives with respect to the state space.

      Find_Placement_In_State_Space
        (Item_Id   => Item_Id,
         Placement => Placement,
         Pack_Id   => Pack_Id);

      --  Items that appear in a non-package construct (subprogram, block, etc)
      --  do not require a Part_Of indicator because they can never act as a
      --  hidden state.

      if Placement = Not_In_Package then
         null;

      --  An item declared in the body state space of a package always act as a
      --  constituent and does not need explicit Part_Of indicator.

      elsif Placement = Body_State_Space then
         null;

      --  In general an item declared in the visible state space of a package
      --  does not require a Part_Of indicator. The only exception is when the
      --  related package is a nongeneric private child unit, in which case
      --  Part_Of must denote a state in the parent unit or in one of its
      --  descendants.

      elsif Placement = Visible_State_Space then
         if Is_Child_Unit (Pack_Id)
           and then not Is_Generic_Unit (Pack_Id)
           and then Is_Private_Descendant (Pack_Id)
         then
            --  A package instantiation does not need a Part_Of indicator when
            --  the related generic template has no visible state.

            if Ekind (Item_Id) = E_Package
              and then Is_Generic_Instance (Item_Id)
              and then not Has_Visible_State (Item_Id)
            then
               null;

            --  All other cases require Part_Of

            else
               Error_Msg_N
                 ("indicator Part_Of is required in this context "
                  & "(SPARK RM 7.2.6(3))", Item_Id);
               Error_Msg_Name_1 := Chars (Pack_Id);
               Error_Msg_N
                 ("\& is declared in the visible part of private child "
                  & "unit %", Item_Id);
            end if;
         end if;

      --  When the item appears in the private state space of a package, it
      --  must be a part of some state declared by the said package.

      else pragma Assert (Placement = Private_State_Space);

         --  The related package does not declare a state, the item cannot act
         --  as a Part_Of constituent.

         if No (Get_Pragma (Pack_Id, Pragma_Abstract_State)) then
            null;

         --  A package instantiation does not need a Part_Of indicator when the
         --  related generic template has no visible state.

         elsif Ekind (Item_Id) = E_Package
           and then Is_Generic_Instance (Item_Id)
           and then not Has_Visible_State (Item_Id)
         then
            null;

         --  All other cases require Part_Of

         else
            Error_Msg_N
              ("indicator Part_Of is required in this context "
               & "(SPARK RM 7.2.6(2))", Item_Id);
            Error_Msg_Name_1 := Chars (Pack_Id);
            Error_Msg_N
              ("\& is declared in the private part of package %", Item_Id);
         end if;
      end if;
   end Check_Missing_Part_Of;

   ---------------------------------------------------
   -- Check_Postcondition_Use_In_Inlined_Subprogram --
   ---------------------------------------------------

   procedure Check_Postcondition_Use_In_Inlined_Subprogram
     (Prag    : Node_Id;
      Spec_Id : Entity_Id)
   is
   begin
      if Warn_On_Redundant_Constructs
        and then Has_Pragma_Inline_Always (Spec_Id)
        and then Assertions_Enabled
      then
         Error_Msg_Name_1 := Original_Aspect_Pragma_Name (Prag);

         if From_Aspect_Specification (Prag) then
            Error_Msg_NE
              ("aspect % not enforced on inlined subprogram &?r?",
               Corresponding_Aspect (Prag), Spec_Id);
         else
            Error_Msg_NE
              ("pragma % not enforced on inlined subprogram &?r?",
               Prag, Spec_Id);
         end if;
      end if;
   end Check_Postcondition_Use_In_Inlined_Subprogram;

   -------------------------------------
   -- Check_State_And_Constituent_Use --
   -------------------------------------

   procedure Check_State_And_Constituent_Use
     (States   : Elist_Id;
      Constits : Elist_Id;
      Context  : Node_Id)
   is
      Constit_Elmt : Elmt_Id;
      Constit_Id   : Entity_Id;
      State_Id     : Entity_Id;

   begin
      --  Nothing to do if there are no states or constituents

      if No (States) or else No (Constits) then
         return;
      end if;

      --  Inspect the list of constituents and try to determine whether its
      --  encapsulating state is in list States.

      Constit_Elmt := First_Elmt (Constits);
      while Present (Constit_Elmt) loop
         Constit_Id := Node (Constit_Elmt);

         --  Determine whether the constituent is part of an encapsulating
         --  state that appears in the same context and if this is the case,
         --  emit an error (SPARK RM 7.2.6(7)).

         State_Id := Find_Encapsulating_State (States, Constit_Id);

         if Present (State_Id) then
            Error_Msg_Name_1 := Chars (Constit_Id);
            SPARK_Msg_NE
              ("cannot mention state & and its constituent % in the same "
               & "context", Context, State_Id);
            exit;
         end if;

         Next_Elmt (Constit_Elmt);
      end loop;
   end Check_State_And_Constituent_Use;

   ---------------------------------------------
   -- Collect_Inherited_Class_Wide_Conditions --
   ---------------------------------------------

   procedure Collect_Inherited_Class_Wide_Conditions (Subp : Entity_Id) is
      Parent_Subp : constant Entity_Id :=
                      Ultimate_Alias (Overridden_Operation (Subp));
      --  The Overridden_Operation may itself be inherited and as such have no
      --  explicit contract.

      Prags        : constant Node_Id := Contract (Parent_Subp);
      In_Spec_Expr : Boolean := In_Spec_Expression;
      Installed    : Boolean;
      Prag         : Node_Id;
      New_Prag     : Node_Id;

   begin
      Installed := False;

      --  Iterate over the contract of the overridden subprogram to find all
      --  inherited class-wide pre- and postconditions.

      if Present (Prags) then
         Prag := Pre_Post_Conditions (Prags);

         while Present (Prag) loop
            if Pragma_Name_Unmapped (Prag)
                 in Name_Precondition | Name_Postcondition
              and then Class_Present (Prag)
            then
               --  The generated pragma must be analyzed in the context of
               --  the subprogram, to make its formals visible. In addition,
               --  we must inhibit freezing and full analysis because the
               --  controlling type of the subprogram is not frozen yet, and
               --  may have further primitives.

               if not Installed then
                  Installed := True;
                  Push_Scope (Subp);
                  Install_Formals (Subp);
                  In_Spec_Expr := In_Spec_Expression;
                  In_Spec_Expression := True;
               end if;

               New_Prag :=
                 Build_Pragma_Check_Equivalent
                   (Prag, Subp, Parent_Subp, Keep_Pragma_Id => True);

               Insert_After (Unit_Declaration_Node (Subp), New_Prag);
               Preanalyze (New_Prag);

               --  Prevent further analysis in subsequent processing of the
               --  current list of declarations

               Set_Analyzed (New_Prag);
            end if;

            Prag := Next_Pragma (Prag);
         end loop;

         if Installed then
            In_Spec_Expression := In_Spec_Expr;
            End_Scope;
         end if;
      end if;
   end Collect_Inherited_Class_Wide_Conditions;

   ---------------------------------------
   -- Collect_Subprogram_Inputs_Outputs --
   ---------------------------------------

   procedure Collect_Subprogram_Inputs_Outputs
     (Subp_Id      : Entity_Id;
      Synthesize   : Boolean := False;
      Subp_Inputs  : in out Elist_Id;
      Subp_Outputs : in out Elist_Id;
      Global_Seen  : out Boolean)
   is
      procedure Collect_Dependency_Clause (Clause : Node_Id);
      --  Collect all relevant items from a dependency clause

      procedure Collect_Global_List
        (List : Node_Id;
         Mode : Name_Id := Name_Input);
      --  Collect all relevant items from a global list

      -------------------------------
      -- Collect_Dependency_Clause --
      -------------------------------

      procedure Collect_Dependency_Clause (Clause : Node_Id) is
         procedure Collect_Dependency_Item
           (Item     : Node_Id;
            Is_Input : Boolean);
         --  Add an item to the proper subprogram input or output collection

         -----------------------------
         -- Collect_Dependency_Item --
         -----------------------------

         procedure Collect_Dependency_Item
           (Item     : Node_Id;
            Is_Input : Boolean)
         is
            Extra : Node_Id;

         begin
            --  Nothing to collect when the item is null

            if Nkind (Item) = N_Null then
               null;

            --  Ditto for attribute 'Result

            elsif Is_Attribute_Result (Item) then
               null;

            --  Multiple items appear as an aggregate

            elsif Nkind (Item) = N_Aggregate then
               Extra := First (Expressions (Item));
               while Present (Extra) loop
                  Collect_Dependency_Item (Extra, Is_Input);
                  Next (Extra);
               end loop;

            --  Otherwise this is a solitary item

            else
               if Is_Input then
                  Append_New_Elmt (Item, Subp_Inputs);
               else
                  Append_New_Elmt (Item, Subp_Outputs);
               end if;
            end if;
         end Collect_Dependency_Item;

      --  Start of processing for Collect_Dependency_Clause

      begin
         if Nkind (Clause) = N_Null then
            null;

         --  A dependency clause appears as component association

         elsif Nkind (Clause) = N_Component_Association then
            Collect_Dependency_Item
              (Item     => Expression (Clause),
               Is_Input => True);

            Collect_Dependency_Item
              (Item     => First (Choices (Clause)),
               Is_Input => False);

         --  To accommodate partial decoration of disabled SPARK features, this
         --  routine may be called with illegal input. If this is the case, do
         --  not raise Program_Error.

         else
            null;
         end if;
      end Collect_Dependency_Clause;

      -------------------------
      -- Collect_Global_List --
      -------------------------

      procedure Collect_Global_List
        (List : Node_Id;
         Mode : Name_Id := Name_Input)
      is
         procedure Collect_Global_Item (Item : Node_Id; Mode : Name_Id);
         --  Add an item to the proper subprogram input or output collection

         -------------------------
         -- Collect_Global_Item --
         -------------------------

         procedure Collect_Global_Item (Item : Node_Id; Mode : Name_Id) is
         begin
            if Mode in Name_In_Out | Name_Input then
               Append_New_Elmt (Item, Subp_Inputs);
            end if;

            if Mode in Name_In_Out | Name_Output then
               Append_New_Elmt (Item, Subp_Outputs);
            end if;
         end Collect_Global_Item;

         --  Local variables

         Assoc : Node_Id;
         Item  : Node_Id;

      --  Start of processing for Collect_Global_List

      begin
         if Nkind (List) = N_Null then
            null;

         --  Single global item declaration

         elsif Nkind (List) in N_Expanded_Name
                             | N_Identifier
                             | N_Selected_Component
         then
            Collect_Global_Item (List, Mode);

         --  Simple global list or moded global list declaration

         elsif Nkind (List) = N_Aggregate then
            if Present (Expressions (List)) then
               Item := First (Expressions (List));
               while Present (Item) loop
                  Collect_Global_Item (Item, Mode);
                  Next (Item);
               end loop;

            else
               Assoc := First (Component_Associations (List));
               while Present (Assoc) loop
                  Collect_Global_List
                    (List => Expression (Assoc),
                     Mode => Chars (First (Choices (Assoc))));
                  Next (Assoc);
               end loop;
            end if;

         --  To accommodate partial decoration of disabled SPARK features, this
         --  routine may be called with illegal input. If this is the case, do
         --  not raise Program_Error.

         else
            null;
         end if;
      end Collect_Global_List;

      --  Local variables

      Clause    : Node_Id;
      Clauses   : Node_Id;
      Depends   : Node_Id;
      Formal    : Entity_Id;
      Global    : Node_Id;
      Spec_Id   : Entity_Id := Empty;
      Subp_Decl : Node_Id;
      Typ       : Entity_Id;

   --  Start of processing for Collect_Subprogram_Inputs_Outputs

   begin
      Global_Seen := False;

      --  Process all formal parameters of entries, [generic] subprograms, and
      --  their bodies.

      if Ekind (Subp_Id) in E_Entry
                          | E_Entry_Family
                          | E_Function
                          | E_Generic_Function
                          | E_Generic_Procedure
                          | E_Procedure
                          | E_Subprogram_Body
      then
         Subp_Decl := Unit_Declaration_Node (Subp_Id);
         Spec_Id   := Unique_Defining_Entity (Subp_Decl);

         --  Process all formal parameters

         Formal := First_Formal (Spec_Id);
         while Present (Formal) loop
            if Ekind (Formal) in E_In_Out_Parameter | E_In_Parameter then
               Append_New_Elmt (Formal, Subp_Inputs);
            end if;

            if Ekind (Formal) in E_In_Out_Parameter | E_Out_Parameter then
               Append_New_Elmt (Formal, Subp_Outputs);

               --  OUT parameters can act as inputs when the related type is
               --  tagged, unconstrained array, unconstrained record, or record
               --  with unconstrained components.

               if Ekind (Formal) = E_Out_Parameter
                 and then Is_Unconstrained_Or_Tagged_Item (Formal)
               then
                  Append_New_Elmt (Formal, Subp_Inputs);
               end if;
            end if;

            --  IN parameters of procedures and protected entries can act as
            --  outputs when the related type is access-to-variable.

            if Ekind (Formal) = E_In_Parameter
              and then Ekind (Spec_Id) not in E_Function
                                            | E_Generic_Function
              and then Is_Access_Variable (Etype (Formal))
            then
               Append_New_Elmt (Formal, Subp_Outputs);
            end if;

            Next_Formal (Formal);
         end loop;

      --  Otherwise the input denotes a task type, a task body, or the
      --  anonymous object created for a single task type.

      elsif Ekind (Subp_Id) in E_Task_Type | E_Task_Body
        or else Is_Single_Task_Object (Subp_Id)
      then
         Subp_Decl := Declaration_Node (Subp_Id);
         Spec_Id   := Unique_Defining_Entity (Subp_Decl);
      end if;

      --  When processing an entry, subprogram or task body, look for pragmas
      --  Refined_Depends and Refined_Global as they specify the inputs and
      --  outputs.

      if Is_Entry_Body (Subp_Id)
        or else Ekind (Subp_Id) in E_Subprogram_Body | E_Task_Body
      then
         Depends := Get_Pragma (Subp_Id, Pragma_Refined_Depends);
         Global  := Get_Pragma (Subp_Id, Pragma_Refined_Global);

      --  Subprogram declaration or stand-alone body case, look for pragmas
      --  Depends and Global.

      else
         Depends := Get_Pragma (Spec_Id, Pragma_Depends);
         Global  := Get_Pragma (Spec_Id, Pragma_Global);
      end if;

      --  Pragma [Refined_]Global takes precedence over [Refined_]Depends
      --  because it provides finer granularity of inputs and outputs.

      if Present (Global) then
         Global_Seen := True;
         Collect_Global_List (Expression (Get_Argument (Global, Spec_Id)));

      --  When the related subprogram lacks pragma [Refined_]Global, fall back
      --  to [Refined_]Depends if the caller requests this behavior. Synthesize
      --  the inputs and outputs from [Refined_]Depends.

      elsif Synthesize and then Present (Depends) then
         Clauses := Expression (Get_Argument (Depends, Spec_Id));

         --  Multiple dependency clauses appear as an aggregate

         if Nkind (Clauses) = N_Aggregate then
            Clause := First (Component_Associations (Clauses));
            while Present (Clause) loop
               Collect_Dependency_Clause (Clause);
               Next (Clause);
            end loop;

         --  Otherwise this is a single dependency clause

         else
            Collect_Dependency_Clause (Clauses);
         end if;
      end if;

      --  The current instance of a protected type acts as a formal parameter
      --  of mode IN for functions and IN OUT for entries and procedures
      --  (SPARK RM 6.1.4).

      if Ekind (Scope (Spec_Id)) = E_Protected_Type then
         Typ := Scope (Spec_Id);

         --  Use the anonymous object when the type is single protected

         if Is_Single_Concurrent_Type_Declaration (Declaration_Node (Typ)) then
            Typ := Anonymous_Object (Typ);
         end if;

         Append_New_Elmt (Typ, Subp_Inputs);

         if Ekind (Spec_Id) in E_Entry | E_Entry_Family | E_Procedure then
            Append_New_Elmt (Typ, Subp_Outputs);
         end if;

      --  The current instance of a task type acts as a formal parameter of
      --  mode IN OUT (SPARK RM 6.1.4).

      elsif Ekind (Spec_Id) = E_Task_Type then
         Typ := Spec_Id;

         --  Use the anonymous object when the type is single task

         if Is_Single_Concurrent_Type_Declaration (Declaration_Node (Typ)) then
            Typ := Anonymous_Object (Typ);
         end if;

         Append_New_Elmt (Typ, Subp_Inputs);
         Append_New_Elmt (Typ, Subp_Outputs);

      elsif Is_Single_Task_Object (Spec_Id) then
         Append_New_Elmt (Spec_Id, Subp_Inputs);
         Append_New_Elmt (Spec_Id, Subp_Outputs);
      end if;
   end Collect_Subprogram_Inputs_Outputs;

   ---------------------------
   -- Contract_Freeze_Error --
   ---------------------------

   procedure Contract_Freeze_Error
     (Contract_Id : Entity_Id;
      Freeze_Id   : Entity_Id)
   is
   begin
      Error_Msg_Name_1 := Chars (Contract_Id);
      Error_Msg_Sloc   := Sloc (Freeze_Id);

      SPARK_Msg_NE
        ("body & declared # freezes the contract of%", Contract_Id, Freeze_Id);
      SPARK_Msg_N
        ("\all contractual items must be declared before body #", Contract_Id);
   end Contract_Freeze_Error;

   ---------------------------------
   -- Delay_Config_Pragma_Analyze --
   ---------------------------------

   function Delay_Config_Pragma_Analyze (N : Node_Id) return Boolean is
   begin
      return Pragma_Name_Unmapped (N)
        in Name_Interrupt_State | Name_Priority_Specific_Dispatching;
   end Delay_Config_Pragma_Analyze;

   -----------------------
   -- Duplication_Error --
   -----------------------

   procedure Duplication_Error (Prag : Node_Id; Prev : Node_Id) is
      Prag_From_Asp : constant Boolean := From_Aspect_Specification (Prag);
      Prev_From_Asp : constant Boolean := From_Aspect_Specification (Prev);

   begin
      Error_Msg_Sloc   := Sloc (Prev);
      Error_Msg_Name_1 := Original_Aspect_Pragma_Name (Prag);

      --  Emit a precise message to distinguish between source pragmas and
      --  pragmas generated from aspects. The ordering of the two pragmas is
      --  the following:

      --    Prev  --  ok
      --    Prag  --  duplicate

      --  No error is emitted when both pragmas come from aspects because this
      --  is already detected by the general aspect analysis mechanism.

      if Prag_From_Asp and Prev_From_Asp then
         null;
      elsif Prag_From_Asp then
         Error_Msg_N ("aspect % duplicates pragma declared #", Prag);
      elsif Prev_From_Asp then
         Error_Msg_N ("pragma % duplicates aspect declared #", Prag);
      else
         Error_Msg_N ("pragma % duplicates pragma declared #", Prag);
      end if;
   end Duplication_Error;

   ------------------------------
   -- Find_Encapsulating_State --
   ------------------------------

   function Find_Encapsulating_State
     (States     : Elist_Id;
      Constit_Id : Entity_Id) return Entity_Id
   is
      State_Id : Entity_Id;

   begin
      --  Since a constituent may be part of a larger constituent set, climb
      --  the encapsulating state chain looking for a state that appears in
      --  States.

      State_Id := Encapsulating_State (Constit_Id);
      while Present (State_Id) loop
         if Contains (States, State_Id) then
            return State_Id;
         end if;

         State_Id := Encapsulating_State (State_Id);
      end loop;

      return Empty;
   end Find_Encapsulating_State;

   --------------------------
   -- Find_Related_Context --
   --------------------------

   function Find_Related_Context
     (Prag      : Node_Id;
      Do_Checks : Boolean := False) return Node_Id
   is
      Stmt : Node_Id;

   begin
      --  If the pragma comes from an aspect on a compilation unit that is a
      --  package instance, then return the original package instantiation
      --  node.

      if Nkind (Parent (Prag)) = N_Compilation_Unit_Aux then
         return
           Get_Unit_Instantiation_Node
             (Defining_Entity (Unit (Enclosing_Comp_Unit_Node (Prag))));
      end if;

      Stmt := Prev (Prag);
      while Present (Stmt) loop

         --  Skip prior pragmas, but check for duplicates

         if Nkind (Stmt) = N_Pragma then
            if Do_Checks
              and then Pragma_Name (Stmt) = Pragma_Name (Prag)
            then
               Duplication_Error
                 (Prag => Prag,
                  Prev => Stmt);
            end if;

         --  Skip internally generated code

         elsif not Comes_From_Source (Stmt)
           and then not Comes_From_Source (Original_Node (Stmt))
         then

            --  The anonymous object created for a single concurrent type is a
            --  suitable context.

            if Nkind (Stmt) = N_Object_Declaration
              and then Is_Single_Concurrent_Object (Defining_Entity (Stmt))
            then
               return Stmt;
            end if;

         --  Return the current source construct

         else
            return Stmt;
         end if;

         Prev (Stmt);
      end loop;

      return Empty;
   end Find_Related_Context;

   --------------------------------------
   -- Find_Related_Declaration_Or_Body --
   --------------------------------------

   function Find_Related_Declaration_Or_Body
     (Prag      : Node_Id;
      Do_Checks : Boolean := False) return Node_Id
   is
      Prag_Nam : constant Name_Id := Original_Aspect_Pragma_Name (Prag);

      procedure Expression_Function_Error;
      --  Emit an error concerning pragma Prag that illegaly applies to an
      --  expression function.

      -------------------------------
      -- Expression_Function_Error --
      -------------------------------

      procedure Expression_Function_Error is
      begin
         Error_Msg_Name_1 := Prag_Nam;

         --  Emit a precise message to distinguish between source pragmas and
         --  pragmas generated from aspects.

         if From_Aspect_Specification (Prag) then
            Error_Msg_N
              ("aspect % cannot apply to a standalone expression function",
               Prag);
         else
            Error_Msg_N
              ("pragma % cannot apply to a standalone expression function",
               Prag);
         end if;
      end Expression_Function_Error;

      --  Local variables

      Context : constant Node_Id := Parent (Prag);
      Stmt    : Node_Id;

      Look_For_Body : constant Boolean :=
                        Prag_Nam in Name_Refined_Depends
                                  | Name_Refined_Global
                                  | Name_Refined_Post
                                  | Name_Refined_State;
      --  Refinement pragmas must be associated with a subprogram body [stub]

   --  Start of processing for Find_Related_Declaration_Or_Body

   begin
      Stmt := Prev (Prag);
      while Present (Stmt) loop

         --  Skip prior pragmas, but check for duplicates. Pragmas produced
         --  by splitting a complex pre/postcondition are not considered to
         --  be duplicates.

         if Nkind (Stmt) = N_Pragma then
            if Do_Checks
              and then not Split_PPC (Stmt)
              and then Original_Aspect_Pragma_Name (Stmt) = Prag_Nam
            then
               Duplication_Error
                 (Prag => Prag,
                  Prev => Stmt);
            end if;

         --  Emit an error when a refinement pragma appears on an expression
         --  function without a completion.

         elsif Do_Checks
           and then Look_For_Body
           and then Nkind (Stmt) = N_Subprogram_Declaration
           and then Nkind (Original_Node (Stmt)) = N_Expression_Function
           and then not Has_Completion (Defining_Entity (Stmt))
         then
            Expression_Function_Error;
            return Empty;

         --  The refinement pragma applies to a subprogram body stub

         elsif Look_For_Body
           and then Nkind (Stmt) = N_Subprogram_Body_Stub
         then
            return Stmt;

         --  Skip internally generated code

         elsif not Comes_From_Source (Stmt) then

            --  The anonymous object created for a single concurrent type is a
            --  suitable context.

            if Nkind (Stmt) = N_Object_Declaration
              and then Is_Single_Concurrent_Object (Defining_Entity (Stmt))
            then
               return Stmt;

            elsif Nkind (Stmt) = N_Subprogram_Declaration then

               --  The subprogram declaration is an internally generated spec
               --  for an expression function.

               if Nkind (Original_Node (Stmt)) = N_Expression_Function then
                  return Stmt;

               --  The subprogram declaration is an internally generated spec
               --  for a stand-alone subrogram body declared inside a protected
               --  body.

               elsif Present (Corresponding_Body (Stmt))
                 and then Comes_From_Source (Corresponding_Body (Stmt))
                 and then Is_Protected_Type (Current_Scope)
               then
                  return Stmt;

               --  The subprogram is actually an instance housed within an
               --  anonymous wrapper package.

               elsif Present (Generic_Parent (Specification (Stmt))) then
                  return Stmt;

               --  Ada 2022: contract on formal subprogram or on generated
               --  Access_Subprogram_Wrapper, which appears after the related
               --  Access_Subprogram declaration.

               elsif Is_Generic_Actual_Subprogram (Defining_Entity (Stmt))
                 and then Ada_Version >= Ada_2022
               then
                  return Stmt;

               elsif Is_Access_Subprogram_Wrapper (Defining_Entity (Stmt))
                 and then Ada_Version >= Ada_2022
               then
                  return Stmt;
               end if;
            end if;

         --  Return the current construct which is either a subprogram body,
         --  a subprogram declaration or is illegal.

         else
            return Stmt;
         end if;

         Prev (Stmt);
      end loop;

      --  If we fall through, then the pragma was either the first declaration
      --  or it was preceded by other pragmas and no source constructs.

      --  The pragma is associated with a library-level subprogram

      if Nkind (Context) = N_Compilation_Unit_Aux then
         return Unit (Parent (Context));

      --  The pragma appears inside the declarations of an entry body

      elsif Nkind (Context) = N_Entry_Body then
         return Context;

      --  The pragma appears inside the statements of a subprogram body at
      --  some nested level.

      elsif Is_Statement (Context)
        and then Present (Enclosing_HSS (Context))
      then
         return Parent (Enclosing_HSS (Context));

      --  The pragma appears directly in the statements of a subprogram body

      elsif Nkind (Context) = N_Handled_Sequence_Of_Statements then
         return Parent (Context);

      --  The pragma appears inside the declarative part of a package body

      elsif Nkind (Context) = N_Package_Body then
         return Context;

      --  The pragma appears inside the declarative part of a subprogram body

      elsif Nkind (Context) = N_Subprogram_Body then
         return Context;

      --  The pragma appears inside the declarative part of a task body

      elsif Nkind (Context) = N_Task_Body then
         return Context;

      --  The pragma appears inside the visible part of a package specification

      elsif Nkind (Context) = N_Package_Specification then
         return Parent (Context);

      --  The pragma is a byproduct of aspect expansion, return the related
      --  context of the original aspect. This case has a lower priority as
      --  the above circuitry pinpoints precisely the related context.

      elsif Present (Corresponding_Aspect (Prag)) then
         return Parent (Corresponding_Aspect (Prag));

      --  No candidate subprogram [body] found

      else
         return Empty;
      end if;
   end Find_Related_Declaration_Or_Body;

   ----------------------------------
   -- Find_Related_Package_Or_Body --
   ----------------------------------

   function Find_Related_Package_Or_Body
     (Prag      : Node_Id;
      Do_Checks : Boolean := False) return Node_Id
   is
      Context  : constant Node_Id := Parent (Prag);
      Prag_Nam : constant Name_Id := Pragma_Name (Prag);
      Stmt     : Node_Id;

   begin
      Stmt := Prev (Prag);
      while Present (Stmt) loop

         --  Skip prior pragmas, but check for duplicates

         if Nkind (Stmt) = N_Pragma then
            if Do_Checks and then Pragma_Name (Stmt) = Prag_Nam then
               Duplication_Error
                 (Prag => Prag,
                  Prev => Stmt);
            end if;

         --  Skip internally generated code

         elsif not Comes_From_Source (Stmt) then
            if Nkind (Stmt) = N_Subprogram_Declaration then

               --  The subprogram declaration is an internally generated spec
               --  for an expression function.

               if Nkind (Original_Node (Stmt)) = N_Expression_Function then
                  return Stmt;

               --  The subprogram is actually an instance housed within an
               --  anonymous wrapper package.

               elsif Present (Generic_Parent (Specification (Stmt))) then
                  return Stmt;
               end if;
            end if;

         --  Return the current source construct which is illegal

         else
            return Stmt;
         end if;

         Prev (Stmt);
      end loop;

      --  If we fall through, then the pragma was either the first declaration
      --  or it was preceded by other pragmas and no source constructs.

      --  The pragma is associated with a package. The immediate context in
      --  this case is the specification of the package.

      if Nkind (Context) = N_Package_Specification then
         return Parent (Context);

      --  The pragma appears in the declarations of a package body

      elsif Nkind (Context) = N_Package_Body then
         return Context;

      --  The pragma appears in the statements of a package body

      elsif Nkind (Context) = N_Handled_Sequence_Of_Statements
        and then Nkind (Parent (Context)) = N_Package_Body
      then
         return Parent (Context);

      --  The pragma is a byproduct of aspect expansion, return the related
      --  context of the original aspect. This case has a lower priority as
      --  the above circuitry pinpoints precisely the related context.

      elsif Present (Corresponding_Aspect (Prag)) then
         return Parent (Corresponding_Aspect (Prag));

      --  No candidate package [body] found

      else
         return Empty;
      end if;
   end Find_Related_Package_Or_Body;

   ------------------
   -- Get_Argument --
   ------------------

   function Get_Argument
     (Prag       : Node_Id;
      Context_Id : Entity_Id := Empty) return Node_Id
   is
      Args : constant List_Id := Pragma_Argument_Associations (Prag);

   begin
      --  Use the expression of the original aspect when analyzing the template
      --  of a generic unit. In both cases the aspect's tree must be decorated
      --  to save the global references in the generic context.

      if From_Aspect_Specification (Prag)
        and then (Present (Context_Id) and then Is_Generic_Unit (Context_Id))
      then
         return Corresponding_Aspect (Prag);

      --  Otherwise use the expression of the pragma

      elsif Present (Args) then
         return First (Args);

      else
         return Empty;
      end if;
   end Get_Argument;

   -------------------------
   -- Get_Base_Subprogram --
   -------------------------

   function Get_Base_Subprogram (Def_Id : Entity_Id) return Entity_Id is
   begin
      --  Follow subprogram renaming chain

      if Is_Subprogram (Def_Id)
        and then Parent_Kind (Declaration_Node (Def_Id)) =
                   N_Subprogram_Renaming_Declaration
        and then Present (Alias (Def_Id))
      then
         return Alias (Def_Id);
      else
         return Def_Id;
      end if;
   end Get_Base_Subprogram;

   -----------------------
   -- Get_SPARK_Mode_Type --
   -----------------------

   function Get_SPARK_Mode_Type (N : Name_Id) return SPARK_Mode_Type is
   begin
      if N = Name_On then
         return On;
      elsif N = Name_Off then
         return Off;

      --  Any other argument is illegal. Assume that no SPARK mode applies to
      --  avoid potential cascaded errors.

      else
         return None;
      end if;
   end Get_SPARK_Mode_Type;

   ------------------------------------
   -- Get_SPARK_Mode_From_Annotation --
   ------------------------------------

   function Get_SPARK_Mode_From_Annotation
     (N : Node_Id) return SPARK_Mode_Type
   is
      Mode : Node_Id;

   begin
      if Nkind (N) = N_Aspect_Specification then
         Mode := Expression (N);

      else pragma Assert (Nkind (N) = N_Pragma);
         Mode := First (Pragma_Argument_Associations (N));

         if Present (Mode) then
            Mode := Get_Pragma_Arg (Mode);
         end if;
      end if;

      --  Aspect or pragma SPARK_Mode specifies an explicit mode

      if Present (Mode) then
         if Nkind (Mode) = N_Identifier then
            return Get_SPARK_Mode_Type (Chars (Mode));

         --  In case of a malformed aspect or pragma, return the default None

         else
            return None;
         end if;

      --  Otherwise the lack of an expression defaults SPARK_Mode to On

      else
         return On;
      end if;
   end Get_SPARK_Mode_From_Annotation;

   ---------------------------
   -- Has_Extra_Parentheses --
   ---------------------------

   function Has_Extra_Parentheses (Clause : Node_Id) return Boolean is
      Expr : Node_Id;

   begin
      --  The aggregate should not have an expression list because a clause
      --  is always interpreted as a component association. The only way an
      --  expression list can sneak in is by adding extra parentheses around
      --  the individual clauses:

      --    Depends  (Output => Input)   --  proper form
      --    Depends ((Output => Input))  --  extra parentheses

      --  Since the extra parentheses are not allowed by the syntax of the
      --  pragma, flag them now to avoid emitting misleading errors down the
      --  line.

      if Nkind (Clause) = N_Aggregate
        and then Present (Expressions (Clause))
      then
         Expr := First (Expressions (Clause));
         while Present (Expr) loop

            --  A dependency clause surrounded by extra parentheses appears
            --  as an aggregate of component associations with an optional
            --  Paren_Count set.

            if Nkind (Expr) = N_Aggregate
              and then Present (Component_Associations (Expr))
            then
               SPARK_Msg_N
                 ("dependency clause contains extra parentheses", Expr);

            --  Otherwise the expression is a malformed construct

            else
               SPARK_Msg_N ("malformed dependency clause", Expr);
            end if;

            Next (Expr);
         end loop;

         return True;
      end if;

      return False;
   end Has_Extra_Parentheses;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      Externals.Init;
      Compile_Time_Warnings_Errors.Init;
   end Initialize;

   --------
   -- ip --
   --------

   procedure ip is
   begin
      Dummy := Dummy + 1;
   end ip;

   -----------------------------
   -- Is_Config_Static_String --
   -----------------------------

   function Is_Config_Static_String (Arg : Node_Id) return Boolean is

      function Add_Config_Static_String (Arg : Node_Id) return Boolean;
      --  This is an internal recursive function that is just like the outer
      --  function except that it adds the string to the name buffer rather
      --  than placing the string in the name buffer.

      ------------------------------
      -- Add_Config_Static_String --
      ------------------------------

      function Add_Config_Static_String (Arg : Node_Id) return Boolean is
         N : Node_Id;
         C : Char_Code;

      begin
         N := Arg;

         if Nkind (N) = N_Op_Concat then
            if Add_Config_Static_String (Left_Opnd (N)) then
               N := Right_Opnd (N);
            else
               return False;
            end if;
         end if;

         if Nkind (N) /= N_String_Literal then
            Error_Msg_N ("string literal expected for pragma argument", N);
            return False;

         else
            for J in 1 .. String_Length (Strval (N)) loop
               C := Get_String_Char (Strval (N), J);

               if not In_Character_Range (C) then
                  Error_Msg
                    ("string literal contains invalid wide character",
                     Sloc (N) + 1 + Source_Ptr (J));
                  return False;
               end if;

               Add_Char_To_Name_Buffer (Get_Character (C));
            end loop;
         end if;

         return True;
      end Add_Config_Static_String;

   --  Start of processing for Is_Config_Static_String

   begin
      Name_Len := 0;

      return Add_Config_Static_String (Arg);
   end Is_Config_Static_String;

   -------------------------------
   -- Is_Elaboration_SPARK_Mode --
   -------------------------------

   function Is_Elaboration_SPARK_Mode (N : Node_Id) return Boolean is
   begin
      pragma Assert
        (Nkind (N) = N_Pragma
          and then Pragma_Name (N) = Name_SPARK_Mode
          and then Is_List_Member (N));

      --  Pragma SPARK_Mode affects the elaboration of a package body when it
      --  appears in the statement part of the body.

      return
         Present (Parent (N))
           and then Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
           and then List_Containing (N) = Statements (Parent (N))
           and then Present (Parent (Parent (N)))
           and then Nkind (Parent (Parent (N))) = N_Package_Body;
   end Is_Elaboration_SPARK_Mode;

   -----------------------
   -- Is_Enabled_Pragma --
   -----------------------

   function Is_Enabled_Pragma (Prag : Node_Id) return Boolean is
      Arg : Node_Id;

   begin
      if Present (Prag) then
         Arg := First (Pragma_Argument_Associations (Prag));

         if Present (Arg) then
            return Is_True (Expr_Value (Get_Pragma_Arg (Arg)));

         --  The lack of a Boolean argument automatically enables the pragma

         else
            return True;
         end if;

      --  The pragma is missing, therefore it is not enabled

      else
         return False;
      end if;
   end Is_Enabled_Pragma;

   -----------------------------------------
   -- Is_Non_Significant_Pragma_Reference --
   -----------------------------------------

   --  This function makes use of the following static table which indicates
   --  whether appearance of some name in a given pragma is to be considered
   --  as a reference for the purposes of warnings about unreferenced objects.

   --  -1  indicates that appearence in any argument is significant
   --  0   indicates that appearance in any argument is not significant
   --  +n  indicates that appearance as argument n is significant, but all
   --      other arguments are not significant
   --  9n  arguments from n on are significant, before n insignificant

   Sig_Flags : constant array (Pragma_Id) of Int :=
     (Pragma_Abort_Defer                    => -1,
      Pragma_Abstract_State                 => -1,
      Pragma_Ada_83                         => -1,
      Pragma_Ada_95                         => -1,
      Pragma_Ada_05                         => -1,
      Pragma_Ada_2005                       => -1,
      Pragma_Ada_12                         => -1,
      Pragma_Ada_2012                       => -1,
      Pragma_Ada_2022                       => -1,
      Pragma_Aggregate_Individually_Assign  => 0,
      Pragma_All_Calls_Remote               => -1,
      Pragma_Allow_Integer_Address          => -1,
      Pragma_Annotate                       => 93,
      Pragma_Assert                         => -1,
      Pragma_Assert_And_Cut                 => -1,
      Pragma_Assertion_Policy               =>  0,
      Pragma_Assume                         => -1,
      Pragma_Assume_No_Invalid_Values       =>  0,
      Pragma_Async_Readers                  =>  0,
      Pragma_Async_Writers                  =>  0,
      Pragma_Asynchronous                   =>  0,
      Pragma_Atomic                         =>  0,
      Pragma_Atomic_Components              =>  0,
      Pragma_Attach_Handler                 => -1,
      Pragma_Attribute_Definition           => 92,
      Pragma_Check                          => -1,
      Pragma_Check_Float_Overflow           =>  0,
      Pragma_Check_Name                     =>  0,
      Pragma_Check_Policy                   =>  0,
      Pragma_CPP_Class                      =>  0,
      Pragma_CPP_Constructor                =>  0,
      Pragma_CPP_Virtual                    =>  0,
      Pragma_CPP_Vtable                     =>  0,
      Pragma_CPU                            => -1,
      Pragma_C_Pass_By_Copy                 =>  0,
      Pragma_Comment                        => -1,
      Pragma_Common_Object                  =>  0,
      Pragma_CUDA_Device                    => -1,
      Pragma_CUDA_Execute                   => -1,
      Pragma_CUDA_Global                    => -1,
      Pragma_Compile_Time_Error             => -1,
      Pragma_Compile_Time_Warning           => -1,
      Pragma_Compiler_Unit                  => -1,
      Pragma_Compiler_Unit_Warning          => -1,
      Pragma_Complete_Representation        =>  0,
      Pragma_Complex_Representation         =>  0,
      Pragma_Component_Alignment            =>  0,
      Pragma_Constant_After_Elaboration     =>  0,
      Pragma_Contract_Cases                 => -1,
      Pragma_Controlled                     =>  0,
      Pragma_Convention                     =>  0,
      Pragma_Convention_Identifier          =>  0,
      Pragma_Deadline_Floor                 => -1,
      Pragma_Debug                          => -1,
      Pragma_Debug_Policy                   =>  0,
      Pragma_Default_Initial_Condition      => -1,
      Pragma_Default_Scalar_Storage_Order   =>  0,
      Pragma_Default_Storage_Pool           =>  0,
      Pragma_Depends                        => -1,
      Pragma_Detect_Blocking                =>  0,
      Pragma_Disable_Atomic_Synchronization =>  0,
      Pragma_Discard_Names                  =>  0,
      Pragma_Dispatching_Domain             => -1,
      Pragma_Effective_Reads                =>  0,
      Pragma_Effective_Writes               =>  0,
      Pragma_Elaborate                      =>  0,
      Pragma_Elaborate_All                  =>  0,
      Pragma_Elaborate_Body                 =>  0,
      Pragma_Elaboration_Checks             =>  0,
      Pragma_Eliminate                      =>  0,
      Pragma_Enable_Atomic_Synchronization  =>  0,
      Pragma_Export                         => -1,
      Pragma_Export_Function                => -1,
      Pragma_Export_Object                  => -1,
      Pragma_Export_Procedure               => -1,
      Pragma_Export_Valued_Procedure        => -1,
      Pragma_Extend_System                  => -1,
      Pragma_Extensions_Allowed             =>  0,
      Pragma_Extensions_Visible             =>  0,
      Pragma_External                       => -1,
      Pragma_External_Name_Casing           =>  0,
      Pragma_Fast_Math                      =>  0,
      Pragma_Favor_Top_Level                =>  0,
      Pragma_Finalize_Storage_Only          =>  0,
      Pragma_Ghost                          =>  0,
      Pragma_Global                         => -1,
      Pragma_GNAT_Annotate                  => 93,
      Pragma_Ident                          => -1,
      Pragma_Ignore_Pragma                  =>  0,
      Pragma_Implementation_Defined         => -1,
      Pragma_Implemented                    => -1,
      Pragma_Implicit_Packing               =>  0,
      Pragma_Import                         => 93,
      Pragma_Import_Function                =>  0,
      Pragma_Import_Object                  =>  0,
      Pragma_Import_Procedure               =>  0,
      Pragma_Import_Valued_Procedure        =>  0,
      Pragma_Independent                    =>  0,
      Pragma_Independent_Components         =>  0,
      Pragma_Initial_Condition              => -1,
      Pragma_Initialize_Scalars             =>  0,
      Pragma_Initializes                    => -1,
      Pragma_Inline                         =>  0,
      Pragma_Inline_Always                  =>  0,
      Pragma_Inline_Generic                 =>  0,
      Pragma_Inspection_Point               => -1,
      Pragma_Interface                      => 92,
      Pragma_Interface_Name                 =>  0,
      Pragma_Interrupt_Handler              => -1,
      Pragma_Interrupt_Priority             => -1,
      Pragma_Interrupt_State                => -1,
      Pragma_Invariant                      => -1,
      Pragma_Keep_Names                     =>  0,
      Pragma_License                        =>  0,
      Pragma_Link_With                      => -1,
      Pragma_Linker_Alias                   => -1,
      Pragma_Linker_Constructor             => -1,
      Pragma_Linker_Destructor              => -1,
      Pragma_Linker_Options                 => -1,
      Pragma_Linker_Section                 => -1,
      Pragma_List                           =>  0,
      Pragma_Lock_Free                      =>  0,
      Pragma_Locking_Policy                 =>  0,
      Pragma_Loop_Invariant                 => -1,
      Pragma_Loop_Optimize                  =>  0,
      Pragma_Loop_Variant                   => -1,
      Pragma_Machine_Attribute              => -1,
      Pragma_Main                           => -1,
      Pragma_Main_Storage                   => -1,
      Pragma_Max_Entry_Queue_Depth          =>  0,
      Pragma_Max_Entry_Queue_Length         =>  0,
      Pragma_Max_Queue_Length               =>  0,
      Pragma_Memory_Size                    =>  0,
      Pragma_No_Body                        =>  0,
      Pragma_No_Caching                     =>  0,
      Pragma_No_Component_Reordering        => -1,
      Pragma_No_Elaboration_Code_All        =>  0,
      Pragma_No_Heap_Finalization           =>  0,
      Pragma_No_Inline                      =>  0,
      Pragma_No_Return                      =>  0,
      Pragma_No_Run_Time                    => -1,
      Pragma_No_Strict_Aliasing             => -1,
      Pragma_No_Tagged_Streams              =>  0,
      Pragma_Normalize_Scalars              =>  0,
      Pragma_Obsolescent                    =>  0,
      Pragma_Optimize                       =>  0,
      Pragma_Optimize_Alignment             =>  0,
      Pragma_Ordered                        =>  0,
      Pragma_Overflow_Mode                  =>  0,
      Pragma_Overriding_Renamings           =>  0,
      Pragma_Pack                           =>  0,
      Pragma_Page                           =>  0,
      Pragma_Part_Of                        =>  0,
      Pragma_Partition_Elaboration_Policy   =>  0,
      Pragma_Passive                        =>  0,
      Pragma_Persistent_BSS                 =>  0,
      Pragma_Post                           => -1,
      Pragma_Postcondition                  => -1,
      Pragma_Post_Class                     => -1,
      Pragma_Pre                            => -1,
      Pragma_Precondition                   => -1,
      Pragma_Predicate                      => -1,
      Pragma_Predicate_Failure              => -1,
      Pragma_Preelaborable_Initialization   => -1,
      Pragma_Preelaborate                   =>  0,
      Pragma_Prefix_Exception_Messages      =>  0,
      Pragma_Pre_Class                      => -1,
      Pragma_Priority                       => -1,
      Pragma_Priority_Specific_Dispatching  =>  0,
      Pragma_Profile                        =>  0,
      Pragma_Profile_Warnings               =>  0,
      Pragma_Propagate_Exceptions           =>  0,
      Pragma_Provide_Shift_Operators        =>  0,
      Pragma_Psect_Object                   =>  0,
      Pragma_Pure                           =>  0,
      Pragma_Pure_Function                  =>  0,
      Pragma_Queuing_Policy                 =>  0,
      Pragma_Rational                       =>  0,
      Pragma_Ravenscar                      =>  0,
      Pragma_Refined_Depends                => -1,
      Pragma_Refined_Global                 => -1,
      Pragma_Refined_Post                   => -1,
      Pragma_Refined_State                  => -1,
      Pragma_Relative_Deadline              =>  0,
      Pragma_Remote_Access_Type             => -1,
      Pragma_Remote_Call_Interface          => -1,
      Pragma_Remote_Types                   => -1,
      Pragma_Rename_Pragma                  =>  0,
      Pragma_Restricted_Run_Time            =>  0,
      Pragma_Restriction_Warnings           =>  0,
      Pragma_Restrictions                   =>  0,
      Pragma_Reviewable                     => -1,
      Pragma_Secondary_Stack_Size           => -1,
      Pragma_Share_Generic                  =>  0,
      Pragma_Shared                         =>  0,
      Pragma_Shared_Passive                 =>  0,
      Pragma_Short_Circuit_And_Or           =>  0,
      Pragma_Short_Descriptors              =>  0,
      Pragma_Simple_Storage_Pool_Type       =>  0,
      Pragma_Source_File_Name               =>  0,
      Pragma_Source_File_Name_Project       =>  0,
      Pragma_Source_Reference               =>  0,
      Pragma_SPARK_Mode                     =>  0,
      Pragma_Static_Elaboration_Desired     =>  0,
      Pragma_Storage_Size                   => -1,
      Pragma_Storage_Unit                   =>  0,
      Pragma_Stream_Convert                 =>  0,
      Pragma_Style_Checks                   =>  0,
      Pragma_Subprogram_Variant             => -1,
      Pragma_Subtitle                       =>  0,
      Pragma_Suppress                       =>  0,
      Pragma_Suppress_All                   =>  0,
      Pragma_Suppress_Debug_Info            =>  0,
      Pragma_Suppress_Exception_Locations   =>  0,
      Pragma_Suppress_Initialization        =>  0,
      Pragma_System_Name                    =>  0,
      Pragma_Task_Dispatching_Policy        =>  0,
      Pragma_Task_Info                      => -1,
      Pragma_Task_Name                      => -1,
      Pragma_Task_Storage                   => -1,
      Pragma_Test_Case                      => -1,
      Pragma_Thread_Local_Storage           => -1,
      Pragma_Time_Slice                     => -1,
      Pragma_Title                          =>  0,
      Pragma_Type_Invariant                 => -1,
      Pragma_Type_Invariant_Class           => -1,
      Pragma_Unchecked_Union                =>  0,
      Pragma_Unevaluated_Use_Of_Old         =>  0,
      Pragma_Unimplemented_Unit             =>  0,
      Pragma_Universal_Aliasing             =>  0,
      Pragma_Unmodified                     =>  0,
      Pragma_Unreferenced                   =>  0,
      Pragma_Unreferenced_Objects           =>  0,
      Pragma_Unreserve_All_Interrupts       =>  0,
      Pragma_Unsuppress                     =>  0,
      Pragma_Unused                         =>  0,
      Pragma_Use_VADS_Size                  =>  0,
      Pragma_Validity_Checks                =>  0,
      Pragma_Volatile                       =>  0,
      Pragma_Volatile_Components            =>  0,
      Pragma_Volatile_Full_Access           =>  0,
      Pragma_Volatile_Function              =>  0,
      Pragma_Warning_As_Error               =>  0,
      Pragma_Warnings                       =>  0,
      Pragma_Weak_External                  =>  0,
      Pragma_Wide_Character_Encoding        =>  0,
      Unknown_Pragma                        =>  0);

   function Is_Non_Significant_Pragma_Reference (N : Node_Id) return Boolean is
      Id : Pragma_Id;
      P  : Node_Id;
      C  : Int;
      AN : Nat;

      function Arg_No return Nat;
      --  Returns an integer showing what argument we are in. A value of
      --  zero means we are not in any of the arguments.

      ------------
      -- Arg_No --
      ------------

      function Arg_No return Nat is
         A : Node_Id;
         N : Nat;

      begin
         A := First (Pragma_Argument_Associations (Parent (P)));
         N := 1;
         loop
            if No (A) then
               return 0;
            elsif A = P then
               return N;
            end if;

            Next (A);
            N := N + 1;
         end loop;
      end Arg_No;

   --  Start of processing for Non_Significant_Pragma_Reference

   begin
      P := Parent (N);

      if Nkind (P) /= N_Pragma_Argument_Association then
         return False;

      else
         Id := Get_Pragma_Id (Parent (P));
         C := Sig_Flags (Id);
         AN := Arg_No;

         if AN = 0 then
            return False;
         end if;

         case C is
            when -1 =>
               return False;

            when 0 =>
               return True;

            when 92 .. 99 =>
               return AN < (C - 90);

            when others =>
               return AN /= C;
         end case;
      end if;
   end Is_Non_Significant_Pragma_Reference;

   ------------------------------
   -- Is_Pragma_String_Literal --
   ------------------------------

   --  This function returns true if the corresponding pragma argument is a
   --  static string expression. These are the only cases in which string
   --  literals can appear as pragma arguments. We also allow a string literal
   --  as the first argument to pragma Assert (although it will of course
   --  always generate a type error).

   function Is_Pragma_String_Literal (Par : Node_Id) return Boolean is
      Pragn : constant Node_Id := Parent (Par);
      Assoc : constant List_Id := Pragma_Argument_Associations (Pragn);
      Pname : constant Name_Id := Pragma_Name (Pragn);
      Argn  : Natural;
      N     : Node_Id;

   begin
      Argn := 1;
      N := First (Assoc);
      loop
         exit when N = Par;
         Argn := Argn + 1;
         Next (N);
      end loop;

      if Pname = Name_Assert then
         return True;

      elsif Pname = Name_Export then
         return Argn > 2;

      elsif Pname = Name_Ident then
         return Argn = 1;

      elsif Pname = Name_Import then
         return Argn > 2;

      elsif Pname = Name_Interface_Name then
         return Argn > 1;

      elsif Pname = Name_Linker_Alias then
         return Argn = 2;

      elsif Pname = Name_Linker_Section then
         return Argn = 2;

      elsif Pname = Name_Machine_Attribute then
         return Argn = 2;

      elsif Pname = Name_Source_File_Name then
         return True;

      elsif Pname = Name_Source_Reference then
         return Argn = 2;

      elsif Pname = Name_Title then
         return True;

      elsif Pname = Name_Subtitle then
         return True;

      else
         return False;
      end if;
   end Is_Pragma_String_Literal;

   ---------------------------
   -- Is_Private_SPARK_Mode --
   ---------------------------

   function Is_Private_SPARK_Mode (N : Node_Id) return Boolean is
   begin
      pragma Assert
        (Nkind (N) = N_Pragma
          and then Pragma_Name (N) = Name_SPARK_Mode
          and then Is_List_Member (N));

      --  For pragma SPARK_Mode to be private, it has to appear in the private
      --  declarations of a package.

      return
        Present (Parent (N))
          and then Nkind (Parent (N)) = N_Package_Specification
          and then List_Containing (N) = Private_Declarations (Parent (N));
   end Is_Private_SPARK_Mode;

   -------------------------------------
   -- Is_Unconstrained_Or_Tagged_Item --
   -------------------------------------

   function Is_Unconstrained_Or_Tagged_Item
     (Item : Entity_Id) return Boolean
   is
      function Has_Unconstrained_Component (Typ : Entity_Id) return Boolean;
      --  Determine whether record type Typ has at least one unconstrained
      --  component.

      ---------------------------------
      -- Has_Unconstrained_Component --
      ---------------------------------

      function Has_Unconstrained_Component (Typ : Entity_Id) return Boolean is
         Comp : Entity_Id;

      begin
         Comp := First_Component (Typ);
         while Present (Comp) loop
            if Is_Unconstrained_Or_Tagged_Item (Comp) then
               return True;
            end if;

            Next_Component (Comp);
         end loop;

         return False;
      end Has_Unconstrained_Component;

      --  Local variables

      Typ : constant Entity_Id := Etype (Item);

   --  Start of processing for Is_Unconstrained_Or_Tagged_Item

   begin
      if Is_Tagged_Type (Typ) then
         return True;

      elsif Is_Array_Type (Typ) and then not Is_Constrained (Typ) then
         return True;

      elsif Is_Record_Type (Typ) then
         if Has_Discriminants (Typ) and then not Is_Constrained (Typ) then
            return True;
         else
            return Has_Unconstrained_Component (Typ);
         end if;

      elsif Is_Private_Type (Typ) and then Has_Discriminants (Typ) then
         return True;

      else
         return False;
      end if;
   end Is_Unconstrained_Or_Tagged_Item;

   -----------------------------
   -- Is_Valid_Assertion_Kind --
   -----------------------------

   function Is_Valid_Assertion_Kind (Nam : Name_Id) return Boolean is
   begin
      case Nam is
         when
            --  RM defined

              Name_Assert
            | Name_Static_Predicate
            | Name_Dynamic_Predicate
            | Name_Pre
            | Name_uPre
            | Name_Post
            | Name_uPost
            | Name_Type_Invariant
            | Name_uType_Invariant

            --  Impl defined

            | Name_Assert_And_Cut
            | Name_Assume
            | Name_Contract_Cases
            | Name_Debug
            | Name_Default_Initial_Condition
            | Name_Ghost
            | Name_Initial_Condition
            | Name_Invariant
            | Name_uInvariant
            | Name_Loop_Invariant
            | Name_Loop_Variant
            | Name_Postcondition
            | Name_Precondition
            | Name_Predicate
            | Name_Refined_Post
            | Name_Statement_Assertions
            | Name_Subprogram_Variant
         =>
            return True;

         when others =>
            return False;
      end case;
   end Is_Valid_Assertion_Kind;

   --------------------------------------
   -- Process_Compilation_Unit_Pragmas --
   --------------------------------------

   procedure Process_Compilation_Unit_Pragmas (N : Node_Id) is
   begin
      --  A special check for pragma Suppress_All, a very strange DEC pragma,
      --  strange because it comes at the end of the unit. Rational has the
      --  same name for a pragma, but treats it as a program unit pragma, In
      --  GNAT we just decide to allow it anywhere at all. If it appeared then
      --  the flag Has_Pragma_Suppress_All was set on the compilation unit
      --  node, and we insert a pragma Suppress (All_Checks) at the start of
      --  the context clause to ensure the correct processing.

      if Has_Pragma_Suppress_All (N) then
         Prepend_To (Context_Items (N),
           Make_Pragma (Sloc (N),
             Chars                        => Name_Suppress,
             Pragma_Argument_Associations => New_List (
               Make_Pragma_Argument_Association (Sloc (N),
                 Expression => Make_Identifier (Sloc (N), Name_All_Checks)))));
      end if;

      --  Nothing else to do at the current time

   end Process_Compilation_Unit_Pragmas;

   --------------------------------------------
   -- Validate_Compile_Time_Warning_Or_Error --
   --------------------------------------------

   procedure Validate_Compile_Time_Warning_Or_Error
     (N     : Node_Id;
      Eloc  : Source_Ptr)
   is
      Arg1  : constant Node_Id := First (Pragma_Argument_Associations (N));
      Arg1x : constant Node_Id := Get_Pragma_Arg (Arg1);
      Arg2  : constant Node_Id := Next (Arg1);

      Pname   : constant Name_Id   := Pragma_Name_Unmapped (N);
      Prag_Id : constant Pragma_Id := Get_Pragma_Id (Pname);

   begin
      Analyze_And_Resolve (Arg1x, Standard_Boolean);

      if Compile_Time_Known_Value (Arg1x) then
         if Is_True (Expr_Value (Arg1x)) then

            --  We have already verified that the second argument is a static
            --  string expression. Its string value must be retrieved
            --  explicitly if it is a declared constant, otherwise it has
            --  been constant-folded previously.

            declare
               Cent    : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
               Str     : constant String_Id :=
                           Strval (Expr_Value_S (Get_Pragma_Arg (Arg2)));
               Str_Len : constant Nat       := String_Length (Str);

               Force : constant Boolean :=
                         Prag_Id = Pragma_Compile_Time_Warning
                           and then Is_Spec_Name (Unit_Name (Current_Sem_Unit))
                           and then (Ekind (Cent) /= E_Package
                                      or else not In_Private_Part (Cent));
               --  Set True if this is the warning case, and we are in the
               --  visible part of a package spec, or in a subprogram spec,
               --  in which case we want to force the client to see the
               --  warning, even though it is not in the main unit.

               C    : Character;
               CC   : Char_Code;
               Cont : Boolean;
               Ptr  : Nat;

            begin
               --  Loop through segments of message separated by line feeds.
               --  We output these segments as separate messages with
               --  continuation marks for all but the first.

               Cont := False;
               Ptr  := 1;
               loop
                  Error_Msg_Strlen := 0;

                  --  Loop to copy characters from argument to error message
                  --  string buffer.

                  loop
                     exit when Ptr > Str_Len;
                     CC := Get_String_Char (Str, Ptr);
                     Ptr := Ptr + 1;

                     --  Ignore wide chars ??? else store character

                     if In_Character_Range (CC) then
                        C := Get_Character (CC);
                        exit when C = ASCII.LF;
                        Error_Msg_Strlen := Error_Msg_Strlen + 1;
                        Error_Msg_String (Error_Msg_Strlen) := C;
                     end if;
                  end loop;

                  --  Here with one line ready to go

                  Error_Msg_Warn := Prag_Id = Pragma_Compile_Time_Warning;

                  --  If this is a warning in a spec, then we want clients
                  --  to see the warning, so mark the message with the
                  --  special sequence !! to force the warning. In the case
                  --  of a package spec, we do not force this if we are in
                  --  the private part of the spec.

                  if Force then
                     if Cont = False then
                        Error_Msg
                           ("<<~!!", Eloc, Is_Compile_Time_Pragma => True);
                        Cont := True;
                     else
                        Error_Msg
                           ("\<<~!!", Eloc, Is_Compile_Time_Pragma => True);
                     end if;

                  --  Error, rather than warning, or in a body, so we do not
                  --  need to force visibility for client (error will be
                  --  output in any case, and this is the situation in which
                  --  we do not want a client to get a warning, since the
                  --  warning is in the body or the spec private part).

                  else
                     if Cont = False then
                        Error_Msg
                           ("<<~", Eloc, Is_Compile_Time_Pragma => True);
                        Cont := True;
                     else
                        Error_Msg
                           ("\<<~", Eloc, Is_Compile_Time_Pragma => True);
                     end if;
                  end if;

                  exit when Ptr > Str_Len;
               end loop;
            end;
         end if;

      --  Arg1x is not known at compile time, so possibly issue an error
      --  or warning. This can happen only if the pragma's processing
      --  was deferred until after the back end is run (see
      --  Process_Compile_Time_Warning_Or_Error). Note that the warning
      --  control switch applies to only the warning case.

      elsif Prag_Id = Pragma_Compile_Time_Error then
         Error_Msg_N ("condition is not known at compile time", Arg1x);

      elsif Warn_On_Unknown_Compile_Time_Warning then
         Error_Msg_N ("?_c?condition is not known at compile time", Arg1x);
      end if;
   end Validate_Compile_Time_Warning_Or_Error;

   ------------------------------------
   -- Record_Possible_Body_Reference --
   ------------------------------------

   procedure Record_Possible_Body_Reference
     (State_Id : Entity_Id;
      Ref      : Node_Id)
   is
      Context : Node_Id;
      Spec_Id : Entity_Id;

   begin
      --  Ensure that we are dealing with a reference to a state

      pragma Assert (Ekind (State_Id) = E_Abstract_State);

      --  Climb the tree starting from the reference looking for a package body
      --  whose spec declares the referenced state. This criteria automatically
      --  excludes references in package specs which are legal. Note that it is
      --  not wise to emit an error now as the package body may lack pragma
      --  Refined_State or the referenced state may not be mentioned in the
      --  refinement. This approach avoids the generation of misleading errors.

      Context := Ref;
      while Present (Context) loop
         if Nkind (Context) = N_Package_Body then
            Spec_Id := Corresponding_Spec (Context);

            if Present (Abstract_States (Spec_Id))
              and then Contains (Abstract_States (Spec_Id), State_Id)
            then
               if No (Body_References (State_Id)) then
                  Set_Body_References (State_Id, New_Elmt_List);
               end if;

               Append_Elmt (Ref, To => Body_References (State_Id));
               exit;
            end if;
         end if;

         Context := Parent (Context);
      end loop;
   end Record_Possible_Body_Reference;

   ------------------------------------------
   -- Relocate_Pragmas_To_Anonymous_Object --
   ------------------------------------------

   procedure Relocate_Pragmas_To_Anonymous_Object
     (Typ_Decl : Node_Id;
      Obj_Decl : Node_Id)
   is
      Decl      : Node_Id;
      Def       : Node_Id;
      Next_Decl : Node_Id;

   begin
      if Nkind (Typ_Decl) = N_Protected_Type_Declaration then
         Def := Protected_Definition (Typ_Decl);
      else
         pragma Assert (Nkind (Typ_Decl) = N_Task_Type_Declaration);
         Def := Task_Definition (Typ_Decl);
      end if;

      --  The concurrent definition has a visible declaration list. Inspect it
      --  and relocate all canidate pragmas.

      if Present (Def) and then Present (Visible_Declarations (Def)) then
         Decl := First (Visible_Declarations (Def));
         while Present (Decl) loop

            --  Preserve the following declaration for iteration purposes due
            --  to possible relocation of a pragma.

            Next_Decl := Next (Decl);

            if Nkind (Decl) = N_Pragma
              and then Pragma_On_Anonymous_Object_OK (Get_Pragma_Id (Decl))
            then
               Remove (Decl);
               Insert_After (Obj_Decl, Decl);

            --  Skip internally generated code

            elsif not Comes_From_Source (Decl) then
               null;

            --  No candidate pragmas are available for relocation

            else
               exit;
            end if;

            Decl := Next_Decl;
         end loop;
      end if;
   end Relocate_Pragmas_To_Anonymous_Object;

   ------------------------------
   -- Relocate_Pragmas_To_Body --
   ------------------------------

   procedure Relocate_Pragmas_To_Body
     (Subp_Body   : Node_Id;
      Target_Body : Node_Id := Empty)
   is
      procedure Relocate_Pragma (Prag : Node_Id);
      --  Remove a single pragma from its current list and add it to the
      --  declarations of the proper body (either Subp_Body or Target_Body).

      ---------------------
      -- Relocate_Pragma --
      ---------------------

      procedure Relocate_Pragma (Prag : Node_Id) is
         Decls  : List_Id;
         Target : Node_Id;

      begin
         --  When subprogram stubs or expression functions are involves, the
         --  destination declaration list belongs to the proper body.

         if Present (Target_Body) then
            Target := Target_Body;
         else
            Target := Subp_Body;
         end if;

         Decls := Declarations (Target);

         if No (Decls) then
            Decls := New_List;
            Set_Declarations (Target, Decls);
         end if;

         --  Unhook the pragma from its current list

         Remove  (Prag);
         Prepend (Prag, Decls);
      end Relocate_Pragma;

      --  Local variables

      Body_Id   : constant Entity_Id :=
                    Defining_Unit_Name (Specification (Subp_Body));
      Next_Stmt : Node_Id;
      Stmt      : Node_Id;

   --  Start of processing for Relocate_Pragmas_To_Body

   begin
      --  Do not process a body that comes from a separate unit as no construct
      --  can possibly follow it.

      if not Is_List_Member (Subp_Body) then
         return;

      --  Do not relocate pragmas that follow a stub if the stub does not have
      --  a proper body.

      elsif Nkind (Subp_Body) = N_Subprogram_Body_Stub
        and then No (Target_Body)
      then
         return;

      --  Do not process internally generated routine _Postconditions

      elsif Ekind (Body_Id) = E_Procedure
        and then Chars (Body_Id) = Name_uPostconditions
      then
         return;
      end if;

      --  Look at what is following the body. We are interested in certain kind
      --  of pragmas (either from source or byproducts of expansion) that can
      --  apply to a body [stub].

      Stmt := Next (Subp_Body);
      while Present (Stmt) loop

         --  Preserve the following statement for iteration purposes due to a
         --  possible relocation of a pragma.

         Next_Stmt := Next (Stmt);

         --  Move a candidate pragma following the body to the declarations of
         --  the body.

         if Nkind (Stmt) = N_Pragma
           and then Pragma_On_Body_Or_Stub_OK (Get_Pragma_Id (Stmt))
         then

            --  If a source pragma Warnings follows the body, it applies to
            --  following statements and does not belong in the body.

            if Get_Pragma_Id (Stmt) = Pragma_Warnings
              and then Comes_From_Source (Stmt)
            then
               null;
            else
               Relocate_Pragma (Stmt);
            end if;

         --  Skip internally generated code

         elsif not Comes_From_Source (Stmt) then
            null;

         --  No candidate pragmas are available for relocation

         else
            exit;
         end if;

         Stmt := Next_Stmt;
      end loop;
   end Relocate_Pragmas_To_Body;

   -------------------
   -- Resolve_State --
   -------------------

   procedure Resolve_State (N : Node_Id) is
      Func  : Entity_Id;
      State : Entity_Id;

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

         --  Handle overloading of state names by functions. Traverse the
         --  homonym chain looking for an abstract state.

         if Ekind (Func) = E_Function and then Has_Homonym (Func) then
            pragma Assert (Is_Overloaded (N));

            State := Homonym (Func);
            while Present (State) loop
               if Ekind (State) = E_Abstract_State then

                  --  Resolve the overloading by setting the proper entity of
                  --  the reference to that of the state.

                  Set_Etype         (N, Standard_Void_Type);
                  Set_Entity        (N, State);
                  Set_Is_Overloaded (N, False);

                  Generate_Reference (State, N);
                  return;
               end if;

               State := Homonym (State);
            end loop;

            --  A function can never act as a state. If the homonym chain does
            --  not contain a corresponding state, then something went wrong in
            --  the overloading mechanism.

            raise Program_Error;
         end if;
      end if;
   end Resolve_State;

   ----------------------------
   -- Rewrite_Assertion_Kind --
   ----------------------------

   procedure Rewrite_Assertion_Kind
     (N           : Node_Id;
      From_Policy : Boolean := False)
   is
      Nam : Name_Id;

   begin
      Nam := No_Name;
      if Nkind (N) = N_Attribute_Reference
        and then Attribute_Name (N) = Name_Class
        and then Nkind (Prefix (N)) = N_Identifier
      then
         case Chars (Prefix (N)) is
            when Name_Pre =>
               Nam := Name_uPre;

            when Name_Post =>
               Nam := Name_uPost;

            when Name_Type_Invariant =>
               Nam := Name_uType_Invariant;

            when Name_Invariant =>
               Nam := Name_uInvariant;

            when others =>
               return;
         end case;

      --  Recommend standard use of aspect names Pre/Post

      elsif Nkind (N) = N_Identifier
        and then From_Policy
        and then Serious_Errors_Detected = 0
      then
         if Chars (N) = Name_Precondition
           or else Chars (N) = Name_Postcondition
         then
            Error_Msg_N ("Check_Policy is a non-standard pragma??", N);
            Error_Msg_N
              ("\use Assertion_Policy and aspect names Pre/Post for "
               & "Ada2012 conformance?", N);
         end if;

         return;
      end if;

      if Nam /= No_Name then
         Rewrite (N, Make_Identifier (Sloc (N), Chars => Nam));
      end if;
   end Rewrite_Assertion_Kind;

   --------
   -- rv --
   --------

   procedure rv is
   begin
      Dummy := Dummy + 1;
   end rv;

   --------------------------------
   -- Set_Encoded_Interface_Name --
   --------------------------------

   procedure Set_Encoded_Interface_Name (E : Entity_Id; S : Node_Id) is
      Str : constant String_Id := Strval (S);
      Len : constant Nat       := String_Length (Str);
      CC  : Char_Code;
      C   : Character;
      J   : Pos;

      Hex : constant array (0 .. 15) of Character := "0123456789abcdef";

      procedure Encode;
      --  Stores encoded value of character code CC. The encoding we use an
      --  underscore followed by four lower case hex digits.

      ------------
      -- Encode --
      ------------

      procedure Encode is
      begin
         Store_String_Char (Get_Char_Code ('_'));
         Store_String_Char
           (Get_Char_Code (Hex (Integer (CC / 2 ** 12))));
         Store_String_Char
           (Get_Char_Code (Hex (Integer (CC / 2 ** 8 and 16#0F#))));
         Store_String_Char
           (Get_Char_Code (Hex (Integer (CC / 2 ** 4 and 16#0F#))));
         Store_String_Char
           (Get_Char_Code (Hex (Integer (CC and 16#0F#))));
      end Encode;

   --  Start of processing for Set_Encoded_Interface_Name

   begin
      --  If first character is asterisk, this is a link name, and we leave it
      --  completely unmodified. We also ignore null strings (the latter case
      --  happens only in error cases).

      if Len = 0
        or else Get_String_Char (Str, 1) = Get_Char_Code ('*')
      then
         Set_Interface_Name (E, S);

      else
         J := 1;
         loop
            CC := Get_String_Char (Str, J);

            exit when not In_Character_Range (CC);

            C := Get_Character (CC);

            exit when C /= '_' and then C /= '$'
              and then C not in '0' .. '9'
              and then C not in 'a' .. 'z'
              and then C not in 'A' .. 'Z';

            if J = Len then
               Set_Interface_Name (E, S);
               return;

            else
               J := J + 1;
            end if;
         end loop;

         --  Here we need to encode. The encoding we use as follows:
         --     three underscores  + four hex digits (lower case)

         Start_String;

         for J in 1 .. String_Length (Str) loop
            CC := Get_String_Char (Str, J);

            if not In_Character_Range (CC) then
               Encode;
            else
               C := Get_Character (CC);

               if C = '_' or else C = '$'
                 or else C in '0' .. '9'
                 or else C in 'a' .. 'z'
                 or else C in 'A' .. 'Z'
               then
                  Store_String_Char (CC);
               else
                  Encode;
               end if;
            end if;
         end loop;

         Set_Interface_Name (E,
           Make_String_Literal (Sloc (S),
             Strval => End_String));
      end if;
   end Set_Encoded_Interface_Name;

   ------------------------
   -- Set_Elab_Unit_Name --
   ------------------------

   procedure Set_Elab_Unit_Name (N : Node_Id; With_Item : Node_Id) is
      Pref : Node_Id;
      Scop : Entity_Id;

   begin
      if Nkind (N) = N_Identifier
        and then Nkind (With_Item) = N_Identifier
      then
         Set_Entity (N, Entity (With_Item));

      elsif Nkind (N) = N_Selected_Component then
         Change_Selected_Component_To_Expanded_Name (N);
         Set_Entity (N, Entity (With_Item));
         Set_Entity (Selector_Name (N), Entity (N));

         Pref := Prefix (N);
         Scop := Scope (Entity (N));
         while Nkind (Pref) = N_Selected_Component loop
            Change_Selected_Component_To_Expanded_Name (Pref);
            Set_Entity (Selector_Name (Pref), Scop);
            Set_Entity (Pref, Scop);
            Pref := Prefix (Pref);
            Scop := Scope (Scop);
         end loop;

         Set_Entity (Pref, Scop);
      end if;

      Generate_Reference (Entity (With_Item), N, Set_Ref => False);
   end Set_Elab_Unit_Name;

   -----------------------
   -- Set_Overflow_Mode --
   -----------------------

   procedure Set_Overflow_Mode (N : Node_Id) is

      function Get_Overflow_Mode (Arg : Node_Id) return Overflow_Mode_Type;
      --  Function to process one pragma argument, Arg

      -----------------------
      -- Get_Overflow_Mode --
      -----------------------

      function Get_Overflow_Mode (Arg : Node_Id) return Overflow_Mode_Type is
         Argx : constant Node_Id := Get_Pragma_Arg (Arg);

      begin
         if Chars (Argx) = Name_Strict then
            return Strict;

         elsif Chars (Argx) = Name_Minimized then
            return Minimized;

         elsif Chars (Argx) = Name_Eliminated then
            return Eliminated;

         else
            raise Program_Error;
         end if;
      end Get_Overflow_Mode;

      --  Local variables

      Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
      Arg2 : constant Node_Id := Next (Arg1);

   --  Start of processing for Set_Overflow_Mode

   begin
      --  Process first argument

      Scope_Suppress.Overflow_Mode_General :=
        Get_Overflow_Mode (Arg1);

      --  Case of only one argument

      if No (Arg2) then
         Scope_Suppress.Overflow_Mode_Assertions :=
           Scope_Suppress.Overflow_Mode_General;

      --  Case of two arguments present

      else
         Scope_Suppress.Overflow_Mode_Assertions  :=
           Get_Overflow_Mode (Arg2);
      end if;
   end Set_Overflow_Mode;

   -------------------
   -- Test_Case_Arg --
   -------------------

   function Test_Case_Arg
     (Prag        : Node_Id;
      Arg_Nam     : Name_Id;
      From_Aspect : Boolean := False) return Node_Id
   is
      Aspect : constant Node_Id := Corresponding_Aspect (Prag);
      Arg    : Node_Id;
      Args   : Node_Id;

   begin
      pragma Assert
        (Arg_Nam in Name_Ensures | Name_Mode | Name_Name | Name_Requires);

      --  The caller requests the aspect argument

      if From_Aspect then
         if Present (Aspect)
           and then Nkind (Expression (Aspect)) = N_Aggregate
         then
            Args := Expression (Aspect);

            --  "Name" and "Mode" may appear without an identifier as a
            --  positional association.

            if Present (Expressions (Args)) then
               Arg := First (Expressions (Args));

               if Present (Arg) and then Arg_Nam = Name_Name then
                  return Arg;
               end if;

               --  Skip "Name"

               Arg := Next (Arg);

               if Present (Arg) and then Arg_Nam = Name_Mode then
                  return Arg;
               end if;
            end if;

            --  Some or all arguments may appear as component associatons

            if Present (Component_Associations (Args)) then
               Arg := First (Component_Associations (Args));
               while Present (Arg) loop
                  if Chars (First (Choices (Arg))) = Arg_Nam then
                     return Arg;
                  end if;

                  Next (Arg);
               end loop;
            end if;
         end if;

      --  Otherwise retrieve the argument directly from the pragma

      else
         Arg := First (Pragma_Argument_Associations (Prag));

         if Present (Arg) and then Arg_Nam = Name_Name then
            return Arg;
         end if;

         --  Skip argument "Name"

         Arg := Next (Arg);

         if Present (Arg) and then Arg_Nam = Name_Mode then
            return Arg;
         end if;

         --  Skip argument "Mode"

         Arg := Next (Arg);

         --  Arguments "Requires" and "Ensures" are optional and may not be
         --  present at all.

         while Present (Arg) loop
            if Chars (Arg) = Arg_Nam then
               return Arg;
            end if;

            Next (Arg);
         end loop;
      end if;

      return Empty;
   end Test_Case_Arg;

   --------------------------------------------
   -- Defer_Compile_Time_Warning_Error_To_BE --
   --------------------------------------------

   procedure Defer_Compile_Time_Warning_Error_To_BE (N : Node_Id) is
      Arg1  : constant Node_Id := First (Pragma_Argument_Associations (N));
   begin
      Compile_Time_Warnings_Errors.Append
        (New_Val => CTWE_Entry'(Eloc  => Sloc (Arg1),
                                Scope => Current_Scope,
                                Prag  => N));

      --  If the Boolean expression contains T'Size, and we're not in the main
      --  unit being compiled, then we need to copy the pragma into the main
      --  unit, because otherwise T'Size might never be computed, leaving it
      --  as 0.

      if not In_Extended_Main_Code_Unit (N) then
         Insert_Library_Level_Action (New_Copy_Tree (N));
      end if;
   end Defer_Compile_Time_Warning_Error_To_BE;

   ------------------------------------------
   -- Validate_Compile_Time_Warning_Errors --
   ------------------------------------------

   procedure Validate_Compile_Time_Warning_Errors is
      procedure Set_Scope (S : Entity_Id);
      --  Install all enclosing scopes of S along with S itself

      procedure Unset_Scope (S : Entity_Id);
      --  Uninstall all enclosing scopes of S along with S itself

      ---------------
      -- Set_Scope --
      ---------------

      procedure Set_Scope (S : Entity_Id) is
      begin
         if S /= Standard_Standard then
            Set_Scope (Scope (S));
         end if;

         Push_Scope (S);
      end Set_Scope;

      -----------------
      -- Unset_Scope --
      -----------------

      procedure Unset_Scope (S : Entity_Id) is
      begin
         if S /= Standard_Standard then
            Unset_Scope (Scope (S));
         end if;

         Pop_Scope;
      end Unset_Scope;

   --  Start of processing for Validate_Compile_Time_Warning_Errors

   begin
      Expander_Mode_Save_And_Set (False);
      In_Compile_Time_Warning_Or_Error := True;

      for N in Compile_Time_Warnings_Errors.First ..
               Compile_Time_Warnings_Errors.Last
      loop
         declare
            T : CTWE_Entry renames Compile_Time_Warnings_Errors.Table (N);

         begin
            Set_Scope (T.Scope);
            Reset_Analyzed_Flags (T.Prag);
            Validate_Compile_Time_Warning_Or_Error (T.Prag, T.Eloc);
            Unset_Scope (T.Scope);
         end;
      end loop;

      In_Compile_Time_Warning_Or_Error := False;
      Expander_Mode_Restore;
   end Validate_Compile_Time_Warning_Errors;

end Sem_Prag;
