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