home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
exp_util.ads
< prev
next >
Wrap
Text File
|
1996-09-28
|
17KB
|
317 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- E X P _ U T I L --
-- --
-- S p e c --
-- --
-- $Revision: 1.58 $ --
-- --
-- Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
-- Package containing utility procedures used throughout the expander
with Snames; use Snames;
with Rtsfind; use Rtsfind;
with Types; use Types;
package Exp_Util is
------------------------
-- Multi-Use Facility --
------------------------
-- It is often the case that an expression appears only once in the code
-- but must be referenced many times by the expanded code without being
-- evaluated more than once. This package provides an abstraction that
-- satisfies this requirement. Such an expression is represented by an
-- object of type Exp_Id that is initialized with Prepare or New_Exp_Id
-- then each reference to the expression is done with New_Ref.
-- Multi-Use may be used both for expressions of the form of names, in
-- which case a reference to the named object is captured, or for the
-- case of simple values, in which case the value is captured.
package Multi_Use is
type Exp_Id is private;
procedure Prepare
(Exp : Node_Id;
Res : out Exp_Id;
Code : out List_Id;
Name_Req : Boolean := False);
-- Given an Exp, create an new Exp_Id (Res) that can be used later for
-- new references to this expression without forcing a re-evaluation.
-- For simple cases, no special code is generated and Code is set to
-- No_List. For complex cases, Code is a sequence of code that creates
-- a temporary to be referenced in copies. The code must be elaborated
-- before any of the copies are elaborated. The Name_Req parameter is
-- set to true if the input Exp is a name, and the resulting copies
-- must also be names (this is true if at least one of the copies is
-- to be used as a name, e.g. on the left side of an assignment). If
-- Name_Req is False, the normal case, then the assumption is that the
-- result is only referenced for its value, and need not be a name.
procedure New_Exp_Id
(Exp : Node_Id;
N : Node_Id;
Res : out Exp_Id;
Name_Req : Boolean := False);
-- Same as Prepare but the code is inserted before N and analyzed.
-- Typically, N is the instruction containing Exp.
procedure New_Exp_Id
(Exp : Node_Id;
L : List_Id;
Res : out Exp_Id;
Name_Req : Boolean := False);
-- Same as Prepare but the code is inserted at the end of L and not
-- analyzed. Typically L is the Actions of an expression_actions.
function New_Ref (E : Exp_Id) return Node_Id;
-- Return a new reference to an expression referenced by E
function Wrap (Code : List_Id; N : Node_Id) return Node_Id;
-- Given a code list returned by a call to Prepare, and a node N
-- for an expression typically containing references constructed
-- using New_Ref, returns the node unchanged if the code list is
-- empty, and otherwise returns an expression actions node which
-- contains the required code.
private
type Exp_Id is new Node_Id;
-- Exp_Id references a node which can be used by New_Ref the first
-- time unchanged, and which then must be copied using New_Copy_Tree
-- for subsequent calls to New_Ref. In simple cases, where copying
-- has no semantic effect, e.g. a simple variable reference, this
-- is simply the original expression node, but in cases where the
-- copy would have a semantic effect (i.e. the cases in which the
-- use of Multi_Use is critical), Exp_Id points to a new safely
-- copyable node (which is e.g. an identifier for a temporary entity
-- constructed to hold the value).
end Multi_Use;
-----------------------------------------------
-- Handling of Actions Associated with Nodes --
-----------------------------------------------
-- The evaluation of certain expression nodes involves the elaboration
-- of associated types and other declarations, and the execution of
-- statement sequences. The tree node N_Expression_Actions is used in
-- the tree to represent this semantic requirement. However these nodes
-- appear only temporarily in the tree, since if code is being generated,
-- Gigi expects that all expression actions nodes must be removed from
-- the tree, since it does not have the capability of handling complex
-- declarations in the middle of evaluation of an expression.
-- This means that the expansion routine for expression actions nodes must
-- find an appropriate place in the tree to rehang the actions so that they
-- will be evaluated at the appropriate point.
-- Some cases are simple:
-- For an expression occurring in a simple statement that is in a list
-- of statements, the actions are simply inserted into the list before
-- the associated statement.
-- For an expression occurring in a declaration (declarations always
-- appear in lists), the actions are similarly inserted into the list
-- just before the associated declaration.
-- The following special cases arise:
-- For actions associated with the right operand of a short circuit
-- form, the actions are first stored in the short circuit form node
-- in the Actions field. The expansion of these forms subsequently
-- expands the short circuit forms into if statements which can then
-- be moved as described above.
-- For actions appearing in the Condition expression of a while loop,
-- or an elsif clause, the actions are similarly temporarily stored in
-- in the node (N_Elsif_Part or N_Iteration_Scheme) associated with
-- the expression using the Condition_Actions field. Sunsequently, the
-- expansion of these nodes rewrites the control structures involved to
-- reposition the actions in normal statement sequence.
-- For actions appearing in the then or else expression of a conditional
-- expression, these actions are similarly placed in the node, using the
-- Then_Actions or Else_Actions field as appropriate. Once again the
-- expansion of the N_Conditional_Expression node rewrites the node so
-- that the actions can be normally positioned.
-- Basically what we do is to climb up to the tree looking for the proper
-- insertion point, as described by one of the above cases.
-- In addition to the actions of expression actions nodes, the definition
-- of implicit types (i.e. the N_Implicit_Type node) that are associated
-- with expression actions must also be inserted in the tree in a similar
-- manner.
-- Note: in some cases, actions are inserted directly without first being
-- placed in expression actions nodes.
procedure Insert_Action
(Assoc_Node : Node_Id; Ins_Action : Node_Id);
procedure Insert_Action
(Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id);
procedure Insert_Actions
(Assoc_Node : Node_Id; Ins_Actions : List_Id);
procedure Insert_Actions
(Assoc_Node : Node_Id; Ins_Actions : List_Id; Suppress : Check_Id);
-- These routines are used to promote a single action or list of actions
-- to the top level. Typical actions that are promoted in this way are
-- the declaration of an Itype, or the actions of an expression actions
-- node. For an exact definition of what top-level means, see body. The
-- first argument is the node to which the action is originally attached.
-- No_List is a valid argument for Actions and results in nothing being
-- done. These routines also analyze the actions once attached, so they
-- return with the actions analyzed. If a Suppress argument is given,
-- then the analysis is done with the specified check suppressed, which
-- can be All_Checks to suppress all checks.
-----------------------
-- Other Subprograms --
-----------------------
function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id;
-- Build an N_Procedure_Call_Statement calling the given runtime entity.
-- The call has no parameters. The first argument provides the location
-- information for the tree and for error messages. The call node is not
-- analyzed on return, the caller is responsible for analyzing it.
type Compare_Result is (LT, LE, EQ, NE, GT, GE, Unknown);
function Compile_Time_Compare (L, R : Node_Id) return Compare_Result;
-- Given two expression nodes, finds out whether it can be determined
-- at compile time how the runtime values will compare. An Unknown
-- result means that the result of a comparison cannot be determined at
-- compile time, otherwise the returned result indicates the known result
-- of the comparison, given as tightly as possible (i.e. EQ or LT is a
-- preferred returned value to LE). This routine is only used in cases
-- where the caller knows that the expression types are scalar.
function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id;
-- Returns an expression that represents the result of a checked convert
-- of expression Exp to type T. If the base type of Exp is T, then no
-- conversion is required, and Exp is returned unchanged. Otherwise an
-- N_Type_Conversion node is constructed to convert the expression.
-- If an N_Type_Conversion node is required, Relocate_Node is used on
-- Exp. This means that it is safe to replace a node by a Convert_To
-- of itself to some other type.
function Unchecked_Convert_To
(Typ : Entity_Id;
Expr : Node_Id)
return Node_Id;
-- Like Convert_To, but if a conversion is actually needed, constructs
-- an N_Unchecked_Type_Conversion node to do the required conversion.
function Convert_To_Actual_Subtype (Exp : Node_Id) return Node_Id;
-- The Etype of an expression is the nominal type of the expression,
-- not the actual subtype. Often these are the same, but not always.
-- For example, a reference to a formal of unconstrained type has the
-- unconstrained type as its Etype, but the actual subtype is obtained
-- by applying the actual bounds. This routine is given an expression,
-- Exp, and (if necessary), replaces it using Rewrite_Substitute_Tree,
-- with a conversion to the actual subtype, building the actual subtype
-- if necessary. The returned value is the possibly modified expression
-- (which will always have the same Node_Id as Exp). Exp is analyzed and
-- resolved on entry and on exit.
function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id;
-- Find the first primitive operation of type T whose name is 'Name'.
-- this function allows the use of a primitive operation which is not
-- directly visible
procedure Expand_Subtype_From_Expr
(N : Node_Id;
Unc_Type : Entity_Id;
Subtype_Indic : Node_Id;
Exp : Node_Id);
-- Build a constrained subtype from the initial value in object
-- declarations and/or allocations when the type is indefinite (including
-- class-wide).
procedure Expand_Tagged_Copy
(N : Node_Id;
Lhs : Multi_Use.Exp_Id;
Rhs : Multi_Use.Exp_Id;
Typ : Entity_Id);
-- Expand the code for copying the value of Rhs to Lhs. The arguments are
-- entities rather than expressions because this procedure is
-- used in conjunction with prepare_multi_use_of_Exp. The value of a
-- tagged type excludes its tag. If the type is controlled it also excludes
-- the finalization pointers
procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id);
-- Add a new freeze action for the given type. The freeze action is
-- attached to the freeze node for the type. Actions will be elaborated
-- in the order in which they are added. Note that the added node is not
-- analyzed. The analyze call is found in Sem_Ch13.Expand_N_Freeze_Entity.
procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id);
-- Adds the given list of freeze actions (declarations or statements)
-- for the given type. The freeze actions are attached to the freeze
-- node for the type. Actions will be elaborated in the order in which
-- they are added, and the actions within the list will be elaborated in
-- list order. Note that the added nodes are not analyzed. The analyze
-- call is found in Sem_Ch13.Expand_N_Freeze_Entity.
procedure Wrap_Cleanup_Procedure (N : Node_Id);
-- Given an N_Subprogram_Body node, this procedure adds an Abort_Defer
-- call at the start of the statement sequence, and an Abort_Undefer call
-- at the end of the statement sequence. All cleanup routines (i.e. those
-- that are called from "at end" handlers) must defer abort on entry and
-- undefer abort on exit. Note that it is assumed that the code for the
-- procedure does not contain any return statements which would allow the
-- flow of control to escape doing the undefer call.
procedure Remove_Side_Effects
(Exp : Node_Id;
Name_Req : Boolean := False);
-- Given the node for a subexpression, this function replaces the node
-- if necessary by an equivalent subexpression that is guaranteed to be
-- side effect free. This is done by extracting any actions that could
-- cause side effects, and inserting them using Insert_Actions into the
-- tree to which Exp is attached. Exp must be analayzed and resolved
-- before the call and is analyzed and resolved on return. The Name_Req
-- may only be set to True if Exp has the form of a name, and the effect
-- is to guarantee that any replacement maintains the form of a name.
function Duplicate_Subexpr
(Exp : Node_Id;
Name_Req : Boolean := False)
return Node_Id;
-- Given the node for a subexpression, this function makes a logical
-- copy of the subexpression, and returns it. This is intended for use
-- when the expansion of an expression needs to repeat part of it. For
-- example, replacing a**2 by a*a requires two references to a which
-- may be a complex subexpression. Duplicate_Subexpression guarantees
-- not to duplicate side effects. If necessary, it generates actions
-- to save the expression value in a temporary, inserting these actions
-- into the tree using Insert_Actions with Exp as the insertion location.
-- The original expression and the returned result then become references
-- to this saved value. Exp must be analyzed on entry. On return, Exp
-- is analyzed, but the caller is responsible for analyzing the returned
-- copy after it is attached to the tree. The Name_Req flag is set to
-- ensure that the result is suitable for use in a context requiring a
-- name (e.g. the prefix of an attribute reference).
-- Note: this will eventually replace multi-use completely ???
end Exp_Util;