File : repinfo.ads


   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-2014, 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 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  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 variables other than discriminants of the
 100    --       current record. In this case, the value is not known, even if
 101    --       the complete data of the record is available, and gigi marks
 102    --       this situation by storing the special value No_Uint.
 103 
 104    --    3. The value depends on the discriminant values for the current
 105    --       record. In this case, gigi back annotates the field with a
 106    --       representation of the expression for computing the value in
 107    --       terms of the discriminants. A negative Uint value is used to
 108    --       represent the value of such an expression, as explained in
 109    --       the following section.
 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 .. 28;
 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 number of the
 178    --  discriminant in the record (1 = first discriminant).
 179 
 180    Discrim_Val : constant TCode := 0;  -- discriminant value       1
 181 
 182    ------------------------
 183    -- The gigi Interface --
 184    ------------------------
 185 
 186    --  The following declarations are for use by gigi for back annotation
 187 
 188    function Create_Node
 189      (Expr : TCode;
 190       Op1  : Node_Ref_Or_Val;
 191       Op2  : Node_Ref_Or_Val := No_Uint;
 192       Op3  : Node_Ref_Or_Val := No_Uint) return Node_Ref;
 193    --  Creates a node using the tree code defined by Expr and from one to three
 194    --  operands as required (unused operands set as shown to No_Uint) Note that
 195    --  this call can be used to create a discriminant reference by using (Expr
 196    --  => Discrim_Val, Op1 => discriminant_number).
 197 
 198    function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref;
 199    --  Creates a reference to the discriminant whose entity is Discr
 200 
 201    --------------------------------------------------------
 202    -- Front-End Interface for Dynamic Size/Offset Values --
 203    --------------------------------------------------------
 204 
 205    --  If Backend_Layout is False, then the front-end deals with all
 206    --  dynamic size and offset fields. There are two cases:
 207 
 208    --    1. The value can be computed at the time of type freezing, and
 209    --       is stored in a run-time constant. In this case, the field
 210    --       contains a reference to this entity. In the case of sizes
 211    --       the value stored is the size in storage units, since dynamic
 212    --       sizes are always a multiple of storage units.
 213 
 214    --    2. The size/offset depends on the value of discriminants at
 215    --       run-time. In this case, the front end builds a function to
 216    --       compute the value. This function has a single parameter
 217    --       which is the discriminated record object in question. Any
 218    --       references to discriminant values are simply references to
 219    --       the appropriate discriminant in this single argument, and
 220    --       to compute the required size/offset value at run time, the
 221    --       code generator simply constructs a call to the function
 222    --       with the appropriate argument. The size/offset field in
 223    --       this case contains a reference to the function entity.
 224    --       Note that as for case 1, if such a function is used to
 225    --       return a size, then the size in storage units is returned,
 226    --       not the size in bits.
 227 
 228    --  The interface here allows these created entities to be referenced
 229    --  using negative Unit values, so that they can be stored in the
 230    --  appropriate size and offset fields in the tree.
 231 
 232    --  In the case of components, if the location of the component is static,
 233    --  then all four fields (Component_Bit_Offset, Normalized_Position, Esize,
 234    --  and Normalized_First_Bit) are set to appropriate values. In the case of
 235    --  a non-static component location, Component_Bit_Offset is not used and
 236    --  is left set to Unknown. Normalized_Position and Normalized_First_Bit
 237    --  are set appropriately.
 238 
 239    subtype SO_Ref is Uint;
 240    --  Type used to represent a Uint value that represents a static or
 241    --  dynamic size/offset value (non-negative if static, negative if
 242    --  the size value is dynamic).
 243 
 244    subtype Dynamic_SO_Ref is Uint;
 245    --  Type used to represent a negative Uint value used to store
 246    --  a dynamic size/offset value.
 247 
 248    function Is_Dynamic_SO_Ref (U : SO_Ref) return Boolean;
 249    pragma Inline (Is_Dynamic_SO_Ref);
 250    --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
 251    --  represents a dynamic Size/Offset value (i.e. it is negative).
 252 
 253    function Is_Static_SO_Ref (U : SO_Ref) return Boolean;
 254    pragma Inline (Is_Static_SO_Ref);
 255    --  Given a SO_Ref (Uint) value, returns True iff the SO_Ref value
 256    --  represents a static Size/Offset value (i.e. it is non-negative).
 257 
 258    function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref;
 259    --  Given the Entity_Id for a constant (case 1), the Node_Id for an
 260    --  expression (case 2), or the Entity_Id for a function (case 3),
 261    --  this function returns a (negative) Uint value that can be used
 262    --  to retrieve the entity or expression for later use.
 263 
 264    function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id;
 265    --  Retrieve the Node_Id or Entity_Id stored by a previous call to
 266    --  Create_Dynamic_SO_Ref. The approach is that the front end makes
 267    --  the necessary Create_Dynamic_SO_Ref calls to associate the node
 268    --  and entity id values and the back end makes Get_Dynamic_SO_Ref
 269    --  calls to retrieve them.
 270 
 271    --------------------
 272    -- ASIS_Interface --
 273    --------------------
 274 
 275    type Discrim_List is array (Pos range <>) of Uint;
 276    --  Type used to represent list of discriminant values
 277 
 278    function Rep_Value
 279      (Val : Node_Ref_Or_Val;
 280       D   : Discrim_List) return Uint;
 281    --  Given the contents of a First_Bit_Position or Esize field containing
 282    --  a node reference (i.e. a negative Uint value) and D, the list of
 283    --  discriminant values, returns the interpreted value of this field.
 284    --  For convenience, Rep_Value will take a non-negative Uint value
 285    --  as an argument value, and return it unmodified. A No_Uint value is
 286    --  also returned unmodified.
 287 
 288    procedure Tree_Read;
 289    --  Initializes internal tables from current tree file using the relevant
 290    --  Table.Tree_Read routines.
 291 
 292    ------------------------
 293    -- Compiler Interface --
 294    ------------------------
 295 
 296    procedure List_Rep_Info (Bytes_Big_Endian : Boolean);
 297    --  Procedure to list representation information. Bytes_Big_Endian is the
 298    --  value from Ttypes (Repinfo cannot have a dependency on Ttypes).
 299 
 300    procedure Tree_Write;
 301    --  Writes out internal tables to current tree file using the relevant
 302    --  Table.Tree_Write routines.
 303 
 304    --------------------------
 305    -- Debugging Procedures --
 306    --------------------------
 307 
 308    procedure List_GCC_Expression (U : Node_Ref_Or_Val);
 309    --  Prints out given expression in symbolic form. Constants are listed
 310    --  in decimal numeric form, Discriminants are listed with a # followed
 311    --  by the discriminant number, and operators are output in appropriate
 312    --  symbolic form No_Uint displays as two question marks. The output is
 313    --  on a single line but has no line return after it. This procedure is
 314    --  useful only if operating in backend layout mode.
 315 
 316    procedure lgx (U : Node_Ref_Or_Val);
 317    --  In backend layout mode, this is like List_GCC_Expression, but
 318    --  includes a line return at the end. If operating in front end
 319    --  layout mode, then the name of the entity for the size (either
 320    --  a function of a variable) is listed followed by a line return.
 321 
 322 end Repinfo;