1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                              R E P I N F O                               --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 1999-2019, Free Software Foundation, Inc.         --
10--                                                                          --
11-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12-- terms of the  GNU General Public License as published  by the Free Soft- --
13-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
17--                                                                          --
18-- As a special exception under Section 7 of GPL version 3, you are granted --
19-- additional permissions described in the GCC Runtime Library Exception,   --
20-- version 3.1, as published by the Free Software Foundation.               --
21--                                                                          --
22-- You should have received a copy of the GNU General Public License and    --
23-- a copy of the GCC Runtime Library Exception along with this program;     --
24-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25-- <http://www.gnu.org/licenses/>.                                          --
26--                                                                          --
27-- GNAT was originally developed  by the GNAT team at  New York University. --
28-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29--                                                                          --
30------------------------------------------------------------------------------
31
32--  This package contains the routines to handle back annotation of the
33--  tree to fill in representation information, and also the routines used
34--  by -gnatR to output this information. This unit is used both in the
35--  compiler and in ASIS (it is used in ASIS as part of the implementation
36--  of the Data Decomposition Annex).
37
38with Types; use Types;
39with Uintp; use Uintp;
40
41package Repinfo is
42
43   --------------------------------
44   -- Representation Information --
45   --------------------------------
46
47   --  The representation information of interest here is size and
48   --  component information for arrays and records. For primitive
49   --  types, the front end computes the Esize and RM_Size fields of
50   --  the corresponding entities as constant non-negative integers,
51   --  and the Uint values are stored directly in these fields.
52
53   --  For composite types, there are three cases:
54
55   --    1. In some cases the front end knows the values statically,
56   --       for example in the case where representation clauses or
57   --       pragmas specify the values.
58
59   --    2. If Frontend_Layout is False, then the backend is responsible
60   --       for layout of all types and objects not laid out by the
61   --       front end. This includes all dynamic values, and also
62   --       static values (e.g. record sizes) when not set by the
63   --       front end.
64
65   --    3. If Frontend_Layout is True, then the front end lays out
66   --       all data, according to target dependent size and alignment
67   --       information, creating dynamic inlinable functions where
68   --       needed in the case of sizes not known till runtime.
69
70   -----------------------------
71   -- Back Annotation by Gigi --
72   -----------------------------
73
74   --  The following interface is used by gigi if Frontend_Layout is False
75
76   --  As part of the processing in gigi, the types are laid out and
77   --  appropriate values computed for the sizes and component positions
78   --  and sizes of records and arrays.
79
80   --  The back-annotation circuit in gigi is responsible for updating the
81   --  relevant fields in the tree to reflect these computations, as follows:
82
83   --    For E_Array_Type entities, the Component_Size field
84
85   --    For all record and array types and subtypes, the Esize and RM_Size
86   --    fields, which respectively contain the Object_Size and Value_Size
87   --    values for the type or subtype.
88
89   --    For E_Component and E_Discriminant entities, the Esize (size
90   --    of component) and Component_Bit_Offset fields. Note that gigi
91   --    does not generally back annotate Normalized_Position/First_Bit.
92
93   --  There are three cases to consider:
94
95   --    1. The value is constant. In this case, the back annotation works
96   --       by simply storing the non-negative universal integer value in
97   --       the appropriate field corresponding to this constant size.
98
99   --    2. The value depends on the discriminant values for the current
100   --       record. In this case, gigi back annotates the field with a
101   --       representation of the expression for computing the value in
102   --       terms of the discriminants. A negative Uint value is used to
103   --       represent the value of such an expression, as explained in
104   --       the following section.
105
106   --    3. The value depends on variables other than discriminants of the
107   --       current record. In this case, gigi also back annotates the field
108   --       with a representation of the expression for computing the value
109   --       in terms of the variables represented symbolically.
110
111   --  Note: the extended back annotation for the dynamic case is needed only
112   --  for -gnatR3 output, and for proper operation of the ASIS DDA. Since it
113   --  can be expensive to do this back annotation (for discriminated records
114   --  with many variable-length arrays), we only do the full back annotation
115   --  in -gnatR3 mode, or ASIS mode. In any other mode, the back-end just sets
116   --  the value to Uint_Minus_1, indicating that the value of the attribute
117   --  depends on discriminant information, but not giving further details.
118
119   --  GCC expressions are represented with a Uint value that is negative.
120   --  See the body of this package for details on the representation used.
121
122   --  One other case in which gigi back annotates GCC expressions is in
123   --  the Present_Expr field of an N_Variant node. This expression which
124   --  will always depend on discriminants, and hence always be represented
125   --  as a negative Uint value, provides an expression which, when evaluated
126   --  with a given set of discriminant values, indicates whether the variant
127   --  is present for that set of values (result is True, i.e. non-zero) or
128   --  not present (result is False, i.e. zero). Again, the full annotation of
129   --  this field is done only in -gnatR3 mode or in ASIS mode, and in other
130   --  modes, the value is set to Uint_Minus_1.
131
132   subtype Node_Ref is Uint;
133   --  Subtype used for negative Uint values used to represent nodes
134
135   subtype Node_Ref_Or_Val is Uint;
136   --  Subtype used for values that can either be a Node_Ref (negative)
137   --  or a value (non-negative)
138
139   type TCode is range 0 .. 27;
140   --  Type used on Ada side to represent DEFTREECODE values defined in
141   --  tree.def. Only a subset of these tree codes can actually appear.
142   --  The names are the names from tree.def in Ada casing.
143
144   --  name                             code   description     operands  symbol
145
146   Cond_Expr        : constant TCode :=  1; -- conditional          3      ?<>
147   Plus_Expr        : constant TCode :=  2; -- addition             2        +
148   Minus_Expr       : constant TCode :=  3; -- subtraction          2        -
149   Mult_Expr        : constant TCode :=  4; -- multiplication       2        *
150   Trunc_Div_Expr   : constant TCode :=  5; -- truncating div       2       /t
151   Ceil_Div_Expr    : constant TCode :=  6; -- div rounding up      2       /c
152   Floor_Div_Expr   : constant TCode :=  7; -- div rounding down    2       /f
153   Trunc_Mod_Expr   : constant TCode :=  8; -- mod for trunc_div    2     modt
154   Ceil_Mod_Expr    : constant TCode :=  9; -- mod for ceil_div     2     modc
155   Floor_Mod_Expr   : constant TCode := 10; -- mod for floor_div    2     modf
156   Exact_Div_Expr   : constant TCode := 11; -- exact div            2       /e
157   Negate_Expr      : constant TCode := 12; -- negation             1        -
158   Min_Expr         : constant TCode := 13; -- minimum              2      min
159   Max_Expr         : constant TCode := 14; -- maximum              2      max
160   Abs_Expr         : constant TCode := 15; -- absolute value       1      abs
161   Truth_And_Expr   : constant TCode := 16; -- boolean and          2      and
162   Truth_Or_Expr    : constant TCode := 17; -- boolean or           2       or
163   Truth_Xor_Expr   : constant TCode := 18; -- boolean xor          2      xor
164   Truth_Not_Expr   : constant TCode := 19; -- boolean not          1      not
165   Lt_Expr          : constant TCode := 20; -- comparison <         2        <
166   Le_Expr          : constant TCode := 21; -- comparison <=        2       <=
167   Gt_Expr          : constant TCode := 22; -- comparison >         2        >
168   Ge_Expr          : constant TCode := 23; -- comparison >=        2       >=
169   Eq_Expr          : constant TCode := 24; -- comparison =         2       ==
170   Ne_Expr          : constant TCode := 25; -- comparison /=        2       !=
171   Bit_And_Expr     : constant TCode := 26; -- bitwise and          2        &
172
173   --  The following entry is used to represent a discriminant value in
174   --  the tree. It has a special tree code that does not correspond
175   --  directly to a GCC node. The single operand is the index number
176   --  of the discriminant in the record (1 = first discriminant).
177
178   Discrim_Val      : constant TCode :=  0;  -- discriminant value  1        #
179
180   --  The following entry is used to represent a value not known at
181   --  compile time in the tree, other than a discriminant value. It
182   --  has a special tree code that does not correspond directly to
183   --  a GCC node. The single operand is an arbitrary index number.
184
185   Dynamic_Val      : constant TCode := 27;  -- dynamic value       1      var
186
187   ----------------------------
188   -- The JSON output format --
189   ----------------------------
190
191   --  The representation information can be output to a file in the JSON
192   --  data interchange format specified by the ECMA-404 standard. In the
193   --  following description, the terminology is that of the JSON syntax
194   --  from the ECMA document and of the JSON grammar from www.json.org.
195
196   --  The output is a concatenation of entities
197
198   --  An entity is an object whose members are pairs taken from:
199
200   --    "name"                 :  string
201   --    "location"             :  string
202   --    "record"               :  array of components
203   --    "variant"              :  array of variants
204   --    "formal"               :  array of formal parameters
205   --    "mechanism"            :  string
206   --    "Size"                 :  numerical expression
207   --    "Object_Size"          :  numerical expression
208   --    "Value_Size"           :  numerical expression
209   --    "Component_Size"       :  numerical expression
210   --    "Range"                :  array of numbers
211   --    "Small"                :  number
212   --    "Alignment"            :  number
213   --    "Convention"           :  string
214   --    "Linker_Section"       :  string
215   --    "Bit_Order"            :  string
216   --    "Scalar_Storage_Order" :  string
217
218   --    "name" and "location" are present for every entity and come from the
219   --    declaration of the associated Ada entity. The value of "name" is the
220   --    fully qualified Ada name. The value of "location" is the expanded
221   --    chain of instantiation locations that contains the entity.
222   --    "record" is present for every record type and its value is the list of
223   --    components. "variant" is present only if the record type has a variant
224   --    part and its value is the list of variants.
225   --    "formal" is present for every subprogram and entry, and its value is
226   --    the list of formal parameters. "mechanism" is present for functions
227   --    only and its value is the return mechanim.
228   --    The other pairs may be present when the eponymous aspect/attribute is
229   --    defined for the Ada entity, and their value is set by the language.
230
231   --  A component is an object whose members are pairs taken from:
232
233   --    "name"                 :  string
234   --    "discriminant"         :  number
235   --    "Position"             :  numerical expression
236   --    "First_Bit"            :  number
237   --    "Size"                 :  numerical expression
238
239   --    "name" is present for every component and comes from the declaration
240   --    of the type; its value is the unqualified Ada name. "discriminant" is
241   --    present only if the component is a discriminant, and its value is the
242   --    ranking of the discriminant in the list of discriminants of the type,
243   --    i.e. an integer index ranging from 1 to the number of discriminants.
244   --    The other three pairs are present for every component and come from
245   --    the layout of the type; their value is the value of the eponymous
246   --    attribute set by the language.
247
248   --  A variant is an object whose members are pairs taken from:
249
250   --    "present"              :  numerical expression
251   --    "record"               :  array of components
252   --    "variant"              :  array of variants
253
254   --    "present" and "record" are present for every variant. The value of
255   --    "present" is a boolean expression that evaluates to true when the
256   --    components of the variant are contained in the record type and to
257   --    false when they are not. The value of "record" is the list of
258   --    components in the variant. "variant" is present only if the variant
259   --    itself has a variant part and its value is the list of (sub)variants.
260
261   --  A formal parameter is an object whose members are pairs taken from:
262
263   --    "name"                 :  string
264   --    "mechanism"            :  string
265
266   --    The two pairs are present for every formal parameter. "name" comes
267   --    from the declaration of the parameter in the subprogram or entry
268   --    and its value is the unqualified Ada name. The value of "mechanism"
269   --    is the passing mechanism for the parameter set by the language.
270
271   --  A numerical expression is either a number or an object whose members
272   --  are pairs taken from:
273
274   --    "code"                 :  string
275   --    "operands"             :  array of numerical expressions
276
277   --    The two pairs are present for every such object. The value of "code"
278   --    is a symbol taken from the table defining the TCode type above. The
279   --    number of elements of the value of "operands" is specified by the
280   --    operands column in the line associated with the symbol in the table.
281
282   --    As documented above, the full back annotation is only done in -gnatR3
283   --    or ASIS mode. In the other cases, if the numerical expression is not
284   --    a number, then it is replaced with the "??" string.
285
286   ------------------------
287   -- The gigi Interface --
288   ------------------------
289
290   --  The following declarations are for use by gigi for back annotation
291
292   function Create_Node
293     (Expr : TCode;
294      Op1  : Node_Ref_Or_Val;
295      Op2  : Node_Ref_Or_Val := No_Uint;
296      Op3  : Node_Ref_Or_Val := No_Uint) return Node_Ref;
297   --  Creates a node using the tree code defined by Expr and from one to three
298   --  operands as required (unused operands set as shown to No_Uint) Note that
299   --  this call can be used to create a discriminant reference by using (Expr
300   --  => Discrim_Val, Op1 => discriminant_number).
301
302   function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref;
303   --  Creates a reference to the discriminant whose entity is Discr
304
305   --------------------------------------------------------
306   -- Front-End Interface for Dynamic Size/Offset Values --
307   --------------------------------------------------------
308
309   --  If Frontend_Layout is True, then the front-end deals with all
310   --  dynamic size and offset fields. There are two cases:
311
312   --    1. The value can be computed at the time of type freezing, and
313   --       is stored in a run-time constant. In this case, the field
314   --       contains a reference to this entity. In the case of sizes
315   --       the value stored is the size in storage units, since dynamic
316   --       sizes are always a multiple of storage units.
317
318   --    2. The size/offset depends on the value of discriminants at
319   --       run-time. In this case, the front end builds a function to
320   --       compute the value. This function has a single parameter
321   --       which is the discriminated record object in question. Any
322   --       references to discriminant values are simply references to
323   --       the appropriate discriminant in this single argument, and
324   --       to compute the required size/offset value at run time, the
325   --       code generator simply constructs a call to the function
326   --       with the appropriate argument. The size/offset field in
327   --       this case contains a reference to the function entity.
328   --       Note that as for case 1, if such a function is used to
329   --       return a size, then the size in storage units is returned,
330   --       not the size in bits.
331
332   --  The interface here allows these created entities to be referenced
333   --  using negative Unit values, so that they can be stored in the
334   --  appropriate size and offset fields in the tree.
335
336   --  In the case of components, if the location of the component is static,
337   --  then all four fields (Component_Bit_Offset, Normalized_Position, Esize,
338   --  and Normalized_First_Bit) are set to appropriate values. In the case of
339   --  a non-static component location, Component_Bit_Offset is not used and
340   --  is left set to Unknown. Normalized_Position and Normalized_First_Bit
341   --  are set appropriately.
342
343   subtype SO_Ref is Uint;
344   --  Type used to represent a Uint value that represents a static or
345   --  dynamic size/offset value (non-negative if static, negative if
346   --  the size value is dynamic).
347
348   subtype Dynamic_SO_Ref is Uint;
349   --  Type used to represent a negative Uint value used to store
350   --  a dynamic size/offset value.
351
352   function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean;
353   pragma Inline (Is_Dynamic_SO_Ref);
354   --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
355   --  represents a dynamic Size/Offset value (i.e. it is negative).
356
357   function Is_Static_SO_Ref (U : SO_Ref) return Boolean;
358   pragma Inline (Is_Static_SO_Ref);
359   --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
360   --  represents a static Size/Offset value (i.e. it is non-negative).
361
362   function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref;
363   --  Given the Entity_Id for a constant (case 1), the Node_Id for an
364   --  expression (case 2), or the Entity_Id for a function (case 3),
365   --  this function returns a (negative) Uint value that can be used
366   --  to retrieve the entity or expression for later use.
367
368   function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id;
369   --  Retrieve the Node_Id or Entity_Id stored by a previous call to
370   --  Create_Dynamic_SO_Ref. The approach is that the front end makes
371   --  the necessary Create_Dynamic_SO_Ref calls to associate the node
372   --  and entity id values and the back end makes Get_Dynamic_SO_Ref
373   --  calls to retrieve them.
374
375   --------------------
376   -- ASIS_Interface --
377   --------------------
378
379   type Discrim_List is array (Pos range <>) of Uint;
380   --  Type used to represent list of discriminant values
381
382   function Rep_Value (Val : Node_Ref_Or_Val; D : Discrim_List) return Uint;
383   --  Given the contents of a First_Bit_Position or Esize field containing
384   --  a node reference (i.e. a negative Uint value) and D, the list of
385   --  discriminant values, returns the interpreted value of this field.
386   --  For convenience, Rep_Value will take a non-negative Uint value
387   --  as an argument value, and return it unmodified. A No_Uint value is
388   --  also returned unmodified.
389
390   procedure Tree_Read;
391   --  Initializes internal tables from current tree file using the relevant
392   --  Table.Tree_Read routines.
393
394   ------------------------
395   -- Compiler Interface --
396   ------------------------
397
398   procedure List_Rep_Info (Bytes_Big_Endian : Boolean);
399   --  Procedure to list representation information. Bytes_Big_Endian is the
400   --  value from Ttypes (Repinfo cannot have a dependency on Ttypes).
401
402   procedure Tree_Write;
403   --  Writes out internal tables to current tree file using the relevant
404   --  Table.Tree_Write routines.
405
406   --------------------------
407   -- Debugging Procedures --
408   --------------------------
409
410   procedure List_GCC_Expression (U : Node_Ref_Or_Val);
411   --  Prints out given expression in symbolic form. Constants are listed
412   --  in decimal numeric form, Discriminants are listed with a # followed
413   --  by the discriminant number, and operators are output in appropriate
414   --  symbolic form No_Uint displays as two question marks. The output is
415   --  on a single line but has no line return after it. This procedure is
416   --  useful only if operating in backend layout mode.
417
418   procedure lgx (U : Node_Ref_Or_Val);
419   --  In backend layout mode, this is like List_GCC_Expression, but
420   --  includes a line return at the end. If operating in front end
421   --  layout mode, then the name of the entity for the size (either
422   --  a function of a variable) is listed followed by a line return.
423
424end Repinfo;
425