OSDN Git Service

2007-04-20 Arnaud Charlet <charlet@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / repinfo.adb
index 602585c..93d5fd4 100644 (file)
@@ -6,8 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                                                                          --
---          Copyright (C) 1999-2002 Free Software Foundation, Inc.          --
+--          Copyright (C) 1999-2007, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -17,8 +16,8 @@
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
+-- Boston, MA 02110-1301, USA.                                              --
 --                                                                          --
 -- As a special exception,  if other files  instantiate  generics from this --
 -- unit, or you link  this unit with other files  to produce an executable, --
 -- covered  by the  GNU  General  Public  License.  This exception does not --
 -- however invalidate  any other reasons why  the executable file  might be --
 -- covered by the  GNU Public License.                                      --
---                                                                          --
+--
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Alloc;    use Alloc;
-with Atree;    use Atree;
-with Casing;   use Casing;
-with Debug;    use Debug;
-with Einfo;    use Einfo;
-with Lib;      use Lib;
-with Namet;    use Namet;
-with Opt;      use Opt;
-with Output;   use Output;
-with Sinfo;    use Sinfo;
-with Sinput;   use Sinput;
-with Table;    use Table;
-with Uname;    use Uname;
-with Urealp;   use Urealp;
+with Alloc;  use Alloc;
+with Atree;  use Atree;
+with Casing; use Casing;
+with Debug;  use Debug;
+with Einfo;  use Einfo;
+with Lib;    use Lib;
+with Namet;  use Namet;
+with Opt;    use Opt;
+with Output; use Output;
+with Sinfo;  use Sinfo;
+with Sinput; use Sinput;
+with Snames; use Snames;
+with Stand;  use Stand;
+with Table;  use Table;
+with Uname;  use Uname;
+with Urealp; use Urealp;
+
+with Ada.Unchecked_Conversion;
 
 package body Repinfo is
 
@@ -53,23 +56,22 @@ package body Repinfo is
    --  Value for Storage_Unit, we do not want to get this from TTypes, since
    --  this introduces problematic dependencies in ASIS, and in any case this
    --  value is assumed to be 8 for the implementation of the DDA.
+
    --  This is wrong for AAMP???
 
    ---------------------------------------
    -- Representation of gcc Expressions --
    ---------------------------------------
 
-   --    This table is used only if Frontend_Layout_On_Target is False,
-   --    so that gigi lays out dynamic size/offset fields using encoded
-   --    gcc expressions.
+   --    This table is used only if Frontend_Layout_On_Target is False, so gigi
+   --    lays out dynamic size/offset fields using encoded gcc expressions.
 
-   --    A table internal to this unit is used to hold the values of
-   --    back annotated expressions. This table is written out by -gnatt
-   --    and read back in for ASIS processing.
+   --    A table internal to this unit is used to hold the values of back
+   --    annotated expressions. This table is written out by -gnatt and read
+   --    back in for ASIS processing.
 
-   --    Node values are stored as Uint values which are the negative of
-   --    the node index in this table. Constants appear as non-negative
-   --    Uint values.
+   --    Node values are stored as Uint values using the negative of the node
+   --    index in this table. Constants appear as non-negative Uint values.
 
    type Exp_Node is record
       Expr : TCode;
@@ -78,6 +80,20 @@ package body Repinfo is
       Op3  : Node_Ref_Or_Val;
    end record;
 
+   --  The following representation clause ensures that the above record
+   --  has no holes. We do this so that when instances of this record are
+   --  written by Tree_Gen, we do not write uninitialized values to the file.
+
+   for Exp_Node use record
+      Expr at  0 range 0 .. 31;
+      Op1  at  4 range 0 .. 31;
+      Op2  at  8 range 0 .. 31;
+      Op3  at 12 range 0 .. 31;
+   end record;
+
+   for Exp_Node'Size use 16 * 8;
+   --  This ensures that we did not leave out any fields
+
    package Rep_Table is new Table.Table (
       Table_Component_Type => Exp_Node,
       Table_Index_Type     => Nat,
@@ -98,26 +114,31 @@ package body Repinfo is
       Table_Increment      => Alloc.Rep_Table_Increment,
       Table_Name           => "FE_Rep_Table");
 
-   -----------------------
-   -- Local Subprograms --
-   -----------------------
-
    Unit_Casing : Casing_Type;
    --  Identifier casing for current unit
 
-   procedure Spaces (N : Natural);
-   --  Output given number of spaces
+   Need_Blank_Line : Boolean;
+   --  Set True if a blank line is needed before outputting any information for
+   --  the current entity. Set True when a new entity is processed, and false
+   --  when the blank line is output.
+
+   -----------------------
+   -- Local Subprograms --
+   -----------------------
 
    function Back_End_Layout return Boolean;
-   --  Test for layout mode, True = back end, False = front end. This
-   --  function is used rather than checking the configuration parameter
-   --  because we do not want Repinfo to depend on Targparm (for ASIS)
+   --  Test for layout mode, True = back end, False = front end. This function
+   --  is used rather than checking the configuration parameter because we do
+   --  not want Repinfo to depend on Targparm (for ASIS)
+
+   procedure Blank_Line;
+   --  Called before outputting anything for an entity. Ensures that
+   --  a blank line precedes the output for a particular entity.
 
    procedure List_Entities (Ent : Entity_Id);
-   --  This procedure lists the entities associated with the entity E,
-   --  starting with the First_Entity and using the Next_Entity link.
-   --  If a nested package is found, entities within the package are
-   --  recursively processed.
+   --  This procedure lists the entities associated with the entity E, starting
+   --  with the First_Entity and using the Next_Entity link. If a nested
+   --  package is found, entities within the package are recursively processed.
 
    procedure List_Name (Ent : Entity_Id);
    --  List name of entity Ent in appropriate case. The name is listed with
@@ -126,6 +147,10 @@ package body Repinfo is
    procedure List_Array_Info (Ent : Entity_Id);
    --  List representation info for array type Ent
 
+   procedure List_Mechanisms (Ent : Entity_Id);
+   --  List mechanism information for parameters of Ent, which is subprogram,
+   --  subprogram type, or an entry or entry family.
+
    procedure List_Object_Info (Ent : Entity_Id);
    --  List representation info for object Ent
 
@@ -139,19 +164,24 @@ package body Repinfo is
    --  Returns True if Val represents a variable value, and False if it
    --  represents a value that is fixed at compile time.
 
+   procedure Spaces (N : Natural);
+   --  Output given number of spaces
+
    procedure Write_Info_Line (S : String);
-   --  Routine to write a line to Repinfo output file. This routine is
-   --  passed as a special output procedure to Output.Set_Special_Output.
-   --  Note that Write_Info_Line is called with an EOL character at the
-   --  end of each line, as per the Output spec, but the internal call
-   --  to the appropriate routine in Osint requires that the end of line
-   --  sequence be stripped off.
+   --  Routine to write a line to Repinfo output file. This routine is passed
+   --  as a special output procedure to Output.Set_Special_Output. Note that
+   --  Write_Info_Line is called with an EOL character at the end of each line,
+   --  as per the Output spec, but the internal call to the appropriate routine
+   --  in Osint requires that the end of line sequence be stripped off.
+
+   procedure Write_Mechanism (M : Mechanism_Type);
+   --  Writes symbolic string for mechanism represented by M
 
    procedure Write_Val (Val : Node_Ref_Or_Val; Paren : Boolean := False);
    --  Given a representation value, write it out. No_Uint values or values
    --  dependent on discriminants are written as two question marks. If the
-   --  flag Paren is set, then the output is surrounded in parentheses if
-   --  it is other than a simple value.
+   --  flag Paren is set, then the output is surrounded in parentheses if it is
+   --  other than a simple value.
 
    ---------------------
    -- Back_End_Layout --
@@ -159,23 +189,31 @@ package body Repinfo is
 
    function Back_End_Layout return Boolean is
    begin
-      --  We have back end layout if the back end has made any entries in
-      --  the table of GCC expressions, otherwise we have front end layout.
+      --  We have back end layout if the back end has made any entries in the
+      --  table of GCC expressions, otherwise we have front end layout.
 
       return Rep_Table.Last > 0;
    end Back_End_Layout;
 
+   ----------------
+   -- Blank_Line --
+   ----------------
+
+   procedure Blank_Line is
+   begin
+      if Need_Blank_Line then
+         Write_Eol;
+         Need_Blank_Line := False;
+      end if;
+   end Blank_Line;
+
    ------------------------
    -- Create_Discrim_Ref --
    ------------------------
 
-   function Create_Discrim_Ref
-     (Discr : Entity_Id)
-      return  Node_Ref
-   is
+   function Create_Discrim_Ref (Discr : Entity_Id) return Node_Ref is
       N : constant Uint := Discriminant_Number (Discr);
       T : Nat;
-
    begin
       Rep_Table.Increment_Last;
       T := Rep_Table.Last;
@@ -190,12 +228,8 @@ package body Repinfo is
    -- Create_Dynamic_SO_Ref --
    ---------------------------
 
-   function Create_Dynamic_SO_Ref
-     (E    : Entity_Id)
-      return Dynamic_SO_Ref
-   is
+   function Create_Dynamic_SO_Ref (E : Entity_Id) return Dynamic_SO_Ref is
       T : Nat;
-
    begin
       Dynamic_SO_Entity_Table.Increment_Last;
       T := Dynamic_SO_Entity_Table.Last;
@@ -211,11 +245,9 @@ package body Repinfo is
      (Expr : TCode;
       Op1  : Node_Ref_Or_Val;
       Op2  : Node_Ref_Or_Val := No_Uint;
-      Op3  : Node_Ref_Or_Val := No_Uint)
-      return  Node_Ref
+      Op3  : Node_Ref_Or_Val := No_Uint) return Node_Ref
    is
       T : Nat;
-
    begin
       Rep_Table.Increment_Last;
       T := Rep_Table.Last;
@@ -223,7 +255,6 @@ package body Repinfo is
       Rep_Table.Table (T).Op1  := Op1;
       Rep_Table.Table (T).Op2  := Op2;
       Rep_Table.Table (T).Op3  := Op3;
-
       return UI_From_Int (-T);
    end Create_Node;
 
@@ -231,10 +262,7 @@ package body Repinfo is
    -- Get_Dynamic_SO_Entity --
    ---------------------------
 
-   function Get_Dynamic_SO_Entity
-     (U    : Dynamic_SO_Ref)
-      return Entity_Id
-   is
+   function Get_Dynamic_SO_Entity (U : Dynamic_SO_Ref) return Entity_Id is
    begin
       return Dynamic_SO_Entity_Table.Table (-UI_To_Int (U));
    end Get_Dynamic_SO_Entity;
@@ -274,7 +302,6 @@ package body Repinfo is
    procedure List_Array_Info (Ent : Entity_Id) is
    begin
       List_Type_Info (Ent);
-
       Write_Str ("for ");
       List_Name (Ent);
       Write_Str ("'Component_Size use ");
@@ -287,46 +314,114 @@ package body Repinfo is
    -------------------
 
    procedure List_Entities (Ent : Entity_Id) is
-      E : Entity_Id;
+      Body_E : Entity_Id;
+      E      : Entity_Id;
+
+      function Find_Declaration (E : Entity_Id) return Node_Id;
+      --  Utility to retrieve declaration node for entity in the
+      --  case of package bodies and subprograms.
+
+      ----------------------
+      -- Find_Declaration --
+      ----------------------
+
+      function Find_Declaration (E : Entity_Id) return Node_Id is
+         Decl : Node_Id;
+
+      begin
+         Decl := Parent (E);
+         while Present (Decl)
+           and then  Nkind (Decl) /= N_Package_Body
+           and then Nkind (Decl) /= N_Subprogram_Declaration
+           and then Nkind (Decl) /= N_Subprogram_Body
+         loop
+            Decl := Parent (Decl);
+         end loop;
+
+         return Decl;
+      end Find_Declaration;
+
+   --  Start of processing for List_Entities
 
    begin
-      if Present (Ent) then
+      --  List entity if we have one, and it is not a renaming declaration.
+      --  For renamings, we don't get proper information, and really it makes
+      --  sense to restrict the output to the renamed entity.
+
+      if Present (Ent)
+        and then Nkind (Declaration_Node (Ent)) not in N_Renaming_Declaration
+      then
+         --  If entity is a subprogram and we are listing mechanisms,
+         --  then we need to list mechanisms for this entity.
+
+         if List_Representation_Info_Mechanisms
+           and then (Is_Subprogram (Ent)
+                       or else Ekind (Ent) = E_Entry
+                       or else Ekind (Ent) = E_Entry_Family)
+         then
+            Need_Blank_Line := True;
+            List_Mechanisms (Ent);
+         end if;
+
          E := First_Entity (Ent);
          while Present (E) loop
+            Need_Blank_Line := True;
 
-            --  We list entities that come from source (excluding private
-            --  types, where we will list the info for the full view). If
-            --  debug flag A is set, all entities are listed
+            --  We list entities that come from source (excluding private or
+            --  incomplete types or deferred constants, where we will list the
+            --  info for the full view). If debug flag A is set, then all
+            --  entities are listed
 
-            if (Comes_From_Source (E) and then not Is_Private_Type (E))
+            if (Comes_From_Source (E)
+              and then not Is_Incomplete_Or_Private_Type (E)
+              and then not (Ekind (E) = E_Constant
+                              and then Present (Full_View (E))))
               or else Debug_Flag_AA
             then
-               if Is_Record_Type (E) then
-                  List_Record_Info (E);
+               if Is_Subprogram (E)
+                       or else
+                     Ekind (E) = E_Entry
+                       or else
+                     Ekind (E) = E_Entry_Family
+                       or else
+                     Ekind (E) = E_Subprogram_Type
+               then
+                  if List_Representation_Info_Mechanisms then
+                     List_Mechanisms (E);
+                  end if;
+
+               elsif Is_Record_Type (E) then
+                  if List_Representation_Info >= 1 then
+                     List_Record_Info (E);
+                  end if;
 
                elsif Is_Array_Type (E) then
-                  List_Array_Info (E);
+                  if List_Representation_Info >= 1 then
+                     List_Array_Info (E);
+                  end if;
 
-               elsif List_Representation_Info >= 2 then
-                  if Is_Type (E) then
+               elsif Is_Type (E) then
+                  if List_Representation_Info >= 2 then
                      List_Type_Info (E);
+                  end if;
 
-                  elsif Ekind (E) = E_Variable
-                          or else
-                        Ekind (E) = E_Constant
-                          or else
-                        Ekind (E) = E_Loop_Parameter
-                          or else
-                        Is_Formal (E)
-                  then
+               elsif Ekind (E) = E_Variable
+                       or else
+                     Ekind (E) = E_Constant
+                       or else
+                     Ekind (E) = E_Loop_Parameter
+                       or else
+                     Is_Formal (E)
+               then
+                  if List_Representation_Info >= 2 then
                      List_Object_Info (E);
                   end if;
+
                end if;
 
-               --  Recurse into nested package, but not if they are
-               --  package renamings (in particular renamings of the
-               --  enclosing package, as for some Java bindings and
-               --  for generic instances).
+               --  Recurse into nested package, but not if they are package
+               --  renamings (in particular renamings of the enclosing package,
+               --  as for some Java bindings and for generic instances).
 
                if Ekind (E) = E_Package then
                   if No (Renamed_Object (E)) then
@@ -358,6 +453,35 @@ package body Repinfo is
 
             E := Next_Entity (E);
          end loop;
+
+         --  For a package body, the entities of the visible subprograms are
+         --  declared in the corresponding spec. Iterate over its entities in
+         --  order to handle properly the subprogram bodies. Skip bodies in
+         --  subunits, which are listed independently.
+
+         if Ekind (Ent) = E_Package_Body
+           and then Present (Corresponding_Spec (Find_Declaration (Ent)))
+         then
+            E := First_Entity (Corresponding_Spec (Find_Declaration (Ent)));
+
+            while Present (E) loop
+               if Is_Subprogram (E)
+                 and then
+                   Nkind (Find_Declaration (E)) = N_Subprogram_Declaration
+               then
+                  Body_E := Corresponding_Body (Find_Declaration (E));
+
+                  if Present (Body_E)
+                    and then
+                      Nkind (Parent (Find_Declaration (Body_E))) /= N_Subunit
+                  then
+                     List_Entities (Body_E);
+                  end if;
+               end if;
+
+               Next_Entity (E);
+            end loop;
+         end if;
       end if;
    end List_Entities;
 
@@ -367,10 +491,14 @@ package body Repinfo is
 
    procedure List_GCC_Expression (U : Node_Ref_Or_Val) is
 
-      procedure P (Val : Node_Ref_Or_Val);
+      procedure Print_Expr (Val : Node_Ref_Or_Val);
       --  Internal recursive procedure to print expression
 
-      procedure P (Val : Node_Ref_Or_Val) is
+      ----------------
+      -- Print_Expr --
+      ----------------
+
+      procedure Print_Expr (Val : Node_Ref_Or_Val) is
       begin
          if Val >= 0 then
             UI_Write (Val, Decimal);
@@ -382,26 +510,30 @@ package body Repinfo is
                procedure Binop (S : String);
                --  Output text for binary operator with S being operator name
 
+               -----------
+               -- Binop --
+               -----------
+
                procedure Binop (S : String) is
                begin
                   Write_Char ('(');
-                  P (Node.Op1);
+                  Print_Expr (Node.Op1);
                   Write_Str (S);
-                  P (Node.Op2);
+                  Print_Expr (Node.Op2);
                   Write_Char (')');
                end Binop;
 
-            --  Start of processing for P
+            --  Start of processing for Print_Expr
 
             begin
                case Node.Expr is
                   when Cond_Expr =>
                      Write_Str ("(if ");
-                     P (Node.Op1);
+                     Print_Expr (Node.Op1);
                      Write_Str (" then ");
-                     P (Node.Op2);
+                     Print_Expr (Node.Op2);
                      Write_Str (" else ");
-                     P (Node.Op3);
+                     Print_Expr (Node.Op3);
                      Write_Str (" end)");
 
                   when Plus_Expr =>
@@ -436,7 +568,7 @@ package body Repinfo is
 
                   when Negate_Expr =>
                      Write_Char ('-');
-                     P (Node.Op1);
+                     Print_Expr (Node.Op1);
 
                   when Min_Expr =>
                      Binop (" min ");
@@ -446,7 +578,7 @@ package body Repinfo is
 
                   when Abs_Expr =>
                      Write_Str ("abs ");
-                     P (Node.Op1);
+                     Print_Expr (Node.Op1);
 
                   when Truth_Andif_Expr =>
                      Binop (" and if ");
@@ -465,7 +597,10 @@ package body Repinfo is
 
                   when Truth_Not_Expr =>
                      Write_Str ("not ");
-                     P (Node.Op1);
+                     Print_Expr (Node.Op1);
+
+                  when Bit_And_Expr =>
+                     Binop (" & ");
 
                   when Lt_Expr =>
                      Binop (" < ");
@@ -492,7 +627,7 @@ package body Repinfo is
                end case;
             end;
          end if;
-      end P;
+      end Print_Expr;
 
    --  Start of processing for List_GCC_Expression
 
@@ -500,10 +635,106 @@ package body Repinfo is
       if U = No_Uint then
          Write_Str ("??");
       else
-         P (U);
+         Print_Expr (U);
       end if;
    end List_GCC_Expression;
 
+   ---------------------
+   -- List_Mechanisms --
+   ---------------------
+
+   procedure List_Mechanisms (Ent : Entity_Id) is
+      Plen : Natural;
+      Form : Entity_Id;
+
+   begin
+      Blank_Line;
+
+      case Ekind (Ent) is
+         when E_Function =>
+            Write_Str ("function ");
+
+         when E_Operator =>
+            Write_Str ("operator ");
+
+         when E_Procedure =>
+            Write_Str ("procedure ");
+
+         when E_Subprogram_Type =>
+            Write_Str ("type ");
+
+         when E_Entry | E_Entry_Family =>
+            Write_Str ("entry ");
+
+         when others =>
+            raise Program_Error;
+      end case;
+
+      Get_Unqualified_Decoded_Name_String (Chars (Ent));
+      Write_Str (Name_Buffer (1 .. Name_Len));
+      Write_Str (" declared at ");
+      Write_Location (Sloc (Ent));
+      Write_Eol;
+
+      Write_Str ("  convention : ");
+
+      case Convention (Ent) is
+         when Convention_Ada       => Write_Line ("Ada");
+         when Convention_Intrinsic => Write_Line ("InLineinsic");
+         when Convention_Entry     => Write_Line ("Entry");
+         when Convention_Protected => Write_Line ("Protected");
+         when Convention_Assembler => Write_Line ("Assembler");
+         when Convention_C         => Write_Line ("C");
+         when Convention_CIL       => Write_Line ("CIL");
+         when Convention_COBOL     => Write_Line ("COBOL");
+         when Convention_CPP       => Write_Line ("C++");
+         when Convention_Fortran   => Write_Line ("Fortran");
+         when Convention_Java      => Write_Line ("Java");
+         when Convention_Stdcall   => Write_Line ("Stdcall");
+         when Convention_Stubbed   => Write_Line ("Stubbed");
+      end case;
+
+      --  Find max length of formal name
+
+      Plen := 0;
+      Form := First_Formal (Ent);
+      while Present (Form) loop
+         Get_Unqualified_Decoded_Name_String (Chars (Form));
+
+         if Name_Len > Plen then
+            Plen := Name_Len;
+         end if;
+
+         Next_Formal (Form);
+      end loop;
+
+      --  Output formals and mechanisms
+
+      Form := First_Formal (Ent);
+      while Present (Form) loop
+         Get_Unqualified_Decoded_Name_String (Chars (Form));
+
+         while Name_Len <= Plen loop
+            Name_Len := Name_Len + 1;
+            Name_Buffer (Name_Len) := ' ';
+         end loop;
+
+         Write_Str ("  ");
+         Write_Str (Name_Buffer (1 .. Plen + 1));
+         Write_Str (": passed by ");
+
+         Write_Mechanism (Mechanism (Form));
+         Write_Eol;
+         Next_Formal (Form);
+      end loop;
+
+      if Etype (Ent) /= Standard_Void_Type then
+         Write_Str ("  returns by ");
+         Write_Mechanism (Mechanism (Ent));
+         Write_Eol;
+      end if;
+   end List_Mechanisms;
+
    ---------------
    -- List_Name --
    ---------------
@@ -526,7 +757,7 @@ package body Repinfo is
 
    procedure List_Object_Info (Ent : Entity_Id) is
    begin
-      Write_Eol;
+      Blank_Line;
 
       Write_Str ("for ");
       List_Name (Ent);
@@ -547,7 +778,6 @@ package body Repinfo is
 
    procedure List_Record_Info (Ent : Entity_Id) is
       Comp  : Entity_Id;
-      Esiz  : Uint;
       Cfbit : Uint;
       Sunit : Uint;
 
@@ -555,6 +785,7 @@ package body Repinfo is
       Max_Suni_Length : Natural;
 
    begin
+      Blank_Line;
       List_Type_Info (Ent);
 
       Write_Str ("for ");
@@ -565,175 +796,167 @@ package body Repinfo is
       --  length, for the purpose of lining things up nicely.
 
       Max_Name_Length := 0;
-      Max_Suni_Length   := 0;
+      Max_Suni_Length := 0;
 
-      Comp := First_Entity (Ent);
+      Comp := First_Component_Or_Discriminant (Ent);
       while Present (Comp) loop
-         if Ekind (Comp) = E_Component
-           or else Ekind (Comp) = E_Discriminant
-         then
-            Get_Decoded_Name_String (Chars (Comp));
-            Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len);
+         Get_Decoded_Name_String (Chars (Comp));
+         Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len);
 
-            Cfbit := Component_Bit_Offset (Comp);
+         Cfbit := Component_Bit_Offset (Comp);
 
-            if Rep_Not_Constant (Cfbit) then
-               UI_Image_Length := 2;
+         if Rep_Not_Constant (Cfbit) then
+            UI_Image_Length := 2;
 
-            else
-               --  Complete annotation in case not done
+         else
+            --  Complete annotation in case not done
 
-               Set_Normalized_Position (Comp, Cfbit / SSU);
-               Set_Normalized_First_Bit (Comp, Cfbit mod SSU);
+            Set_Normalized_Position (Comp, Cfbit / SSU);
+            Set_Normalized_First_Bit (Comp, Cfbit mod SSU);
 
-               Esiz  := Esize (Comp);
-               Sunit := Cfbit / SSU;
-               UI_Image (Sunit);
-            end if;
-
-            --  If the record is not packed, then we know that all
-            --  fields whose position is not specified have a starting
-            --  normalized bit position of zero
+            Sunit := Cfbit / SSU;
+            UI_Image (Sunit);
+         end if;
 
-            if Unknown_Normalized_First_Bit (Comp)
-              and then not Is_Packed (Ent)
-            then
-               Set_Normalized_First_Bit (Comp, Uint_0);
-            end if;
+         --  If the record is not packed, then we know that all fields whose
+         --  position is not specified have a starting normalized bit position
+         --  of zero.
 
-            Max_Suni_Length :=
-              Natural'Max (Max_Suni_Length, UI_Image_Length);
+         if Unknown_Normalized_First_Bit (Comp)
+           and then not Is_Packed (Ent)
+         then
+            Set_Normalized_First_Bit (Comp, Uint_0);
          end if;
 
-         Comp := Next_Entity (Comp);
+         Max_Suni_Length :=
+           Natural'Max (Max_Suni_Length, UI_Image_Length);
+
+         Next_Component_Or_Discriminant (Comp);
       end loop;
 
       --  Second loop does actual output based on those values
 
-      Comp := First_Entity (Ent);
+      Comp := First_Component_Or_Discriminant (Ent);
       while Present (Comp) loop
-         if Ekind (Comp) = E_Component
-           or else Ekind (Comp) = E_Discriminant
-         then
-            declare
-               Esiz : constant Uint := Esize (Comp);
-               Bofs : constant Uint := Component_Bit_Offset (Comp);
-               Npos : constant Uint := Normalized_Position (Comp);
-               Fbit : constant Uint := Normalized_First_Bit (Comp);
-               Lbit : Uint;
-
-            begin
-               Write_Str ("   ");
-               Get_Decoded_Name_String (Chars (Comp));
-               Set_Casing (Unit_Casing);
-               Write_Str (Name_Buffer (1 .. Name_Len));
+         declare
+            Esiz : constant Uint := Esize (Comp);
+            Bofs : constant Uint := Component_Bit_Offset (Comp);
+            Npos : constant Uint := Normalized_Position (Comp);
+            Fbit : constant Uint := Normalized_First_Bit (Comp);
+            Lbit : Uint;
+
+         begin
+            Write_Str ("   ");
+            Get_Decoded_Name_String (Chars (Comp));
+            Set_Casing (Unit_Casing);
+            Write_Str (Name_Buffer (1 .. Name_Len));
 
-               for J in 1 .. Max_Name_Length - Name_Len loop
-                  Write_Char (' ');
-               end loop;
+            for J in 1 .. Max_Name_Length - Name_Len loop
+               Write_Char (' ');
+            end loop;
 
-               Write_Str (" at ");
+            Write_Str (" at ");
 
-               if Known_Static_Normalized_Position (Comp) then
-                  UI_Image (Npos);
-                  Spaces (Max_Suni_Length - UI_Image_Length);
-                  Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
+            if Known_Static_Normalized_Position (Comp) then
+               UI_Image (Npos);
+               Spaces (Max_Suni_Length - UI_Image_Length);
+               Write_Str (UI_Image_Buffer (1 .. UI_Image_Length));
 
-               elsif Known_Component_Bit_Offset (Comp)
-                 and then List_Representation_Info = 3
-               then
-                  Spaces (Max_Suni_Length - 2);
-                  Write_Str ("bit offset");
-                  Write_Val (Bofs, Paren => True);
-                  Write_Str (" size in bits = ");
-                  Write_Val (Esiz, Paren => True);
-                  Write_Eol;
-                  goto Continue;
+            elsif Known_Component_Bit_Offset (Comp)
+              and then List_Representation_Info = 3
+            then
+               Spaces (Max_Suni_Length - 2);
+               Write_Str ("bit offset");
+               Write_Val (Bofs, Paren => True);
+               Write_Str (" size in bits = ");
+               Write_Val (Esiz, Paren => True);
+               Write_Eol;
+               goto Continue;
 
-               elsif Known_Normalized_Position (Comp)
-                 and then List_Representation_Info = 3
-               then
-                  Spaces (Max_Suni_Length - 2);
-                  Write_Val (Npos);
+            elsif Known_Normalized_Position (Comp)
+              and then List_Representation_Info = 3
+            then
+               Spaces (Max_Suni_Length - 2);
+               Write_Val (Npos);
 
-               else
-                  --  For the packed case, we don't know the bit positions
-                  --  if we don't know the starting position!
+            else
+               --  For the packed case, we don't know the bit positions if we
+               --  don't know the starting position!
 
-                  if Is_Packed (Ent) then
-                     Write_Line ("?? range  ? .. ??;");
-                     goto Continue;
+               if Is_Packed (Ent) then
+                  Write_Line ("?? range  ? .. ??;");
+                  goto Continue;
 
-                  --  Otherwise we can continue
+               --  Otherwise we can continue
 
-                  else
-                     Write_Str ("??");
-                  end if;
+               else
+                  Write_Str ("??");
                end if;
+            end if;
 
-               Write_Str (" range  ");
-               UI_Write (Fbit);
-               Write_Str (" .. ");
+            Write_Str (" range  ");
+            UI_Write (Fbit);
+            Write_Str (" .. ");
 
-               --  Allowing Uint_0 here is a kludge, really this should be
-               --  a fine Esize value but currently it means unknown, except
-               --  that we know after gigi has back annotated that a size of
-               --  zero is real, since otherwise gigi back annotates using
-               --  No_Uint as the value to indicate unknown).
+            --  Allowing Uint_0 here is a kludge, really this should be a
+            --  fine Esize value but currently it means unknown, except that
+            --  we know after gigi has back annotated that a size of zero is
+            --  real, since otherwise gigi back annotates using No_Uint as
+            --  the value to indicate unknown).
 
-               if (Esize (Comp) = Uint_0 or else Known_Static_Esize (Comp))
-                 and then Known_Static_Normalized_First_Bit (Comp)
-               then
-                  Lbit := Fbit + Esiz - 1;
+            if (Esize (Comp) = Uint_0 or else Known_Static_Esize (Comp))
+              and then Known_Static_Normalized_First_Bit (Comp)
+            then
+               Lbit := Fbit + Esiz - 1;
 
-                  if Lbit < 10 then
-                     Write_Char (' ');
-                  end if;
+               if Lbit < 10 then
+                  Write_Char (' ');
+               end if;
 
-                  UI_Write (Lbit);
+               UI_Write (Lbit);
 
-               --  The test for Esize (Comp) not being Uint_0 here is a kludge.
-               --  Officially a value of zero for Esize means unknown, but here
-               --  we use the fact that we know that gigi annotates Esize with
-               --  No_Uint, not Uint_0. Really everyone should use No_Uint???
+            --  The test for Esize (Comp) not being Uint_0 here is a kludge.
+            --  Officially a value of zero for Esize means unknown, but here
+            --  we use the fact that we know that gigi annotates Esize with
+            --  No_Uint, not Uint_0. Really everyone should use No_Uint???
 
-               elsif List_Representation_Info < 3
-                 or else (Esize (Comp) /= Uint_0 and then Unknown_Esize (Comp))
-               then
-                  Write_Str ("??");
+            elsif List_Representation_Info < 3
+              or else (Esize (Comp) /= Uint_0 and then Unknown_Esize (Comp))
+            then
+               Write_Str ("??");
 
-               else -- List_Representation >= 3 and Known_Esize (Comp)
+            --  List_Representation >= 3 and Known_Esize (Comp)
 
-                  Write_Val (Esiz, Paren => True);
+            else
+               Write_Val (Esiz, Paren => True);
 
-                  --  If in front end layout mode, then dynamic size is
-                  --  stored in storage units, so renormalize for output
+               --  If in front end layout mode, then dynamic size is stored
+               --  in storage units, so renormalize for output
 
-                  if not Back_End_Layout then
-                     Write_Str (" * ");
-                     Write_Int (SSU);
-                  end if;
+               if not Back_End_Layout then
+                  Write_Str (" * ");
+                  Write_Int (SSU);
+               end if;
 
-                  --  Add appropriate first bit offset
+               --  Add appropriate first bit offset
 
-                  if Fbit = 0 then
-                     Write_Str (" - 1");
+               if Fbit = 0 then
+                  Write_Str (" - 1");
 
-                  elsif Fbit = 1 then
-                     null;
+               elsif Fbit = 1 then
+                  null;
 
-                  else
-                     Write_Str (" + ");
-                     Write_Int (UI_To_Int (Fbit) - 1);
-                  end if;
+               else
+                  Write_Str (" + ");
+                  Write_Int (UI_To_Int (Fbit) - 1);
                end if;
+            end if;
 
-               Write_Line (";");
-            end;
-         end if;
+            Write_Line (";");
+         end;
 
       <<Continue>>
-         Comp := Next_Entity (Comp);
+         Next_Component_Or_Discriminant (Comp);
       end loop;
 
       Write_Line ("end record;");
@@ -747,55 +970,51 @@ package body Repinfo is
       Col : Nat;
 
    begin
-      for U in Main_Unit .. Last_Unit loop
-         if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
+      if List_Representation_Info /= 0
+        or else List_Representation_Info_Mechanisms
+      then
+         for U in Main_Unit .. Last_Unit loop
+            if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
 
-            --  Normal case, list to standard output
+               --  Normal case, list to standard output
 
-            if not List_Representation_Info_To_File then
-               Unit_Casing := Identifier_Casing (Source_Index (U));
-               Write_Eol;
-               Write_Str ("Representation information for unit ");
-               Write_Unit_Name (Unit_Name (U));
-               Col := Column;
-               Write_Eol;
+               if not List_Representation_Info_To_File then
+                  Unit_Casing := Identifier_Casing (Source_Index (U));
+                  Write_Eol;
+                  Write_Str ("Representation information for unit ");
+                  Write_Unit_Name (Unit_Name (U));
+                  Col := Column;
+                  Write_Eol;
 
-               for J in 1 .. Col - 1 loop
-                  Write_Char ('-');
-               end loop;
+                  for J in 1 .. Col - 1 loop
+                     Write_Char ('-');
+                  end loop;
 
-               Write_Eol;
-               List_Entities (Cunit_Entity (U));
+                  Write_Eol;
+                  List_Entities (Cunit_Entity (U));
 
-            --  List representation information to file
+               --  List representation information to file
 
-            else
-               Creat_Repinfo_File_Access.all (File_Name (Source_Index (U)));
-               Set_Special_Output (Write_Info_Line'Access);
-               List_Entities (Cunit_Entity (U));
-               Set_Special_Output (null);
-               Close_Repinfo_File_Access.all;
+               else
+                  Create_Repinfo_File_Access.all
+                    (Get_Name_String (File_Name (Source_Index (U))));
+                  Set_Special_Output (Write_Info_Line'Access);
+                  List_Entities (Cunit_Entity (U));
+                  Set_Special_Output (null);
+                  Close_Repinfo_File_Access.all;
+               end if;
             end if;
-         end if;
-      end loop;
+         end loop;
+      end if;
    end List_Rep_Info;
 
-   ---------------------
-   -- Write_Info_Line --
-   ---------------------
-
-   procedure Write_Info_Line (S : String) is
-   begin
-      Write_Repinfo_Line_Access.all (S (S'First .. S'Last - 1));
-   end Write_Info_Line;
-
    --------------------
    -- List_Type_Info --
    --------------------
 
    procedure List_Type_Info (Ent : Entity_Id) is
    begin
-      Write_Eol;
+      Blank_Line;
 
       --  Do not list size info for unconstrained arrays, not meaningful
 
@@ -814,8 +1033,8 @@ package body Repinfo is
             Write_Line (";");
 
          --  For now, temporary case, to be removed when gigi properly back
-         --  annotates RM_Size, if RM_Size is not set, then list Esize as
-         --  Size. This avoids odd Object_Size output till we fix things???
+         --  annotates RM_Size, if RM_Size is not set, then list Esize as Size.
+         --  This avoids odd Object_Size output till we fix things???
 
          elsif Unknown_RM_Size (Ent) then
             Write_Str ("for ");
@@ -869,9 +1088,8 @@ package body Repinfo is
    ---------------
 
    function Rep_Value
-     (Val  : Node_Ref_Or_Val;
-      D    : Discrim_List)
-      return Uint
+     (Val : Node_Ref_Or_Val;
+      D   : Discrim_List) return Uint
    is
       function B (Val : Boolean) return Uint;
       --  Returns Uint_0 for False, Uint_1 for True
@@ -882,6 +1100,14 @@ package body Repinfo is
       function V (Val : Node_Ref_Or_Val) return Uint;
       --  Internal recursive routine to evaluate tree
 
+      function W (Val : Uint) return Word;
+      --  Convert Val to Word, assuming Val is always in the Int range. This is
+      --  a helper function for the evaluation of bitwise expressions like
+      --  Bit_And_Expr, for which there is no direct support in uintp. Uint
+      --  values out of the Int range are expected to be seen in such
+      --  expressions only with overflowing byte sizes around, introducing
+      --  inherent unreliabilties in computations anyway.
+
       -------
       -- B --
       -------
@@ -999,6 +1225,11 @@ package body Repinfo is
                   when Truth_Not_Expr =>
                      return B (not T (Node.Op1));
 
+                  when Bit_And_Expr =>
+                     L := V (Node.Op1);
+                     R := V (Node.Op2);
+                     return UI_From_Int (Int (W (L) and W (R)));
+
                   when Lt_Expr =>
                      return B (V (Node.Op1) < V (Node.Op2));
 
@@ -1031,6 +1262,23 @@ package body Repinfo is
          end if;
       end V;
 
+      -------
+      -- W --
+      -------
+
+      --  We use an unchecked conversion to map Int values to their Word
+      --  bitwise equivalent, which we could not achieve with a normal type
+      --  conversion for negative Ints. We want bitwise equivalents because W
+      --  is used as a helper for bit operators like Bit_And_Expr, and can be
+      --  called for negative Ints in the context of aligning expressions like
+      --  X+Align & -Align.
+
+      function W (Val : Uint) return Word is
+         function To_Word is new Ada.Unchecked_Conversion (Int, Word);
+      begin
+         return To_Word (UI_To_Int (Val));
+      end W;
+
    --  Start of processing for Rep_Value
 
    begin
@@ -1071,6 +1319,60 @@ package body Repinfo is
       Rep_Table.Tree_Write;
    end Tree_Write;
 
+   ---------------------
+   -- Write_Info_Line --
+   ---------------------
+
+   procedure Write_Info_Line (S : String) is
+   begin
+      Write_Repinfo_Line_Access.all (S (S'First .. S'Last - 1));
+   end Write_Info_Line;
+
+   ---------------------
+   -- Write_Mechanism --
+   ---------------------
+
+   procedure Write_Mechanism (M : Mechanism_Type) is
+   begin
+      case M is
+         when 0 =>
+            Write_Str ("default");
+
+         when -1 =>
+            Write_Str ("copy");
+
+         when -2 =>
+            Write_Str ("reference");
+
+         when -3 =>
+            Write_Str ("descriptor");
+
+         when -4 =>
+            Write_Str ("descriptor (UBS)");
+
+         when -5 =>
+            Write_Str ("descriptor (UBSB)");
+
+         when -6 =>
+            Write_Str ("descriptor (UBA)");
+
+         when -7 =>
+            Write_Str ("descriptor (S)");
+
+         when -8 =>
+            Write_Str ("descriptor (SB)");
+
+         when -9 =>
+            Write_Str ("descriptor (A)");
+
+         when -10 =>
+            Write_Str ("descriptor (NCA)");
+
+         when others =>
+            raise Program_Error;
+      end case;
+   end Write_Mechanism;
+
    ---------------
    -- Write_Val --
    ---------------