OSDN Git Service

New Language: Ada
[pf3gnuchains/gcc-fork.git] / gcc / ada / repinfo.ads
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              R E P I N F O                               --
6 --                                                                          --
7 --                                 S p e c                                  --
8 --                                                                          --
9 --                            $Revision: 1.20 $
10 --                                                                          --
11 --          Copyright (C) 1999-2001 Free Software Foundation, Inc.          --
12 --                                                                          --
13 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
14 -- terms of the  GNU General Public License as published  by the Free Soft- --
15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
16 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
19 -- for  more details.  You should have  received  a copy of the GNU General --
20 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
21 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
22 -- MA 02111-1307, USA.                                                      --
23 --                                                                          --
24 -- As a special exception,  if other files  instantiate  generics from this --
25 -- unit, or you link  this unit with other files  to produce an executable, --
26 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
27 -- covered  by the  GNU  General  Public  License.  This exception does not --
28 -- however invalidate  any other reasons why  the executable file  might be --
29 -- covered by the  GNU Public License.                                      --
30 --                                                                          --
31 -- GNAT was originally developed  by the GNAT team at  New York University. --
32 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
33 --                                                                          --
34 ------------------------------------------------------------------------------
35
36 --  This package contains the routines to handle back annotation of the
37 --  tree to fill in representation information, and also the routine used
38 --  by -gnatR to print this information. This unit is used both in the
39 --  compiler and in ASIS (it is used in ASIS as part of the implementation
40 --  of the data decomposition annex.
41
42 with Types; use Types;
43 with Uintp; use Uintp;
44
45 package Repinfo is
46
47    --------------------------------
48    -- Representation Information --
49    --------------------------------
50
51    --  The representation information of interest here is size and
52    --  component information for arrays and records. For primitive
53    --  types, the front end computes the Esize and RM_Size fields of
54    --  the corresponding entities as constant non-negative integers,
55    --  and the Uint values are stored directly in these fields.
56
57    --  For composite types, there are three cases:
58
59    --    1. In some cases the front end knows the values statically,
60    --       for example in the ase where representation clauses or
61    --       pragmas specify the values.
62
63    --    2. If Backend_Layout is True, then the backend is responsible
64    --       for layout of all types and objects not laid out by the
65    --       front end. This includes all dynamic values, and also
66    --       static values (e.g. record sizes) when not set by the
67    --       front end.
68
69    --    3. If Backend_Layout is False, then the front end lays out
70    --       all data, according to target dependent size and alignment
71    --       information, creating dynamic inlinable functions where
72    --       needed in the case of sizes not known till runtime.
73
74    -----------------------------
75    -- Back-Annotation by Gigi --
76    -----------------------------
77
78    --  The following interface is used by gigi if Backend_Layout is True.
79
80    --  As part of the processing in gigi, the types are laid out and
81    --  appropriate values computed for the sizes and component positions
82    --  and sizes of records and arrays.
83
84    --  The back-annotation circuit in gigi is responsible for updating the
85    --  relevant fields in the tree to reflect these computations, as follows:
86
87    --    For E_Array_Type entities, the Component_Size field
88
89    --    For all record and array types and subtypes, the Esize field,
90    --    which contains the Size (more accurately the Object_SIze) value
91    --    for the type or subtype.
92
93    --    For E_Component and E_Distriminant entities, the Esize (size
94    --    of component) and Component_Bit_Offset fields. Note that gigi
95    --    does not (yet ???) back annotate Normalized_Position/First_Bit.
96
97    --  There are three cases to consider:
98
99    --    1. The value is constant. In this case, the back annotation works
100    --       by simply storing the non-negative universal integer value in
101    --       the appropriate field corresponding to this constant size.
102
103    --    2. The value depends on variables other than discriminants of the
104    --       current record. In this case, the value is not known, even if
105    --       the complete data of the record is available, and gigi marks
106    --       this situation by storing the special value No_Uint.
107
108    --    3. The value depends on the discriminant values for the current
109    --       record. In this case, gigi back annotates the field with a
110    --       representation of the expression for computing the value in
111    --       terms of the discriminants. A negative Uint value is used to
112    --       represent the value of such an expression, as explained in
113    --       the following section.
114
115    --  GCC expressions are represented with a Uint value that is negative.
116    --  See the body of this package for details on the representation used.
117
118    --  One other case in which gigi back annotates GCC expressions is in
119    --  the Present_Expr field of an N_Variant node. This expression which
120    --  will always depend on discriminants, and hence always be represented
121    --  as a negative Uint value, provides an expression which, when evaluated
122    --  with a given set of discriminant values, indicates whether the variant
123    --  is present for that set of values (result is True, i.e. non-zero) or
124    --  not present (result is False, i.e. zero).
125
126    subtype Node_Ref is Uint;
127    --  Subtype used for negative Uint values used to represent nodes
128
129    subtype Node_Ref_Or_Val is Uint;
130    --  Subtype used for values that can either be a Node_Ref (negative)
131    --  or a value (non-negative)
132
133    type TCode is range 0 .. 27;
134    --  Type used on Ada side to represent DEFTREECODE values defined in
135    --  tree.def. Only a subset of these tree codes can actually appear.
136    --  The names are the names from tree.def in Ada casing.
137
138    --  name                             code   description           operands
139
140    Cond_Expr        : constant TCode :=  1; -- conditional              3
141    Plus_Expr        : constant TCode :=  2; -- addition                 2
142    Minus_Expr       : constant TCode :=  3; -- subtraction              2
143    Mult_Expr        : constant TCode :=  4; -- multiplication           2
144    Trunc_Div_Expr   : constant TCode :=  5; -- truncating division      2
145    Ceil_Div_Expr    : constant TCode :=  6; -- division rounding up     2
146    Floor_Div_Expr   : constant TCode :=  7; -- division rounding down   2
147    Trunc_Mod_Expr   : constant TCode :=  8; -- mod for trunc_div        2
148    Ceil_Mod_Expr    : constant TCode :=  9; -- mod for ceil_div         2
149    Floor_Mod_Expr   : constant TCode := 10; -- mod for floor_div        2
150    Exact_Div_Expr   : constant TCode := 11; -- exact div                2
151    Negate_Expr      : constant TCode := 12; -- negation                 1
152    Min_Expr         : constant TCode := 13; -- minimum                  2
153    Max_Expr         : constant TCode := 14; -- maximum                  2
154    Abs_Expr         : constant TCode := 15; -- absolute value           1
155    Truth_Andif_Expr : constant TCode := 16; -- Boolean and then         2
156    Truth_Orif_Expr  : constant TCode := 17; -- Boolean or else          2
157    Truth_And_Expr   : constant TCode := 18; -- Boolean and              2
158    Truth_Or_Expr    : constant TCode := 19; -- Boolean or               2
159    Truth_Xor_Expr   : constant TCode := 20; -- Boolean xor              2
160    Truth_Not_Expr   : constant TCode := 21; -- Boolean not              1
161    Lt_Expr          : constant TCode := 22; -- comparision <            2
162    Le_Expr          : constant TCode := 23; -- comparision <=           2
163    Gt_Expr          : constant TCode := 24; -- comparision >            2
164    Ge_Expr          : constant TCode := 25; -- comparision >=           2
165    Eq_Expr          : constant TCode := 26; -- comparision =            2
166    Ne_Expr          : constant TCode := 27; -- comparision /=           2
167
168    --  The following entry is used to represent a discriminant value in
169    --  the tree. It has a special tree code that does not correspond
170    --  directly to a gcc node. The single operand is the number of the
171    --  discriminant in the record (1 = first discriminant).
172
173    Discrim_Val : constant TCode := 0;  -- discriminant value       1
174
175    ------------------------
176    -- The gigi Interface --
177    ------------------------
178
179    --  The following declarations are for use by gigi for back annotation
180
181    function Create_Node
182      (Expr  : TCode;
183       Op1   : Node_Ref_Or_Val;
184       Op2   : Node_Ref_Or_Val := No_Uint;
185       Op3   : Node_Ref_Or_Val := No_Uint)
186       return  Node_Ref;
187    --  Creates a node with using the tree code defined by Expr and from
188    --  1-3 operands as required (unused operands set as shown to No_Uint)
189    --  Note that this call can be used to create a discriminant reference
190    --  by using (Expr => Discrim_Val, Op1 => discriminant_number).
191
192    function Create_Discrim_Ref
193      (Discr : Entity_Id)
194       return  Node_Ref;
195    --  Creates a refrerence to the discriminant whose entity is Discr.
196
197    --------------------------------------------------------
198    -- Front-End Interface for Dynamic Size/Offset Values --
199    --------------------------------------------------------
200
201    --  If Backend_Layout is False, then the front-end deals with all
202    --  dynamic size and offset fields. There are two cases:
203
204    --    1. The value can be computed at the time of type freezing, and
205    --       is stored in a run-time constant. In this case, the field
206    --       contains a reference to this entity. In the case of sizes
207    --       the value stored is the size in storage units, since dynamic
208    --       sizes are always a multiple of storage units.
209
210    --    2. The size/offset depends on the value of discriminants at
211    --       run-time. In this case, the front end builds a function to
212    --       compute the value. This function has a single parameter
213    --       which is the discriminated record object in question. Any
214    --       references to discriminant values are simply references to
215    --       the appropriate discriminant in this single argument, and
216    --       to compute the required size/offset value at run time, the
217    --       code generator simply constructs a call to the function
218    --       with the appropriate argument. The size/offset field in
219    --       this case contains a reference to the function entity.
220    --       Note that as for case 1, if such a function is used to
221    --       return a size, then the size in storage units is returned,
222    --       not the size in bits.
223
224    --  The interface here allows these created entities to be referenced
225    --  using negative Unit values, so that they can be stored in the
226    --  appropriate size and offset fields in the tree.
227
228    --  In the case of components, if the location of the component is static,
229    --  then all four fields (Component_Bit_Offset, Normalized_Position, Esize,
230    --  and Normalized_First_Bit) are set to appropraite values. In the case of
231    --  a non-static component location, Component_Bit_Offset is not used and
232    --  is left set to Unknown. Normalized_Position and Normalized_First_Bit
233    --  are set appropriately.
234
235    subtype SO_Ref is Uint;
236    --  Type used to represent a Uint value that represents a static or
237    --  dynamic size/offset value (non-negative if static, negative if
238    --  the size value is dynamic).
239
240    subtype Dynamic_SO_Ref is Uint;
241    --  Type used to represent a negative Uint value used to store
242    --  a dynamic size/offset value.
243
244    function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean;
245    pragma Inline (Is_Dynamic_SO_Ref);
246    --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
247    --  represents a dynamic Size/Offset value (i.e. it is negative).
248
249    function Is_Static_SO_Ref (U : SO_Ref) return Boolean;
250    pragma Inline (Is_Static_SO_Ref);
251    --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
252    --  represents a static Size/Offset value (i.e. it is non-negative).
253
254    function Create_Dynamic_SO_Ref
255      (E    : Entity_Id)
256       return Dynamic_SO_Ref;
257    --  Given the Entity_Id for a constant (case 1), the Node_Id for an
258    --  expression (case 2), or the Entity_Id for a function (case 3),
259    --  this function returns a (negative) Uint value that can be used
260    --  to retrieve the entity or expression for later use.
261
262    function Get_Dynamic_SO_Entity
263      (U    : Dynamic_SO_Ref)
264       return Entity_Id;
265    --  Retrieve the Node_Id or Entity_Id stored by a previous call to
266    --  Create_Dynamic_SO_Ref. The approach is that the front end makes
267    --  the necessary Create_Dynamic_SO_Ref calls to associate the node
268    --  and entity id values and the back end makes Get_Dynamic_SO_Ref
269    --  calls to retrive them.
270
271    --------------------
272    -- ASIS_Interface --
273    --------------------
274
275    type Discrim_List is array (Pos range <>) of Uint;
276    --  Type used to represent list of discriminant values
277
278    function Rep_Value
279      (Val  : Node_Ref_Or_Val;
280       D    : Discrim_List)
281       return Uint;
282    --  Given the contents of a First_Bit_Position or Esize field containing
283    --  a node reference (i.e. a negative Uint value) and D, the list of
284    --  discriminant values, returns the interpreted value of this field.
285    --  For convenience, Rep_Value will take a non-negative Uint value
286    --  as an argument value, and return it unmodified. A No_Uint value is
287    --  also returned unmodified.
288
289    procedure Tree_Read;
290    --  Read in the value of the Rep_Table
291
292    ------------------------
293    -- Compiler Interface --
294    ------------------------
295
296    procedure List_Rep_Info;
297    --  Procedure to list representation information
298
299    procedure Tree_Write;
300    --  Write out the value of the Rep_Table
301
302    --------------------------
303    -- Debugging Procedures --
304    --------------------------
305
306    procedure List_GCC_Expression (U : Node_Ref_Or_Val);
307    --  Prints out given expression in symbolic form. Constants are listed
308    --  in decimal numeric form, Discriminants are listed with a # followed
309    --  by the discriminant number, and operators are output in appropriate
310    --  symbolic form No_Uint displays as two question marks. The output is
311    --  on a single line but has no line return after it. This procedure is
312    --  useful only if operating in backend layout mode.
313
314    procedure lgx (U : Node_Ref_Or_Val);
315    --  In backend layout mode, this is like List_GCC_Expression, but
316    --  includes a line return at the end. If operating in front end
317    --  layout mode, then the name of the entity for the size (either
318    --  a function of a variable) is listed followed by a line return.
319
320 end Repinfo;