------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              P A R _ S C O                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2009-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Aspects;        use Aspects;
with Atree;          use Atree;
with Debug;          use Debug;
with Errout;         use Errout;
with Lib;            use Lib;
with Lib.Util;       use Lib.Util;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Output;         use Output;
with Put_SCOs;
with SCOs;           use SCOs;
with Sem;            use Sem;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Table;

with GNAT.HTable;    use GNAT.HTable;
with GNAT.Heap_Sort_G;

package body Par_SCO is

   --------------------------
   -- First-pass SCO table --
   --------------------------

   --  The Short_Circuit_And_Or pragma enables one to use AND and OR operators
   --  in source code while the ones used with booleans will be interpreted as
   --  their short circuit alternatives (AND THEN and OR ELSE). Thus, the true
   --  meaning of these operators is known only after the semantic analysis.

   --  However, decision SCOs include short circuit operators only. The SCO
   --  information generation pass must be done before expansion, hence before
   --  the semantic analysis. Because of this, the SCO information generation
   --  is done in two passes.

   --  The first one (SCO_Record_Raw, before semantic analysis) completes the
   --  SCO_Raw_Table assuming all AND/OR operators are short circuit ones.
   --  Then, the semantic analysis determines which operators are promoted to
   --  short circuit ones. Finally, the second pass (SCO_Record_Filtered)
   --  translates the SCO_Raw_Table to SCO_Table, taking care of removing the
   --  remaining AND/OR operators and of adjusting decisions accordingly
   --  (splitting decisions, removing empty ones, etc.).

   type SCO_Generation_State_Type is (None, Raw, Filtered);
   SCO_Generation_State : SCO_Generation_State_Type := None;
   --  Keep track of the SCO generation state: this will prevent us from
   --  running some steps multiple times (the second pass has to be started
   --  from multiple places).

   package SCO_Raw_Table is new Table.Table
     (Table_Component_Type => SCO_Table_Entry,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => 500,
      Table_Increment      => 300,
      Table_Name           => "Raw_Table");

   -----------------------
   -- Unit Number Table --
   -----------------------

   --  This table parallels the SCO_Unit_Table, keeping track of the unit
   --  numbers corresponding to the entries made in this table, so that before
   --  writing out the SCO information to the ALI file, we can fill in the
   --  proper dependency numbers and file names.

   --  Note that the zeroth entry is here for convenience in sorting the table;
   --  the real lower bound is 1.

   package SCO_Unit_Number_Table is new Table.Table
     (Table_Component_Type => Unit_Number_Type,
      Table_Index_Type     => SCO_Unit_Index,
      Table_Low_Bound      => 0, -- see note above on sort
      Table_Initial        => 20,
      Table_Increment      => 200,
      Table_Name           => "SCO_Unit_Number_Entry");

   ------------------------------------------
   -- Condition/Operator/Pragma Hash Table --
   ------------------------------------------

   --  We need to be able to get to conditions quickly for handling the calls
   --  to Set_SCO_Condition efficiently, and similarly to get to pragmas to
   --  handle calls to Set_SCO_Pragma_Enabled (the same holds for operators and
   --  Set_SCO_Logical_Operator). For this purpose we identify the conditions,
   --  operators and pragmas in the table by their starting sloc, and use this
   --  hash table to map from these sloc values to SCO_Table indexes.

   type Header_Num is new Integer range 0 .. 996;
   --  Type for hash table headers

   function Hash (F : Source_Ptr) return Header_Num;
   --  Function to Hash source pointer value

   function Equal (F1 : Source_Ptr; F2 : Source_Ptr) return Boolean;
   --  Function to test two keys for equality

   function "<" (S1 : Source_Location; S2 : Source_Location) return Boolean;
   --  Function to test for source locations order

   package SCO_Raw_Hash_Table is new Simple_HTable
     (Header_Num, Int, 0, Source_Ptr, Hash, Equal);
   --  The actual hash table

   --------------------------
   -- Internal Subprograms --
   --------------------------

   function Has_Decision (N : Node_Id) return Boolean;
   --  N is the node for a subexpression. Returns True if the subexpression
   --  contains a nested decision (i.e. either is a logical operator, or
   --  contains a logical operator in its subtree).
   --
   --  This must be used in the first pass (SCO_Record_Raw) only: here AND/OR
   --  operators are considered as short circuit, just in case the
   --  Short_Circuit_And_Or pragma is used: only real short circuit operations
   --  will be kept in the secord pass.

   type Tristate is (False, True, Unknown);

   function Is_Logical_Operator (N : Node_Id) return Tristate;
   --  N is the node for a subexpression. This procedure determines whether N
   --  is a logical operator: True for short circuit conditions, Unknown for OR
   --  and AND (the Short_Circuit_And_Or pragma may be used) and False
   --  otherwise. Note that in cases where True is returned, callers assume
   --  Nkind (N) in N_Op.

   function To_Source_Location (S : Source_Ptr) return Source_Location;
   --  Converts Source_Ptr value to Source_Location (line/col) format

   procedure Process_Decisions
     (N           : Node_Id;
      T           : Character;
      Pragma_Sloc : Source_Ptr);
   --  If N is Empty, has no effect. Otherwise scans the tree for the node N,
   --  to output any decisions it contains. T is one of IEGPWX (for context of
   --  expression: if/exit when/entry guard/pragma/while/expression). If T is
   --  other than X, the node N is the if expression involved, and a decision
   --  is always present (at the very least a simple decision is present at the
   --  top level).

   procedure Process_Decisions
     (L           : List_Id;
      T           : Character;
      Pragma_Sloc : Source_Ptr);
   --  Calls above procedure for each element of the list L

   procedure Set_Raw_Table_Entry
     (C1                 : Character;
      C2                 : Character;
      From               : Source_Ptr;
      To                 : Source_Ptr;
      Last               : Boolean;
      Pragma_Sloc        : Source_Ptr := No_Location;
      Pragma_Aspect_Name : Name_Id    := No_Name);
   --  Append an entry to SCO_Raw_Table with fields set as per arguments

   type Dominant_Info is record
      K : Character;
      --  F/T/S/E for a valid dominance marker, or ' ' for no dominant

      N : Node_Id;
      --  Node providing the Sloc(s) for the dominance marker
   end record;
   No_Dominant : constant Dominant_Info := (' ', Empty);

   procedure Record_Instance (Id : Instance_Id; Inst_Sloc : Source_Ptr);
   --  Add one entry from the instance table to the corresponding SCO table

   procedure Traverse_Declarations_Or_Statements
     (L : List_Id;
      D : Dominant_Info := No_Dominant;
      P : Node_Id       := Empty);
   --  Process L, a list of statements or declarations dominated by D. If P is
   --  present, it is processed as though it had been prepended to L.

   function Traverse_Declarations_Or_Statements
     (L : List_Id;
      D : Dominant_Info := No_Dominant;
      P : Node_Id       := Empty) return Dominant_Info;
   --  Same as above, and returns dominant information corresponding to the
   --  last node with SCO in L.

   --  The following Traverse_* routines perform appropriate calls to
   --  Traverse_Declarations_Or_Statements to traverse specific node kinds.
   --  Parameter D, when present, indicates the dominant of the first
   --  declaration or statement within N.

   procedure Traverse_Generic_Package_Declaration (N : Node_Id);

   procedure Traverse_Handled_Statement_Sequence
     (N : Node_Id;
      D : Dominant_Info := No_Dominant);

   procedure Traverse_Package_Body (N : Node_Id);

   procedure Traverse_Package_Declaration
     (N : Node_Id;
      D : Dominant_Info := No_Dominant);

   procedure Traverse_Subprogram_Or_Task_Body
     (N : Node_Id;
      D : Dominant_Info := No_Dominant);

   procedure Traverse_Protected_Or_Task_Definition (N : Node_Id);

   --  Note regarding traversals: In a few cases where an Alternatives list is
   --  involved, pragmas such as "pragma Page" may show up before the first
   --  alternative. We skip them because we're out of statement or declaration
   --  context, so these can't be pragmas of interest for SCO purposes, and
   --  the regular alternative processing typically involves attribute queries
   --  which aren't valid for a pragma.

   procedure Write_SCOs_To_ALI_File is new Put_SCOs;
   --  Write SCO information to the ALI file using routines in Lib.Util

   ----------
   -- dsco --
   ----------

   procedure dsco is
      procedure Dump_Entry (Index : Nat; T : SCO_Table_Entry);
      --  Dump a SCO table entry

      ----------------
      -- Dump_Entry --
      ----------------

      procedure Dump_Entry (Index : Nat; T : SCO_Table_Entry) is
      begin
         Write_Str  ("  ");
         Write_Int  (Index);
         Write_Char ('.');

         if T.C1 /= ' ' then
            Write_Str  ("  C1 = '");
            Write_Char (T.C1);
            Write_Char (''');
         end if;

         if T.C2 /= ' ' then
            Write_Str  ("  C2 = '");
            Write_Char (T.C2);
            Write_Char (''');
         end if;

         if T.From /= No_Source_Location then
            Write_Str ("  From = ");
            Write_Int (Int (T.From.Line));
            Write_Char (':');
            Write_Int (Int (T.From.Col));
         end if;

         if T.To /= No_Source_Location then
            Write_Str ("  To = ");
            Write_Int (Int (T.To.Line));
            Write_Char (':');
            Write_Int (Int (T.To.Col));
         end if;

         if T.Last then
            Write_Str ("  True");
         else
            Write_Str ("  False");
         end if;

         Write_Eol;
      end Dump_Entry;

   --  Start of processing for dsco

   begin
      --  Dump SCO unit table

      Write_Line ("SCO Unit Table");
      Write_Line ("--------------");

      for Index in 1 .. SCO_Unit_Table.Last loop
         declare
            UTE : SCO_Unit_Table_Entry renames SCO_Unit_Table.Table (Index);

         begin
            Write_Str ("  ");
            Write_Int (Int (Index));
            Write_Str ("  Dep_Num = ");
            Write_Int (Int (UTE.Dep_Num));
            Write_Str ("  From = ");
            Write_Int (Int (UTE.From));
            Write_Str ("  To = ");
            Write_Int (Int (UTE.To));

            Write_Str ("  File_Name = """);

            if UTE.File_Name /= null then
               Write_Str (UTE.File_Name.all);
            end if;

            Write_Char ('"');
            Write_Eol;
         end;
      end loop;

      --  Dump SCO Unit number table if it contains any entries

      if SCO_Unit_Number_Table.Last >= 1 then
         Write_Eol;
         Write_Line ("SCO Unit Number Table");
         Write_Line ("---------------------");

         for Index in 1 .. SCO_Unit_Number_Table.Last loop
            Write_Str ("  ");
            Write_Int (Int (Index));
            Write_Str (". Unit_Number = ");
            Write_Int (Int (SCO_Unit_Number_Table.Table (Index)));
            Write_Eol;
         end loop;
      end if;

      --  Dump SCO raw-table

      Write_Eol;
      Write_Line ("SCO Raw Table");
      Write_Line ("---------");

      if SCO_Generation_State = Filtered then
         Write_Line ("Empty (free'd after second pass)");
      else
         for Index in 1 .. SCO_Raw_Table.Last loop
            Dump_Entry (Index, SCO_Raw_Table.Table (Index));
         end loop;
      end if;

      --  Dump SCO table itself

      Write_Eol;
      Write_Line ("SCO Filtered Table");
      Write_Line ("---------");

      for Index in 1 .. SCO_Table.Last loop
         Dump_Entry (Index, SCO_Table.Table (Index));
      end loop;
   end dsco;

   -----------
   -- Equal --
   -----------

   function Equal (F1 : Source_Ptr; F2 : Source_Ptr) return Boolean is
   begin
      return F1 = F2;
   end Equal;

   -------
   -- < --
   -------

   function "<" (S1 : Source_Location; S2 : Source_Location) return Boolean is
   begin
      return S1.Line < S2.Line
        or else (S1.Line = S2.Line and then S1.Col < S2.Col);
   end "<";

   ------------------
   -- Has_Decision --
   ------------------

   function Has_Decision (N : Node_Id) return Boolean is
      function Check_Node (N : Node_Id) return Traverse_Result;
      --  Determine if Nkind (N) indicates the presence of a decision (i.e. N
      --  is a logical operator, which is a decision in itself, or an
      --  IF-expression whose Condition attribute is a decision).

      ----------------
      -- Check_Node --
      ----------------

      function Check_Node (N : Node_Id) return Traverse_Result is
      begin
         --  If we are not sure this is a logical operator (AND and OR may be
         --  turned into logical operators with the Short_Circuit_And_Or
         --  pragma), assume it is. Putative decisions will be discarded if
         --  needed in the secord pass.

         if Is_Logical_Operator (N) /= False
           or else Nkind (N) = N_If_Expression
         then
            return Abandon;
         else
            return OK;
         end if;
      end Check_Node;

      function Traverse is new Traverse_Func (Check_Node);

   --  Start of processing for Has_Decision

   begin
      return Traverse (N) = Abandon;
   end Has_Decision;

   ----------
   -- Hash --
   ----------

   function Hash (F : Source_Ptr) return Header_Num is
   begin
      return Header_Num (Nat (F) mod 997);
   end Hash;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      SCO_Unit_Number_Table.Init;

      --  The SCO_Unit_Number_Table entry with index 0 is intentionally set
      --  aside to be used as temporary for sorting.

      SCO_Unit_Number_Table.Increment_Last;
   end Initialize;

   -------------------------
   -- Is_Logical_Operator --
   -------------------------

   function Is_Logical_Operator (N : Node_Id) return Tristate is
   begin
      if Nkind (N) in N_And_Then | N_Op_Not | N_Or_Else then
         return True;
      elsif Nkind (N) in N_Op_And | N_Op_Or then
         return Unknown;
      else
         return False;
      end if;
   end Is_Logical_Operator;

   -----------------------
   -- Process_Decisions --
   -----------------------

   --  Version taking a list

   procedure Process_Decisions
     (L           : List_Id;
      T           : Character;
      Pragma_Sloc : Source_Ptr)
   is
      N : Node_Id;

   begin
      if L /= No_List then
         N := First (L);
         while Present (N) loop
            Process_Decisions (N, T, Pragma_Sloc);
            Next (N);
         end loop;
      end if;
   end Process_Decisions;

   --  Version taking a node

   Current_Pragma_Sloc : Source_Ptr := No_Location;
   --  While processing a pragma, this is set to the sloc of the N_Pragma node

   procedure Process_Decisions
     (N           : Node_Id;
      T           : Character;
      Pragma_Sloc : Source_Ptr)
   is
      Mark : Nat;
      --  This is used to mark the location of a decision sequence in the SCO
      --  table. We use it for backing out a simple decision in an expression
      --  context that contains only NOT operators.

      Mark_Hash : Nat;
      --  Likewise for the putative SCO_Raw_Hash_Table entries: see below

      type Hash_Entry is record
         Sloc      : Source_Ptr;
         SCO_Index : Nat;
      end record;
      --  We must register all conditions/pragmas in SCO_Raw_Hash_Table.
      --  However we cannot register them in the same time we are adding the
      --  corresponding SCO entries to the raw table since we may discard them
      --  later on. So instead we put all putative conditions into Hash_Entries
      --  (see below) and register them once we are sure we keep them.
      --
      --  This data structure holds the conditions/pragmas to register in
      --  SCO_Raw_Hash_Table.

      package Hash_Entries is new Table.Table
        (Table_Component_Type => Hash_Entry,
         Table_Index_Type     => Nat,
         Table_Low_Bound      => 1,
         Table_Initial        => 10,
         Table_Increment      => 10,
         Table_Name           => "Hash_Entries");
      --  Hold temporarily (i.e. free'd before returning) the Hash_Entry before
      --  they are registered in SCO_Raw_Hash_Table.

      X_Not_Decision : Boolean;
      --  This flag keeps track of whether a decision sequence in the SCO table
      --  contains only NOT operators, and is for an expression context (T=X).
      --  The flag will be set False if T is other than X, or if an operator
      --  other than NOT is in the sequence.

      procedure Output_Decision_Operand (N : Node_Id);
      --  The node N is the top level logical operator of a decision, or it is
      --  one of the operands of a logical operator belonging to a single
      --  complex decision. This routine outputs the sequence of table entries
      --  corresponding to the node. Note that we do not process the sub-
      --  operands to look for further decisions, that processing is done in
      --  Process_Decision_Operand, because we can't get decisions mixed up in
      --  the global table. Call has no effect if N is Empty.

      procedure Output_Element (N : Node_Id);
      --  Node N is an operand of a logical operator that is not itself a
      --  logical operator, or it is a simple decision. This routine outputs
      --  the table entry for the element, with C1 set to ' '. Last is set
      --  False, and an entry is made in the condition hash table.

      procedure Output_Header (T : Character);
      --  Outputs a decision header node. T is I/W/E/P for IF/WHILE/EXIT WHEN/
      --  PRAGMA, and 'X' for the expression case.

      procedure Process_Decision_Operand (N : Node_Id);
      --  This is called on node N, the top level node of a decision, or on one
      --  of its operands or suboperands after generating the full output for
      --  the complex decision. It process the suboperands of the decision
      --  looking for nested decisions.

      function Process_Node (N : Node_Id) return Traverse_Result;
      --  Processes one node in the traversal, looking for logical operators,
      --  and if one is found, outputs the appropriate table entries.

      -----------------------------
      -- Output_Decision_Operand --
      -----------------------------

      procedure Output_Decision_Operand (N : Node_Id) is
         C1 : Character;
         C2 : Character;
         --  C1 holds a character that identifies the operation while C2
         --  indicates whether we are sure (' ') or not ('?') this operation
         --  belongs to the decision. '?' entries will be filtered out in the
         --  second (SCO_Record_Filtered) pass.

         L : Node_Id;
         T : Tristate;

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

         T := Is_Logical_Operator (N);

         --  Logical operator

         if T /= False then
            if Nkind (N) = N_Op_Not then
               C1 := '!';
               L := Empty;

            else
               L := Left_Opnd (N);

               if Nkind (N) in N_Op_Or | N_Or_Else then
                  C1 := '|';
               else pragma Assert (Nkind (N) in N_Op_And | N_And_Then);
                  C1 := '&';
               end if;
            end if;

            if T = True then
               C2 := ' ';
            else
               C2 := '?';
            end if;

            Set_Raw_Table_Entry
              (C1   => C1,
               C2   => C2,
               From => Sloc (N),
               To   => No_Location,
               Last => False);

            Hash_Entries.Append ((Sloc (N), SCO_Raw_Table.Last));

            Output_Decision_Operand (L);
            Output_Decision_Operand (Right_Opnd (N));

         --  Not a logical operator

         else
            Output_Element (N);
         end if;
      end Output_Decision_Operand;

      --------------------
      -- Output_Element --
      --------------------

      procedure Output_Element (N : Node_Id) is
         FSloc : Source_Ptr;
         LSloc : Source_Ptr;
      begin
         Sloc_Range (N, FSloc, LSloc);
         Set_Raw_Table_Entry
           (C1   => ' ',
            C2   => 'c',
            From => FSloc,
            To   => LSloc,
            Last => False);
         Hash_Entries.Append ((FSloc, SCO_Raw_Table.Last));
      end Output_Element;

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

      procedure Output_Header (T : Character) is
         Loc : Source_Ptr := No_Location;
         --  Node whose Sloc is used for the decision

         Nam : Name_Id := No_Name;
         --  For the case of an aspect, aspect name

      begin
         case T is
            when 'I' | 'E' | 'W' | 'a' | 'A' =>

               --  For IF, EXIT, WHILE, or aspects, the token SLOC is that of
               --  the parent of the expression.

               Loc := Sloc (Parent (N));

               if T = 'a' or else T = 'A' then
                  Nam := Chars (Identifier (Parent (N)));
               end if;

            when 'G' | 'P' =>

               --  For entry guard, the token sloc is from the N_Entry_Body.
               --  For PRAGMA, we must get the location from the pragma node.
               --  Argument N is the pragma argument, and we have to go up
               --  two levels (through the pragma argument association) to
               --  get to the pragma node itself. For the guard on a select
               --  alternative, we do not have access to the token location for
               --  the WHEN, so we use the first sloc of the condition itself.
               --  First_Sloc gives the most sensible result, but we have to
               --  beware of also using it when computing the dominance marker
               --  sloc (in the Set_Statement_Entry procedure), as this is not
               --  fully equivalent to the "To" sloc computed by
               --  Sloc_Range (Guard, To, From).

               if Nkind (Parent (N)) in N_Accept_Alternative
                                      | N_Delay_Alternative
                                      | N_Terminate_Alternative
               then
                  Loc := First_Sloc (N);
               else
                  Loc := Sloc (Parent (Parent (N)));
               end if;

            when 'X' =>

               --  For an expression, no Sloc

               null;

            --  No other possibilities

            when others =>
               raise Program_Error;
         end case;

         Set_Raw_Table_Entry
           (C1                 => T,
            C2                 => ' ',
            From               => Loc,
            To                 => No_Location,
            Last               => False,
            Pragma_Sloc        => Pragma_Sloc,
            Pragma_Aspect_Name => Nam);

         --  For an aspect specification, which will be rewritten into a
         --  pragma, enter a hash table entry now.

         if T = 'a' then
            Hash_Entries.Append ((Loc, SCO_Raw_Table.Last));
         end if;
      end Output_Header;

      ------------------------------
      -- Process_Decision_Operand --
      ------------------------------

      procedure Process_Decision_Operand (N : Node_Id) is
      begin
         if Is_Logical_Operator (N) /= False then
            if Nkind (N) /= N_Op_Not then
               Process_Decision_Operand (Left_Opnd (N));
               X_Not_Decision := False;
            end if;

            Process_Decision_Operand (Right_Opnd (N));

         else
            Process_Decisions (N, 'X', Pragma_Sloc);
         end if;
      end Process_Decision_Operand;

      ------------------
      -- Process_Node --
      ------------------

      function Process_Node (N : Node_Id) return Traverse_Result is
      begin
         case Nkind (N) is

            --  Logical operators, output table entries and then process
            --  operands recursively to deal with nested conditions.

            when N_And_Then
               | N_Op_And
               | N_Op_Not
               | N_Op_Or
               | N_Or_Else
            =>
               declare
                  T : Character;

               begin
                  --  If outer level, then type comes from call, otherwise it
                  --  is more deeply nested and counts as X for expression.

                  if N = Process_Decisions.N then
                     T := Process_Decisions.T;
                  else
                     T := 'X';
                  end if;

                  --  Output header for sequence

                  X_Not_Decision := T = 'X' and then Nkind (N) = N_Op_Not;
                  Mark      := SCO_Raw_Table.Last;
                  Mark_Hash := Hash_Entries.Last;
                  Output_Header (T);

                  --  Output the decision

                  Output_Decision_Operand (N);

                  --  If the decision was in an expression context (T = 'X')
                  --  and contained only NOT operators, then we don't output
                  --  it, so delete it.

                  if X_Not_Decision then
                     SCO_Raw_Table.Set_Last (Mark);
                     Hash_Entries.Set_Last (Mark_Hash);

                  --  Otherwise, set Last in last table entry to mark end

                  else
                     SCO_Raw_Table.Table (SCO_Raw_Table.Last).Last := True;
                  end if;

                  --  Process any embedded decisions

                  Process_Decision_Operand (N);
                  return Skip;
               end;

            --  Case expression

            --  Really hard to believe this is correct given the special
            --  handling for if expressions below ???

            when N_Case_Expression =>
               return OK; -- ???

            --  If expression, processed like an if statement

            when N_If_Expression =>
               declare
                  Cond : constant Node_Id := First (Expressions (N));
                  Thnx : constant Node_Id := Next (Cond);
                  Elsx : constant Node_Id := Next (Thnx);

               begin
                  Process_Decisions (Cond, 'I', Pragma_Sloc);
                  Process_Decisions (Thnx, 'X', Pragma_Sloc);
                  Process_Decisions (Elsx, 'X', Pragma_Sloc);
                  return Skip;
               end;

            when N_Quantified_Expression =>
               declare
                  Cond : constant Node_Id := Condition (N);
               begin
                  Process_Decisions (Cond, 'W', Pragma_Sloc);
                  return Skip;
               end;

            --  All other cases, continue scan

            when others =>
               return OK;
         end case;
      end Process_Node;

      procedure Traverse is new Traverse_Proc (Process_Node);

   --  Start of processing for Process_Decisions

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

      Hash_Entries.Init;

      --  See if we have simple decision at outer level and if so then
      --  generate the decision entry for this simple decision. A simple
      --  decision is a boolean expression (which is not a logical operator
      --  or short circuit form) appearing as the operand of an IF, WHILE,
      --  EXIT WHEN, or special PRAGMA construct.

      if T /= 'X' and then Is_Logical_Operator (N) = False then
         Output_Header (T);
         Output_Element (N);

         --  Change Last in last table entry to True to mark end of
         --  sequence, which is this case is only one element long.

         SCO_Raw_Table.Table (SCO_Raw_Table.Last).Last := True;
      end if;

      Traverse (N);

      --  Now we have the definitive set of SCO entries, register them in the
      --  corresponding hash table.

      for J in 1 .. Hash_Entries.Last loop
         SCO_Raw_Hash_Table.Set
           (Hash_Entries.Table (J).Sloc,
            Hash_Entries.Table (J).SCO_Index);
      end loop;

      Hash_Entries.Free;
   end Process_Decisions;

   -----------
   -- pscos --
   -----------

   procedure pscos is
      procedure Write_Info_Char (C : Character) renames Write_Char;
      --  Write one character;

      procedure Write_Info_Initiate (Key : Character) renames Write_Char;
      --  Start new one and write one character;

      procedure Write_Info_Nat (N : Nat);
      --  Write value of N

      procedure Write_Info_Terminate renames Write_Eol;
      --  Terminate current line

      --------------------
      -- Write_Info_Nat --
      --------------------

      procedure Write_Info_Nat (N : Nat) is
      begin
         Write_Int (N);
      end Write_Info_Nat;

      procedure Debug_Put_SCOs is new Put_SCOs;

   --  Start of processing for pscos

   begin
      Debug_Put_SCOs;
   end pscos;

   ---------------------
   -- Record_Instance --
   ---------------------

   procedure Record_Instance (Id : Instance_Id; Inst_Sloc : Source_Ptr) is
      Inst_Src  : constant Source_File_Index :=
                    Get_Source_File_Index (Inst_Sloc);
   begin
      SCO_Instance_Table.Append
        ((Inst_Dep_Num       => Dependency_Num (Unit (Inst_Src)),
          Inst_Loc           => To_Source_Location (Inst_Sloc),
          Enclosing_Instance => SCO_Instance_Index (Instance (Inst_Src))));

      pragma Assert
        (SCO_Instance_Table.Last = SCO_Instance_Index (Id));
   end Record_Instance;

   ----------------
   -- SCO_Output --
   ----------------

   procedure SCO_Output is
      procedure Populate_SCO_Instance_Table is
        new Sinput.Iterate_On_Instances (Record_Instance);

   begin
      pragma Assert (SCO_Generation_State = Filtered);

      if Debug_Flag_Dot_OO then
         dsco;
      end if;

      Populate_SCO_Instance_Table;

      --  Sort the unit tables based on dependency numbers

      Unit_Table_Sort : declare
         function Lt (Op1 : Natural; Op2 : Natural) return Boolean;
         --  Comparison routine for sort call

         procedure Move (From : Natural; To : Natural);
         --  Move routine for sort call

         --------
         -- Lt --
         --------

         function Lt (Op1 : Natural; Op2 : Natural) return Boolean is
         begin
            return
              Dependency_Num
                (SCO_Unit_Number_Table.Table (SCO_Unit_Index (Op1)))
                     <
              Dependency_Num
                (SCO_Unit_Number_Table.Table (SCO_Unit_Index (Op2)));
         end Lt;

         ----------
         -- Move --
         ----------

         procedure Move (From : Natural; To : Natural) is
         begin
            SCO_Unit_Table.Table (SCO_Unit_Index (To)) :=
              SCO_Unit_Table.Table (SCO_Unit_Index (From));
            SCO_Unit_Number_Table.Table (SCO_Unit_Index (To)) :=
              SCO_Unit_Number_Table.Table (SCO_Unit_Index (From));
         end Move;

         package Sorting is new GNAT.Heap_Sort_G (Move, Lt);

      --  Start of processing for Unit_Table_Sort

      begin
         Sorting.Sort (Integer (SCO_Unit_Table.Last));
      end Unit_Table_Sort;

      --  Loop through entries in the unit table to set file name and
      --  dependency number entries.

      for J in 1 .. SCO_Unit_Table.Last loop
         declare
            U   : constant Unit_Number_Type := SCO_Unit_Number_Table.Table (J);
            UTE : SCO_Unit_Table_Entry renames SCO_Unit_Table.Table (J);

         begin
            Get_Name_String (Reference_Name (Source_Index (U)));
            UTE.File_Name := new String'(Name_Buffer (1 .. Name_Len));
            UTE.Dep_Num := Dependency_Num (U);
         end;
      end loop;

      --  Now the tables are all setup for output to the ALI file

      Write_SCOs_To_ALI_File;
   end SCO_Output;

   -------------------------
   -- SCO_Pragma_Disabled --
   -------------------------

   function SCO_Pragma_Disabled (Loc : Source_Ptr) return Boolean is
      Index : Nat;

   begin
      if Loc = No_Location then
         return False;
      end if;

      Index := SCO_Raw_Hash_Table.Get (Loc);

      --  The test here for zero is to deal with possible previous errors, and
      --  for the case of pragma statement SCOs, for which we always set the
      --  Pragma_Sloc even if the particular pragma cannot be specifically
      --  disabled.

      if Index /= 0 then
         declare
            T : SCO_Table_Entry renames SCO_Raw_Table.Table (Index);

         begin
            case T.C1 is
               when 'S' =>
                  --  Pragma statement

                  return T.C2 = 'p';

               when 'A' =>
                  --  Aspect decision (enabled)

                  return False;

               when 'a' =>
                  --  Aspect decision (not enabled)

                  return True;

               when ASCII.NUL =>
                  --  Nullified disabled SCO

                  return True;

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

      else
         return False;
      end if;
   end SCO_Pragma_Disabled;

   --------------------
   -- SCO_Record_Raw --
   --------------------

   procedure SCO_Record_Raw (U : Unit_Number_Type) is
      procedure Traverse_Aux_Decls (N : Node_Id);
      --  Traverse the Aux_Decls_Node of compilation unit N

      ------------------------
      -- Traverse_Aux_Decls --
      ------------------------

      procedure Traverse_Aux_Decls (N : Node_Id) is
         ADN : constant Node_Id := Aux_Decls_Node (N);

      begin
         Traverse_Declarations_Or_Statements (Config_Pragmas (ADN));
         Traverse_Declarations_Or_Statements (Pragmas_After  (ADN));

         --  Declarations and Actions do not correspond to source constructs,
         --  they contain only nodes from expansion, so at this point they
         --  should still be empty:

         pragma Assert (No (Declarations (ADN)));
         pragma Assert (No (Actions (ADN)));
      end Traverse_Aux_Decls;

      --  Local variables

      From : Nat;
      Lu   : Node_Id;

   --  Start of processing for SCO_Record_Raw

   begin
      --  It is legitimate to run this pass multiple times (once per unit) so
      --  run it even if it was already run before.

      pragma Assert (SCO_Generation_State in None .. Raw);
      SCO_Generation_State := Raw;

      --  Ignore call if not generating code and generating SCO's

      if not (Generate_SCO and then Operating_Mode = Generate_Code) then
         return;
      end if;

      --  Ignore call if this unit already recorded

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

      --  Otherwise record starting entry

      From := SCO_Raw_Table.Last + 1;

      --  Get Unit (checking case of subunit)

      Lu := Unit (Cunit (U));

      if Nkind (Lu) = N_Subunit then
         Lu := Proper_Body (Lu);
      end if;

      --  Traverse the unit

      Traverse_Aux_Decls (Cunit (U));

      case Nkind (Lu) is
         when N_Generic_Instantiation
            | N_Generic_Package_Declaration
            | N_Package_Body
            | N_Package_Declaration
            | N_Protected_Body
            | N_Subprogram_Body
            | N_Subprogram_Declaration
            | N_Task_Body
         =>
            Traverse_Declarations_Or_Statements (L => No_List, P => Lu);

         --  All other cases of compilation units (e.g. renamings), generate no
         --  SCO information.

         when others =>
            null;
      end case;

      --  Make entry for new unit in unit tables, we will fill in the file
      --  name and dependency numbers later.

      SCO_Unit_Table.Append (
        (Dep_Num    => 0,
         File_Name  => null,
         File_Index => Get_Source_File_Index (Sloc (Lu)),
         From       => From,
         To         => SCO_Raw_Table.Last));

      SCO_Unit_Number_Table.Append (U);
   end SCO_Record_Raw;

   -----------------------
   -- Set_SCO_Condition --
   -----------------------

   procedure Set_SCO_Condition (Cond : Node_Id; Val : Boolean) is

      --  SCO annotations are not processed after the filtering pass

      pragma Assert (not Generate_SCO or else SCO_Generation_State = Raw);

      Constant_Condition_Code : constant array (Boolean) of Character :=
                                  (False => 'f', True => 't');

      Orig  : constant Node_Id := Original_Node (Cond);
      Dummy : Source_Ptr;
      Index : Nat;
      Start : Source_Ptr;

   begin
      Sloc_Range (Orig, Start, Dummy);
      Index := SCO_Raw_Hash_Table.Get (Start);

      --  Index can be zero for boolean expressions that do not have SCOs
      --  (simple decisions outside of a control flow structure), or in case
      --  of a previous error.

      if Index = 0 then
         return;

      else
         pragma Assert (SCO_Raw_Table.Table (Index).C1 = ' ');
         SCO_Raw_Table.Table (Index).C2 := Constant_Condition_Code (Val);
      end if;
   end Set_SCO_Condition;

   ------------------------------
   -- Set_SCO_Logical_Operator --
   ------------------------------

   procedure Set_SCO_Logical_Operator (Op : Node_Id) is

      --  SCO annotations are not processed after the filtering pass

      pragma Assert (not Generate_SCO or else SCO_Generation_State = Raw);

      Orig      : constant Node_Id    := Original_Node (Op);
      Orig_Sloc : constant Source_Ptr := Sloc (Orig);
      Index     : constant Nat        := SCO_Raw_Hash_Table.Get (Orig_Sloc);

   begin
      --  All (putative) logical operators are supposed to have their own entry
      --  in the SCOs table. However, the semantic analysis may invoke this
      --  subprogram with nodes that are out of the SCO generation scope.

      if Index /= 0 then
         SCO_Raw_Table.Table (Index).C2 := ' ';
      end if;
   end Set_SCO_Logical_Operator;

   ----------------------------
   -- Set_SCO_Pragma_Enabled --
   ----------------------------

   procedure Set_SCO_Pragma_Enabled (Loc : Source_Ptr) is

      --  SCO annotations are not processed after the filtering pass

      pragma Assert (not Generate_SCO or else SCO_Generation_State = Raw);

      Index : Nat;

   begin
      --  Nothing to do if not generating SCO, or if we're not processing the
      --  original source occurrence of the pragma.

      if not (Generate_SCO
               and then In_Extended_Main_Source_Unit (Loc)
               and then not (In_Instance or In_Inlined_Body))
      then
         return;
      end if;

      --  Note: the reason we use the Sloc value as the key is that in the
      --  generic case, the call to this procedure is made on a copy of the
      --  original node, so we can't use the Node_Id value.

      Index := SCO_Raw_Hash_Table.Get (Loc);

      --  A zero index here indicates that semantic analysis found an
      --  activated pragma at Loc which does not have a corresponding pragma
      --  or aspect at the syntax level. This may occur in legitimate cases
      --  because of expanded code (such are Pre/Post conditions generated for
      --  formal parameter validity checks), or as a consequence of a previous
      --  error.

      if Index = 0 then
         return;

      else
         declare
            T : SCO_Table_Entry renames SCO_Raw_Table.Table (Index);

         begin
            --  Note: may be called multiple times for the same sloc, so
            --  account for the fact that the entry may already have been
            --  marked enabled.

            case T.C1 is
               --  Aspect (decision SCO)

               when 'a' =>
                  T.C1 := 'A';

               when 'A' =>
                  null;

               --  Pragma (statement SCO)

               when 'S' =>
                  pragma Assert (T.C2 = 'p' or else T.C2 = 'P');
                  T.C2 := 'P';

               when others =>
                  raise Program_Error;
            end case;
         end;
      end if;
   end Set_SCO_Pragma_Enabled;

   -------------------------
   -- Set_Raw_Table_Entry --
   -------------------------

   procedure Set_Raw_Table_Entry
     (C1                 : Character;
      C2                 : Character;
      From               : Source_Ptr;
      To                 : Source_Ptr;
      Last               : Boolean;
      Pragma_Sloc        : Source_Ptr := No_Location;
      Pragma_Aspect_Name : Name_Id    := No_Name)
   is
      pragma Assert (SCO_Generation_State = Raw);
   begin
      SCO_Raw_Table.Append
        ((C1                 => C1,
          C2                 => C2,
          From               => To_Source_Location (From),
          To                 => To_Source_Location (To),
          Last               => Last,
          Pragma_Sloc        => Pragma_Sloc,
          Pragma_Aspect_Name => Pragma_Aspect_Name));
   end Set_Raw_Table_Entry;

   ------------------------
   -- To_Source_Location --
   ------------------------

   function To_Source_Location (S : Source_Ptr) return Source_Location is
   begin
      if S = No_Location then
         return No_Source_Location;
      else
         return
           (Line => Get_Logical_Line_Number (S),
            Col  => Get_Column_Number (S));
      end if;
   end To_Source_Location;

   -----------------------------------------
   -- Traverse_Declarations_Or_Statements --
   -----------------------------------------

   --  Tables used by Traverse_Declarations_Or_Statements for temporarily
   --  holding statement and decision entries. These are declared globally
   --  since they are shared by recursive calls to this procedure.

   type SC_Entry is record
      N    : Node_Id;
      From : Source_Ptr;
      To   : Source_Ptr;
      Typ  : Character;
   end record;
   --  Used to store a single entry in the following table, From:To represents
   --  the range of entries in the CS line entry, and typ is the type, with
   --  space meaning that no type letter will accompany the entry.

   package SC is new Table.Table
     (Table_Component_Type => SC_Entry,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => 1000,
      Table_Increment      => 200,
      Table_Name           => "SCO_SC");
   --  Used to store statement components for a CS entry to be output as a
   --  result of the call to this procedure. SC.Last is the last entry stored,
   --  so the current statement sequence is represented by SC_Array (SC_First
   --  .. SC.Last), where SC_First is saved on entry to each recursive call to
   --  the routine.
   --
   --  Extend_Statement_Sequence adds an entry to this array, and then
   --  Set_Statement_Entry clears the entries starting with SC_First, copying
   --  these entries to the main SCO output table. The reason that we do the
   --  temporary caching of results in this array is that we want the SCO table
   --  entries for a given CS line to be contiguous, and the processing may
   --  output intermediate entries such as decision entries.

   type SD_Entry is record
      Nod : Node_Id;
      Lst : List_Id;
      Typ : Character;
      Plo : Source_Ptr;
   end record;
   --  Used to store a single entry in the following table. Nod is the node to
   --  be searched for decisions for the case of Process_Decisions_Defer with a
   --  node argument (with Lst set to No_List. Lst is the list to be searched
   --  for decisions for the case of Process_Decisions_Defer with a List
   --  argument (in which case Nod is set to Empty). Plo is the sloc of the
   --  enclosing pragma, if any.

   package SD is new Table.Table
     (Table_Component_Type => SD_Entry,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => 1000,
      Table_Increment      => 200,
      Table_Name           => "SCO_SD");
   --  Used to store possible decision information. Instead of calling the
   --  Process_Decisions procedures directly, we call Process_Decisions_Defer,
   --  which simply stores the arguments in this table. Then when we clear
   --  out a statement sequence using Set_Statement_Entry, after generating
   --  the CS lines for the statements, the entries in this table result in
   --  calls to Process_Decision. The reason for doing things this way is to
   --  ensure that decisions are output after the CS line for the statements
   --  in which the decisions occur.

   procedure Traverse_Declarations_Or_Statements
     (L : List_Id;
      D : Dominant_Info := No_Dominant;
      P : Node_Id       := Empty)
   is
      Discard_Dom : Dominant_Info;
      pragma Warnings (Off, Discard_Dom);
   begin
      Discard_Dom := Traverse_Declarations_Or_Statements (L, D, P);
   end Traverse_Declarations_Or_Statements;

   function Traverse_Declarations_Or_Statements
     (L : List_Id;
      D : Dominant_Info := No_Dominant;
      P : Node_Id       := Empty) return Dominant_Info
   is
      Current_Dominant : Dominant_Info := D;
      --  Dominance information for the current basic block

      Current_Test : Node_Id;
      --  Conditional node (N_If_Statement or N_Elsif being processed)

      N : Node_Id;

      SC_First : constant Nat := SC.Last + 1;
      SD_First : constant Nat := SD.Last + 1;
      --  Record first entries used in SC/SD at this recursive level

      procedure Extend_Statement_Sequence (N : Node_Id; Typ : Character);
      --  Extend the current statement sequence to encompass the node N. Typ is
      --  the letter that identifies the type of statement/declaration that is
      --  being added to the sequence.

      procedure Process_Decisions_Defer (N : Node_Id; T : Character);
      pragma Inline (Process_Decisions_Defer);
      --  This routine is logically the same as Process_Decisions, except that
      --  the arguments are saved in the SD table for later processing when
      --  Set_Statement_Entry is called, which goes through the saved entries
      --  making the corresponding calls to Process_Decision. Note: the
      --  enclosing statement must have already been added to the current
      --  statement sequence, so that nested decisions are properly
      --  identified as such.

      procedure Process_Decisions_Defer (L : List_Id; T : Character);
      pragma Inline (Process_Decisions_Defer);
      --  Same case for list arguments, deferred call to Process_Decisions

      procedure Set_Statement_Entry;
      --  Output CS entries for all statements saved in table SC, and end the
      --  current CS sequence. Then output entries for all decisions nested in
      --  these statements, which have been deferred so far.

      procedure Traverse_One (N : Node_Id);
      --  Traverse one declaration or statement

      procedure Traverse_Aspects (N : Node_Id);
      --  Helper for Traverse_One: traverse N's aspect specifications

      procedure Traverse_Degenerate_Subprogram (N : Node_Id);
      --  Common code to handle null procedures and expression functions. Emit
      --  a SCO of the given Kind and N outside of the dominance flow.

      -------------------------------
      -- Extend_Statement_Sequence --
      -------------------------------

      procedure Extend_Statement_Sequence (N : Node_Id; Typ : Character) is
         Dummy   : Source_Ptr;
         F       : Source_Ptr;
         T       : Source_Ptr;
         To_Node : Node_Id := Empty;

      begin
         Sloc_Range (N, F, T);

         case Nkind (N) is
            when N_Accept_Statement =>
               if Present (Parameter_Specifications (N)) then
                  To_Node := Last (Parameter_Specifications (N));
               elsif Present (Entry_Index (N)) then
                  To_Node := Entry_Index (N);
               else
                  To_Node := Entry_Direct_Name (N);
               end if;

            when N_Case_Statement =>
               To_Node := Expression (N);

            when N_Elsif_Part
               | N_If_Statement
            =>
               To_Node := Condition (N);

            when N_Extended_Return_Statement =>
               To_Node := Last (Return_Object_Declarations (N));

            when N_Loop_Statement =>
               To_Node := Iteration_Scheme (N);

            when N_Asynchronous_Select
               | N_Conditional_Entry_Call
               | N_Selective_Accept
               | N_Single_Protected_Declaration
               | N_Single_Task_Declaration
               | N_Timed_Entry_Call
            =>
               T := F;

            when N_Protected_Type_Declaration
               | N_Task_Type_Declaration
            =>
               if Has_Aspects (N) then
                  To_Node := Last (Aspect_Specifications (N));

               elsif Present (Discriminant_Specifications (N)) then
                  To_Node := Last (Discriminant_Specifications (N));

               else
                  To_Node := Defining_Identifier (N);
               end if;

            when N_Subexpr =>
               To_Node := N;

            when others =>
               null;
         end case;

         if Present (To_Node) then
            Sloc_Range (To_Node, Dummy, T);
         end if;

         SC.Append ((N, F, T, Typ));
      end Extend_Statement_Sequence;

      -----------------------------
      -- Process_Decisions_Defer --
      -----------------------------

      procedure Process_Decisions_Defer (N : Node_Id; T : Character) is
      begin
         SD.Append ((N, No_List, T, Current_Pragma_Sloc));
      end Process_Decisions_Defer;

      procedure Process_Decisions_Defer (L : List_Id; T : Character) is
      begin
         SD.Append ((Empty, L, T, Current_Pragma_Sloc));
      end Process_Decisions_Defer;

      -------------------------
      -- Set_Statement_Entry --
      -------------------------

      procedure Set_Statement_Entry is
         SC_Last : constant Int := SC.Last;
         SD_Last : constant Int := SD.Last;

      begin
         --  Output statement entries from saved entries in SC table

         for J in SC_First .. SC_Last loop
            if J = SC_First then

               if Current_Dominant /= No_Dominant then
                  declare
                     From : Source_Ptr;
                     To   : Source_Ptr;

                  begin
                     Sloc_Range (Current_Dominant.N, From, To);

                     if Current_Dominant.K /= 'E' then
                        To := No_Location;
                     end if;

                     --  Be consistent with the location determined in
                     --  Output_Header.

                     if Current_Dominant.K = 'T'
                        and then Nkind (Parent (Current_Dominant.N))
                                   in N_Accept_Alternative
                                    | N_Delay_Alternative
                                    | N_Terminate_Alternative
                     then
                        From := First_Sloc (Current_Dominant.N);
                     end if;

                     Set_Raw_Table_Entry
                       (C1                 => '>',
                        C2                 => Current_Dominant.K,
                        From               => From,
                        To                 => To,
                        Last               => False,
                        Pragma_Sloc        => No_Location,
                        Pragma_Aspect_Name => No_Name);
                  end;
               end if;
            end if;

            declare
               SCE                : SC_Entry renames SC.Table (J);
               Pragma_Sloc        : Source_Ptr := No_Location;
               Pragma_Aspect_Name : Name_Id    := No_Name;

            begin
               --  For the case of a statement SCO for a pragma controlled by
               --  Set_SCO_Pragma_Enabled, set Pragma_Sloc so that the SCO (and
               --  those of any nested decision) is emitted only if the pragma
               --  is enabled.

               if SCE.Typ = 'p' then
                  Pragma_Sloc := SCE.From;
                  SCO_Raw_Hash_Table.Set
                    (Pragma_Sloc, SCO_Raw_Table.Last + 1);
                  Pragma_Aspect_Name := Pragma_Name_Unmapped (SCE.N);
                  pragma Assert (Pragma_Aspect_Name /= No_Name);

               elsif SCE.Typ = 'P' then
                  Pragma_Aspect_Name := Pragma_Name_Unmapped (SCE.N);
                  pragma Assert (Pragma_Aspect_Name /= No_Name);
               end if;

               Set_Raw_Table_Entry
                 (C1                 => 'S',
                  C2                 => SCE.Typ,
                  From               => SCE.From,
                  To                 => SCE.To,
                  Last               => (J = SC_Last),
                  Pragma_Sloc        => Pragma_Sloc,
                  Pragma_Aspect_Name => Pragma_Aspect_Name);
            end;
         end loop;

         --  Last statement of basic block, if present, becomes new current
         --  dominant.

         if SC_Last >= SC_First then
            Current_Dominant := ('S', SC.Table (SC_Last).N);
         end if;

         --  Clear out used section of SC table

         SC.Set_Last (SC_First - 1);

         --  Output any embedded decisions

         for J in SD_First .. SD_Last loop
            declare
               SDE : SD_Entry renames SD.Table (J);

            begin
               if Present (SDE.Nod) then
                  Process_Decisions (SDE.Nod, SDE.Typ, SDE.Plo);
               else
                  Process_Decisions (SDE.Lst, SDE.Typ, SDE.Plo);
               end if;
            end;
         end loop;

         --  Clear out used section of SD table

         SD.Set_Last (SD_First - 1);
      end Set_Statement_Entry;

      ----------------------
      -- Traverse_Aspects --
      ----------------------

      procedure Traverse_Aspects (N : Node_Id) is
         AE : Node_Id;
         AN : Node_Id;
         C1 : Character;

      begin
         AN := First (Aspect_Specifications (N));
         while Present (AN) loop
            AE := Expression (AN);

            --  SCOs are generated before semantic analysis/expansion:
            --  PPCs are not split yet.

            pragma Assert (not Split_PPC (AN));

            C1 := ASCII.NUL;

            case Get_Aspect_Id (AN) is

               --  Aspects rewritten into pragmas controlled by a Check_Policy:
               --  Current_Pragma_Sloc must be set to the sloc of the aspect
               --  specification. The corresponding pragma will have the same
               --  sloc. Note that Invariant, Pre, and Post will be enabled if
               --  the policy is Check; on the other hand, predicate aspects
               --  will be enabled for Check and Ignore (when Add_Predicate
               --  is called) because the actual checks occur in client units.
               --  When the assertion policy for Predicate is Disable, the
               --  SCO remains disabled, because Add_Predicate is never called.

               --  Pre/post can have checks in client units too because of
               --  inheritance, so should they receive the same treatment???

               when Aspect_Dynamic_Predicate
                  | Aspect_Invariant
                  | Aspect_Post
                  | Aspect_Postcondition
                  | Aspect_Pre
                  | Aspect_Precondition
                  | Aspect_Predicate
                  | Aspect_Static_Predicate
                  | Aspect_Type_Invariant
               =>
                  C1 := 'a';

               --  Other aspects: just process any decision nested in the
               --  aspect expression.

               when others =>
                  if Has_Decision (AE) then
                     C1 := 'X';
                  end if;
            end case;

            if C1 /= ASCII.NUL then
               pragma Assert (Current_Pragma_Sloc = No_Location);

               if C1 = 'a' or else C1 = 'A' then
                  Current_Pragma_Sloc := Sloc (AN);
               end if;

               Process_Decisions_Defer (AE, C1);

               Current_Pragma_Sloc := No_Location;
            end if;

            Next (AN);
         end loop;
      end Traverse_Aspects;

      ------------------------------------
      -- Traverse_Degenerate_Subprogram --
      ------------------------------------

      procedure Traverse_Degenerate_Subprogram (N : Node_Id) is
      begin
         --  Complete current sequence of statements

         Set_Statement_Entry;

         declare
            Saved_Dominant : constant Dominant_Info := Current_Dominant;
            --  Save last statement in current sequence as dominant

         begin
            --  Output statement SCO for degenerate subprogram body (null
            --  statement or freestanding expression) outside of the dominance
            --  chain.

            Current_Dominant := No_Dominant;
            Extend_Statement_Sequence (N, Typ => 'X');

            --  For the case of an expression-function, collect decisions
            --  embedded in the expression now.

            if Nkind (N) in N_Subexpr then
               Process_Decisions_Defer (N, 'X');
            end if;

            Set_Statement_Entry;

            --  Restore current dominant information designating last statement
            --  in previous sequence (i.e. make the dominance chain skip over
            --  the degenerate body).

            Current_Dominant := Saved_Dominant;
         end;
      end Traverse_Degenerate_Subprogram;

      ------------------
      -- Traverse_One --
      ------------------

      procedure Traverse_One (N : Node_Id) is
      begin
         --  Initialize or extend current statement sequence. Note that for
         --  special cases such as IF and Case statements we will modify
         --  the range to exclude internal statements that should not be
         --  counted as part of the current statement sequence.

         case Nkind (N) is

            --  Package declaration

            when N_Package_Declaration =>
               Set_Statement_Entry;
               Traverse_Package_Declaration (N, Current_Dominant);

            --  Generic package declaration

            when N_Generic_Package_Declaration =>
               Set_Statement_Entry;
               Traverse_Generic_Package_Declaration (N);

            --  Package body

            when N_Package_Body =>
               Set_Statement_Entry;
               Traverse_Package_Body (N);

            --  Subprogram declaration or subprogram body stub

            when N_Expression_Function
               | N_Subprogram_Body_Stub
               | N_Subprogram_Declaration
            =>
               declare
                  Spec : constant Node_Id := Specification (N);
               begin
                  Process_Decisions_Defer
                    (Parameter_Specifications (Spec), 'X');

                  --  Case of a null procedure: generate SCO for fictitious
                  --  NULL statement located at the NULL keyword in the
                  --  procedure specification.

                  if Nkind (N) = N_Subprogram_Declaration
                    and then Nkind (Spec) = N_Procedure_Specification
                    and then Null_Present (Spec)
                  then
                     Traverse_Degenerate_Subprogram (Null_Statement (Spec));

                  --  Case of an expression function: generate a statement SCO
                  --  for the expression (and then decision SCOs for any nested
                  --  decisions).

                  elsif Nkind (N) = N_Expression_Function then
                     Traverse_Degenerate_Subprogram (Expression (N));
                  end if;
               end;

            --  Entry declaration

            when N_Entry_Declaration =>
               Process_Decisions_Defer (Parameter_Specifications (N), 'X');

            --  Generic subprogram declaration

            when N_Generic_Subprogram_Declaration =>
               Process_Decisions_Defer
                 (Generic_Formal_Declarations (N), 'X');
               Process_Decisions_Defer
                 (Parameter_Specifications (Specification (N)), 'X');

            --  Task or subprogram body

            when N_Subprogram_Body
               | N_Task_Body
            =>
               Set_Statement_Entry;
               Traverse_Subprogram_Or_Task_Body (N);

            --  Entry body

            when N_Entry_Body =>
               declare
                  Cond : constant Node_Id :=
                           Condition (Entry_Body_Formal_Part (N));

                  Inner_Dominant : Dominant_Info := No_Dominant;

               begin
                  Set_Statement_Entry;

                  if Present (Cond) then
                     Process_Decisions_Defer (Cond, 'G');

                     --  For an entry body with a barrier, the entry body
                     --  is dominated by a True evaluation of the barrier.

                     Inner_Dominant := ('T', N);
                  end if;

                  Traverse_Subprogram_Or_Task_Body (N, Inner_Dominant);
               end;

            --  Protected body

            when N_Protected_Body =>
               Set_Statement_Entry;
               Traverse_Declarations_Or_Statements (Declarations (N));

            --  Exit statement, which is an exit statement in the SCO sense,
            --  so it is included in the current statement sequence, but
            --  then it terminates this sequence. We also have to process
            --  any decisions in the exit statement expression.

            when N_Exit_Statement =>
               Extend_Statement_Sequence (N, 'E');
               Process_Decisions_Defer (Condition (N), 'E');
               Set_Statement_Entry;

               --  If condition is present, then following statement is
               --  only executed if the condition evaluates to False.

               if Present (Condition (N)) then
                  Current_Dominant := ('F', N);
               else
                  Current_Dominant := No_Dominant;
               end if;

            --  Label, which breaks the current statement sequence, but the
            --  label itself is not included in the next statement sequence,
            --  since it generates no code.

            when N_Label =>
               Set_Statement_Entry;
               Current_Dominant := No_Dominant;

            --  Block statement, which breaks the current statement sequence

            when N_Block_Statement =>
               Set_Statement_Entry;

               --  The first statement in the handled sequence of statements
               --  is dominated by the elaboration of the last declaration.

               Current_Dominant := Traverse_Declarations_Or_Statements
                                     (L => Declarations (N),
                                      D => Current_Dominant);

               Traverse_Handled_Statement_Sequence
                 (N => Handled_Statement_Sequence (N),
                  D => Current_Dominant);

            --  If statement, which breaks the current statement sequence,
            --  but we include the condition in the current sequence.

            when N_If_Statement =>
               Current_Test := N;
               Extend_Statement_Sequence (N, 'I');
               Process_Decisions_Defer (Condition (N), 'I');
               Set_Statement_Entry;

               --  Now we traverse the statements in the THEN part

               Traverse_Declarations_Or_Statements
                 (L => Then_Statements (N),
                  D => ('T', N));

               --  Loop through ELSIF parts if present

               if Present (Elsif_Parts (N)) then
                  declare
                     Saved_Dominant : constant Dominant_Info :=
                                        Current_Dominant;

                     Elif : Node_Id := First (Elsif_Parts (N));

                  begin
                     while Present (Elif) loop

                        --  An Elsif is executed only if the previous test
                        --  got a FALSE outcome.

                        Current_Dominant := ('F', Current_Test);

                        --  Now update current test information

                        Current_Test := Elif;

                        --  We generate a statement sequence for the
                        --  construct "ELSIF condition", so that we have
                        --  a statement for the resulting decisions.

                        Extend_Statement_Sequence (Elif, 'I');
                        Process_Decisions_Defer (Condition (Elif), 'I');
                        Set_Statement_Entry;

                        --  An ELSIF part is never guaranteed to have
                        --  been executed, following statements are only
                        --  dominated by the initial IF statement.

                        Current_Dominant := Saved_Dominant;

                        --  Traverse the statements in the ELSIF

                        Traverse_Declarations_Or_Statements
                          (L => Then_Statements (Elif),
                           D => ('T', Elif));
                        Next (Elif);
                     end loop;
                  end;
               end if;

               --  Finally traverse the ELSE statements if present

               Traverse_Declarations_Or_Statements
                 (L => Else_Statements (N),
                  D => ('F', Current_Test));

            --  CASE statement, which breaks the current statement sequence,
            --  but we include the expression in the current sequence.

            when N_Case_Statement =>
               Extend_Statement_Sequence (N, 'C');
               Process_Decisions_Defer (Expression (N), 'X');
               Set_Statement_Entry;

               --  Process case branches, all of which are dominated by the
               --  CASE statement.

               declare
                  Alt : Node_Id;
               begin
                  Alt := First_Non_Pragma (Alternatives (N));
                  while Present (Alt) loop
                     Traverse_Declarations_Or_Statements
                       (L => Statements (Alt),
                        D => Current_Dominant);
                     Next (Alt);
                  end loop;
               end;

            --  ACCEPT statement

            when N_Accept_Statement =>
               Extend_Statement_Sequence (N, 'A');
               Set_Statement_Entry;

               --  Process sequence of statements, dominant is the ACCEPT
               --  statement.

               Traverse_Handled_Statement_Sequence
                 (N => Handled_Statement_Sequence (N),
                  D => Current_Dominant);

            --  SELECT

            when N_Selective_Accept =>
               Extend_Statement_Sequence (N, 'S');
               Set_Statement_Entry;

               --  Process alternatives

               declare
                  Alt   : Node_Id;
                  Guard : Node_Id;
                  S_Dom : Dominant_Info;

               begin
                  Alt := First (Select_Alternatives (N));
                  while Present (Alt) loop
                     S_Dom := Current_Dominant;
                     Guard := Condition (Alt);

                     if Present (Guard) then
                        Process_Decisions
                          (Guard,
                           'G',
                           Pragma_Sloc => No_Location);
                        Current_Dominant := ('T', Guard);
                     end if;

                     Traverse_One (Alt);

                     Current_Dominant := S_Dom;
                     Next (Alt);
                  end loop;
               end;

               Traverse_Declarations_Or_Statements
                 (L => Else_Statements (N),
                  D => Current_Dominant);

            when N_Conditional_Entry_Call
               | N_Timed_Entry_Call
            =>
               Extend_Statement_Sequence (N, 'S');
               Set_Statement_Entry;

               --  Process alternatives

               Traverse_One (Entry_Call_Alternative (N));

               if Nkind (N) = N_Timed_Entry_Call then
                  Traverse_One (Delay_Alternative (N));
               else
                  Traverse_Declarations_Or_Statements
                    (L => Else_Statements (N),
                     D => Current_Dominant);
               end if;

            when N_Asynchronous_Select =>
               Extend_Statement_Sequence (N, 'S');
               Set_Statement_Entry;

               Traverse_One (Triggering_Alternative (N));
               Traverse_Declarations_Or_Statements
                 (L => Statements (Abortable_Part (N)),
                  D => Current_Dominant);

            when N_Accept_Alternative =>
               Traverse_Declarations_Or_Statements
                 (L => Statements (N),
                  D => Current_Dominant,
                  P => Accept_Statement (N));

            when N_Entry_Call_Alternative =>
               Traverse_Declarations_Or_Statements
                 (L => Statements (N),
                  D => Current_Dominant,
                  P => Entry_Call_Statement (N));

            when N_Delay_Alternative =>
               Traverse_Declarations_Or_Statements
                 (L => Statements (N),
                  D => Current_Dominant,
                  P => Delay_Statement (N));

            when N_Triggering_Alternative =>
               Traverse_Declarations_Or_Statements
                 (L => Statements (N),
                  D => Current_Dominant,
                  P => Triggering_Statement (N));

            when N_Terminate_Alternative =>

               --  It is dubious to emit a statement SCO for a TERMINATE
               --  alternative, since no code is actually executed if the
               --  alternative is selected -- the tasking runtime call just
               --  never returns???

               Extend_Statement_Sequence (N, ' ');
               Set_Statement_Entry;

            --  Unconditional exit points, which are included in the current
            --  statement sequence, but then terminate it

            when N_Goto_Statement
               | N_Raise_Statement
               | N_Requeue_Statement
            =>
               Extend_Statement_Sequence (N, ' ');
               Set_Statement_Entry;
               Current_Dominant := No_Dominant;

            --  Simple return statement. which is an exit point, but we
            --  have to process the return expression for decisions.

            when N_Simple_Return_Statement =>
               Extend_Statement_Sequence (N, ' ');
               Process_Decisions_Defer (Expression (N), 'X');
               Set_Statement_Entry;
               Current_Dominant := No_Dominant;

            --  Extended return statement

            when N_Extended_Return_Statement =>
               Extend_Statement_Sequence (N, 'R');
               Process_Decisions_Defer (Return_Object_Declarations (N), 'X');
               Set_Statement_Entry;

               Traverse_Handled_Statement_Sequence
                 (N => Handled_Statement_Sequence (N),
                  D => Current_Dominant);

               Current_Dominant := No_Dominant;

            --  Loop ends the current statement sequence, but we include
            --  the iteration scheme if present in the current sequence.
            --  But the body of the loop starts a new sequence, since it
            --  may not be executed as part of the current sequence.

            when N_Loop_Statement =>
               declare
                  ISC            : constant Node_Id := Iteration_Scheme (N);
                  Inner_Dominant : Dominant_Info    := No_Dominant;

               begin
                  if Present (ISC) then

                     --  If iteration scheme present, extend the current
                     --  statement sequence to include the iteration scheme
                     --  and process any decisions it contains.

                     --  While loop

                     if Present (Condition (ISC)) then
                        Extend_Statement_Sequence (N, 'W');
                        Process_Decisions_Defer (Condition (ISC), 'W');

                        --  Set more specific dominant for inner statements
                        --  (the control sloc for the decision is that of
                        --  the WHILE token).

                        Inner_Dominant := ('T', ISC);

                     --  For loop

                     else
                        Extend_Statement_Sequence (N, 'F');
                        Process_Decisions_Defer
                          (Loop_Parameter_Specification (ISC), 'X');
                     end if;
                  end if;

                  Set_Statement_Entry;

                  if Inner_Dominant = No_Dominant then
                     Inner_Dominant := Current_Dominant;
                  end if;

                  Traverse_Declarations_Or_Statements
                    (L => Statements (N),
                     D => Inner_Dominant);
               end;

            --  Pragma

            when N_Pragma =>

               --  Record sloc of pragma (pragmas don't nest)

               pragma Assert (Current_Pragma_Sloc = No_Location);
               Current_Pragma_Sloc := Sloc (N);

               --  Processing depends on the kind of pragma

               declare
                  Nam : constant Name_Id := Pragma_Name_Unmapped (N);
                  Arg : Node_Id          :=
                          First (Pragma_Argument_Associations (N));
                  Typ : Character;

               begin
                  case Nam is
                     when Name_Assert
                        | Name_Assert_And_Cut
                        | Name_Assume
                        | Name_Check
                        | Name_Loop_Invariant
                        | Name_Postcondition
                        | Name_Precondition
                        | Name_Type_Invariant
                        | Name_Invariant
                     =>
                        --  For Assert/Check/Precondition/Postcondition, we
                        --  must generate a P entry for the decision. Note
                        --  that this is done unconditionally at this stage.
                        --  Output for disabled pragmas is suppressed later
                        --  on when we output the decision line in Put_SCOs,
                        --  depending on setting by Set_SCO_Pragma_Enabled.

                        if Nam = Name_Check
                           or else Nam = Name_Type_Invariant
                           or else Nam = Name_Invariant
                        then
                           Next (Arg);
                        end if;

                        Process_Decisions_Defer (Expression (Arg), 'P');
                        Typ := 'p';

                        --  Pre/postconditions can be inherited so SCO should
                        --  never be deactivated???

                     when Name_Debug =>
                        if Present (Arg) and then Present (Next (Arg)) then

                           --  Case of a dyadic pragma Debug: first argument
                           --  is a P decision, any nested decision in the
                           --  second argument is an X decision.

                           Process_Decisions_Defer (Expression (Arg), 'P');
                           Next (Arg);
                        end if;

                        Process_Decisions_Defer (Expression (Arg), 'X');
                        Typ := 'p';

                     --  For all other pragmas, we generate decision entries
                     --  for any embedded expressions, and the pragma is
                     --  never disabled.

                     --  Should generate P decisions (not X) for assertion
                     --  related pragmas: [{Static,Dynamic}_]Predicate???

                     when others =>
                        Process_Decisions_Defer (N, 'X');
                        Typ := 'P';
                  end case;

                  --  Add statement SCO

                  Extend_Statement_Sequence (N, Typ);

                  Current_Pragma_Sloc := No_Location;
               end;

            --  Object declaration. Ignored if Prev_Ids is set, since the
            --  parser generates multiple instances of the whole declaration
            --  if there is more than one identifier declared, and we only
            --  want one entry in the SCOs, so we take the first, for which
            --  Prev_Ids is False.

            when N_Number_Declaration
               | N_Object_Declaration
            =>
               if not Prev_Ids (N) then
                  Extend_Statement_Sequence (N, 'o');

                  if Has_Decision (N) then
                     Process_Decisions_Defer (N, 'X');
                  end if;
               end if;

            --  All other cases, which extend the current statement sequence
            --  but do not terminate it, even if they have nested decisions.

            when N_Protected_Type_Declaration
               | N_Task_Type_Declaration
            =>
               Extend_Statement_Sequence (N, 't');
               Process_Decisions_Defer (Discriminant_Specifications (N), 'X');
               Set_Statement_Entry;

               Traverse_Protected_Or_Task_Definition (N);

            when N_Single_Protected_Declaration
               | N_Single_Task_Declaration
            =>
               Extend_Statement_Sequence (N, 'o');
               Set_Statement_Entry;

               Traverse_Protected_Or_Task_Definition (N);

            when others =>

               --  Determine required type character code, or ASCII.NUL if
               --  no SCO should be generated for this node.

               declare
                  NK  : constant Node_Kind := Nkind (N);
                  Typ : Character;

               begin
                  case NK is
                     when N_Full_Type_Declaration
                        | N_Incomplete_Type_Declaration
                        | N_Private_Extension_Declaration
                        | N_Private_Type_Declaration
                     =>
                        Typ := 't';

                     when N_Subtype_Declaration =>
                        Typ := 's';

                     when N_Renaming_Declaration =>
                        Typ := 'r';

                     when N_Generic_Instantiation =>
                        Typ := 'i';

                     when N_Package_Body_Stub
                        | N_Protected_Body_Stub
                        | N_Representation_Clause
                        | N_Task_Body_Stub
                        | N_Use_Package_Clause
                        | N_Use_Type_Clause
                     =>
                        Typ := ASCII.NUL;

                     when N_Procedure_Call_Statement =>
                        Typ := ' ';

                     when others =>
                        if NK in N_Statement_Other_Than_Procedure_Call then
                           Typ := ' ';
                        else
                           Typ := 'd';
                        end if;
                  end case;

                  if Typ /= ASCII.NUL then
                     Extend_Statement_Sequence (N, Typ);
                  end if;
               end;

               --  Process any embedded decisions

               if Has_Decision (N) then
                  Process_Decisions_Defer (N, 'X');
               end if;
         end case;

         --  Process aspects if present

         Traverse_Aspects (N);
      end Traverse_One;

   --  Start of processing for Traverse_Declarations_Or_Statements

   begin
      --  Process single prefixed node

      if Present (P) then
         Traverse_One (P);
      end if;

      --  Loop through statements or declarations

      if Is_Non_Empty_List (L) then
         N := First (L);
         while Present (N) loop

            --  Note: For separate bodies, we see the tree after Par.Labl has
            --  introduced implicit labels, so we need to ignore those nodes.

            if Nkind (N) /= N_Implicit_Label_Declaration then
               Traverse_One (N);
            end if;

            Next (N);
         end loop;

      end if;

      --  End sequence of statements and flush deferred decisions

      if Present (P) or else Is_Non_Empty_List (L) then
         Set_Statement_Entry;
      end if;

      return Current_Dominant;
   end Traverse_Declarations_Or_Statements;

   ------------------------------------------
   -- Traverse_Generic_Package_Declaration --
   ------------------------------------------

   procedure Traverse_Generic_Package_Declaration (N : Node_Id) is
   begin
      Process_Decisions (Generic_Formal_Declarations (N), 'X', No_Location);
      Traverse_Package_Declaration (N);
   end Traverse_Generic_Package_Declaration;

   -----------------------------------------
   -- Traverse_Handled_Statement_Sequence --
   -----------------------------------------

   procedure Traverse_Handled_Statement_Sequence
     (N : Node_Id;
      D : Dominant_Info := No_Dominant)
   is
      Handler : Node_Id;

   begin
      --  For package bodies without a statement part, the parser adds an empty
      --  one, to normalize the representation. The null statement therein,
      --  which does not come from source, does not get a SCO.

      if Present (N) and then Comes_From_Source (N) then
         Traverse_Declarations_Or_Statements (Statements (N), D);

         if Present (Exception_Handlers (N)) then
            Handler := First_Non_Pragma (Exception_Handlers (N));
            while Present (Handler) loop
               Traverse_Declarations_Or_Statements
                 (L => Statements (Handler),
                  D => ('E', Handler));
               Next (Handler);
            end loop;
         end if;
      end if;
   end Traverse_Handled_Statement_Sequence;

   ---------------------------
   -- Traverse_Package_Body --
   ---------------------------

   procedure Traverse_Package_Body (N : Node_Id) is
      Dom : Dominant_Info;
   begin
      --  The first statement in the handled sequence of statements is
      --  dominated by the elaboration of the last declaration.

      Dom := Traverse_Declarations_Or_Statements (Declarations (N));

      Traverse_Handled_Statement_Sequence
        (Handled_Statement_Sequence (N), Dom);
   end Traverse_Package_Body;

   ----------------------------------
   -- Traverse_Package_Declaration --
   ----------------------------------

   procedure Traverse_Package_Declaration
     (N : Node_Id;
      D : Dominant_Info := No_Dominant)
   is
      Spec : constant Node_Id := Specification (N);
      Dom  : Dominant_Info;

   begin
      Dom :=
        Traverse_Declarations_Or_Statements (Visible_Declarations (Spec), D);

      --  First private declaration is dominated by last visible declaration

      Traverse_Declarations_Or_Statements (Private_Declarations (Spec), Dom);
   end Traverse_Package_Declaration;

   -------------------------------------------
   -- Traverse_Protected_Or_Task_Definition --
   -------------------------------------------

   procedure Traverse_Protected_Or_Task_Definition (N : Node_Id) is
      Dom_Info : Dominant_Info := ('S', N);
      --  The first declaration is dominated by the protected or task [type]
      --  declaration.

      Sync_Def : Node_Id;
      --  N's protected or task definition

      Priv_Decl : List_Id;
      Vis_Decl  : List_Id;
      --  Sync_Def's Visible_Declarations and Private_Declarations

   begin
      case Nkind (N) is
         when N_Protected_Type_Declaration
            | N_Single_Protected_Declaration
         =>
            Sync_Def := Protected_Definition (N);

         when N_Single_Task_Declaration
            | N_Task_Type_Declaration
         =>
            Sync_Def := Task_Definition (N);

         when others =>
            raise Program_Error;
      end case;

      --  Sync_Def may be Empty at least for empty Task_Type_Declarations.
      --  Querying Visible or Private_Declarations is invalid in this case.

      if Present (Sync_Def) then
         Vis_Decl  := Visible_Declarations (Sync_Def);
         Priv_Decl := Private_Declarations (Sync_Def);
      else
         Vis_Decl  := No_List;
         Priv_Decl := No_List;
      end if;

      Dom_Info := Traverse_Declarations_Or_Statements
                    (L => Vis_Decl,
                     D => Dom_Info);

      --  If visible declarations are present, the first private declaration
      --  is dominated by the last visible declaration.

      Traverse_Declarations_Or_Statements
        (L => Priv_Decl,
         D => Dom_Info);
   end Traverse_Protected_Or_Task_Definition;

   --------------------------------------
   -- Traverse_Subprogram_Or_Task_Body --
   --------------------------------------

   procedure Traverse_Subprogram_Or_Task_Body
     (N : Node_Id;
      D : Dominant_Info := No_Dominant)
   is
      Decls    : constant List_Id := Declarations (N);
      Dom_Info : Dominant_Info    := D;

   begin
      --  If declarations are present, the first statement is dominated by the
      --  last declaration.

      Dom_Info := Traverse_Declarations_Or_Statements
                    (L => Decls, D => Dom_Info);

      Traverse_Handled_Statement_Sequence
        (N => Handled_Statement_Sequence (N),
         D => Dom_Info);
   end Traverse_Subprogram_Or_Task_Body;

   -------------------------
   -- SCO_Record_Filtered --
   -------------------------

   procedure SCO_Record_Filtered is
      type Decision is record
         Kind : Character;
         --  Type of the SCO decision (see comments for SCO_Table_Entry.C1)

         Sloc : Source_Location;

         Top  : Nat;
         --  Index in the SCO_Raw_Table for the root operator/condition for the
         --  expression that controls the decision.
      end record;
      --  Decision descriptor: used to gather information about a candidate
      --  SCO decision.

      package Pending_Decisions is new Table.Table
        (Table_Component_Type => Decision,
         Table_Index_Type     => Nat,
         Table_Low_Bound      => 1,
         Table_Initial        => 1000,
         Table_Increment      => 200,
         Table_Name           => "Filter_Pending_Decisions");
      --  Table used to hold decisions to process during the collection pass

      procedure Add_Expression_Tree (Idx : in out Nat);
      --  Add SCO raw table entries for the decision controlling expression
      --  tree starting at Idx to the filtered SCO table.

      procedure Collect_Decisions
        (D    : Decision;
         Next : out Nat);
      --  Collect decisions to add to the filtered SCO table starting at the
      --  D decision (including it and its nested operators/conditions). Set
      --  Next to the first node index passed the whole decision.

      procedure Compute_Range
        (Idx  : in out Nat;
         From : out Source_Location;
         To   : out Source_Location);
      --  Compute the source location range for the expression tree starting at
      --  Idx in the SCO raw table. Store its bounds in From and To.

      function Is_Decision (Idx : Nat) return Boolean;
      --  Return if the expression tree starting at Idx has adjacent nested
      --  nodes that make a decision.

      procedure Process_Pending_Decisions
        (Original_Decision : SCO_Table_Entry);
      --  Complete the filtered SCO table using collected decisions. Output
      --  decisions inherit the pragma information from the original decision.

      procedure Search_Nested_Decisions (Idx : in out Nat);
      --  Collect decisions to add to the filtered SCO table starting at the
      --  node at Idx in the SCO raw table. This node must not be part of an
      --  already-processed decision. Set Idx to the first node index passed
      --  the whole expression tree.

      procedure Skip_Decision
        (Idx                      : in out Nat;
         Process_Nested_Decisions : Boolean);
      --  Skip all the nodes that belong to the decision starting at Idx. If
      --  Process_Nested_Decision, call Search_Nested_Decisions on the first
      --  nested nodes that do not belong to the decision. Set Idx to the first
      --  node index passed the whole expression tree.

      -------------------------
      -- Add_Expression_Tree --
      -------------------------

      procedure Add_Expression_Tree (Idx : in out Nat) is
         Node_Idx : constant Nat := Idx;
         T        : SCO_Table_Entry renames SCO_Raw_Table.Table (Node_Idx);
         From     : Source_Location;
         To       : Source_Location;

      begin
         case T.C1 is
            when ' ' =>

               --  This is a single condition. Add an entry for it and move on

               SCO_Table.Append (T);
               Idx := Idx + 1;

            when '!' =>

               --  This is a NOT operator: add an entry for it and browse its
               --  only child.

               SCO_Table.Append (T);
               Idx := Idx + 1;
               Add_Expression_Tree (Idx);

            when others =>

               --  This must be an AND/OR/AND THEN/OR ELSE operator

               if T.C2 = '?' then

                  --  This is not a short circuit operator: consider this one
                  --  and all its children as a single condition.

                  Compute_Range (Idx, From, To);
                  SCO_Table.Append
                    ((From               => From,
                      To                 => To,
                      C1                 => ' ',
                      C2                 => 'c',
                      Last               => False,
                      Pragma_Sloc        => No_Location,
                      Pragma_Aspect_Name => No_Name));

               else
                  --  This is a real short circuit operator: add an entry for
                  --  it and browse its children.

                  SCO_Table.Append (T);
                  Idx := Idx + 1;
                  Add_Expression_Tree (Idx);
                  Add_Expression_Tree (Idx);
               end if;
         end case;
      end Add_Expression_Tree;

      -----------------------
      -- Collect_Decisions --
      -----------------------

      procedure Collect_Decisions
        (D    : Decision;
         Next : out Nat)
      is
         Idx : Nat := D.Top;

      begin
         if D.Kind /= 'X' or else Is_Decision (D.Top) then
            Pending_Decisions.Append (D);
         end if;

         Skip_Decision (Idx, True);
         Next := Idx;
      end Collect_Decisions;

      -------------------
      -- Compute_Range --
      -------------------

      procedure Compute_Range
        (Idx  : in out Nat;
         From : out Source_Location;
         To   : out Source_Location)
      is
         Sloc_F : Source_Location := No_Source_Location;
         Sloc_T : Source_Location := No_Source_Location;

         procedure Process_One;
         --  Process one node of the tree, and recurse over children. Update
         --  Idx during the traversal.

         -----------------
         -- Process_One --
         -----------------

         procedure Process_One is
         begin
            if Sloc_F = No_Source_Location
                 or else
               SCO_Raw_Table.Table (Idx).From < Sloc_F
            then
               Sloc_F := SCO_Raw_Table.Table (Idx).From;
            end if;

            if Sloc_T = No_Source_Location
                 or else
               Sloc_T < SCO_Raw_Table.Table (Idx).To
            then
               Sloc_T := SCO_Raw_Table.Table (Idx).To;
            end if;

            if SCO_Raw_Table.Table (Idx).C1 = ' ' then

               --  This is a condition: nothing special to do

               Idx := Idx + 1;

            elsif SCO_Raw_Table.Table (Idx).C1 = '!' then

               --  The "not" operator has only one operand

               Idx := Idx + 1;
               Process_One;

            else
               --  This is an AND THEN or OR ELSE logical operator: follow the
               --  left, then the right operands.

               Idx := Idx + 1;

               Process_One;
               Process_One;
            end if;
         end Process_One;

      --  Start of processing for Compute_Range

      begin
         Process_One;
         From := Sloc_F;
         To   := Sloc_T;
      end Compute_Range;

      -----------------
      -- Is_Decision --
      -----------------

      function Is_Decision (Idx : Nat) return Boolean is
         Index : Nat := Idx;

      begin
         loop
            declare
               T : SCO_Table_Entry renames SCO_Raw_Table.Table (Index);

            begin
               case T.C1 is
                  when ' ' =>
                     return False;

                  when '!' =>

                     --  This is a decision iff the only operand of the NOT
                     --  operator could be a standalone decision.

                     Index := Idx + 1;

                  when others =>

                     --  This node is a logical operator (and thus could be a
                     --  standalone decision) iff it is a short circuit
                     --  operator.

                     return T.C2 /= '?';
               end case;
            end;
         end loop;
      end Is_Decision;

      -------------------------------
      -- Process_Pending_Decisions --
      -------------------------------

      procedure Process_Pending_Decisions
        (Original_Decision : SCO_Table_Entry)
      is
      begin
         for Index in 1 .. Pending_Decisions.Last loop
            declare
               D   : Decision renames Pending_Decisions.Table (Index);
               Idx : Nat := D.Top;

            begin
               --  Add a SCO table entry for the decision itself

               pragma Assert (D.Kind /= ' ');

               SCO_Table.Append
                 ((To                 => No_Source_Location,
                   From               => D.Sloc,
                   C1                 => D.Kind,
                   C2                 => ' ',
                   Last               => False,
                   Pragma_Sloc        => Original_Decision.Pragma_Sloc,
                   Pragma_Aspect_Name =>
                      Original_Decision.Pragma_Aspect_Name));

               --  Then add ones for its nested operators/operands. Do not
               --  forget to tag its *last* entry as such.

               Add_Expression_Tree (Idx);
               SCO_Table.Table (SCO_Table.Last).Last := True;
            end;
         end loop;

         --  Clear the pending decisions list
         Pending_Decisions.Set_Last (0);
      end Process_Pending_Decisions;

      -----------------------------
      -- Search_Nested_Decisions --
      -----------------------------

      procedure Search_Nested_Decisions (Idx : in out Nat) is
      begin
         loop
            declare
               T : SCO_Table_Entry renames SCO_Raw_Table.Table (Idx);

            begin
               case T.C1 is
                  when ' ' =>
                     Idx := Idx + 1;
                     exit;

                  when '!' =>
                     Collect_Decisions
                       ((Kind => 'X',
                         Sloc => T.From,
                         Top  => Idx),
                        Idx);
                     exit;

                  when others =>
                     if T.C2 = '?' then

                        --  This is not a logical operator: start looking for
                        --  nested decisions from here. Recurse over the left
                        --  child and let the loop take care of the right one.

                        Idx := Idx + 1;
                        Search_Nested_Decisions (Idx);

                     else
                        --  We found a nested decision

                        Collect_Decisions
                          ((Kind => 'X',
                            Sloc => T.From,
                            Top  => Idx),
                            Idx);
                        exit;
                     end if;
               end case;
            end;
         end loop;
      end Search_Nested_Decisions;

      -------------------
      -- Skip_Decision --
      -------------------

      procedure Skip_Decision
        (Idx                      : in out Nat;
         Process_Nested_Decisions : Boolean)
      is
      begin
         loop
            declare
               T : SCO_Table_Entry renames SCO_Raw_Table.Table (Idx);

            begin
               Idx := Idx + 1;

               case T.C1 is
                  when ' ' =>
                     exit;

                  when '!' =>

                     --  This NOT operator belongs to the outside decision:
                     --  just skip it.

                     null;

                  when others =>
                     if T.C2 = '?' and then Process_Nested_Decisions then

                        --  This is not a logical operator: start looking for
                        --  nested decisions from here. Recurse over the left
                        --  child and let the loop take care of the right one.

                        Search_Nested_Decisions (Idx);

                     else
                        --  This is a logical operator, so it belongs to the
                        --  outside decision: skip its left child, then let the
                        --  loop take care of the right one.

                        Skip_Decision (Idx, Process_Nested_Decisions);
                     end if;
               end case;
            end;
         end loop;
      end Skip_Decision;

   --  Start of processing for SCO_Record_Filtered

   begin
      --  Filtering must happen only once: do nothing if it this pass was
      --  already run.

      if SCO_Generation_State = Filtered then
         return;
      else
         pragma Assert (SCO_Generation_State = Raw);
         SCO_Generation_State := Filtered;
      end if;

      --  Loop through all SCO entries under SCO units

      for Unit_Idx in 1 .. SCO_Unit_Table.Last loop
         declare
            Unit : SCO_Unit_Table_Entry
                     renames SCO_Unit_Table.Table (Unit_Idx);

            Idx : Nat := Unit.From;
            --  Index of the current SCO raw table entry

            New_From : constant Nat := SCO_Table.Last + 1;
            --  After copying SCO enties of interest to the final table, we
            --  will have to change the From/To indexes this unit targets.
            --  This constant keeps track of the new From index.

         begin
            while Idx <= Unit.To loop
               declare
                  T : SCO_Table_Entry renames SCO_Raw_Table.Table (Idx);

               begin
                  case T.C1 is

                     --  Decision (of any kind, including pragmas and aspects)

                     when 'E' | 'G' | 'I' | 'W' | 'X' | 'P' | 'a' | 'A' =>
                        if SCO_Pragma_Disabled (T.Pragma_Sloc) then

                           --  Skip SCO entries for decisions in disabled
                           --  constructs (pragmas or aspects).

                           Idx := Idx + 1;
                           Skip_Decision (Idx, False);

                        else
                           Collect_Decisions
                             ((Kind => T.C1,
                               Sloc => T.From,
                               Top  => Idx + 1),
                              Idx);
                           Process_Pending_Decisions (T);
                        end if;

                     --  There is no translation/filtering to do for other kind
                     --  of SCO items (statements, dominance markers, etc.).

                     when '|' | '&' | '!' | ' ' =>

                        --  SCO logical operators and conditions cannot exist
                        --  on their own: they must be inside a decision (such
                        --  entries must have been skipped by
                        --  Collect_Decisions).

                        raise Program_Error;

                     when others =>
                        SCO_Table.Append (T);
                        Idx := Idx + 1;
                  end case;
               end;
            end loop;

            --  Now, update the SCO entry indexes in the unit entry

            Unit.From := New_From;
            Unit.To   := SCO_Table.Last;
         end;
      end loop;

      --  Then clear the raw table to free bytes

      SCO_Raw_Table.Free;
   end SCO_Record_Filtered;

end Par_SCO;
