------------------------------------------------------------------------------
--                                                                          --
--                          GNATCHECK COMPONENTS                            --
--                                                                          --
--              G N A T S Y N C . A S I S _ U T I L I T I E S               --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                    Copyright (C) 2007-2010, AdaCore                      --
--                                                                          --
-- GNATSYNC  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.  GNATCHECK  is  distributed in the hope that it will be useful, --
-- but  WITHOUT  ANY  WARRANTY;   without  even  the  implied  warranty  of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General --
-- Public License for more details.  You should have received a copy of the --
-- GNU  General Public License distributed with GNAT; see file  COPYING. If --
-- not,  write to the  Free Software Foundation,  51 Franklin Street, Fifth --
-- Floor, Boston, MA 02110-1301, USA.                                       --
--                                                                          --
-- GNATSYNC is maintained by AdaCore (http://www.adacore.com).              --
--                                                                          --
------------------------------------------------------------------------------

--  This package defines various ASIS secondary and extension queries for
--  gnatsync

with Asis;         use Asis;

with ASIS_UL.Misc; use ASIS_UL.Misc;

package Gnatsync.ASIS_Utilities is

   function Corresponding_Element (El : Asis.Element) return Asis.Element;
   --  For the argument Element, computes the element that is used as the basis
   --  for representation of the given entity in the call graph. The rules for
   --  defining the corresponding element are:
   --
   --  * for a task body  - the corresponding element is the body itself
   --
   --  * for a subprogram - if a separate declaration is given, the
   --                       corresponding element is the declaration, otherwise
   --                       the subprogram body, except it is a proper body for
   --                       a subunit, in this case the corresponding element
   --                       is either the corresponding declaration, if
   --                       present, or the body stub.
   --                       For inherited subprograms - the explicit
   --                       declaration of user-defined subprogram from which
   --                       the argument was ultimately inherited.
   --
   --  * for a subprogram instantiation - the instantiation itself
   --
   --  * for an expanded subprogram spec or body corresponding to a subprogram
   --    instantiation - the corresponding instantiation
   --
   --  * for a subprogram renaming:
   --     - the Corresponding_Element of the renamed subprogram, if the
   --       renaming can be resolved statically to some subprogram;
   --
   --     - An_Attribute_Reference Element if the renaming renames an
   --       attribite subprogram
   --
   --     - An_Enumeration_Literal Element if the renaming renames an
   --       enumeration literal
   --
   --     - Nil_Element for all the other cases
   --
   --     - ??? Remnaming entries as subprorgams???
   --
   --  * ,,, to be extended...
   --
   --  If the argument Element does not correspond to any of the cases
   --  described above, it is returned as the result.

   function Enclosing_Scope (El : Asis.Element) return Asis.Element;
   --  Returns the closest Is_Scope Element that encloses the argument Element

   function Get_Called_Element (El : Asis.Element) return Asis.Element;
   --  Gets the called entity declaration element from a subprogram call or
   --  function call Element

   function Get_Renamed_Subprogram (El : Asis.Element) return Asis.Element;
   --  Assuming that El is a subprogram renaming element, tries to get the
   --  declaration of renamed callable entity by unwinding renamings. If the
   --  renamed subprogram cannot be determined statically, returns Nil_Element
   --  and generates a warning message.

   function Get_Enity_Name (El : Asis.Element) return String;
   --  Returns the string image of the Entity defining name.

   function Get_Expanded_Name (El : Asis.Element) return Wide_String_Access;
   --  Provided that El is either A_Defining_Name element or A_Declaration
   --  Element, returns the string image of the corresponding  full expanded
   --  defining name. In case of a declaration element that defines more then
   --  one defining name, returns the image of the first name. The returned
   --  image does not contain any white space character
   --
   --  At the moment the function works correctly on the entities defined in
   --  library packages or in the library-level package instantiations. The
   --  function does not compute correct results for task entries and
   --  protected operations. The function returns correct result if the
   --  argument is a defining expanded name. The result name image does not
   --  start from "Standard".
   --
   --
   --
   --  ??? Move to ASIS_UL.Utilities or to Asis.Extensions???

   --------------------
   -- Test functions --
   --------------------

   function Is_Atomic (El : Asis.Element) return Boolean;
   --  Check if pragma Atomic is applied to the argument Element (that is
   --  supposed to be a variable defining name). (Note that this function does
   --  not check that the argument indeed is a variable defining name.) Returns
   --  False for any unexpected Element.
   --
   --  Expected Defining_Name_Kinds
   --     A_Defining_Identifier.

   function Is_Concurrent (El : Asis.Element) return Boolean;
   --  Checks if the argument is a defining name of a task or protected object
   --  or a declaration of an array object with task or protected components.
   --  Returns False for any unexpected element.
   --
   --  Expected Defining_Name_Kinds:
   --     A_Defining_Identifier

--   function Is_Declaration_Of_Callable_Entity
--     (El   : Asis.Element)
--      return Boolean;
   --  Use the gnatcheck version at the moment!
   --  Checks if El is a declaration of a callable entity that is of interest
   --  for our analysis. This function does not consider subprogram renamings
   --  as being declarations of callable entities - renamings are processed
   --  separately. Bodies (even if they act as specs) are also not considered
   --  as declarations of callable entities.
   --
   --  This function assumes, that it is called only in the source context that
   --  is of interest for our analyzis. That is, if it see a function
   --  declaration, it does not care if it is a protected function or if it is
   --  declared inside a generic - these possibilities are filtered out by
   --  high-level traversal control.

   function Is_Reference_To_Councurrent_Component
     (El   : Asis.Element)
      return Boolean;
   --  Checks if El is the name of a record variable from the reference to a
   --  component of this record that is of concurrent type. Returns False for
   --  any unexpected Element.
   --
   --  Consider:
   --
   --     protected type T is ... end T;
   --
   --     type Rec1 is record
   --        C1 : T;
   --     end record;
   --
   --     type Rec is record
   --        C : Rec1;
   --     end record;
   --
   --     Var_Rec : Rec;
   --
   --     ...
   --
   --     P (Var_Rec.C.C1);
   --
   --  This function returns True for identifier Var_Rec from procedure call.
   --
   --  Returns False for any unexpected Element
   --
   --  Expected Expression_Kinds:
   --     An_Identifier

   function Is_Of_No_Interest (El : Asis.Element) return Boolean;
   --  Detects if a construct is of no interest for a tool. We should not
   --  analyze non-executable constructs, such as generics and initialization
   --  expressions in the record component definitions, because they may
   --  contain calls that never executed during the program run. We also
   --  consider protected types as being completely safe, so we do not look
   --  inside at all.
   --  See the body for full details.

   function Is_Protected (El : Asis.Element) return Boolean;
   --  Checks if El is a single protected definition, a protected type
   --  definition or a protected body

   function Is_Scope (El : Asis.Element) return Boolean;
   --  Checks if the argument is a scope. See the body for the definition of
   --  the notion of scope in gnatsync.

   function Is_Subprogram_Call (El : Asis.Element) return Boolean;
   --  Checks if the argument is a subprogram call to be processed.

   function Can_Be_Accessed_By_Enclosed_Tasks
     (El   : Asis.Element)
      return Boolean;
   --  Assuming that El is of A_Variable_Declaration kind, checks if it is a
   --  non-library-level declaration that can be accessed by enclosed can be
   --  tasks, Returns False for any unexpected Element. Note that the caller
   --  should guarantee that this variable declaration indeed is not of library
   --  level, that is, it is declared in some scope (see Is_Scope for the
   --  definition of the notion of a scope)
   --
   --  Expected Declaration_Kinds:
   --     A_Variable_Declaration
   --

end Gnatsync.ASIS_Utilities;
