Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/repinfo.ads @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
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-2017, 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 routine used | |
34 -- by -gnatR to print 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 | |
38 with Types; use Types; | |
39 with Uintp; use Uintp; | |
40 | |
41 package 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 Backend_Layout is True, 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 Backend_Layout is False, 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 Backend_Layout is True | |
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 field, | |
86 -- which contains the Size (more accurately the Object_Size) value | |
87 -- 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 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 .. 29; | |
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 | |
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 division 2 | |
151 Ceil_Div_Expr : constant TCode := 6; -- division rounding up 2 | |
152 Floor_Div_Expr : constant TCode := 7; -- division rounding down 2 | |
153 Trunc_Mod_Expr : constant TCode := 8; -- mod for trunc_div 2 | |
154 Ceil_Mod_Expr : constant TCode := 9; -- mod for ceil_div 2 | |
155 Floor_Mod_Expr : constant TCode := 10; -- mod for floor_div 2 | |
156 Exact_Div_Expr : constant TCode := 11; -- exact div 2 | |
157 Negate_Expr : constant TCode := 12; -- negation 1 | |
158 Min_Expr : constant TCode := 13; -- minimum 2 | |
159 Max_Expr : constant TCode := 14; -- maximum 2 | |
160 Abs_Expr : constant TCode := 15; -- absolute value 1 | |
161 Truth_Andif_Expr : constant TCode := 16; -- Boolean and then 2 | |
162 Truth_Orif_Expr : constant TCode := 17; -- Boolean or else 2 | |
163 Truth_And_Expr : constant TCode := 18; -- Boolean and 2 | |
164 Truth_Or_Expr : constant TCode := 19; -- Boolean or 2 | |
165 Truth_Xor_Expr : constant TCode := 20; -- Boolean xor 2 | |
166 Truth_Not_Expr : constant TCode := 21; -- Boolean not 1 | |
167 Lt_Expr : constant TCode := 22; -- comparison < 2 | |
168 Le_Expr : constant TCode := 23; -- comparison <= 2 | |
169 Gt_Expr : constant TCode := 24; -- comparison > 2 | |
170 Ge_Expr : constant TCode := 25; -- comparison >= 2 | |
171 Eq_Expr : constant TCode := 26; -- comparison = 2 | |
172 Ne_Expr : constant TCode := 27; -- comparison /= 2 | |
173 Bit_And_Expr : constant TCode := 28; -- Binary and 2 | |
174 | |
175 -- The following entry is used to represent a discriminant value in | |
176 -- the tree. It has a special tree code that does not correspond | |
177 -- directly to a GCC node. The single operand is the index number | |
178 -- of the discriminant in the record (1 = first discriminant). | |
179 | |
180 Discrim_Val : constant TCode := 0; -- discriminant value 1 | |
181 | |
182 -- The following entry is used to represent a value not known at | |
183 -- compile time in the tree, other than a discriminant value. It | |
184 -- has a special tree code that does not correspond directly to | |
185 -- a GCC node. The single operand is an arbitrary index number. | |
186 | |
187 Dynamic_Val : constant TCode := 29; -- dynamic value 1 | |
188 | |
189 ------------------------ | |
190 -- The gigi Interface -- | |
191 ------------------------ | |
192 | |
193 -- The following declarations are for use by gigi for back annotation | |
194 | |
195 function Create_Node | |
196 (Expr : TCode; | |
197 Op1 : Node_Ref_Or_Val; | |
198 Op2 : Node_Ref_Or_Val := No_Uint; | |
199 Op3 : Node_Ref_Or_Val := No_Uint) return Node_Ref; | |
200 -- Creates a node using the tree code defined by Expr and from one to three | |
201 -- operands as required (unused operands set as shown to No_Uint) Note that | |
202 -- this call can be used to create a discriminant reference by using (Expr | |
203 -- => Discrim_Val, Op1 => discriminant_number). | |
204 | |
205 function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref; | |
206 -- Creates a reference to the discriminant whose entity is Discr | |
207 | |
208 -------------------------------------------------------- | |
209 -- Front-End Interface for Dynamic Size/Offset Values -- | |
210 -------------------------------------------------------- | |
211 | |
212 -- If Backend_Layout is False, then the front-end deals with all | |
213 -- dynamic size and offset fields. There are two cases: | |
214 | |
215 -- 1. The value can be computed at the time of type freezing, and | |
216 -- is stored in a run-time constant. In this case, the field | |
217 -- contains a reference to this entity. In the case of sizes | |
218 -- the value stored is the size in storage units, since dynamic | |
219 -- sizes are always a multiple of storage units. | |
220 | |
221 -- 2. The size/offset depends on the value of discriminants at | |
222 -- run-time. In this case, the front end builds a function to | |
223 -- compute the value. This function has a single parameter | |
224 -- which is the discriminated record object in question. Any | |
225 -- references to discriminant values are simply references to | |
226 -- the appropriate discriminant in this single argument, and | |
227 -- to compute the required size/offset value at run time, the | |
228 -- code generator simply constructs a call to the function | |
229 -- with the appropriate argument. The size/offset field in | |
230 -- this case contains a reference to the function entity. | |
231 -- Note that as for case 1, if such a function is used to | |
232 -- return a size, then the size in storage units is returned, | |
233 -- not the size in bits. | |
234 | |
235 -- The interface here allows these created entities to be referenced | |
236 -- using negative Unit values, so that they can be stored in the | |
237 -- appropriate size and offset fields in the tree. | |
238 | |
239 -- In the case of components, if the location of the component is static, | |
240 -- then all four fields (Component_Bit_Offset, Normalized_Position, Esize, | |
241 -- and Normalized_First_Bit) are set to appropriate values. In the case of | |
242 -- a non-static component location, Component_Bit_Offset is not used and | |
243 -- is left set to Unknown. Normalized_Position and Normalized_First_Bit | |
244 -- are set appropriately. | |
245 | |
246 subtype SO_Ref is Uint; | |
247 -- Type used to represent a Uint value that represents a static or | |
248 -- dynamic size/offset value (non-negative if static, negative if | |
249 -- the size value is dynamic). | |
250 | |
251 subtype Dynamic_SO_Ref is Uint; | |
252 -- Type used to represent a negative Uint value used to store | |
253 -- a dynamic size/offset value. | |
254 | |
255 function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean; | |
256 pragma Inline (Is_Dynamic_SO_Ref); | |
257 -- Given a SO_Ref (Uint) value, returns True iff the SO_Ref value | |
258 -- represents a dynamic Size/Offset value (i.e. it is negative). | |
259 | |
260 function Is_Static_SO_Ref (U : SO_Ref) return Boolean; | |
261 pragma Inline (Is_Static_SO_Ref); | |
262 -- Given a SO_Ref (Uint) value, returns True iff the SO_Ref value | |
263 -- represents a static Size/Offset value (i.e. it is non-negative). | |
264 | |
265 function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref; | |
266 -- Given the Entity_Id for a constant (case 1), the Node_Id for an | |
267 -- expression (case 2), or the Entity_Id for a function (case 3), | |
268 -- this function returns a (negative) Uint value that can be used | |
269 -- to retrieve the entity or expression for later use. | |
270 | |
271 function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id; | |
272 -- Retrieve the Node_Id or Entity_Id stored by a previous call to | |
273 -- Create_Dynamic_SO_Ref. The approach is that the front end makes | |
274 -- the necessary Create_Dynamic_SO_Ref calls to associate the node | |
275 -- and entity id values and the back end makes Get_Dynamic_SO_Ref | |
276 -- calls to retrieve them. | |
277 | |
278 -------------------- | |
279 -- ASIS_Interface -- | |
280 -------------------- | |
281 | |
282 type Discrim_List is array (Pos range <>) of Uint; | |
283 -- Type used to represent list of discriminant values | |
284 | |
285 function Rep_Value | |
286 (Val : Node_Ref_Or_Val; | |
287 D : Discrim_List) return Uint; | |
288 -- Given the contents of a First_Bit_Position or Esize field containing | |
289 -- a node reference (i.e. a negative Uint value) and D, the list of | |
290 -- discriminant values, returns the interpreted value of this field. | |
291 -- For convenience, Rep_Value will take a non-negative Uint value | |
292 -- as an argument value, and return it unmodified. A No_Uint value is | |
293 -- also returned unmodified. | |
294 | |
295 procedure Tree_Read; | |
296 -- Initializes internal tables from current tree file using the relevant | |
297 -- Table.Tree_Read routines. | |
298 | |
299 ------------------------ | |
300 -- Compiler Interface -- | |
301 ------------------------ | |
302 | |
303 procedure List_Rep_Info (Bytes_Big_Endian : Boolean); | |
304 -- Procedure to list representation information. Bytes_Big_Endian is the | |
305 -- value from Ttypes (Repinfo cannot have a dependency on Ttypes). | |
306 | |
307 procedure Tree_Write; | |
308 -- Writes out internal tables to current tree file using the relevant | |
309 -- Table.Tree_Write routines. | |
310 | |
311 -------------------------- | |
312 -- Debugging Procedures -- | |
313 -------------------------- | |
314 | |
315 procedure List_GCC_Expression (U : Node_Ref_Or_Val); | |
316 -- Prints out given expression in symbolic form. Constants are listed | |
317 -- in decimal numeric form, Discriminants are listed with a # followed | |
318 -- by the discriminant number, and operators are output in appropriate | |
319 -- symbolic form No_Uint displays as two question marks. The output is | |
320 -- on a single line but has no line return after it. This procedure is | |
321 -- useful only if operating in backend layout mode. | |
322 | |
323 procedure lgx (U : Node_Ref_Or_Val); | |
324 -- In backend layout mode, this is like List_GCC_Expression, but | |
325 -- includes a line return at the end. If operating in front end | |
326 -- layout mode, then the name of the entity for the size (either | |
327 -- a function of a variable) is listed followed by a line return. | |
328 | |
329 end Repinfo; |