------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             S E M _ E L I M                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1997-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 Atree;          use Atree;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Errout;         use Errout;
with Lib;            use Lib;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Opt;            use Opt;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Prag;       use Sem_Prag;
with Sem_Util;       use Sem_Util;
with Sinput;         use Sinput;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with Table;

with GNAT.HTable;    use GNAT.HTable;

package body Sem_Elim is

   No_Elimination : Boolean;
   --  Set True if no Eliminate pragmas active

   ---------------------
   -- Data Structures --
   ---------------------

   --  A single pragma Eliminate is represented by the following record

   type Elim_Data;
   type Access_Elim_Data is access Elim_Data;

   type Names is array (Nat range <>) of Name_Id;
   --  Type used to represent set of names. Used for names in Unit_Name
   --  and also the set of names in Argument_Types.

   type Access_Names is access Names;

   type Elim_Data is record

      Unit_Name : Access_Names;
      --  Unit name, broken down into a set of names (e.g. A.B.C is
      --  represented as Name_Id values for A, B, C in sequence).

      Entity_Name : Name_Id;
      --  Entity name if Entity parameter if present. If no Entity parameter
      --  was supplied, then Entity_Node is set to Empty, and the Entity_Name
      --  field contains the last identifier name in the Unit_Name.

      Entity_Scope : Access_Names;
      --  Static scope of the entity within the compilation unit represented by
      --  Unit_Name.

      Entity_Node : Node_Id;
      --  Save node of entity argument, for posting error messages. Set
      --  to Empty if there is no entity argument.

      Parameter_Types : Access_Names;
      --  Set to set of names given for parameter types. If no parameter
      --  types argument is present, this argument is set to null.

      Result_Type : Name_Id;
      --  Result type name if Result_Types parameter present, No_Name if not

      Source_Location : Name_Id;
      --  String describing the source location of subprogram defining name if
      --  Source_Location parameter present, No_Name if not

      Hash_Link : Access_Elim_Data;
      --  Link for hash table use

      Homonym : Access_Elim_Data;
      --  Pointer to next entry with same key

      Prag : Node_Id;
      --  Node_Id for Eliminate pragma

   end record;

   ----------------
   -- Hash_Table --
   ----------------

   --  Setup hash table using the Entity_Name field as the hash key

   subtype Element is Elim_Data;
   subtype Elmt_Ptr is Access_Elim_Data;

   subtype Key is Name_Id;

   type Header_Num is range 0 .. 1023;

   Null_Ptr : constant Elmt_Ptr := null;

   ----------------------
   -- Hash_Subprograms --
   ----------------------

   package Hash_Subprograms is

      function Equal (F1, F2 : Key) return Boolean;
      pragma Inline (Equal);

      function Get_Key (E : Elmt_Ptr) return Key;
      pragma Inline (Get_Key);

      function Hash (F : Key) return Header_Num;
      pragma Inline (Hash);

      function Next (E : Elmt_Ptr) return Elmt_Ptr;
      pragma Inline (Next);

      procedure Set_Next (E : Elmt_Ptr; Next : Elmt_Ptr);
      pragma Inline (Set_Next);

   end Hash_Subprograms;

   package body Hash_Subprograms is

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

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

      -------------
      -- Get_Key --
      -------------

      function Get_Key (E : Elmt_Ptr) return Key is
      begin
         return E.Entity_Name;
      end Get_Key;

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

      function Hash (F : Key) return Header_Num is
      begin
         return Header_Num (Int (F) mod 1024);
      end Hash;

      ----------
      -- Next --
      ----------

      function Next (E : Elmt_Ptr) return Elmt_Ptr is
      begin
         return E.Hash_Link;
      end Next;

      --------------
      -- Set_Next --
      --------------

      procedure Set_Next (E : Elmt_Ptr; Next : Elmt_Ptr) is
      begin
         E.Hash_Link := Next;
      end Set_Next;
   end Hash_Subprograms;

   ------------
   -- Tables --
   ------------

   --  The following table records the data for each pragma, using the
   --  entity name as the hash key for retrieval. Entries in this table
   --  are set by Process_Eliminate_Pragma and read by Check_Eliminated.

   package Elim_Hash_Table is new Static_HTable (
      Header_Num => Header_Num,
      Element    => Element,
      Elmt_Ptr   => Elmt_Ptr,
      Null_Ptr   => Null_Ptr,
      Set_Next   => Hash_Subprograms.Set_Next,
      Next       => Hash_Subprograms.Next,
      Key        => Key,
      Get_Key    => Hash_Subprograms.Get_Key,
      Hash       => Hash_Subprograms.Hash,
      Equal      => Hash_Subprograms.Equal);

   --  The following table records entities for subprograms that are
   --  eliminated, and corresponding eliminate pragmas that caused the
   --  elimination. Entries in this table are set by Check_Eliminated
   --  and read by Eliminate_Error_Msg.

   type Elim_Entity_Entry is record
      Prag : Node_Id;
      Subp : Entity_Id;
   end record;

   package Elim_Entities is new Table.Table (
     Table_Component_Type => Elim_Entity_Entry,
     Table_Index_Type     => Name_Id'Base,
     Table_Low_Bound      => First_Name_Id,
     Table_Initial        => 50,
     Table_Increment      => 200,
     Table_Name           => "Elim_Entries");

   ----------------------
   -- Check_Eliminated --
   ----------------------

   procedure Check_Eliminated (E : Entity_Id) is
      Elmt : Access_Elim_Data;
      Scop : Entity_Id;
      Form : Entity_Id;
      Up   : Nat;

   begin
      if No_Elimination then
         return;

      --  Elimination of objects and types is not implemented yet

      elsif Ekind (E) not in Subprogram_Kind then
         return;
      end if;

      --  Loop through homonyms for this key

      Elmt := Elim_Hash_Table.Get (Chars (E));
      while Elmt /= null loop
         Check_Homonyms : declare
            procedure Set_Eliminated;
            --  Set current subprogram entity as eliminated

            --------------------
            -- Set_Eliminated --
            --------------------

            procedure Set_Eliminated is
               Overridden : Entity_Id;

            begin
               if Is_Dispatching_Operation (E) then

                  --  If an overriding dispatching primitive is eliminated then
                  --  its parent must have been eliminated. If the parent is an
                  --  inherited operation, check the operation that it renames,
                  --  because flag Eliminated is only set on source operations.

                  Overridden := Overridden_Operation (E);

                  if Present (Overridden)
                    and then not Comes_From_Source (Overridden)
                    and then Present (Alias (Overridden))
                  then
                     Overridden := Alias (Overridden);
                  end if;

                  if Present (Overridden)
                    and then not Is_Eliminated (Overridden)
                    and then not Is_Abstract_Subprogram (Overridden)
                  then
                     Error_Msg_Name_1 := Chars (E);
                     Error_Msg_N ("cannot eliminate subprogram %", E);
                     return;
                  end if;
               end if;

               Set_Is_Eliminated (E);
               Elim_Entities.Append ((Prag => Elmt.Prag, Subp => E));
            end Set_Eliminated;

         --  Start of processing for Check_Homonyms

         begin
            --  First we check that the name of the entity matches

            if Elmt.Entity_Name /= Chars (E) then
               goto Continue;
            end if;

            --  Find enclosing unit, and verify that its name and those of its
            --  parents match.

            Scop := Cunit_Entity (Current_Sem_Unit);

            --  Now see if compilation unit matches

            Up := Elmt.Unit_Name'Last;

            --  If we are within a subunit, the name in the pragma has been
            --  parsed as a child unit, but the current compilation unit is in
            --  fact the parent in which the subunit is embedded. We must skip
            --  the first name which is that of the subunit to match the pragma
            --  specification. Body may be that of a package or subprogram.

            declare
               Par : Node_Id;

            begin
               Par := Parent (E);
               while Present (Par) loop
                  if Nkind (Par) = N_Subunit then
                     if Chars (Defining_Entity (Proper_Body (Par))) =
                                                         Elmt.Unit_Name (Up)
                     then
                        Up := Up - 1;
                        exit;

                     else
                        goto Continue;
                     end if;
                  end if;

                  Par := Parent (Par);
               end loop;
            end;

            for J in reverse Elmt.Unit_Name'First .. Up loop
               if Elmt.Unit_Name (J) /= Chars (Scop) then
                  goto Continue;
               end if;

               Scop := Scope (Scop);

               if Scop /= Standard_Standard and then J = 1 then
                  goto Continue;
               end if;
            end loop;

            if Scop /= Standard_Standard then
               goto Continue;
            end if;

            if Present (Elmt.Entity_Node)
              and then Elmt.Entity_Scope /= null
            then
               --  Check that names of enclosing scopes match. Skip blocks and
               --  wrapper package of subprogram instances, which do not appear
               --  in the pragma.

               Scop := Scope (E);

               for J in reverse  Elmt.Entity_Scope'Range loop
                  while Ekind (Scop) = E_Block
                    or else
                     (Ekind (Scop) = E_Package
                       and then Is_Wrapper_Package (Scop))
                  loop
                     Scop := Scope (Scop);
                  end loop;

                  if Elmt.Entity_Scope (J) /= Chars (Scop) then
                     if Ekind (Scop) /= E_Protected_Type
                       or else Comes_From_Source (Scop)
                     then
                        goto Continue;

                     --  For simple protected declarations, retrieve the source
                     --  name of the object, which appeared in the Eliminate
                     --  pragma.

                     else
                        declare
                           Decl : constant Node_Id :=
                             Original_Node (Parent (Scop));

                        begin
                           if Elmt.Entity_Scope (J) /=
                             Chars (Defining_Identifier (Decl))
                           then
                              if J > 0 then
                                 null;
                              end if;
                              goto Continue;
                           end if;
                        end;
                     end if;

                  end if;

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

            --  If given entity is a library level subprogram and pragma had a
            --  single parameter, a match.

            if Is_Compilation_Unit (E)
              and then Is_Subprogram (E)
              and then No (Elmt.Entity_Node)
            then
               Set_Eliminated;
               return;

               --  Check for case of type or object with two parameter case

            elsif (Is_Type (E) or else Is_Object (E))
              and then Elmt.Result_Type = No_Name
              and then Elmt.Parameter_Types = null
            then
               Set_Eliminated;
               return;

            --  Check for case of subprogram

            elsif Ekind (E) in E_Function | E_Procedure then

               --  If Source_Location present, then see if it matches

               if Elmt.Source_Location /= No_Name then
                  Get_Name_String (Elmt.Source_Location);

                  declare
                     Sloc_Trace : constant String :=
                                    Name_Buffer (1 .. Name_Len);

                     Idx : Natural := Sloc_Trace'First;
                     --  Index in Sloc_Trace, if equals to 0, then we have
                     --  completely traversed Sloc_Trace

                     Last : constant Natural := Sloc_Trace'Last;

                     P      : Source_Ptr;
                     Sindex : Source_File_Index;

                     function File_Name_Match return Boolean;
                     --  This function is supposed to be called when Idx points
                     --  to the beginning of the new file name, and Name_Buffer
                     --  is set to contain the name of the proper source file
                     --  from the chain corresponding to the Sloc of E. First
                     --  it checks that these two files have the same name. If
                     --  this check is successful, moves Idx to point to the
                     --  beginning of the column number.

                     function Line_Num_Match return Boolean;
                     --  This function is supposed to be called when Idx points
                     --  to the beginning of the column number, and P is
                     --  set to point to the proper Sloc the chain
                     --  corresponding to the Sloc of E. First it checks that
                     --  the line number Idx points on and the line number
                     --  corresponding to P are the same. If this check is
                     --  successful, moves Idx to point to the beginning of
                     --  the next file name in Sloc_Trace. If there is no file
                     --  name any more, Idx is set to 0.

                     function Different_Trace_Lengths return Boolean;
                     --  From Idx and P, defines if there are in both traces
                     --  more element(s) in the instantiation chains. Returns
                     --  False if one trace contains more element(s), but
                     --  another does not. If both traces contains more
                     --  elements (that is, the function returns False), moves
                     --  P ahead in the chain corresponding to E, recomputes
                     --  Sindex and sets the name of the corresponding file in
                     --  Name_Buffer

                     function Skip_Spaces return Natural;
                     --  If Sloc_Trace (Idx) is not space character, returns
                     --  Idx. Otherwise returns the index of the nearest
                     --  non-space character in Sloc_Trace to the right of Idx.
                     --  Returns 0 if there is no such character.

                     -----------------------------
                     -- Different_Trace_Lengths --
                     -----------------------------

                     function Different_Trace_Lengths return Boolean is
                     begin
                        P := Instantiation (Sindex);

                        if (P = No_Location and then Idx /= 0)
                          or else
                           (P /= No_Location and then Idx = 0)
                        then
                           return True;

                        else
                           if P /= No_Location then
                              Sindex := Get_Source_File_Index (P);
                              Get_Name_String (File_Name (Sindex));
                           end if;

                           return False;
                        end if;
                     end Different_Trace_Lengths;

                     ---------------------
                     -- File_Name_Match --
                     ---------------------

                     function File_Name_Match return Boolean is
                        Tmp_Idx : Natural;
                        End_Idx : Natural;

                     begin
                        if Idx = 0 then
                           return False;
                        end if;

                        --  Find first colon. If no colon, then return False.
                        --  If there is a colon, Tmp_Idx is set to point just
                        --  before the colon.

                        Tmp_Idx := Idx - 1;
                        loop
                           if Tmp_Idx >= Last then
                              return False;
                           elsif Sloc_Trace (Tmp_Idx + 1) = ':' then
                              exit;
                           else
                              Tmp_Idx := Tmp_Idx + 1;
                           end if;
                        end loop;

                        --  Find last non-space before this colon. If there is
                        --  no space character before this colon, then return
                        --  False. Otherwise, End_Idx is set to point to this
                        --  non-space character.

                        End_Idx := Tmp_Idx;
                        loop
                           if End_Idx < Idx then
                              return False;

                           elsif Sloc_Trace (End_Idx) /= ' ' then
                              exit;

                           else
                              End_Idx := End_Idx - 1;
                           end if;
                        end loop;

                        --  Now see if file name matches what is in Name_Buffer
                        --  and if so, step Idx past it and return True. If the
                        --  name does not match, return False.

                        if Sloc_Trace (Idx .. End_Idx) =
                           Name_Buffer (1 .. Name_Len)
                        then
                           Idx := Tmp_Idx + 2;
                           Idx := Skip_Spaces;
                           return True;
                        else
                           return False;
                        end if;
                     end File_Name_Match;

                     --------------------
                     -- Line_Num_Match --
                     --------------------

                     function Line_Num_Match return Boolean is
                        N : Nat := 0;

                     begin
                        if Idx = 0 then
                           return False;
                        end if;

                        while Idx <= Last
                           and then Sloc_Trace (Idx) in '0' .. '9'
                        loop
                           N := N * 10 +
                            (Character'Pos (Sloc_Trace (Idx)) -
                             Character'Pos ('0'));
                           Idx := Idx + 1;
                        end loop;

                        if Get_Physical_Line_Number (P) =
                           Physical_Line_Number (N)
                        then
                           while Idx <= Last and then
                              Sloc_Trace (Idx) /= '['
                           loop
                              Idx := Idx + 1;
                           end loop;

                           if Idx <= Last then
                              pragma Assert (Sloc_Trace (Idx) = '[');
                              Idx := Idx + 1;
                              Idx := Skip_Spaces;
                           else
                              Idx := 0;
                           end if;

                           return True;

                        else
                           return False;
                        end if;
                     end Line_Num_Match;

                     -----------------
                     -- Skip_Spaces --
                     -----------------

                     function Skip_Spaces return Natural is
                        Res : Natural;

                     begin
                        Res := Idx;
                        while Sloc_Trace (Res) = ' ' loop
                           Res := Res + 1;

                           if Res > Last then
                              Res := 0;
                              exit;
                           end if;
                        end loop;

                        return Res;
                     end Skip_Spaces;

                  begin
                     P := Sloc (E);
                     Sindex := Get_Source_File_Index (P);
                     Get_Name_String (File_Name (Sindex));

                     Idx := Skip_Spaces;
                     while Idx > 0 loop
                        if not File_Name_Match then
                           goto Continue;
                        elsif not Line_Num_Match then
                           goto Continue;
                        end if;

                        if Different_Trace_Lengths then
                           goto Continue;
                        end if;
                     end loop;
                  end;
               end if;

               --  If we have a Result_Type, then we must have a function with
               --  the proper result type.

               if Elmt.Result_Type /= No_Name then
                  if Ekind (E) /= E_Function
                    or else Chars (Etype (E)) /= Elmt.Result_Type
                  then
                     goto Continue;
                  end if;
               end if;

               --  If we have Parameter_Types, they must match

               if Elmt.Parameter_Types /= null then
                  Form := First_Formal (E);

                  if No (Form)
                    and then Elmt.Parameter_Types'Length = 1
                    and then Elmt.Parameter_Types (1) = No_Name
                  then
                     --  Parameterless procedure matches

                     null;

                  elsif Elmt.Parameter_Types = null then
                     goto Continue;

                  else
                     for J in Elmt.Parameter_Types'Range loop
                        if No (Form)
                          or else
                            Chars (Etype (Form)) /= Elmt.Parameter_Types (J)
                        then
                           goto Continue;
                        else
                           Next_Formal (Form);
                        end if;
                     end loop;

                     if Present (Form) then
                        goto Continue;
                     end if;
                  end if;
               end if;

               --  If we fall through, this is match

               Set_Eliminated;
               return;
            end if;
         end Check_Homonyms;

      <<Continue>>
         Elmt := Elmt.Homonym;
      end loop;

      return;
   end Check_Eliminated;

   -------------------------------------
   -- Check_For_Eliminated_Subprogram --
   -------------------------------------

   procedure Check_For_Eliminated_Subprogram (N : Node_Id; S : Entity_Id) is
      Ultimate_Subp  : constant Entity_Id := Ultimate_Alias (S);
      Enclosing_Subp : Entity_Id;

   begin
      --  No check needed within a default expression for a formal, since this
      --  is not really a use, and the expression (a call or attribute) may
      --  never be used if the enclosing subprogram is itself eliminated.

      if In_Spec_Expression then
         return;
      end if;

      if Is_Eliminated (Ultimate_Subp)
        and then not Inside_A_Generic
        and then not Is_Generic_Unit (Cunit_Entity (Current_Sem_Unit))
      then
         Enclosing_Subp := Current_Subprogram;
         while Present (Enclosing_Subp) loop
            if Is_Eliminated (Enclosing_Subp) then
               return;
            end if;

            Enclosing_Subp := Enclosing_Subprogram (Enclosing_Subp);
         end loop;

         --  Emit error, unless we are within an instance body and the expander
         --  is disabled, indicating an instance within an enclosing generic.
         --  In an instance, the ultimate alias is an internal entity, so place
         --  the message on the original subprogram.

         if In_Instance_Body and then not Expander_Active then
            null;

         elsif Comes_From_Source (Ultimate_Subp) then
            Eliminate_Error_Msg (N, Ultimate_Subp);

         else
            Eliminate_Error_Msg (N, S);
         end if;
      end if;
   end Check_For_Eliminated_Subprogram;

   -------------------------
   -- Eliminate_Error_Msg --
   -------------------------

   procedure Eliminate_Error_Msg (N : Node_Id; E : Entity_Id) is
   begin
      for J in Elim_Entities.First .. Elim_Entities.Last loop
         if E = Elim_Entities.Table (J).Subp then
            Error_Msg_Sloc := Sloc (Elim_Entities.Table (J).Prag);
            Error_Msg_NE ("cannot reference subprogram & eliminated #", N, E);
            return;
         end if;
      end loop;

      --  If this is an internal operation generated for a protected operation,
      --  its name does not match the source name, so just report the error.

      if not Comes_From_Source (E)
        and then Present (First_Entity (E))
        and then Is_Concurrent_Record_Type (Etype (First_Entity (E)))
      then
         Error_Msg_NE
           ("cannot reference eliminated protected subprogram&", N, E);

      --  Otherwise should not fall through, entry should be in table

      else
         Error_Msg_NE
           ("subprogram& is called but its alias is eliminated", N, E);
         --  raise Program_Error;
      end if;
   end Eliminate_Error_Msg;

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

   procedure Initialize is
   begin
      Elim_Hash_Table.Reset;
      Elim_Entities.Init;
      No_Elimination := True;
   end Initialize;

   ------------------------------
   -- Process_Eliminate_Pragma --
   ------------------------------

   procedure Process_Eliminate_Pragma
     (Pragma_Node         : Node_Id;
      Arg_Unit_Name       : Node_Id;
      Arg_Entity          : Node_Id;
      Arg_Parameter_Types : Node_Id;
      Arg_Result_Type     : Node_Id;
      Arg_Source_Location : Node_Id)
   is
      Data : constant Access_Elim_Data := new Elim_Data;
      --  Build result data here

      Elmt : Access_Elim_Data;

      Num_Names : Nat := 0;
      --  Number of names in unit name

      Lit       : Node_Id;
      Arg_Ent   : Entity_Id;
      Arg_Uname : Node_Id;

      function OK_Selected_Component (N : Node_Id) return Boolean;
      --  Test if N is a selected component with all identifiers, or a selected
      --  component whose selector is an operator symbol. As a side effect
      --  if result is True, sets Num_Names to the number of names present
      --  (identifiers, and operator if any).

      ---------------------------
      -- OK_Selected_Component --
      ---------------------------

      function OK_Selected_Component (N : Node_Id) return Boolean is
      begin
         if Nkind (N) = N_Identifier
           or else Nkind (N) = N_Operator_Symbol
         then
            Num_Names := Num_Names + 1;
            return True;

         elsif Nkind (N) = N_Selected_Component then
            return OK_Selected_Component (Prefix (N))
              and then OK_Selected_Component (Selector_Name (N));

         else
            return False;
         end if;
      end OK_Selected_Component;

   --  Start of processing for Process_Eliminate_Pragma

   begin
      Data.Prag := Pragma_Node;
      Error_Msg_Name_1 := Name_Eliminate;

      --  Process Unit_Name argument

      if Nkind (Arg_Unit_Name) = N_Identifier then
         Data.Unit_Name := new Names'(1 => Chars (Arg_Unit_Name));
         Num_Names := 1;

      elsif OK_Selected_Component (Arg_Unit_Name) then
         Data.Unit_Name := new Names (1 .. Num_Names);

         Arg_Uname := Arg_Unit_Name;
         for J in reverse 2 .. Num_Names loop
            Data.Unit_Name (J) := Chars (Selector_Name (Arg_Uname));
            Arg_Uname := Prefix (Arg_Uname);
         end loop;

         Data.Unit_Name (1) := Chars (Arg_Uname);

      else
         Error_Msg_N
           ("wrong form for Unit_Name parameter of pragma%", Arg_Unit_Name);
         return;
      end if;

      --  Process Entity argument

      if Present (Arg_Entity) then
         Num_Names := 0;

         if Nkind (Arg_Entity) = N_Identifier
           or else Nkind (Arg_Entity) = N_Operator_Symbol
         then
            Data.Entity_Name  := Chars (Arg_Entity);
            Data.Entity_Node  := Arg_Entity;
            Data.Entity_Scope := null;

         elsif OK_Selected_Component (Arg_Entity) then
            Data.Entity_Scope := new Names (1 .. Num_Names - 1);
            Data.Entity_Name  := Chars (Selector_Name (Arg_Entity));
            Data.Entity_Node  := Arg_Entity;

            Arg_Ent := Prefix (Arg_Entity);
            for J in reverse 2 .. Num_Names - 1 loop
               Data.Entity_Scope (J) := Chars (Selector_Name (Arg_Ent));
               Arg_Ent := Prefix (Arg_Ent);
            end loop;

            Data.Entity_Scope (1) := Chars (Arg_Ent);

         elsif Is_Config_Static_String (Arg_Entity) then
            Data.Entity_Name := Name_Find;
            Data.Entity_Node := Arg_Entity;

         else
            return;
         end if;
      else
         Data.Entity_Node := Empty;
         Data.Entity_Name := Data.Unit_Name (Num_Names);
      end if;

      --  Process Parameter_Types argument

      if Present (Arg_Parameter_Types) then

         --  Here for aggregate case

         if Nkind (Arg_Parameter_Types) = N_Aggregate then
            Data.Parameter_Types :=
              new Names
                (1 .. List_Length (Expressions (Arg_Parameter_Types)));

            Lit := First (Expressions (Arg_Parameter_Types));
            for J in Data.Parameter_Types'Range loop
               if Is_Config_Static_String (Lit) then
                  Data.Parameter_Types (J) := Name_Find;
                  Next (Lit);
               else
                  return;
               end if;
            end loop;

         --  Otherwise we must have case of one name, which looks like a
         --  parenthesized literal rather than an aggregate.

         elsif Paren_Count (Arg_Parameter_Types) /= 1 then
            Error_Msg_N
              ("wrong form for argument of pragma Eliminate",
               Arg_Parameter_Types);
            return;

         elsif Is_Config_Static_String (Arg_Parameter_Types) then
            String_To_Name_Buffer (Strval (Arg_Parameter_Types));

            if Name_Len = 0 then

               --  Parameterless procedure

               Data.Parameter_Types := new Names'(1 => No_Name);

            else
               Data.Parameter_Types := new Names'(1 => Name_Find);
            end if;

         else
            return;
         end if;
      end if;

      --  Process Result_Types argument

      if Present (Arg_Result_Type) then
         if Is_Config_Static_String (Arg_Result_Type) then
            Data.Result_Type := Name_Find;
         else
            return;
         end if;

      --  Here if no Result_Types argument

      else
         Data.Result_Type := No_Name;
      end if;

      --  Process Source_Location argument

      if Present (Arg_Source_Location) then
         if Is_Config_Static_String (Arg_Source_Location) then
            Data.Source_Location := Name_Find;
         else
            return;
         end if;
      else
         Data.Source_Location := No_Name;
      end if;

      Elmt := Elim_Hash_Table.Get (Hash_Subprograms.Get_Key (Data));

      --  If we already have an entry with this same key, then link
      --  it into the chain of entries for this key.

      if Elmt /= null then
         Data.Homonym := Elmt.Homonym;
         Elmt.Homonym := Data;

      --  Otherwise create a new entry

      else
         Elim_Hash_Table.Set (Data);
      end if;

      No_Elimination := False;
   end Process_Eliminate_Pragma;

end Sem_Elim;
