------------------------------------------------------------------------------
--                                                                          --
--                 ASIS-for-GNAT IMPLEMENTATION COMPONENTS                  --
--                                                                          --
--                       A 4 G . E N C L _ E L _ O L D                      --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision: 1.41 $
--                                                                          --
--            Copyright (c) 1995-2002, Free Software Foundation, Inc.       --
--                                                                          --
-- ASIS-for-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 --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version. ASIS-for-GNAT is distributed  in the hope  that it will be use- --
-- ful, but WITHOUT ANY WARRANTY; without even the implied warranty of MER- --
-- CHANTABILITY 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 ASIS-for-GNAT; see file     --
-- COPYING. If not, write to the Free Software Foundation,  59 Temple Place --
-- - Suite 330,  Boston, MA 02111-1307, USA.                                --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- ASIS-for-GNAT was originally developed  by the ASIS-for-GNAT team at the --
-- Software  Engineering  Laboratory  of  the Swiss  Federal  Institute  of --
-- Technology (LGL-EPFL) in Lausanne,  Switzerland, in cooperation with the --
-- Scientific  Research  Computer  Center of  Moscow State University (SRCC --
-- MSU), Russia,  with funding partially provided  by grants from the Swiss --
-- National  Science  Foundation  and  the  Swiss  Academy  of  Engineering --
-- Sciences.  ASIS-for-GNAT is now maintained by  Ada Core Technologies Inc --
-- (http://www.gnat.com).                                                   --
--                                                                          --
------------------------------------------------------------------------------

with System.Assertions;
with Ada.Exceptions;

with Asis.Exceptions;  use Asis.Exceptions;

with Asis.Set_Get;     use Asis.Set_Get;
with A4G.Int_Knds;     use A4G.Int_Knds;
with A4G.A_Types;      use A4G.A_Types;
with A4G.Mapping;      use A4G.Mapping;
with A4G.Vcheck;       use A4G.Vcheck;
with A4G.Nencl_El;     use A4G.Nencl_El;

with Types;            use Types;
with Atree;            use Atree;
with Sinfo;            use Sinfo;
with Einfo;            use Einfo;
with Nlists;           use Nlists;

package body A4G.Encl_El_Old is

   --  !!!??? This file is '-gnatg-compilable', but both its content and its
   --  !!!???  documentation need revising

   --  !!!! When (and if) the implementation of Enclosing_Element is
   --  !!!! rewritten ot top of Traverse_Element, the global variable
   --  !!!! A4G.Mapping.Parent_Node should be hidden in the body of the
   --  !!!! A4G.Mapping package!!!


   LT : String renames A4G.A_Types.ASIS_Line_Terminator;

--------------------------------------------------------------------------
--       The general structure of Enclosing Element retrieval           --
--------------------------------------------------------------------------

--  The Enclosing Element retrieval is performed separately for explicit
--  and for implicit constructs as well as for constructs that are and are
--  not parts of generic expansions]

--------------------------------------------------------------------
--      The Enclosing Element retrieval for explicit constructs,  --
--      [which are not Is_Part_Of_Instance]                       --
--------------------------------------------------------------------

--  The general structure and implementation technique is similar to the
--  PART ONE of the package Asis_Vendor_Primitives.Gnat_To_Asis_Mapping

--  The Enclosing Element retrieval for explicit constructs is implemented
--  by means of two-level table-driven switching.
--
--  The first switch distinguishs the three trivial cases: when the
--  Atree.Parent function could be used to obtain the Node for the result
--  element and the general Node_To_Element constructor could be used after
--  that, when the Enclosing Element is based on the same tree node,
--  but is of some other kind or when the Enclosing Element is definitely
--  a Asis.Nil_Element, and some non-trivial cases. It also filters
--  Internal_Element_Kinds values for which the local enclosing element
--  construction items have not been defined/implemented yet.
--
--  The second switch selects functions which define the The Enclosing
--  Element construction in non-trivial cases.
--
--  Both switches are implemented as one-dimention array objects indexed
--  by the Internal_Element_Kinds type. Tne component type of the first
--  switch is also the Internal_Element_Kinds type. The component type of
--  the second switch is an access_to_function type. For each
--  Internal_Element_Kinds values requiring non-trivial construction
--  of the corresponding Enclosing Enclosing Element it contains the
--  access to the corresponding Enclosing Element construction function as
--  its component. It is erroneous to obtain and to use any information
--  (access to function) for all the other Node_Kind values (which should
--  be filtered out by the first swithch as trivial or non-implemented.)
--  It also contains the access to the special function
--  Not_Implemented_Enclosing Element for the Internal_Element_Kinds
--  values, for which it is already known, that the correcponding
--  Enclosing Element construction is nontrivial, but the real function
--  for this item has not been implemented yet.

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

   procedure Skip_Implicit_Subtype (Constr : in out Node_Id);
   --  Supposing that Constr is a constraint, this procedure checks if the
   --  parent node for it points to implicit subtype created in case if
   --  this constraint is used directly in object declaration, and if
   --  so, resets Constr to point to the constraint from the object
   --  declaration

   function Parent (Node : Node_Id) return Node_Id;
   --  this function is the modifiaction of Atree.Parent. It is able
   --  to deal in the "ASIS mode" with the sequences of one-identifier
   --  declarations/with clauses resulting from the normalization of
   --  multi-name declarations/with clauses which is done by the
   --  compiler

   ------------
   -- Parent --
   ------------

   function Parent (Node : Node_Id) return Node_Id is
      Result_Node : Node_Id;
   begin
      Result_Node := Atree.Parent (Node);
      Skip_Normalized_Declarations_Back (Result_Node);
      return Result_Node;
   end Parent;

   ---------------------------
   -- Skip_Implicit_Subtype --
   ---------------------------

   procedure Skip_Implicit_Subtype (Constr : in out Node_Id) is
   begin

      if not Comes_From_Source (Parent (Constr)) then

         Constr := Parent (Constr);

         while Nkind (Constr) /= N_Object_Declaration loop
            Constr := Next_Non_Pragma (Constr);
         end loop;

         Constr := Object_Definition (Constr);

      end if;
   end Skip_Implicit_Subtype;

--------------------------------------------------------------------------
--                LOCAL TYPES, DATA AND FUNCTIONS
--------------------------------------------------------------------------

--------------------------------------------------------------------------
--    ASIS_Internal_Element_Kinds.Internal_Element_Kinds-based
--    packaging and documentation
--------------------------------------------------------------------------

--------------------------------------------------------------------------
--   Enclosing Element for Explicits - First Switch
--------------------------------------------------------------------------

--  The meaning of the componrents of the first switch is as follows:
--
--   Not_An_Element       => Asis.Nil_Element should be returtned
--                           as Enclosed Element;
--
--   Trivial_Mapping      => generally
--                           Node_To_Element (
--                               Node    => Atree.Parent (R_Node (Element)),
--                               In_Unit => Encl_Unit  (Element)) call
--                            could be used to get the Enclosing Element,
--                            but sometimes we have to go more then one step
--                            more up in the tree to skip a node for which
--                            no Element could be cretated, for example,
--                            for a declaration enclosed in a package, we have
--                            to go up twice, because the first step gives
--                            only a node of  N_Package_Specification kind,
--                            which is of no use in ASIS, and only the second
--                            step will give the required node of
--                            N_Package_Declaration kind. So we have a
--                            special function named General_Encl_Elem
--                            to handle such cases
--
--
--   No_Mapping           => to be set at least for the special values
--                           added to the Internal_Element_Kinds literals
--                           to organize the Node_to_Element and
--                           Enclosind Elemen switches.
--                           Some other use could be possible (??)
--
--   Non_Trivial_Mapping  => it is known for sure that special function is
--                           needed to get the Enclosing Element. This
--                           function should be selected on the base of
--            second switch, but until the whole function is
--            completely implemented, the second switch may
--            get the reference to the function
--            corresponding to the non-implemented
--            non-trivial mapping, which raises an
--            exception.
--
--   Not_Implemented_Mapping => it means what is sounds
--
--   all the other values => the Enclosing Element for the Element of the
--                           corresponding index-value-kind is based on the
--                           same node, but is of component-value-kind
--                            Node_To_Element (
--                               Node          => R_Node (Element),
--                               Internal_Kind => Component_Value
--                               In_Unit       => Encl_Unit  (Element))
--                           call can be used.
--

   Enclosing_Element_For_Explicits_First_Switch :
      array (Internal_Element_Kinds) of Internal_Element_Kinds :=
(
--   type Internal_Element_Kinds is (
--
Not_An_Element   => Not_An_Element,
--  Asis.Nil_Element should be returned as the
--  Enclosing for the Asis.Nil_Element, should not it???
--
------------------------------------------------------------------------------
--
--  --  A_Pragma,                  -- Asis.Elements
--
------------------------------------------------------------------------------
--
An_All_Calls_Remote_Pragma ..
--     An_Asynchronous_Pragma,
--     An_Atomic_Pragma,
--     An_Atomic_Components_Pragma,
--     An_Attach_Handler_Pragma,
--     A_Controlled_Pragma,
--     A_Convention_Pragma,
--     A_Discard_Names_Pragma,
--     An_Elaborate_Pragma,
--     An_Elaborate_All_Pragma,
--     An_Elaborate_Body_Pragma,
--     An_Export_Pragma,
--     An_Import_Pragma,
--     An_Inline_Pragma,
--     An_Inspection_Point_Pragma,
--     An_Interrupt_Handler_Pragma,
--     An_Interrupt_Priority_Pragma,
--     A_Linker_Options_Pragma
--     A_List_Pragma,
--     A_Locking_Policy_Pragma,
--     A_Normalize_Scalars_Pragma,
--     An_Optimize_Pragma,
--     A_Pack_Pragma,
--     A_Page_Pragma,
--     A_Preelaborate_Pragma,
--     A_Priority_Pragma,
--     A_Pure_Pragma,
--     A_Queuing_Policy_Pragma,
--     A_Remote_Call_Interface_Pragma,
--     A_Remote_Types_Pragma,
--     A_Restrictions_Pragma,
--     A_Reviewable_Pragma,
--     A_Shared_Passive_Pragma,
--     A_Storage_Size_Pragma,
--     A_Suppress_Pragma,
--     A_Task_Dispatching_Policy_Pragma,
--     A_Volatile_Pragma,
--     A_Volatile_Components_Pragma,
--
--     An_Implementation_Defined_Pragma,
--
An_Unknown_Pragma        => Non_Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  --  A_Defining_Name,           -- Asis.Declarations
--
------------------------------------------------------------------------------
--
A_Defining_Identifier          => Non_Trivial_Mapping,
A_Defining_Character_Literal   => An_Enumeration_Literal_Specification,
A_Defining_Enumeration_Literal => An_Enumeration_Literal_Specification,
--
--  --  A_Defining_Operator_Symbol  => Non_Trivial_Mapping
--
A_Defining_And_Operator ..
--        A_Defining_Or_Operator,
--        A_Defining_Xor_Operator,
--        A_Defining_Equal_Operator,
--        A_Defining_Not_Equal_Operator,
--        A_Defining_Less_Than_Operator,
--        A_Defining_Less_Than_Or_Equal_Operator,
--        A_Defining_Greater_Than_Operator,
--        A_Defining_Greater_Than_Or_Equal_Operator,
--        A_Defining_Plus_Operator,
--        A_Defining_Minus_Operator,
--        A_Defining_Concatenate_Operator,
--        A_Defining_Unary_Plus_Operator,
--        A_Defining_Unary_Minus_Operator,
--        A_Defining_Multiply_Operator,
--        A_Defining_Divide_Operator,
--        A_Defining_Mod_Operator,
--        A_Defining_Rem_Operator,
--        A_Defining_Exponentiate_Operator,
--        A_Defining_Abs_Operator,
A_Defining_Not_Operator            => Non_Trivial_Mapping,

A_Defining_Expanded_Name           => Non_Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  --  A_Declaration,             -- Asis.Declarations
--
------------------------------------------------------------------------------
--
An_Ordinary_Type_Declaration ..
--     A_Task_Type_Declaration,
--     A_Protected_Type_Declaration,
--     An_Incomplete_Type_Declaration,
--     A_Private_Type_Declaration,
--     A_Private_Extension_Declaration,
--
--     A_Subtype_Declaration,
--
--     A_Variable_Declaration,
--     A_Constant_Declaration,
--     A_Deferred_Constant_Declaration,
--     A_Single_Task_Declaration,
--     A_Single_Protected_Declaration,
--
--     An_Integer_Number_Declaration,
A_Real_Number_Declaration                => Trivial_Mapping,
--
An_Enumeration_Literal_Specification     => Non_Trivial_Mapping,
--  is it really so?
--
A_Discriminant_Specification             => Non_Trivial_Mapping,

A_Component_Declaration                  => Non_Trivial_Mapping,

A_Loop_Parameter_Specification           => Non_Trivial_Mapping,

A_Procedure_Declaration                  => Non_Trivial_Mapping,
A_Function_Declaration                   => Non_Trivial_Mapping,
--
A_Parameter_Specification                => Non_Trivial_Mapping,
--
A_Procedure_Body_Declaration             => Non_Trivial_Mapping,
A_Function_Body_Declaration              => Non_Trivial_Mapping,

A_Package_Declaration                    => Non_Trivial_Mapping,
A_Package_Body_Declaration               => Non_Trivial_Mapping,

An_Object_Renaming_Declaration           => Trivial_Mapping,
An_Exception_Renaming_Declaration        => Trivial_Mapping,
A_Package_Renaming_Declaration           => Non_Trivial_Mapping,
A_Procedure_Renaming_Declaration         => Non_Trivial_Mapping,
A_Function_Renaming_Declaration          => Non_Trivial_Mapping,
A_Generic_Package_Renaming_Declaration   => Non_Trivial_Mapping,
A_Generic_Procedure_Renaming_Declaration => Non_Trivial_Mapping,
A_Generic_Function_Renaming_Declaration  => Non_Trivial_Mapping,

A_Task_Body_Declaration                  => Non_Trivial_Mapping,
A_Protected_Body_Declaration             => Non_Trivial_Mapping,

An_Entry_Declaration                     => Non_Trivial_Mapping,

An_Entry_Body_Declaration                => Trivial_Mapping,
An_Entry_Index_Specification             => Trivial_Mapping,

A_Procedure_Body_Stub                    => Trivial_Mapping,
A_Function_Body_Stub                     => Trivial_Mapping,
A_Package_Body_Stub                      => Trivial_Mapping,
A_Task_Body_Stub                         => Trivial_Mapping,
A_Protected_Body_Stub                    => Trivial_Mapping,

An_Exception_Declaration                 => Trivial_Mapping,
A_Choice_Parameter_Specification         => Trivial_Mapping,
--
A_Generic_Procedure_Declaration          => Non_Trivial_Mapping,
A_Generic_Function_Declaration           => Non_Trivial_Mapping,
A_Generic_Package_Declaration            => Non_Trivial_Mapping,

A_Package_Instantiation                  => Non_Trivial_Mapping,
A_Procedure_Instantiation                => Non_Trivial_Mapping,
A_Function_Instantiation                 => Non_Trivial_Mapping,

A_Formal_Object_Declaration              => Trivial_Mapping,
A_Formal_Type_Declaration                => Trivial_Mapping,
A_Formal_Procedure_Declaration           => Trivial_Mapping,
A_Formal_Function_Declaration            => Trivial_Mapping,
A_Formal_Package_Declaration             => Trivial_Mapping,
A_Formal_Package_Declaration_With_Box    => Trivial_Mapping,

------------------------------------------------------------------------------
--
--  --  A_Definition,              -- Asis.Definitions
--
------------------------------------------------------------------------------
--
--  --  A_Type_Definition,
--
A_Derived_Type_Definition               => Trivial_Mapping,
A_Derived_Record_Extension_Definition   => Trivial_Mapping,

--
An_Enumeration_Type_Definition          => Non_Trivial_Mapping,
--
A_Signed_Integer_Type_Definition        => Trivial_Mapping,
A_Modular_Type_Definition               => Trivial_Mapping,
--
--  --     A_Root_Type_Definition,             ----- #########
--
--           A_Root_Integer_Definition,       ----- #########
--           A_Root_Real_Definition,          ----- #########
--           A_Root_Fixed_Definition,         ----- #########
--
--           A_Universal_Integer_Definition,  ----- #########
--           A_Universal_Real_Definition,     ----- #########
--           A_Universal_Fixed_Definition,    ----- #########
--
--
A_Floating_Point_Definition             => Trivial_Mapping,
--
An_Ordinary_Fixed_Point_Definition      => Trivial_Mapping,
A_Decimal_Fixed_Point_Definition        => Trivial_Mapping,
--
An_Unconstrained_Array_Definition       => Trivial_Mapping,
A_Constrained_Array_Definition          => Trivial_Mapping,
--
A_Record_Type_Definition                => Trivial_Mapping, -- ???
A_Tagged_Record_Type_Definition         => Trivial_Mapping, -- ???
--
--  --     An_Access_Type_Definition,
--
A_Pool_Specific_Access_To_Variable      => Trivial_Mapping,
An_Access_To_Variable                   => Trivial_Mapping,
An_Access_To_Constant                   => Trivial_Mapping,
--
An_Access_To_Procedure                  => Trivial_Mapping,
An_Access_To_Protected_Procedure        => Trivial_Mapping,
An_Access_To_Function                   => Trivial_Mapping,
An_Access_To_Protected_Function         => Trivial_Mapping,
--
--
A_Subtype_Indication                    => Non_Trivial_Mapping,
--
--  --  A_Constraint,
--
A_Range_Attribute_Reference             => Trivial_Mapping,    --  ???
A_Simple_Expression_Range               => Non_Trivial_Mapping,
A_Digits_Constraint                     => Trivial_Mapping,
A_Delta_Constraint                      => Trivial_Mapping,
An_Index_Constraint                     => Non_Trivial_Mapping,
A_Discriminant_Constraint               => Non_Trivial_Mapping,
--
A_Component_Definition                  => Trivial_Mapping,
--
--  --  A_Discrete_Subtype_Definition,
--
A_Discrete_Subtype_Indication_As_Subtype_Definition        => Trivial_Mapping,
A_Discrete_Range_Attribute_Reference_As_Subtype_Definition => Trivial_Mapping,
A_Discrete_Simple_Expression_Range_As_Subtype_Definition   => Trivial_Mapping,
--
--  --  A_Discrete_Range,
--
A_Discrete_Subtype_Indication        => Non_Trivial_Mapping,
A_Discrete_Range_Attribute_Reference => Non_Trivial_Mapping,
A_Discrete_Simple_Expression_Range   => Non_Trivial_Mapping,
--
--
An_Unknown_Discriminant_Part     => Non_Trivial_Mapping,
A_Known_Discriminant_Part        => Non_Trivial_Mapping,
--
A_Record_Definition              => Non_Trivial_Mapping,
A_Null_Record_Definition         => Non_Trivial_Mapping,
--
A_Null_Component                 => Non_Trivial_Mapping,
A_Variant_Part                   => Non_Trivial_Mapping,
A_Variant                        => Trivial_Mapping,
--
An_Others_Choice                 => Non_Trivial_Mapping,
--
A_Private_Type_Definition        => A_Private_Type_Declaration,
A_Tagged_Private_Type_Definition => A_Private_Type_Declaration,
A_Private_Extension_Definition   => A_Private_Extension_Declaration,
--
A_Task_Definition                => Trivial_Mapping,
A_Protected_Definition           => Non_Trivial_Mapping,
--
--  --  A_Formal_Type_Definition,
--
A_Formal_Private_Type_Definition ..
--        A_Formal_Tagged_Private_Type_Definition,
--
--        A_Formal_Derived_Type_Definition,
--
--        A_Formal_Discrete_Type_Definition,
--
--        A_Formal_Signed_Integer_Type_Definition,
--        A_Formal_Modular_Type_Definition,
--
--        A_Formal_Floating_Point_Definition,
--
--        A_Formal_Ordinary_Fixed_Point_Definition,
--        A_Formal_Decimal_Fixed_Point_Definition,
--
--        A_Formal_Unconstrained_Array_Definition,
--        A_Formal_Constrained_Array_Definition,
--
--  --     A_Formal_Access_Type_Definition,
--
--           A_Formal_Pool_Specific_Access_To_Variable,
--           A_Formal_Access_To_Variable,
--           A_Formal_Access_To_Constant,
--
--           A_Formal_Access_To_Procedure,
--           A_Formal_Access_To_Protected_Procedure,
--           A_Formal_Access_To_Function,
A_Formal_Access_To_Protected_Function           => Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  --  An_Expression,             -- Asis.Expressions        --##########
--
------------------------------------------------------------------------------
--
An_Integer_Literal     => Non_Trivial_Mapping,
A_Real_Literal         => Non_Trivial_Mapping,

A_String_Literal       => Non_Trivial_Mapping,
An_Identifier          => Non_Trivial_Mapping,
--
--  --  An_Operator_Symbol,
--
An_And_Operator ..
--           An_Or_Operator,
--           An_Xor_Operator,
--           An_Equal_Operator,
--           A_Not_Equal_Operator,
--           A_Less_Than_Operator,
--           A_Less_Than_Or_Equal_Operator,
--           A_Greater_Than_Operator,
--           A_Greater_Than_Or_Equal_Operator,
--           A_Plus_Operator,
--           A_Minus_Operator,
--           A_Concatenate_Operator,
--           A_Unary_Plus_Operator,
--           A_Unary_Minus_Operator,
--           A_Multiply_Operator,
--           A_Divide_Operator,
--           A_Mod_Operator,
--           A_Rem_Operator,
--           An_Exponentiate_Operator,
--           An_Abs_Operator,
--   A_Not_Operator        => A_Function_Call,
A_Not_Operator        => Non_Trivial_Mapping,
--
--  A_Character_Literal ..
--  --     An_Enumeration_Literal,
--  An_Explicit_Dereference  => Trivial_Mapping,
--
--  A_Function_Call          => Non_Trivial_Mapping,
--  --
--  An_Indexed_Component  ..
--  A_Slice                  => Trivial_Mapping,
--  A_Selected_Component     => Non_Trivial_Mapping,
--  --
--  --     -- ??? Not_An_Attribute,
--  --  -- An_Attribute_Reference  => Non_Trivial_Mapping,
--  --
--  An_Access_Attribute ..
--  --          An_Address_Attribute,
--  --          An_Adjacent_Attribute,
--  --          An_Aft_Attribute,
--  --          An_Alignment_Attribute,
--  --          A_Base_Attribute,
--  --          A_Bit_Order_Attribute,
--  --          A_Body_Version_Attribute,
--  --          A_Callable_Attribute,
--  --          A_Caller_Attribute,
--  --          A_Ceiling_Attribute,
--  --          A_Class_Attribute,
--  --          A_Component_Size_Attribute,
--  --          A_Compose_Attribute,
--  --          A_Constrained_Attribute,
--  --          A_Copy_Sign_Attribute,
--  --          A_Count_Attribute,
--  --          A_Definite_Attribute,
--  --          A_Delta_Attribute,
--  --          A_Denorm_Attribute,
--  --          A_Digits_Attribute,
--  --          An_Exponent_Attribute,
--  --          An_External_Tag_Attribute,
--  --          A_First_Attribute,
--  --          A_First_Bit_Attribute,
--  --          A_Floor_Attribute,
--  --          A_Fore_Attribute,
--  --          A_Fraction_Attribute,
--  --          An_Identity_Attribute,
--  --          An_Image_Attribute,
--  --          An_Input_Attribute,
--  --          A_Last_Attribute,
--  --          A_Last_Bit_Attribute,
--  --          A_Leading_Part_Attribute,
--  --          A_Length_Attribute,
--  --          A_Machine_Attribute,
--  --          A_Machine_Emax_Attribute,
--  --          A_Machine_Emin_Attribute,
--  --          A_Machine_Mantissa_Attribute,
--  --          A_Machine_Overflows_Attribute,
--  --          A_Machine_Radix_Attribute,
--  --          A_Machine_Rounds_Attribute,
--  --          A_Max_Attribute,
--  --          A_Max_Size_In_Storage_Elements_Attribute,
--  --          A_Min_Attribute,
--  --          A_Model_Attribute,
--  --          A_Model_Emin_Attribute,
--  --          A_Model_Epsilon_Attribute,
--  --          A_Model_Mantissa_Attribute,
--  --          A_Model_Small_Attribute,
--  --          A_Modulus_Attribute,
--  --          An_Output_Attribute,
--  --          A_Partition_ID_Attribute,
--  --          A_Pos_Attribute,
--  --          A_Position_Attribute,
--  --          A_Pred_Attribute,
--  --          A_Range_Attribute,
--  --          A_Read_Attribute,
--  --          A_Remainder_Attribute,
--  --          A_Round_Attribute,
--  --          A_Rounding_Attribute,
--  --          A_Safe_First_Attribute,
--  --          A_Safe_Last_Attribute,
--  --          A_Scale_Attribute,
--  --          A_Scaling_Attribute,
--  --          A_Signed_Zeros_Attribute,
--  --          A_Size_Attribute,
--  --          A_Small_Attribute,
--  --          A_Storage_Pool_Attribute,
--  --          A_Storage_Size_Attribute,
--  --
--  --          A_Succ_Attribute,
--  --          A_Tag_Attribute,
--  --          A_Terminated_Attribute,
--  --          A_Truncation_Attribute,
--  --          An_Unbiased_Rounding_Attribute,
--  --          An_Unchecked_Access_Attribute,
--  --          A_Val_Attribute,
--  --          A_Valid_Attribute,
--  --          A_Value_Attribute,
--  --          A_Version_Attribute,
--  --          A_Wide_Image_Attribute,
--  --          A_Wide_Value_Attribute,
--  --          A_Wide_Width_Attribute,
--  --          A_Width_Attribute,
--  --          A_Write_Attribute,
--  --
--  --          An_Implementation_Defined_Attribute,  -- Vendor Annex M
--  An_Unknown_Attribute   => Non_Trivial_Mapping,
--
--  --     A_Record_Aggregate,
--  --     An_Extension_Aggregate,
--  --     A_Positional_Array_Aggregate,
--  --     A_Named_Array_Aggregate,
--  --
--  --     An_And_Then_Short_Circuit,
--  --     An_Or_Else_Short_Circuit,
--  --
--  --     An_In_Range_Membership_Test,
--  --     A_Not_In_Range_Membership_Test,
--  --     An_In_Type_Membership_Test,
--   --     A_Not_In_Type_Membership_Test,
--   --
--   --     A_Null_Literal,
--   --     A_Parenthesized_Expression,
--   --
--   --     A_Type_Conversion,
--   --     A_Qualified_Expression,
--   --
--   --     An_Allocation_From_Subtype,
--  An_Allocation_From_Qualified_Expression => Trivial_Mapping,

A_Character_Literal ..
An_Allocation_From_Qualified_Expression => Non_Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  --  An_Association,            -- Asis.Expressions
--
------------------------------------------------------------------------------
--
A_Pragma_Argument_Association      => Trivial_Mapping,
A_Discriminant_Association         => Non_Trivial_Mapping,
A_Record_Component_Association     => Trivial_Mapping,
An_Array_Component_Association     => Non_Trivial_Mapping,

A_Parameter_Association            => Non_Trivial_Mapping,

A_Generic_Association              => Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  --  A_Statement,               -- Asis.Statements
--
--  All subordinates of A_Statement kind require non trivial processing,
--  this processing is the same for all of them except
--  A_Terminate_Alternative_Statement
------------------------------------------------------------------------------
--
A_Null_Statement ..
--     An_Assignment_Statement,
--     An_If_Statement,
--     A_Case_Statement,
--
--     A_Loop_Statement,
--     A_While_Loop_Statement,
--     A_For_Loop_Statement,
--
--     A_Block_Statement,
--     An_Exit_Statement,
--     A_Goto_Statement,
--
--     A_Procedure_Call_Statement,
--     A_Return_Statement,
--
--     An_Accept_Statement,
--     An_Entry_Call_Statement,
--
--     A_Requeue_Statement,
--     A_Requeue_Statement_With_Abort,
--
--     A_Delay_Until_Statement,
--     A_Delay_Relative_Statement,
--
--     A_Terminate_Alternative_Statement,
--     A_Selective_Accept_Statement,
--     A_Timed_Entry_Call_Statement,
--     A_Conditional_Entry_Call_Statement,
--     An_Asynchronous_Select_Statement,
--
--     An_Abort_Statement,
--     A_Raise_Statement,
A_Code_Statement               => Non_Trivial_Mapping,
--
------------------------------------------------------------------------------
--  Path_Kinds
--  Literals                        -- Ada RM 95
--
--  Detailed classification for
--  ASIS_Element_Kinds.Element_Kinds(A_Path) literal
--  corresponds to subtype Internal_Path_Kinds
------------------------------------------------------------------------------

An_If_Path        => An_If_Statement,
An_Elsif_Path     => Trivial_Mapping,
An_Else_Path      => Non_Trivial_Mapping,
A_Case_Path       => Trivial_Mapping,
A_Select_Path     => Trivial_Mapping,
An_Or_Path        => Trivial_Mapping,
A_Then_Abort_Path => Trivial_Mapping,
--
------------------------------------------------------------------------------
--
--  -- A_Clause,                  -- Asis.Clauses
--
------------------------------------------------------------------------------
--
A_Use_Package_Clause => Non_Trivial_Mapping,
A_Use_Type_Clause    => Non_Trivial_Mapping,
A_With_Clause        => Not_An_Element,
--
--  --  A_Representation_Clause,
--
An_Attribute_Definition_Clause       => Non_Trivial_Mapping,
An_Enumeration_Representation_Clause => Trivial_Mapping,
A_Record_Representation_Clause       => Trivial_Mapping,
An_At_Clause                         => Trivial_Mapping,
--
--
A_Component_Clause                   => Trivial_Mapping,
--
------------------------------------------------------------------------------
--
An_Exception_Handler      => Non_Trivial_Mapping,
--
------------------------------------------------------------------------------
--  Special values added for Node -> Element and
--  Element -> Enclosing Element switchings,
------------------------------------------------------------------------------

Non_Trivial_Mapping     => No_Mapping,
Not_Implemented_Mapping => No_Mapping,
Trivial_Mapping         => No_Mapping,
No_Mapping              => No_Mapping,

others                  => Not_Implemented_Mapping
   );


--------------------------------------------------------------------------
--   Enclosing Element for Explicits - Second Switch
--------------------------------------------------------------------------

   type Enclosing_Element_Construction_For_Explicits_Items is access
     function (Element : Asis.Element) return Asis.Element;
--
--  access to the local items of the constructing the Enclosing Elements
--  for Explicit constructs
--
--  The Enclosing_Element_For_Explicits_First_Switch array object is
--  defined after the definitions of all local construction items to allow
--  the initialization to be performed in its definition.

----------------------------------------------------
-- Function beind accessed from the second switch --
----------------------------------------------------

   procedure No_Enclosing_Element (Element_Kind : Internal_Element_Kinds);
   --  Should be called only in erroneous situations, when no Enclosing_Element
   --  can correspond to a given Element. Raises ASIS_FAiled with the
   --  coresponding Diagnosis

   function Not_Implemented_Enclosing_Element_Construction
       (Element : Asis.Element) return Asis.Element;
   procedure Not_Implemented_Enclosing_Element_Construction
       (Element : Asis.Element);
   --  Placeholders for "ohters" choice

   function General_Encl_Elem (Element : Asis.Element) return Asis.Element;
   --  Computes Enclosing_Element for most common cases

   --  The functions below computes Enclosing_Elememnt for specific Element
   --  kinds; the corresponding situations cannot be covered by
   --  General_Encl_Elem

   function A_Pragma_Enclosing (Element : Asis.Element) return Asis.Element;

   function A_Defining_Identifier_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Defining_Operator_Symbol_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Enumeration_Literal_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Discriminant_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Loop_Parameter_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Parameter_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Enumeration_Type_Definition_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Subtype_Indication_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Simple_Expression_Range_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Discrete_Range_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Discriminant_Part_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Record_Definition_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Null_Component_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Variant_Part_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Others_Choice_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function A_Statement_Enclosing
     (Element : Asis.Element)
      return Asis.Element;
   function A_Terminate_Alternative_Statement_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Else_Path_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Attribute_Definition_Clause_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function An_Exception_Handler_Enclosing
     (Element : Asis.Element)
      return Asis.Element;

   function Possible_C_U_Enclosing
     (Element : Asis.Element)
      return Asis.Element;
   --  Called in a situation when Enclosing_Element may have to be Nil_Element,
   --  because we may reach the very top of the Element hierarchy of an ASIS
   --  Compilation_Unit, so logically the next step up should be from Elements
   --  into enclosing unit.

   --------------------------------------------------------------------------
   procedure No_Enclosing_Element (Element_Kind : Internal_Element_Kinds) is
   begin
      Raise_ASIS_Failed (Diagnosis => "No Enclosing Element can correspond "
                                   &  "to the Element with "
                                   &  "Internal_Element_Kinds value of "
                                   &   Internal_Element_Kinds'Image
                                       (Element_Kind));
   end No_Enclosing_Element;
   --------------------------------------------------------------------------

   function Not_Implemented_Enclosing_Element_Construction
       (Element : Asis.Element) return Asis.Element is
   begin
      Not_Implemented_Yet (Diagnosis =>
                        "Enclosing Element retrieval for the explicit Element "
                      &  "of the " &  Internal_Element_Kinds'Image
                      (Int_Kind (Element)) & " kind "
                      & "has not been implemented yet");
      return Asis.Nil_Element; -- to make the code syntactically correct;
   end Not_Implemented_Enclosing_Element_Construction;
   --------------------------------------------------------------------------

   procedure Not_Implemented_Enclosing_Element_Construction
       (Element : Asis.Element) is
   begin
      Not_Implemented_Yet (Diagnosis =>
                        "Enclosing Element retrieval for the explicit Element "
                      &  "of the " &  Internal_Element_Kinds'Image
                      (Int_Kind (Element)) & " kind "
                      & "has not been implemented yet");
   end Not_Implemented_Enclosing_Element_Construction;

   pragma No_Return (Not_Implemented_Enclosing_Element_Construction);

   function General_Encl_Elem (Element : Asis.Element) return Asis.Element is
      Result_Node  : Node_Id;
      Result_Nkind : Node_Kind;
   begin
      Result_Node  := Parent (R_Node (Element));
      Result_Nkind := Nkind (Result_Node);

      --  and now - special processing for some node kinds to skip nodes which
      --  are of no use in ASIS
      if Result_Nkind = N_Package_Specification   or else
         Result_Nkind = N_Function_Specification  or else
         Result_Nkind = N_Procedure_Specification or else
         Result_Nkind = N_Entry_Body_Formal_Part
      then
         Result_Node := Parent (Result_Node);
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Considering_Parent_Count => False);
   end General_Encl_Elem;

--------------------------------------------------------------------------
--              Local Enclosing Element Conctruction items
--
--       ASIS_Internal_Element_Kinds.Internal_Element_Kinds-based
--       packaging and documentation
--------------------------------------------------------------------------

--  type Internal_Element_Kinds is (
--
--    Not_An_Element,            -- Asis.Nil_Element
--
------------------------------------------------------------------------------

--  A_Pragma,                  -- Asis.Elements

------------------------------------------------------------------------------

--    An_All_Calls_Remote_Pragma,       -- E.2.3(4)
--    An_Asynchronous_Pragma,           -- E.4.1(2)
--    An_Atomic_Pragma,                 -- C.6(2)
--    An_Atomic_Components_Pragma,      -- C.6(2)
--    An_Attach_Handler_Pragma,         -- C.3.1(3)
--    A_Controlled_Pragma,              -- 13.11.3(2)
--    A_Convention_Pragma,              -- B.1(4)
--    A_Discard_Names_Pragma,           -- C.5(2),     added in ASIS-for-GNAT
--    An_Elaborate_Pragma,              -- 10.2.1(19), added in ASIS-for-GNAT
--    An_Elaborate_All_Pragma,          -- 10.2.1(19)
--    An_Elaborate_Body_Pragma,         -- 10.2.1(19)
--    An_Export_Pragma,                 -- B.1(4)
--    An_Import_Pragma,                 -- B.1(4)
--    An_Inline_Pragma,                 -- 6.3.2(2)
--    An_Inspection_Point_Pragma,       -- H.3.2(2)
--    An_Interrupt_Handler_Pragma,      -- C.3.1(1)
--    An_Interrupt_Priority_Pragma,     -- D.1(4)
--    A_Linker_Options_Pragma,          -- B.1(4),     added in ASIS-for-GNAT
--    A_List_Pragma,                    -- 2.8(20)
--    A_Locking_Policy_Pragma,          -- D.3(2)
--    A_Normalize_Scalars_Pragma,       -- H.1(2)
--    An_Optimize_Pragma,               -- 2.8(20)
--    A_Pack_Pragma,                    -- 13.2(2)
--    A_Page_Pragma,                    -- 2.8(20)
--    A_Preelaborate_Pragma,            -- 10.2.1(2)
--    A_Priority_Pragma,                -- D.1(2)
--    A_Pure_Pragma,                    -- 10.2.1(13)
--    A_Queuing_Policy_Pragma,          -- D.4(2)
--    A_Remote_Call_Interface_Pragma,   -- E.2.3(2)
--    A_Remote_Types_Pragma,            -- E.2.2(2)
--    A_Restrictions_Pragma,            -- 13.12(2)
--    A_Reviewable_Pragma,              -- H.3.1(2)
--    A_Shared_Passive_Pragma,          -- E.2.1(2)
--    A_Storage_Size_Pragma,            -- 13.3(62),   added in ASIS-for-GNAT
--    A_Suppress_Pragma,                -- 11.5(3)
--    A_Task_Dispatching_Policy_Pragma, -- D.2.2(2)
--    A_Volatile_Pragma,                -- C.6(2)
--    A_Volatile_Components_Pragma,     -- C.6(2)
--
--    An_Implementation_Defined_Pragma, -- Vendor Annex M
--
--    An_Unknown_Pragma;                -- Unknown to ASIS

------------------------------------------------------------------------------
--  See file mapping.2 for the documentation.

   function A_Pragma_Enclosing (Element : Asis.Element) return Asis.Element is

      Parent_Node          : Node_Id   := Atree.Parent (R_Node (Element));
      Parent_Node_Kind     : Node_Kind := Nkind (Parent_Node);
      Parent_Internal_Kind : Internal_Element_Kinds;

   begin

      --  filtering out compilation pragmas and correcting Parent_Node,
      --  if neseccary

      case Parent_Node_Kind is

         when   N_Handled_Sequence_Of_Statements
              | N_Package_Specification
              | N_Component_List                  =>

            Parent_Node      := Atree.Parent (Parent_Node);
            Parent_Node_Kind := Nkind (Parent_Node);

         when N_Compilation_Unit =>
            return Asis.Nil_Element;
         when others =>
            null;

      end case;

      --  special processing for Nodes requiring by-hand Enclosing Element
      --  kind determination and returning the result for all other Nodes

      case Parent_Node_Kind is

         when N_If_Statement =>

            if List_Containing (Node (Element)) =
               Then_Statements (Parent_Node)
            then
               Parent_Internal_Kind := An_If_Path;
            else
               Parent_Internal_Kind := An_Else_Path;
            end if;
            --  ???    List_Containing (Node (Element))   ??
            --  ??? or List_Containing (R_Node (Element)) ??

         when   N_Conditional_Entry_Call
              | N_Selective_Accept       =>

            Parent_Internal_Kind := An_Else_Path;

         when N_Record_Definition =>

            Parent_Internal_Kind := An_Else_Path;

         when others => --  auto determination of the Enclosing Element kind:

            return Node_To_Element_New (Node             => Parent_Node,
                                        Starting_Element => Element);
      end case;

      --  returning the Enclosing Element with the by-hand-defined kind:

      return Node_To_Element_New (Node             => Parent_Node,
                                  Internal_Kind    => Parent_Internal_Kind,
                                  Starting_Element => Element);

   end A_Pragma_Enclosing;

------------------------------------------------------------------------------


------------------------------------------------------------------------------

--  A_Defining_Name,           -- Asis.Declarations

------------------------------------------------------------------------------

--    A_Defining_Identifier,

   function A_Defining_Expanded_Name_Enclosing (Element : Asis.Element)
                    return Asis.Element;

   --  a forward declaration is needed, because this function is used for
   --  implementing A_Defining_Identifier_Enclosing

   function A_Defining_Identifier_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      --  A_Defining_Identifier may be processed just in the same way as
      --  A_Defining_Expanded_Name, except the follofing cases:

      --  - A_Defining_Identifier obtained as the child of
      --    A_Choice_Parameter_Specification element (by means of Names
      --    query) - both these elements are based on the same
      --    N_Defining_Identifier node
      --
      --   - A_Defining_Identifier representing a statement label, it is
      --     obtained by means of Label_Names query, and it is based on
      --     N_Label node which is the member of the node list representing
      --     the corresponding statement sequence. The Enclosing_Element of
      --     such A_Defining_Name element will be the statement labeled by
      --     it, see Asis_Statements.Label_Names.
      --
      --   - A_Defining_Identifier representing a statement identifier, it is
      --     obtained by means of Statement_Identifier query, and it is based
      --     on N_Identifier node. The Enclosing_Element of the name is the
      --     named statement, see Asis_Statements.Statement_Identifier. But
      --     there is no difference in computing the Enclosing Element
      --     (compared to A_Defining_Expanded_Name) in this case.
      --
      --   - A special processing is needed for a formal package defining name

      Parent_Node      : Node_Id   := Parent (R_Node (Element));
      Parent_Node_Kind : Node_Kind := Nkind  (Parent_Node);

      Result_Kind      : Internal_Element_Kinds := Not_An_Element;
   begin

      if Nkind (Node (Element)) = N_Label then
         Parent_Node    := Next (R_Node (Element));
         --  R_Node (Element) definitely is a list member

         while not Is_Statement (Parent_Node) loop
            Parent_Node := Next (Parent_Node);
         end loop;

      elsif Parent_Node_Kind = N_Exception_Handler then
         Parent_Node := R_Node (Element);
         Result_Kind := A_Choice_Parameter_Specification;

      elsif (not Is_From_Implicit (Element)) and then
            --  ??? do we need this check
            Nkind (Parent (Parent_Node)) = N_Package_Declaration and then
            Nkind (Parent (Parent (Parent_Node))) in
               N_Generic_Declaration and then
            not (Comes_From_Source (Parent (Parent_Node)))
      then
         --  this correspnds to the case when the compiler creates an implicit
         --  expanded package for a formal package.

         Parent_Node := Next (Parent (Parent_Node));

      else
         return A_Defining_Expanded_Name_Enclosing (Element);
      end if;

      return Node_To_Element_New (Node             => Parent_Node,
                                  Internal_Kind    => Result_Kind,
                                  Starting_Element => Element);

   end A_Defining_Identifier_Enclosing;
------------------------------------------------------------------------------
--    A_Defining_Character_Literal,              -- 3.5.1
--    A_Defining_Enumeration_Literal,            -- 3.5.1
--
------------------------------------------------------------------------------
--  --  A_Defining_Operator_Symbol
--
--       A_Defining_And_Operator,                    -- and
--       A_Defining_Or_Operator,                     -- or
--       A_Defining_Xor_Operator,                    -- xor
--       A_Defining_Equal_Operator,                  -- =
--       A_Defining_Not_Equal_Operator,              -- /=
--       A_Defining_Less_Than_Operator,              -- <
--       A_Defining_Less_Than_Or_Equal_Operator,     -- <=
--       A_Defining_Greater_Than_Operator,           -- >
--       A_Defining_Greater_Than_Or_Equal_Operator,  -- >=
--       A_Defining_Plus_Operator,                   -- +
--       A_Defining_Minus_Operator,                  -- -
--       A_Defining_Concatenate_Operator,            -- &
--       A_Defining_Unary_Plus_Operator,             -- +
--       A_Defining_Unary_Minus_Operator,            -- -
--       A_Defining_Multiply_Operator,               -- *
--       A_Defining_Divide_Operator,                 -- /
--       A_Defining_Mod_Operator,                    -- mod
--       A_Defining_Rem_Operator,                    -- rem
--       A_Defining_Exponentiate_Operator,           -- **
--       A_Defining_Abs_Operator,                    -- abs
--       A_Defining_Not_Operator,                    -- not
--

   function A_Defining_Operator_Symbol_Enclosing (Element : Asis.Element)
                    return Asis.Element is

      Parent_Node      : Node_Id   := Parent (R_Node (Element));
      Parent_Node_Kind : Node_Kind := Nkind (Parent_Node);

   begin

      if Parent_Node_Kind = N_Function_Specification

      then -- one more spep up required

         Parent_Node := Parent (Parent_Node);

      end if;

      return Node_To_Element_New (Node             => Parent_Node,
                                  Starting_Element => Element);

   end A_Defining_Operator_Symbol_Enclosing;
------------------------------------------------------------------------------
--    A_Defining_Expanded_Name,

   function A_Defining_Expanded_Name_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Parent_Node      : Node_Id   := Parent (R_Node (Element));
      Parent_Node_Kind : Node_Kind := Nkind (Parent_Node);
   begin
      if (Parent_Node_Kind = N_Function_Specification  or else
          Parent_Node_Kind = N_Procedure_Specification or else
          Parent_Node_Kind = N_Package_Specification)
      then -- one more spep up required
         Parent_Node := Parent (Parent_Node);
      end if;
      return Node_To_Element_New (Node             => Parent_Node,
                                  Starting_Element => Element);
   end A_Defining_Expanded_Name_Enclosing;
------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
--
--  --  A_Declaration,             -- Asis.Declarations
--
-------------------------------------------------------------------------------
--
--    An_Ordinary_Type_Declaration,              -- 3.2.1
--    A_Task_Type_Declaration,                   -- 3.2.1
--    A_Protected_Type_Declaration,              -- 3.2.1
--    An_Incomplete_Type_Declaration,            -- 3.2.1
--    A_Private_Type_Declaration,                -- 3.2.1
--    A_Private_Extension_Declaration,           -- 3.2.1
--
--    A_Subtype_Declaration,                     -- 3.2.2
--
--    A_Variable_Declaration,                    -- 3.3.1 -> Trait_Kinds
--    A_Constant_Declaration,                    -- 3.3.1 -> Trait_Kinds
--    A_Deferred_Constant_Declaration,           -- 3.3.1 -> Trait_Kinds
--    A_Single_Task_Declaration,                 -- 3.3.1
--    A_Single_Protected_Declaration,            -- 3.3.1
--
--    An_Integer_Number_Declaration,             -- 3.3.2
--    A_Real_Number_Declaration,                 -- 3.3.2
--
-------------------------------------------------------------------------------
--    An_Enumeration_Literal_Specification,      -- 3.5.1
--
   function An_Enumeration_Literal_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node : Node_Id;
      Start_Elem  : Asis.Element := Element;
   begin
      if Special_Case (Element) = Stand_Char_Literal then
         Result_Node  := R_Node (Element);

         Set_Character_Code (Start_Elem, 0);
         Set_Special_Case   (Start_Elem, Explicit_From_Standard);
      else
         Result_Node  := Parent (R_Node (Element));
      end if;

      return Node_To_Element_New
        (Starting_Element         => Start_Elem,
         Node                     => Result_Node,
         Internal_Kind            => An_Enumeration_Type_Definition);

   end An_Enumeration_Literal_Specification_Enclosing;
-------------------------------------------------------------------------------
--    A_Discriminant_Specification,

   function A_Discriminant_Specification_Enclosing (Element : Asis.Element)
                    return Asis.Element is
   begin

      return Node_To_Element_New (
                Node          => Parent (R_Node (Element)),
                Internal_Kind => A_Known_Discriminant_Part,
                Starting_Element => Element);

   end A_Discriminant_Specification_Enclosing;
-------------------------------------------------------------------------------
--
--    A_Loop_Parameter_Specification,            -- 5.5   -> Trait_Kinds

   function A_Loop_Parameter_Specification_Enclosing (Element : Asis.Element)
                    return Asis.Element is
   begin
      return Node_To_Element_New
               (Node             => Parent (Parent (R_Node (Element))),
                Internal_Kind    => A_For_Loop_Statement,
                Starting_Element => Element);
      --  the inner Parent gives N_Ineration_Sceme node only
   end A_Loop_Parameter_Specification_Enclosing;
-------------------------------------------------------------------------------
--  The same approach is used for defining the Enclosing_Element for the
--  Elements of the subordinate A_Declaration kinds which can be a
--  declaration part of a Compilation_Unit:
--  if Parent (R_Node (Element)) is of N_Compilation_Unit or N_Subunit
--  kind then a Asis.Nil_Element is returned, otherwise the Enclosed Element
--  is constructed by the Node_To_Element function with auto determination
--  of its kind. So for all of these suburdinate values of A_Declaration
--  kind the reference to same Possible_C_U_Enclosing function is assigned
--
--  This approach does not seem to be reliable and smart enough, but
--  only extensive testing could be used to find its drawbacks

   function Possible_C_U_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Parent_Node      : Node_Id   := Parent (R_Node (Element));
      Parent_Node_Kind : Node_Kind := Nkind (Parent_Node);
   begin
      if Parent_Node_Kind = N_Compilation_Unit or else
         Parent_Node_Kind = N_Subunit
      then
         return Asis.Nil_Element;

      elsif Parent_Node_Kind = N_Package_Specification then
         Parent_Node := Parent (Parent_Node);

      elsif Parent_Node_Kind = N_Protected_Definition then
         Parent_Node := Parent (Parent_Node);
         Parent_Node := Protected_Definition (Original_Node (Parent_Node));
      end if;

      return Node_To_Element_New
        (Starting_Element => Element,
         Node             => Parent_Node);

   end Possible_C_U_Enclosing;
-------------------------------------------------------------------------------
--
--    A_Procedure_Declaration,  -> Possible_C_U_Enclosing
--    A_Function_Declaration,   -> Possible_C_U_Enclosing
--
-------------------------------------------------------------------------------
--    A_Parameter_Specification,

   function A_Parameter_Specification_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node      : Node_Id   := Parent (R_Node (Element));
      Result_Node_Kind : Node_Kind := Nkind (Result_Node);
   begin
      if not (Result_Node_Kind = N_Entry_Declaration           or else
               Result_Node_Kind = N_Access_Function_Definition  or else
               Result_Node_Kind = N_Access_Procedure_Definition or else
               Result_Node_Kind = N_Accept_Statement)
      then
         Result_Node := Parent (Result_Node);
         --  the first Parent gives N_Function/Procedure_Specification only
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Considering_Parent_Count => False);
   end A_Parameter_Specification_Enclosing;
-------------------------------------------------------------------------------
--                                               --       -> Mode_Kinds
--    A_Procedure_Body_Declaration,  -> Possible_C_U_Enclosing
--    A_Function_Body_Declaration,   -> Possible_C_U_Enclosing
--
--    A_Package_Declaration,        -> Possible_C_U_Enclosing
--    A_Package_Body_Declaration,   -> Possible_C_U_Enclosing
--
--    An_Object_Renaming_Declaration,            -- 8.5.1
--    An_Exception_Renaming_Declaration,         -- 8.5.2
--    A_Package_Renaming_Declaration,            -> Possible_C_U_Enclosing
--    A_Procedure_Renaming_Declaration,          -> Possible_C_U_Enclosing
--    A_Function_Renaming_Declaration,           -> Possible_C_U_Enclosing
--    A_Generic_Package_Renaming_Declaration,    -> Possible_C_U_Enclosing
--    A_Generic_Procedure_Renaming_Declaration,  -> Possible_C_U_Enclosing
--    A_Generic_Function_Renaming_Declaration,   -> Possible_C_U_Enclosing
--
--    A_Task_Body_Declaration,           -> Possible_C_U_Enclosing
--    A_Protected_Body_Declaration,      -> Possible_C_U_Enclosing
--
--    An_Entry_Declaration,                      -- 9.5.2
--    An_Entry_Body_Declaration,                 -- 9.5.2
--    An_Entry_Index_Specification,              -- 9.5.2
--
--    A_Procedure_Body_Stub,                     -- 10.1.3
--    A_Function_Body_Stub,                      -- 10.1.3
--    A_Package_Body_Stub,                       -- 10.1.3
--    A_Task_Body_Stub,                          -- 10.1.3
--    A_Protected_Body_Stub,                     -- 10.1.3
--
--    An_Exception_Declaration,                  -- 11.1
--    A_Choice_Parameter_Specification,          -- 11.2
--
--    A_Generic_Procedure_Declaration,   -> Possible_C_U_Enclosing
--    A_Generic_Function_Declaration,    -> Possible_C_U_Enclosing
--    A_Generic_Package_Declaration,     -> Possible_C_U_Enclosing
--
--    A_Package_Instantiation,           -> Possible_C_U_Enclosing
--    A_Procedure_Instantiation,         -> Possible_C_U_Enclosing
--    A_Function_Instantiation,          -> Possible_C_U_Enclosing
--
--    A_Formal_Object_Declaration,               -- 12.4  -> Mode_Kinds
--
--    A_Formal_Type_Declaration,                 -- 12.5
--    A_Formal_Procedure_Declaration,            -- 12.6  -> Default_Kinds
--
--    A_Formal_Function_Declaration,             -- 12.6  -> Default_Kinds
--
--    A_Formal_Package_Declaration,              -- 12.7
--    A_Formal_Package_Declaration_With_Box,     -- 12.7
--
-------------------------------------------------------------------------------
--
--  --  A_Definition,              -- Asis.Definitions
--
-------------------------------------------------------------------------------
--
--  --  A_Type_Definition,                -- 3.2.1   -> Type_Kinds
--
--       A_Derived_Type_Definition,             -- 3.4    -> Trait_Kinds
--       A_Derived_Record_Extension_Definition, -- 3.4    -> Trait_Kinds
--
-------------------------------------------------------------------------------
--       An_Enumeration_Type_Definition,        -- 3.5.1
--
   function An_Enumeration_Type_Definition_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node : Node_Id;
   begin
      if Special_Case (Element) = Stand_Char_Literal then
         Result_Node  := R_Node (Element);

         if Nkind (Result_Node) = N_Defining_Identifier then
            --  we are in the definition of Standard.Boolean:
            Result_Node := Parent (Etype (Result_Node));
         end if;

      else
         Result_Node  := Parent (R_Node (Element));
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Internal_Kind            => An_Ordinary_Type_Declaration);

   end An_Enumeration_Type_Definition_Enclosing;
-------------------------------------------------------------------------------
--       A_Signed_Integer_Type_Definition,      -- 3.5.4
--       A_Modular_Type_Definition,             -- 3.5.4
--
--  --     A_Root_Type_Definition,                -- 3.5.4(10), 3.5.6(4)
--                                              --        -> Root_Type_Kinds
--          A_Root_Integer_Definition,             -- 3.5.4(9)
--          A_Root_Real_Definition,                -- 3.5.6(2)
--          A_Root_Fixed_Definition,               -- 3.5.6(2)
--
--          A_Universal_Integer_Definition,        -- 3.5.4(10)
--          A_Universal_Real_Definition,           -- 3.5.6(4)
--          A_Universal_Fixed_Definition,          -- 3.5.6(4)
--
--
--       A_Floating_Point_Definition,           -- 3.5.7
--
--       An_Ordinary_Fixed_Point_Definition,    -- 3.5.9
--       A_Decimal_Fixed_Point_Definition,      -- 3.5.9
--
--       An_Unconstrained_Array_Definition,     -- 3.6
--       A_Constrained_Array_Definition,        -- 3.6
--
--       A_Record_Type_Definition,              -- 3.8    -> Trait_Kinds
--       A_Tagged_Record_Type_Definition,       -- 3.8    -> Trait_Kinds
--
--  --     An_Access_Type_Definition,             -- 3.10 -> Access_Type_Kinds
--
--          A_Pool_Specific_Access_To_Variable,  -- access subtype_indication
--          An_Access_To_Variable,             -- access all subtype_indication
--          An_Access_To_Constant,        -- access constant subtype_indication
--
--          An_Access_To_Procedure,              -- access procedure
--          An_Access_To_Protected_Procedure,    -- access protected procedure
--          An_Access_To_Function,               -- access function
--          An_Access_To_Protected_Function,     -- access protected function
--
--
------------------------------------------------------------------------------
--    A_Subtype_Indication,
--
--  A_Subtype_Indication element can be obtained
--
--  from element:                               by functions:
--
--
--                  From Asis_Declarations
--
--
--  A_Subtype_Declaration                       Type_Declaration_View
--
--
--
--  A_Variable_Declaration             Object_Declaration_View
--  A_Constant_Declaration
--  A_Deferred_Constant_Declaration
--  A_Component_Declaration
--
--
--
--
--
--                  From Asis_Definitions
--
--
--  A_Derived_Type_Definition                   Parent_Subtype_Indication
--  A_Derived_Record_Extension_Definition
--
--
--  A_Pool_Specific_Access_To_Variable          Access_To_Object_Definition
--  An_Access_To_Variable
--  An_Access_To_Constant
--
--  A_Formal_Pool_Specific_Access_To_Variable
--  A_Formal_Access_To_Variable
--  A_Formal_Access_To_Constant
--
--
--
--
--  A_Component_Definition                    Component_Subtype_Indication
--  (the Enclosing Element is based
--   on the same node and has
--   A_Component_Definition kind,
--   the parent node is of
--   N_Unconstrained_Array_Definition
--   or of N_Constrained_Array_definition
--   Kind)
--
--
--
--  A_Private_Extension_Definition            Ancestor_Subtype_Indication
--  (the Enclosing Element is based on
--   N_Private_Extension_Declaration,
--   bot its kind should be set by hands)
--
--
--
--
--                  From Asis_Expressions
--
--
--  An_Allocation_From_Subtype                Allocator_Subtype_Indication
--
--
--  So we have only two non-trivial cases: when the Parent Node is of
--  N_Unconstrained_Array_Definition, N_Constrained_Array_definition
--  or N_Private_Extension_Declaration kind

   function A_Subtype_Indication_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Parent_Node      : Node_Id   := Parent (R_Node (Element));
      Result_Node      : Node_Id   := R_Node (Element);
      Parent_Node_Kind : Node_Kind := Nkind  (Parent_Node);
      Result_Kind      : Internal_Element_Kinds;
   begin
      if Parent_Node_Kind = N_Unconstrained_Array_Definition or else
         Parent_Node_Kind = N_Constrained_Array_Definition   or else
         Parent_Node_Kind = N_Component_Declaration
      then
         Result_Kind := A_Component_Definition;

      elsif Parent_Node_Kind = N_Private_Extension_Declaration then
         Result_Kind := A_Private_Extension_Definition;
         Result_Node := Parent_Node;
      else
         return Node_To_Element_New
          (Starting_Element         => Element,
           Node                     => Parent_Node,
           Considering_Parent_Count => False);
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Internal_Kind            => Result_Kind,
         Considering_Parent_Count => False);

   end A_Subtype_Indication_Enclosing;
------------------------------------------------------------------------------

--
--  --  A_Constraint,                     -- 3.2.2   -> Constraint_Kinds
--
--       A_Range_Attribute_Reference,           -- 3.2.2, 3.5

------------------------------------------------------------------------------
--       A_Simple_Expression_Range,             -- 3.2.2, 3.5

   function A_Simple_Expression_Range_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Enclosing_Node         : Node_Id   := Node (Element);
      Enclosing_Node_Kind    : Node_Kind := Nkind (Enclosing_Node);
      Context                : Node_Id;
      Context_Kind           : Node_Kind;
      Enclosing_Element_Kind : Internal_Element_Kinds;
   begin
      if Enclosing_Node_Kind = N_Signed_Integer_Type_Definition then
         --  back from Integer_Constraint
         return Node_To_Element_New
                 (Starting_Element         => Element,
                  Node                     => R_Node (Element),
                  Internal_Kind            => A_Signed_Integer_Type_Definition,
                  Considering_Parent_Count => False);
      else -- one step up
         Enclosing_Node      := Parent (R_Node (Element));
         Enclosing_Node_Kind := Nkind  (Enclosing_Node);
   --  possible values of                corresponding kinds of
   --  Enclosing_Node_Kind:              Enclosing Element:
   --
   --  N_Floating_Point_Definition      A_Floating_Point_Definition        (*)
   --  N_Ordinary_Fixed_Point_Definition An_Ordinary_Fixed_Point_Definition (*)
   --  N_Decimal_Fixed_Point_Definition  A_Decimal_Fixed_Point_Definition   (*)
   --
   --  A_Constraint
   --      N_Digits_Constraint          A_Digits_Constraint                (*)
   --      N_Delta_Constraint           A_Delta_Constraint                 (*)
   --
   --
   --  A_Subtype_Indication
   --       N_Subtype_Indication   A_Discrete_Subtype_Indication
   --                                         (_As_Subtype_Definition)
   --                              A_Subtype_Indication
   --
   --  A_Discrete_Range
   --       N_Subtype_Indication   A_Discrete_Subtype_Indication
   --
   --
   --
   --  N_In      An_In_Range_Membership_Test                              (*)
   --  N_Not_In  A_Not_In_Range_Membership_Test                           (*)
   --
   --  (*) means that the Enclosing Element can be obtained by Node_To_Elemen
   --    constructor with auto determination of the Element kind

         if Enclosing_Node_Kind /= N_Subtype_Indication then
            return Node_To_Element_New
                    (Starting_Element         => Element,
                     Node                     => Enclosing_Node,
                     Considering_Parent_Count => False);
         else
            --  A_Discrete_Subtype_Indication or
            --  A_Discrete_Subtype_Indication_As_Subtype_Definition
            --  or A_Subtype_Indication?

            --  First, we have to skip implicit subtype created for
            --  constraint directly included in object declaration,
            --  if any

            Skip_Implicit_Subtype (Enclosing_Node);

            Context      := Parent (Enclosing_Node);
            Context_Kind := Nkind (Context);

            if Context_Kind = N_Subtype_Indication then
               --  it's impossible to make a decision on the base
               --  of this node, we shal go one more step up
               Context      := Parent (Context);
               Context_Kind := Nkind (Context);
            end if;

            if Context_Kind = N_Subtype_Declaration           or else
               ((Context_Kind = N_Constrained_Array_Definition  or else
                  Context_Kind = N_Unconstrained_Array_Definition)
                and then
                 Enclosing_Node = Sinfo.Subtype_Indication (Context))
               or else
               --   is it enough or should we add:
               --   and then Enclosing_Node = Subtype_Indication (Context)?
               Context_Kind = N_Derived_Type_Definition or else
               Context_Kind = N_Access_To_Object_Definition
            then
               Enclosing_Element_Kind := A_Subtype_Indication;

            elsif (Context_Kind = N_Constrained_Array_Definition or else
                   Context_Kind = N_Entry_Declaration            or else
                   Context_Kind = N_Entry_Index_Specification    or else
                   Context_Kind = N_Loop_Parameter_Specification)
            then
               Enclosing_Element_Kind :=
                    A_Discrete_Subtype_Indication_As_Subtype_Definition;
            elsif Context_Kind = N_Component_Declaration or else
                  Context_Kind = N_Object_Declaration
            then
               Enclosing_Element_Kind := A_Subtype_Indication;
            else
               Enclosing_Element_Kind :=
                    A_Discrete_Subtype_Indication;
            end if;

            return Node_To_Element_New
                 (Starting_Element         => Element,
                  Node                     => Enclosing_Node,
                  Internal_Kind            => Enclosing_Element_Kind,
                  Considering_Parent_Count => False);
         end if;
      end if;
   end A_Simple_Expression_Range_Enclosing;
------------------------------------------------------------------------------
--       A_Digits_Constraint,                   -- 3.2.2, 3.5.9
--       A_Delta_Constraint,                    -- 3.2.2, N.3
------------------------------------------------------------------------------
--       A_Discriminant_Constraint,            -- 3.2.2
--
--    A_Component_Definition,           -- 3.6
--
--  --  A_Discrete_Subtype_Definition,    -- 3.6     -> Discrete_Range_Kinds
--
--       A_Discrete_Subtype_Indication_As_Subtype_Definition,
--       A_Discrete_Range_Attribute_Reference_As_Subtype_Definition,
--       A_Discrete_Simple_Expression_Range_As_Subtype_Definition,
--
------------------------------------------------------------------------------
--  --  A_Discrete_Range,                 -- 3.6.1   -> Discrete_Range_Kinds
--
--       A_Discrete_Subtype_Indication,         -- 3.6.1, 3.2.2
--       A_Discrete_Range_Attribute_Reference,  -- 3.6.1, 3.5
--       A_Discrete_Simple_Expression_Range,    -- 3.6.1, 3.5
--
--  All the subordinates of A_Discrete_Range have the same function for
--  determimimg the Enclosing element

--  A_Discrete_Range Element can be obtained
--
--
--  from Element:                       by function:
--
--  An_Index_Constraint                 Discrete_Ranges(def)
--
--  A_Variant                           Variant_Choices(def)
--
--  A_Slice                             Slice_Range(expr)
--
--
--  An_Array_Component_Association      Array_Component_Choices(expr)
--  --
--  -- all cases except this can be handled as trivial, but here we have
--  -- to set An_Array_Component_Association kind for the enclosing Element
--  -- which is to be built on the base of N_Component_Association node
--  -- by hand
--
--
--  A_Case_Path                         Case_Statement_Alternative_Choices(st)

   function A_Discrete_Range_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node      : Node_Id   := Parent (R_Node (Element));
      Result_Node_Kind : Node_Kind := Nkind  (Result_Node);
      Result_Elem_Kind : Internal_Element_Kinds := Not_An_Element;
   begin
      if Nkind (Node (Element)) = N_Component_Clause then
         Result_Node      := R_Node (Element);
         Result_Elem_Kind := A_Component_Clause;
      elsif Result_Node_Kind = N_Component_Association then
         Result_Elem_Kind := An_Array_Component_Association;
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Internal_Kind            => Result_Elem_Kind,
         Considering_Parent_Count => False);
   end A_Discrete_Range_Enclosing;
------------------------------------------------------------------------------
--
--    An_Unknown_Discriminant_Part,     -- 3.7
--    A_Known_Discriminant_Part,        -- 3.7
--
--  These kinds can be handled by the same function
--
--  An_Unknown_Discriminant_Part and A_Known_Discriminant_Part Elements
--  can be obtained
--
--  from Element:                          by function:
--
--  An_Ordinary_Type_Declaration           Discriminant_Part(decl)
--  A_Task_Type_Declaration
--  A_Protected_Type_Declaration
--  An_Incomplete_Type_Declaration
--  A_Private_Type_Declaration
--  A_Private_Extension_Declaration
--  A_Formal_Type_Declaration
--
--  The enclosing element should be based on the same node, but the elemnent
--  kind determination should be performed

   function A_Discriminant_Part_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
   begin
      return Node_To_Element_New (Node             => R_Node (Element),
                                  Starting_Element => Element);
   end A_Discriminant_Part_Enclosing;
------------------------------------------------------------------------------
--    A_Record_Definition,              -- 3.8
--    A_Null_Record_Definition,         -- 3.8
--
--  These kinds can be handled by the same function
--
--  A_Record_Definition and A_Null_Record_Definition Elements
--  can be obtained
--
--  from Element:                          by function:
--
--  A_Derived_Record_Extension_Definition  Record_Definition(def)
--  A_Record_Type_Definition
--  A_Tagged_Record_Type_Definition
--
--  If the Enclosing Element is of A_Derived_Record_Extension_Definition kind,
--  it should be based on the parent node, otherwise it should be based
--  on the same node

   function A_Record_Definition_Enclosing (Element : Asis.Element)
                    return Asis.Element is

      Parent_Node          : Node_Id;
      Parent_Internal_Kind : Internal_Element_Kinds;

   begin

      if Nkind (Parent (R_Node (Element))) = N_Derived_Type_Definition then

         Parent_Node          := Parent (R_Node (Element));
         Parent_Internal_Kind := A_Derived_Record_Extension_Definition;

      else

         Parent_Node := Node (Element);

         if Tagged_Present (Parent_Node) then
            Parent_Internal_Kind := A_Tagged_Record_Type_Definition;
         else
            Parent_Internal_Kind := A_Record_Type_Definition;
         end if;

      end if;

      return Node_To_Element_New (Node             => Parent_Node,
                                  Internal_Kind    => Parent_Internal_Kind,
                                  Starting_Element => Element);

   end A_Record_Definition_Enclosing;
------------------------------------------------------------------------------
--
------------------------------------------------------------------------------
--    A_Null_Component,                 -- 3.8

--  A_Null_Component Element can be obtained
--
--  from Element:                          by function:
--
--  A_Record_Definition                    Record_Components(def)
--  A_Variant
--
--  The Enclosind Element should be based on the same node, but it can have
--  either A_Record_Definition or A_Variant kind depending on the node kind

   function A_Null_Component_Enclosing (Element : Asis.Element)
                    return Asis.Element is

      Parent_Node          : Node_Id := Node (Element);
      Parent_Internal_Kind : Internal_Element_Kinds;

   begin

      if Nkind (Parent_Node) = N_Record_Definition then
         Parent_Internal_Kind := A_Record_Definition;
      else
         Parent_Internal_Kind := A_Variant;
      end if;

      return Node_To_Element_New (Node             => Parent_Node,
                                  Internal_Kind    => Parent_Internal_Kind,
                                  Starting_Element => Element);

   end A_Null_Component_Enclosing;
------------------------------------------------------------------------------
--    A_Variant_Part,                   -- 3.8

--  A_Variant_Part Element can be obtained
--
--  from Element:                          by function:
--
--
--  A_Record_Definition                    Record_Components(def)
--  A_Variant
--
--  The Enclosind Element should be based on the parent node, but in the case
--  of A_Record_Definition only by-hand determination of its kind is possible

   function A_Variant_Part_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node : Node_Id := Parent (Parent (R_Node (Element)));
      Result_Kind : Internal_Element_Kinds;
   begin
      if Nkind (Result_Node) = N_Record_Definition then
         Result_Kind := A_Record_Definition;
      else
         Result_Kind := A_Variant;
      end if;
      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Internal_Kind            => Result_Kind,
         Considering_Parent_Count => False);
   end A_Variant_Part_Enclosing;
------------------------------------------------------------------------------
--    A_Variant,                        -- 3.8
------------------------------------------------------------------------------
--    An_Others_Choice,                 -- 3.8.1, 4.3.1, 4.3.3, 11.2
--
--  An_Others_Choice Element can be obtained
--
--  from Element:                        by function:
--
--  A_Variant                            Variant_Choices(def)
--
--  An_Array_Component_Association       Array_Component_Choices(expr)
--
--  A_Record_Component_Association       Record_Component_Choices(expr)
--
--  A_Case_Path                          Case_Statement_Alternative_Choices(st)
--
--  An_Exception_Handler                   Exception_Choices(st)
--   Cases of A_Variant, A_Case_Path and An_Exception_Handler Enclosing
--   Element kinds are trivial - Enclosing Element is build on the Parent
--   node with auto determination of its kind, but for
--   An_Array_Component_Association and A_Record_Component_Association
--   (which are both built on N_Component_Association node) by-hand kind
--   determination is required.

   function An_Others_Choice_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Parent_Node : Node_Id := Parent (Parent (R_Node (Element)));
      Result_Node : Node_Id := Parent (R_Node (Element));
      Result_Kind : Internal_Element_Kinds;
   begin
      if Nkind (Result_Node) = N_Component_Association then
         --  we have to find out, is it record or array component
         --  association. Parent_Node points to the enclosing aggregate

         if No (Etype (Parent_Node)) or else
            Is_Array_Type (Etype (Parent_Node))
         then
            --  the first condition in 'or else' is true for multi-dimensional
            --  array aggregates
            Result_Kind := An_Array_Component_Association;
         else
            Result_Kind := A_Record_Component_Association;
         end if;

         return Node_To_Element_New
           (Starting_Element         => Element,
            Node                     => Result_Node,
            Internal_Kind            => Result_Kind,
            Considering_Parent_Count => False);
      else
         return Node_To_Element_New
           (Starting_Element         => Element,
            Node                     => Result_Node,
            Considering_Parent_Count => False);
      end if;
   end An_Others_Choice_Enclosing;
------------------------------------------------------------------------------
--
--    A_Private_Type_Definition,        -- 7.3     -> Trait_Kinds
--    A_Tagged_Private_Type_Definition, -- 7.3     -> Trait_Kinds
--    A_Private_Extension_Definition,   -- 7.3     -> Trait_Kinds
--
--    A_Task_Definition,                -- 9.1
--    A_Protected_Definition,           -- 9.4
--
--  --  A_Formal_Type_Definition,         -- 12.5    -> Formal_Type_Kinds
--
--       A_Formal_Private_Type_Definition,         -- 12.5.1  -> Trait_Kinds
--       A_Formal_Tagged_Private_Type_Definition,  -- 12.5.1  -> Trait_Kinds
--
--       A_Formal_Derived_Type_Definition,         -- 12.5.1  -> Trait_Kinds
--
--       A_Formal_Discrete_Type_Definition,        -- 12.5.2
--
--       A_Formal_Signed_Integer_Type_Definition,  -- 12.5.2
--       A_Formal_Modular_Type_Definition,         -- 12.5.2
--
--       A_Formal_Floating_Point_Definition,       -- 12.5.2
--
--       A_Formal_Ordinary_Fixed_Point_Definition, -- 12.5.2
--       A_Formal_Decimal_Fixed_Point_Definition,  -- 12.5.2
--
--       A_Formal_Unconstrained_Array_Definition,  -- 12.5.3
--       A_Formal_Constrained_Array_Definition,    -- 12.5.3
--
--       A_Formal_Access_Type_Definition,
--
--          A_Formal_Pool_Specific_Access_To_Variable,
--          A_Formal_Access_To_Variable,
--          A_Formal_Access_To_Constant,
--
--          A_Formal_Access_To_Procedure,
--          A_Formal_Access_To_Protected_Procedure,
--          A_Formal_Access_To_Function,
--          A_Formal_Access_To_Protected_Function,
--
-------------------------------------------------------------------------------
--
--  --  An_Expression,             -- Asis.Expressions
--
-------------------------------------------------------------------------------
--
--    An_Integer_Literal,                        -- 2.4
--    A_Real_Literal,                            -- 2.4.1
--    A_String_Literal,                          -- 2.6

-------------------------------------------------------------------------------
--
--  --  An_Operator_Symbol,                        -- 4.1
--
--          An_And_Operator,                     -- and
--          An_Or_Operator,                      -- or
--          An_Xor_Operator,                     -- xor
--          An_Equal_Operator,                   -- =
--          A_Not_Equal_Operator,                -- /=
--          A_Less_Than_Operator,                -- <
--          A_Less_Than_Or_Equal_Operator,       -- <=
--          A_Greater_Than_Operator,             -- >
--          A_Greater_Than_Or_Equal_Operator,    -- >=
--          A_Plus_Operator,                     -- +
--          A_Minus_Operator,                    -- -
--          A_Concatenate_Operator,              -- &
--          A_Unary_Plus_Operator,               -- +
--          A_Unary_Minus_Operator,              -- -
--          A_Multiply_Operator,                 -- *
--          A_Divide_Operator,                   -- /
--          A_Mod_Operator,                      -- mod
--          A_Rem_Operator,                      -- rem
--          An_Exponentiate_Operator,            -- **
--          An_Abs_Operator,                     -- abs
--          A_Not_Operator,                      -- not


--
--    A_Character_Literal,                       -- 4.1
--    An_Enumeration_Literal,                    -- 4.1
--    An_Explicit_Dereference,                   -- 4.1
-------------------------------------------------------------------------------
--    A_Function_Call,                           -- 4.1
--
-------------------------------------------------------------------------------
--    An_Indexed_Component,                      -- 4.1.1
--    A_Slice,                                   -- 4.1.2
-------------------------------------------------------------------------------
--    A_Selected_Component,                      -- 4.1.3
--
--  Processed by An_Identifier_Enclosing
-------------------------------------------------------------------------------
--
--    -- ??? Not_An_Attribute,
--    An_Attribute_Reference,                    -- 4.1.4  -> Attribute_Kinds
--
--          An_Access_Attribute ..
--          An_Address_Attribute,
--          An_Adjacent_Attribute,
--          An_Aft_Attribute,
--          An_Alignment_Attribute,
--          A_Base_Attribute,
--          A_Bit_Order_Attribute,
--          A_Body_Version_Attribute,
--          A_Callable_Attribute,
--          A_Caller_Attribute,
--          A_Ceiling_Attribute,
--          A_Class_Attribute,
--          A_Component_Size_Attribute,
--          A_Compose_Attribute,
--          A_Constrained_Attribute,
--          A_Copy_Sign_Attribute,
--          A_Count_Attribute,
--          A_Definite_Attribute,
--          A_Delta_Attribute,
--          A_Denorm_Attribute,
--          A_Digits_Attribute,
--          An_Exponent_Attribute,
--          An_External_Tag_Attribute,
--          A_First_Attribute,
--          A_First_Bit_Attribute,
--          A_Floor_Attribute,
--          A_Fore_Attribute,
--          A_Fraction_Attribute,
--          An_Identity_Attribute,
--          An_Image_Attribute,
--          An_Input_Attribute,
--          A_Last_Attribute,
--          A_Last_Bit_Attribute,
--          A_Leading_Part_Attribute,
--          A_Length_Attribute,
--          A_Machine_Attribute,
--          A_Machine_Emax_Attribute,
--          A_Machine_Emin_Attribute,
--          A_Machine_Mantissa_Attribute,
--          A_Machine_Overflows_Attribute,
--          A_Machine_Radix_Attribute,
--          A_Machine_Rounds_Attribute,
--          A_Max_Attribute,
--          A_Max_Size_In_Storage_Elements_Attribute,
--          A_Min_Attribute,
--          A_Model_Attribute,
--          A_Model_Emin_Attribute,
--          A_Model_Epsilon_Attribute,
--          A_Model_Mantissa_Attribute,
--          A_Model_Small_Attribute,
--          A_Modulus_Attribute,
--          An_Output_Attribute,
--          A_Partition_ID_Attribute,
--          A_Pos_Attribute,
--          A_Position_Attribute,
--          A_Pred_Attribute,
-------------------------------------------------------------------------------
--          A_Range_Attribute,

-------------------------------------------------------------------------------
--          A_Read_Attribute,
--          A_Remainder_Attribute,
--          A_Round_Attribute,
--          A_Rounding_Attribute,
--          A_Safe_First_Attribute,
--          A_Safe_Last_Attribute,
--          A_Scale_Attribute,
--          A_Scaling_Attribute,
--          A_Signed_Zeros_Attribute,
--          A_Size_Attribute,
--          A_Small_Attribute,
--          A_Storage_Pool_Attribute,
--          A_Storage_Size_Attribute,
--
--          A_Succ_Attribute,
--          A_Tag_Attribute,
--          A_Terminated_Attribute,
--          A_Truncation_Attribute,
--          An_Unbiased_Rounding_Attribute,
--          An_Unchecked_Access_Attribute,
--          A_Val_Attribute,
--          A_Valid_Attribute,
--          A_Value_Attribute,
--          A_Version_Attribute,
--          A_Wide_Image_Attribute,
--          A_Wide_Value_Attribute,
--          A_Wide_Width_Attribute,
--          A_Width_Attribute,
--          A_Write_Attribute,
--
--          An_Implementation_Defined_Attribute,
--          An_Unknown_Attribute,
--
--    A_Record_Aggregate,                        -- 4.3
--    An_Extension_Aggregate,                    -- 4.3
--    A_Positional_Array_Aggregate,             -- 4.3
--    A_Named_Array_Aggregate,                  -- 4.3
--
--    An_And_Then_Short_Circuit,                 -- 4.4
--    An_Or_Else_Short_Circuit,                  -- 4.4
--
--    An_In_Range_Membership_Test,               -- 4.4
--    A_Not_In_Range_Membership_Test,            -- 4.4
--    An_In_Type_Membership_Test,                -- 4.4
--    A_Not_In_Type_Membership_Test,             -- 4.4
--
--    A_Null_Literal,                            -- 4.4
--    A_Parenthesized_Expression,                -- 4.4
--
--    A_Type_Conversion,                         -- 4.6
--    A_Qualified_Expression,                    -- 4.7
--
--    An_Allocation_From_Subtype,                -- 4.8
--    An_Allocation_From_Qualified_Expression,   -- 4.8
--
-------------------------------------------------------------------------------
--
--  --  An_Association,            -- Asis.Expressions
--
-------------------------------------------------------------------------------
--
--    A_Pragma_Argument_Association,         -- 2.8
--    A_Discriminant_Association,            -- 3.7.1
--    A_Record_Component_Association,        -- 4.3.1
--    An_Array_Component_Association,        -- 4.3.3
--    A_Parameter_Association,               -- 6.4
--
-------------------------------------------------------------------------------
--
--  --  A_Statement,               -- Asis.Statements
--
--
--  All subordinates of A_Statement kind require non trivial processing,
--  this processing is the same for all of them except
--  A_Terminate_Alternative_Statement
--
--  A_Statement element can be obtained
--
--  from Element:                               by functions:
--
--  A_Function_Body_Declaration                 Body_Statements(decl)
--  A_Procedure_Body_Declaration
--  A_Package_Body_Declaration
--  A_Task_Body_Declaration
--  An_Entry_Body_Declaration
--   obtaining of the Enclosed Element is trivial
--
--
--  A_Path                                     Sequence_Of_Statements(stmt)
--   obtaining of the Enclosed Element is non-trivial
--
--
--  A_Loop_Statement                           Loop_Statements(stmt)
--  A_While_Loop_Statement
--  A_For_Loop_Statement
--   obtaining of the Enclosed Element is trivial
--
--
--  A_Block_Statement                          Block_Statements(stmt)
--   obtaining of the Enclosed Element is non-trivial - two steps up are
--   required to traverse through the N_Handled_Sequence_Of_Statements node
--   and to come to N_Block_Statement node
--
--
--  An_Accept_Statement                        Accept_Body_Statements(stmt)
--   obtaining of the Enclosed Element is non-trivial - two steps up are
--   required to traverse through the N_Handled_Sequence_Of_Statements node
--   and to come to N_Accept_Statement node
--
--
--  An_Exception_Handler                       Handler_Statements(stmt)
--   obtaining of the Enclosed Element is trivial
--
--   For more details concerning problems arising when Enclosing Element
--   is of A_Path kind see the "A_Path" section of the mapping2 file,
--   here is the summary. If the Enclosing_Element is to be of A_Path kind,
--   then Atree.Parent function can return one of the following nodes:
--
--                    * 133 N_If_Statement           (shared)
--                      139 N_Abortable_Part
--                      141 N_Accept_Alternative     (shared)
--                      145 N_Case_Statement_Alternative
--                    * 149 N_Conditional_Entry_Call (shared)
--                      159 N_Elsif_Part
--                      153 N_Delay_Alternative      (shared)
--                      162 N_Entry_Call_Alternative
--                    * 193 N_Selective_Accept       (shared)
--                      198 N_Terminate_Alternative
--                      200 N_Triggering_Alternative
--
--   (shared) marks the situations when the Elements of different kinds share
--   the same Node Kind
--
--  * marks the situations when the non-trivial processing is required when
--    A_Path Element is created as the Enclosing Element for some
--    A_Statement/A_Pragma Element (except the special processing of the
--    N_Terminate_Alternative <-> A_Terminate_Alternative_Statement situation
--    the construction of the Enclosing Element starts from calling to the
--    Atree.Parent function, and then the parent context should be analyzed
--    to determine the kind of the Enclosing Element
--
--
--    - N_If_Statement - either An_If_Path or An_Else_Path is possible for
--                       Enclosing Element
--
--    - N_Conditional_Entry_Call - An_Else_Path should be returned for
--                                 Enclosing Element
--
--    - N_Selective_Accept An_Else_Path should be returned for
--                                 Enclosing Element

   function A_Statement_Enclosing (Element : Asis.Element)
                    return Asis.Element is

      Parent_Node          : Node_Id   := Parent (R_Node (Element));
      Parent_Node_Kind     : Node_Kind := Nkind (Parent_Node);
      Parent_Internal_Kind : Internal_Element_Kinds;

   begin

      if Parent_Node_Kind = N_If_Statement then

         if List_Containing (R_Node (Element)) =
            Then_Statements (Parent_Node)
         then
            Parent_Internal_Kind := An_If_Path;
         else
            Parent_Internal_Kind := An_Else_Path;
         end if;
         --  ???    List_Containing (Node (Element))   ??
         --  ?? or List_Containing (R_Node (Element)) ??

      elsif Parent_Node_Kind = N_Conditional_Entry_Call or else
            Parent_Node_Kind = N_Selective_Accept
      then

         Parent_Internal_Kind := An_Else_Path;

      else

         if Parent_Node_Kind = N_Handled_Sequence_Of_Statements then
            --  to go to N_Block_Statement, N_Accept_Statement,
            --  N_Subprogram_Body, N_Package_Body, N_Task_Body or
            --  N_Entry_Body node
            Parent_Node := Parent (Parent_Node);
         end if;

         return Node_To_Element_New (Node             => Parent_Node,
                                     Starting_Element => Element);
      end if;

      return Node_To_Element_New (Node             => Parent_Node,
                                  Internal_Kind    => Parent_Internal_Kind,
                                  Starting_Element => Element);

   end A_Statement_Enclosing;
-------------------------------------------------------------------------------
--
--    A_Null_Statement,                    -- 5.1
--    An_Assignment_Statement,             -- 5.2
--    An_If_Statement,                     -- 5.3
--    A_Case_Statement,                    -- 5.4
--
--    A_Loop_Statement,                    -- 5.5
--    A_While_Loop_Statement,              -- 5.5
--    A_For_Loop_Statement,                -- 5.5
--
--    A_Block_Statement,                   -- 5.6
--    An_Exit_Statement,                   -- 5.7
--    A_Goto_Statement,                    -- 5.8
--
--    A_Procedure_Call_Statement,          -- 6.4
--    A_Return_Statement,                  -- 6.5
--
--    An_Accept_Statement,                 -- 9.5.2
--    An_Entry_Call_Statement,             -- 9.5.3
--
--    A_Requeue_Statement,                 -- 9.5.4
--    A_Requeue_Statement_With_Abort,      -- 9.5.4
--
--    A_Delay_Until_Statement,             -- 9.6
--    A_Delay_Relative_Statement,          -- 9.6
--
------------------------------------------------------------------------------
--    A_Terminate_Alternative_Statement,
--
--  The Enclosing Element is built on the same node, but it nay have
--  A_Select_Path or An_Or_Path kind.

   function A_Terminate_Alternative_Statement_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
   begin
      return Node_To_Element_New (Node             => R_Node (Element),
                                  Starting_Element => Element);
   end A_Terminate_Alternative_Statement_Enclosing;
------------------------------------------------------------------------------
--
--    A_Selective_Accept_Statement,        -- 9.7.2
--    A_Timed_Entry_Call_Statement,        -- 9.7.3
--    A_Conditional_Entry_Call_Statement,  -- 9.7.3
--    An_Asynchronous_Select_Statement,    -- 9.7.4
--
--    An_Abort_Statement,                  -- 9.8
--    A_Raise_Statement,                   -- 11.3
--    A_Code_Statement,                    -- 13.8
--
-------------------------------------------------------------------------------
--  Path_Kinds
--  Literals                        -- RM 95
------------------------------------------------------------------------------
--
--    An_If_Path,
--    An_Elsif_Path,
------------------------------------------------------------------------------
--    An_Else_Path,
--
--  the Enclosing Element should be based on the same node, but the auto
--  determination of the Element Kind is requred

   function An_Else_Path_Enclosing (Element : Asis.Element)
                    return Asis.Element is
   begin
      return Node_To_Element_New (Node             => R_Node (Element),
                                  Starting_Element => Element);
   end An_Else_Path_Enclosing;
------------------------------------------------------------------------------

--    A_Case_Path,
--    A_Select_Path,
--    An_Or_Path,
--    A_Then_Abort_Path,
--
-------------------------------------------------------------------------------
--
--  -- A_Clause,                  -- Asis.Clauses
--
-------------------------------------------------------------------------------
--
--    A_Use_Package_Clause,           -- 8.4
--    A_Use_Type_Clause,              -- 8.4
--
--    A_Use_Package_Clause_In_Context_Specification,           -- 8.4
--    A_Use_Type_Clause_In_Context_Specification,              -- 8.4
--
--    A_With_Clause,                  -- 10.1.2
--
--  --  A_Representation_Clause,      -- 13.1    -> Representation_Clause_Kinds
--
-------------------------------------------------------------------------------
--       An_Attribute_Definition_Clause,           -- 13.3.1
--
--  A_Clause element can be obtained
--
--  from Element:                               by functions:
--
--  A_Record_Definition                     Record_Components(def)
--  A_Variant                               (along with A_Component_Declaration
--  (only An_Attribute_Definition_Clause)   and A_Variant_Part Elements =>
--                                          obtaining of the Enclosing
--                                          Element is NON_trivial)
--
--  If An_Attribute_Definition_Clause is obtained by the Record_Components
--  query, its Node is in the same list as nodes for
--  A_Component_Declaration Elements, which requires two steps down the
--  tree to be made during the tree traversing

   function An_Attribute_Definition_Clause_Enclosing
     (Element : Asis.Element)
      return Asis.Element
   is
      Result_Node      : Node_Id   := Parent (R_Node (Element));
      Result_Node_Kind : Node_Kind := Nkind  (Result_Node);
      Result_Kind     : Internal_Element_Kinds := Not_An_Element;
   begin
      if Result_Node_Kind = N_Component_List or else
         Result_Node_Kind = N_Package_Specification
      then
         Result_Node      := Parent (Result_Node);
         Result_Node_Kind := Nkind  (Result_Node);
      end if;

      if Result_Node_Kind = N_Record_Definition then
         Result_Kind := A_Record_Definition;
      elsif Result_Node_Kind = N_Variant then
         Result_Kind := A_Variant;
      end if;

      return Node_To_Element_New
        (Starting_Element         => Element,
         Node                     => Result_Node,
         Internal_Kind            => Result_Kind,
         Considering_Parent_Count => False);
   end An_Attribute_Definition_Clause_Enclosing;
-------------------------------------------------------------------------------
--       An_Enumeration_Representation_Clause,     -- 13.4
--       A_Record_Representation_Clause,           -- 13.5.3
--       An_At_Clause,                             -- N.7
--
--
--    A_Component_Clause,             -- 13.5.3
--
-------------------------------------------------------------------------------
--
--    An_Exception_Handler,    -- Asis.Statements
--
--  To get the node on which tThe Enclosing Element should be built, the
--  Atree.Parent function should be applied twice, becouse its firs call
--  yields the N_Handled_Sequence_Of_Statements node.

   function An_Exception_Handler_Enclosing (Element : Asis.Element)
                 return Asis.Element is
   begin
      return Node_To_Element_New
               (Node             => Parent (Parent (R_Node (Element))),
                Starting_Element => Element);
   end An_Exception_Handler_Enclosing;
-------------------------------------------------------------------------------
--  -- Special values added for Node -> Element switching,
--  -- see Asis_Vendor_Primitives.GNAT_to_Asis_Mapping body for
--  -- more details
-------------------------------------------------------------------------------
--
--    Non_Trivial_Mapping,
--    Not_Implemented_Mapping,
--    No_Mapping
--
--   );

--------------------------------------------------------------------------
--  The Second Switch definition and initialization
--------------------------------------------------------------------------

   Enclosing_Element_For_Explicits_Second_Switch :
      array (Internal_Element_Kinds)
         of Enclosing_Element_Construction_For_Explicits_Items :=
(

--  type Internal_Element_Kinds is (
--
--    Not_An_Element,            -- Asis.Nil_Element
--
------------------------------------------------------------------------------

--  A_Pragma,                  -- Asis.Elements

------------------------------------------------------------------------------

An_All_Calls_Remote_Pragma ..
--     An_Asynchronous_Pragma,
--     An_Atomic_Pragma,
--     An_Atomic_Components_Pragma,
--     An_Attach_Handler_Pragma,
--     A_Controlled_Pragma,
--     A_Convention_Pragma,
--     A_Discard_Names_Pragma,
--     An_Elaborate_Pragma,
--     An_Elaborate_All_Pragma,
--     An_Elaborate_Body_Pragma,
--     An_Export_Pragma,
--     An_Import_Pragma,
--     An_Inline_Pragma,
--     An_Inspection_Point_Pragma,
--     An_Interrupt_Handler_Pragma,
--     An_Interrupt_Priority_Pragma,
--     A_Linker_Options_Pragma
--     A_List_Pragma,
--     A_Locking_Policy_Pragma,
--     A_Normalize_Scalars_Pragma,
--     An_Optimize_Pragma,
--     A_Pack_Pragma,
--     A_Page_Pragma,
--     A_Preelaborate_Pragma,
--     A_Priority_Pragma,
--     A_Pure_Pragma,
--     A_Queuing_Policy_Pragma,
--     A_Remote_Call_Interface_Pragma,
--     A_Remote_Types_Pragma,
--     A_Restrictions_Pragma,
--     A_Reviewable_Pragma,
--     A_Shared_Passive_Pragma,
--     A_Storage_Size_Pragma,
--     A_Suppress_Pragma,
--     A_Task_Dispatching_Policy_Pragma,
--     A_Volatile_Pragma,
--     A_Volatile_Components_Pragma,
--
--     An_Implementation_Defined_Pragma,
--
An_Unknown_Pragma                => A_Pragma_Enclosing'Access,


------------------------------------------------------------------------------

--  A_Defining_Name,           -- Asis.Declarations

------------------------------------------------------------------------------

A_Defining_Identifier            => A_Defining_Identifier_Enclosing'Access,

--    A_Defining_Character_Literal,    -- an Enclosing Element is based
--    A_Defining_Enumeration_Literal,  -- on the same Node
--
--  --  A_Defining_Operator_Symbol
--
A_Defining_And_Operator ..
--       A_Defining_Or_Operator,
--       A_Defining_Xor_Operator,
--       A_Defining_Equal_Operator,
--       A_Defining_Not_Equal_Operator,
--       A_Defining_Less_Than_Operator,
--       A_Defining_Less_Than_Or_Equal_Operator,
--       A_Defining_Greater_Than_Operator,
--       A_Defining_Greater_Than_Or_Equal_Operator,
--       A_Defining_Plus_Operator,
--       A_Defining_Minus_Operator,
--       A_Defining_Concatenate_Operator,
--       A_Defining_Unary_Plus_Operator,
--       A_Defining_Unary_Minus_Operator,
--       A_Defining_Multiply_Operator,
--       A_Defining_Divide_Operator,
--       A_Defining_Mod_Operator,
--       A_Defining_Rem_Operator,
--       A_Defining_Exponentiate_Operator,
--       A_Defining_Abs_Operator,
A_Defining_Not_Operator         => A_Defining_Operator_Symbol_Enclosing'Access,
A_Defining_Expanded_Name        => A_Defining_Expanded_Name_Enclosing'Access,
--
-------------------------------------------------------------------------------
--
--  --  A_Declaration,             -- Asis.Declarations
--
-------------------------------------------------------------------------------
--
--    An_Ordinary_Type_Declaration,              -- 3.2.1
--    A_Task_Type_Declaration,                   -- 3.2.1
--    A_Protected_Type_Declaration,              -- 3.2.1
--    An_Incomplete_Type_Declaration,            -- 3.2.1
--    A_Private_Type_Declaration,                -- 3.2.1
--    A_Private_Extension_Declaration,           -- 3.2.1
--
--    A_Subtype_Declaration,                     -- 3.2.2
--
--    A_Variable_Declaration,                    -- 3.3.1 -> Trait_Kinds
--    A_Constant_Declaration,                    -- 3.3.1 -> Trait_Kinds
--    A_Deferred_Constant_Declaration,           -- 3.3.1 -> Trait_Kinds
--    A_Single_Task_Declaration,                 -- 3.3.1
--    A_Single_Protected_Declaration,            -- 3.3.1
--
--    An_Integer_Number_Declaration,             -- 3.3.2
--    A_Real_Number_Declaration,                 -- 3.3.2
--
An_Enumeration_Literal_Specification =>
   An_Enumeration_Literal_Specification_Enclosing'Access,
--

A_Discriminant_Specification => A_Discriminant_Specification_Enclosing'Access,
--
--  A_Component_Declaration      => A_Component_Declaration_Enclosing'Access,
A_Component_Declaration      => An_Expression_Enclosing'Access,
--
A_Loop_Parameter_Specification =>
                         A_Loop_Parameter_Specification_Enclosing'Access,
--
A_Procedure_Declaration       => Possible_C_U_Enclosing'Access,
A_Function_Declaration        => Possible_C_U_Enclosing'Access,
--
A_Parameter_Specification     => A_Parameter_Specification_Enclosing'Access,

A_Procedure_Body_Declaration  => Possible_C_U_Enclosing'Access,
A_Function_Body_Declaration   => Possible_C_U_Enclosing'Access,
--
A_Package_Declaration         => Possible_C_U_Enclosing'Access,
A_Package_Body_Declaration    => Possible_C_U_Enclosing'Access,
--
--    An_Object_Renaming_Declaration,            -- 8.5.1
--    An_Exception_Renaming_Declaration,         -- 8.5.2

A_Package_Renaming_Declaration           => Possible_C_U_Enclosing'Access,
A_Procedure_Renaming_Declaration         => Possible_C_U_Enclosing'Access,
A_Function_Renaming_Declaration          => Possible_C_U_Enclosing'Access,
A_Generic_Package_Renaming_Declaration   => Possible_C_U_Enclosing'Access,
A_Generic_Procedure_Renaming_Declaration => Possible_C_U_Enclosing'Access,
A_Generic_Function_Renaming_Declaration  => Possible_C_U_Enclosing'Access,

A_Task_Body_Declaration                  => Possible_C_U_Enclosing'Access,
A_Protected_Body_Declaration             => Possible_C_U_Enclosing'Access,
--
An_Entry_Declaration                     => An_Expression_Enclosing'Access,
--  for entry declarations, the problem is for sigge task declarations
--  rewritten as anonymous task type declaration and task object declaration,
--  that's why we have to use An_Expression_Enclosing


--    An_Entry_Body_Declaration,                 -- 9.5.2
--    An_Entry_Index_Specification,              -- 9.5.2
--
--    A_Procedure_Body_Stub,                     -- 10.1.3
--    A_Function_Body_Stub,                      -- 10.1.3
--    A_Package_Body_Stub,                       -- 10.1.3
--    A_Task_Body_Stub,                          -- 10.1.3
--    A_Protected_Body_Stub,                     -- 10.1.3
--
--    An_Exception_Declaration,                  -- 11.1
--    A_Choice_Parameter_Specification,          -- 11.2
--
A_Generic_Procedure_Declaration => Possible_C_U_Enclosing'Access,
A_Generic_Function_Declaration  => Possible_C_U_Enclosing'Access,
A_Generic_Package_Declaration   => Possible_C_U_Enclosing'Access,

A_Package_Instantiation         => Possible_C_U_Enclosing'Access,
A_Procedure_Instantiation       => Possible_C_U_Enclosing'Access,
A_Function_Instantiation        => Possible_C_U_Enclosing'Access,
--
--    A_Formal_Object_Declaration,               -- 12.4  -> Mode_Kinds
--
--    A_Formal_Type_Declaration,                 -- 12.5
--    A_Formal_Procedure_Declaration,            -- 12.6  -> Default_Kinds
--
--    A_Formal_Function_Declaration,             -- 12.6  -> Default_Kinds
--
--    A_Formal_Package_Declaration,              -- 12.7
--    A_Formal_Package_Declaration_With_Box,     -- 12.7
--
-------------------------------------------------------------------------------
--
--  --  A_Definition,              -- Asis.Definitions
--
-------------------------------------------------------------------------------
--
--  --  A_Type_Definition,                -- 3.2.1   -> Type_Kinds
--
--       A_Derived_Type_Definition,             -- 3.4    -> Trait_Kinds
--       A_Derived_Record_Extension_Definition, -- 3.4    -> Trait_Kinds
--

An_Enumeration_Type_Definition =>
   An_Enumeration_Type_Definition_Enclosing'Access,

--
--       A_Signed_Integer_Type_Definition,      -- 3.5.4
--       A_Modular_Type_Definition,             -- 3.5.4
--
--  --     A_Root_Type_Definition,                -- 3.5.4(10), 3.5.6(4)
--                                              --        -> Root_Type_Kinds
--          A_Root_Integer_Definition,             -- 3.5.4(9)
--          A_Root_Real_Definition,                -- 3.5.6(2)
--          A_Root_Fixed_Definition,               -- 3.5.6(2)
--
--          A_Universal_Integer_Definition,        -- 3.5.4(10)
--          A_Universal_Real_Definition,           -- 3.5.6(4)
--          A_Universal_Fixed_Definition,          -- 3.5.6(4)
--
--
--       A_Floating_Point_Definition,           -- 3.5.7
--
--       An_Ordinary_Fixed_Point_Definition,    -- 3.5.9
--       A_Decimal_Fixed_Point_Definition,      -- 3.5.9
--
--       An_Unconstrained_Array_Definition,     -- 3.6
--       A_Constrained_Array_Definition,        -- 3.6
--
--       A_Record_Type_Definition,              -- 3.8    -> Trait_Kinds
--       A_Tagged_Record_Type_Definition,       -- 3.8    -> Trait_Kinds
--
--  --     An_Access_Type_Definition,           -- 3.10   -> Access_Type_Kinds
--
--          A_Pool_Specific_Access_To_Variable,
--          An_Access_To_Variable,
--          An_Access_To_Constant,
--
--          An_Access_To_Procedure,
--          An_Access_To_Protected_Procedure,
--          An_Access_To_Function,
--          An_Access_To_Protected_Function,
--
--
A_Subtype_Indication      => A_Subtype_Indication_Enclosing'Access,
--
--  --  A_Constraint,                     -- 3.2.2   -> Constraint_Kinds
--
--       A_Range_Attribute_Reference,           -- 3.2.2, 3.5

A_Simple_Expression_Range => A_Simple_Expression_Range_Enclosing'Access,

--       A_Digits_Constraint,                   -- 3.2.2, 3.5.9
--       A_Delta_Constraint,                    -- 3.2.2, N.3

--  An_Index_Constraint      => An_Index_Constraint_Enclosing'Access,
An_Index_Constraint      => An_Expression_Enclosing'Access,

A_Discriminant_Constraint => An_Expression_Enclosing'Access,
--
--    A_Component_Definition,           -- 3.6
--
--  --  A_Discrete_Subtype_Definition,    -- 3.6     -> Discrete_Range_Kinds
--
--       A_Discrete_Subtype_Indication_As_Subtype_Definition,
--       A_Discrete_Range_Attribute_Reference_As_Subtype_Definition,
--       A_Discrete_Simple_Expression_Range_As_Subtype_Definition,
--
--  --  A_Discrete_Range,                 -- 3.6.1   -> Discrete_Range_Kinds
--
A_Discrete_Subtype_Indication        => A_Discrete_Range_Enclosing'Access,
A_Discrete_Range_Attribute_Reference => A_Discrete_Range_Enclosing'Access,
A_Discrete_Simple_Expression_Range   => A_Discrete_Range_Enclosing'Access,
--
--
An_Unknown_Discriminant_Part         => A_Discriminant_Part_Enclosing'Access,
A_Known_Discriminant_Part            => A_Discriminant_Part_Enclosing'Access,
--
A_Record_Definition                  => A_Record_Definition_Enclosing'Access,
A_Null_Record_Definition             => A_Record_Definition_Enclosing'Access,
--
A_Null_Component                     => A_Null_Component_Enclosing'Access,
A_Variant_Part                       => A_Variant_Part_Enclosing'Access,
--    A_Variant,                        -- 3.8
--
An_Others_Choice                     => An_Others_Choice_Enclosing'Access,
--    A_Private_Type_Definition,        -- 7.3     -> Trait_Kinds
--    A_Tagged_Private_Type_Definition, -- 7.3     -> Trait_Kinds
--    A_Private_Extension_Definition,   -- 7.3     -> Trait_Kinds
--
--    A_Task_Definition,                -- 9.1

A_Protected_Definition               => An_Expression_Enclosing'Access,

--
--  --  A_Formal_Type_Definition,         -- 12.5    -> Formal_Type_Kinds
--
--       A_Formal_Private_Type_Definition,         -- 12.5.1  -> Trait_Kinds
--       A_Formal_Tagged_Private_Type_Definition,  -- 12.5.1  -> Trait_Kinds
--
--       A_Formal_Derived_Type_Definition,         -- 12.5.1  -> Trait_Kinds
--
--       A_Formal_Discrete_Type_Definition,        -- 12.5.2
--
--       A_Formal_Signed_Integer_Type_Definition,  -- 12.5.2
--       A_Formal_Modular_Type_Definition,         -- 12.5.2
--
--       A_Formal_Floating_Point_Definition,       -- 12.5.2
--
--       A_Formal_Ordinary_Fixed_Point_Definition, -- 12.5.2
--       A_Formal_Decimal_Fixed_Point_Definition,  -- 12.5.2
--
--       A_Formal_Unconstrained_Array_Definition,  -- 12.5.3
--       A_Formal_Constrained_Array_Definition,    -- 12.5.3
--
--  --     A_Formal_Access_Type_Definition,
--
--          A_Formal_Pool_Specific_Access_To_Variable,
--          A_Formal_Access_To_Variable,
--          A_Formal_Access_To_Constant,
--
--          A_Formal_Access_To_Procedure,
--          A_Formal_Access_To_Protected_Procedure,
--          A_Formal_Access_To_Function,
--          A_Formal_Access_To_Protected_Function,
--
-------------------------------------------------------------------------------
--
--  --  An_Expression,             -- Asis.Expressions
--
-------------------------------------------------------------------------------
--  --
An_Integer_Literal ..
--  --    A_Real_Literal,                            -- 2.4.1
--  A_String_Literal      => A_Literal_Enclosing'Access,
--  --
An_Identifier    => An_Expression_Enclosing'Access,
--  An_Identifier    => An_Identifier_Enclosing'Access,
--  --
--  ----  An_Operator_Symbol,                        -- 4.1
--  --
An_And_Operator ..
--  --          An_Or_Operator,                      -- or
--  --          An_Xor_Operator,                      -- xor
--  --          An_Equal_Operator,                   -- =
--  --          A_Not_Equal_Operator,                -- /=
--  --          A_Less_Than_Operator,                -- <
--  --          A_Less_Than_Or_Equal_Operator,       -- <=
--  --          A_Greater_Than_Operator,             -- >
--  --          A_Greater_Than_Or_Equal_Operator,    -- >=
--  --          A_Plus_Operator,                     -- +
--  --          A_Minus_Operator,                    -- -
--  --          A_Concatenate_Operator,              -- &
--  --          A_Unary_Plus_Operator,               -- +
--  --          A_Unary_Minus_Operator,              -- -
--  --          A_Multiply_Operator,                 -- *
--  --          A_Divide_Operator,                   -- /
--  --          A_Mod_Operator,                      -- mod
--  --          A_Rem_Operator,                      -- rem
--  --          An_Exponentiate_Operator,            -- **
--  --          An_Abs_Operator,                     -- abs
--  A_Not_Operator => An_Operator_Symbol_Enclosing'Access,
--  ??? Do we need An_Operator_Symbol_Enclosing???

A_Not_Operator => An_Expression_Enclosing'Access,
--  --
A_Character_Literal ..
--  --    An_Enumeration_Literal,                    -- 4.1
--  --    An_Explicit_Dereference,                   -- 4.1
--
--  A_Function_Call    => A_Function_Call_Enclosing'Access,
--  --
--  --    An_Indexed_Component,                      -- 4.1.1
--  --    A_Slice,                                   -- 4.1.2
--  A_Selected_Component  => An_Identifier_Enclosing'Access,
--  --
--  --    An_Attribute_Reference,  -- 4.1.4  -> Attribute_Kinds
--  --
--  An_Access_Attribute ..
--  --          An_Address_Attribute,
--  --          An_Adjacent_Attribute,
--  --          An_Aft_Attribute,
--  --          An_Alignment_Attribute,
--  --          A_Base_Attribute,
--  --          A_Bit_Order_Attribute,
--  --          A_Body_Version_Attribute,
--  --          A_Callable_Attribute,
--  --          A_Caller_Attribute,
--  --          A_Ceiling_Attribute,
--  --          A_Class_Attribute,
--  --          A_Component_Size_Attribute,
--  --          A_Compose_Attribute,
--  --          A_Constrained_Attribute,
--  --          A_Copy_Sign_Attribute,
--  --          A_Count_Attribute,
--  --          A_Definite_Attribute,
--  --          A_Delta_Attribute,
--  --          A_Denorm_Attribute,
--  --          A_Digits_Attribute,
--  --          An_Exponent_Attribute,
--  --          An_External_Tag_Attribute,
--  --          A_First_Attribute,
--  --          A_First_Bit_Attribute,
--  --          A_Floor_Attribute,
--  --          A_Fore_Attribute,
--  --          A_Fraction_Attribute,
--  --          An_Identity_Attribute,
--  --          An_Image_Attribute,
--  --          An_Input_Attribute,
--  --          A_Last_Attribute,
--  --          A_Last_Bit_Attribute,
--  --          A_Leading_Part_Attribute,
--  --          A_Length_Attribute,
--  --          A_Machine_Attribute,
--  --          A_Machine_Emax_Attribute,
--  --          A_Machine_Emin_Attribute,
--  --          A_Machine_Mantissa_Attribute,
--  --          A_Machine_Overflows_Attribute,
--  --          A_Machine_Radix_Attribute,
--  --          A_Machine_Rounds_Attribute,
--  --          A_Max_Attribute,
--  --          A_Max_Size_In_Storage_Elements_Attribute,
--  --          A_Min_Attribute,
--  --          A_Model_Attribute,
--  --          A_Model_Emin_Attribute,
--  --          A_Model_Epsilon_Attribute,
--  --          A_Model_Mantissa_Attribute,
--  --          A_Model_Small_Attribute,
--  --          A_Modulus_Attribute,
--  --          An_Output_Attribute,
--  --          A_Partition_ID_Attribute,
--  --          A_Pos_Attribute,
--  --          A_Position_Attribute,
--  A_Pred_Attribute  => An_Attribute_Reference_Enclosing'Access,
--
--  A_Range_Attribute => A_Range_Attribute_Enclosing'Access,
--
--  A_Read_Attribute ..
--  --          A_Remainder_Attribute,
--  --          A_Round_Attribute,
--  --          A_Rounding_Attribute,
--  --          A_Safe_First_Attribute,
--  --          A_Safe_Last_Attribute,
--  --          A_Scale_Attribute,
--  --          A_Scaling_Attribute,
--  --          A_Signed_Zeros_Attribute,
--  --          A_Size_Attribute,
--  --          A_Small_Attribute,
--  --          A_Storage_Pool_Attribute,
--  --          A_Storage_Size_Attribute,
--  --
--  --          A_Succ_Attribute,
--  --          A_Tag_Attribute,
--  --          A_Terminated_Attribute,
--  --          A_Truncation_Attribute,
--  --          An_Unbiased_Rounding_Attribute,
--  --          An_Unchecked_Access_Attribute,
--  --          A_Val_Attribute,
--  --          A_Valid_Attribute,
--  --          A_Value_Attribute,
--  --          A_Version_Attribute,
--  --          A_Wide_Image_Attribute,
--  --          A_Wide_Value_Attribute,
--  --          A_Wide_Width_Attribute,
--  --          A_Width_Attribute,
--  --          A_Write_Attribute,
--  --
--  --          An_Implementation_Defined_Attribute,  -- Vendor Annex M
--  An_Unknown_Attribute     => An_Attribute_Reference_Enclosing'Access,
--  --
--  --    A_Record_Aggregate,                        -- 4.3
--  --    An_Extension_Aggregate,                    -- 4.3
--  --    A_Positional_Array_Aggregate,              -- 4.3
--  --    A_Named_Array_Aggregate,                   -- 4.3
--  --
--  --    An_And_Then_Short_Circuit,                 -- 4.4
--  --    An_Or_Else_Short_Circuit,                  -- 4.4
--  --
--  --    An_In_Range_Membership_Test,               -- 4.4
--  --    A_Not_In_Range_Membership_Test,            -- 4.4
--  --    An_In_Type_Membership_Test,                -- 4.4
--  --    A_Not_In_Type_Membership_Test,             -- 4.4
--  --
--  --    A_Null_Literal,                            -- 4.4
--  --    A_Parenthesized_Expression,                -- 4.4
--  --
--  --    A_Type_Conversion,                         -- 4.6
--  --    A_Qualified_Expression,                    -- 4.7
--  --
--  --    An_Allocation_From_Subtype,                -- 4.8
--  --    An_Allocation_From_Qualified_Expression,   -- 4.8
--  --

An_Allocation_From_Qualified_Expression => An_Expression_Enclosing'Access,
-------------------------------------------------------------------------------
--
--  --  An_Association,            -- Asis.Expressions
--
-------------------------------------------------------------------------------
--
--    A_Pragma_Argument_Association,         -- 2.8

A_Discriminant_Association => An_Expression_Enclosing'Access,

--    A_Record_Component_Association,        -- 4.3.1

An_Array_Component_Association => An_Expression_Enclosing'Access,

A_Parameter_Association => An_Expression_Enclosing'Access,
--
-------------------------------------------------------------------------------
--
--  --  A_Statement,               -- Asis.Statements
--
-------------------------------------------------------------------------------
--
A_Null_Statement  ..
--    An_Assignment_Statement,             -- 5.2
--    An_If_Statement,                     -- 5.3
--    A_Case_Statement,                    -- 5.4
--
--    A_Loop_Statement,                    -- 5.5
--    A_While_Loop_Statement,              -- 5.5
--    A_For_Loop_Statement,                -- 5.5
--
--    A_Block_Statement,                   -- 5.6
--    An_Exit_Statement,                   -- 5.7
--    A_Goto_Statement,                    -- 5.8
--
--    A_Procedure_Call_Statement,          -- 6.4
--    A_Return_Statement,                  -- 6.5
--
--    An_Accept_Statement,                 -- 9.5.2
--    An_Entry_Call_Statement,             -- 9.5.3
--
--    A_Requeue_Statement,                 -- 9.5.4
--    A_Requeue_Statement_With_Abort,      -- 9.5.4
--
--    A_Delay_Until_Statement,             -- 9.6
A_Delay_Relative_Statement        => A_Statement_Enclosing'Access,
--
A_Terminate_Alternative_Statement =>
                           A_Terminate_Alternative_Statement_Enclosing'Access,
--
A_Selective_Accept_Statement   ..
--    A_Timed_Entry_Call_Statement,        -- 9.7.3
--    A_Conditional_Entry_Call_Statement,  -- 9.7.3
--    An_Asynchronous_Select_Statement,    -- 9.7.4
--
--    An_Abort_Statement,                  -- 9.8
--    A_Raise_Statement,                   -- 11.3
A_Code_Statement                  => A_Statement_Enclosing'Access,
--
-------------------------------------------------------------------------------
--  Path_Kinds
--  Literals                        -- RM 95
------------------------------------------------------------------------------
--
--    An_If_Path,
--    An_Elsif_Path,
--
An_Else_Path   => An_Else_Path_Enclosing'Access,
--
--    A_Case_Path,
--              -- when discrete_choice_list =>
--              --   sequence_of_statements
--
--    A_Select_Path,
--              -- select [guard] select_alternative
--              -- 9.7.2, 9.7.3:
--              -- select entry_call_alternative
--              -- 9.7.4:
--              -- select triggering_alternative
--
--    An_Or_Path,
--              -- or [guard] select_alternative  9.7.2:
--              -- or delay_alternative
--
--    A_Then_Abort_Path,        -- 9.7.4
--                                    -- then abort sequence_of_statements
--
--
-------------------------------------------------------------------------------
--
--  -- A_Clause,                  -- Asis.Clauses
--
-------------------------------------------------------------------------------
--
    A_Use_Package_Clause => Possible_C_U_Enclosing'Access,           -- 8.4
    A_Use_Type_Clause    => Possible_C_U_Enclosing'Access,              -- 8.4
--
--    A_Use_Package_Clause_In_Context_Specification,           -- 8.4
--    A_Use_Type_Clause_In_Context_Specification,              -- 8.4
--
--    A_With_Clause,                  -- 10.1.2
--
--  --  A_Representation_Clause,        -- 13.1 -> Representation_Clause_Kinds
--
An_Attribute_Definition_Clause =>
                               An_Attribute_Definition_Clause_Enclosing'Access,
--       An_Enumeration_Representation_Clause,     -- 13.4
--       A_Record_Representation_Clause,           -- 13.5.3
--       An_At_Clause,                             -- N.7
--
--
--    A_Component_Clause,             -- 13.5.3
--
-------------------------------------------------------------------------------
--
An_Exception_Handler   => An_Exception_Handler_Enclosing'Access,
--
-------------------------------------------------------------------------------
--  -- Special values added for Node -> Element switching,
--  -- see Asis_Vendor_Primitives.GNAT_to_Asis_Mapping body for
--  -- more details
-------------------------------------------------------------------------------
--
--    Non_Trivial_Mapping,
--    Not_Implemented_Mapping,
--    No_Mapping
--
others => Not_Implemented_Enclosing_Element_Construction'Access);

--------------------------------------------------------------------------
--                  END OF LOCAL DECLARATIONS
--        (ENCLOSING ELEMENT CONSTRUCTIONS FOR EXPLICITS)
--------------------------------------------------------------------------

   -----------------------------------------
   -- Enclosing_Element_For_Explicits_Old --
   -----------------------------------------

   function Enclosing_Element_For_Explicits_Old
     (Element : Asis.Element)
      return Asis.Element
   is
      Enclosing_Construction_Case : Internal_Element_Kinds;
      Element_Internal_Kind       : Internal_Element_Kinds;
      Result_Element              : Asis.Element;
   begin
      Element_Internal_Kind       := Int_Kind (Element);
      Enclosing_Construction_Case :=
         Enclosing_Element_For_Explicits_First_Switch (Element_Internal_Kind);

      case Enclosing_Construction_Case is
         when Not_An_Element =>
            return Asis.Nil_Element;
         when Trivial_Mapping =>
            Result_Element := General_Encl_Elem (Element);
         when Non_Trivial_Mapping =>
            Result_Element :=
               Enclosing_Element_For_Explicits_Second_Switch
                 (Element_Internal_Kind) (Element);
         when No_Mapping =>
               No_Enclosing_Element (Element_Kind => Element_Internal_Kind);
            return Asis.Nil_Element; -- to avoid GNAT warning
         when  Not_Implemented_Mapping =>
               Not_Implemented_Enclosing_Element_Construction
                  (Element => Element);
         when others =>
            --  others means here that the Enclosing Element should
            --  based on the same node.
            Result_Element := Node_To_Element_New
              (Starting_Element         => Element,
               Node                     => R_Node (Element),
               Internal_Kind            => Enclosing_Construction_Case,
               Considering_Parent_Count => False);

            if Element_Internal_Kind = A_Defining_Character_Literal then
               Set_Character_Code (Result_Element, Character_Code (Element));
            end if;

      end case;

      return Result_Element;
   exception
      when ASIS_Failed =>
         --  as the result of the call of the special case function during
         --  the execution of Enclosing_Element_Construction;
         raise;
      when Assert_Error : System.Assertions.Assert_Failure =>
         Raise_ASIS_Failed (
            Argument  => Element,
            Diagnosis =>
                "Enclosing_Element_For_Explicits_Old - "  & LT
              & "Assert_Failure at "
              &  Ada.Exceptions.Exception_Message (Assert_Error));
      when others =>
         Raise_ASIS_Failed (
            Argument  => Element,
            Diagnosis =>
               LT & "Unknown failure in " &
                   " Enclosing_Element_Construction item for the " & LT &
                    "explicit Element of the " &
             Internal_Element_Kinds'Image (Element_Internal_Kind));
   end Enclosing_Element_For_Explicits_Old;

end A4G.Encl_El_Old;
