------------------------------------------------------------------------------
--                                                                          --
--                          GNATCHECK COMPONENTS                            --
--                                                                          --
--             G N A T C H E C K . A S I S _ U T I L I T I E S              --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                     Copyright (C) 2004-2007, AdaCore                     --
--                                                                          --
-- GNATCHECK  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.                                       --
--                                                                          --
-- GNATCHECK is maintained by AdaCore (http://www.adacore.com).             --
--                                                                          --
------------------------------------------------------------------------------

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

with Asis; use Asis;

package Gnatcheck.ASIS_Utilities is

   --------------------------------------
   -- General-purpose utility routines --
   --------------------------------------

   function Get_Root_Type (Decl : Asis.Element) return Asis.Element;
   --  Returns the root type for the object(s). All the subtypings and
   --  derivations are unwound.
   --
   --  What about private types???
   --
   --  Appropriate Declaration_Kinds:
   --       A_Variable_Declaration
   --       A_Constant_Declaration
   --       ????
   --
   --  Returns Element_Kinds:
   --       An_Ordinary_Type_Declaration
   --       A_Task_Type_Declaration
   --       ????

   function Get_Type_Components
     (El                    : Asis.Element;
      Include_Discriminants : Boolean)
      return                  Asis.Element_List;
   --  Supposing that El is either a A_Protected_Type_Declaration or
   --  (non-private!) An_Ordinary_Type_Declaration element, returns the
   --  component definitions from the type definition, if any. Returns
   --  Nil_Element_List if the type does not have components. Discriminant
   --  components are included in the result only if Include_Discriminants is
   --  set ON.
   --
   --  For a derived type or for a type extension, the result also includes
   --  implicit inherited components (so we relay on the fact that processing
   --  of implicit components is reliable enough!). Inherited discriminants are
   --  NOT collected!

   function Get_Associations (El : Asis.Element) return Asis.Element_List;
   --  Returns a list of associations from El. This function expects that
   --  El has a list of associations as its first-level components. If it is
   --  not the case, Nil_Element_List is returned
   --
   --  Expected Expression_Kinds:
   --     A_Record_Aggregate
   --     An_Extension_Aggregate
   --     A_Positional_Array_Aggregate
   --     A_Named_Array_Aggregate
   --
   --  List of expected argument kinds may be extended!!!
   --
   --  Returned Element_Kinds:
   --     An_Association

   function Get_Choices (El : Asis.Element) return Asis.Element_List;
   --  Returns a list of choices from El. This function expects that
   --  El has a list of choices as its first-level components. If it is
   --  not the case, Nil_Element_List is returned
   --
   --  Expected Association_Kinds:
   --     A_Record_Component_Association
   --     An_Array_Component_Association
   --
   --  List of expected Association_Kinds may be extended!!!
   --
   --  Returns Element_Kinds:
   --     A_Definition
   --     An_Expression
   --
   --  Returns Definition_Kinds:
   --     A_Discrete_Range
   --     An_Others_Choice

   function Get_Name_Definition (Ref : Asis.Element) return Asis.Element;
   --  Returns the name definition for Ref, unvinding all the renamings, if
   --  any. Note, that this function should be used only if a client is sure
   --  that all the possible ranemings indeed can be unwound (that is, it is
   --  safe to apply it to exception or package names, but it may blow up or
   --  return a junk result on variable name)
   --
   --  ??? Should be moved to Asis.Extensions???
   --
   --  Appropriate Expression_Kinds:
   --       An_Identifier
   --       A_Selected_Component
   --
   --  Returns Element_Kinds:
   --       Not_An_Element
   --       A_Defining_Name

   function Get_Type_Decl_From_Subtype_Mark
     (SM   : Asis.Element)
      return Asis.Element;
   --  Supposing that SM represents subtype mark that is not an attribute
   --  reference, returns the full declaration of the corresponding type,
   --  unwinding subtyping and getting the full type declaration in case of a
   --  private type. Raises ASIS_Inappropriate_Element otherwise. (Note that
   --  this function does not expect to get any incomplete type declaration
   --  as a part of processing)
   --
   --  Appropriate Expression_Kinds:
   --       An_Identifier
   --       A_Selected_Component
   --
   --  Returns Declaration_Kinds:
   --       An_Ordinary_Type_Declaration
   --       A_Task_Type_Declaration
   --       A_Protected_Type_Declaration

   function Is_Frame (El : Asis.Element) return Boolean;
   --  Checks if El contains a handled sequence of statement as its first-level
   --  component ("frame" is an old Ada-83 term for such a construct). All the
   --  Element kinds are expected.

   function Is_Indefinite_Subtype (SM : Asis.Element) return Boolean;
   --  If Sm is a subtype mark represented by a simple or e[panded name, check
   --  that the denoted subtype is indefinite. Returns False for any unexpected
   --  element (that is, returns False for an attribute reference used as a
   --  subtype mark). A caller is respondible for the fact that SN indeed is a
   --  subtype mark

   function Declaration_Of_Renamed_Entity
     (R    : Asis.Element)
      return Asis.Element;
   --  Supposing that R is a renaming declaration element, this function tries
   --  to find the declaration of the entity that is renamed (it can be another
   --  renaming declaration). If this is impossible because of any reason (the
   --  renamimg entity is a component that does not have  a separate
   --  declaration, a object, subprogram or a value pointed by an access value,
   --  etc.), Nil_Elemet is returned

   function Is_Function_Declaration (El : Asis.Element) return Boolean;
   --  Checks if El is any kind of a declaration that declares a function
   --  (actually this function checks that the declaration kind of El is in
   --  the list of returned kinds of Corresponding_Called_Function)

   function Is_Positional (El : Asis.Element) return Boolean;
   --  Checks if the argument association element is a positional association.
   --  Returns False for any unexpected element
   --
   --  Expected Element_Kinds:
   --
   --     An_Association

   function Has_Positional_Association (El : Asis.Element) return Boolean;
   --  Checks if this argument contains a positional association. At the momemt
   --  this function is implemented only for aggregates, but it may be
   --  generalized for other elements that have associations as their
   --  first-level components (subprogram and entry calls, discriminant
   --  constraints, generic instantiations)
   --
   --  Returns False for any unexpected Element
   --
   --  Expected Expression_Kinds
   --
   --     A_Record_Aggregate
   --     An_Extension_Aggregate

   function Get_Called_Ref (Call : Asis.Element) return Asis.Element;
   --  If Element is a function, procedure or entry call - returns the name
   --  of the called entity from this call. Otherwise this function raises
   --  ASIS_INAPPROPRIATE_ELEMENT, but does it without providing any proper
   --  diagnosis.

   function Get_Handlers
     (El              : Asis.Element;
      Include_Pragmas : Boolean := False)
      return            Asis.Element_List;
   --  If Is_Frame (El), returns a list of the exception handlers from El,
   --  otherwise returns Nil_Element List

   function Is_Handled
     (Exc  : Asis.Element;
      By   : Asis.Element_List)
      return Boolean;
   --  Supposing that Exc is a defining name of an exception from an exception
   --  declaration (or from exception renaming declaration), and By is a list
   --  of AN_Exception_Handler elements, checks if this exception is handled by
   --  the given list of handlers. The function does not check that its
   --  arguments are appropriate for this check, a caller is completely
   --  responsible for providing correct arguments. This bunction assumes that
   --  any actual for By parameter is a list or exception handlers obtained
   --  from some construct, that is, if it contains a handler with OTHERS
   --  choice, then this is the last handler in the argument list, and in this
   --  case the result is TRUE.

   function Unwind_Derivations_And_Subtyping
     (Decl : Asis.Element)
      return Asis.Element;
   --  Provided that Decl is of An_Ordinary_Type_Declaration or
   --  A_Subtype_Declaration kind (a caller is responsible for providing the
   --  appropriate Element), unvinds all derivations and subtypings, returning
   --  the type declaration that defines all the type properties of the
   --  argument type. Type extensions are also unwound.

   ---------------------------------------
   -- Routines used by individual rules --
   ---------------------------------------

   function Can_Be_Replaced_With_Function
     (Decl : Asis.Element)
      return Boolean;
   --  Checks if its argument element is a procedure that can be rewritten as
   --  a function. A procedure is considered as being replaced with an
   --  equivalent function if it has exactly one non-limited paramenet of OUT
   --  mode, and no parameter of IN OUT mode. Returns False for any unexpected
   --  element
   --
   --  Expected Declaration_Kinds:
   --     A_Procedure_Declaration
   --     A_Procedure_Body_Declaration
   --     A_Procedure_Body_Stub
   --     A_Generic_Procedure_Declaration
   --     A_Formal_Function_Declaration

   function Normalize_Reference (Ref : Asis.Element) return Asis.Element;
   --  This function is supposed to be called for the ASIS Elements
   --  representing a subtype mark. A subtype mark can be represented by
   --  an Element of one of the tree following kinds:
   --
   --       An_Identifier
   --       A_Selected_Component
   --       An_Attribute_Reference
   --
   --  This function "prepares" its argument for applying the ASIS
   --  Corresponding_Name_Definition and Corresponding_Name_Declaration
   --  queries, that is, returns its argument if it is of An_Identifier kind,
   --  returns the selector of the argument if it is of A_Selected_Component
   --  kind, and applies itself to the attribute prefix in case of
   --  An_Attribute_Reference

   function First_Name (Dcl : Asis.Element) return Asis.Element;
   --  Returns the first defining name from an argument declaration.
   --
   --  Appropriate Element_Kinds:
   --     A_Declaration

   function Get_Corresponding_Definition
     (El   : Asis.Element)
      return Asis.Element;
   --  Similar to the ASIS Corresponding_Name_Definition, but in case if in is
   --  not possible to get a single defining name for the argument, returns
   --  Nil_Element instead of raising Asis_Inappropriate_Element

   function Get_Parameter_Declaration (El : Asis.Element) return Asis.Element;
   --  Supposing that El is of A_Parameter_Association kind and the called
   --  entity is not an attribute subprogram (that is we have a possibility
   --  to get the profile of the called entity), gets the declaration of the
   --  corresponding formal parameter.

   function Is_Boolean_Logical_Op (Op : Asis.Element) return Boolean;
   --  Checks if Op is a reference to a logical operation of a Boolean (that
   --  is, Standard.Boolean or derived thereof) type. returns False for any
   --  unexpecyed Element
   --
   --  Expected Operator_Kinds:
   --     An_And_Operator
   --     An_Or_Operator
   --     An_Xor_Operator

   function Is_Control_Structure (Stmt : Asis.Element) return Boolean;
   --  Checks if its argument is a control structure (according to the
   --  definition of the control structure in Control_Structure_Nesting rule).
   --  Returns False for any unexpected element
   --
   --  Expected Element_Kinds:
   --     A_Statement

   function Is_Controlled (Type_Name : Asis.Element) return Boolean;
   --  Provided that  Type_Name is A_Defining_Identifier Element, checks if
   --  this is a defining name of a controlled type. This function is
   --  implemented as an extension query, it extracts the needed information
   --  directly from the tree.

   function Is_Predefined (Operation : Asis.Element) return Boolean;
   --  Check if Operation denotes a predefined operation. Returns False for
   --  any unexpected element. Also returns False if Operation is an ambiguous
   --  reference to more than one entity.
   --
   --  Expected Expression_Kinds:
   --     An_Operator_Symbol

   function Is_Float (Expr : Asis.Element) return Boolean;
   --  Check if Expr is of float type.
   --  Returns False for any unexpected element
   --
   --  Expected Element_Kinds:
   --     An_Expression (should be Asis.Extensions.Is_True_Expression)

   function Is_From_Standard (El : Asis.Element) return Boolean;
   --  Checks if its argument belongs to the predefined Standard package. Any
   --  non-null Element is expected

   function Is_Public (Def_Name : Asis.Element) return Boolean;
   --  Checks if Def_Name can be referenced from another compilation unit.
   --  Returns False for any unexpected element,
   --
   --  Expected Element_Kinds:
   --     A_Defining_Name

   function Is_Ref_To_Standard_Num_Subtype
     (Ref  : Asis.Element)
      return Boolean;
   --  Supposing that Ref is of An_Identifier kind, checks if it is a reference
   --  to a predefined numeric (sub)type defined in Standard.
   --  See Gnatcheck.Rules.Custom_1.Predef_Num_Types.

   function Is_Standard_Boolean (Expr : Asis.Element) return Boolean;
   --  Check if Expr is of the type Standard.Boolean.
   --  Returns False for any unexpected element
   --
   --  Expected Element_Kinds:
   --     An_Expression (should be Asis.Extensions.Is_True_Expression)

   function Is_Unconstrained_Array (Type_Decl : Asis.Element) return Boolean;
   --  Check if Type_Decl is the declaration of an unconstrained array type or
   --  subtype. A type derived from an unconstrained array (sub)type is also
   --  considered as an unconstrained array type.
   --  Returns False for any unexpected element
   --
   --  Expected Declaration_Kinds:
   --     An_Ordinary_Type_Declaration
   --     A_Subtype_Declaration

   function Is_Volatile (Def_Name : Asis.Element) return Boolean;
   --  Checks if Def_Name denotes a volatile data object. See comments to
   --  the rule Volatile_Requires_Addr_Clause in Gnatcheck.Rules.Default
   --  for the precise definition of the notion of a volatile object.
   --  This function is supposed to be used for this rule only.
   --
   --  Returns False for any unexpected element
   --
   --  Expected Defining_Name_Kinds:
   --     A_Defining_Identifier

   function Contains_Loop (El : Asis.Element) return Boolean;
   --  Supposing that El is of A_Statement or A_Path kind, checks if it
   --  contains a loop statement. Declarations (that may be a part of enclosed
   --  block statements) are not considered. Returns False for any unexpected
   --  argument
   --
   --  Expected Element_Kinds:
   --
   --    A_Statement
   --    A_Path

   function Has_Address_Clause (Def_Name : Asis.Element) return Boolean;
   --  Checks if the argument is a defining name to which the address clause
   --  is applied. Returns False for any unexpected element
   --
   --  Expected Defining_Name_Kinds:
   --     A_Defining_Identifier

   function Has_Statements_And_Decls (Decl : Asis.Element) return Boolean;
   --  Checks that the argument package body declarations has both non-empty
   --  declaration and statement sequences. Returns False for any unexpected
   --  Element
   --
   --  Expected Declaration_Kinds:
   --     A_Package_Body_Declaration

   function Get_Call_Element return Asis.Element;
   --  Supposing that the top of the traversal stack is a function name, this
   --  function tries to locate the corresponding function call. Note, that
   --  this function uses the traversal stack to go up the syntax structure, so
   --  it is safe to use it only in the Pre- and Post-operations to get the
   --  call element for the currently visied element. Note also, that the
   --  result may be not a function call (for example, if the argument is an
   --  operation symbol that is a pragma argument), so the caller is
   --  responsible for checking the result.

   function Call_Parameters (Call : Asis.Element) return Asis.Element_List;
   --  Supposing that Call is a procedure, function or entry call, returns
   --  a (non-normalized) list of parameter associations from the call. This
   --  function checks if its argument is an appropriate element for getting
   --  the association list only by applying the corresponding assertion, if
   --  assertions are OFF, Nil_Element_List is returned for an unappropriate
   --  argument element.

   function Called_Profile (Call : Asis.Element) return Asis.Element_List;
   --  Supposing that Call is a procedure, function or entry call, returns
   --  a list of parameter specifications that statically correspond to the
   --  called entity (in case of a dispatching call this list is taken from the
   --  declaration of the corresponding subprogram, in case of dynamic call
   --  through the access-to-subprogram value - from the corresponding access
   --  definition. This function checks if its argument is an appropriate
   --  element for getting the called profile only by applying the
   --  corresponding assertion, if assertions are OFF, Nil_Element_List is
   --  returned for an unappropriate argument element.
   --
   --  Returns Nil_Element_List in case of a call to a predefined operator.
   --
   --  ??? Needs more testing!!!

   ----------------------------------------------------------------------
   -- Routines used for creating and analyzing of the global structure --
   ----------------------------------------------------------------------

   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 Global Structure
   --
   --    Argument Element    Result Element
   --
   --     Body                         corresponding spec, if any, otherwise
   --                                  the argument element is returned
   --
   --     A_Procedure_Declaration      the argument Element
   --     A_Function_Declaration
   --     A_Single_Task_Declaration
   --     A_Task_Type_Declaration
   --     A_Protected_Type_Declaration
   --     A_Defining_Identifier

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

   function Changed_Element (El : Asis.Element) return Asis.Element;
   --  Supposing that El represents a name of a data object (???), tries
   --  to locate the Element representing the defining name of the (whole)
   --  object (that is, returns the defining name of a variable in case if
   --  El a reference to a component, and so on)

   function Get_Called_Element (Call : Asis.Element) return Asis.Element;
   --  Supposing that the argument Is_Call, tries to compute the called
   --  element, depending on the kind of the call. If the called element
   --  can be detected, returns Corresponding_Element for it, otherwise
   --  returns Nil_Element.
   --
   --  What about calls to attribute subprograms in case when the corresponding
   --  attribute is predefined???

   function Corresponding_Protected_Object
     (Pref : Asis.Element)
      return Asis.Element;
   --  Provided that Pref is a prefix name from a protected operation call,
   --  defines the declaration of the protected object the called operation
   --  belongs to.
   --  For a protected object declared by a single protected declaration, this
   --  function returns this declaration, otherwise the defining name of a
   --  protected object is returned.
   --
   --  ??? Protected objects that are parts of other data structures???

   function Is_Non_Executable_Construct (El : Asis.Element) return Boolean;
   --  Checks if its argument is a non-executable construct. We are interested
   --  in constructs that can contain subprogram calls but that can never
   --  result in issuing real calls (generic declarations and bodies, type
   --  declarations, parameter profiles)

   function Is_Exec_Call (El : Asis.Element) return Boolean;
   --  Checks if El is a subprogram or entry call.

   function Is_Task_Entry_Call (Call : Asis.Element) return Boolean;
   --  Provided that Call is of An_Entry_Call_Statement kind, check that the
   --  called entry is a task entry.

   function Is_Protected_Operation_Call (Call : Asis.Element) return Boolean;
   --  Provided that Call is of A_Function_Call, A_Procedure_Call_Statement or
   --  An_Entry_Call_Statement kind, check that the called entity is a
   --  protected operation.

   function Can_Have_Elab_Calls (El : Asis.Element) return Boolean;
   --  Checks if El is construct that can issue a subprogram or entry calls as
   --  a result of its elaboration

   function Can_Cause_Side_Effect (El : Asis.Element) return Boolean;
   --  Checks if the argument can cause a side effect. (That is, the
   --  execution/evaluation/elaboration of a construct can change any data
   --  object).
   --
   --  This function partly duplicates duplicates the routine that computes a
   --  side effect level (???), we introduce it at the development stage
   --  to get some structurable and maintainable design of the side effect
   --  problem

   function Is_Renaming (El : Asis.Element) return Boolean;
   --  Checks if El is a renaming that is of interest for a call graph.

   function Is_Scope (El : Asis.Element) return Boolean;
   --  Checks if El is a scope in the Call Graph sense - that is, an executable
   --  body of an entity that can be called by another entities and that itself
   --  can call other entities. We also consider as scopes library-level
   --  packages and library-level package instantiations.

   function Is_Caller (El : Asis.Element) return Boolean;
   --  Checks if El is an entity that can call another entity. Each scope is
   --  a caller, but here we also consider program unit specs. Moreover, two
   --  different task objects are two different callers even if they are of the
   --  same task type.
   --  ??? What about routines that can be called? Are we consider each caller
   --  entity as the entity that can be called by another caller? What about
   --  library-level packages and library-level package instantiations.

   function Is_Template_Caller (El : Asis.Element) return Boolean;
   --  Checks if El is a "template" for entities that can call another entity
   --  and/or called by another entity. For example, a task type or a protected
   --  operation is such a template.

   function Is_Task_Creation (El : Asis.Element) return Boolean;
   --  Check if a new task object can be created as a result of elaboration of
   --  the argument object. Note that we are considering a task as a callable
   --  entity, and creation a task means calling this entity

   function Is_Call_To_Predefined_Operation
     (Call : Asis.Element)
      return Boolean;
   --  Checks if the argument is a call to a predefined operation

   function Is_Predefined_Operation_Renaming
     (Ren  : Asis.Element)
      return Boolean;
   --  Checks if the argument is a renaming of a predefined operation (returns
   --  true for undirect predefined operators renamings as well)

   function Is_Dynamic_Call (Call : Asis.Element) return Boolean;
   --  Checks if the argument is a dynamic (but not dispatching!) call.
   --  Dynamic means that the calling entity cannot be statically determined
   --  (what else can we have here except the call through the access to
   --  a procedure or to a function?)

   function Is_Body (El : Asis.Element) return Boolean;
   --  Checks if the argument element is a body element from the point of view
   --  of the call graph

   function Is_Call_To_Attribute_Subprogram
     (El   : Asis.Element)
      return Boolean;
   --  Checks if the argument element is a call to an attribute subprogram,
   --  this check is used if ASIS returns Nil_Element as the corresponding
   --  called subprogram

   function Is_Call_To_Operator_Function (El : Asis.Element) return Boolean;
   --  Checks if the argument element is a call to an operator function, if the
   --  argument represents a call to operator function in prefix form, such as
   --  "+" (I, J), the result is also True. Returns False for any unexpected
   --  argument.
   --
   --  Expected Expression_Kinds:
   --     A_Function_Call

   function Is_Enum_Literal_Renaming (El : Asis.Element) return Boolean;
   --  Checks if the argument element is a renaming declaration and the renamed
   --  entity is an enumeration literal (the renamed entity does not have
   --  to be statically determined!)

   function Is_Prefix_Notation_Exception (El : Asis.Element) return Boolean;
   --  This function checks if its argument is one of two exception cases for
   --  Positional_Parameter_Associations rule, related to prefix notation
   --  for primitive operations of tagged types. The first exception case
   --  corresponds to the first parameter of a call that uses prefixed
   --  notation - it is always has a positional association. The second
   --  exception is a second parameter of the call, if the called subprogram
   --  has exactly two parameters (that is, to Parameter in
   --
   --    Object.Operation (Parameter)
   --
   --  This function assumes that Is_Prefix_Notation is True for
   --  Enclosing_Element of his argument.

   function Has_One_Parameter (El : Asis.Element) return Boolean;
   --  Checks that its argument element is a subprogram/entry call and the
   --  called entity has exactly one formal parameter.  Returns False for any
   --  unexpected argument.
   --
   --  Expected Expression_Kinds:
   --     A_Function_Call
   --
   --  Expected Statement_Kinds:
   --     A_Procedure_Call_Statement
   --     An_Entry_Call_Statement

   function Needs_Completion (El : Asis.Element) return Boolean;
   --  Checks if its argument needs a completion

   function Get_Body_Name (El : Asis.Element) return String;
   --  This function tries to define the (full normalized) name of the source
   --  file containing the body of the unit that is
   --  Enclosing_Compilation_Unit (El). There are two special cases here:
   --
   --  - because of some reasons a body of a library package may be represented
   --    by some tree created for anoter unit. If this body instantiates
   --    generics, then this tree does not contain the expanded bodies for
   --    these generics, and we can get these expanded bodies only from the
   --    tree ctreates for the given package body. In that situation this
   --    function may be called for El that is from a body unit, and it should
   --    return the name of the given body unit;
   --
   --  - if a library package that does not need (and does not have) a body
   --    contains a generic instantiation, then the expanded body for this
   --    instantiation is created only in the tree created for the given
   --    library package. In that case this function returns the name of this
   --    spec file.
   --
   --  ??? Should be revised when a general project support is implemented!!!

   function Get_Whole_Object (El : Asis.Element) return Asis.Element;
   --  Supposing thay El is A_Selected_Component Element (and it indeed
   --  represents a true expression), returns the part of this expanded name
   --  that represents the whole data object (the argument can be either a
   --  subcomponent or an expanded name of some data object). The result should
   --  be of An_Identifier kind.
   --  Returns Nil_Element if returning An_Identifier Element representing the
   --  whole data object is impossible because of any reason (???)
   --  (For the rule about side effects)

   function Used_To_Pass_Actual_Subpr (El : Asis.Element) return Boolean;
   --  Checks if the argument is an artificial subprogram renaming used to pass
   --  the actual subprogram into expanded generic instantiation.

   function Call_To_Complicated_Cuncurrent_Structure
     (Call : Asis.Element)
      return Boolean;
   --  This function actually defines the limitations imposed on the complexity
   --  of the calls to protected operations and task entries. If it returns
   --  True, that means that the given call can not be represented in the call
   --  graph and used for checking the global rules.
   --
   --  The current limitations are rather strong - the task or protected object
   --  the called entry or protected operation belongs to should be declared
   --  either by single task/protected declarations or by an object declaration
   --  with a subtype mark denoting a task or protected type or a type derived
   --  from a task or protected type.
   --
   --  This function does not check that its argument is a call to a protected
   --  operation or a task entry.

end Gnatcheck.ASIS_Utilities;
