1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1999-2023, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
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.
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
33 with Types
; use Types
;
34 with Uintp
; use Uintp
;
38 --------------------------------
39 -- Representation Information --
40 --------------------------------
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.
48 -- For composite types, there are two cases:
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.
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
59 -----------------------------
60 -- Back Annotation by Gigi --
61 -----------------------------
63 -- The following interface is used by gigi
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.
69 -- The back-annotation circuit in gigi is responsible for updating the
70 -- relevant fields in the tree to reflect these computations, as follows:
72 -- For E_Array_Type entities, the Component_Size field
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.
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.
82 -- There are three cases to consider:
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.
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.
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.
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
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.
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.
121 subtype Node_Ref
is Unegative
;
122 -- Subtype used for negative Uint values used to represent nodes
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.
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.
133 -- name code description operands symbol
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 &
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).
167 Discrim_Val
: constant TCode
:= 0; -- discriminant value 1 #
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.
174 Dynamic_Val
: constant TCode
:= 27; -- dynamic value 1 var
176 ----------------------------
177 -- The JSON output format --
178 ----------------------------
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.
185 -- The output is an array of entities
187 -- An entity is an object whose members are pairs taken from:
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 numerical expressions
200 -- "Small" : numerical expression
201 -- "Alignment" : number
202 -- "Convention" : string
203 -- "Linker_Section" : string
204 -- "Bit_Order" : string
205 -- "Scalar_Storage_Order" : string
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.
221 -- A component is an object whose members are pairs taken from:
224 -- "discriminant" : number
225 -- "Position" : numerical expression
226 -- "First_Bit" : number
227 -- "Size" : numerical expression
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.
238 -- A variant is an object whose members are pairs taken from:
240 -- "present" : numerical expression
241 -- "record" : array of components
242 -- "variant" : array of variants
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, with the exception that a value of 1 means
248 -- that the components of the variant are contained in the record type
249 -- only when the "present" member of all the preceding variants in the
250 -- variant list evaluates to false. The value of "record" is the list of
251 -- components in the variant. "variant" is present only if the variant
252 -- itself has a variant part and its value is the list of (sub)variants.
254 -- A formal parameter is an object whose members are pairs taken from:
257 -- "mechanism" : string
259 -- The two pairs are present for every formal parameter. "name" comes
260 -- from the declaration of the parameter in the subprogram or entry
261 -- and its value is the unqualified Ada name. The value of "mechanism"
262 -- is the passing mechanism for the parameter set by the language.
264 -- A numerical expression is either a number or an object whose members
265 -- are pairs taken from:
268 -- "operands" : array of numerical expressions
270 -- The two pairs are present for every such object. The value of "code"
271 -- is a symbol taken from the table defining the TCode type above. The
272 -- number of elements of the value of "operands" is specified by the
273 -- operands column in the line associated with the symbol in the table.
275 -- As documented above, the full back annotation is only done in -gnatR3.
276 -- In the other cases, if the numerical expression is not a number, then
277 -- it is replaced with the "??" string.
279 ------------------------
280 -- The gigi Interface --
281 ------------------------
283 -- The following declarations are for use by gigi for back annotation
287 Op1
: Node_Ref_Or_Val
;
288 Op2
: Node_Ref_Or_Val
:= No_Uint
;
289 Op3
: Node_Ref_Or_Val
:= No_Uint
) return Node_Ref
;
290 -- Creates a node using the tree code defined by Expr and from one to three
291 -- operands as required (unused operands set as shown to No_Uint) Note that
292 -- this call can be used to create a discriminant reference by using (Expr
293 -- => Discrim_Val, Op1 => discriminant_number).
295 function Create_Discrim_Ref
(Discr
: Entity_Id
) return Node_Ref
;
296 -- Creates a reference to the discriminant whose entity is Discr
298 --------------------------------------------------------
299 -- Front-End Interface for Dynamic Size/Offset Values --
300 --------------------------------------------------------
302 -- This interface is used by GNAT LLVM to deal with all dynamic size and
305 -- The interface here allows these created entities to be referenced
306 -- using negative Unit values, so that they can be stored in the
307 -- appropriate size and offset fields in the tree.
309 -- In the case of components, if the location of the component is static,
310 -- then all four fields (Component_Bit_Offset, Normalized_Position, Esize,
311 -- and Normalized_First_Bit) are set to appropriate values. In the case of
312 -- a nonstatic component location, Component_Bit_Offset is not used and
313 -- is left set to Unknown. Normalized_Position and Normalized_First_Bit
314 -- are set appropriately.
316 subtype SO_Ref
is Uint
;
317 -- Type used to represent a Uint value that represents a static or
318 -- dynamic size/offset value (non-negative if static, negative if
319 -- the size value is dynamic).
321 subtype Dynamic_SO_Ref
is Uint
;
322 -- Type used to represent a negative Uint value used to store
323 -- a dynamic size/offset value.
325 function Is_Dynamic_SO_Ref
(U
: SO_Ref
) return Boolean;
326 pragma Inline
(Is_Dynamic_SO_Ref
);
327 -- Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
328 -- represents a dynamic Size/Offset value (i.e. it is negative).
330 function Is_Static_SO_Ref
(U
: SO_Ref
) return Boolean;
331 pragma Inline
(Is_Static_SO_Ref
);
332 -- Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
333 -- represents a static Size/Offset value (i.e. it is non-negative).
335 function Create_Dynamic_SO_Ref
(E
: Entity_Id
) return Dynamic_SO_Ref
;
336 -- Given the Entity_Id for a constant (case 1), the Node_Id for an
337 -- expression (case 2), or the Entity_Id for a function (case 3),
338 -- this function returns a (negative) Uint value that can be used
339 -- to retrieve the entity or expression for later use.
341 function Get_Dynamic_SO_Entity
(U
: Dynamic_SO_Ref
) return Entity_Id
;
342 -- Retrieve the Node_Id or Entity_Id stored by a previous call to
343 -- Create_Dynamic_SO_Ref. The approach is that the front end makes
344 -- the necessary Create_Dynamic_SO_Ref calls to associate the node
345 -- and entity id values and the back end makes Get_Dynamic_SO_Ref
346 -- calls to retrieve them.
348 ------------------------------
349 -- External tools Interface --
350 ------------------------------
352 type Discrim_List
is array (Pos
range <>) of Uint
;
353 -- Type used to represent list of discriminant values
355 function Rep_Value
(Val
: Node_Ref_Or_Val
; D
: Discrim_List
) return Uint
;
356 -- Given the contents of a First_Bit_Position or Esize field containing
357 -- a node reference (i.e. a negative Uint value) and D, the list of
358 -- discriminant values, returns the interpreted value of this field.
359 -- For convenience, Rep_Value will take a non-negative Uint value
360 -- as an argument value, and return it unmodified. A No_Uint value is
361 -- also returned unmodified.
363 ------------------------
364 -- Compiler Interface --
365 ------------------------
367 procedure List_Rep_Info
(Bytes_Big_Endian
: Boolean);
368 -- Procedure to list representation information. Bytes_Big_Endian is the
369 -- value from Ttypes (Repinfo cannot have a dependency on Ttypes).
371 --------------------------
372 -- Debugging Procedures --
373 --------------------------
375 procedure List_GCC_Expression
(U
: Node_Ref_Or_Val
);
376 -- Prints out given expression in symbolic form. Constants are listed
377 -- in decimal numeric form, Discriminants are listed with a # followed
378 -- by the discriminant number, and operators are output in appropriate
379 -- symbolic form No_Uint displays as two question marks. The output is
380 -- on a single line but has no line return after it. This procedure is
381 -- useful only if operating in backend layout mode.
383 procedure lgx
(U
: Node_Ref_Or_Val
);
384 -- In backend layout mode, this is like List_GCC_Expression, but
385 -- includes a line return at the end. If operating in front end
386 -- layout mode, then the name of the entity for the size (either
387 -- a function of a variable) is listed followed by a line return.