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