]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Mon, 14 Oct 2013 12:52:31 +0000 (14:52 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 14 Oct 2013 12:52:31 +0000 (14:52 +0200)
2013-10-14  Tristan Gingold  <gingold@adacore.com>

* s-vmexta.ads: Add comments.

2013-10-14  Hristian Kirtchev  <kirtchev@adacore.com>

* sem_ch6.adb (Analyze_Subprogram_Body_Contract): Add processing
for pragma Refined_State.
* sem_ch13.adb (Analyze_Aspect_Specifications): Add processing
for aspect Refined_Depends.
* sem_prag.adb (Analyze_Contract_Cases_In_Decl_Part):
Use Find_Related_Subprogram_Or_Body to find the related
context. Use the current scope when determining whether to
ensure proper visibility.
(Analyze_Depends_In_Decl_Part):
Add local variable Spec_Id. Update the comment on usage of
Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
related context. Extract the corresponding spec of the body
(if any). Use the current scope when determining when to
ensure proper visibility.
(Analyze_Global_In_Decl_Part):
Add local variable Spec_Id. Update the comment on usage of
Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
related context. Extract the corresponding spec of the body
(if any). Use the current scope when determining when to
ensure proper visibility.
(Analyze_Global_Item): Use the
entity of the subprogram spec when performing formal parameter
checks. Perform state-related checks.
(Analyze_Input_Output):
Use Is_Attribute_Result to detect 'Result. Query the
entity of a subprogram spec when verifying the prefix of
'Result. Perform state-related checks. (Analyze_Pragma):
Merge the analysis of Refined_Depends and Refined_Global.
(Analyze_Refined_Depends_In_Decl_Part): Provide implemenation.
(Analyze_Refined_Global_In_Decl_Part): Move state-related checks
to the body of Analyze_Global_In_Decl_Part. Rename local constant
List to Items. (Analyze_Refined_Pragma): Remove circuitry to
find the proper context, use Find_Related_Subprogram_Or_Body
instead.
(Check_Function_Return): Query the entity of
the subprogram spec when verifying the use of 'Result.
(Check_In_Out_States, Check_Input_States, Check_Output_States):
Avoid using Has_Null_Refinement to detect a state with
a non-null refinement, use the Refinement_Constituents
list instead.
(Check_Matching_Constituent): Remove initialization code.
(Check_Mode_Restriction_In_Function): Use the entity of the subprogram
spec when verifying mode usage in functions.
(Collect_Global_Items): New routine.
(Collect_Subprogram_Inputs_Outputs): Add local
variable Spec_Id. Add circuitry for bodies-as-specs. Use
pragma Refined_Global when collecting for a body.
(Create_Or_Modify_Clause): Use the location of the
clause. Rename local variable Clause to New_Clause to avoid
confusion and update all occurrences.  Use Is_Attribute_Result
to detect 'Result.
(Find_Related_Subprogram): Removed.
(Find_Related_Subprogram_Or_Body): New routine.
(Is_Part_Of): Move routine to top level.
(Normalize_Clause): Update the
comment on usage. The routine can now normalize a clause with
multiple outputs by splitting it.
(Collect_Global_Items):
Rename local constant List to Items. Remove the check for
a null list.
(Requires_Profile_Installation): Removed.
(Split_Multiple_Outputs): New routine.
* sem_prag.ads: Update the comments on usage of various
pragma-related analysis routines.
* sem_util.adb (Contains_Refined_State): The routine can now
process pragma [Refined_]Depends.
(Has_Refined_State): Removed.
(Has_State_In_Dependency): New routine.
(Has_State_In_Global): New routine.
(Is_Attribute_Result): New routine.
* sem_util.ads (Is_Attribute_Result): New routine.

2013-10-14  Emmanuel Briot  <briot@adacore.com>

* s-regpat.adb (Compile): Fix finalization of the automaton
when its size was automatically computed to be exactly 1000 bytes.

2013-10-14  Ed Schonberg  <schonberg@adacore.com>

* sem_ch3.adb (Complete_Private_Subtype): If the full view of
the base type is constrained, the full view of the subtype is
known to be constrained as well.

From-SVN: r203531

gcc/ada/ChangeLog
gcc/ada/s-regpat.adb
gcc/ada/s-vmexta.ads
gcc/ada/sem_ch13.adb
gcc/ada/sem_ch3.adb
gcc/ada/sem_ch6.adb
gcc/ada/sem_prag.adb
gcc/ada/sem_prag.ads
gcc/ada/sem_util.adb
gcc/ada/sem_util.ads

index 99ad22f5ba674318353bf3e6d64ed466dffc7e8c..93741193f28070fb5fb9d87d60452bb565854424 100644 (file)
@@ -1,3 +1,92 @@
+2013-10-14  Tristan Gingold  <gingold@adacore.com>
+
+       * s-vmexta.ads: Add comments.
+
+2013-10-14  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * sem_ch6.adb (Analyze_Subprogram_Body_Contract): Add processing
+       for pragma Refined_State.
+       * sem_ch13.adb (Analyze_Aspect_Specifications): Add processing
+       for aspect Refined_Depends.
+       * sem_prag.adb (Analyze_Contract_Cases_In_Decl_Part):
+       Use Find_Related_Subprogram_Or_Body to find the related
+       context. Use the current scope when determining whether to
+       ensure proper visibility.
+       (Analyze_Depends_In_Decl_Part):
+       Add local variable Spec_Id. Update the comment on usage of
+       Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
+       related context. Extract the corresponding spec of the body
+       (if any). Use the current scope when determining when to
+       ensure proper visibility.
+       (Analyze_Global_In_Decl_Part):
+       Add local variable Spec_Id. Update the comment on usage of
+       Subp_Id. Use Find_Related_Subprogram_Or_Body to find the
+       related context. Extract the corresponding spec of the body
+       (if any). Use the current scope when determining when to
+       ensure proper visibility.
+       (Analyze_Global_Item): Use the
+       entity of the subprogram spec when performing formal parameter
+       checks. Perform state-related checks.
+       (Analyze_Input_Output):
+       Use Is_Attribute_Result to detect 'Result. Query the
+       entity of a subprogram spec when verifying the prefix of
+       'Result. Perform state-related checks.  (Analyze_Pragma):
+       Merge the analysis of Refined_Depends and Refined_Global.
+       (Analyze_Refined_Depends_In_Decl_Part): Provide implemenation.
+       (Analyze_Refined_Global_In_Decl_Part): Move state-related checks
+       to the body of Analyze_Global_In_Decl_Part. Rename local constant
+       List to Items.  (Analyze_Refined_Pragma): Remove circuitry to
+       find the proper context, use Find_Related_Subprogram_Or_Body
+       instead.
+       (Check_Function_Return): Query the entity of
+       the subprogram spec when verifying the use of 'Result.
+       (Check_In_Out_States, Check_Input_States, Check_Output_States):
+       Avoid using Has_Null_Refinement to detect a state with
+       a non-null refinement, use the Refinement_Constituents
+       list instead.
+       (Check_Matching_Constituent): Remove initialization code.
+       (Check_Mode_Restriction_In_Function): Use the entity of the subprogram
+       spec when verifying mode usage in functions.
+       (Collect_Global_Items): New routine.
+       (Collect_Subprogram_Inputs_Outputs): Add local
+       variable Spec_Id. Add circuitry for bodies-as-specs. Use
+       pragma Refined_Global when collecting for a body.
+       (Create_Or_Modify_Clause): Use the location of the
+       clause. Rename local variable Clause to New_Clause to avoid
+       confusion and update all occurrences.  Use Is_Attribute_Result
+       to detect 'Result.
+       (Find_Related_Subprogram): Removed.
+       (Find_Related_Subprogram_Or_Body): New routine.
+       (Is_Part_Of): Move routine to top level.
+       (Normalize_Clause): Update the
+       comment on usage. The routine can now normalize a clause with
+       multiple outputs by splitting it.
+       (Collect_Global_Items):
+       Rename local constant List to Items. Remove the check for
+       a null list.
+       (Requires_Profile_Installation): Removed.
+       (Split_Multiple_Outputs): New routine.
+       * sem_prag.ads: Update the comments on usage of various
+       pragma-related analysis routines.
+       * sem_util.adb (Contains_Refined_State): The routine can now
+       process pragma [Refined_]Depends.
+       (Has_Refined_State): Removed.
+       (Has_State_In_Dependency): New routine.
+       (Has_State_In_Global): New routine.
+       (Is_Attribute_Result): New routine.
+       * sem_util.ads (Is_Attribute_Result): New routine.
+
+2013-10-14  Emmanuel Briot  <briot@adacore.com>
+
+       * s-regpat.adb (Compile): Fix finalization of the automaton
+       when its size was automatically computed to be exactly 1000 bytes.
+
+2013-10-14  Ed Schonberg  <schonberg@adacore.com>
+
+       * sem_ch3.adb (Complete_Private_Subtype): If the full view of
+       the base type is constrained, the full view of the subtype is
+       known to be constrained as well.
+
 2013-10-14  Vincent Celier  <celier@adacore.com>
 
        * projects.texi: Add documentation for new attributes of package
index cee229ef6b5d7ceaaa807272f242011956b0740f..88143289e44bf1aac8d01784c6fb84adc1ed9e44 100644 (file)
@@ -7,7 +7,7 @@
 --                                 B o d y                                  --
 --                                                                          --
 --               Copyright (C) 1986 by University of Toronto.               --
---                      Copyright (C) 1999-2011, AdaCore                    --
+--                      Copyright (C) 1999-2013, AdaCore                    --
 --                                                                          --
 -- 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- --
@@ -921,7 +921,7 @@ package body System.Regpat is
 
          Link_Tail (IP, Ender);
 
-         if Have_Branch and then Emit_Ptr <= PM.Size then
+         if Have_Branch and then Emit_Ptr <= PM.Size + 1 then
 
             --  Hook the tails of the branches to the closing node
 
index e19929e1df98dc2c0cd78ed1f2d798fdd685c354..4bf83dedc003eeb9fd017d056e544029c7fae470 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1997-2009, Free Software Foundation, Inc.         --
+--          Copyright (C) 1997-2013, 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- --
@@ -29,7 +29,7 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package is usually used only on Alpha/VMS systems in the case
+--  This package is usually used only on OpenVMS systems in the case
 --  where there is at least one Import/Export exception present.
 
 with System.Standard_Library;
@@ -44,16 +44,23 @@ package System.VMS_Exception_Table is
    --  Register an exception in the hash table mapping with a VMS
    --  condition code.
 
+   --  The table is used by exception code (the personnality routine) to
+   --  detect wether a VMS exception (aka condition) is known by the Ada code.
+   --  In that case, the identity of the imported or exported exception is
+   --  used to create the occurrence.
+
    --  LOTS more comments needed here regarding the entire scheme ???
 
 private
 
+   --  The following functions are directly called (without import/export) in
+   --  init.c by __gnat_handle_vms_condition.
+
    function Base_Code_In (Code : SSL.Exception_Code) return SSL.Exception_Code;
    --  Value of Code with the severity bits masked off
 
    function Coded_Exception (X : SSL.Exception_Code)
      return SSL.Exception_Data_Ptr;
    --  Given a VMS condition, find and return it's allocated Ada exception
-   --  (called only from init.c).
 
 end System.VMS_Exception_Table;
index fb5abed1c43b8526fc26513b925cdd09d4190adf..0e01c8ebfab71e6cfc57c74d99b43d9978251891 100644 (file)
@@ -1998,10 +1998,21 @@ package body Sem_Ch13 is
 
                --  Refined_Depends
 
-               --  ??? To be implemented
+               --  Aspect Refined_Depends must be delayed because it can
+               --  mention state refinements introduced by aspect Refined_State
+               --  and further classified by aspect Refined_Global. Since both
+               --  those aspects are delayed, so is Refined_Depends.
 
                when Aspect_Refined_Depends =>
-                  null;
+                  Make_Aitem_Pragma
+                    (Pragma_Argument_Associations => New_List (
+                       Make_Pragma_Argument_Association (Loc,
+                         Expression => Relocate_Node (Expr))),
+                     Pragma_Name                  => Name_Refined_Depends);
+
+                  Decorate_Delayed_Aspect_And_Pragma (Aspect, Aitem);
+                  Insert_Delayed_Pragma (Aitem);
+                  goto Continue;
 
                --  Refined_Global
 
index b2e2a9263cb43a889c7344450339c02cd5bb2b1e..acaf0ef0129c31e0d5dc3535abca29d320a1f36b 100644 (file)
@@ -10393,6 +10393,14 @@ package body Sem_Ch3 is
             Set_First_Entity (Full, First_Entity (Full_Base));
             Set_Last_Entity  (Full, Last_Entity (Full_Base));
 
+            --  If the underlying base type is constrained, we know that the
+            --  full view of the subtype is constrained as well (the converse
+            --  is not necessarily true).
+
+            if Is_Constrained (Full_Base) then
+               Set_Is_Constrained (Full);
+            end if;
+
          when others =>
             Copy_Node (Full_Base, Full);
 
index 34d0a8853b1e2d79ca2584271d194c42344a8f9b..7d47436e7a86b3bcb5a28e482e1841c952f18bb0 100644 (file)
@@ -2029,6 +2029,18 @@ package body Sem_Ch6 is
 
       if Present (Ref_Depends) then
          Analyze_Refined_Depends_In_Decl_Part (Ref_Depends);
+
+      --  When the corresponding Depends aspect/pragma references a state with
+      --  visible refinement, the body requires Refined_Depends.
+
+      elsif Present (Spec_Id) then
+         Prag := Get_Pragma (Spec_Id, Pragma_Depends);
+
+         if Present (Prag) and then Contains_Refined_State (Prag) then
+            Error_Msg_NE
+              ("body of subprogram & requires dependance refinement",
+               Body_Decl, Spec_Id);
+         end if;
       end if;
    end Analyze_Subprogram_Body_Contract;
 
index 16902d63b4ec74acb515b821c35f3ac537dbcc48..ec9d9ae824041ce99ea2ccf824a80349009e2556 100644 (file)
@@ -204,27 +204,49 @@ package body Sem_Prag is
    --  _Post, _Invariant, or _Type_Invariant, which are special names used
    --  in identifiers to represent these attribute references.
 
+   procedure Collect_Global_Items
+     (Prag             : Node_Id;
+      In_Items         : in out Elist_Id;
+      In_Out_Items     : in out Elist_Id;
+      Out_Items        : in out Elist_Id;
+      Has_In_State     : out Boolean;
+      Has_In_Out_State : out Boolean;
+      Has_Out_State    : out Boolean;
+      Has_Null_State   : out Boolean);
+   --  Subsidiary to the analysis of pragma Refined_Depends and pragma
+   --  Refined_Global. Prag denotes pragma [Refined_]Global. Gather all input,
+   --  in out and output items of Prag in lists In_Items, In_Out_Items and
+   --  Out_Items. Flags Has_In_State, Has_In_Out_State and Has_Out_State are
+   --  set when there is at least one abstract state with visible refinement
+   --  available in the corresponding mode. Flag Has_Null_State is set when at
+   --  least state has a null refinement.
+
    procedure Collect_Subprogram_Inputs_Outputs
      (Subp_Id      : Entity_Id;
       Subp_Inputs  : in out Elist_Id;
       Subp_Outputs : in out Elist_Id;
       Global_Seen  : out Boolean);
-   --  Subsidiary to the analysis of pragma Global and pragma Depends. Gather
-   --  all inputs and outputs of subprogram Subp_Id in lists Subp_Inputs and
-   --  Subp_Outputs. If the case where the subprogram has no inputs and/or
-   --  outputs, the corresponding returned list is No_Elist. Flag Global_Seen
-   --  is set when the related subprogram has aspect/pragma Global.
-
-   function Find_Related_Subprogram
-     (Prag             : Node_Id;
-      Check_Duplicates : Boolean := False) return Node_Id;
-   --  Find the declaration of the related subprogram subject to pragma Prag.
-   --  If flag Check_Duplicates is set, the routine emits errors concerning
-   --  duplicate pragmas. If a related subprogram is found, then either the
-   --  corresponding N_Subprogram_Declaration node is returned, or, if the
-   --  pragma applies to a subprogram body, then the N_Subprogram_Body node
-   --  is returned. Note that in the latter case, no check is made to ensure
-   --  that there is no separate declaration of the subprogram.
+   --  Subsidiary to the analysis of pragma Depends, Global, Refined_Depends
+   --  and Refined_Global. Gather all inputs and outputs of subprogram Subp_Id
+   --  in lists Subp_Inputs and Subp_Outputs. If the case where the subprogram
+   --  has no inputs and/oroutputs, the returned list is No_Elist. Global_Seen
+   --  is set when the related subprogram has pragma [Refined_]Global.
+
+   function Find_Related_Subprogram_Or_Body
+     (Prag      : Node_Id;
+      Do_Checks : Boolean := False) return Node_Id;
+   --  Subsidiary to the analysis of pragmas Contract_Cases, Depends, Global,
+   --  Refined_Depends, Refined_Global, Refined_Post and Refined_Pre. Find the
+   --  declaration of the related subprogram [body or stub] subject to pragma
+   --  Prag. If flag Do_Checks is set, the routine reports duplicate pragmas
+   --  and detects improper use of refinement pragmas in stand alone expression
+   --  functions. The returned value depends on the related pragma as follows:
+   --    1) Pragmas Contract_Cases, Depends and Global yield the corresponding
+   --       N_Subprogram_Declaration node or if the pragma applies to a stand
+   --       alone body, the N_Subprogram_Body node or Empty if illegal.
+   --    2) Pragmas Refined_Depends, Refined_Global, Refined_Post and
+   --       Refined_Pre yield N_Subprogram_Body or N_Subprogram_Body_Stub nodes
+   --       or Empty if illegal.
 
    function Get_Base_Subprogram (Def_Id : Entity_Id) return Entity_Id;
    --  If Def_Id refers to a renamed subprogram, then the base subprogram (the
@@ -236,6 +258,14 @@ package body Sem_Prag is
    --  Get_SPARK_Mode_Id. Convert a name into a corresponding value of type
    --  SPARK_Mode_Id.
 
+   function Is_Part_Of
+     (State    : Entity_Id;
+      Ancestor : Entity_Id) return Boolean;
+   --  Subsidiary to the processing of pragma Refined_Depends and pragma
+   --  Refined_Global. Determine whether abstract state State is part of an
+   --  ancestor abstract state Ancestor. For this relationship to hold, State
+   --  must have option Part_Of in its Abstract_State definition.
+
    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
@@ -259,13 +289,6 @@ package body Sem_Prag is
    --  pragma in the source program, a breakpoint on rv catches this place in
    --  the source, allowing convenient stepping to the point of interest.
 
-   function Requires_Profile_Installation
-     (Prag : Node_Id;
-      Subp : Node_Id) return Boolean;
-   --  Subsidiary routine to the analysis of pragma Depends and pragma Global.
-   --  Determine whether the profile of subprogram Subp must be installed into
-   --  visibility to access its formals from pragma Prag.
-
    procedure Set_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
@@ -410,8 +433,8 @@ package body Sem_Prag is
    begin
       Set_Analyzed (N);
 
-      Subp_Decl := Find_Related_Subprogram (N);
-      Subp_Id   := Defining_Unit_Name (Specification (Subp_Decl));
+      Subp_Decl := Find_Related_Subprogram_Or_Body (N);
+      Subp_Id   := Defining_Entity (Subp_Decl);
       All_Cases := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
 
       --  Multiple contract cases appear in aggregate form
@@ -428,7 +451,7 @@ package body Sem_Prag is
             --  pertaining to subprogram declarations. Skip the installation
             --  for subprogram bodies because the formals are already visible.
 
-            if Requires_Profile_Installation (N, Subp_Decl) then
+            if Current_Scope /= Subp_Id then
                Restore_Scope := True;
                Push_Scope (Subp_Id);
                Install_Formals (Subp_Id);
@@ -475,8 +498,12 @@ package body Sem_Prag is
       Result_Seen : Boolean := False;
       --  A flag set when Subp_Id'Result is processed
 
+      Spec_Id : Entity_Id;
+      --  The entity of the subprogram subject to pragma [Refined_]Depends
+
       Subp_Id : Entity_Id;
-      --  The entity of the subprogram subject to pragma Depends
+      --  The entity of the subprogram [body or stub] subject to pragma
+      --  [Refined_]Depends.
 
       Subp_Inputs  : Elist_Id := No_Elist;
       Subp_Outputs : Elist_Id := No_Elist;
@@ -512,10 +539,9 @@ package body Sem_Prag is
       --  error if this is not the case.
 
       procedure Normalize_Clause (Clause : Node_Id);
-      --  Remove a self-dependency "+" from the input list of a clause.
-      --  Depending on the contents of the relation, either split the the
-      --  clause into multiple smaller clauses or perform the normalization in
-      --  place.
+      --  Remove a self-dependency "+" from the input list of a clause. Split
+      --  a clause with multiple outputs into multiple clauses with a single
+      --  output.
 
       -------------------------------
       -- Analyze_Dependency_Clause --
@@ -656,20 +682,19 @@ package body Sem_Prag is
 
             --  Process Function'Result in the context of a dependency clause
 
-            elsif Nkind (Item) = N_Attribute_Reference
-              and then Attribute_Name (Item) = Name_Result
-            then
+            elsif Is_Attribute_Result (Item) then
+
                --  It is sufficent to analyze the prefix of 'Result in order to
                --  establish legality of the attribute.
 
                Analyze (Prefix (Item));
 
                --  The prefix of 'Result must denote the function for which
-               --  aspect/pragma Depends applies.
+               --  pragma Depends applies.
 
                if not Is_Entity_Name (Prefix (Item))
-                 or else Ekind (Subp_Id) /= E_Function
-                 or else Entity (Prefix (Item)) /= Subp_Id
+                 or else Ekind (Spec_Id) /= E_Function
+                 or else Entity (Prefix (Item)) /= Spec_Id
                then
                   Error_Msg_Name_1 := Name_Result;
                   Error_Msg_N
@@ -751,6 +776,38 @@ package body Sem_Prag is
                         Add_Item (Item_Id, All_Inputs_Seen);
                      end if;
 
+                     if Ekind (Item_Id) = E_Abstract_State then
+
+                        --  The state acts as a constituent of some other
+                        --  state. Ensure that the other state is a proper
+                        --  ancestor of the item.
+
+                        if Present (Refined_State (Item_Id)) then
+                           if not Is_Part_Of
+                                    (Item_Id, Refined_State (Item_Id))
+                           then
+                              Error_Msg_Name_1 :=
+                                Chars (Refined_State (Item_Id));
+                              Error_Msg_NE
+                                ("state & is not a valid constituent of "
+                                 & "ancestor state %", Item, Item_Id);
+                              return;
+                           end if;
+
+                        --  An abstract state with visible refinement cannot
+                        --  appear in pragma [Refined_]Global as its place must
+                        --  be taken by some of its constituents.
+
+                        elsif not Is_Empty_Elmt_List
+                                    (Refinement_Constituents (Item_Id))
+                        then
+                           Error_Msg_NE
+                             ("cannot mention state & in global refinement, "
+                              & "use its constituents instead", Item, Item_Id);
+                           return;
+                        end if;
+                     end if;
+
                      --  When the item renames an entire object, replace the
                      --  item with a reference to the object.
 
@@ -824,10 +881,10 @@ package body Sem_Prag is
 
       procedure Check_Function_Return is
       begin
-         if Ekind (Subp_Id) = E_Function and then not Result_Seen then
+         if Ekind (Spec_Id) = E_Function and then not Result_Seen then
             Error_Msg_NE
               ("result of & must appear in exactly one output list",
-               N, Subp_Id);
+               N, Spec_Id);
          end if;
       end Check_Function_Return;
 
@@ -982,6 +1039,11 @@ package body Sem_Prag is
          --  Flag Multiple should be set when Output comes from a list with
          --  multiple items.
 
+         procedure Split_Multiple_Outputs;
+         --  If Clause contains more than one output, split the clause into
+         --  multiple clauses with a single output. All new clauses are added
+         --  after Clause.
+
          -----------------------------
          -- Create_Or_Modify_Clause --
          -----------------------------
@@ -1097,25 +1159,23 @@ package body Sem_Prag is
 
             --  Local variables
 
-            Loc    : constant Source_Ptr := Sloc (Output);
-            Clause : Node_Id;
+            Loc        : constant Source_Ptr := Sloc (Clause);
+            New_Clause : Node_Id;
 
          --  Start of processing for Create_Or_Modify_Clause
 
          begin
-            --  A function result cannot depend on itself because it cannot
-            --  appear in the input list of a relation.
+            --  A null output depending on itself does not require any
+            --  normalization.
 
-            if Nkind (Output) = N_Attribute_Reference
-              and then Attribute_Name (Output) = Name_Result
-            then
-               Error_Msg_N ("function result cannot depend on itself", Output);
+            if Nkind (Output) = N_Null then
                return;
 
-            --  A null output depending on itself does not require any
-            --  normalization.
+            --  A function result cannot depend on itself because it cannot
+            --  appear in the input list of a relation.
 
-            elsif Nkind (Output) = N_Null then
+            elsif Is_Attribute_Result (Output) then
+               Error_Msg_N ("function result cannot depend on itself", Output);
                return;
             end if;
 
@@ -1142,16 +1202,15 @@ package body Sem_Prag is
             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 aspect or
-               --  pragma Depends.
+               --  as null because this will violate the semantics of pragma
+               --  Depends.
 
                Remove (Output);
 
-               --  Create a new clause of the form:
-
+               --  Generate a new clause of the form:
                --    (Output => Inputs)
 
-               Clause :=
+               New_Clause :=
                  Make_Component_Association (Loc,
                    Choices    => New_List (Output),
                    Expression => New_Copy_Tree (Inputs));
@@ -1160,16 +1219,80 @@ package body Sem_Prag is
                --  been analyzed. There is not need to reanalyze it or
                --  renormalize it again.
 
-               Set_Analyzed (Clause);
+               Set_Analyzed (New_Clause);
 
                Propagate_Output
-                 (Output => First (Choices (Clause)),
-                  Inputs => Expression (Clause));
+                 (Output => First (Choices (New_Clause)),
+                  Inputs => Expression (New_Clause));
 
-               Insert_After (After, Clause);
+               Insert_After (After, New_Clause);
             end if;
          end Create_Or_Modify_Clause;
 
+         ----------------------------
+         -- Split_Multiple_Outputs --
+         ----------------------------
+
+         procedure Split_Multiple_Outputs is
+            Inputs      : constant Node_Id    := Expression (Clause);
+            Loc         : constant Source_Ptr := Sloc (Clause);
+            Outputs     : constant Node_Id    := First (Choices (Clause));
+            Last_Output : Node_Id;
+            Next_Output : Node_Id;
+            Output      : Node_Id;
+            Split       : Node_Id;
+
+         --  Start of processing for Split_Multiple_Outputs
+
+         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)
+
+                     Split :=
+                       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 (Split);
+                     Insert_After (Clause, Split);
+                  end if;
+
+                  Output := Next_Output;
+               end loop;
+            end if;
+         end Split_Multiple_Outputs;
+
          --  Local variables
 
          Outputs     : constant Node_Id := First (Choices (Clause));
@@ -1224,6 +1347,11 @@ package body Sem_Prag is
                   Multiple => False);
             end if;
          end if;
+
+         --  Split a clause with multiple outputs into multiple clauses with a
+         --  single output.
+
+         Split_Multiple_Outputs;
       end Normalize_Clause;
 
       --  Local variables
@@ -1241,9 +1369,27 @@ package body Sem_Prag is
    begin
       Set_Analyzed (N);
 
-      Subp_Decl := Find_Related_Subprogram (N);
-      Subp_Id   := Defining_Unit_Name (Specification (Subp_Decl));
-      Clause    := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
+      Subp_Decl := Find_Related_Subprogram_Or_Body (N);
+      Subp_Id   := Defining_Entity (Subp_Decl);
+
+      --  The logic in this routine is used to analyze both pragma Depends and
+      --  pragma Refined_Depends since they have the same syntax and base
+      --  semantics. Find the entity of the corresponding spec when analyzing
+      --  Refined_Depends.
+
+      if Nkind (Subp_Decl) = N_Subprogram_Body
+        and then not Acts_As_Spec (Subp_Decl)
+      then
+         Spec_Id := Corresponding_Spec (Subp_Decl);
+
+      elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub then
+         Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl);
+
+      else
+         Spec_Id := Subp_Id;
+      end if;
+
+      Clause := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
 
       --  Empty dependency list
 
@@ -1251,7 +1397,7 @@ package body Sem_Prag is
 
          --  Gather all states, variables and formal parameters that the
          --  subprogram may depend on. These items are obtained from the
-         --  parameter profile or pragma Global (if available).
+         --  parameter profile or pragma [Refined_]Global (if available).
 
          Collect_Subprogram_Inputs_Outputs
            (Subp_Id      => Subp_Id,
@@ -1275,7 +1421,7 @@ package body Sem_Prag is
 
          --  Gather all states, variables and formal parameters that the
          --  subprogram may depend on. These items are obtained from the
-         --  parameter profile or pragma Global (if available).
+         --  parameter profile or pragma [Refined_]Global (if available).
 
          Collect_Subprogram_Inputs_Outputs
            (Subp_Id      => Subp_Id,
@@ -1288,10 +1434,10 @@ package body Sem_Prag is
          --  to subprogram declarations. Skip the installation for subprogram
          --  bodies because the formals are already visible.
 
-         if Requires_Profile_Installation (N, Subp_Decl) then
+         if Current_Scope /= Spec_Id then
             Restore_Scope := True;
-            Push_Scope (Subp_Id);
-            Install_Formals (Subp_Id);
+            Push_Scope (Spec_Id);
+            Install_Formals (Spec_Id);
          end if;
 
          Clause := First (Component_Associations (Clause));
@@ -1299,8 +1445,7 @@ package body Sem_Prag is
             Errors := Serious_Errors_Detected;
 
             --  Normalization may create extra clauses that contain replicated
-            --  input and output names. There is no need to reanalyze or
-            --  renormalize these extra clauses.
+            --  input and output names. There is no need to reanalyze them.
 
             if not Analyzed (Clause) then
                Set_Analyzed (Clause);
@@ -1308,13 +1453,13 @@ package body Sem_Prag is
                Analyze_Dependency_Clause
                  (Clause  => Clause,
                   Is_Last => Clause = Last_Clause);
+            end if;
 
-               --  Do not normalize an erroneous clause because the inputs or
-               --  outputs may denote illegal items.
+            --  Do not normalize an erroneous clause because the inputs and/or
+            --  outputs may denote illegal items.
 
-               if Errors = Serious_Errors_Detected then
-                  Normalize_Clause (Clause);
-               end if;
+            if Serious_Errors_Detected = Errors then
+               Normalize_Clause (Clause);
             end if;
 
             Next (Clause);
@@ -1347,8 +1492,12 @@ package body Sem_Prag is
       --  A list containing the entities of all the items processed so far. It
       --  plays a role in detecting distinct entities.
 
+      Spec_Id : Entity_Id;
+      --  The entity of the subprogram subject to pragma [Refined_]Global
+
       Subp_Id : Entity_Id;
-      --  The entity of the subprogram subject to pragma Global
+      --  The entity of the subprogram [body or stub] subject to pragma
+      --  [Refined_]Global.
 
       In_Out_Seen : Boolean := False;
       Input_Seen  : Boolean := False;
@@ -1433,7 +1582,7 @@ package body Sem_Prag is
                --  diagnostic.
 
                if Is_Formal (Item_Id) then
-                  if Scope (Item_Id) = Subp_Id then
+                  if Scope (Item_Id) = Spec_Id then
                      Error_Msg_N
                        ("global item cannot reference formal parameter", Item);
                      return;
@@ -1448,6 +1597,35 @@ package body Sem_Prag is
                   return;
                end if;
 
+               if Ekind (Item_Id) = E_Abstract_State then
+
+                  --  The state acts as a constituent of some other state.
+                  --  Ensure that the other state is a proper ancestor of the
+                  --  item.
+
+                  if Present (Refined_State (Item_Id)) then
+                     if not Is_Part_Of (Item_Id, Refined_State (Item_Id)) then
+                        Error_Msg_Name_1 := Chars (Refined_State (Item_Id));
+                        Error_Msg_NE
+                          ("state & is not a valid constituent of ancestor "
+                           & "state %", Item, Item_Id);
+                        return;
+                     end if;
+
+                  --  An abstract state with visible refinement cannot appear
+                  --  in pragma [Refined_]Global as its place must be taken by
+                  --  some of its constituents.
+
+                  elsif not Is_Empty_Elmt_List
+                              (Refinement_Constituents (Item_Id))
+                  then
+                     Error_Msg_NE
+                       ("cannot mention state & in global refinement, use its "
+                        & "constituents instead", Item, Item_Id);
+                     return;
+                  end if;
+               end if;
+
                --  When the item renames an entire object, replace the item
                --  with a reference to the object.
 
@@ -1543,7 +1721,7 @@ package body Sem_Prag is
 
          begin
             --  Traverse the scope stack looking for enclosing subprograms
-            --  subject to aspect/pragma Global.
+            --  subject to pragma [Refined_]Global.
 
             Context := Scope (Subp_Id);
             while Present (Context) and then Context /= Standard_Standard loop
@@ -1585,7 +1763,7 @@ package body Sem_Prag is
 
          procedure Check_Mode_Restriction_In_Function (Mode : Node_Id) is
          begin
-            if Ekind (Subp_Id) = E_Function then
+            if Ekind (Spec_Id) = E_Function then
                Error_Msg_N
                  ("global mode & not applicable to functions", Mode);
             end if;
@@ -1705,9 +1883,27 @@ package body Sem_Prag is
    begin
       Set_Analyzed (N);
 
-      Subp_Decl := Find_Related_Subprogram (N);
-      Subp_Id   := Defining_Unit_Name (Specification (Subp_Decl));
-      Items     := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
+      Subp_Decl := Find_Related_Subprogram_Or_Body (N);
+      Subp_Id   := Defining_Entity (Subp_Decl);
+
+      --  The logic in this routine is used to analyze both pragma Global and
+      --  pragma Refined_Global since they have the same syntax and base
+      --  semantics. Find the entity of the corresponding spec when analyzing
+      --  Refined_Global.
+
+      if Nkind (Subp_Decl) = N_Subprogram_Body
+        and then not Acts_As_Spec (Subp_Decl)
+      then
+         Spec_Id := Corresponding_Spec (Subp_Decl);
+
+      elsif Nkind (Subp_Decl) = N_Subprogram_Body_Stub then
+         Spec_Id := Corresponding_Spec_Of_Stub (Subp_Decl);
+
+      else
+         Spec_Id := Subp_Id;
+      end if;
+
+      Items := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
 
       --  There is nothing to be done for a null global list
 
@@ -1723,10 +1919,10 @@ package body Sem_Prag is
          --  item. This falls out of the general rule of aspects pertaining to
          --  subprogram declarations.
 
-         if Requires_Profile_Installation (N, Subp_Decl) then
+         if Current_Scope /= Spec_Id then
             Restore_Scope := True;
-            Push_Scope (Subp_Id);
-            Install_Formals (Subp_Id);
+            Push_Scope (Spec_Id);
+            Install_Formals (Spec_Id);
          end if;
 
          Analyze_Global_List (Items);
@@ -2226,9 +2422,8 @@ package body Sem_Prag is
 
       procedure Check_Declaration_Order (States : Node_Id; Inits : Node_Id);
       --  Subsidiary routine to the analysis of pragmas Abstract_State and
-      --  Initializes. Determine whether aspect/pragma Abstract_State denoted
-      --  by States is defined earlier than aspect/pragma Initializes denoted
-      --  by Inits.
+      --  Initializes. Determine whether pragma Abstract_State denoted by
+      --  States is defined earlier than pragma Initializes denoted by Inits.
 
       procedure Check_Duplicate_Pragma (E : Entity_Id);
       --  Check if a rep item of the same name as the current pragma is already
@@ -2669,10 +2864,9 @@ package body Sem_Prag is
          Body_Id : out Entity_Id;
          Legal   : out Boolean)
       is
-         Body_Decl : Node_Id := Parent (N);
+         Body_Decl : Node_Id;
          Pack_Spec : Node_Id;
          Spec_Decl : Node_Id;
-         Stmt      : Node_Id;
 
       begin
          --  Assume that the pragma is illegal
@@ -2685,56 +2879,10 @@ package body Sem_Prag is
          Check_Arg_Count (1);
          Check_No_Identifiers;
 
-         --  Verify the placement of the pragma and check for duplicates
-
-         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
-                  Error_Msg_Name_1 := Pname;
-                  Error_Msg_Sloc   := Sloc (Stmt);
-                  Error_Msg_N ("pragma % duplicates pragma declared #", N);
-               end if;
-
-            --  Emit an error when the pragma applies to an expression function
-            --  that does not act as a completion.
-
-            elsif Nkind (Stmt) = N_Subprogram_Declaration
-              and then Nkind (Original_Node (Stmt)) = N_Expression_Function
-              and then not
-                Has_Completion (Defining_Unit_Name (Specification (Stmt)))
-            then
-               Error_Pragma
-                 ("pragma % cannot apply to a stand alone expression "
-                  & "function");
-               return;
-
-            --  The pragma applies to a subprogram body stub
-
-            elsif Nkind (Stmt) = N_Subprogram_Body_Stub then
-               Body_Decl := Stmt;
-               exit;
-
-            --  Skip internally generated code
-
-            elsif not Comes_From_Source (Stmt) then
-               null;
-
-            --  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;
+         --  Verify the placement of the pragma and check for duplicates. The
+         --  pragma must apply to a subprogram body [stub].
 
-         --  Pragma Refined_Pre/Post must apply to a subprogram body [stub]
+         Body_Decl := Find_Related_Subprogram_Or_Body (N, Do_Checks => True);
 
          if not Nkind_In (Body_Decl, N_Subprogram_Body,
                                      N_Subprogram_Body_Stub)
@@ -2759,7 +2907,7 @@ package body Sem_Prag is
             return;
          end if;
 
-         --  Refined_Pre/Post may only apply to the body [stub] of a subprogram
+         --  The pragma may only apply to the body [stub] of a subprogram
          --  declared in the visible part of a package. Retrieve the context of
          --  the subprogram declaration.
 
@@ -9103,8 +9251,8 @@ package body Sem_Prag is
             Pack_Id := Defining_Entity (Context);
             Add_Contract_Item (N, Pack_Id);
 
-            --  Verify the declaration order of aspects/pragmas Abstract_State
-            --  and Initializes.
+            --  Verify the declaration order of pragmas Abstract_State and
+            --  Initializes.
 
             Check_Declaration_Order
               (States => N,
@@ -10195,7 +10343,7 @@ package body Sem_Prag is
 
                   if Is_Checked (N) and then not Split_PPC (N) then
 
-                     --  Mark pragma/aspect SCO as enabled
+                     --  Mark aspect/pragma SCO as enabled
 
                      Set_SCO_Pragma_Enabled (Loc);
                   end if;
@@ -10681,7 +10829,6 @@ package body Sem_Prag is
 
          when Pragma_Contract_Cases => Contract_Cases : declare
             Subp_Decl : Node_Id;
-            Subp_Id   : Entity_Id;
 
          begin
             GNAT_Pragma;
@@ -10691,7 +10838,8 @@ package body Sem_Prag is
             --  be associated with a subprogram declaration or a body that acts
             --  as a spec.
 
-            Subp_Decl := Find_Related_Subprogram (N, Check_Duplicates => True);
+            Subp_Decl :=
+              Find_Related_Subprogram_Or_Body (N, Do_Checks => True);
 
             if Nkind (Subp_Decl) /= N_Subprogram_Declaration
               and then (Nkind (Subp_Decl) /= N_Subprogram_Body
@@ -10701,15 +10849,13 @@ package body Sem_Prag is
                return;
             end if;
 
-            Subp_Id := Defining_Unit_Name (Specification (Subp_Decl));
-
             --  The pragma is analyzed at the end of the declarative part which
             --  contains the related subprogram. Reset the analyzed flag.
 
             Set_Analyzed (N, False);
 
-            --  When the aspect/pragma appears on a subprogram body, perform
-            --  the full analysis now.
+            --  When the pragma appears on a subprogram body, perform the full
+            --  analysis now.
 
             if Nkind (Subp_Decl) = N_Subprogram_Body then
                Analyze_Contract_Cases_In_Decl_Part (N);
@@ -10726,7 +10872,7 @@ package body Sem_Prag is
 
             --  Chain the pragma on the contract for further processing
 
-            Add_Contract_Item (N, Subp_Id);
+            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
          end Contract_Cases;
 
          ----------------
@@ -11201,7 +11347,6 @@ package body Sem_Prag is
 
          when Pragma_Depends => Depends : declare
             Subp_Decl : Node_Id;
-            Subp_Id   : Entity_Id;
 
          begin
             GNAT_Pragma;
@@ -11212,7 +11357,8 @@ package body Sem_Prag is
             --  associated with a subprogram declaration or a body that acts
             --  as a spec.
 
-            Subp_Decl := Find_Related_Subprogram (N, Check_Duplicates => True);
+            Subp_Decl :=
+              Find_Related_Subprogram_Or_Body (N, Do_Checks => True);
 
             if Nkind (Subp_Decl) /= N_Subprogram_Declaration
               and then (Nkind (Subp_Decl) /= N_Subprogram_Body
@@ -11222,10 +11368,8 @@ package body Sem_Prag is
                return;
             end if;
 
-            Subp_Id := Defining_Unit_Name (Specification (Subp_Decl));
-
-            --  When the aspect/pragma appears on a subprogram body, perform
-            --  the full analysis now.
+            --  When the pragma appears on a subprogram body, perform the full
+            --  analysis now.
 
             if Nkind (Subp_Decl) = N_Subprogram_Body then
                Analyze_Depends_In_Decl_Part (N);
@@ -11242,7 +11386,7 @@ package body Sem_Prag is
 
             --  Chain the pragma on the contract for further processing
 
-            Add_Contract_Item (N, Subp_Id);
+            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
          end Depends;
 
          ---------------------
@@ -12452,7 +12596,6 @@ package body Sem_Prag is
 
          when Pragma_Global => Global : declare
             Subp_Decl : Node_Id;
-            Subp_Id   : Entity_Id;
 
          begin
             GNAT_Pragma;
@@ -12463,7 +12606,8 @@ package body Sem_Prag is
             --  associated with a subprogram declaration or a body that acts
             --  as a spec.
 
-            Subp_Decl := Find_Related_Subprogram (N, Check_Duplicates => True);
+            Subp_Decl :=
+              Find_Related_Subprogram_Or_Body (N, Do_Checks => True);
 
             if Nkind (Subp_Decl) /= N_Subprogram_Declaration
               and then (Nkind (Subp_Decl) /= N_Subprogram_Body
@@ -12473,10 +12617,8 @@ package body Sem_Prag is
                return;
             end if;
 
-            Subp_Id := Defining_Unit_Name (Specification (Subp_Decl));
-
-            --  When the aspect/pragma appears on a subprogram body, perform
-            --  the full analysis now.
+            --  When the pragma appears on a subprogram body, perform the full
+            --  analysis now.
 
             if Nkind (Subp_Decl) = N_Subprogram_Body then
                Analyze_Global_In_Decl_Part (N);
@@ -12493,7 +12635,7 @@ package body Sem_Prag is
 
             --  Chain the pragma on the contract for further processing
 
-            Add_Contract_Item (N, Subp_Id);
+            Add_Contract_Item (N, Defining_Entity (Subp_Decl));
          end Global;
 
          -----------
@@ -13275,8 +13417,8 @@ package body Sem_Prag is
             Pack_Id := Defining_Entity (Context);
             Add_Contract_Item (N, Pack_Id);
 
-            --  Verify the declaration order of aspects/pragmas Abstract_State
-            --  and Initializes.
+            --  Verify the declaration order of pragmas Abstract_State and
+            --  Initializes.
 
             Check_Declaration_Order
               (States => Get_Pragma (Pack_Id, Pragma_Abstract_State),
@@ -16631,18 +16773,30 @@ package body Sem_Prag is
          when Pragma_Rational =>
             Set_Rational_Profile;
 
-         ---------------------
-         -- Refined_Depends --
-         ---------------------
+         ------------------------------------
+         -- Refined_Depends/Refined_Global --
+         ------------------------------------
 
-         --  ??? To be implemented
+         --  pragma Refined_Depends (DEPENDENCY_RELATION);
 
-         when Pragma_Refined_Depends =>
-            null;
+         --  DEPENDENCY_RELATION ::=
+         --    null
+         --  | DEPENDENCY_CLAUSE {, DEPENDENCY_CLAUSE}
 
-         --------------------
-         -- Refined_Global --
-         --------------------
+         --  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
 
          --  pragma Refined_Global (GLOBAL_SPECIFICATION);
 
@@ -16657,7 +16811,9 @@ package body Sem_Prag is
          --  GLOBAL_LIST   ::= GLOBAL_ITEM | (GLOBAL_ITEM {, GLOBAL_ITEM})
          --  GLOBAL_ITEM   ::= NAME
 
-         when Pragma_Refined_Global => Refined_Global : declare
+         when Pragma_Refined_Depends |
+              Pragma_Refined_Global  => Refined_Depends_Global :
+         declare
             Body_Id : Entity_Id;
             Legal   : Boolean;
             Spec_Id : Entity_Id;
@@ -16672,7 +16828,7 @@ package body Sem_Prag is
             if Legal then
                Add_Contract_Item (N, Body_Id);
             end if;
-         end Refined_Global;
+         end Refined_Depends_Global;
 
          ------------------------------
          -- Refined_Post/Refined_Pre --
@@ -16764,7 +16920,7 @@ package body Sem_Prag is
             end loop;
 
             --  State refinement is allowed only when the corresponding package
-            --  declaration has a non-null aspect/pragma Abstract_State.
+            --  declaration has a non-null pragma Abstract_State.
 
             Spec_Id := Corresponding_Spec (Context);
 
@@ -19338,148 +19494,908 @@ package body Sem_Prag is
    -- Analyze_Refined_Depends_In_Decl_Part --
    ------------------------------------------
 
-   --  ??? To be implemented
-
    procedure Analyze_Refined_Depends_In_Decl_Part (N : Node_Id) is
-      pragma Unreferenced (N);
-   begin
-      null;
-   end Analyze_Refined_Depends_In_Decl_Part;
-
-   -----------------------------------------
-   -- Analyze_Refined_Global_In_Decl_Part --
-   -----------------------------------------
+      Dependencies : List_Id := No_List;
+      Depends      : Node_Id;
+      --  The corresponding Depends pragma along with its clauses
 
-   procedure Analyze_Refined_Global_In_Decl_Part (N : Node_Id) is
-      Global : Node_Id;
-      --  The corresponding Global aspect/pragma
+      Global : Node_Id := Empty;
+      --  The corresponding Refined_Global pragma (if any)
 
-      Has_In_State     : Boolean := False;
-      Has_In_Out_State : Boolean := False;
-      Has_Out_State    : Boolean := False;
-      --  These flags are set when the corresponding Global aspect/pragma has
-      --  a state of mode Input, In_Out and Output respectively with a visible
-      --  refinement.
+      Out_Items : Elist_Id := No_Elist;
+      --  All output items as defined in pragma Refined_Global (if any)
 
-      Has_Null_State : Boolean := False;
-      --  This flag is set when the corresponding Global aspect/pragma has at
-      --  least one state with a null refinement.
+      Refinements : List_Id := No_List;
+      --  The clauses of pragma Refined_Depends
 
-      In_Constits     : Elist_Id := No_Elist;
-      In_Out_Constits : Elist_Id := No_Elist;
-      Out_Constits    : Elist_Id := No_Elist;
-      --  These lists contain the entities of all Input, In_Out and Output
-      --  constituents that appear in Refined_Global and participate in state
-      --  refinement.
+      Spec_Id : Entity_Id;
+      --  The entity of the subprogram subject to pragma Refined_Depends
 
-      In_Items     : Elist_Id := No_Elist;
-      In_Out_Items : Elist_Id := No_Elist;
-      Out_Items    : Elist_Id := No_Elist;
-      --  These list contain the entities of all Input, In_Out and Output items
-      --  defined in the corresponding Global aspect.
+      procedure Check_Dependency_Clause (Dep_Clause : Node_Id);
+      --  Verify the legality of a single clause
 
-      procedure Check_In_Out_States;
-      --  Determine whether the corresponding Global aspect/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
-      --  and Out_Constits.
+      procedure Report_Extra_Clauses;
+      --  Emit an error for each extra clause the appears in Refined_Depends
 
-      procedure Check_Input_States;
-      --  Determine whether the corresponding Global aspect/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
-      --  and Out_Constits.
+      -----------------------------
+      -- Check_Dependency_Clause --
+      -----------------------------
 
-      procedure Check_Output_States;
-      --  Determine whether the corresponding Global aspect/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 and
-      --  Out_Constits.
+      procedure Check_Dependency_Clause (Dep_Clause : Node_Id) is
+         function Inputs_Match
+           (Ref_Clause : Node_Id;
+            Do_Checks  : Boolean) return Boolean;
+         --  Determine whether the inputs of clause Dep_Clause match those of
+         --  clause Ref_Clause. If flag Do_Checks is set, the routine reports
+         --  missed or extra input items.
 
-      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.
+         function Output_Constituents (State_Id : Entity_Id) return Elist_Id;
+         --  Given a state denoted by State_Id, return a list of all output
+         --  constituents that may be referenced within Refined_Depends. The
+         --  contents of the list depend on whethe Refined_Global is present.
 
-      procedure Collect_Global_Items (Prag : Node_Id);
-      --  Collect the entities of all items of pragma Prag by populating lists
-      --  In_Items, In_Out_Items and Out_Items. The routine also sets flags
-      --  Has_In_State, Has_In_Out_State and Has_Out_State if there is a state
-      --  of a particular kind with visible refinement.
+         procedure Report_Unused_Constituents (Constits : Elist_Id);
+         --  Emit errors for all constituents found in list Constits
 
-      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.
+         ------------------
+         -- Inputs_Match --
+         ------------------
 
-      procedure Report_Extra_Constituents;
-      --  Emit an error for each constituent found in lists In_Constits,
-      --  In_Out_Constits and Out_Constits.
+         function Inputs_Match
+           (Ref_Clause : Node_Id;
+            Do_Checks  : Boolean) return Boolean
+         is
+            Ref_Inputs : List_Id;
+            --  The input list of the refinement clause
 
-      -------------------------
-      -- Check_In_Out_States --
-      -------------------------
+            function Is_Matching_Input (Dep_Input : Node_Id) return Boolean;
+            --  Determine whether input Dep_Input matches one of the inputs of
+            --  clause Ref_Clause.
 
-      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
-         --    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.
-         --  If this is not the case, emit an error.
+            procedure Report_Extra_Inputs;
+            --  Emit errors for all extra inputs that appear in Ref_Clause
 
-         -----------------------------
-         -- Check_Constituent_Usage --
-         -----------------------------
+            -----------------------
+            -- Is_Matching_Input --
+            -----------------------
 
-         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
-            Constit_Elmt : Elmt_Id;
-            Constit_Id   : Entity_Id;
-            Has_Missing  : Boolean := False;
-            In_Out_Seen  : Boolean := False;
-            In_Seen      : Boolean := False;
-            Out_Seen     : Boolean := False;
+            function Is_Matching_Input (Dep_Input : Node_Id) return Boolean is
+               procedure Match_Error (Msg : String; N : Node_Id);
+               --  Emit a matching error if flag Do_Checks is set
 
-         begin
-            --  Process all the constituents of the state and note their modes
-            --  within the global refinement.
+               -----------------
+               -- Match_Error --
+               -----------------
 
-            Constit_Elmt := First_Elmt (Refinement_Constituents (State_Id));
-            while Present (Constit_Elmt) loop
-               Constit_Id := Node (Constit_Elmt);
+               procedure Match_Error (Msg : String; N : Node_Id) is
+               begin
+                  if Do_Checks then
+                     Error_Msg_N (Msg, N);
+                  end if;
+               end Match_Error;
 
-               if Present_Then_Remove (In_Constits, Constit_Id) then
-                  In_Seen := True;
+               --  Local variables
 
-               elsif Present_Then_Remove (In_Out_Constits, Constit_Id) then
-                  In_Out_Seen := True;
+               Dep_Id         : Node_Id;
+               Next_Ref_Input : Node_Id;
+               Ref_Id         : Entity_Id;
+               Ref_Input      : Node_Id;
 
-               elsif Present_Then_Remove (Out_Constits, Constit_Id) then
-                  Out_Seen := True;
+               Has_Constituent : Boolean := False;
+               --  Flag set when the refinement input list contains at least
+               --  one constituent of the state denoted by Dep_Id.
 
-               else
-                  Has_Missing := True;
-               end if;
+               Has_Null_State : Boolean := False;
+               --  Flag set when the dependency input is a state with a null
+               --  refinement.
 
-               Next_Elmt (Constit_Elmt);
-            end loop;
+               Has_Refined_State : Boolean := False;
+               --  Flag set when the dependency input is a state with visible
+               --  refinement.
 
-            --  A single In_Out constituent is a valid completion
+            --  Start of processing for Is_Matching_Input
 
-            if In_Out_Seen then
-               null;
+            begin
+               --  Match a null input with another null input
+
+               if Nkind (Dep_Input) = N_Null then
+                  if Nkind (Expression (Ref_Clause)) = N_Null then
+                     return True;
+                  else
+                     Match_Error
+                       ("null input cannot be matched in corresponding "
+                        & "refinement clause", Dep_Input);
+                  end if;
+
+               --  The remaining cases are formal parameters, variables and
+               --  states.
+
+               else
+                  Dep_Id := Entity_Of (Dep_Input);
+
+                  --  Inspect all inputs of the refinement clause and attempt
+                  --  to match against the inputs of the dependance clause.
+
+                  Ref_Input := First (Ref_Inputs);
+                  while Present (Ref_Input) loop
+
+                     --  Store the next input now because a match will remove
+                     --  it from the list.
+
+                     Next_Ref_Input := Next (Ref_Input);
+
+                     if Ekind (Dep_Id) = E_Abstract_State then
+
+                        --  A state with a null refinement matches either a
+                        --  null input list or nothing at all (no input):
+
+                        --    Refined_State (State => null)
+
+                        --  No input
+
+                        --    Depends         => (<output> => (State, Input))
+                        --    Refined_Depends => (<output> => Input  --  OK
+
+                        --  Null input list
+
+                        --    Depends         => (<output> => State)
+                        --    Refined_Depends => (<output> => null)  --  OK
+
+                        if Has_Null_Refinement (Dep_Id) then
+                           Has_Null_State := True;
+
+                           --  Remove the matching null from the pool of
+                           --  candidates.
+
+                           if Nkind (Ref_Input) = N_Null then
+                              Remove (Ref_Input);
+                           end if;
+
+                           return True;
+
+                        --  The state has a non-null refinement in which case
+                        --  remove all the matching constituents of the state:
+
+                        --    Refined_State   => (State    => (C1, C2))
+                        --    Depends         => (<output> =>  State)
+                        --    Refined_Depends => (<output> => (C1, C2))
+
+                        elsif not Is_Empty_Elmt_List
+                                    (Refinement_Constituents (Dep_Id))
+                        then
+                           Has_Refined_State := True;
+
+                           if Is_Entity_Name (Ref_Input) then
+                              Ref_Id := Entity_Of (Ref_Input);
+
+                              --  The input of the refinement clause is a valid
+                              --  constituent of the state. Remove the input
+                              --  from the pool of candidates. Note that the
+                              --  search continues because the state may be
+                              --  represented by multiple constituents.
+
+                              if Ekind_In (Ref_Id, E_Abstract_State,
+                                                   E_Variable)
+                                and then Present (Refined_State (Ref_Id))
+                                and then Refined_State (Ref_Id) = Dep_Id
+                              then
+                                 Has_Constituent := True;
+                                 Remove (Ref_Input);
+                              end if;
+                           end if;
+                        end if;
+
+                     --  Formal parameters and variables are matched on
+                     --  entities. If this is the case, remove the input from
+                     --  the candidate list.
+
+                     elsif Is_Entity_Name (Ref_Input)
+                       and then Entity_Of (Ref_Input) = Dep_Id
+                     then
+                        Remove (Ref_Input);
+                        return True;
+                     end if;
+
+                     Ref_Input := Next_Ref_Input;
+                  end loop;
+               end if;
+
+               --  A state with visible refinement was matched against one or
+               --  more of its constituents.
+
+               if Has_Constituent then
+                  return True;
+
+               --  A state with a null refinement matched null or nothing
+
+               elsif Has_Null_State then
+                  return True;
+
+               --  The input of a dependence clause does not have a matching
+               --  input in the refinement clause, emit an error.
+
+               else
+                  Match_Error
+                    ("input cannot be matched in corresponding refinement "
+                     & "clause", Dep_Input);
+
+                  if Has_Refined_State then
+                     Match_Error
+                       ("\check the use of constituents in dependence "
+                        & "refinement", Dep_Input);
+                  end if;
+
+                  return False;
+               end if;
+            end Is_Matching_Input;
+
+            -------------------------
+            -- Report_Extra_Inputs --
+            -------------------------
+
+            procedure Report_Extra_Inputs is
+               Input : Node_Id;
+
+            begin
+               if Present (Ref_Inputs) and then Do_Checks then
+                  Input := First (Ref_Inputs);
+                  while Present (Input) loop
+                     Error_Msg_N
+                       ("unmatched or extra input in refinement clause",
+                        Input);
+
+                     Next (Input);
+                  end loop;
+               end if;
+            end Report_Extra_Inputs;
+
+            --  Local variables
+
+            Dep_Inputs : constant Node_Id := Expression (Dep_Clause);
+            Inputs     : constant Node_Id := Expression (Ref_Clause);
+            Dep_Input  : Node_Id;
+            Result     : Boolean;
+
+         --  Start of processing for Inputs_Match
+
+         begin
+            --  Construct a list of all refinement inputs. Note that the input
+            --  list is copied because the algorithm modifies its contents and
+            --  this should not be visible in Refined_Depends.
+
+            if Nkind (Inputs) = N_Aggregate then
+               Ref_Inputs := New_Copy_List (Expressions (Inputs));
+            else
+               Ref_Inputs := New_List (Inputs);
+            end if;
+
+            --  Depending on whether the original dependency clause mentions
+            --  states with visible refinement, the corresponding refinement
+            --  clause may differ greatly in structure and contents:
+
+            --  State with null refinement
+
+            --    Refined_State   => (State    => null)
+            --    Depends         => (<output> => State)
+            --    Refined_Depends => (<output> => null)
+
+            --    Depends         => (<output> => (State, Input))
+            --    Refined_Depends => (<output> => Input)
+
+            --    Depends         => (<output> => (Input_1, State, Input_2))
+            --    Refined_Depends => (<output> => (Input_1, Input_2))
+
+            --  State with non-null refinement
+
+            --    Refined_State   => (State_1 => (C1, C2))
+            --    Depends         => (<output> => State)
+            --    Refined_Depends => (<output> => C1)
+            --  or
+            --    Refined_Depends => (<output> => (C1, C2))
+
+            if Nkind (Dep_Inputs) = N_Aggregate then
+               Dep_Input := First (Expressions (Dep_Inputs));
+               while Present (Dep_Input) loop
+                  if not Is_Matching_Input (Dep_Input) then
+                     Result := False;
+                  end if;
+
+                  Next (Dep_Input);
+               end loop;
+
+               Result := True;
+
+            --  Solitary input
+
+            else
+               Result := Is_Matching_Input (Dep_Inputs);
+            end if;
+
+            Report_Extra_Inputs;
+            return Result;
+         end Inputs_Match;
+
+         -------------------------
+         -- Output_Constituents --
+         -------------------------
+
+         function Output_Constituents (State_Id : Entity_Id) return Elist_Id is
+            Item_Elmt : Elmt_Id;
+            Item_Id   : Entity_Id;
+            Result    : Elist_Id := No_Elist;
+
+         begin
+            --  The related subprogram is subject to pragma Refined_Global. All
+            --  usable output constituents are defined in its output item list.
+
+            if Present (Global) then
+               Item_Elmt := First_Elmt (Out_Items);
+               while Present (Item_Elmt) loop
+                  Item_Id := Node (Item_Elmt);
+
+                  --  The constituent is part of the refinement of the input
+                  --  state, add it to the result list.
+
+                  if Refined_State (Item_Id) = State_Id then
+                     Add_Item (Item_Id, Result);
+                  end if;
+
+                  Next_Elmt (Item_Elmt);
+               end loop;
+
+            --  When pragma Refined_Global is not present, the usable output
+            --  constituents are all the constituents as defined in pragma
+            --  Refined_State. Note that the elements are copied because the
+            --  algorithm trims the list and this should not be reflected in
+            --  the state itself.
+
+            else
+               Result := New_Copy_Elist (Refinement_Constituents (State_Id));
+            end if;
+
+            return Result;
+         end Output_Constituents;
+
+         --------------------------------
+         -- Report_Unused_Constituents --
+         --------------------------------
+
+         procedure Report_Unused_Constituents (Constits : Elist_Id) is
+            Constit : Entity_Id;
+            Elmt    : Elmt_Id;
+            Posted  : Boolean := False;
+
+         begin
+            if Present (Constits) then
+               Elmt := First_Elmt (Constits);
+               while Present (Elmt) loop
+                  Constit := Node (Elmt);
+
+                  --  A constituent must always refine a state
+
+                  pragma Assert (Present (Refined_State (Constit)));
+
+                  --  When a state has a visible refinement and its mode is
+                  --  Output_Only, all its constituents must be used as
+                  --  outputs.
+
+                  if not Posted then
+                     Posted := True;
+                     Error_Msg_NE
+                       ("output only state & must be replaced by all its "
+                        & "constituents in dependence refinement",
+                        N, Refined_State (Constit));
+                  end if;
+
+                  Error_Msg_NE
+                    ("\  constituent & is missing in output list", N, Constit);
+
+                  Next_Elmt (Elmt);
+               end loop;
+            end if;
+         end Report_Unused_Constituents;
+
+         --  Local variables
+
+         Dep_Output      : constant Node_Id := First (Choices (Dep_Clause));
+         Dep_Id          : Entity_Id;
+         Matching_Clause : Node_Id := Empty;
+         Next_Ref_Clause : Node_Id;
+         Ref_Clause      : Node_Id;
+         Ref_Id          : Entity_Id;
+         Ref_Output      : Node_Id;
+
+         Has_Constituent : Boolean := False;
+         --  Flag set when the refinement output list contains at least one
+         --  constituent of the state denoted by Dep_Id.
+
+         Has_Null_State : Boolean := False;
+         --  Flag set when the output of clause Dep_Clause is a state with a
+         --  null refinement.
+
+         Has_Refined_State : Boolean := False;
+         --  Flag set when the output of clause Dep_Clause is a state with
+         --  visible refinement.
+
+         Out_Constits : Elist_Id := No_Elist;
+         --  This list contains the entities all output constituents of state
+         --  Dep_Id as defined in pragma Refined_State.
+
+      --  Start of processing for Check_Dependency_Clause
+
+      begin
+         --  The analysis of pragma Depends should produce normalized clauses
+         --  with exactly one output. This is important because output items
+         --  are unique in the whole dependance relation and can be used as
+         --  keys.
+
+         pragma Assert (No (Next (Dep_Output)));
+
+         --  Inspect all clauses of Refined_Depends and attempt to match the
+         --  output of Dep_Clause against an output from the refinement clauses
+         --  set.
+
+         Ref_Clause := First (Refinements);
+         while Present (Ref_Clause) loop
+            Matching_Clause := Empty;
+
+            --  Store the next clause now because a match will trim the list of
+            --  refinement clauses and this side effect should not be visible
+            --  in pragma Refined_Depends.
+
+            Next_Ref_Clause := Next (Ref_Clause);
+
+            --  The analysis of pragma Refined_Depends should produce
+            --  normalized clauses with exactly one output.
+
+            Ref_Output := First (Choices (Ref_Clause));
+            pragma Assert (No (Next (Ref_Output)));
+
+            --  Two null output lists match if their inputs match
+
+            if Nkind (Dep_Output) = N_Null
+              and then Nkind (Ref_Output) = N_Null
+            then
+               Matching_Clause := Ref_Clause;
+               exit;
+
+            --  Two function 'Result attributes match if their inputs match.
+            --  Note that there is no need to compare the two prefixes because
+            --  the attributes cannot denote anything but the related function.
+
+            elsif Is_Attribute_Result (Dep_Output)
+              and then Is_Attribute_Result (Ref_Output)
+            then
+               Matching_Clause := Ref_Clause;
+               exit;
+
+            --  The remaining cases are formal parameters, variables and states
+
+            elsif Is_Entity_Name (Dep_Output) then
+               Dep_Id := Entity_Of (Dep_Output);
+
+               if Ekind (Dep_Id) = E_Abstract_State then
+
+                  --  A state with a null refinement matches either a null
+                  --  output list or nothing at all (no clause):
+
+                  --    Refined_State => (State => null)
+
+                  --  No clause
+
+                  --    Depends         => (State => null)
+                  --    Refined_Depends =>  null               --  OK
+
+                  --  Null output list
+
+                  --    Depends         => (State => <input>)
+                  --    Refined_Depends => (null  => <input>)  --  OK
+
+                  if Has_Null_Refinement (Dep_Id) then
+                     Has_Null_State := True;
+
+                     --  When a state with null refinement matches a null
+                     --  output, compare their inputs.
+
+                     if Nkind (Ref_Output) = N_Null then
+                        Matching_Clause := Ref_Clause;
+                     end if;
+
+                     exit;
+
+                  --  The state has a non-null refinement in which case the
+                  --  match is based on constituents and inputs. A state with
+                  --  multiple output constituents may match multiple clauses:
+
+                  --    Refined_State   => (State => (C1, C2))
+                  --    Depends         => (State => <input>)
+                  --    Refined_Depends => ((C1, C2) => <input>)
+
+                  --  When normalized, the above becomes:
+
+                  --    Refined_Depends => (C1 => <input>,
+                  --                        C2 => <input>)
+
+                  elsif not Is_Empty_Elmt_List
+                              (Refinement_Constituents (Dep_Id))
+                  then
+                     Has_Refined_State := True;
+
+                     --  Store the entities of all output constituents of an
+                     --  Output_Only state with visible refinement.
+
+                     if No (Out_Constits)
+                       and then Is_Output_Only_State (Dep_Id)
+                     then
+                        Out_Constits := Output_Constituents (Dep_Id);
+                     end if;
+
+                     if Is_Entity_Name (Ref_Output) then
+                        Ref_Id := Entity_Of (Ref_Output);
+
+                        --  The output of the refinement clause is a valid
+                        --  constituent of the state. Remove the clause from
+                        --  the pool of candidates if both input lists match.
+                        --  Note that the search continues because one clause
+                        --  may have been normalized into multiple clauses as
+                        --  per the example above.
+
+                        if Ekind_In (Ref_Id, E_Abstract_State, E_Variable)
+                          and then Present (Refined_State (Ref_Id))
+                          and then Refined_State (Ref_Id) = Dep_Id
+                          and then Inputs_Match
+                                     (Ref_Clause, Do_Checks => False)
+                        then
+                           Has_Constituent := True;
+                           Remove (Ref_Clause);
+
+                           --  The matching constituent may act as an output
+                           --  for an Output_Only state. Remove the item from
+                           --  the available output constituents.
+
+                           Remove (Out_Constits, Ref_Id);
+                        end if;
+                     end if;
+                  end if;
+
+               --  Formal parameters and variables match when their inputs
+               --  match.
+
+               elsif Is_Entity_Name (Ref_Output)
+                 and then Entity_Of (Ref_Output) = Dep_Id
+               then
+                  Matching_Clause := Ref_Clause;
+                  exit;
+               end if;
+            end if;
+
+            Ref_Clause := Next_Ref_Clause;
+         end loop;
+
+         --  Handle the case where pragma Depends contains one or more clauses
+         --  that only mention states with null refinements. In that case the
+         --  corresponding pragma Refined_Depends may have a null relation.
+
+         --    Refined_State   => (State => null)
+         --    Depends         => (State => null)
+         --    Refined_Depends =>  null            --  OK
+
+         if No (Refinements) and then Is_Entity_Name (Dep_Output) then
+            Dep_Id := Entity_Of (Dep_Output);
+
+            if Ekind (Dep_Id) = E_Abstract_State
+              and then Has_Null_Refinement (Dep_Id)
+            then
+               Has_Null_State := True;
+            end if;
+         end if;
+
+         --  The above search produced a match based on unique output. Ensure
+         --  that the inputs match as well and if they do, remove the clause
+         --  from the pool of candidates.
+
+         if Present (Matching_Clause) then
+            if Inputs_Match (Matching_Clause, Do_Checks => True) then
+               Remove (Matching_Clause);
+            end if;
+
+         --  A state with a visible refinement was matched against one or
+         --  more clauses containing appropriate constituents.
+
+         elsif Has_Constituent then
+            null;
+
+         --  A state with a null refinement did not warrant a clause
+
+         elsif Has_Null_State then
+            null;
+
+         --  The dependence relation of pragma Refined_Depends does not contain
+         --  a matching clause, emit an error.
+
+         else
+            Error_Msg_NE
+              ("dependence clause of subprogram & has no matching refinement "
+               & "in body", Ref_Clause, Spec_Id);
+
+            if Has_Refined_State then
+               Error_Msg_N
+                 ("\check the use of constituents in dependence refinement",
+                  Ref_Clause);
+            end if;
+         end if;
+
+         --  Emit errors for all unused constituents of an Output_Only state
+         --  with visible refinement.
+
+         Report_Unused_Constituents (Out_Constits);
+      end Check_Dependency_Clause;
+
+      --------------------------
+      -- Report_Extra_Clauses --
+      --------------------------
+
+      procedure Report_Extra_Clauses is
+         Clause : Node_Id;
+
+      begin
+         if Present (Refinements) then
+            Clause := First (Refinements);
+            while Present (Clause) loop
+               Error_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   := Parent (N);
+      Body_Id   : constant Entity_Id := Defining_Entity (Body_Decl);
+      Errors    : constant Nat       := Serious_Errors_Detected;
+      Clause    : Node_Id;
+      Deps      : Node_Id;
+      Refs      : Node_Id;
+
+      --  The following are dummy variables that capture unused output of
+      --  routine Collect_Global_Items.
+
+      D1, D2         : Elist_Id := No_Elist;
+      D3, D4, D5, D6 : Boolean;
+
+   --  Start of processing for Analyze_Refined_Depends_In_Decl_Part
+
+   begin
+      Spec_Id := Corresponding_Spec (Body_Decl);
+      Depends := Get_Pragma (Spec_Id, Pragma_Depends);
+
+      --  The subprogram declarations lacks pragma Depends. This renders
+      --  Refined_Depends useless as there is nothing to refine.
+
+      if No (Depends) then
+         Error_Msg_NE
+           ("useless refinement, subprogram & lacks dependence clauses",
+            N, Spec_Id);
+         return;
+      end if;
+
+      Deps := Get_Pragma_Arg (First (Pragma_Argument_Associations (Depends)));
+
+      --  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.
+
+      if Nkind (Deps) = N_Null then
+         Error_Msg_NE
+           ("useless refinement, subprogram & does not depend on abstract "
+            & "state with visible refinement", N, Spec_Id);
+         return;
+      end if;
+
+      --  Multiple dependency clauses appear as component associations of an
+      --  aggregate.
+
+      pragma Assert (Nkind (Deps) = N_Aggregate);
+      Dependencies := Component_Associations (Deps);
+
+      --  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);
+      Refs := Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
+
+      if Serious_Errors_Detected = Errors then
+
+         --  The related subprogram may be subject to pragma Refined_Global. If
+         --  this is the case, gather all output items. These are needed when
+         --  verifying the use of constituents that apply to output states with
+         --  visible refinement.
+
+         Global := Get_Pragma (Body_Id, Pragma_Refined_Global);
+
+         if Present (Global) then
+            Collect_Global_Items
+              (Prag             => Global,
+               In_Items         => D1,
+               In_Out_Items     => D2,
+               Out_Items        => Out_Items,
+               Has_In_State     => D3,
+               Has_In_Out_State => D4,
+               Has_Out_State    => D5,
+               Has_Null_State   => D6);
+         end if;
+
+         if Nkind (Refs) = N_Null then
+            Refinements := No_List;
+
+         --  Multiple dependeny 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 (Component_Associations (Refs));
+         end if;
+
+         --  Inspect all the clauses of pragma Depends trying to find a
+         --  matching clause in pragma Refined_Depends. The approach is to use
+         --  the sole output of a clause as a key. Output items are unique in a
+         --  dependence relation. Clause normalization also ensured that all
+         --  clauses have exactly on output. Depending on what the key is, one
+         --  or more refinement clauses may satisfy the dependency clause. Each
+         --  time a dependency clause is matched, its related refinement clause
+         --  is consumed. In the end, two things may happen:
+
+         --    1) A clause of pragma Depends was not matched in which case
+         --       Check_Dependency_Clause reports the error.
+
+         --    2) Refined_Depends has an extra clause in which case the error
+         --       is reported by Report_Extra_Clauses.
+
+         Clause := First (Dependencies);
+         while Present (Clause) loop
+            Check_Dependency_Clause (Clause);
+
+            Next (Clause);
+         end loop;
+      end if;
+
+      if Serious_Errors_Detected = Errors then
+         Report_Extra_Clauses;
+      end if;
+   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;
+      --  These flags are set when the corresponding Global pragma has a state
+      --  of mode Input, In_Out and Output 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;
+      --  These lists contain the entities of all Input, In_Out and Output
+      --  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;
+      --  These list contain the entities of all Input, In_Out and Output items
+      --  defined in the corresponding Global pragma.
+
+      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
+      --  and Out_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
+      --  and Out_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 and
+      --  Out_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.
+
+      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 Report_Extra_Constituents;
+      --  Emit an error for each constituent found in lists In_Constits,
+      --  In_Out_Constits and Out_Constits.
+
+      -------------------------
+      -- 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
+         --    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.
+         --  If this is not the case, emit an error.
+
+         -----------------------------
+         -- Check_Constituent_Usage --
+         -----------------------------
+
+         procedure Check_Constituent_Usage (State_Id : Entity_Id) is
+            Constit_Elmt : Elmt_Id;
+            Constit_Id   : Entity_Id;
+            Has_Missing  : Boolean := False;
+            In_Out_Seen  : Boolean := False;
+            In_Seen      : Boolean := False;
+            Out_Seen     : Boolean := False;
+
+         begin
+            --  Process all the constituents of the state and note their modes
+            --  within the global refinement.
+
+            Constit_Elmt := First_Elmt (Refinement_Constituents (State_Id));
+            while Present (Constit_Elmt) loop
+               Constit_Id := Node (Constit_Elmt);
+
+               if Present_Then_Remove (In_Constits, Constit_Id) then
+                  In_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
+                  Out_Seen := True;
+
+               else
+                  Has_Missing := True;
+               end if;
+
+               Next_Elmt (Constit_Elmt);
+            end loop;
+
+            --  A single In_Out constituent is a valid completion
+
+            if In_Out_Seen then
+               null;
 
             --  A pair of one Input and one Output constituent is a valid
             --  completion.
@@ -19508,7 +20424,7 @@ package body Sem_Prag is
       --  Start of processing for Check_In_Out_States
 
       begin
-         --  Inspect the In_Out items of the corresponding Global aspect/pragma
+         --  Inspect the In_Out items of the corresponding Global pragma
          --  looking for a state with a visible refinement.
 
          if Has_In_Out_State and then Present (In_Out_Items) then
@@ -19519,7 +20435,8 @@ package body Sem_Prag is
                --  Ensure that one of the three coverage variants is satisfied
 
                if Ekind (Item_Id) = E_Abstract_State
-                 and then not Has_Null_Refinement (Item_Id)
+                 and then not Is_Empty_Elmt_List
+                                (Refinement_Constituents (Item_Id))
                then
                   Check_Constituent_Usage (Item_Id);
                end if;
@@ -19590,7 +20507,7 @@ package body Sem_Prag is
       --  Start of processing for Check_Input_States
 
       begin
-         --  Inspect the Input items of the corresponding Global aspect/pragma
+         --  Inspect the Input items of the corresponding Global pragma
          --  looking for a state with a visible refinement.
 
          if Has_In_State and then Present (In_Items) then
@@ -19602,7 +20519,8 @@ package body Sem_Prag is
                --  is of mode Input.
 
                if Ekind (Item_Id) = E_Abstract_State
-                 and then not Has_Null_Refinement (Item_Id)
+                 and then not Is_Empty_Elmt_List
+                                (Refinement_Constituents (Item_Id))
                then
                   Check_Constituent_Usage (Item_Id);
                end if;
@@ -19660,7 +20578,7 @@ package body Sem_Prag is
       --  Start of processing for Check_Output_States
 
       begin
-         --  Inspect the Output items of the corresponding Global aspect/pragma
+         --  Inspect the Output items of the corresponding Global pragma
          --  looking for a state with a visible refinement.
 
          if Has_Out_State and then Present (Out_Items) then
@@ -19672,7 +20590,8 @@ package body Sem_Prag is
                --  have mode Output.
 
                if Ekind (Item_Id) = E_Abstract_State
-                 and then not Has_Null_Refinement (Item_Id)
+                 and then not Is_Empty_Elmt_List
+                                (Refinement_Constituents (Item_Id))
                then
                   Check_Constituent_Usage (Item_Id);
                end if;
@@ -19710,14 +20629,7 @@ package body Sem_Prag is
 
             procedure Check_Matching_Modes (Item_Id : Entity_Id);
             --  Verify that the global modes of item Item_Id are the same in
-            --  both aspects/pragmas Global and Refined_Global.
-
-            function Is_Part_Of
-              (State    : Entity_Id;
-               Ancestor : Entity_Id) return Boolean;
-            --  Determine whether abstract state State is part of an ancestor
-            --  abstract state Ancestor. For this relationship to hold, State
-            --  must have option Part_Of in its Abstract_State definition.
+            --  both pragmas Global and Refined_Global.
 
             ---------------------
             -- Add_Constituent --
@@ -19783,43 +20695,9 @@ package body Sem_Prag is
                --  it must be an extra.
 
                else
-                  Error_Msg_NE ("extra global item &", Item, Item_Id);
-               end if;
-            end Check_Matching_Modes;
-
-            ----------------
-            -- Is_Part_Of --
-            ----------------
-
-            function Is_Part_Of
-              (State    : Entity_Id;
-               Ancestor : Entity_Id) return Boolean
-            is
-               Options : constant Node_Id := Parent (State);
-               Name    : Node_Id;
-               Option  : Node_Id;
-               Value   : Node_Id;
-
-            begin
-               --  A state declaration with option Part_Of appears as an
-               --  extension aggregate with component associations.
-
-               if Nkind (Options) = N_Extension_Aggregate then
-                  Option := First (Component_Associations (Options));
-                  while Present (Option) loop
-                     Name  := First (Choices (Option));
-                     Value := Expression (Option);
-
-                     if Chars (Name) = Name_Part_Of then
-                        return Entity (Value) = Ancestor;
-                     end if;
-
-                     Next (Option);
-                  end loop;
+                  Error_Msg_NE ("extra global item &", Item, Item_Id);
                end if;
-
-               return False;
-            end Is_Part_Of;
+            end Check_Matching_Modes;
 
             --  Local variables
 
@@ -19828,42 +20706,19 @@ package body Sem_Prag is
          --  Start of processing for Check_Refined_Global_Item
 
          begin
-            --  State checks
-
             if Ekind (Item_Id) = E_Abstract_State then
 
-               --  The state acts as a constituent of some other state. Ensure
-               --  that the other state is a proper ancestor of the item.
-
-               if Present (Refined_State (Item_Id)) then
-                  if Is_Part_Of (Item_Id, Refined_State (Item_Id)) then
-                     Add_Constituent (Item_Id);
-                  else
-                     Error_Msg_Name_1 := Chars (Refined_State (Item_Id));
-                     Error_Msg_NE
-                       ("state & is not a valid constituent of ancestor "
-                        & "state %", Item, Item_Id);
-                  end if;
-
-               --  An abstract state with visible refinement cannot appear in a
-               --  global refinement as its place must be taken by some of its
-               --  constituents.
-
-               elsif Present (Refinement_Constituents (Item_Id)) then
-                  Error_Msg_NE
-                    ("cannot mention state & in global refinement, use its "
-                     & "constituents instead", Item, Item_Id);
-
-               --  The state is not refined nor is it a constituent. Ensure
-               --  that the modes of both its occurrences in Global and
-               --  Refined_Global match.
+               --  The state is neither a constituent of an ancestor state nor
+               --  has a visible refinement. Ensure that the modes of both its
+               --  occurrences in Global and Refined_Global match.
 
-               else
+               if No (Refined_State (Item_Id))
+                 and then Is_Empty_Elmt_List
+                            (Refinement_Constituents (Item_Id))
+               then
                   Check_Matching_Modes (Item_Id);
                end if;
 
-            --  Variable checks
-
             else pragma Assert (Ekind (Item_Id) = E_Variable);
 
                --  The variable acts as a constituent of a state, collect it
@@ -19941,141 +20796,6 @@ package body Sem_Prag is
          end if;
       end Check_Refined_Global_List;
 
-      --------------------------
-      -- Collect_Global_Items --
-      --------------------------
-
-      procedure Collect_Global_Items (Prag : Node_Id) is
-         procedure Process_Global_List
-           (List : Node_Id;
-            Mode : Name_Id := Name_Input);
-         --  Collect all items housed in a global list. Formal Mode denotes the
-         --  current mode in effect.
-
-         -------------------------
-         -- Process_Global_List --
-         -------------------------
-
-         procedure Process_Global_List
-           (List : Node_Id;
-            Mode : Name_Id := Name_Input)
-         is
-            procedure Process_Global_Item (Item : Node_Id; Mode : Name_Id);
-            --  Add a single item to the appropriate list. Formal Mode denotes
-            --  the current mode in effect.
-
-            -------------------------
-            -- Process_Global_Item --
-            -------------------------
-
-            procedure Process_Global_Item (Item : Node_Id; Mode : Name_Id) is
-               Item_Id : constant Entity_Id := Entity_Of (Item);
-
-            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_Refinement (Item_Id) then
-                     Has_Null_State := True;
-                  else
-                     if Mode = Name_Input then
-                        Has_In_State := True;
-                     elsif Mode = Name_In_Out then
-                        Has_In_Out_State := True;
-                     elsif Mode = Name_Output then
-                        Has_Out_State := True;
-                     end if;
-                  end if;
-               end if;
-
-               --  Add the item to the proper list
-
-               if Mode = Name_Input then
-                  Add_Item (Item_Id, In_Items);
-               elsif Mode = Name_In_Out then
-                  Add_Item (Item_Id, In_Out_Items);
-               elsif Mode = Name_Output then
-                  Add_Item (Item_Id, Out_Items);
-               end if;
-            end Process_Global_Item;
-
-            --  Local variables
-
-            Item : Node_Id;
-
-         --  Start of processing for Process_Global_List
-
-         begin
-            if Nkind (List) = N_Null then
-               null;
-
-            --  Single global item declaration
-
-            elsif Nkind_In (List, N_Expanded_Name,
-                                  N_Identifier,
-                                  N_Selected_Component)
-            then
-               Process_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
-                     Process_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 modes.
-
-               elsif Present (Component_Associations (List)) then
-                  Item := First (Component_Associations (List));
-                  while Present (Item) loop
-                     Process_Global_List
-                       (List => Expression (Item),
-                        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 Process_Global_List;
-
-         --  Local variables
-
-         List : constant Node_Id :=
-                  Get_Pragma_Arg (First (Pragma_Argument_Associations (Prag)));
-
-      --  Start of processing for Collect_Global_Items
-
-      begin
-         --  Do not process a null global list as it contains nothing
-
-         if Nkind (List) /= N_Null then
-            Process_Global_List (List);
-         end if;
-      end Collect_Global_Items;
-
       -------------------------
       -- Present_Then_Remove --
       -------------------------
@@ -20139,7 +20859,7 @@ package body Sem_Prag is
 
       Body_Decl : constant Node_Id := Parent (N);
       Errors    : constant Nat     := Serious_Errors_Detected;
-      List      : constant Node_Id :=
+      Items     : constant Node_Id :=
                     Get_Pragma_Arg (First (Pragma_Argument_Associations (N)));
       Spec_Id   : constant Entity_Id := Corresponding_Spec (Body_Decl);
 
@@ -20148,7 +20868,7 @@ package body Sem_Prag is
    begin
       Global := Get_Pragma (Spec_Id, Pragma_Global);
 
-      --  The subprogram declaration lacks aspect/pragma Global. This renders
+      --  The subprogram declaration lacks pragma Global. This renders
       --  Refined_Global useless as there is nothing to refine.
 
       if No (Global) then
@@ -20157,15 +20877,21 @@ package body Sem_Prag is
          return;
       end if;
 
-      --  Extract all relevant items from the corresponding Global aspect or
-      --  pragma.
+      --  Extract all relevant items from the corresponding Global pragma
 
-      Collect_Global_Items (Global);
+      Collect_Global_Items
+        (Prag             => Global,
+         In_Items         => In_Items,
+         In_Out_Items     => In_Out_Items,
+         Out_Items        => Out_Items,
+         Has_In_State     => Has_In_State,
+         Has_In_Out_State => Has_In_Out_State,
+         Has_Out_State    => Has_Out_State,
+         Has_Null_State   => Has_Null_State);
 
-      --  The corresponding Global aspect/pragma must mention at least one
-      --  state with a visible refinement at the point Refined_Global is
-      --  processed. States with null refinements warrant a Refined_Global
-      --  aspect/pragma.
+      --  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 warrant a Refined_Global pragma.
 
       if not Has_In_State
         and then not Has_In_Out_State
@@ -20179,15 +20905,15 @@ package body Sem_Prag is
       end if;
 
       --  The global refinement of inputs and outputs cannot be null when the
-      --  corresponding Global aspect/pragma contains at least one item except
-      --  in the case where we have states with null refinements.
+      --  corresponding Global pragma contains at least one item except in the
+      --  case where we have states with null refinements.
 
-      if Nkind (List) = N_Null
+      if Nkind (Items) = N_Null
         and then
           (Present (In_Items)
             or else Present (In_Out_Items)
             or else Present (Out_Items))
-         and then not Has_Null_State
+        and then not Has_Null_State
       then
          Error_Msg_NE
            ("refinement cannot be null, subprogram & has global items",
@@ -20195,9 +20921,9 @@ package body Sem_Prag is
          return;
       end if;
 
-      --  Analyze Refined_Global as if it behaved as a regular aspect/pragma
-      --  Global. This ensures that the categorization of all refined global
-      --  items is consistent with their role.
+      --  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);
 
@@ -20205,7 +20931,7 @@ package body Sem_Prag is
       --  matching.
 
       if Serious_Errors_Detected = Errors then
-         Check_Refined_Global_List (List);
+         Check_Refined_Global_List (Items);
       end if;
 
       --  For Input states with visible refinement, at least one constituent
@@ -20348,10 +21074,6 @@ package body Sem_Prag is
                      --  Establish a relation between the refined state and its
                      --  constituent.
 
-                     if No (Refinement_Constituents (State_Id)) then
-                        Set_Refinement_Constituents (State_Id, New_Elmt_List);
-                     end if;
-
                      Append_Elmt
                        (Constit_Id, Refinement_Constituents (State_Id));
                      Set_Refined_State (Constit_Id, State_Id);
@@ -20931,6 +21653,150 @@ package body Sem_Prag is
       end if;
    end Check_Applicable_Policy;
 
+   --------------------------
+   -- Collect_Global_Items --
+   --------------------------
+
+   procedure Collect_Global_Items
+     (Prag             : Node_Id;
+      In_Items         : in out Elist_Id;
+      In_Out_Items     : in out Elist_Id;
+      Out_Items        : in out Elist_Id;
+      Has_In_State     : out Boolean;
+      Has_In_Out_State : out Boolean;
+      Has_Out_State    : out Boolean;
+      Has_Null_State   : out Boolean)
+   is
+      procedure Process_Global_List
+        (List : Node_Id;
+         Mode : Name_Id := Name_Input);
+      --  Collect all items housed in a global list. Formal Mode denotes the
+      --  current mode in effect.
+
+      -------------------------
+      -- Process_Global_List --
+      -------------------------
+
+      procedure Process_Global_List
+        (List : Node_Id;
+         Mode : Name_Id := Name_Input)
+      is
+         procedure Process_Global_Item (Item : Node_Id; Mode : Name_Id);
+         --  Add a single item to the appropriate list. Formal Mode denotes the
+         --  current mode in effect.
+
+         -------------------------
+         -- Process_Global_Item --
+         -------------------------
+
+         procedure Process_Global_Item (Item : Node_Id; Mode : Name_Id) is
+            Item_Id : constant Entity_Id := Entity_Of (Item);
+
+         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_Refinement (Item_Id) then
+                  Has_Null_State := True;
+               elsif Mode = Name_Input then
+                  Has_In_State := True;
+               elsif Mode = Name_In_Out then
+                  Has_In_Out_State := True;
+               elsif Mode = Name_Output then
+                  Has_Out_State := True;
+               end if;
+            end if;
+
+            --  Add the item to the proper list
+
+            if Mode = Name_Input then
+               Add_Item (Item_Id, In_Items);
+            elsif Mode = Name_In_Out then
+               Add_Item (Item_Id, In_Out_Items);
+            elsif Mode = Name_Output then
+               Add_Item (Item_Id, Out_Items);
+            end if;
+         end Process_Global_Item;
+
+         --  Local variables
+
+         Item : Node_Id;
+
+      --  Start of processing for Process_Global_List
+
+      begin
+         if Nkind (List) = N_Null then
+            null;
+
+         --  Single global item declaration
+
+         elsif Nkind_In (List, N_Expanded_Name,
+                               N_Identifier,
+                               N_Selected_Component)
+         then
+            Process_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
+                  Process_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
+                  Process_Global_List
+                    (List => Expression (Item),
+                     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 Process_Global_List;
+
+      --  Local variables
+
+      Items : constant Node_Id :=
+                Get_Pragma_Arg (First (Pragma_Argument_Associations (Prag)));
+
+   --  Start of processing for Collect_Global_Items
+
+   begin
+      --  Assume that no states have been encountered
+
+      Has_In_State     := False;
+      Has_In_Out_State := False;
+      Has_Out_State    := False;
+      Has_Null_State   := False;
+
+      Process_Global_List (Items);
+   end Collect_Global_Items;
+
    ---------------------------------------
    -- Collect_Subprogram_Inputs_Outputs --
    ---------------------------------------
@@ -20980,17 +21846,20 @@ package body Sem_Prag is
       --  Start of processing for Collect_Global_List
 
       begin
+         if Nkind (List) = N_Null then
+            null;
+
          --  Single global item declaration
 
-         if Nkind_In (List, N_Expanded_Name,
-                            N_Identifier,
-                            N_Selected_Component)
+         elsif Nkind_In (List, N_Expanded_Name,
+                               N_Identifier,
+                               N_Selected_Component)
          then
             Collect_Global_Item (List, Mode);
 
          --  Simple global list or moded global list declaration
 
-         else
+         elsif Nkind (List) = N_Aggregate then
             if Present (Expressions (List)) then
                Item := First (Expressions (List));
                while Present (Item) loop
@@ -21007,23 +21876,37 @@ package body Sem_Prag is
                   Next (Assoc);
                end loop;
             end if;
+
+         --  Invalid list
+
+         else
+            raise Program_Error;
          end if;
       end Collect_Global_List;
 
       --  Local variables
 
-      Formal : Entity_Id;
-      Global : Node_Id;
-      List   : Node_Id;
+      Formal  : Entity_Id;
+      Global  : Node_Id;
+      List    : Node_Id;
+      Spec_Id : Entity_Id;
 
    --  Start of processing for Collect_Subprogram_Inputs_Outputs
 
    begin
       Global_Seen := False;
 
+      --  Find the entity of the corresponding spec when processing a body
+
+      if Ekind (Subp_Id) = E_Subprogram_Body then
+         Spec_Id := Corresponding_Spec (Parent (Parent (Subp_Id)));
+      else
+         Spec_Id := Subp_Id;
+      end if;
+
       --  Process all formal parameters
 
-      Formal := First_Formal (Subp_Id);
+      Formal := First_Formal (Spec_Id);
       while Present (Formal) loop
          if Ekind_In (Formal, E_In_Out_Parameter, E_In_Parameter) then
             Add_Item (Formal, Subp_Inputs);
@@ -21046,10 +21929,18 @@ package body Sem_Prag is
          Next_Formal (Formal);
       end loop;
 
-      --  If the subprogram is subject to pragma Global, traverse all global
-      --  lists and gather the relevant items.
+      --  When processing a subprogram body, look for pragma Refined_Global as
+      --  it provides finer granularity of inputs and outputs.
+
+      if Ekind (Subp_Id) = E_Subprogram_Body then
+         Global := Get_Pragma (Subp_Id, Pragma_Refined_Global);
+
+      --  Subprogram declaration case, look for pragma Global
+
+      else
+         Global := Get_Pragma (Spec_Id, Pragma_Global);
+      end if;
 
-      Global := Get_Pragma (Subp_Id, Pragma_Global);
       if Present (Global) then
          Global_Seen := True;
          List := Expression (First (Pragma_Argument_Associations (Global)));
@@ -21059,7 +21950,11 @@ package body Sem_Prag is
          --  the purposes of item extraction.
 
          if not Analyzed (List) then
-            Analyze_Global_In_Decl_Part (Global);
+            if Pragma_Name (Global) = Name_Refined_Global then
+               Analyze_Refined_Global_In_Decl_Part (Global);
+            else
+               Analyze_Global_In_Decl_Part (Global);
+            end if;
          end if;
 
          --  Nothing to be done for a null global list
@@ -21080,77 +21975,93 @@ package body Sem_Prag is
                                       Name_Priority_Specific_Dispatching);
    end Delay_Config_Pragma_Analyze;
 
-   -----------------------------
-   -- Find_Related_Subprogram --
-   -----------------------------
+   -------------------------------------
+   -- Find_Related_Subprogram_Or_Body --
+   -------------------------------------
 
-   function Find_Related_Subprogram
-     (Prag             : Node_Id;
-      Check_Duplicates : Boolean := False) return Node_Id
+   function Find_Related_Subprogram_Or_Body
+     (Prag      : Node_Id;
+      Do_Checks : Boolean := False) return Node_Id
    is
-      Context   : constant Node_Id := Parent (Prag);
-      Nam       : constant Name_Id := Pragma_Name (Prag);
-      Elmt      : Node_Id;
-      Subp_Decl : Node_Id;
+      Context : constant Node_Id := Parent (Prag);
+      Nam     : constant Name_Id := Pragma_Name (Prag);
+      Stmt    : Node_Id;
+
+      Look_For_Body : constant Boolean :=
+                        Nam_In (Nam, Name_Refined_Depends,
+                                     Name_Refined_Global,
+                                     Name_Refined_Post,
+                                     Name_Refined_Pre);
+      --  Refinement pragmas must be associated with a subprogram body [stub]
 
    begin
       pragma Assert (Nkind (Prag) = N_Pragma);
 
-      --  If the pragma comes from an aspect, then what we want is the
-      --  declaration to which the aspect is attached, i.e. its parent.
+      --  If the pragma is a byproduct of aspect expansion, return the related
+      --  context of the original aspect.
 
       if Present (Corresponding_Aspect (Prag)) then
          return Parent (Corresponding_Aspect (Prag));
       end if;
 
-      --  Otherwise the pragma must be a list element, and the first thing to
-      --  do is to position past any previous pragmas or generated code. What
-      --  we are doing here is looking for the preceding declaration. This is
-      --  also where we will check for a duplicate pragma.
+      --  Otherwise the pragma is a source construct, most likely part of a
+      --  declarative list. Skip preceding declarations while looking for a
+      --  proper subprogram declaration.
 
       pragma Assert (Is_List_Member (Prag));
 
-      Elmt := Prag;
-      loop
-         Elmt := Prev (Elmt);
-         exit when No (Elmt);
-
-         --  Typically want we will want is the declaration original node. But
-         --  for the generic subprogram case, don't go to to the original node,
-         --  which is the unanalyzed tree: we need to attach the pre- and post-
-         --  conditions to the analyzed version at this point. They propagate
-         --  to the original tree when analyzing the corresponding body.
-
-         if Nkind (Elmt) not in N_Generic_Declaration then
-            Subp_Decl := Original_Node (Elmt);
-         else
-            Subp_Decl := Elmt;
-         end if;
+      Stmt := Prev (Prag);
+      while Present (Stmt) loop
 
-         --  Skip prior pragmas
+         --  Skip prior pragmas, but check for duplicates
 
-         if Nkind (Subp_Decl) = N_Pragma then
-            if Check_Duplicates and then Pragma_Name (Subp_Decl) = Nam then
+         if Nkind (Stmt) = N_Pragma then
+            if Do_Checks and then Pragma_Name (Stmt) = Nam then
                Error_Msg_Name_1 := Nam;
-               Error_Msg_Sloc   := Sloc (Subp_Decl);
+               Error_Msg_Sloc   := Sloc (Stmt);
                Error_Msg_N ("pragma % duplicates pragma declared #", Prag);
             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
+            Error_Msg_Name_1 := Nam;
+            Error_Msg_N
+              ("pragma % cannot apply to a stand alone expression function",
+               Prag);
+
+            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 (Subp_Decl) then
+         elsif not Comes_From_Source (Stmt) then
             null;
 
-         --  Otherwise we have a declaration to return
+         --  Return the current construct which is either a subprogram body,
+         --  a subprogram declaration or is illegal.
 
          else
-            return Subp_Decl;
+            return Stmt;
          end if;
+
+         Prev (Stmt);
       end loop;
 
-      --  We fell through, which means there was no declaration preceding the
-      --  pragma (either it was the first element of the list, or we only had
-      --  other pragmas and generated code before it).
+      --  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
 
@@ -21162,12 +22073,12 @@ package body Sem_Prag is
       elsif Nkind (Context) = N_Subprogram_Body then
          return Context;
 
-      --  Otherwise no subprogram found, return original pragma
+      --  No candidate subprogram [body] found
 
       else
-         return Prag;
+         return Empty;
       end if;
-   end Find_Related_Subprogram;
+   end Find_Related_Subprogram_Or_Body;
 
    -------------------------
    -- Get_Base_Subprogram --
@@ -21620,6 +22531,40 @@ package body Sem_Prag is
       end if;
    end Is_Non_Significant_Pragma_Reference;
 
+   ----------------
+   -- Is_Part_Of --
+   ----------------
+
+   function Is_Part_Of
+     (State    : Entity_Id;
+      Ancestor : Entity_Id) return Boolean
+   is
+      Options : constant Node_Id := Parent (State);
+      Name    : Node_Id;
+      Option  : Node_Id;
+      Value   : Node_Id;
+
+   begin
+      --  A state declaration with option Part_Of appears as an extension
+      --  aggregate with component associations.
+
+      if Nkind (Options) = N_Extension_Aggregate then
+         Option := First (Component_Associations (Options));
+         while Present (Option) loop
+            Name  := First (Choices (Option));
+            Value := Expression (Option);
+
+            if Chars (Name) = Name_Part_Of then
+               return Entity (Value) = Ancestor;
+            end if;
+
+            Next (Option);
+         end loop;
+      end if;
+
+      return False;
+   end Is_Part_Of;
+
    ------------------------------
    -- Is_Pragma_String_Literal --
    ------------------------------
@@ -22091,44 +23036,6 @@ package body Sem_Prag is
       null;
    end rv;
 
-   -----------------------------------
-   -- Requires_Profile_Installation --
-   -----------------------------------
-
-   function Requires_Profile_Installation
-     (Prag : Node_Id;
-      Subp : Node_Id) return Boolean
-   is
-   begin
-      --  When aspects Depends and Global are associated with a subprogram
-      --  declaration, their corresponding pragmas are analyzed at the end of
-      --  the declarative part. This is done out of context, therefore the
-      --  formals must be installed in visibility.
-
-      if Nkind (Subp) = N_Subprogram_Declaration then
-         return True;
-
-      --  When aspects Depends and Global are associated with a subprogram body
-      --  which is also a compilation unit, their corresponding pragmas appear
-      --  in the Pragmas_After list. The Pragmas_After collection is analyzed
-      --  out of context and the formals must be installed in visibility. This
-      --  does not apply when the pragma is a source construct.
-
-      elsif Nkind (Subp) = N_Subprogram_Body then
-         if Nkind (Parent (Subp)) = N_Compilation_Unit then
-            return Present (Corresponding_Aspect (Prag));
-         else
-            return False;
-         end if;
-
-      --  In all other cases the two corresponding pragmas are analyzed in
-      --  context and the formals are already visibile.
-
-      else
-         return False;
-      end if;
-   end Requires_Profile_Installation;
-
    --------------------------------
    -- Set_Encoded_Interface_Name --
    --------------------------------
index cef28caf8031f7cf2cee59e5f574095fb607e3fd..3f7b30660593d2c44ddabe8cac6bc09250ababf2 100644 (file)
@@ -57,10 +57,12 @@ package Sem_Prag is
    --  Perform full analysis and expansion of delayed pragma Contract_Cases
 
    procedure Analyze_Depends_In_Decl_Part (N : Node_Id);
-   --  Perform full analysis of delayed pragma Depends
+   --  Perform full analysis of delayed pragma Depends. This routine is also
+   --  capable of performing basic analysis of pragma Refined_Depends.
 
    procedure Analyze_Global_In_Decl_Part (N : Node_Id);
-   --  Perform full analysis of delayed pragma Global
+   --  Perform full analysis of delayed pragma Global. This routine is also
+   --  capable of performing basic analysis of pragma Refind_Global.
 
    procedure Analyze_Initializes_In_Decl_Part (N : Node_Id);
    --  Perform full analysis of delayed pragma Initializes
@@ -75,10 +77,14 @@ package Sem_Prag is
    --  of Default and Per-Object Expressions in Sem).
 
    procedure Analyze_Refined_Depends_In_Decl_Part (N : Node_Id);
-   --  Preform full analysis of delayed pragma Refined_Depends
+   --  Preform full analysis of delayed pragma Refined_Depends. This routine
+   --  uses Analyze_Depends_In_Decl_Part as a starting point, then performs
+   --  various consistency checks between Depends and Refined_Depends.
 
    procedure Analyze_Refined_Global_In_Decl_Part (N : Node_Id);
-   --  Perform full analysis of delayed pragma Refined_Global
+   --  Perform full analysis of delayed pragma Refined_Global. This routine
+   --  uses Analyze_Global_In_Decl_Part as a starting point, then performs
+   --  various consistency checks between Global and Refined_Global.
 
    procedure Analyze_Refined_State_In_Decl_Part (N : Node_Id);
    --  Perform full analysis of delayed pragma Refined_State
index a5a6f7b35faf0f58b1554ce4fc18f45e3154f2d9..2f0f41c2402f3a779c31de032f63e3685a256683 100644 (file)
@@ -3242,44 +3242,79 @@ package body Sem_Util is
    ----------------------------
 
    function Contains_Refined_State (Prag : Node_Id) return Boolean is
-      function Has_Refined_State (List : Node_Id) return Boolean;
+      function Has_State_In_Dependency (List : Node_Id) return Boolean;
+      --  Determine whether a dependency list mentions a state with a visible
+      --  refinement.
+
+      function Has_State_In_Global (List : Node_Id) return Boolean;
       --  Determine whether a global list mentions a state with a visible
       --  refinement.
 
-      -----------------------
-      -- Has_Refined_State --
-      -----------------------
+      function Is_Refined_State (Item : Node_Id) return Boolean;
+      --  Determine whether Item is a reference to an abstract state with a
+      --  visible refinement.
 
-      function Has_Refined_State (List : Node_Id) return Boolean is
-         function Is_Refined_State (Item : Node_Id) return Boolean;
-         --  Determine whether Item is a reference to an abstract state with a
-         --  visible refinement.
+      -----------------------------
+      -- Has_State_In_Dependency --
+      -----------------------------
 
-         ----------------------
-         -- Is_Refined_State --
-         ----------------------
+      function Has_State_In_Dependency (List : Node_Id) return Boolean is
+         Clause : Node_Id;
+         Output : Node_Id;
 
-         function Is_Refined_State (Item : Node_Id) return Boolean is
-            Item_Id : Entity_Id;
+      begin
+         --  A null dependency list does not mention any states
 
-         begin
-            if Nkind (Item) = N_Null then
-               return False;
+         if Nkind (List) = N_Null then
+            return False;
 
-            else
-               Item_Id := Entity_Of (Item);
+         --  Dependency clauses appear as component associations of an
+         --  aggregate.
 
-               return
-                 Ekind (Item_Id) = E_Abstract_State
-                   and then Present (Refinement_Constituents (Item_Id));
-            end if;
-         end Is_Refined_State;
+         elsif Nkind (List) = N_Aggregate
+           and then Present (Component_Associations (List))
+         then
+            Clause := First (Component_Associations (List));
+            while Present (Clause) loop
 
-         --  Local variables
+               --  Inspect the outputs of a dependency clause
 
-         Item : Node_Id;
+               Output := First (Choices (Clause));
+               while Present (Output) loop
+                  if Is_Refined_State (Output) then
+                     return True;
+                  end if;
+
+                  Next (Output);
+               end loop;
 
-      --  Start of processing for Has_Refined_State
+               --  Inspect the outputs of a dependency clause
+
+               if Is_Refined_State (Expression (Clause)) then
+                  return True;
+               end if;
+
+               Next (Clause);
+            end loop;
+
+            --  If we get here, then none of the dependency clauses mention a
+            --  state with visible refinement.
+
+            return False;
+
+         --  An illegal pragma managed to sneak in
+
+         else
+            raise Program_Error;
+         end if;
+      end Has_State_In_Dependency;
+
+      -------------------------
+      -- Has_State_In_Global --
+      -------------------------
+
+      function Has_State_In_Global (List : Node_Id) return Boolean is
+         Item : Node_Id;
 
       begin
          --  A null global list does not mention any states
@@ -3287,14 +3322,6 @@ package body Sem_Util is
          if Nkind (List) = N_Null then
             return False;
 
-         --  Single global item declaration
-
-         elsif Nkind_In (List, N_Expanded_Name,
-                               N_Identifier,
-                               N_Selected_Component)
-         then
-            return Is_Refined_State (List);
-
          --  Simple global list or moded global list declaration
 
          elsif Nkind (List) = N_Aggregate then
@@ -3319,7 +3346,7 @@ package body Sem_Util is
             else
                Item := First (Component_Associations (List));
                while Present (Item) loop
-                  if Has_Refined_State (Expression (Item)) then
+                  if Has_State_In_Global (Expression (Item)) then
                      return True;
                   end if;
 
@@ -3332,12 +3359,68 @@ package body Sem_Util is
 
             return False;
 
-         --  Something went horribly wrong, we have a malformed tree
+         --  Single global item declaration
+
+         elsif Is_Entity_Name (List) then
+            return Is_Refined_State (List);
+
+         --  An illegal pragma managed to sneak in
 
          else
             raise Program_Error;
          end if;
-      end Has_Refined_State;
+      end Has_State_In_Global;
+
+      ----------------------
+      -- Is_Refined_State --
+      ----------------------
+
+      function Is_Refined_State (Item : Node_Id) return Boolean is
+         Elmt    : Node_Id;
+         Item_Id : Entity_Id;
+
+      begin
+         if Nkind (Item) = N_Null then
+            return False;
+
+         --  States cannot be subject to attribute 'Result. This case arises
+         --  in dependency relations.
+
+         elsif Nkind (Item) = N_Attribute_Reference
+           and then Attribute_Name (Item) = Name_Result
+         then
+            return False;
+
+         --  Multiple items appear as an aggregate. This case arises in
+         --  dependency relations.
+
+         elsif Nkind (Item) = N_Aggregate
+           and then Present (Expressions (Item))
+         then
+            Elmt := First (Expressions (Item));
+            while Present (Elmt) loop
+               if Is_Refined_State (Elmt) then
+                  return True;
+               end if;
+
+               Next (Elmt);
+            end loop;
+
+            --  If we get here, then none of the inputs or outputs reference a
+            --  state with visible refinement.
+
+            return False;
+
+         --  Single item
+
+         else
+            Item_Id := Entity_Of (Item);
+
+            return
+              Ekind (Item_Id) = E_Abstract_State
+                and then Present (Refinement_Constituents (Item_Id));
+         end if;
+      end Is_Refined_State;
 
       --  Local variables
 
@@ -3348,13 +3431,11 @@ package body Sem_Util is
    --  Start of processing for Contains_Refined_State
 
    begin
-      --  ??? To be implemented
-
       if Nam = Name_Depends then
-         return False;
+         return Has_State_In_Dependency (Arg);
 
       else pragma Assert (Nam = Name_Global);
-         return Has_Refined_State (Arg);
+         return Has_State_In_Global (Arg);
       end if;
    end Contains_Refined_State;
 
@@ -8188,6 +8269,17 @@ package body Sem_Util is
       end if;
    end Is_Atomic_Object;
 
+   -------------------------
+   -- Is_Attribute_Result --
+   -------------------------
+
+   function Is_Attribute_Result (N : Node_Id) return Boolean is
+   begin
+      return
+         Nkind (N) = N_Attribute_Reference
+           and then Attribute_Name (N) = Name_Result;
+   end Is_Attribute_Result;
+
    ------------------------------------
    -- Is_Body_Or_Package_Declaration --
    ------------------------------------
index d19ba57710c927c30f304d01cbb61864d07a0da2..8eaa58014c89e6ee23aee308c586ad5c31c1a969 100644 (file)
@@ -902,6 +902,9 @@ package Sem_Util is
    --  Determines if the given node denotes an atomic object in the sense of
    --  the legality checks described in RM C.6(12).
 
+   function Is_Attribute_Result (N : Node_Id) return Boolean;
+   --  Determine whether node N denotes attribute 'Result
+
    function Is_Body_Or_Package_Declaration (N : Node_Id) return Boolean;
    --  Determine whether node N denotes a body or a package declaration