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