------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                        E X P _ P U T _ I M A G E                         --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--             Copyright (C) 2020-2021, 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- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- 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 COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Aspects;        use Aspects;
with Atree;          use Atree;
with Csets;          use Csets;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Lib;            use Lib;
with Namet;          use Namet;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Opt;            use Opt;
with Rtsfind;        use Rtsfind;
with Sem_Aux;        use Sem_Aux;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Snames;         use Snames;
with Stand;
with Stringt;        use Stringt;
with Tbuild;         use Tbuild;
with Ttypes;         use Ttypes;
with Uintp;          use Uintp;

package body Exp_Put_Image is

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Build_Put_Image_Proc
     (Loc  : Source_Ptr;
      Typ  : Entity_Id;
      Decl : out Node_Id;
      Pnam : Entity_Id;
      Stms : List_Id);
   --  Build an array or record Put_Image procedure. Stms is the list of
   --  statements for the body and Pnam is the name of the constructed
   --  procedure. (The declaration list is always null.)

   function Make_Put_Image_Name
     (Loc : Source_Ptr; Typ : Entity_Id) return Entity_Id;
   --  Return the entity that identifies the Put_Image subprogram for Typ. This
   --  procedure deals with the difference between tagged types (where a single
   --  subprogram associated with the type is generated) and all other cases
   --  (where a subprogram is generated at the point of the attribute
   --  reference). The Loc parameter is used as the Sloc of the created entity.

   function Put_Image_Base_Type (E : Entity_Id) return Entity_Id;
   --  Returns the base type, except for an array type whose whose first
   --  subtype is constrained, in which case it returns the first subtype.

   -------------------------------------
   -- Build_Array_Put_Image_Procedure --
   -------------------------------------

   procedure Build_Array_Put_Image_Procedure
     (Nod  : Node_Id;
      Typ  : Entity_Id;
      Decl : out Node_Id;
      Pnam : out Entity_Id)
   is
      Loc  : constant Source_Ptr := Sloc (Nod);

      function Wrap_In_Loop
        (Stms : List_Id;
         Dim : Pos;
         Index_Subtype : Entity_Id;
         Between_Proc : RE_Id) return Node_Id;
      --  Wrap Stms in a loop and if statement of the form:
      --
      --     if V'First (Dim) <= V'Last (Dim) then -- nonempty range?
      --        declare
      --           LDim : Index_Type_For_Dim := V'First (Dim);
      --        begin
      --           loop
      --              Stms;
      --              exit when LDim = V'Last (Dim);
      --              Between_Proc (S);
      --              LDim := Index_Type_For_Dim'Succ (LDim);
      --           end loop;
      --        end;
      --     end if;
      --
      --  This is called once per dimension, from inner to outer.

      function Wrap_In_Loop
        (Stms : List_Id;
         Dim : Pos;
         Index_Subtype : Entity_Id;
         Between_Proc : RE_Id) return Node_Id
      is
         Index : constant Entity_Id :=
           Make_Defining_Identifier
             (Loc, Chars => New_External_Name ('L', Dim));
         Decl : constant Node_Id :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Index,
             Object_Definition =>
               New_Occurrence_Of (Index_Subtype, Loc),
             Expression =>
               Make_Attribute_Reference (Loc,
                 Prefix         => Make_Identifier (Loc, Name_V),
                 Attribute_Name => Name_First,
                 Expressions => New_List (
                   Make_Integer_Literal (Loc, Dim))));
         Loop_Stm : constant Node_Id :=
           Make_Implicit_Loop_Statement (Nod, Statements => Stms);
         Exit_Stm : constant Node_Id :=
           Make_Exit_Statement (Loc,
             Condition =>
               Make_Op_Eq (Loc,
                 Left_Opnd => New_Occurrence_Of (Index, Loc),
                 Right_Opnd =>
                   Make_Attribute_Reference (Loc,
                     Prefix         =>
                       Make_Identifier (Loc, Name_V),
                     Attribute_Name => Name_Last,
                     Expressions => New_List (
                       Make_Integer_Literal (Loc, Dim)))));
         Increment : constant Node_Id :=
           Make_Increment (Loc, Index, Index_Subtype);
         Between : constant Node_Id :=
           Make_Procedure_Call_Statement (Loc,
             Name =>
               New_Occurrence_Of (RTE (Between_Proc), Loc),
             Parameter_Associations => New_List
               (Make_Identifier (Loc, Name_S)));
         Block : constant Node_Id :=
           Make_Block_Statement (Loc,
             Declarations               => New_List (Decl),
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 Statements => New_List (Loop_Stm)));
      begin
         Append_To (Stms, Exit_Stm);
         Append_To (Stms, Between);
         Append_To (Stms, Increment);
         --  Note that we're appending to the Stms list passed in

         return
           Make_If_Statement (Loc,
             Condition =>
               Make_Op_Le (Loc,
                 Left_Opnd  =>
                   Make_Attribute_Reference (Loc,
                     Prefix => Make_Identifier (Loc, Name_V),
                     Attribute_Name => Name_First,
                     Expressions => New_List (
                       Make_Integer_Literal (Loc, Dim))),
                 Right_Opnd =>
                   Make_Attribute_Reference (Loc,
                     Prefix => Make_Identifier (Loc, Name_V),
                     Attribute_Name => Name_Last,
                     Expressions => New_List (
                       Make_Integer_Literal (Loc, Dim)))),
             Then_Statements => New_List (Block));
      end Wrap_In_Loop;

      Ndim : constant Pos        := Number_Dimensions (Typ);
      Ctyp : constant Entity_Id  := Component_Type (Typ);

      Stm         : Node_Id;
      Exl         : constant List_Id := New_List;
      PI_Entity   : Entity_Id;

      Indices : array (1 .. Ndim) of Entity_Id;

   --  Start of processing for Build_Array_Put_Image_Procedure

   begin
      Pnam :=
        Make_Defining_Identifier (Loc,
          Chars => Make_TSS_Name_Local (Typ, TSS_Put_Image));

      --  Get the Indices

      declare
         Index_Subtype : Node_Id := First_Index (Typ);
      begin
         for Dim in 1 .. Ndim loop
            Indices (Dim) := Etype (Index_Subtype);
            Next_Index (Index_Subtype);
         end loop;
         pragma Assert (No (Index_Subtype));
      end;

      --  Build the inner attribute call

      for Dim in 1 .. Ndim loop
         Append_To (Exl, Make_Identifier (Loc, New_External_Name ('L', Dim)));
      end loop;

      Stm :=
        Make_Attribute_Reference (Loc,
          Prefix => New_Occurrence_Of (Put_Image_Base_Type (Ctyp), Loc),
          Attribute_Name => Name_Put_Image,
          Expressions => New_List (
            Make_Identifier (Loc, Name_S),
            Make_Indexed_Component (Loc,
              Prefix      => Make_Identifier (Loc, Name_V),
              Expressions => Exl)));

      --  The corresponding attribute for the component type of the array might
      --  be user-defined, and frozen after the array type. In that case,
      --  freeze the Put_Image attribute of the component type, whose
      --  declaration could not generate any additional freezing actions in any
      --  case.

      PI_Entity := TSS (Base_Type (Ctyp), TSS_Put_Image);

      if Present (PI_Entity) and then not Is_Frozen (PI_Entity) then
         Set_Is_Frozen (PI_Entity);
      end if;

      --  Loop through the dimensions, innermost first, generating a loop for
      --  each dimension.

      declare
         Stms : List_Id := New_List (Stm);
      begin
         for Dim in reverse 1 .. Ndim loop
            declare
               New_Stms : constant List_Id := New_List;
               Between_Proc : RE_Id;
            begin
               --  For a one-dimensional array of elementary type, use
               --  RE_Simple_Array_Between. The same applies to the last
               --  dimension of a multidimensional array.

               if Is_Elementary_Type (Ctyp) and then Dim = Ndim then
                  Between_Proc := RE_Simple_Array_Between;
               else
                  Between_Proc := RE_Array_Between;
               end if;

               Append_To (New_Stms,
                 Make_Procedure_Call_Statement (Loc,
                   Name => New_Occurrence_Of (RTE (RE_Array_Before), Loc),
                   Parameter_Associations => New_List
                     (Make_Identifier (Loc, Name_S))));

               Append_To
                 (New_Stms,
                  Wrap_In_Loop (Stms, Dim, Indices (Dim), Between_Proc));

               Append_To (New_Stms,
                 Make_Procedure_Call_Statement (Loc,
                   Name => New_Occurrence_Of (RTE (RE_Array_After), Loc),
                   Parameter_Associations => New_List
                     (Make_Identifier (Loc, Name_S))));

               Stms := New_Stms;
            end;
         end loop;

         Build_Put_Image_Proc (Loc, Typ, Decl, Pnam, Stms);
      end;
   end Build_Array_Put_Image_Procedure;

   -------------------------------------
   -- Build_Elementary_Put_Image_Call --
   -------------------------------------

   function Build_Elementary_Put_Image_Call (N : Node_Id) return Node_Id is
      Loc     : constant Source_Ptr := Sloc (N);
      P_Type  : constant Entity_Id  := Entity (Prefix (N));
      U_Type  : constant Entity_Id  := Underlying_Type (P_Type);
      FST     : constant Entity_Id  := First_Subtype (U_Type);
      Sink    : constant Node_Id    := First (Expressions (N));
      Item    : constant Node_Id    := Next (Sink);
      P_Size  : constant Uint       := Esize (FST);
      Lib_RE  : RE_Id;

   begin
      if Is_Signed_Integer_Type (U_Type) then
         if P_Size <= Standard_Integer_Size then
            Lib_RE := RE_Put_Image_Integer;
         elsif P_Size <= Standard_Long_Long_Integer_Size then
            Lib_RE := RE_Put_Image_Long_Long_Integer;
         else
            pragma Assert (P_Size <= Standard_Long_Long_Long_Integer_Size);
            Lib_RE := RE_Put_Image_Long_Long_Long_Integer;
         end if;

      elsif Is_Modular_Integer_Type (U_Type) then
         if P_Size <= Standard_Integer_Size then -- Yes, Integer
            Lib_RE := RE_Put_Image_Unsigned;
         elsif P_Size <= Standard_Long_Long_Integer_Size then
            Lib_RE := RE_Put_Image_Long_Long_Unsigned;
         else
            pragma Assert (P_Size <= Standard_Long_Long_Long_Integer_Size);
            Lib_RE := RE_Put_Image_Long_Long_Long_Unsigned;
         end if;

      elsif Is_Access_Type (U_Type) then
         if Is_Access_Protected_Subprogram_Type (Base_Type (U_Type)) then
            Lib_RE := RE_Put_Image_Access_Prot_Subp;
         elsif Is_Access_Subprogram_Type (Base_Type (U_Type)) then
            Lib_RE := RE_Put_Image_Access_Subp;
         elsif P_Size = System_Address_Size then
            Lib_RE := RE_Put_Image_Thin_Pointer;
         else
            pragma Assert (P_Size = 2 * System_Address_Size);
            Lib_RE := RE_Put_Image_Fat_Pointer;
         end if;

      else
         pragma Assert
           (Is_Enumeration_Type (U_Type) or else Is_Real_Type (U_Type));

         --  For other elementary types, generate:
         --
         --     Wide_Wide_Put (Sink, U_Type'Wide_Wide_Image (Item));
         --
         --  It would be more elegant to do it the other way around (define
         --  '[[Wide_]Wide_]Image in terms of 'Put_Image). But this is easier
         --  to implement, because we already have support for
         --  'Wide_Wide_Image. Furthermore, we don't want to remove the
         --  existing support for '[[Wide_]Wide_]Image, because we don't
         --  currently plan to support 'Put_Image on restricted runtimes.

         --  We can't do this:
         --
         --     Put_UTF_8 (Sink, U_Type'Image (Item));
         --
         --  because we need to generate UTF-8, but 'Image for enumeration
         --  types uses the character encoding of the source file.
         --
         --  Note that this is putting a leading space for reals.

         declare
            Image : constant Node_Id :=
              Make_Attribute_Reference (Loc,
                Prefix => New_Occurrence_Of (U_Type, Loc),
                Attribute_Name => Name_Wide_Wide_Image,
                Expressions => New_List (Relocate_Node (Item)));
            Put_Call : constant Node_Id :=
              Make_Procedure_Call_Statement (Loc,
                Name =>
                  New_Occurrence_Of (RTE (RE_Wide_Wide_Put), Loc),
                Parameter_Associations => New_List
                  (Relocate_Node (Sink), Image));
         begin
            return Put_Call;
         end;
      end if;

      --  Unchecked-convert parameter to the required type (i.e. the type of
      --  the corresponding parameter), and call the appropriate routine.
      --  We could use a normal type conversion for scalars, but the
      --  "unchecked" is needed for access and private types.

      declare
         Libent : constant Entity_Id := RTE (Lib_RE);
      begin
         return
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (Libent, Loc),
             Parameter_Associations => New_List (
               Relocate_Node (Sink),
               Unchecked_Convert_To
                (Etype (Next_Formal (First_Formal (Libent))),
                 Relocate_Node (Item))));
      end;
   end Build_Elementary_Put_Image_Call;

   -------------------------------------
   -- Build_String_Put_Image_Call --
   -------------------------------------

   function Build_String_Put_Image_Call (N : Node_Id) return Node_Id is
      Loc     : constant Source_Ptr := Sloc (N);
      P_Type  : constant Entity_Id  := Entity (Prefix (N));
      U_Type  : constant Entity_Id  := Underlying_Type (P_Type);
      R       : constant Entity_Id  := Root_Type (U_Type);
      Sink    : constant Node_Id    := First (Expressions (N));
      Item    : constant Node_Id    := Next (Sink);
      Lib_RE  : RE_Id;
      use Stand;
   begin
      if R = Standard_String then
         Lib_RE := RE_Put_Image_String;
      elsif R = Standard_Wide_String then
         Lib_RE := RE_Put_Image_Wide_String;
      elsif R = Standard_Wide_Wide_String then
         Lib_RE := RE_Put_Image_Wide_Wide_String;
      else
         raise Program_Error;
      end if;

      --  Convert parameter to the required type (i.e. the type of the
      --  corresponding parameter), and call the appropriate routine.
      --  We set the Conversion_OK flag in case the type is private.

      declare
         Libent : constant Entity_Id := RTE (Lib_RE);
         Conv   : constant Node_Id :=
           OK_Convert_To
            (Etype (Next_Formal (First_Formal (Libent))),
             Relocate_Node (Item));
      begin
         return
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (Libent, Loc),
             Parameter_Associations => New_List (
               Relocate_Node (Sink),
               Conv));
      end;
   end Build_String_Put_Image_Call;

   ------------------------------------
   -- Build_Protected_Put_Image_Call --
   ------------------------------------

   --  For "Protected_Type'Put_Image (S, Protected_Object)", build:
   --
   --    Put_Image_Protected (S);
   --
   --  The protected object is not passed.

   function Build_Protected_Put_Image_Call (N : Node_Id) return Node_Id is
      Loc    : constant Source_Ptr := Sloc (N);
      Sink   : constant Node_Id    := First (Expressions (N));
      Lib_RE : constant RE_Id      := RE_Put_Image_Protected;
      Libent : constant Entity_Id  := RTE (Lib_RE);
   begin
      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Occurrence_Of (Libent, Loc),
          Parameter_Associations => New_List (
            Relocate_Node (Sink)));
   end Build_Protected_Put_Image_Call;

   ------------------------------------
   -- Build_Task_Put_Image_Call --
   ------------------------------------

   --  For "Task_Type'Put_Image (S, Task_Object)", build:
   --
   --    Put_Image_Task (S, Task_Object'Identity);
   --
   --  The task object is not passed; its Task_Id is.

   function Build_Task_Put_Image_Call (N : Node_Id) return Node_Id is
      Loc    : constant Source_Ptr := Sloc (N);
      Sink   : constant Node_Id    := First (Expressions (N));
      Item   : constant Node_Id    := Next (Sink);
      Lib_RE : constant RE_Id      := RE_Put_Image_Task;
      Libent : constant Entity_Id  := RTE (Lib_RE);

      Task_Id : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix => Relocate_Node (Item),
          Attribute_Name => Name_Identity,
          Expressions => No_List);

   begin
      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Occurrence_Of (Libent, Loc),
          Parameter_Associations => New_List (
            Relocate_Node (Sink),
            Task_Id));
   end Build_Task_Put_Image_Call;

   --------------------------------------
   -- Build_Record_Put_Image_Procedure --
   --------------------------------------

   --  The form of the record Put_Image procedure is as shown by the
   --  following example:

   --    procedure Put_Image (S : in out Sink'Class; V : Typ) is
   --    begin
   --       Component_Type'Put_Image (S, V.component);
   --       Component_Type'Put_Image (S, V.component);
   --       ...
   --       Component_Type'Put_Image (S, V.component);
   --
   --       case V.discriminant is
   --          when choices =>
   --             Component_Type'Put_Image (S, V.component);
   --             Component_Type'Put_Image (S, V.component);
   --             ...
   --             Component_Type'Put_Image (S, V.component);
   --
   --          when choices =>
   --             Component_Type'Put_Image (S, V.component);
   --             Component_Type'Put_Image (S, V.component);
   --             ...
   --             Component_Type'Put_Image (S, V.component);
   --          ...
   --       end case;
   --    end Put_Image;

   procedure Build_Record_Put_Image_Procedure
     (Loc  : Source_Ptr;
      Typ  : Entity_Id;
      Decl : out Node_Id;
      Pnam : out Entity_Id)
   is
      Btyp : constant Entity_Id := Base_Type (Typ);
      pragma Assert (not Is_Class_Wide_Type (Btyp));
      pragma Assert (not Is_Unchecked_Union (Btyp));

      First_Time : Boolean := True;

      function Make_Component_List_Attributes (CL : Node_Id) return List_Id;
      --  Returns a sequence of Component_Type'Put_Image attribute_references
      --  to process the components that are referenced in the given component
      --  list. Called for the main component list, and then recursively for
      --  variants.

      function Make_Component_Attributes (Clist : List_Id) return List_Id;
      --  Given Clist, a component items list, construct series of
      --  Component_Type'Put_Image attribute_references for componentwise
      --  processing of the corresponding components. Called for the
      --  discriminants, and then from Make_Component_List_Attributes for each
      --  list (including in variants).

      procedure Append_Component_Attr (Clist : List_Id; C : Entity_Id);
      --  Given C, the entity for a discriminant or component, build a call to
      --  Component_Type'Put_Image for the corresponding component value, and
      --  append it onto Clist. Called from Make_Component_Attributes.

      function Make_Component_Name (C : Entity_Id) return Node_Id;
      --  Create a call that prints "Comp_Name => "

      ------------------------------------
      -- Make_Component_List_Attributes --
      ------------------------------------

      function Make_Component_List_Attributes (CL : Node_Id) return List_Id is
         CI : constant List_Id := Component_Items (CL);
         VP : constant Node_Id := Variant_Part (CL);

         Result : List_Id;
         Alts   : List_Id;
         V      : Node_Id;
         DC     : Node_Id;
         DCH    : List_Id;
         D_Ref  : Node_Id;

      begin
         Result := Make_Component_Attributes (CI);

         if Present (VP) then
            Alts := New_List;

            V := First_Non_Pragma (Variants (VP));
            while Present (V) loop
               DCH := New_List;

               DC := First (Discrete_Choices (V));
               while Present (DC) loop
                  Append_To (DCH, New_Copy_Tree (DC));
                  Next (DC);
               end loop;

               Append_To (Alts,
                 Make_Case_Statement_Alternative (Loc,
                   Discrete_Choices => DCH,
                   Statements =>
                     Make_Component_List_Attributes (Component_List (V))));
               Next_Non_Pragma (V);
            end loop;

            --  Note: in the following, we use New_Occurrence_Of for the
            --  selector, since there are cases in which we make a reference
            --  to a hidden discriminant that is not visible.

            D_Ref :=
               Make_Selected_Component (Loc,
                 Prefix        => Make_Identifier (Loc, Name_V),
                 Selector_Name =>
                   New_Occurrence_Of (Entity (Name (VP)), Loc));

            Append_To (Result,
              Make_Case_Statement (Loc,
                Expression   => D_Ref,
                Alternatives => Alts));
         end if;

         return Result;
      end Make_Component_List_Attributes;

      --------------------------------
      -- Append_Component_Attr --
      --------------------------------

      procedure Append_Component_Attr (Clist : List_Id; C : Entity_Id) is
         Component_Typ : constant Entity_Id := Put_Image_Base_Type (Etype (C));
      begin
         if Ekind (C) /= E_Void then
            Append_To (Clist,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Component_Typ, Loc),
                Attribute_Name => Name_Put_Image,
                Expressions    => New_List (
                  Make_Identifier (Loc, Name_S),
                  Make_Selected_Component (Loc,
                    Prefix        => Make_Identifier (Loc, Name_V),
                    Selector_Name => New_Occurrence_Of (C, Loc)))));
         end if;
      end Append_Component_Attr;

      -------------------------------
      -- Make_Component_Attributes --
      -------------------------------

      function Make_Component_Attributes (Clist : List_Id) return List_Id is
         Item   : Node_Id;
         Result : List_Id;

      begin
         Result := New_List;

         if Present (Clist) then
            Item := First (Clist);

            --  Loop through components, skipping all internal components,
            --  which are not part of the value (e.g. _Tag), except that we
            --  don't skip the _Parent, since we do want to process that
            --  recursively.

            while Present (Item) loop
               if Nkind (Item) in
                    N_Component_Declaration | N_Discriminant_Specification
               then
                  if Chars (Defining_Identifier (Item)) = Name_uParent then
                     declare
                        Parent_Type : constant Entity_Id :=
                          Implementation_Base_Type
                            (Etype (Defining_Identifier (Item)));

                        Parent_Aspect_Spec : constant Node_Id :=
                          Find_Aspect (Parent_Type, Aspect_Put_Image);

                        Parent_Type_Decl : constant Node_Id :=
                          Declaration_Node (Parent_Type);

                        Parent_Rdef : Node_Id :=
                          Type_Definition (Parent_Type_Decl);
                     begin
                        --  If parent type has an noninherited
                        --  explicitly-specified Put_Image aspect spec, then
                        --  display parent part by calling specified procedure,
                        --  and then use extension-aggregate syntax for the
                        --  remaining components as per RM 4.10(15/5);
                        --  otherwise, "look through" the parent component
                        --  to its components - we don't want the image text
                        --  to include mention of an "_parent" component.

                        if Present (Parent_Aspect_Spec) and then
                          Entity (Parent_Aspect_Spec) = Parent_Type
                        then
                           Append_Component_Attr
                             (Result, Defining_Identifier (Item));

                           --  Omit the " with " if no subsequent components.

                           if not Is_Null_Extension_Of
                                    (Descendant => Typ,
                                     Ancestor => Parent_Type)
                           then
                              Append_To (Result,
                                 Make_Procedure_Call_Statement (Loc,
                                   Name =>
                                     New_Occurrence_Of
                                       (RTE (RE_Put_UTF_8), Loc),
                                   Parameter_Associations => New_List
                                     (Make_Identifier (Loc, Name_S),
                                      Make_String_Literal (Loc, " with "))));
                           end if;
                        else
                           if Nkind (Parent_Rdef) = N_Derived_Type_Definition
                           then
                              Parent_Rdef :=
                                Record_Extension_Part (Parent_Rdef);
                           end if;

                           if Present (Component_List (Parent_Rdef)) then
                              Append_List_To (Result,
                                 Make_Component_List_Attributes
                                   (Component_List (Parent_Rdef)));
                           end if;
                        end if;
                     end;

                  elsif not Is_Internal_Name
                              (Chars (Defining_Identifier (Item)))
                  then
                     if First_Time then
                        First_Time := False;
                     else
                        Append_To (Result,
                          Make_Procedure_Call_Statement (Loc,
                            Name =>
                              New_Occurrence_Of (RTE (RE_Record_Between), Loc),
                            Parameter_Associations => New_List
                              (Make_Identifier (Loc, Name_S))));
                     end if;

                     Append_To (Result, Make_Component_Name (Item));
                     Append_Component_Attr
                       (Result, Defining_Identifier (Item));
                  end if;
               end if;

               Next (Item);
            end loop;
         end if;

         return Result;
      end Make_Component_Attributes;

      -------------------------
      -- Make_Component_Name --
      -------------------------

      function Make_Component_Name (C : Entity_Id) return Node_Id is
         Name : constant Name_Id := Chars (Defining_Identifier (C));
         pragma Assert (Name /= Name_uParent);

         function To_Upper (S : String) return String;
         --  Same as Ada.Characters.Handling.To_Upper, but withing
         --  Ada.Characters.Handling seems to cause mailserver problems.

         --------------
         -- To_Upper --
         --------------

         function To_Upper (S : String) return String is
         begin
            return Result : String := S do
               for Char of Result loop
                  Char := Fold_Upper (Char);
               end loop;
            end return;
         end To_Upper;

      --  Start of processing for Make_Component_Name

      begin
         return
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
             Parameter_Associations => New_List
               (Make_Identifier (Loc, Name_S),
                Make_String_Literal (Loc,
                  To_Upper (Get_Name_String (Name)) & " => ")));
      end Make_Component_Name;

      Stms : constant List_Id := New_List;
      Rdef : Node_Id;
      Type_Decl : constant Node_Id :=
        Declaration_Node (Base_Type (Underlying_Type (Btyp)));

   --  Start of processing for Build_Record_Put_Image_Procedure

   begin
      if (Ada_Version < Ada_2022)
        or else not Enable_Put_Image (Btyp)
      then
         --  generate a very simple Put_Image implementation

         if Is_RTE (Typ, RE_Root_Buffer_Type) then
            --  Avoid introducing a cyclic dependency between
            --  Ada.Strings.Text_Buffers and System.Put_Images.

            Append_To (Stms,
              Make_Raise_Program_Error (Loc,
              Reason => PE_Explicit_Raise));
         else
            Append_To (Stms,
              Make_Procedure_Call_Statement (Loc,
                Name => New_Occurrence_Of (RTE (RE_Put_Image_Unknown), Loc),
                Parameter_Associations => New_List
                  (Make_Identifier (Loc, Name_S),
                   Make_String_Literal (Loc,
                     To_String (Fully_Qualified_Name_String (Btyp))))));
         end if;
      elsif Is_Null_Record_Type (Btyp, Ignore_Privacy => True) then

         --  Interface types take this path.

         Append_To (Stms,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Put_UTF_8), Loc),
             Parameter_Associations => New_List
               (Make_Identifier (Loc, Name_S),
                Make_String_Literal (Loc, "(NULL RECORD)"))));
      else
         Append_To (Stms,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Record_Before), Loc),
             Parameter_Associations => New_List
               (Make_Identifier (Loc, Name_S))));

         --  Generate Put_Images for the discriminants of the type

         Append_List_To (Stms,
           Make_Component_Attributes
             (Discriminant_Specifications (Type_Decl)));

         Rdef := Type_Definition (Type_Decl);

         --  In the record extension case, the components we want are to be
         --  found in the extension (although we have to process the
         --  _Parent component to find inherited components).

         if Nkind (Rdef) = N_Derived_Type_Definition then
            Rdef := Record_Extension_Part (Rdef);
         end if;

         if Present (Component_List (Rdef)) then
            Append_List_To (Stms,
              Make_Component_List_Attributes (Component_List (Rdef)));
         end if;

         Append_To (Stms,
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (RE_Record_After), Loc),
             Parameter_Associations => New_List
               (Make_Identifier (Loc, Name_S))));
      end if;

      Pnam := Make_Put_Image_Name (Loc, Btyp);
      Build_Put_Image_Proc (Loc, Btyp, Decl, Pnam, Stms);
   end Build_Record_Put_Image_Procedure;

   -------------------------------
   -- Build_Put_Image_Profile --
   -------------------------------

   function Build_Put_Image_Profile
     (Loc : Source_Ptr; Typ : Entity_Id) return List_Id
   is
   begin
      return New_List (
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_S),
          In_Present          => True,
          Out_Present         => True,
          Parameter_Type      =>
            New_Occurrence_Of
              (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_V),
          Parameter_Type      => New_Occurrence_Of (Typ, Loc)));
   end Build_Put_Image_Profile;

   --------------------------
   -- Build_Put_Image_Proc --
   --------------------------

   procedure Build_Put_Image_Proc
     (Loc  : Source_Ptr;
      Typ  : Entity_Id;
      Decl : out Node_Id;
      Pnam : Entity_Id;
      Stms : List_Id)
   is
      Spec : constant Node_Id :=
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name => Pnam,
          Parameter_Specifications => Build_Put_Image_Profile (Loc, Typ));
   begin
      Decl :=
        Make_Subprogram_Body (Loc,
          Specification              => Spec,
          Declarations               => Empty_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => Stms));
   end Build_Put_Image_Proc;

   ------------------------------------
   -- Build_Unknown_Put_Image_Call --
   ------------------------------------

   function Build_Unknown_Put_Image_Call (N : Node_Id) return Node_Id is
      Loc    : constant Source_Ptr := Sloc (N);
      Sink   : constant Node_Id    := First (Expressions (N));
      Lib_RE : constant RE_Id      := RE_Put_Image_Unknown;
      Libent : constant Entity_Id  := RTE (Lib_RE);
   begin
      return
        Make_Procedure_Call_Statement (Loc,
          Name => New_Occurrence_Of (Libent, Loc),
          Parameter_Associations => New_List (
            Relocate_Node (Sink),
            Make_String_Literal (Loc,
              Exp_Util.Fully_Qualified_Name_String (
                Entity (Prefix (N)), Append_NUL => False))));
   end Build_Unknown_Put_Image_Call;

   ----------------------
   -- Enable_Put_Image --
   ----------------------

   function Enable_Put_Image (Typ : Entity_Id) return Boolean is
   begin
      --  If this function returns False for a non-scalar type Typ, then
      --    a) calls to Typ'Image will result in calls to
      --       System.Put_Images.Put_Image_Unknown to generate the image.
      --    b) If Typ is a tagged type, then similarly the implementation
      --       of Typ's Put_Image procedure will call Put_Image_Unknown
      --       and will ignore its formal parameter of type Typ.
      --       Note that Typ will still have a Put_Image procedure
      --       in this case, albeit one with a simplified implementation.
      --
      --  The name "Sink" here is a short nickname for
      --  "Ada.Strings.Text_Buffers.Root_Buffer_Type".
      --
      --  Put_Image does not work for Remote_Types. We check the containing
      --  package, rather than the type itself, because we want to include
      --  types in the private part of a Remote_Types package.

      if Is_Remote_Types (Scope (Typ))
        or else Is_Remote_Call_Interface (Typ)
        or else (Is_Tagged_Type (Typ) and then In_Predefined_Unit (Typ))
      then
         return False;
      end if;

      --  No sense in generating code for Put_Image if there are errors. This
      --  avoids certain cascade errors.

      if Total_Errors_Detected > 0 then
         return False;
      end if;

      --  If type Sink is unavailable in this runtime, disable Put_Image
      --  altogether.

      if No_Run_Time_Mode or else not RTE_Available (RE_Root_Buffer_Type) then
         return False;
      end if;

      --  ???Disable Put_Image on type Root_Buffer_Type declared in
      --  Ada.Strings.Text_Buffers. Note that we can't call Is_RTU on
      --  Ada_Strings_Text_Buffers, because it's not known yet (we might be
      --  compiling it). But this is insufficient to allow support for tagged
      --  predefined types.

      declare
         Parent_Scope : constant Entity_Id := Scope (Scope (Typ));
      begin
         if Present (Parent_Scope)
           and then Is_RTU (Parent_Scope, Ada_Strings)
           and then Chars (Scope (Typ)) = Name_Find ("text_buffers")
         then
            return False;
         end if;
      end;

      --  Disable for CPP types, because the components are unavailable on the
      --  Ada side.

      if Is_Tagged_Type (Typ)
        and then Convention (Typ) = Convention_CPP
        and then Is_CPP_Class (Root_Type (Typ))
      then
         return False;
      end if;

      --  Disable for unchecked unions, because there is no way to know the
      --  discriminant value, and therefore no way to know which components
      --  should be printed.

      if Is_Unchecked_Union (Typ) then
         return False;
      end if;

      return True;
   end Enable_Put_Image;

   -------------------------
   -- Make_Put_Image_Name --
   -------------------------

   function Make_Put_Image_Name
     (Loc : Source_Ptr; Typ : Entity_Id) return Entity_Id
   is
      Sname : Name_Id;
   begin
      --  For tagged types, we are dealing with a TSS associated with the
      --  declaration, so we use the standard primitive function name. For
      --  other types, generate a local TSS name since we are generating
      --  the subprogram at the point of use.

      if Is_Tagged_Type (Typ) then
         Sname := Make_TSS_Name (Typ, TSS_Put_Image);
      else
         Sname := Make_TSS_Name_Local (Typ, TSS_Put_Image);
      end if;

      return Make_Defining_Identifier (Loc, Sname);
   end Make_Put_Image_Name;

   ---------------------------------
   -- Image_Should_Call_Put_Image --
   ---------------------------------

   function Image_Should_Call_Put_Image (N : Node_Id) return Boolean is
   begin
      if Ada_Version < Ada_2022 then
         return False;
      end if;

      --  In Ada 2022, T'Image calls T'Put_Image if there is an explicit
      --  aspect_specification for Put_Image, or if U_Type'Image is illegal
      --  in pre-2022 versions of Ada.

      declare
         U_Type : constant Entity_Id := Underlying_Type (Entity (Prefix (N)));
      begin
         if Present (TSS (U_Type, TSS_Put_Image)) then
            return True;
         end if;

         return not Is_Scalar_Type (U_Type);
      end;
   end Image_Should_Call_Put_Image;

   ----------------------
   -- Build_Image_Call --
   ----------------------

   function Build_Image_Call (N : Node_Id) return Node_Id is
      --  For T'Image (X) Generate an Expression_With_Actions node:
      --
      --     do
      --        S : Buffer;
      --        U_Type'Put_Image (S, X);
      --        Result : constant String := Get (S);
      --        Destroy (S);
      --     in Result end
      --
      --  where U_Type is the underlying type, as needed to bypass privacy.

      Loc : constant Source_Ptr := Sloc (N);
      U_Type : constant Entity_Id := Underlying_Type (Entity (Prefix (N)));
      Sink_Entity : constant Entity_Id :=
        Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('S'));
      Sink_Decl : constant Node_Id :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Sink_Entity,
          Object_Definition =>
            New_Occurrence_Of (RTE (RE_Buffer_Type), Loc));

      Image_Prefix : constant Node_Id :=
        Duplicate_Subexpr (First (Expressions (N)));

      Put_Im : constant Node_Id :=
        Make_Attribute_Reference (Loc,
          Prefix         => New_Occurrence_Of (U_Type, Loc),
          Attribute_Name => Name_Put_Image,
          Expressions    => New_List (
            New_Occurrence_Of (Sink_Entity, Loc),
            Image_Prefix));
      Result_Entity : constant Entity_Id :=
        Make_Defining_Identifier (Loc, Chars => New_Internal_Name ('R'));
      Result_Decl : constant Node_Id :=
        Make_Object_Declaration (Loc,
          Defining_Identifier => Result_Entity,
          Object_Definition =>
            New_Occurrence_Of (Stand.Standard_String, Loc),
          Expression =>
            Make_Function_Call (Loc,
              Name => New_Occurrence_Of (RTE (RE_Get), Loc),
              Parameter_Associations => New_List (
                New_Occurrence_Of (Sink_Entity, Loc))));
      Actions : List_Id;

      function Put_String_Exp (String_Exp : Node_Id;
                               Wide_Wide  : Boolean := False) return Node_Id;
      --  Generate a call to evaluate a String (or Wide_Wide_String, depending
      --  on the Wide_Wide Boolean parameter) expression and output it into
      --  the buffer.

      --------------------
      -- Put_String_Exp --
      --------------------

      function Put_String_Exp (String_Exp : Node_Id;
                               Wide_Wide  : Boolean := False) return Node_Id is
         Put_Id : constant RE_Id :=
           (if Wide_Wide then RE_Wide_Wide_Put else RE_Put_UTF_8);

         --  We could build a nondispatching call here, but to make
         --  that work we'd have to change Rtsfind spec to make available
         --  corresponding callees out of Ada.Strings.Text_Buffers.Unbounded
         --  (as opposed to from Ada.Strings.Text_Buffers). Seems simpler to
         --  introduce a type conversion and leave it to the optimizer to
         --  eliminate the dispatching. This does not *introduce* any problems
         --  if a no-dispatching-allowed restriction is in effect, since we
         --  are already in the middle of generating a call to T'Class'Image.

         Sink_Exp : constant Node_Id :=
           Make_Type_Conversion (Loc,
             Subtype_Mark =>
               New_Occurrence_Of
                 (Class_Wide_Type (RTE (RE_Root_Buffer_Type)), Loc),
             Expression   => New_Occurrence_Of (Sink_Entity, Loc));
      begin
         return
           Make_Procedure_Call_Statement (Loc,
             Name => New_Occurrence_Of (RTE (Put_Id), Loc),
             Parameter_Associations => New_List (Sink_Exp, String_Exp));
      end Put_String_Exp;

   --  Start of processing for Build_Image_Call

   begin
      if Is_Class_Wide_Type (U_Type) then
         --  Generate qualified-expression syntax; qualification name comes
         --  from calling Ada.Tags.Wide_Wide_Expanded_Name.

         declare
            --  The copy of Image_Prefix will be evaluated before the
            --  original, which is ok if no side effects are involved.

            pragma Assert (Side_Effect_Free (Image_Prefix));

            Specific_Type_Name : constant Node_Id :=
              Put_String_Exp
                (Make_Function_Call (Loc,
                   Name => New_Occurrence_Of
                             (RTE (RE_Wide_Wide_Expanded_Name), Loc),
                   Parameter_Associations => New_List (
                     Make_Attribute_Reference (Loc,
                       Prefix         => Duplicate_Subexpr (Image_Prefix),
                       Attribute_Name => Name_Tag))),
                 Wide_Wide => True);

            Qualification : constant Node_Id :=
              Put_String_Exp (Make_String_Literal (Loc, "'"));
         begin
            Actions := New_List
                         (Sink_Decl,
                          Specific_Type_Name,
                          Qualification,
                          Put_Im,
                          Result_Decl);
         end;
      else
         Actions := New_List (Sink_Decl, Put_Im, Result_Decl);
      end if;

      return Make_Expression_With_Actions (Loc,
        Actions    => Actions,
        Expression => New_Occurrence_Of (Result_Entity, Loc));
   end Build_Image_Call;

   ------------------------------
   -- Preload_Root_Buffer_Type --
   ------------------------------

   procedure Preload_Root_Buffer_Type (Compilation_Unit : Node_Id) is
   begin
      --  We can't call RTE (RE_Root_Buffer_Type) for at least some
      --  predefined units, because it would introduce cyclic dependences.
      --  The package where Root_Buffer_Type is declared, for example, and
      --  things it depends on.
      --
      --  It's only needed for tagged types, so don't do it unless Put_Image is
      --  enabled for tagged types, and we've seen a tagged type. Note that
      --  Tagged_Seen is set True by the parser if the "tagged" reserved word
      --  is seen; this flag tells us whether we have any tagged types.
      --  It's unfortunate to have this Tagged_Seen processing so scattered
      --  about, but we need to know if there are tagged types where this is
      --  called in Analyze_Compilation_Unit, before we have analyzed any type
      --  declarations. This mechanism also prevents doing
      --  RTE (RE_Root_Buffer_Type) when compiling the compiler itself.
      --  Packages Ada.Strings.Buffer_Types and friends are not included
      --  in the compiler.
      --
      --  Don't do it if type Root_Buffer_Type is unavailable in the runtime.

      if not In_Predefined_Unit (Compilation_Unit)
        and then Tagged_Seen
        and then not No_Run_Time_Mode
        and then RTE_Available (RE_Root_Buffer_Type)
      then
         declare
            Ignore : constant Entity_Id := RTE (RE_Root_Buffer_Type);
         begin
            null;
         end;
      end if;
   end Preload_Root_Buffer_Type;

   -------------------------
   -- Put_Image_Base_Type --
   -------------------------

   function Put_Image_Base_Type (E : Entity_Id) return Entity_Id is
   begin
      if Is_Array_Type (E) and then Is_First_Subtype (E) then
         return E;
      else
         return Base_Type (E);
      end if;
   end Put_Image_Base_Type;

end Exp_Put_Image;
