------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                               F R E E Z E                                --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2006, 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 2,  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 COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;    use Atree;
with Debug;    use Debug;
with Einfo;    use Einfo;
with Elists;   use Elists;
with Errout;   use Errout;
with Exp_Ch7;  use Exp_Ch7;
with Exp_Pakd; use Exp_Pakd;
with Exp_Util; use Exp_Util;
with Exp_Tss;  use Exp_Tss;
with Layout;   use Layout;
with Lib.Xref; use Lib.Xref;
with Nlists;   use Nlists;
with Nmake;    use Nmake;
with Opt;      use Opt;
with Restrict; use Restrict;
with Rident;   use Rident;
with Sem;      use Sem;
with Sem_Cat;  use Sem_Cat;
with Sem_Ch6;  use Sem_Ch6;
with Sem_Ch7;  use Sem_Ch7;
with Sem_Ch8;  use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
with Sem_Eval; use Sem_Eval;
with Sem_Mech; use Sem_Mech;
with Sem_Prag; use Sem_Prag;
with Sem_Res;  use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo;    use Sinfo;
with Snames;   use Snames;
with Stand;    use Stand;
with Targparm; use Targparm;
with Tbuild;   use Tbuild;
with Ttypes;   use Ttypes;
with Uintp;    use Uintp;
with Urealp;   use Urealp;

package body Freeze is

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

   procedure Adjust_Esize_For_Alignment (Typ : Entity_Id);
   --  Typ is a type that is being frozen. If no size clause is given,
   --  but a default Esize has been computed, then this default Esize is
   --  adjusted up if necessary to be consistent with a given alignment,
   --  but never to a value greater than Long_Long_Integer'Size. This
   --  is used for all discrete types and for fixed-point types.

   procedure Build_And_Analyze_Renamed_Body
     (Decl  : Node_Id;
      New_S : Entity_Id;
      After : in out Node_Id);
   --  Build body for a renaming declaration, insert in tree and analyze

   procedure Check_Address_Clause (E : Entity_Id);
   --  Apply legality checks to address clauses for object declarations,
   --  at the point the object is frozen.

   procedure Check_Strict_Alignment (E : Entity_Id);
   --  E is a base type. If E is tagged or has a component that is aliased
   --  or tagged or contains something this is aliased or tagged, set
   --  Strict_Alignment.

   procedure Check_Unsigned_Type (E : Entity_Id);
   pragma Inline (Check_Unsigned_Type);
   --  If E is a fixed-point or discrete type, then all the necessary work
   --  to freeze it is completed except for possible setting of the flag
   --  Is_Unsigned_Type, which is done by this procedure. The call has no
   --  effect if the entity E is not a discrete or fixed-point type.

   procedure Freeze_And_Append
     (Ent    : Entity_Id;
      Loc    : Source_Ptr;
      Result : in out List_Id);
   --  Freezes Ent using Freeze_Entity, and appends the resulting list of
   --  nodes to Result, modifying Result from No_List if necessary.

   procedure Freeze_Enumeration_Type (Typ : Entity_Id);
   --  Freeze enumeration type. The Esize field is set as processing
   --  proceeds (i.e. set by default when the type is declared and then
   --  adjusted by rep clauses. What this procedure does is to make sure
   --  that if a foreign convention is specified, and no specific size
   --  is given, then the size must be at least Integer'Size.

   procedure Freeze_Static_Object (E : Entity_Id);
   --  If an object is frozen which has Is_Statically_Allocated set, then
   --  all referenced types must also be marked with this flag. This routine
   --  is in charge of meeting this requirement for the object entity E.

   procedure Freeze_Subprogram (E : Entity_Id);
   --  Perform freezing actions for a subprogram (create extra formals,
   --  and set proper default mechanism values). Note that this routine
   --  is not called for internal subprograms, for which neither of these
   --  actions is needed (or desirable, we do not want for example to have
   --  these extra formals present in initialization procedures, where they
   --  would serve no purpose). In this call E is either a subprogram or
   --  a subprogram type (i.e. an access to a subprogram).

   function Is_Fully_Defined (T : Entity_Id) return Boolean;
   --  True if T is not private and has no private components, or has a full
   --  view. Used to determine whether the designated type of an access type
   --  should be frozen when the access type is frozen. This is done when an
   --  allocator is frozen, or an expression that may involve attributes of
   --  the designated type. Otherwise freezing the access type does not freeze
   --  the designated type.

   procedure Process_Default_Expressions
     (E     : Entity_Id;
      After : in out Node_Id);
   --  This procedure is called for each subprogram to complete processing
   --  of default expressions at the point where all types are known to be
   --  frozen. The expressions must be analyzed in full, to make sure that
   --  all error processing is done (they have only been pre-analyzed). If
   --  the expression is not an entity or literal, its analysis may generate
   --  code which must not be executed. In that case we build a function
   --  body to hold that code. This wrapper function serves no other purpose
   --  (it used to be called to evaluate the default, but now the default is
   --  inlined at each point of call).

   procedure Set_Component_Alignment_If_Not_Set (Typ : Entity_Id);
   --  Typ is a record or array type that is being frozen. This routine
   --  sets the default component alignment from the scope stack values
   --  if the alignment is otherwise not specified.

   procedure Check_Debug_Info_Needed (T : Entity_Id);
   --  As each entity is frozen, this routine is called to deal with the
   --  setting of Debug_Info_Needed for the entity. This flag is set if
   --  the entity comes from source, or if we are in Debug_Generated_Code
   --  mode or if the -gnatdV debug flag is set. However, it never sets
   --  the flag if Debug_Info_Off is set.

   procedure Set_Debug_Info_Needed (T : Entity_Id);
   --  Sets the Debug_Info_Needed flag on entity T if not already set, and
   --  also on any entities that are needed by T (for an object, the type
   --  of the object is needed, and for a type, the subsidiary types are
   --  needed -- see body for details). Never has any effect on T if the
   --  Debug_Info_Off flag is set.

   procedure Undelay_Type (T : Entity_Id);
   --  T is a type of a component that we know to be an Itype.
   --  We don't want this to have a Freeze_Node, so ensure it doesn't.
   --  Do the same for any Full_View or Corresponding_Record_Type.

   procedure Warn_Overlay
     (Expr : Node_Id;
      Typ  : Entity_Id;
      Nam  : Node_Id);
   --  Expr is the expression for an address clause for entity Nam whose type
   --  is Typ. If Typ has a default initialization, and there is no explicit
   --  initialization in the source declaration, check whether the address
   --  clause might cause overlaying of an entity, and emit a warning on the
   --  side effect that the initialization will cause.

   -------------------------------
   -- Adjust_Esize_For_Alignment --
   -------------------------------

   procedure Adjust_Esize_For_Alignment (Typ : Entity_Id) is
      Align : Uint;

   begin
      if Known_Esize (Typ) and then Known_Alignment (Typ) then
         Align := Alignment_In_Bits (Typ);

         if Align > Esize (Typ)
           and then Align <= Standard_Long_Long_Integer_Size
         then
            Set_Esize (Typ, Align);
         end if;
      end if;
   end Adjust_Esize_For_Alignment;

   ------------------------------------
   -- Build_And_Analyze_Renamed_Body --
   ------------------------------------

   procedure Build_And_Analyze_Renamed_Body
     (Decl  : Node_Id;
      New_S : Entity_Id;
      After : in out Node_Id)
   is
      Body_Node : constant Node_Id := Build_Renamed_Body (Decl, New_S);
   begin
      Insert_After (After, Body_Node);
      Mark_Rewrite_Insertion (Body_Node);
      Analyze (Body_Node);
      After := Body_Node;
   end Build_And_Analyze_Renamed_Body;

   ------------------------
   -- Build_Renamed_Body --
   ------------------------

   function Build_Renamed_Body
     (Decl  : Node_Id;
      New_S : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (New_S);
      --  We use for the source location of the renamed body, the location
      --  of the spec entity. It might seem more natural to use the location
      --  of the renaming declaration itself, but that would be wrong, since
      --  then the body we create would look as though it was created far
      --  too late, and this could cause problems with elaboration order
      --  analysis, particularly in connection with instantiations.

      N          : constant Node_Id := Unit_Declaration_Node (New_S);
      Nam        : constant Node_Id := Name (N);
      Old_S      : Entity_Id;
      Spec       : constant Node_Id := New_Copy_Tree (Specification (Decl));
      Actuals    : List_Id := No_List;
      Call_Node  : Node_Id;
      Call_Name  : Node_Id;
      Body_Node  : Node_Id;
      Formal     : Entity_Id;
      O_Formal   : Entity_Id;
      Param_Spec : Node_Id;

   begin
      --  Determine the entity being renamed, which is the target of the
      --  call statement. If the name is an explicit dereference, this is
      --  a renaming of a subprogram type rather than a subprogram. The
      --  name itself is fully analyzed.

      if Nkind (Nam) = N_Selected_Component then
         Old_S := Entity (Selector_Name (Nam));

      elsif Nkind (Nam) = N_Explicit_Dereference then
         Old_S := Etype (Nam);

      elsif Nkind (Nam) = N_Indexed_Component then
         if Is_Entity_Name (Prefix (Nam)) then
            Old_S := Entity (Prefix (Nam));
         else
            Old_S := Entity (Selector_Name (Prefix (Nam)));
         end if;

      elsif Nkind (Nam) = N_Character_Literal then
         Old_S := Etype (New_S);

      else
         Old_S := Entity (Nam);
      end if;

      if Is_Entity_Name (Nam) then

         --  If the renamed entity is a predefined operator, retain full
         --  name to ensure its visibility.

         if Ekind (Old_S) = E_Operator
           and then Nkind (Nam) = N_Expanded_Name
         then
            Call_Name := New_Copy (Name (N));
         else
            Call_Name := New_Reference_To (Old_S, Loc);
         end if;

      else
         Call_Name := New_Copy (Name (N));

         --  The original name may have been overloaded, but
         --  is fully resolved now.

         Set_Is_Overloaded (Call_Name, False);
      end if;

      --  For simple renamings, subsequent calls can be expanded directly
      --  as called to the renamed entity. The body must be generated in
      --  any case for calls they may appear elsewhere.

      if (Ekind (Old_S) = E_Function
           or else Ekind (Old_S) = E_Procedure)
        and then Nkind (Decl) = N_Subprogram_Declaration
      then
         Set_Body_To_Inline (Decl, Old_S);
      end if;

      --  The body generated for this renaming is an internal artifact, and
      --  does not  constitute a freeze point for the called entity.

      Set_Must_Not_Freeze (Call_Name);

      Formal := First_Formal (Defining_Entity (Decl));

      if Present (Formal) then
         Actuals := New_List;

         while Present (Formal) loop
            Append (New_Reference_To (Formal, Loc), Actuals);
            Next_Formal (Formal);
         end loop;
      end if;

      --  If the renamed entity is an entry, inherit its profile. For
      --  other renamings as bodies, both profiles must be subtype
      --  conformant, so it is not necessary to replace the profile given
      --  in the declaration. However, default values that are aggregates
      --  are rewritten when partially analyzed, so we recover the original
      --  aggregate to insure that subsequent conformity checking works.
      --  Similarly, if the default expression was constant-folded, recover
      --  the original expression.

      Formal := First_Formal (Defining_Entity (Decl));

      if Present (Formal) then
         O_Formal := First_Formal (Old_S);
         Param_Spec := First (Parameter_Specifications (Spec));

         while Present (Formal) loop
            if Is_Entry (Old_S) then

               if Nkind (Parameter_Type (Param_Spec)) /=
                                                    N_Access_Definition
               then
                  Set_Etype (Formal, Etype (O_Formal));
                  Set_Entity (Parameter_Type (Param_Spec), Etype (O_Formal));
               end if;

            elsif Nkind (Default_Value (O_Formal)) = N_Aggregate
              or else Nkind (Original_Node (Default_Value (O_Formal))) /=
                                           Nkind (Default_Value (O_Formal))
            then
               Set_Expression (Param_Spec,
                 New_Copy_Tree (Original_Node (Default_Value (O_Formal))));
            end if;

            Next_Formal (Formal);
            Next_Formal (O_Formal);
            Next (Param_Spec);
         end loop;
      end if;

      --  If the renamed entity is a function, the generated body contains a
      --  return statement. Otherwise, build a procedure call. If the entity is
      --  an entry, subsequent analysis of the call will transform it into the
      --  proper entry or protected operation call. If the renamed entity is
      --  a character literal, return it directly.

      if Ekind (Old_S) = E_Function
        or else Ekind (Old_S) = E_Operator
        or else (Ekind (Old_S) = E_Subprogram_Type
                  and then Etype (Old_S) /= Standard_Void_Type)
      then
         Call_Node :=
           Make_Return_Statement (Loc,
              Expression =>
                Make_Function_Call (Loc,
                  Name => Call_Name,
                  Parameter_Associations => Actuals));

      elsif Ekind (Old_S) = E_Enumeration_Literal then
         Call_Node :=
           Make_Return_Statement (Loc,
              Expression => New_Occurrence_Of (Old_S, Loc));

      elsif Nkind (Nam) = N_Character_Literal then
         Call_Node :=
           Make_Return_Statement (Loc,
             Expression => Call_Name);

      else
         Call_Node :=
           Make_Procedure_Call_Statement (Loc,
             Name => Call_Name,
             Parameter_Associations => Actuals);
      end if;

      --  Create entities for subprogram body and formals

      Set_Defining_Unit_Name (Spec,
        Make_Defining_Identifier (Loc, Chars => Chars (New_S)));

      Param_Spec := First (Parameter_Specifications (Spec));

      while Present (Param_Spec) loop
         Set_Defining_Identifier (Param_Spec,
           Make_Defining_Identifier (Loc,
             Chars => Chars (Defining_Identifier (Param_Spec))));
         Next (Param_Spec);
      end loop;

      Body_Node :=
        Make_Subprogram_Body (Loc,
          Specification => Spec,
          Declarations => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              Statements => New_List (Call_Node)));

      if Nkind (Decl) /= N_Subprogram_Declaration then
         Rewrite (N,
           Make_Subprogram_Declaration (Loc,
             Specification => Specification (N)));
      end if;

      --  Link the body to the entity whose declaration it completes. If
      --  the body is analyzed when the renamed entity is frozen, it may be
      --  necessary to restore the proper scope (see package Exp_Ch13).

      if Nkind (N) =  N_Subprogram_Renaming_Declaration
        and then Present (Corresponding_Spec (N))
      then
         Set_Corresponding_Spec (Body_Node, Corresponding_Spec (N));
      else
         Set_Corresponding_Spec (Body_Node, New_S);
      end if;

      return Body_Node;
   end Build_Renamed_Body;

   --------------------------
   -- Check_Address_Clause --
   --------------------------

   procedure Check_Address_Clause (E : Entity_Id) is
      Addr : constant Node_Id   := Address_Clause (E);
      Expr : Node_Id;
      Decl : constant Node_Id   := Declaration_Node (E);
      Typ  : constant Entity_Id := Etype (E);

   begin
      if Present (Addr) then
         Expr := Expression (Addr);

         --  If we have no initialization of any kind, then we don't
         --  need to place any restrictions on the address clause, because
         --  the object will be elaborated after the address clause is
         --  evaluated. This happens if the declaration has no initial
         --  expression, or the type has no implicit initialization, or
         --  the object is imported.

         --  The same holds for all initialized scalar types and all
         --  access types. Packed bit arrays of size up to 64 are
         --  represented using a modular type with an initialization
         --  (to zero) and can be processed like other initialized
         --  scalar types.

         --  If the type is controlled, code to attach the object to a
         --  finalization chain is generated at the point of declaration,
         --  and therefore the elaboration of the object cannot be delayed:
         --  the address expression must be a constant.

         if (No (Expression (Decl))
              and then not Controlled_Type (Typ)
              and then
                (not Has_Non_Null_Base_Init_Proc (Typ)
                  or else Is_Imported (E)))

           or else
             (Present (Expression (Decl))
               and then Is_Scalar_Type (Typ))

           or else
             Is_Access_Type (Typ)

           or else
             (Is_Bit_Packed_Array (Typ)
               and then
                 Is_Modular_Integer_Type (Packed_Array_Type (Typ)))
         then
            null;

         --  Otherwise, we require the address clause to be constant
         --  because the call to the initialization procedure (or the
         --  attach code) has to happen at the point of the declaration.

         else
            Check_Constant_Address_Clause (Expr, E);
            Set_Has_Delayed_Freeze (E, False);
         end if;

         if not Error_Posted (Expr)
           and then not Controlled_Type (Typ)
         then
            Warn_Overlay (Expr, Typ, Name (Addr));
         end if;
      end if;
   end Check_Address_Clause;

   -----------------------------
   -- Check_Compile_Time_Size --
   -----------------------------

   procedure Check_Compile_Time_Size (T : Entity_Id) is

      procedure Set_Small_Size (T : Entity_Id; S : Uint);
      --  Sets the compile time known size (32 bits or less) in the Esize
      --  field, of T checking for a size clause that was given which attempts
      --  to give a smaller size.

      function Size_Known (T : Entity_Id) return Boolean;
      --  Recursive function that does all the work

      function Static_Discriminated_Components (T : Entity_Id) return Boolean;
      --  If T is a constrained subtype, its size is not known if any of its
      --  discriminant constraints is not static and it is not a null record.
      --  The test is conservative and doesn't check that the components are
      --  in fact constrained by non-static discriminant values. Could be made
      --  more precise ???

      --------------------
      -- Set_Small_Size --
      --------------------

      procedure Set_Small_Size (T : Entity_Id; S : Uint) is
      begin
         if S > 32 then
            return;

         elsif Has_Size_Clause (T) then
            if RM_Size (T) < S then
               Error_Msg_Uint_1 := S;
               Error_Msg_NE
                 ("size for & is too small, minimum is ^",
                  Size_Clause (T), T);

            elsif Unknown_Esize (T) then
               Set_Esize (T, S);
            end if;

         --  Set sizes if not set already

         else
            if Unknown_Esize (T) then
               Set_Esize (T, S);
            end if;

            if Unknown_RM_Size (T) then
               Set_RM_Size (T, S);
            end if;
         end if;
      end Set_Small_Size;

      ----------------
      -- Size_Known --
      ----------------

      function Size_Known (T : Entity_Id) return Boolean is
         Index : Entity_Id;
         Comp  : Entity_Id;
         Ctyp  : Entity_Id;
         Low   : Node_Id;
         High  : Node_Id;

      begin
         if Size_Known_At_Compile_Time (T) then
            return True;

         elsif Is_Scalar_Type (T)
           or else Is_Task_Type (T)
         then
            return not Is_Generic_Type (T);

         elsif Is_Array_Type (T) then
            if Ekind (T) = E_String_Literal_Subtype then
               Set_Small_Size (T, Component_Size (T)
                               * String_Literal_Length (T));
               return True;

            elsif not Is_Constrained (T) then
               return False;

            --  Don't do any recursion on type with error posted, since
            --  we may have a malformed type that leads us into a loop

            elsif Error_Posted (T) then
               return False;

            elsif not Size_Known (Component_Type (T)) then
               return False;
            end if;

            --  Check for all indexes static, and also compute possible
            --  size (in case it is less than 32 and may be packable).

            declare
               Esiz : Uint := Component_Size (T);
               Dim  : Uint;

            begin
               Index := First_Index (T);
               while Present (Index) loop
                  if Nkind (Index) = N_Range then
                     Get_Index_Bounds (Index, Low, High);

                  elsif Error_Posted (Scalar_Range (Etype (Index))) then
                     return False;

                  else
                     Low  := Type_Low_Bound (Etype (Index));
                     High := Type_High_Bound (Etype (Index));
                  end if;

                  if not Compile_Time_Known_Value (Low)
                    or else not Compile_Time_Known_Value (High)
                    or else Etype (Index) = Any_Type
                  then
                     return False;

                  else
                     Dim := Expr_Value (High) - Expr_Value (Low) + 1;

                     if Dim >= 0 then
                        Esiz := Esiz * Dim;
                     else
                        Esiz := Uint_0;
                     end if;
                  end if;

                  Next_Index (Index);
               end loop;

               Set_Small_Size (T, Esiz);
               return True;
            end;

         elsif Is_Access_Type (T) then
            return True;

         elsif Is_Private_Type (T)
           and then not Is_Generic_Type (T)
           and then Present (Underlying_Type (T))
         then
            --  Don't do any recursion on type with error posted, since
            --  we may have a malformed type that leads us into a loop

            if Error_Posted (T) then
               return False;
            else
               return Size_Known (Underlying_Type (T));
            end if;

         elsif Is_Record_Type (T) then

            --  A class-wide type is never considered to have a known size

            if Is_Class_Wide_Type (T) then
               return False;

            --  A subtype of a variant record must not have non-static
            --  discriminanted components.

            elsif T /= Base_Type (T)
              and then not Static_Discriminated_Components (T)
            then
               return False;

            --  Don't do any recursion on type with error posted, since
            --  we may have a malformed type that leads us into a loop

            elsif Error_Posted (T) then
               return False;
            end if;

            --  Now look at the components of the record

            declare
               --  The following two variables are used to keep track of
               --  the size of packed records if we can tell the size of
               --  the packed record in the front end. Packed_Size_Known
               --  is True if so far we can figure out the size. It is
               --  initialized to True for a packed record, unless the
               --  record has discriminants. The reason we eliminate the
               --  discriminated case is that we don't know the way the
               --  back end lays out discriminated packed records. If
               --  Packed_Size_Known is True, then Packed_Size is the
               --  size in bits so far.

               Packed_Size_Known : Boolean :=
                                     Is_Packed (T)
                                       and then not Has_Discriminants (T);

               Packed_Size : Uint := Uint_0;

            begin
               --  Test for variant part present

               if Has_Discriminants (T)
                 and then Present (Parent (T))
                 and then Nkind (Parent (T)) = N_Full_Type_Declaration
                 and then Nkind (Type_Definition (Parent (T))) =
                            N_Record_Definition
                 and then not Null_Present (Type_Definition (Parent (T)))
                 and then Present (Variant_Part
                            (Component_List (Type_Definition (Parent (T)))))
               then
                  --  If variant part is present, and type is unconstrained,
                  --  then we must have defaulted discriminants, or a size
                  --  clause must be present for the type, or else the size
                  --  is definitely not known at compile time.

                  if not Is_Constrained (T)
                    and then
                      No (Discriminant_Default_Value
                           (First_Discriminant (T)))
                    and then Unknown_Esize (T)
                  then
                     return False;
                  end if;
               end if;

               --  Loop through components

               Comp := First_Entity (T);
               while Present (Comp) loop
                  if Ekind (Comp) = E_Component
                       or else
                     Ekind (Comp) = E_Discriminant
                  then
                     Ctyp := Etype (Comp);

                     --  We do not know the packed size if there is a
                     --  component clause present (we possibly could,
                     --  but this would only help in the case of a record
                     --  with partial rep clauses. That's because in the
                     --  case of full rep clauses, the size gets figured
                     --  out anyway by a different circuit).

                     if Present (Component_Clause (Comp)) then
                        Packed_Size_Known := False;
                     end if;

                     --  We need to identify a component that is an array
                     --  where the index type is an enumeration type with
                     --  non-standard representation, and some bound of the
                     --  type depends on a discriminant.

                     --  This is because gigi computes the size by doing a
                     --  substituation of the appropriate discriminant value
                     --  in the size expression for the base type, and gigi
                     --  is not clever enough to evaluate the resulting
                     --  expression (which involves a call to rep_to_pos)
                     --  at compile time.

                     --  It would be nice if gigi would either recognize that
                     --  this expression can be computed at compile time, or
                     --  alternatively figured out the size from the subtype
                     --  directly, where all the information is at hand ???

                     if Is_Array_Type (Etype (Comp))
                       and then Present (Packed_Array_Type (Etype (Comp)))
                     then
                        declare
                           Ocomp  : constant Entity_Id :=
                                      Original_Record_Component (Comp);
                           OCtyp  : constant Entity_Id := Etype (Ocomp);
                           Ind    : Node_Id;
                           Indtyp : Entity_Id;
                           Lo, Hi : Node_Id;

                        begin
                           Ind := First_Index (OCtyp);
                           while Present (Ind) loop
                              Indtyp := Etype (Ind);

                              if Is_Enumeration_Type (Indtyp)
                                and then Has_Non_Standard_Rep (Indtyp)
                              then
                                 Lo := Type_Low_Bound  (Indtyp);
                                 Hi := Type_High_Bound (Indtyp);

                                 if Is_Entity_Name (Lo)
                                   and then
                                     Ekind (Entity (Lo)) = E_Discriminant
                                 then
                                    return False;

                                 elsif Is_Entity_Name (Hi)
                                   and then
                                     Ekind (Entity (Hi)) = E_Discriminant
                                 then
                                    return False;
                                 end if;
                              end if;

                              Next_Index (Ind);
                           end loop;
                        end;
                     end if;

                     --  Clearly size of record is not known if the size of
                     --  one of the components is not known.

                     if not Size_Known (Ctyp) then
                        return False;
                     end if;

                     --  Accumulate packed size if possible

                     if Packed_Size_Known then

                        --  We can only deal with elementary types, since for
                        --  non-elementary components, alignment enters into
                        --  the picture, and we don't know enough to handle
                        --  proper alignment in this context. Packed arrays
                        --  count as elementary if the representation is a
                        --  modular type.

                        if Is_Elementary_Type (Ctyp)
                          or else (Is_Array_Type (Ctyp)
                                     and then
                                       Present (Packed_Array_Type (Ctyp))
                                     and then
                                       Is_Modular_Integer_Type
                                         (Packed_Array_Type (Ctyp)))
                        then
                           --  If RM_Size is known and static, then we can
                           --  keep accumulating the packed size.

                           if Known_Static_RM_Size (Ctyp) then

                              --  A little glitch, to be removed sometime ???
                              --  gigi does not understand zero sizes yet.

                              if RM_Size (Ctyp) = Uint_0 then
                                 Packed_Size_Known := False;

                              --  Normal case where we can keep accumulating
                              --  the packed array size.

                              else
                                 Packed_Size := Packed_Size + RM_Size (Ctyp);
                              end if;

                           --  If we have a field whose RM_Size is not known
                           --  then we can't figure out the packed size here.

                           else
                              Packed_Size_Known := False;
                           end if;

                        --  If we have a non-elementary type we can't figure
                        --  out the packed array size (alignment issues).

                        else
                           Packed_Size_Known := False;
                        end if;
                     end if;
                  end if;

                  Next_Entity (Comp);
               end loop;

               if Packed_Size_Known then
                  Set_Small_Size (T, Packed_Size);
               end if;

               return True;
            end;

         else
            return False;
         end if;
      end Size_Known;

      -------------------------------------
      -- Static_Discriminated_Components --
      -------------------------------------

      function Static_Discriminated_Components
        (T : Entity_Id) return Boolean
      is
         Constraint : Elmt_Id;
         Discr      : Entity_Id;

      begin
         if Has_Discriminants (T)
           and then Present (Discriminant_Constraint (T))
           and then Present (First_Component (T))
         then
            Discr := First_Discriminant (T);

            if Is_Access_Type (Etype (Discr)) then
               null;

            --  If the bounds of the discriminant are not compile-time known,
            --  treat this as non-static, even if the value of the discriminant
            --  is compile-time known, because the back-end treats aggregates
            --  of such a subtype as having unknown size.

            elsif not
              (Compile_Time_Known_Value (Type_Low_Bound  (Etype (Discr)))
                 and then
               Compile_Time_Known_Value (Type_High_Bound (Etype (Discr))))
            then
               return False;
            end if;

            Constraint := First_Elmt (Discriminant_Constraint (T));
            while Present (Constraint) loop
               if not Compile_Time_Known_Value (Node (Constraint)) then
                  return False;
               end if;

               Next_Elmt (Constraint);
            end loop;
         end if;

         return True;
      end Static_Discriminated_Components;

   --  Start of processing for Check_Compile_Time_Size

   begin
      Set_Size_Known_At_Compile_Time (T, Size_Known (T));
   end Check_Compile_Time_Size;

   -----------------------------
   -- Check_Debug_Info_Needed --
   -----------------------------

   procedure Check_Debug_Info_Needed (T : Entity_Id) is
   begin
      if Needs_Debug_Info (T) or else Debug_Info_Off (T) then
         return;

      elsif Comes_From_Source (T)
        or else Debug_Generated_Code
        or else Debug_Flag_VV
      then
         Set_Debug_Info_Needed (T);
      end if;
   end Check_Debug_Info_Needed;

   ----------------------------
   -- Check_Strict_Alignment --
   ----------------------------

   procedure Check_Strict_Alignment (E : Entity_Id) is
      Comp  : Entity_Id;

   begin
      if Is_Tagged_Type (E) or else Is_Concurrent_Type (E) then
         Set_Strict_Alignment (E);

      elsif Is_Array_Type (E) then
         Set_Strict_Alignment (E, Strict_Alignment (Component_Type (E)));

      elsif Is_Record_Type (E) then
         if Is_Limited_Record (E) then
            Set_Strict_Alignment (E);
            return;
         end if;

         Comp := First_Component (E);

         while Present (Comp) loop
            if not Is_Type (Comp)
              and then (Strict_Alignment (Etype (Comp))
                         or else Is_Aliased (Comp))
            then
               Set_Strict_Alignment (E);
               return;
            end if;

            Next_Component (Comp);
         end loop;
      end if;
   end Check_Strict_Alignment;

   -------------------------
   -- Check_Unsigned_Type --
   -------------------------

   procedure Check_Unsigned_Type (E : Entity_Id) is
      Ancestor : Entity_Id;
      Lo_Bound : Node_Id;
      Btyp     : Entity_Id;

   begin
      if not Is_Discrete_Or_Fixed_Point_Type (E) then
         return;
      end if;

      --  Do not attempt to analyze case where range was in error

      if Error_Posted (Scalar_Range (E)) then
         return;
      end if;

      --  The situation that is non trivial is something like

      --     subtype x1 is integer range -10 .. +10;
      --     subtype x2 is x1 range 0 .. V1;
      --     subtype x3 is x2 range V2 .. V3;
      --     subtype x4 is x3 range V4 .. V5;

      --  where Vn are variables. Here the base type is signed, but we still
      --  know that x4 is unsigned because of the lower bound of x2.

      --  The only way to deal with this is to look up the ancestor chain

      Ancestor := E;
      loop
         if Ancestor = Any_Type or else Etype (Ancestor) = Any_Type then
            return;
         end if;

         Lo_Bound := Type_Low_Bound (Ancestor);

         if Compile_Time_Known_Value (Lo_Bound) then

            if Expr_Rep_Value (Lo_Bound) >= 0 then
               Set_Is_Unsigned_Type (E, True);
            end if;

            return;

         else
            Ancestor := Ancestor_Subtype (Ancestor);

            --  If no ancestor had a static lower bound, go to base type

            if No (Ancestor) then

               --  Note: the reason we still check for a compile time known
               --  value for the base type is that at least in the case of
               --  generic formals, we can have bounds that fail this test,
               --  and there may be other cases in error situations.

               Btyp := Base_Type (E);

               if Btyp = Any_Type or else Etype (Btyp) = Any_Type then
                  return;
               end if;

               Lo_Bound := Type_Low_Bound (Base_Type (E));

               if Compile_Time_Known_Value (Lo_Bound)
                 and then Expr_Rep_Value (Lo_Bound) >= 0
               then
                  Set_Is_Unsigned_Type (E, True);
               end if;

               return;
            end if;
         end if;
      end loop;
   end Check_Unsigned_Type;

   -----------------------------
   -- Expand_Atomic_Aggregate --
   -----------------------------

   procedure Expand_Atomic_Aggregate (E : Entity_Id; Typ : Entity_Id) is
      Loc   : constant Source_Ptr := Sloc (E);
      New_N : Node_Id;
      Temp  : Entity_Id;

   begin
      if (Nkind (Parent (E)) = N_Object_Declaration
            or else Nkind (Parent (E)) = N_Assignment_Statement)
        and then Comes_From_Source (Parent (E))
        and then Nkind (E) = N_Aggregate
      then
         Temp :=
           Make_Defining_Identifier (Loc,
             New_Internal_Name ('T'));

         New_N :=
           Make_Object_Declaration (Loc,
             Defining_Identifier => Temp,
         --  LLVM local
             Object_Definition => New_Occurrence_Of (Typ, Loc),
             Expression => Relocate_Node (E));
         Insert_Before (Parent (E), New_N);
         Analyze (New_N);

         Set_Expression (Parent (E), New_Occurrence_Of (Temp, Loc));

         --  To prevent the temporary from being constant-folded (which
         --  would lead to the same piecemeal assignment on the original
         --  target) indicate to the back-end that the temporary  is a
         --  variable with real storage. See description of this flag
         --  in Einfo, and the notes on N_Assignment_Statement and
         --  N_Object_Declaration in Sinfo.

         Set_Is_True_Constant (Temp, False);
      end if;
   end Expand_Atomic_Aggregate;

   ----------------
   -- Freeze_All --
   ----------------

   --  Note: the easy coding for this procedure would be to just build a
   --  single list of freeze nodes and then insert them and analyze them
   --  all at once. This won't work, because the analysis of earlier freeze
   --  nodes may recursively freeze types which would otherwise appear later
   --  on in the freeze list. So we must analyze and expand the freeze nodes
   --  as they are generated.

   procedure Freeze_All (From : Entity_Id; After : in out Node_Id) is
      Loc   : constant Source_Ptr := Sloc (After);
      E     : Entity_Id;
      Decl  : Node_Id;

      procedure Freeze_All_Ent (From : Entity_Id; After : in out Node_Id);
      --  This is the internal recursive routine that does freezing of
      --  entities (but NOT the analysis of default expressions, which
      --  should not be recursive, we don't want to analyze those till
      --  we are sure that ALL the types are frozen).

      --------------------
      -- Freeze_All_Ent --
      --------------------

      procedure Freeze_All_Ent
        (From  : Entity_Id;
         After : in out Node_Id)
      is
         E     : Entity_Id;
         Flist : List_Id;
         Lastn : Node_Id;

         procedure Process_Flist;
         --  If freeze nodes are present, insert and analyze, and reset
         --  cursor for next insertion.

         -------------------
         -- Process_Flist --
         -------------------

         procedure Process_Flist is
         begin
            if Is_Non_Empty_List (Flist) then
               Lastn := Next (After);
               Insert_List_After_And_Analyze (After, Flist);

               if Present (Lastn) then
                  After := Prev (Lastn);
               else
                  After := Last (List_Containing (After));
               end if;
            end if;
         end Process_Flist;

      --  Start or processing for Freeze_All_Ent

      begin
         E := From;
         while Present (E) loop

            --  If the entity is an inner package which is not a package
            --  renaming, then its entities must be frozen at this point.
            --  Note that such entities do NOT get frozen at the end of
            --  the nested package itself (only library packages freeze).

            --  Same is true for task declarations, where anonymous records
            --  created for entry parameters must be frozen.

            if Ekind (E) = E_Package
              and then No (Renamed_Object (E))
              and then not Is_Child_Unit (E)
              and then not Is_Frozen (E)
            then
               New_Scope (E);
               Install_Visible_Declarations (E);
               Install_Private_Declarations (E);

               Freeze_All (First_Entity (E), After);

               End_Package_Scope (E);

            elsif Ekind (E) in Task_Kind
              and then
                (Nkind (Parent (E)) = N_Task_Type_Declaration
                   or else
                 Nkind (Parent (E)) = N_Single_Task_Declaration)
            then
               New_Scope (E);
               Freeze_All (First_Entity (E), After);
               End_Scope;

            --  For a derived tagged type, we must ensure that all the
            --  primitive operations of the parent have been frozen, so
            --  that their addresses will be in the parent's dispatch table
            --  at the point it is inherited.

            elsif Ekind (E) = E_Record_Type
              and then Is_Tagged_Type (E)
              and then Is_Tagged_Type (Etype (E))
              and then Is_Derived_Type (E)
            then
               declare
                  Prim_List : constant Elist_Id :=
                               Primitive_Operations (Etype (E));

                  Prim : Elmt_Id;
                  Subp : Entity_Id;

               begin
                  Prim  := First_Elmt (Prim_List);

                  while Present (Prim) loop
                     Subp := Node (Prim);

                     if Comes_From_Source (Subp)
                       and then not Is_Frozen (Subp)
                     then
                        Flist := Freeze_Entity (Subp, Loc);
                        Process_Flist;
                     end if;

                     Next_Elmt (Prim);
                  end loop;
               end;
            end if;

            if not Is_Frozen (E) then
               Flist := Freeze_Entity (E, Loc);
               Process_Flist;
            end if;

            --  If an incomplete type is still not frozen, this may be
            --  a premature freezing because of a body declaration that
            --  follows. Indicate where the freezing took place.

            --  If the freezing is caused by the end of the current
            --  declarative part, it is a Taft Amendment type, and there
            --  is no error.

            if not Is_Frozen (E)
              and then Ekind (E) = E_Incomplete_Type
            then
               declare
                  Bod : constant Node_Id := Next (After);

               begin
                  if (Nkind (Bod) = N_Subprogram_Body
                        or else Nkind (Bod) = N_Entry_Body
                        or else Nkind (Bod) = N_Package_Body
                        or else Nkind (Bod) = N_Protected_Body
                        or else Nkind (Bod) = N_Task_Body
                        or else Nkind (Bod) in N_Body_Stub)
                     and then
                       List_Containing (After) = List_Containing (Parent (E))
                  then
                     Error_Msg_Sloc := Sloc (Next (After));
                     Error_Msg_NE
                       ("type& is frozen# before its full declaration",
                         Parent (E), E);
                  end if;
               end;
            end if;

            Next_Entity (E);
         end loop;
      end Freeze_All_Ent;

   --  Start of processing for Freeze_All

   begin
      Freeze_All_Ent (From, After);

      --  Now that all types are frozen, we can deal with default expressions
      --  that require us to build a default expression functions. This is the
      --  point at which such functions are constructed (after all types that
      --  might be used in such expressions have been frozen).

      --  We also add finalization chains to access types whose designated
      --  types are controlled. This is normally done when freezing the type,
      --  but this misses recursive type definitions where the later members
      --  of the recursion introduce controlled components (e.g. 5624-001).

      --  Loop through entities

      E := From;
      while Present (E) loop
         if Is_Subprogram (E) then

            if not Default_Expressions_Processed (E) then
               Process_Default_Expressions (E, After);
            end if;

            if not Has_Completion (E) then
               Decl := Unit_Declaration_Node (E);

               if Nkind (Decl) = N_Subprogram_Renaming_Declaration then
                  Build_And_Analyze_Renamed_Body (Decl, E, After);

               elsif Nkind (Decl) = N_Subprogram_Declaration
                 and then Present (Corresponding_Body (Decl))
                 and then
                   Nkind (Unit_Declaration_Node (Corresponding_Body (Decl)))
                                          = N_Subprogram_Renaming_Declaration
               then
                  Build_And_Analyze_Renamed_Body
                    (Decl, Corresponding_Body (Decl), After);
               end if;
            end if;

         elsif Ekind (E) in Task_Kind
           and then
             (Nkind (Parent (E)) = N_Task_Type_Declaration
                or else
              Nkind (Parent (E)) = N_Single_Task_Declaration)
         then
            declare
               Ent : Entity_Id;
            begin
               Ent := First_Entity (E);

               while Present (Ent) loop

                  if Is_Entry (Ent)
                    and then not Default_Expressions_Processed (Ent)
                  then
                     Process_Default_Expressions (Ent, After);
                  end if;

                  Next_Entity (Ent);
               end loop;
            end;

         elsif Is_Access_Type (E)
           and then Comes_From_Source (E)
           and then Ekind (Directly_Designated_Type (E)) = E_Incomplete_Type
           and then Controlled_Type (Designated_Type (E))
           and then No (Associated_Final_Chain (E))
         then
            Build_Final_List (Parent (E), E);
         end if;

         Next_Entity (E);
      end loop;
   end Freeze_All;

   -----------------------
   -- Freeze_And_Append --
   -----------------------

   procedure Freeze_And_Append
     (Ent    : Entity_Id;
      Loc    : Source_Ptr;
      Result : in out List_Id)
   is
      L : constant List_Id := Freeze_Entity (Ent, Loc);
   begin
      if Is_Non_Empty_List (L) then
         if Result = No_List then
            Result := L;
         else
            Append_List (L, Result);
         end if;
      end if;
   end Freeze_And_Append;

   -------------------
   -- Freeze_Before --
   -------------------

   procedure Freeze_Before (N : Node_Id; T : Entity_Id) is
      Freeze_Nodes : constant List_Id := Freeze_Entity (T, Sloc (N));
   begin
      if Is_Non_Empty_List (Freeze_Nodes) then
         Insert_Actions (N, Freeze_Nodes);
      end if;
   end Freeze_Before;

   -------------------
   -- Freeze_Entity --
   -------------------

   function Freeze_Entity (E : Entity_Id; Loc : Source_Ptr) return List_Id is
      Test_E : Entity_Id := E;
      Comp   : Entity_Id;
      F_Node : Node_Id;
      Result : List_Id;
      Indx   : Node_Id;
      Formal : Entity_Id;
      Atype  : Entity_Id;

      procedure Check_Current_Instance (Comp_Decl : Node_Id);
      --  Check that an Access or Unchecked_Access attribute with a prefix
      --  which is the current instance type can only be applied when the type
      --  is limited.

      function After_Last_Declaration return Boolean;
      --  If Loc is a freeze_entity that appears after the last declaration
      --  in the scope, inhibit error messages on late completion.

      procedure Freeze_Record_Type (Rec : Entity_Id);
      --  Freeze each component, handle some representation clauses, and freeze
      --  primitive operations if this is a tagged type.

      ----------------------------
      -- After_Last_Declaration --
      ----------------------------

      function After_Last_Declaration return Boolean is
         Spec  : constant Node_Id := Parent (Current_Scope);

      begin
         if Nkind (Spec) = N_Package_Specification then
            if Present (Private_Declarations (Spec)) then
               return Loc >= Sloc (Last (Private_Declarations (Spec)));

            elsif Present (Visible_Declarations (Spec)) then
               return Loc >= Sloc (Last (Visible_Declarations (Spec)));
            else
               return False;
            end if;

         else
            return False;
         end if;
      end After_Last_Declaration;

      ----------------------------
      -- Check_Current_Instance --
      ----------------------------

      procedure Check_Current_Instance (Comp_Decl : Node_Id) is

         function Process (N : Node_Id) return Traverse_Result;
         --  Process routine to apply check to given node

         -------------
         -- Process --
         -------------

         function Process (N : Node_Id) return Traverse_Result is
         begin
            case Nkind (N) is
               when N_Attribute_Reference =>
                  if  (Attribute_Name (N) = Name_Access
                        or else
                      Attribute_Name (N) = Name_Unchecked_Access)
                    and then Is_Entity_Name (Prefix (N))
                    and then Is_Type (Entity (Prefix (N)))
                    and then Entity (Prefix (N)) = E
                  then
                     Error_Msg_N
                       ("current instance must be a limited type", Prefix (N));
                     return Abandon;
                  else
                     return OK;
                  end if;

               when others => return OK;
            end case;
         end Process;

         procedure Traverse is new Traverse_Proc (Process);

      --  Start of processing for Check_Current_Instance

      begin
         Traverse (Comp_Decl);
      end Check_Current_Instance;

      ------------------------
      -- Freeze_Record_Type --
      ------------------------

      procedure Freeze_Record_Type (Rec : Entity_Id) is
         Comp : Entity_Id;
         IR   : Node_Id;
         Junk : Boolean;
         ADC  : Node_Id;
         Prev : Entity_Id;

         Unplaced_Component : Boolean := False;
         --  Set True if we find at least one component with no component
         --  clause (used to warn about useless Pack pragmas).

         Placed_Component : Boolean := False;
         --  Set True if we find at least one component with a component
         --  clause (used to warn about useless Bit_Order pragmas).

         procedure Check_Itype (Desig : Entity_Id);
         --  If the component subtype is an access to a constrained subtype
         --  of an already frozen type, make the subtype frozen as well. It
         --  might otherwise be frozen in the wrong scope, and a freeze node
         --  on subtype has no effect.

         -----------------
         -- Check_Itype --
         -----------------

         procedure Check_Itype (Desig : Entity_Id) is
         begin
            if not Is_Frozen (Desig)
              and then Is_Frozen (Base_Type (Desig))
            then
               Set_Is_Frozen (Desig);

               --  In addition, add an Itype_Reference to ensure that the
               --  access subtype is elaborated early enough. This cannot
               --  be done if the subtype may depend on discriminants.

               if Ekind (Comp) = E_Component
                 and then Is_Itype (Etype (Comp))
                 and then not Has_Discriminants (Rec)
               then
                  IR := Make_Itype_Reference (Sloc (Comp));
                  Set_Itype (IR, Desig);

                  if No (Result) then
                     Result := New_List (IR);
                  else
                     Append (IR, Result);
                  end if;
               end if;
            end if;
         end Check_Itype;

      --  Start of processing for Freeze_Record_Type

      begin
         --  If this is a subtype of a controlled type, declared without
         --  a constraint, the _controller may not appear in the component
         --  list if the parent was not frozen at the point of subtype
         --  declaration. Inherit the _controller component now.

         if Rec /= Base_Type (Rec)
           and then Has_Controlled_Component (Rec)
         then
            if Nkind (Parent (Rec)) = N_Subtype_Declaration
              and then Is_Entity_Name (Subtype_Indication (Parent (Rec)))
            then
               Set_First_Entity (Rec, First_Entity (Base_Type (Rec)));

            --  If this is an internal type without a declaration, as for
            --  record component, the base type may not yet be frozen, and its
            --  controller has not been created. Add an explicit freeze node
            --  for the itype, so it will be frozen after the base type. This
            --  freeze node is used to communicate with the expander, in order
            --  to create the controller for the enclosing record, and it is
            --  deleted afterwards (see exp_ch3). It must not be created when
            --  expansion is off, because it might appear in the wrong context
            --  for the back end.

            elsif Is_Itype (Rec)
              and then Has_Delayed_Freeze (Base_Type (Rec))
              and then
                Nkind (Associated_Node_For_Itype (Rec)) =
                                                     N_Component_Declaration
              and then Expander_Active
            then
               Ensure_Freeze_Node (Rec);
            end if;
         end if;

         --  Freeze components and embedded subtypes

         Comp := First_Entity (Rec);
         Prev := Empty;
         while Present (Comp) loop

            --  First handle the (real) component case

            if Ekind (Comp) = E_Component
              or else Ekind (Comp) = E_Discriminant
            then
               declare
                  CC : constant Node_Id := Component_Clause (Comp);

               begin
                  --  Freezing a record type freezes the type of each of its
                  --  components. However, if the type of the component is
                  --  part of this record, we do not want or need a separate
                  --  Freeze_Node. Note that Is_Itype is wrong because that's
                  --  also set in private type cases. We also can't check for
                  --  the Scope being exactly Rec because of private types and
                  --  record extensions.

                  if Is_Itype (Etype (Comp))
                    and then Is_Record_Type (Underlying_Type
                                             (Scope (Etype (Comp))))
                  then
                     Undelay_Type (Etype (Comp));
                  end if;

                  Freeze_And_Append (Etype (Comp), Loc, Result);

                  --  Check for error of component clause given for variable
                  --  sized type. We have to delay this test till this point,
                  --  since the component type has to be frozen for us to know
                  --  if it is variable length. We omit this test in a generic
                  --  context, it will be applied at instantiation time.

                  if Present (CC) then
                     Placed_Component := True;

                     if Inside_A_Generic then
                        null;

                     elsif not Size_Known_At_Compile_Time
                              (Underlying_Type (Etype (Comp)))
                     then
                        Error_Msg_N
                          ("component clause not allowed for variable " &
                           "length component", CC);
                     end if;

                  else
                     Unplaced_Component := True;
                  end if;

                  --  Case of component requires byte alignment

                  if Must_Be_On_Byte_Boundary (Etype (Comp)) then

                     --  Set the enclosing record to also require byte align

                     Set_Must_Be_On_Byte_Boundary (Rec);

                     --  Check for component clause that is inconsistent
                     --  with the required byte boundary alignment.

                     if Present (CC)
                       and then Normalized_First_Bit (Comp) mod
                                  System_Storage_Unit /= 0
                     then
                        Error_Msg_N
                          ("component & must be byte aligned",
                           Component_Name (Component_Clause (Comp)));
                     end if;
                  end if;

                  --  If component clause is present, then deal with the
                  --  non-default bit order case. We cannot do this before
                  --  the freeze point, because there is no required order
                  --  for the component clause and the bit_order clause.

                  --  We only do this processing for the base type, and in
                  --  fact that's important, since otherwise if there are
                  --  record subtypes, we could reverse the bits once for
                  --  each subtype, which would be incorrect.

                  if Present (CC)
                    and then Reverse_Bit_Order (Rec)
                    and then Ekind (E) = E_Record_Type
                  then
                     declare
                        CFB : constant Uint    := Component_Bit_Offset (Comp);
                        CSZ : constant Uint    := Esize (Comp);
                        CLC : constant Node_Id := Component_Clause (Comp);
                        Pos : constant Node_Id := Position (CLC);
                        FB  : constant Node_Id := First_Bit (CLC);

                        Storage_Unit_Offset : constant Uint :=
                                                CFB / System_Storage_Unit;

                        Start_Bit : constant Uint :=
                                      CFB mod System_Storage_Unit;

                     begin
                        --  Cases where field goes over storage unit boundary

                        if Start_Bit + CSZ > System_Storage_Unit then

                           --  Allow multi-byte field but generate warning

                           if Start_Bit mod System_Storage_Unit = 0
                             and then CSZ mod System_Storage_Unit = 0
                           then
                              Error_Msg_N
                                ("multi-byte field specified with non-standard"
                                 & " Bit_Order?", CLC);

                              if Bytes_Big_Endian then
                                 Error_Msg_N
                                   ("bytes are not reversed "
                                    & "(component is big-endian)?", CLC);
                              else
                                 Error_Msg_N
                                   ("bytes are not reversed "
                                    & "(component is little-endian)?", CLC);
                              end if;

                              --  Do not allow non-contiguous field

                           else
                              Error_Msg_N
                                ("attempt to specify non-contiguous field"
                                 & " not permitted", CLC);
                              Error_Msg_N
                                ("\(caused by non-standard Bit_Order "
                                 & "specified)", CLC);
                           end if;

                           --  Case where field fits in one storage unit

                        else
                           --  Give warning if suspicious component clause

                           if Intval (FB) >= System_Storage_Unit then
                              Error_Msg_N
                                ("?Bit_Order clause does not affect " &
                                 "byte ordering", Pos);
                              Error_Msg_Uint_1 :=
                                Intval (Pos) + Intval (FB) /
                                  System_Storage_Unit;
                              Error_Msg_N
                                ("?position normalized to ^ before bit " &
                                 "order interpreted", Pos);
                           end if;

                           --  Here is where we fix up the Component_Bit_Offset
                           --  value to account for the reverse bit order.
                           --  Some examples of what needs to be done are:

                           --    First_Bit .. Last_Bit     Component_Bit_Offset
                           --      old          new          old       new

                           --     0 .. 0       7 .. 7         0         7
                           --     0 .. 1       6 .. 7         0         6
                           --     0 .. 2       5 .. 7         0         5
                           --     0 .. 7       0 .. 7         0         4

                           --     1 .. 1       6 .. 6         1         6
                           --     1 .. 4       3 .. 6         1         3
                           --     4 .. 7       0 .. 3         4         0

                           --  The general rule is that the first bit is
                           --  is obtained by subtracting the old ending bit
                           --  from storage_unit - 1.

                           Set_Component_Bit_Offset
                             (Comp,
                              (Storage_Unit_Offset * System_Storage_Unit) +
                                (System_Storage_Unit - 1) -
                                  (Start_Bit + CSZ - 1));

                           Set_Normalized_First_Bit
                             (Comp,
                                Component_Bit_Offset (Comp) mod
                                  System_Storage_Unit);
                        end if;
                     end;
                  end if;
               end;
            end if;

            --  If the component is an Itype with Delayed_Freeze and is either
            --  a record or array subtype and its base type has not yet been
            --  frozen, we must remove this from the entity list of this
            --  record and put it on the entity list of the scope of its base
            --  type. Note that we know that this is not the type of a
            --  component since we cleared Has_Delayed_Freeze for it in the
            --  previous loop. Thus this must be the Designated_Type of an
            --  access type, which is the type of a component.

            if Is_Itype (Comp)
              and then Is_Type (Scope (Comp))
              and then Is_Composite_Type (Comp)
              and then Base_Type (Comp) /= Comp
              and then Has_Delayed_Freeze (Comp)
              and then not Is_Frozen (Base_Type (Comp))
            then
               declare
                  Will_Be_Frozen : Boolean := False;
                  S : Entity_Id := Scope (Rec);

               begin
                  --  We have a pretty bad kludge here. Suppose Rec is a
                  --  subtype being defined in a subprogram that's created
                  --  as part of the freezing of Rec'Base. In that case,
                  --  we know that Comp'Base must have already been frozen by
                  --  the time we get to elaborate this because Gigi doesn't
                  --  elaborate any bodies until it has elaborated all of the
                  --  declarative part. But Is_Frozen will not be  set at this
                  --  point because we are processing code in lexical order.

                  --  We detect this case by going up the Scope chain of
                  --  Rec and seeing if we have a subprogram scope before
                  --  reaching the top of the scope chain or that of Comp'Base.
                  --  If we do, then mark that Comp'Base will actually be
                  --  frozen. If so, we merely undelay it.

                  while Present (S) loop
                     if Is_Subprogram (S) then
                        Will_Be_Frozen := True;
                        exit;
                     elsif S = Scope (Base_Type (Comp)) then
                        exit;
                     end if;

                     S := Scope (S);
                  end loop;

                  if Will_Be_Frozen then
                     Undelay_Type (Comp);
                  else
                     if Present (Prev) then
                        Set_Next_Entity (Prev, Next_Entity (Comp));
                     else
                        Set_First_Entity (Rec, Next_Entity (Comp));
                     end if;

                     --  Insert in entity list of scope of base type (which
                     --  must be an enclosing scope, because still unfrozen).

                     Append_Entity (Comp, Scope (Base_Type (Comp)));
                  end if;
               end;

            --  If the component is an access type with an allocator as
            --  default value, the designated type will be frozen by the
            --  corresponding expression in init_proc. In order to place the
            --  freeze node for the designated type before that for the
            --  current record type, freeze it now.

            --  Same process if the component is an array of access types,
            --  initialized with an aggregate. If the designated type is
            --  private, it cannot contain allocators, and it is premature to
            --  freeze the type, so we check for this as well.

            elsif Is_Access_Type (Etype (Comp))
              and then Present (Parent (Comp))
              and then Present (Expression (Parent (Comp)))
              and then Nkind (Expression (Parent (Comp))) = N_Allocator
            then
               declare
                  Alloc : constant Node_Id := Expression (Parent (Comp));

               begin
                  --  If component is pointer to a classwide type, freeze
                  --  the specific type in the expression being allocated.
                  --  The expression may be a subtype indication, in which
                  --  case freeze the subtype mark.

                  if Is_Class_Wide_Type (Designated_Type (Etype (Comp))) then
                     if Is_Entity_Name (Expression (Alloc)) then
                        Freeze_And_Append
                          (Entity (Expression (Alloc)), Loc, Result);
                     elsif
                       Nkind (Expression (Alloc)) = N_Subtype_Indication
                     then
                        Freeze_And_Append
                         (Entity (Subtype_Mark (Expression (Alloc))),
                           Loc, Result);
                     end if;

                  elsif Is_Itype (Designated_Type (Etype (Comp))) then
                     Check_Itype (Designated_Type (Etype (Comp)));

                  else
                     Freeze_And_Append
                       (Designated_Type (Etype (Comp)), Loc, Result);
                  end if;
               end;

            elsif Is_Access_Type (Etype (Comp))
              and then Is_Itype (Designated_Type (Etype (Comp)))
            then
               Check_Itype (Designated_Type (Etype (Comp)));

            elsif Is_Array_Type (Etype (Comp))
              and then Is_Access_Type (Component_Type (Etype (Comp)))
              and then Present (Parent (Comp))
              and then Nkind (Parent (Comp)) = N_Component_Declaration
              and then Present (Expression (Parent (Comp)))
              and then Nkind (Expression (Parent (Comp))) = N_Aggregate
              and then Is_Fully_Defined
                 (Designated_Type (Component_Type (Etype (Comp))))
            then
               Freeze_And_Append
                 (Designated_Type
                   (Component_Type (Etype (Comp))), Loc, Result);
            end if;

            Prev := Comp;
            Next_Entity (Comp);
         end loop;

         --  Check for useless pragma Bit_Order

         if not Placed_Component and then Reverse_Bit_Order (Rec) then
            ADC := Get_Attribute_Definition_Clause (Rec, Attribute_Bit_Order);
            Error_Msg_N ("?Bit_Order specification has no effect", ADC);
            Error_Msg_N ("\?since no component clauses were specified", ADC);
         end if;

         --  Check for useless pragma Pack when all components placed. We only
         --  do this check for record types, not subtypes, since a subtype may
         --  have all its components placed, and it still makes perfectly good
         --  sense to pack other subtypes or the parent type.

         if Ekind (Rec) = E_Record_Type
           and then Is_Packed (Rec)
           and then not Unplaced_Component
         then
            --  Reset packed status. Probably not necessary, but we do it
            --  so that there is no chance of the back end doing something
            --  strange with this redundant indication of packing.

            Set_Is_Packed (Rec, False);

            --  Give warning if redundant constructs warnings on

            if Warn_On_Redundant_Constructs then
               Error_Msg_N
                 ("?pragma Pack has no effect, no unplaced components",
                  Get_Rep_Pragma (Rec, Name_Pack));
            end if;
         end if;

         --  If this is the record corresponding to a remote type, freeze the
         --  remote type here since that is what we are semantically freezing.
         --  This prevents the freeze node for that type in an inner scope.

         --  Also, Check for controlled components and unchecked unions.
         --  Finally, enforce the restriction that access attributes with a
         --  current instance prefix can only apply to limited types.

         if  Ekind (Rec) = E_Record_Type then
            if Present (Corresponding_Remote_Type (Rec)) then
               Freeze_And_Append
                 (Corresponding_Remote_Type (Rec), Loc, Result);
            end if;

            Comp := First_Component (Rec);
            while Present (Comp) loop
               if Has_Controlled_Component (Etype (Comp))
                 or else (Chars (Comp) /= Name_uParent
                           and then Is_Controlled (Etype (Comp)))
                 or else (Is_Protected_Type (Etype (Comp))
                           and then Present
                             (Corresponding_Record_Type (Etype (Comp)))
                           and then Has_Controlled_Component
                             (Corresponding_Record_Type (Etype (Comp))))
               then
                  Set_Has_Controlled_Component (Rec);
                  exit;
               end if;

               if Has_Unchecked_Union (Etype (Comp)) then
                  Set_Has_Unchecked_Union (Rec);
               end if;

               if Has_Per_Object_Constraint (Comp)
                 and then not Is_Limited_Type (Rec)
               then
                  --  Scan component declaration for likely misuses of current
                  --  instance, either in a constraint or a default expression.

                  Check_Current_Instance (Parent (Comp));
               end if;

               Next_Component (Comp);
            end loop;
         end if;

         Set_Component_Alignment_If_Not_Set (Rec);

         --  For first subtypes, check if there are any fixed-point fields with
         --  component clauses, where we must check the size. This is not done
         --  till the freeze point, since for fixed-point types, we do not know
         --  the size until the type is frozen. Similar processing applies to
         --  bit packed arrays.

         if Is_First_Subtype (Rec) then
            Comp := First_Component (Rec);

            while Present (Comp) loop
               if Present (Component_Clause (Comp))
                 and then (Is_Fixed_Point_Type (Etype (Comp))
                             or else
                           Is_Bit_Packed_Array (Etype (Comp)))
               then
                  Check_Size
                    (Component_Name (Component_Clause (Comp)),
                     Etype (Comp),
                     Esize (Comp),
                     Junk);
               end if;

               Next_Component (Comp);
            end loop;
         end if;
      end Freeze_Record_Type;

   --  Start of processing for Freeze_Entity

   begin
      --  We are going to test for various reasons why this entity need not be
      --  frozen here, but in the case of an Itype that's defined within a
      --  record, that test actually applies to the record.

      if Is_Itype (E) and then Is_Record_Type (Scope (E)) then
         Test_E := Scope (E);
      elsif Is_Itype (E) and then Present (Underlying_Type (Scope (E)))
        and then Is_Record_Type (Underlying_Type (Scope (E)))
      then
         Test_E := Underlying_Type (Scope (E));
      end if;

      --  Do not freeze if already frozen since we only need one freeze node

      if Is_Frozen (E) then
         return No_List;

      --  It is improper to freeze an external entity within a generic because
      --  its freeze node will appear in a non-valid context. The entity will
      --  be frozen in the proper scope after the current generic is analyzed.

      elsif Inside_A_Generic and then External_Ref_In_Generic (Test_E) then
         return No_List;

      --  Do not freeze a global entity within an inner scope created during
      --  expansion. A call to subprogram E within some internal procedure
      --  (a stream attribute for example) might require freezing E, but the
      --  freeze node must appear in the same declarative part as E itself.
      --  The two-pass elaboration mechanism in gigi guarantees that E will
      --  be frozen before the inner call is elaborated. We exclude constants
      --  from this test, because deferred constants may be frozen early, and
      --  must be diagnosed (see e.g. 1522-005). If the enclosing subprogram
      --  comes from source, or is a generic instance, then the freeze point
      --  is the one mandated by the language. and we freze the entity.

      elsif In_Open_Scopes (Scope (Test_E))
        and then Scope (Test_E) /= Current_Scope
        and then Ekind (Test_E) /= E_Constant
      then
         declare
            S : Entity_Id := Current_Scope;

         begin
            while Present (S) loop
               if Is_Overloadable (S) then
                  if Comes_From_Source (S)
                    or else Is_Generic_Instance (S)
                  then
                     exit;
                  else
                     return No_List;
                  end if;
               end if;

               S := Scope (S);
            end loop;
         end;

      --  Similarly, an inlined instance body may make reference to global
      --  entities, but these references cannot be the proper freezing point
      --  for them, and the the absence of inlining freezing will take place
      --  in their own scope. Normally instance bodies are analyzed after
      --  the enclosing compilation, and everything has been frozen at the
      --  proper place, but with front-end inlining an instance body is
      --  compiled before the end of the enclosing scope, and as a result
      --  out-of-order freezing must be prevented.

      elsif Front_End_Inlining
        and then  In_Instance_Body
        and then Present (Scope (Test_E))
      then
         declare
            S : Entity_Id := Scope (Test_E);

         begin
            while Present (S) loop
               if Is_Generic_Instance (S) then
                  exit;
               else
                  S := Scope (S);
               end if;
            end loop;

            if No (S) then
               return No_List;
            end if;
         end;
      end if;

      --  Here to freeze the entity

      Result := No_List;
      Set_Is_Frozen (E);

      --  Case of entity being frozen is other than a type

      if not Is_Type (E) then

         --  If entity is exported or imported and does not have an external
         --  name, now is the time to provide the appropriate default name.
         --  Skip this if the entity is stubbed, since we don't need a name
         --  for any stubbed routine.

         if (Is_Imported (E) or else Is_Exported (E))
           and then No (Interface_Name (E))
           and then Convention (E) /= Convention_Stubbed
         then
            Set_Encoded_Interface_Name
              (E, Get_Default_External_Name (E));

         --  Special processing for atomic objects appearing in object decls

         elsif Is_Atomic (E)
           and then Nkind (Parent (E)) = N_Object_Declaration
           and then Present (Expression (Parent (E)))
         then
            declare
               Expr : constant Node_Id := Expression (Parent (E));

            begin
               --  If expression is an aggregate, assign to a temporary to
               --  ensure that the actual assignment is done atomically rather
               --  than component-wise (the assignment to the temp may be done
               --  component-wise, but that is harmless.

               if Nkind (Expr) = N_Aggregate then
                  Expand_Atomic_Aggregate (Expr, Etype (E));

               --  If the expression is a reference to a record or array object
               --  entity, then reset Is_True_Constant to False so that the
               --  compiler will not optimize away the intermediate object,
               --  which we need in this case for the same reason (to ensure
               --  that the actual assignment is atomic, rather than
               --  component-wise).

               elsif Is_Entity_Name (Expr)
                 and then (Is_Record_Type (Etype (Expr))
                             or else
                           Is_Array_Type (Etype (Expr)))
               then
                  Set_Is_True_Constant (Entity (Expr), False);
               end if;
            end;
         end if;

         --  For a subprogram, freeze all parameter types and also the return
         --  type (RM 13.14(14)). However skip this for internal subprograms.
         --  This is also the point where any extra formal parameters are
         --  created since we now know whether the subprogram will use
         --  a foreign convention.

         if Is_Subprogram (E) then
            if not Is_Internal (E) then
               declare
                  F_Type    : Entity_Id;
                  Warn_Node : Node_Id;

                  function Is_Fat_C_Ptr_Type (T : Entity_Id) return Boolean;
                  --  Determines if given type entity is a fat pointer type
                  --  used as an argument type or return type to a subprogram
                  --  with C or C++ convention set.

                  --------------------------
                  -- Is_Fat_C_Access_Type --
                  --------------------------

                  function Is_Fat_C_Ptr_Type (T : Entity_Id) return Boolean is
                  begin
                     return (Convention (E) = Convention_C
                               or else
                             Convention (E) = Convention_CPP)
                       and then Is_Access_Type (T)
                       and then Esize (T) > Ttypes.System_Address_Size;
                  end Is_Fat_C_Ptr_Type;

               begin
                  --  Loop through formals

                  Formal := First_Formal (E);
                  while Present (Formal) loop
                     F_Type := Etype (Formal);
                     Freeze_And_Append (F_Type, Loc, Result);

                     if Is_Private_Type (F_Type)
                       and then Is_Private_Type (Base_Type (F_Type))
                       and then No (Full_View (Base_Type (F_Type)))
                       and then not Is_Generic_Type (F_Type)
                       and then not Is_Derived_Type (F_Type)
                     then
                        --  If the type of a formal is incomplete, subprogram
                        --  is being frozen prematurely. Within an instance
                        --  (but not within a wrapper package) this is an
                        --  an artifact of our need to regard the end of an
                        --  instantiation as a freeze point. Otherwise it is
                        --  a definite error.

                        --  and then not Is_Wrapper_Package (Current_Scope) ???

                        if In_Instance then
                           Set_Is_Frozen (E, False);
                           return No_List;

                        elsif not After_Last_Declaration then
                           Error_Msg_Node_1 := F_Type;
                           Error_Msg
                             ("type& must be fully defined before this point",
                               Loc);
                        end if;
                     end if;

                     --  Check bad use of fat C pointer

                     if Warn_On_Export_Import and then
                       Is_Fat_C_Ptr_Type (F_Type)
                     then
                        Error_Msg_Qual_Level := 1;
                        Error_Msg_N
                           ("?type of & does not correspond to C pointer",
                            Formal);
                        Error_Msg_Qual_Level := 0;
                     end if;

                     --  Check for unconstrained array in exported foreign
                     --  convention case.

                     if Convention (E) in Foreign_Convention
                       and then not Is_Imported (E)
                       and then Is_Array_Type (F_Type)
                       and then not Is_Constrained (F_Type)
                       and then Warn_On_Export_Import
                     then
                        Error_Msg_Qual_Level := 1;

                        --  If this is an inherited operation, place the
                        --  warning on the derived type declaration, rather
                        --  than on the original subprogram.

                        if Nkind (Original_Node (Parent (E))) =
                          N_Full_Type_Declaration
                        then
                           Warn_Node := Parent (E);

                           if Formal = First_Formal (E) then
                              Error_Msg_NE
                                ("?in inherited operation&", Warn_Node, E);
                           end if;
                        else
                           Warn_Node := Formal;
                        end if;

                        Error_Msg_NE
                          ("?type of argument& is unconstrained array",
                           Warn_Node, Formal);
                        Error_Msg_NE
                          ("?foreign caller must pass bounds explicitly",
                           Warn_Node, Formal);
                        Error_Msg_Qual_Level := 0;
                     end if;

                     --  Ada 2005 (AI-326): Check wrong use of tag incomplete
                     --  types with unknown discriminants. For example:

                     --    type T (<>) is tagged;
                     --    procedure P (X : access T); -- ERROR
                     --    procedure P (X : T);        -- ERROR

                     if not From_With_Type (F_Type) then
                        if Is_Access_Type (F_Type) then
                           F_Type := Designated_Type (F_Type);
                        end if;

                        if Ekind (F_Type) = E_Incomplete_Type
                          and then Is_Tagged_Type (F_Type)
                          and then not Is_Class_Wide_Type (F_Type)
                          and then No (Full_View (F_Type))
                          and then Unknown_Discriminants_Present
                                     (Parent (F_Type))
                          and then No (Stored_Constraint (F_Type))
                        then
                           Error_Msg_N
                             ("(Ada 2005): invalid use of unconstrained tagged"
                              & " incomplete type", E);

                        elsif Ekind (F_Type) = E_Subprogram_Type then
                           Freeze_And_Append (F_Type, Loc, Result);
                        end if;
                     end if;

                     Next_Formal (Formal);
                  end loop;

                  --  Check return type

                  if Ekind (E) = E_Function then
                     Freeze_And_Append (Etype (E), Loc, Result);

                     if Warn_On_Export_Import
                       and then Is_Fat_C_Ptr_Type (Etype (E))
                     then
                        Error_Msg_N
                          ("?return type of& does not correspond to C pointer",
                           E);

                     elsif Is_Array_Type (Etype (E))
                       and then not Is_Constrained (Etype (E))
                       and then not Is_Imported (E)
                       and then Convention (E) in Foreign_Convention
                       and then Warn_On_Export_Import
                     then
                        Error_Msg_N
                          ("?foreign convention function& should not " &
                           "return unconstrained array", E);

                     --  Ada 2005 (AI-326): Check wrong use of tagged
                     --  incomplete type
                     --
                     --    type T is tagged;
                     --    function F (X : Boolean) return T; -- ERROR

                     elsif Ekind (Etype (E)) = E_Incomplete_Type
                       and then Is_Tagged_Type (Etype (E))
                       and then No (Full_View (Etype (E)))
                     then
                        Error_Msg_N
                          ("(Ada 2005): invalid use of tagged incomplete type",
                           E);
                     end if;
                  end if;
               end;
            end if;

            --  Must freeze its parent first if it is a derived subprogram

            if Present (Alias (E)) then
               Freeze_And_Append (Alias (E), Loc, Result);
            end if;

            --  If the return type requires a transient scope, and we are on
            --  a target allowing functions to return with a depressed stack
            --  pointer, then we mark the function as requiring this treatment.

            if Ekind (E) = E_Function
              and then Functions_Return_By_DSP_On_Target
              and then Requires_Transient_Scope (Etype (E))
            then
               Set_Function_Returns_With_DSP (E);
            end if;

            if not Is_Internal (E) then
               Freeze_Subprogram (E);
            end if;

         --  Here for other than a subprogram or type

         else
            --  If entity has a type, and it is not a generic unit, then
            --  freeze it first (RM 13.14(10))

            if Present (Etype (E))
              and then Ekind (E) /= E_Generic_Function
            then
               Freeze_And_Append (Etype (E), Loc, Result);
            end if;

            --  Special processing for objects created by object declaration

            if Nkind (Declaration_Node (E)) = N_Object_Declaration then

               --  For object created by object declaration, perform required
               --  categorization (preelaborate and pure) checks. Defer these
               --  checks to freeze time since pragma Import inhibits default
               --  initialization and thus pragma Import affects these checks.

               Validate_Object_Declaration (Declaration_Node (E));

               --  If there is an address clause, check it is valid

               Check_Address_Clause (E);

               --  For imported objects, set Is_Public unless there is also
               --  an address clause, which means that there is no external
               --  symbol needed for the Import (Is_Public may still be set
               --  for other unrelated reasons). Note that we delayed this
               --  processing till freeze time so that we can be sure not
               --  to set the flag if there is an address clause. If there
               --  is such a clause, then the only purpose of the import
               --  pragma is to suppress implicit initialization.

               if Is_Imported (E)
                 and then No (Address_Clause (E))
               then
                  Set_Is_Public (E);
               end if;
            end if;

            --  Check that a constant which has a pragma Volatile[_Components]
            --  or Atomic[_Components] also has a pragma Import (RM C.6(13))

            --  Note: Atomic[_Components] also sets Volatile[_Components]

            if Ekind (E) = E_Constant
              and then (Has_Volatile_Components (E) or else Is_Volatile (E))
              and then not Is_Imported (E)
            then
               --  Make sure we actually have a pragma, and have not merely
               --  inherited the indication from elsewhere (e.g. an address
               --  clause, which is not good enough in RM terms!)

               if Has_Rep_Pragma (E, Name_Atomic)
                    or else
                  Has_Rep_Pragma (E, Name_Atomic_Components)
               then
                  Error_Msg_N
                    ("stand alone atomic constant must be " &
                     "imported ('R'M 'C.6(13))", E);

               elsif Has_Rep_Pragma (E, Name_Volatile)
                       or else
                     Has_Rep_Pragma (E, Name_Volatile_Components)
               then
                  Error_Msg_N
                    ("stand alone volatile constant must be " &
                     "imported ('R'M 'C.6(13))", E);
               end if;
            end if;

            --  Static objects require special handling

            if (Ekind (E) = E_Constant or else Ekind (E) = E_Variable)
              and then Is_Statically_Allocated (E)
            then
               Freeze_Static_Object (E);
            end if;

            --  Remaining step is to layout objects

            if Ekind (E) = E_Variable
                 or else
               Ekind (E) = E_Constant
                 or else
               Ekind (E) = E_Loop_Parameter
                 or else
               Is_Formal (E)
            then
               Layout_Object (E);
            end if;
         end if;

      --  Case of a type or subtype being frozen

      else
         --  The type may be defined in a generic unit. This can occur when
         --  freezing a generic function that returns the type (which is
         --  defined in a parent unit). It is clearly meaningless to freeze
         --  this type. However, if it is a subtype, its size may be determi-
         --  nable and used in subsequent checks, so might as well try to
         --  compute it.

         if Present (Scope (E))
           and then Is_Generic_Unit (Scope (E))
         then
            Check_Compile_Time_Size (E);
            return No_List;
         end if;

         --  Deal with special cases of freezing for subtype

         if E /= Base_Type (E) then

            --  If ancestor subtype present, freeze that first.
            --  Note that this will also get the base type frozen.

            Atype := Ancestor_Subtype (E);

            if Present (Atype) then
               Freeze_And_Append (Atype, Loc, Result);

            --  Otherwise freeze the base type of the entity before
            --  freezing the entity itself, (RM 13.14(15)).

            elsif E /= Base_Type (E) then
               Freeze_And_Append (Base_Type (E), Loc, Result);
            end if;

         --  For a derived type, freeze its parent type first (RM 13.14(15))

         elsif Is_Derived_Type (E) then
            Freeze_And_Append (Etype (E), Loc, Result);
            Freeze_And_Append (First_Subtype (Etype (E)), Loc, Result);
         end if;

         --  For array type, freeze index types and component type first
         --  before freezing the array (RM 13.14(15)).

         if Is_Array_Type (E) then
            declare
               Ctyp : constant Entity_Id := Component_Type (E);
               Pnod : Node_Id;

               Non_Standard_Enum : Boolean := False;
               --  Set true if any of the index types is an enumeration
               --  type with a non-standard representation.

            begin
               Freeze_And_Append (Ctyp, Loc, Result);

               Indx := First_Index (E);
               while Present (Indx) loop
                  Freeze_And_Append (Etype (Indx), Loc, Result);

                  if Is_Enumeration_Type (Etype (Indx))
                    and then Has_Non_Standard_Rep (Etype (Indx))
                  then
                     Non_Standard_Enum := True;
                  end if;

                  Next_Index (Indx);
               end loop;

               --  Processing that is done only for base types

               if Ekind (E) = E_Array_Type then

                  --  Propagate flags for component type

                  if Is_Controlled (Component_Type (E))
                    or else Has_Controlled_Component (Ctyp)
                  then
                     Set_Has_Controlled_Component (E);
                  end if;

                  if Has_Unchecked_Union (Component_Type (E)) then
                     Set_Has_Unchecked_Union (E);
                  end if;

                  --  If packing was requested or if the component size was set
                  --  explicitly, then see if bit packing is required. This
                  --  processing is only done for base types, since all the
                  --  representation aspects involved are type-related. This
                  --  is not just an optimization, if we start processing the
                  --  subtypes, they intefere with the settings on the base
                  --  type (this is because Is_Packed has a slightly different
                  --  meaning before and after freezing).

                  declare
                     Csiz : Uint;
                     Esiz : Uint;

                  begin
                     if (Is_Packed (E) or else Has_Pragma_Pack (E))
                       and then not Has_Atomic_Components (E)
                       and then Known_Static_RM_Size (Ctyp)
                     then
                        Csiz := UI_Max (RM_Size (Ctyp), 1);

                     elsif Known_Component_Size (E) then
                        Csiz := Component_Size (E);

                     elsif not Known_Static_Esize (Ctyp) then
                        Csiz := Uint_0;

                     else
                        Esiz := Esize (Ctyp);

                        --  We can set the component size if it is less than
                        --  16, rounding it up to the next storage unit size.

                        if Esiz <= 8 then
                           Csiz := Uint_8;
                        elsif Esiz <= 16 then
                           Csiz := Uint_16;
                        else
                           Csiz := Uint_0;
                        end if;

                        --  Set component size up to match alignment if
                        --  it would otherwise be less than the alignment.
                        --  This deals with cases of types whose alignment
                        --  exceeds their sizes (padded types).

                        if Csiz /= 0 then
                           declare
                              A : constant Uint := Alignment_In_Bits (Ctyp);

                           begin
                              if Csiz < A then
                                 Csiz := A;
                              end if;
                           end;
                        end if;

                     end if;

                     if 1 <= Csiz and then Csiz <= 64 then

                        --  We set the component size for all cases 1-64

                        Set_Component_Size (Base_Type (E), Csiz);

                        --  Check for base type of 8,16,32 bits, where the
                        --  subtype has a length one less than the base type
                        --  and is unsigned (e.g. Natural subtype of Integer)

                        --  In such cases, if a component size was not set
                        --  explicitly, then generate a warning.

                        if Has_Pragma_Pack (E)
                          and then not Has_Component_Size_Clause (E)
                          and then
                            (Csiz = 7 or else Csiz = 15 or else Csiz = 31)
                          and then Esize (Base_Type (Ctyp)) = Csiz + 1
                        then
                           Error_Msg_Uint_1 := Csiz;
                           Pnod :=
                             Get_Rep_Pragma (First_Subtype (E), Name_Pack);

                           if Present (Pnod) then
                              Error_Msg_N
                                ("pragma Pack causes component size to be ^?",
                                 Pnod);
                              Error_Msg_N
                                ("\use Component_Size to set desired value",
                                 Pnod);
                           end if;
                        end if;

                        --  Actual packing is not needed for 8,16,32,64
                        --  Also not needed for 24 if alignment is 1

                        if        Csiz = 8
                          or else Csiz = 16
                          or else Csiz = 32
                          or else Csiz = 64
                          or else (Csiz = 24 and then Alignment (Ctyp) = 1)
                        then
                           --  Here the array was requested to be packed, but
                           --  the packing request had no effect, so Is_Packed
                           --  is reset.

                           --  Note: semantically this means that we lose
                           --  track of the fact that a derived type inherited
                           --  a pack pragma that was non-effective, but that
                           --  seems fine.

                           --  We regard a Pack pragma as a request to set a
                           --  representation characteristic, and this request
                           --  may be ignored.

                           Set_Is_Packed (Base_Type (E), False);

                        --  In all other cases, packing is indeed needed

                        else
                           Set_Has_Non_Standard_Rep (Base_Type (E));
                           Set_Is_Bit_Packed_Array  (Base_Type (E));
                           Set_Is_Packed            (Base_Type (E));
                        end if;
                     end if;
                  end;

               --  Processing that is done only for subtypes

               else
                  --  Acquire alignment from base type

                  if Unknown_Alignment (E) then
                     Set_Alignment (E, Alignment (Base_Type (E)));
                  end if;
               end if;

               --  For bit-packed arrays, check the size

               if Is_Bit_Packed_Array (E)
                 and then Known_Esize (E)
               then
                  declare
                     Discard : Boolean;
                     SizC    : constant Node_Id := Size_Clause (E);

                  begin
                     --  It is not clear if it is possible to have no size
                     --  clause at this stage, but this is not worth worrying
                     --  about. Post the error on the entity name in the size
                     --  clause if present, else on the type entity itself.

                     if Present (SizC) then
                        Check_Size (Name (SizC), E, Esize (E), Discard);
                     else
                        Check_Size (E, E, Esize (E), Discard);
                     end if;
                  end;
               end if;

               --  Check one common case of a size given where the array
               --  needs to be packed, but was not so the size cannot be
               --  honored. This would of course be caught by the backend,
               --  and indeed we don't catch all cases. The point is that
               --  we can give a better error message in those cases that
               --  we do catch with the circuitry here.

               declare
                  Lo, Hi : Node_Id;
                  Ctyp   : constant Entity_Id := Component_Type (E);

               begin
                  if Present (Size_Clause (E))
                    and then Known_Static_Esize (E)
                    and then not Is_Bit_Packed_Array (E)
                    and then not Has_Pragma_Pack (E)
                    and then Number_Dimensions (E) = 1
                    and then not Has_Component_Size_Clause (E)
                    and then Known_Static_Esize (Ctyp)
                  then
                     Get_Index_Bounds (First_Index (E), Lo, Hi);

                     if Compile_Time_Known_Value (Lo)
                       and then Compile_Time_Known_Value (Hi)
                       and then Known_Static_RM_Size (Ctyp)
                       and then RM_Size (Ctyp) < 64
                     then
                        declare
                           Lov  : constant Uint := Expr_Value (Lo);
                           Hiv  : constant Uint := Expr_Value (Hi);
                           Len  : constant Uint :=
                                    UI_Max (Uint_0, Hiv - Lov + 1);
                           Rsiz : constant Uint := RM_Size (Ctyp);

                        --  What we are looking for here is the situation
                        --  where the Esize given would be exactly right
                        --  if there was a pragma Pack (resulting in the
                        --  component size being the same as the RM_Size).
                        --  Furthermore, the component type size must be
                        --  an odd size (not a multiple of storage unit)

                        begin
                           if Esize (E) = Len * Rsiz
                             and then Rsiz mod System_Storage_Unit /= 0
                           then
                              Error_Msg_NE
                                ("size given for& too small",
                                   Size_Clause (E), E);
                              Error_Msg_N
                                ("\explicit pragma Pack is required",
                                   Size_Clause (E));
                           end if;
                        end;
                     end if;
                  end if;
               end;

               --  If any of the index types was an enumeration type with
               --  a non-standard rep clause, then we indicate that the
               --  array type is always packed (even if it is not bit packed).

               if Non_Standard_Enum then
                  Set_Has_Non_Standard_Rep (Base_Type (E));
                  Set_Is_Packed            (Base_Type (E));
               end if;

               Set_Component_Alignment_If_Not_Set (E);

               --  If the array is packed, we must create the packed array
               --  type to be used to actually implement the type. This is
               --  only needed for real array types (not for string literal
               --  types, since they are present only for the front end).

               if Is_Packed (E)
                 and then Ekind (E) /= E_String_Literal_Subtype
               then
                  Create_Packed_Array_Type (E);
                  Freeze_And_Append (Packed_Array_Type (E), Loc, Result);

                  --  Size information of packed array type is copied to the
                  --  array type, since this is really the representation.

                  Set_Size_Info (E, Packed_Array_Type (E));
                  Set_RM_Size   (E, RM_Size (Packed_Array_Type (E)));
               end if;

               --  For non-packed arrays set the alignment of the array
               --  to the alignment of the component type if it is unknown.
               --  Skip this in the atomic case, since atomic arrays may
               --  need larger alignments.

               if not Is_Packed (E)
                 and then Unknown_Alignment (E)
                 and then Known_Alignment (Ctyp)
                 and then Known_Static_Component_Size (E)
                 and then Known_Static_Esize (Ctyp)
                 and then Esize (Ctyp) = Component_Size (E)
                 and then not Is_Atomic (E)
               then
                  Set_Alignment (E, Alignment (Component_Type (E)));
               end if;
            end;

         --  For a class-wide type, the corresponding specific type is
         --  frozen as well (RM 13.14(15))

         elsif Is_Class_Wide_Type (E) then
            Freeze_And_Append (Root_Type (E), Loc, Result);

            --  If the Class_Wide_Type is an Itype (when type is the anonymous
            --  parent of a derived type) and it is a library-level entity,
            --  generate an itype reference for it. Otherwise, its first
            --  explicit reference may be in an inner scope, which will be
            --  rejected by the back-end.

            if Is_Itype (E)
              and then Is_Compilation_Unit (Scope (E))
            then
               declare
                  Ref : constant Node_Id := Make_Itype_Reference (Loc);

               begin
                  Set_Itype (Ref, E);
                  if No (Result) then
                     Result := New_List (Ref);
                  else
                     Append (Ref, Result);
                  end if;
               end;
            end if;

            --  The equivalent type associated with a class-wide subtype
            --  needs to be frozen to ensure that its layout is done.
            --  Class-wide subtypes are currently only frozen on targets
            --  requiring front-end layout (see New_Class_Wide_Subtype
            --  and Make_CW_Equivalent_Type in exp_util.adb).

            if Ekind (E) = E_Class_Wide_Subtype
              and then Present (Equivalent_Type (E))
            then
               Freeze_And_Append (Equivalent_Type (E), Loc, Result);
            end if;

         --  For a record (sub)type, freeze all the component types (RM
         --  13.14(15). We test for E_Record_(sub)Type here, rather than
         --  using Is_Record_Type, because we don't want to attempt the
         --  freeze for the case of a private type with record extension
         --  (we will do that later when the full type is frozen).

         elsif Ekind (E) = E_Record_Type
           or else  Ekind (E) = E_Record_Subtype
         then
            Freeze_Record_Type (E);

         --  For a concurrent type, freeze corresponding record type. This
         --  does not correpond to any specific rule in the RM, but the
         --  record type is essentially part of the concurrent type.
         --  Freeze as well all local entities. This includes record types
         --  created for entry parameter blocks, and whatever local entities
         --  may appear in the private part.

         elsif Is_Concurrent_Type (E) then
            if Present (Corresponding_Record_Type (E)) then
               Freeze_And_Append
                 (Corresponding_Record_Type (E), Loc, Result);
            end if;

            Comp := First_Entity (E);

            while Present (Comp) loop
               if Is_Type (Comp) then
                  Freeze_And_Append (Comp, Loc, Result);

               elsif (Ekind (Comp)) /= E_Function then
                  if Is_Itype (Etype (Comp))
                    and then Underlying_Type (Scope (Etype (Comp))) = E
                  then
                     Undelay_Type (Etype (Comp));
                  end if;

                  Freeze_And_Append (Etype (Comp), Loc, Result);
               end if;

               Next_Entity (Comp);
            end loop;

         --  Private types are required to point to the same freeze node as
         --  their corresponding full views. The freeze node itself has to
         --  point to the partial view of the entity (because from the partial
         --  view, we can retrieve the full view, but not the reverse).
         --  However, in order to freeze correctly, we need to freeze the full
         --  view. If we are freezing at the end of a scope (or within the
         --  scope of the private type), the partial and full views will have
         --  been swapped, the full view appears first in the entity chain and
         --  the swapping mechanism ensures that the pointers are properly set
         --  (on scope exit).

         --  If we encounter the partial view before the full view (e.g. when
         --  freezing from another scope), we freeze the full view, and then
         --  set the pointers appropriately since we cannot rely on swapping to
         --  fix things up (subtypes in an outer scope might not get swapped).

         elsif Is_Incomplete_Or_Private_Type (E)
           and then not Is_Generic_Type (E)
         then
            --  Case of full view present

            if Present (Full_View (E)) then

               --  If full view has already been frozen, then no further
               --  processing is required

               if Is_Frozen (Full_View (E)) then

                  Set_Has_Delayed_Freeze (E, False);
                  Set_Freeze_Node (E, Empty);
                  Check_Debug_Info_Needed (E);

               --  Otherwise freeze full view and patch the pointers so that
               --  the freeze node will elaborate both views in the back-end.

               else
                  declare
                     Full : constant Entity_Id := Full_View (E);

                  begin
                     if Is_Private_Type (Full)
                       and then Present (Underlying_Full_View (Full))
                     then
                        Freeze_And_Append
                          (Underlying_Full_View (Full), Loc, Result);
                     end if;

                     Freeze_And_Append (Full, Loc, Result);

                     if Has_Delayed_Freeze (E) then
                        F_Node := Freeze_Node (Full);

                        if Present (F_Node) then
                           Set_Freeze_Node (E, F_Node);
                           Set_Entity (F_Node, E);

                        else
                           --  {Incomplete,Private}_Subtypes
                           --  with Full_Views constrained by discriminants

                           Set_Has_Delayed_Freeze (E, False);
                           Set_Freeze_Node (E, Empty);
                        end if;
                     end if;
                  end;

                  Check_Debug_Info_Needed (E);
               end if;

               --  AI-117 requires that the convention of a partial view be the
               --  same as the convention of the full view. Note that this is a
               --  recognized breach of privacy, but it's essential for logical
               --  consistency of representation, and the lack of a rule in
               --  RM95 was an oversight.

               Set_Convention (E, Convention (Full_View (E)));

               Set_Size_Known_At_Compile_Time (E,
                 Size_Known_At_Compile_Time (Full_View (E)));

               --  Size information is copied from the full view to the
               --  incomplete or private view for consistency

               --  We skip this is the full view is not a type. This is very
               --  strange of course, and can only happen as a result of
               --  certain illegalities, such as a premature attempt to derive
               --  from an incomplete type.

               if Is_Type (Full_View (E)) then
                  Set_Size_Info (E, Full_View (E));
                  Set_RM_Size   (E, RM_Size (Full_View (E)));
               end if;

               return Result;

            --  Case of no full view present. If entity is derived or subtype,
            --  it is safe to freeze, correctness depends on the frozen status
            --  of parent. Otherwise it is either premature usage, or a Taft
            --  amendment type, so diagnosis is at the point of use and the
            --  type might be frozen later.

            elsif E /= Base_Type (E)
              or else Is_Derived_Type (E)
            then
               null;

            else
               Set_Is_Frozen (E, False);
               return No_List;
            end if;

         --  For access subprogram, freeze types of all formals, the return
         --  type was already frozen, since it is the Etype of the function.

         elsif Ekind (E) = E_Subprogram_Type then
            Formal := First_Formal (E);
            while Present (Formal) loop
               Freeze_And_Append (Etype (Formal), Loc, Result);
               Next_Formal (Formal);
            end loop;

            --  If the return type requires a transient scope, and we are on
            --  a target allowing functions to return with a depressed stack
            --  pointer, then we mark the function as requiring this treatment.

            if Functions_Return_By_DSP_On_Target
              and then Requires_Transient_Scope (Etype (E))
            then
               Set_Function_Returns_With_DSP (E);
            end if;

            Freeze_Subprogram (E);

            --  AI-326: Check wrong use of tag incomplete type
            --
            --    type T is tagged;
            --    type Acc is access function (X : T) return T; -- ERROR

            if Ekind (Etype (E)) = E_Incomplete_Type
              and then Is_Tagged_Type (Etype (E))
              and then No (Full_View (Etype (E)))
            then
               Error_Msg_N
                 ("(Ada 2005): invalid use of tagged incomplete type", E);
            end if;

         --  For access to a protected subprogram, freeze the equivalent type
         --  (however this is not set if we are not generating code or if this
         --  is an anonymous type used just for resolution).

         elsif Ekind (E) = E_Access_Protected_Subprogram_Type then

            --  AI-326: Check wrong use of tagged incomplete types

            --    type T is tagged;
            --    type As3D is access protected
            --      function (X : Float) return T; -- ERROR

            declare
               Etyp : Entity_Id;

            begin
               Etyp := Etype (Directly_Designated_Type (E));

               if Is_Class_Wide_Type (Etyp) then
                  Etyp := Etype (Etyp);
               end if;

               if Ekind (Etyp) = E_Incomplete_Type
                 and then Is_Tagged_Type (Etyp)
                 and then No (Full_View (Etyp))
               then
                  Error_Msg_N
                    ("(Ada 2005): invalid use of tagged incomplete type", E);
               end if;
            end;

            if Present (Equivalent_Type (E)) then
               Freeze_And_Append (Equivalent_Type (E), Loc, Result);
            end if;
         end if;

         --  Generic types are never seen by the back-end, and are also not
         --  processed by the expander (since the expander is turned off for
         --  generic processing), so we never need freeze nodes for them.

         if Is_Generic_Type (E) then
            return Result;
         end if;

         --  Some special processing for non-generic types to complete
         --  representation details not known till the freeze point.

         if Is_Fixed_Point_Type (E) then
            Freeze_Fixed_Point_Type (E);

            --  Some error checks required for ordinary fixed-point type. Defer
            --  these till the freeze-point since we need the small and range
            --  values. We only do these checks for base types

            if Is_Ordinary_Fixed_Point_Type (E)
              and then E = Base_Type (E)
            then
               if Small_Value (E) < Ureal_2_M_80 then
                  Error_Msg_Name_1 := Name_Small;
                  Error_Msg_N
                    ("`&''%` is too small, minimum is 2.0'*'*(-80)", E);

               elsif Small_Value (E) > Ureal_2_80 then
                  Error_Msg_Name_1 := Name_Small;
                  Error_Msg_N
                    ("`&''%` is too large, maximum is 2.0'*'*80", E);
               end if;

               if Expr_Value_R (Type_Low_Bound (E)) < Ureal_M_10_36 then
                  Error_Msg_Name_1 := Name_First;
                  Error_Msg_N
                    ("`&''%` is too small, minimum is -10.0'*'*36", E);
               end if;

               if Expr_Value_R (Type_High_Bound (E)) > Ureal_10_36 then
                  Error_Msg_Name_1 := Name_Last;
                  Error_Msg_N
                    ("`&''%` is too large, maximum is 10.0'*'*36", E);
               end if;
            end if;

         elsif Is_Enumeration_Type (E) then
            Freeze_Enumeration_Type (E);

         elsif Is_Integer_Type (E) then
            Adjust_Esize_For_Alignment (E);

         elsif Is_Access_Type (E) then

            --  Check restriction for standard storage pool

            if No (Associated_Storage_Pool (E)) then
               Check_Restriction (No_Standard_Storage_Pools, E);
            end if;

            --  Deal with error message for pure access type. This is not an
            --  error in Ada 2005 if there is no pool (see AI-366).

            if Is_Pure_Unit_Access_Type (E)
              and then (Ada_Version < Ada_05
                        or else not No_Pool_Assigned (E))
            then
               Error_Msg_N ("named access type not allowed in pure unit", E);
            end if;
         end if;

         --  Case of composite types

         if Is_Composite_Type (E) then

            --  AI-117 requires that all new primitives of a tagged type must
            --  inherit the convention of the full view of the type. Inherited
            --  and overriding operations are defined to inherit the convention
            --  of their parent or overridden subprogram (also specified in
            --  AI-117), which will have occurred earlier (in Derive_Subprogram
            --  and New_Overloaded_Entity). Here we set the convention of
            --  primitives that are still convention Ada, which will ensure
            --  that any new primitives inherit the type's convention.
            --  Class-wide types can have a foreign convention inherited from
            --  their specific type, but are excluded from this since they
            --  don't have any associated primitives.

            if Is_Tagged_Type (E)
              and then not Is_Class_Wide_Type (E)
              and then Convention (E) /= Convention_Ada
            then
               declare
                  Prim_List : constant Elist_Id := Primitive_Operations (E);
                  Prim      : Elmt_Id;
               begin
                  Prim := First_Elmt (Prim_List);
                  while Present (Prim) loop
                     if Convention (Node (Prim)) = Convention_Ada then
                        Set_Convention (Node (Prim), Convention (E));
                     end if;

                     Next_Elmt (Prim);
                  end loop;
               end;
            end if;
         end if;

         --  Generate primitive operation references for a tagged type

         if Is_Tagged_Type (E)
           and then not Is_Class_Wide_Type (E)
         then
            declare
               Prim_List : Elist_Id;
               Prim      : Elmt_Id;
               Ent       : Entity_Id;
               Aux_E     : Entity_Id;

            begin
               --  Handle subtypes

               if Ekind (E) = E_Protected_Subtype
                 or else Ekind (E) = E_Task_Subtype
               then
                  Aux_E := Etype (E);
               else
                  Aux_E := E;
               end if;

               --  Ada 2005 (AI-345): In case of concurrent type generate
               --  reference to the wrapper that allow us to dispatch calls
               --  through their implemented abstract interface types.

               --  The check for Present here is to protect against previously
               --  reported critical errors.

               if Is_Concurrent_Type (Aux_E)
                 and then Present (Corresponding_Record_Type (Aux_E))
               then
                  pragma Assert (not Is_Empty_Elmt_List
                                       (Abstract_Interfaces
                                        (Corresponding_Record_Type (Aux_E))));

                  Prim_List := Primitive_Operations
                                (Corresponding_Record_Type (Aux_E));
               else
                  Prim_List := Primitive_Operations (Aux_E);
               end if;

               --  Loop to generate references for primitive operations

               if Present (Prim_List) then
                  Prim := First_Elmt (Prim_List);
                  while Present (Prim) loop

                     --  If the operation is derived, get the original for
                     --  cross-reference purposes (it is the original for
                     --  which we want the xref, and for which the comes
                     --  from source test needs to be performed).

                     Ent := Node (Prim);
                     while Present (Alias (Ent)) loop
                        Ent := Alias (Ent);
                     end loop;

                     Generate_Reference (E, Ent, 'p', Set_Ref => False);
                     Next_Elmt (Prim);
                  end loop;
               end if;
            end;
         end if;

         --  Now that all types from which E may depend are frozen, see if the
         --  size is known at compile time, if it must be unsigned, or if
         --  strict alignent is required

         Check_Compile_Time_Size (E);
         Check_Unsigned_Type (E);

         if Base_Type (E) = E then
            Check_Strict_Alignment (E);
         end if;

         --  Do not allow a size clause for a type which does not have a size
         --  that is known at compile time

         if Has_Size_Clause (E)
           and then not Size_Known_At_Compile_Time (E)
         then
            --  Supress this message if errors posted on E, even if we are
            --  in all errors mode, since this is often a junk message

            if not Error_Posted (E) then
               Error_Msg_N
                 ("size clause not allowed for variable length type",
                  Size_Clause (E));
            end if;
         end if;

         --  Remaining process is to set/verify the representation information,
         --  in particular the size and alignment values. This processing is
         --  not required for generic types, since generic types do not play
         --  any part in code generation, and so the size and alignment values
         --  for such types are irrelevant.

         if Is_Generic_Type (E) then
            return Result;

         --  Otherwise we call the layout procedure

         else
            Layout_Type (E);
         end if;

         --  End of freeze processing for type entities
      end if;

      --  Here is where we logically freeze the current entity. If it has a
      --  freeze node, then this is the point at which the freeze node is
      --  linked into the result list.

      if Has_Delayed_Freeze (E) then

         --  If a freeze node is already allocated, use it, otherwise allocate
         --  a new one. The preallocation happens in the case of anonymous base
         --  types, where we preallocate so that we can set First_Subtype_Link.
         --  Note that we reset the Sloc to the current freeze location.

         if Present (Freeze_Node (E)) then
            F_Node := Freeze_Node (E);
            Set_Sloc (F_Node, Loc);

         else
            F_Node := New_Node (N_Freeze_Entity, Loc);
            Set_Freeze_Node (E, F_Node);
            Set_Access_Types_To_Process (F_Node, No_Elist);
            Set_TSS_Elist (F_Node, No_Elist);
            Set_Actions (F_Node, No_List);
         end if;

         Set_Entity (F_Node, E);

         if Result = No_List then
            Result := New_List (F_Node);
         else
            Append (F_Node, Result);
         end if;

         --  A final pass over record types with discriminants. If the type
         --  has an incomplete declaration, there may be constrained access
         --  subtypes declared elsewhere, which do not depend on the discrimi-
         --  nants of the type, and which are used as component types (i.e.
         --  the full view is a recursive type). The designated types of these
         --  subtypes can only be elaborated after the type itself, and they
         --  need an itype reference.

         if Ekind (E) = E_Record_Type
           and then Has_Discriminants (E)
         then
            declare
               Comp : Entity_Id;
               IR   : Node_Id;
               Typ  : Entity_Id;

            begin
               Comp := First_Component (E);

               while Present (Comp) loop
                  Typ  := Etype (Comp);

                  if Ekind (Comp) = E_Component
                    and then Is_Access_Type (Typ)
                    and then Scope (Typ) /= E
                    and then Base_Type (Designated_Type (Typ)) = E
                    and then Is_Itype (Designated_Type (Typ))
                  then
                     IR := Make_Itype_Reference (Sloc (Comp));
                     Set_Itype (IR, Designated_Type (Typ));
                     Append (IR, Result);
                  end if;

                  Next_Component (Comp);
               end loop;
            end;
         end if;
      end if;

      --  When a type is frozen, the first subtype of the type is frozen as
      --  well (RM 13.14(15)). This has to be done after freezing the type,
      --  since obviously the first subtype depends on its own base type.

      if Is_Type (E) then
         Freeze_And_Append (First_Subtype (E), Loc, Result);

         --  If we just froze a tagged non-class wide record, then freeze the
         --  corresponding class-wide type. This must be done after the tagged
         --  type itself is frozen, because the class-wide type refers to the
         --  tagged type which generates the class.

         if Is_Tagged_Type (E)
           and then not Is_Class_Wide_Type (E)
           and then Present (Class_Wide_Type (E))
         then
            Freeze_And_Append (Class_Wide_Type (E), Loc, Result);
         end if;
      end if;

      Check_Debug_Info_Needed (E);

      --  Special handling for subprograms

      if Is_Subprogram (E) then

         --  If subprogram has address clause then reset Is_Public flag, since
         --  we do not want the backend to generate external references.

         if Present (Address_Clause (E))
           and then not Is_Library_Level_Entity (E)
         then
            Set_Is_Public (E, False);

         --  If no address clause and not intrinsic, then for imported
         --  subprogram in main unit, generate descriptor if we are in
         --  Propagate_Exceptions mode.

         elsif Propagate_Exceptions
           and then Is_Imported (E)
           and then not Is_Intrinsic_Subprogram (E)
           and then Convention (E) /= Convention_Stubbed
         then
            if Result = No_List then
               Result := Empty_List;
            end if;
         end if;
      end if;

      return Result;
   end Freeze_Entity;

   -----------------------------
   -- Freeze_Enumeration_Type --
   -----------------------------

   procedure Freeze_Enumeration_Type (Typ : Entity_Id) is
   begin
      if Has_Foreign_Convention (Typ)
        and then not Has_Size_Clause (Typ)
        and then Esize (Typ) < Standard_Integer_Size
      then
         Init_Esize (Typ, Standard_Integer_Size);
      else
         Adjust_Esize_For_Alignment (Typ);
      end if;
   end Freeze_Enumeration_Type;

   -----------------------
   -- Freeze_Expression --
   -----------------------

   procedure Freeze_Expression (N : Node_Id) is
      In_Def_Exp : constant Boolean := In_Default_Expression;
      Typ        : Entity_Id;
      Nam        : Entity_Id;
      Desig_Typ  : Entity_Id;
      P          : Node_Id;
      Parent_P   : Node_Id;

      Freeze_Outside : Boolean := False;
      --  This flag is set true if the entity must be frozen outside the
      --  current subprogram. This happens in the case of expander generated
      --  subprograms (_Init_Proc, _Input, _Output, _Read, _Write) which do
      --  not freeze all entities like other bodies, but which nevertheless
      --  may reference entities that have to be frozen before the body and
      --  obviously cannot be frozen inside the body.

      function In_Exp_Body (N : Node_Id) return Boolean;
      --  Given an N_Handled_Sequence_Of_Statements node N, determines whether
      --  it is the handled statement sequence of an expander-generated
      --  subprogram (init proc, or stream subprogram). If so, it returns
      --  True, otherwise False.

      -----------------
      -- In_Exp_Body --
      -----------------

      function In_Exp_Body (N : Node_Id) return Boolean is
         P : Node_Id;

      begin
         if Nkind (N) = N_Subprogram_Body then
            P := N;
         else
            P := Parent (N);
         end if;

         if Nkind (P) /= N_Subprogram_Body then
            return False;

         else
            P := Defining_Unit_Name (Specification (P));

            if Nkind (P) = N_Defining_Identifier
              and then (Is_Init_Proc (P)              or else
                        Is_TSS (P, TSS_Stream_Input)  or else
                        Is_TSS (P, TSS_Stream_Output) or else
                        Is_TSS (P, TSS_Stream_Read)   or else
                        Is_TSS (P, TSS_Stream_Write))
            then
               return True;
            else
               return False;
            end if;
         end if;
      end In_Exp_Body;

   --  Start of processing for Freeze_Expression

   begin
      --  Immediate return if freezing is inhibited. This flag is set by the
      --  analyzer to stop freezing on generated expressions that would cause
      --  freezing if they were in the source program, but which are not
      --  supposed to freeze, since they are created.

      if Must_Not_Freeze (N) then
         return;
      end if;

      --  If expression is non-static, then it does not freeze in a default
      --  expression, see section "Handling of Default Expressions" in the
      --  spec of package Sem for further details. Note that we have to
      --  make sure that we actually have a real expression (if we have
      --  a subtype indication, we can't test Is_Static_Expression!)

      if In_Def_Exp
        and then Nkind (N) in N_Subexpr
        and then not Is_Static_Expression (N)
      then
         return;
      end if;

      --  Freeze type of expression if not frozen already

      Typ := Empty;

      if Nkind (N) in N_Has_Etype then
         if not Is_Frozen (Etype (N)) then
            Typ := Etype (N);

         --  Base type may be an derived numeric type that is frozen at
         --  the point of declaration, but first_subtype is still unfrozen.

         elsif not Is_Frozen (First_Subtype (Etype (N))) then
            Typ := First_Subtype (Etype (N));
         end if;
      end if;

      --  For entity name, freeze entity if not frozen already. A special
      --  exception occurs for an identifier that did not come from source.
      --  We don't let such identifiers freeze a non-internal entity, i.e.
      --  an entity that did come from source, since such an identifier was
      --  generated by the expander, and cannot have any semantic effect on
      --  the freezing semantics. For example, this stops the parameter of
      --  an initialization procedure from freezing the variable.

      if Is_Entity_Name (N)
        and then not Is_Frozen (Entity (N))
        and then (Nkind (N) /= N_Identifier
                   or else Comes_From_Source (N)
                   or else not Comes_From_Source (Entity (N)))
      then
         Nam := Entity (N);
      else
         Nam := Empty;
      end if;

      --  For an allocator freeze designated type if not frozen already

      --  For an aggregate whose component type is an access type, freeze the
      --  designated type now, so that its freeze does not appear within the
      --  loop that might be created in the expansion of the aggregate. If the
      --  designated type is a private type without full view, the expression
      --  cannot contain an allocator, so the type is not frozen.

      Desig_Typ := Empty;

      case Nkind (N) is
         when N_Allocator =>
            Desig_Typ := Designated_Type (Etype (N));

         when N_Aggregate =>
            if Is_Array_Type (Etype (N))
              and then Is_Access_Type (Component_Type (Etype (N)))
            then
               Desig_Typ := Designated_Type (Component_Type (Etype (N)));
            end if;

         when N_Selected_Component |
            N_Indexed_Component    |
            N_Slice                =>

            if Is_Access_Type (Etype (Prefix (N))) then
               Desig_Typ := Designated_Type (Etype (Prefix (N)));
            end if;

         when others =>
            null;
      end case;

      if Desig_Typ /= Empty
        and then (Is_Frozen (Desig_Typ)
                   or else (not Is_Fully_Defined (Desig_Typ)))
      then
         Desig_Typ := Empty;
      end if;

      --  All done if nothing needs freezing

      if No (Typ)
        and then No (Nam)
        and then No (Desig_Typ)
      then
         return;
      end if;

      --  Loop for looking at the right place to insert the freeze nodes
      --  exiting from the loop when it is appropriate to insert the freeze
      --  node before the current node P.

      --  Also checks some special exceptions to the freezing rules. These
      --  cases result in a direct return, bypassing the freeze action.

      P := N;
      loop
         Parent_P := Parent (P);

         --  If we don't have a parent, then we are not in a well-formed tree.
         --  This is an unusual case, but there are some legitimate situations
         --  in which this occurs, notably when the expressions in the range of
         --  a type declaration are resolved. We simply ignore the freeze
         --  request in this case. Is this right ???

         if No (Parent_P) then
            return;
         end if;

         --  See if we have got to an appropriate point in the tree

         case Nkind (Parent_P) is

            --  A special test for the exception of (RM 13.14(8)) for the case
            --  of per-object expressions (RM 3.8(18)) occurring in component
            --  definition or a discrete subtype definition. Note that we test
            --  for a component declaration which includes both cases we are
            --  interested in, and furthermore the tree does not have explicit
            --  nodes for either of these two constructs.

            when N_Component_Declaration =>

               --  The case we want to test for here is an identifier that is
               --  a per-object expression, this is either a discriminant that
               --  appears in a context other than the component declaration
               --  or it is a reference to the type of the enclosing construct.

               --  For either of these cases, we skip the freezing

               if not In_Default_Expression
                 and then Nkind (N) = N_Identifier
                 and then (Present (Entity (N)))
               then
                  --  We recognize the discriminant case by just looking for
                  --  a reference to a discriminant. It can only be one for
                  --  the enclosing construct. Skip freezing in this case.

                  if Ekind (Entity (N)) = E_Discriminant then
                     return;

                  --  For the case of a reference to the enclosing record,
                  --  (or task or protected type), we look for a type that
                  --  matches the current scope.

                  elsif Entity (N) = Current_Scope then
                     return;
                  end if;
               end if;

            --  If we have an enumeration literal that appears as the choice in
            --  the aggregate of an enumeration representation clause, then
            --  freezing does not occur (RM 13.14(10)).

            when N_Enumeration_Representation_Clause =>

               --  The case we are looking for is an enumeration literal

               if (Nkind (N) = N_Identifier or Nkind (N) = N_Character_Literal)
                 and then Is_Enumeration_Type (Etype (N))
               then
                  --  If enumeration literal appears directly as the choice,
                  --  do not freeze (this is the normal non-overloade case)

                  if Nkind (Parent (N)) = N_Component_Association
                    and then First (Choices (Parent (N))) = N
                  then
                     return;

                  --  If enumeration literal appears as the name of function
                  --  which is the choice, then also do not freeze. This
                  --  happens in the overloaded literal case, where the
                  --  enumeration literal is temporarily changed to a function
                  --  call for overloading analysis purposes.

                  elsif Nkind (Parent (N)) = N_Function_Call
                     and then
                       Nkind (Parent (Parent (N))) = N_Component_Association
                     and then
                       First (Choices (Parent (Parent (N)))) = Parent (N)
                  then
                     return;
                  end if;
               end if;

            --  Normally if the parent is a handled sequence of statements,
            --  then the current node must be a statement, and that is an
            --  appropriate place to insert a freeze node.

            when N_Handled_Sequence_Of_Statements =>

               --  An exception occurs when the sequence of statements is for
               --  an expander generated body that did not do the usual freeze
               --  all operation. In this case we usually want to freeze
               --  outside this body, not inside it, and we skip past the
               --  subprogram body that we are inside.

               if In_Exp_Body (Parent_P) then

                  --  However, we *do* want to freeze at this point if we have
                  --  an entity to freeze, and that entity is declared *inside*
                  --  the body of the expander generated procedure. This case
                  --  is recognized by the scope of the type, which is either
                  --  the spec for some enclosing body, or (in the case of
                  --  init_procs, for which there are no separate specs) the
                  --  current scope.

                  declare
                     Subp : constant Node_Id := Parent (Parent_P);
                     Cspc : Entity_Id;

                  begin
                     if Nkind (Subp) = N_Subprogram_Body then
                        Cspc := Corresponding_Spec (Subp);

                        if (Present (Typ) and then Scope (Typ) = Cspc)
                             or else
                           (Present (Nam) and then Scope (Nam) = Cspc)
                        then
                           exit;

                        elsif Present (Typ)
                          and then Scope (Typ) = Current_Scope
                          and then Current_Scope = Defining_Entity (Subp)
                        then
                           exit;
                        end if;
                     end if;
                  end;

                  --  If not that exception to the exception, then this is
                  --  where we delay the freeze till outside the body.

                  Parent_P := Parent (Parent_P);
                  Freeze_Outside := True;

               --  Here if normal case where we are in handled statement
               --  sequence and want to do the insertion right there.

               else
                  exit;
               end if;

            --  If parent is a body or a spec or a block, then the current node
            --  is a statement or declaration and we can insert the freeze node
            --  before it.

            when N_Package_Specification |
                 N_Package_Body          |
                 N_Subprogram_Body       |
                 N_Task_Body             |
                 N_Protected_Body        |
                 N_Entry_Body            |
                 N_Block_Statement       => exit;

            --  The expander is allowed to define types in any statements list,
            --  so any of the following parent nodes also mark a freezing point
            --  if the actual node is in a list of statements or declarations.

            when N_Exception_Handler          |
                 N_If_Statement               |
                 N_Elsif_Part                 |
                 N_Case_Statement_Alternative |
                 N_Compilation_Unit_Aux       |
                 N_Selective_Accept           |
                 N_Accept_Alternative         |
                 N_Delay_Alternative          |
                 N_Conditional_Entry_Call     |
                 N_Entry_Call_Alternative     |
                 N_Triggering_Alternative     |
                 N_Abortable_Part             |
                 N_Freeze_Entity              =>

               exit when Is_List_Member (P);

            --  Note: The N_Loop_Statement is a special case. A type that
            --  appears in the source can never be frozen in a loop (this
            --  occurs only because of a loop expanded by the expander), so we
            --  keep on going. Otherwise we terminate the search. Same is true
            --  of any entity which comes from source. (if they have predefined
            --  type, that type does not appear to come from source, but the
            --  entity should not be frozen here).

            when N_Loop_Statement =>
               exit when not Comes_From_Source (Etype (N))
                 and then (No (Nam) or else not Comes_From_Source (Nam));

            --  For all other cases, keep looking at parents

            when others =>
               null;
         end case;

         --  We fall through the case if we did not yet find the proper
         --  place in the free for inserting the freeze node, so climb!

         P := Parent_P;
      end loop;

      --  If the expression appears in a record or an initialization procedure,
      --  the freeze nodes are collected and attached to the current scope, to
      --  be inserted and analyzed on exit from the scope, to insure that
      --  generated entities appear in the correct scope. If the expression is
      --  a default for a discriminant specification, the scope is still void.
      --  The expression can also appear in the discriminant part of a private
      --  or concurrent type.

      --  If the expression appears in a constrained subcomponent of an
      --  enclosing record declaration, the freeze nodes must be attached to
      --  the outer record type so they can eventually be placed in the
      --  enclosing declaration list.

      --  The other case requiring this special handling is if we are in a
      --  default expression, since in that case we are about to freeze a
      --  static type, and the freeze scope needs to be the outer scope, not
      --  the scope of the subprogram with the default parameter.

      --  For default expressions in generic units, the Move_Freeze_Nodes
      --  mechanism (see sem_ch12.adb) takes care of placing them at the proper
      --  place, after the generic unit.

      if (In_Def_Exp and not Inside_A_Generic)
        or else Freeze_Outside
        or else (Is_Type (Current_Scope)
                  and then (not Is_Concurrent_Type (Current_Scope)
                             or else not Has_Completion (Current_Scope)))
        or else Ekind (Current_Scope) = E_Void
      then
         declare
            Loc          : constant Source_Ptr := Sloc (Current_Scope);
            Freeze_Nodes : List_Id := No_List;
            Pos          : Int := Scope_Stack.Last;

         begin
            if Present (Desig_Typ) then
               Freeze_And_Append (Desig_Typ, Loc, Freeze_Nodes);
            end if;

            if Present (Typ) then
               Freeze_And_Append (Typ, Loc, Freeze_Nodes);
            end if;

            if Present (Nam) then
               Freeze_And_Append (Nam, Loc, Freeze_Nodes);
            end if;

            --  The current scope may be that of a constrained component of
            --  an enclosing record declaration, which is above the current
            --  scope in the scope stack.

            if Is_Record_Type (Scope (Current_Scope)) then
               Pos := Pos - 1;
            end if;

            if Is_Non_Empty_List (Freeze_Nodes) then
               if No (Scope_Stack.Table (Pos).Pending_Freeze_Actions) then
                  Scope_Stack.Table (Pos).Pending_Freeze_Actions :=
                      Freeze_Nodes;
               else
                  Append_List (Freeze_Nodes, Scope_Stack.Table
                                   (Pos).Pending_Freeze_Actions);
               end if;
            end if;
         end;

         return;
      end if;

      --  Now we have the right place to do the freezing. First, a special
      --  adjustment, if we are in default expression analysis mode, these
      --  freeze actions must not be thrown away (normally all inserted actions
      --  are thrown away in this mode. However, the freeze actions are from
      --  static expressions and one of the important reasons we are doing this
      --  special analysis is to get these freeze actions. Therefore we turn
      --  off the In_Default_Expression mode to propagate these freeze actions.
      --  This also means they get properly analyzed and expanded.

      In_Default_Expression := False;

      --  Freeze the designated type of an allocator (RM 13.14(13))

      if Present (Desig_Typ) then
         Freeze_Before (P, Desig_Typ);
      end if;

      --  Freeze type of expression (RM 13.14(10)). Note that we took care of
      --  the enumeration representation clause exception in the loop above.

      if Present (Typ) then
         Freeze_Before (P, Typ);
      end if;

      --  Freeze name if one is present (RM 13.14(11))

      if Present (Nam) then
         Freeze_Before (P, Nam);
      end if;

      In_Default_Expression := In_Def_Exp;
   end Freeze_Expression;

   -----------------------------
   -- Freeze_Fixed_Point_Type --
   -----------------------------

   --  Certain fixed-point types and subtypes, including implicit base types
   --  and declared first subtypes, have not yet set up a range. This is
   --  because the range cannot be set until the Small and Size values are
   --  known, and these are not known till the type is frozen.

   --  To signal this case, Scalar_Range contains an unanalyzed syntactic range
   --  whose bounds are unanalyzed real literals. This routine will recognize
   --  this case, and transform this range node into a properly typed range
   --  with properly analyzed and resolved values.

   procedure Freeze_Fixed_Point_Type (Typ : Entity_Id) is
      Rng   : constant Node_Id    := Scalar_Range (Typ);
      Lo    : constant Node_Id    := Low_Bound (Rng);
      Hi    : constant Node_Id    := High_Bound (Rng);
      Btyp  : constant Entity_Id  := Base_Type (Typ);
      Brng  : constant Node_Id    := Scalar_Range (Btyp);
      BLo   : constant Node_Id    := Low_Bound (Brng);
      BHi   : constant Node_Id    := High_Bound (Brng);
      Small : constant Ureal      := Small_Value (Typ);
      Loval : Ureal;
      Hival : Ureal;
      Atype : Entity_Id;

      Actual_Size : Nat;

      function Fsize (Lov, Hiv : Ureal) return Nat;
      --  Returns size of type with given bounds. Also leaves these
      --  bounds set as the current bounds of the Typ.

      -----------
      -- Fsize --
      -----------

      function Fsize (Lov, Hiv : Ureal) return Nat is
      begin
         Set_Realval (Lo, Lov);
         Set_Realval (Hi, Hiv);
         return Minimum_Size (Typ);
      end Fsize;

   --  Start of processing for Freeze_Fixed_Point_Type

   begin
      --  If Esize of a subtype has not previously been set, set it now

      if Unknown_Esize (Typ) then
         Atype := Ancestor_Subtype (Typ);

         if Present (Atype) then
            Set_Esize (Typ, Esize (Atype));
         else
            Set_Esize (Typ, Esize (Base_Type (Typ)));
         end if;
      end if;

      --  Immediate return if the range is already analyzed. This means that
      --  the range is already set, and does not need to be computed by this
      --  routine.

      if Analyzed (Rng) then
         return;
      end if;

      --  Immediate return if either of the bounds raises Constraint_Error

      if Raises_Constraint_Error (Lo)
        or else Raises_Constraint_Error (Hi)
      then
         return;
      end if;

      Loval := Realval (Lo);
      Hival := Realval (Hi);

      --  Ordinary fixed-point case

      if Is_Ordinary_Fixed_Point_Type (Typ) then

         --  For the ordinary fixed-point case, we are allowed to fudge the
         --  end-points up or down by small. Generally we prefer to fudge up,
         --  i.e. widen the bounds for non-model numbers so that the end points
         --  are included. However there are cases in which this cannot be
         --  done, and indeed cases in which we may need to narrow the bounds.
         --  The following circuit makes the decision.

         --  Note: our terminology here is that Incl_EP means that the bounds
         --  are widened by Small if necessary to include the end points, and
         --  Excl_EP means that the bounds are narrowed by Small to exclude the
         --  end-points if this reduces the size.

         --  Note that in the Incl case, all we care about is including the
         --  end-points. In the Excl case, we want to narrow the bounds as
         --  much as permitted by the RM, to give the smallest possible size.

         Fudge : declare
            Loval_Incl_EP : Ureal;
            Hival_Incl_EP : Ureal;

            Loval_Excl_EP : Ureal;
            Hival_Excl_EP : Ureal;

            Size_Incl_EP  : Nat;
            Size_Excl_EP  : Nat;

            Model_Num     : Ureal;
            First_Subt    : Entity_Id;
            Actual_Lo     : Ureal;
            Actual_Hi     : Ureal;

         begin
            --  First step. Base types are required to be symmetrical. Right
            --  now, the base type range is a copy of the first subtype range.
            --  This will be corrected before we are done, but right away we
            --  need to deal with the case where both bounds are non-negative.
            --  In this case, we set the low bound to the negative of the high
            --  bound, to make sure that the size is computed to include the
            --  required sign. Note that we do not need to worry about the
            --  case of both bounds negative, because the sign will be dealt
            --  with anyway. Furthermore we can't just go making such a bound
            --  symmetrical, since in a twos-complement system, there is an
            --  extra negative value which could not be accomodated on the
            --  positive side.

            if Typ = Btyp
              and then not UR_Is_Negative (Loval)
              and then Hival > Loval
            then
               Loval := -Hival;
               Set_Realval (Lo, Loval);
            end if;

            --  Compute the fudged bounds. If the number is a model number,
            --  then we do nothing to include it, but we are allowed to backoff
            --  to the next adjacent model number when we exclude it. If it is
            --  not a model number then we straddle the two values with the
            --  model numbers on either side.

            Model_Num := UR_Trunc (Loval / Small) * Small;

            if Loval = Model_Num then
               Loval_Incl_EP := Model_Num;
            else
               Loval_Incl_EP := Model_Num - Small;
            end if;

            --  The low value excluding the end point is Small greater, but
            --  we do not do this exclusion if the low value is positive,
            --  since it can't help the size and could actually hurt by
            --  crossing the high bound.

            if UR_Is_Negative (Loval_Incl_EP) then
               Loval_Excl_EP := Loval_Incl_EP + Small;
            else
               Loval_Excl_EP := Loval_Incl_EP;
            end if;

            --  Similar processing for upper bound and high value

            Model_Num := UR_Trunc (Hival / Small) * Small;

            if Hival = Model_Num then
               Hival_Incl_EP := Model_Num;
            else
               Hival_Incl_EP := Model_Num + Small;
            end if;

            if UR_Is_Positive (Hival_Incl_EP) then
               Hival_Excl_EP := Hival_Incl_EP - Small;
            else
               Hival_Excl_EP := Hival_Incl_EP;
            end if;

            --  One further adjustment is needed. In the case of subtypes, we
            --  cannot go outside the range of the base type, or we get
            --  peculiarities, and the base type range is already set. This
            --  only applies to the Incl values, since clearly the Excl values
            --  are already as restricted as they are allowed to be.

            if Typ /= Btyp then
               Loval_Incl_EP := UR_Max (Loval_Incl_EP, Realval (BLo));
               Hival_Incl_EP := UR_Min (Hival_Incl_EP, Realval (BHi));
            end if;

            --  Get size including and excluding end points

            Size_Incl_EP := Fsize (Loval_Incl_EP, Hival_Incl_EP);
            Size_Excl_EP := Fsize (Loval_Excl_EP, Hival_Excl_EP);

            --  No need to exclude end-points if it does not reduce size

            if Fsize (Loval_Incl_EP, Hival_Excl_EP) = Size_Excl_EP then
               Loval_Excl_EP := Loval_Incl_EP;
            end if;

            if Fsize (Loval_Excl_EP, Hival_Incl_EP) = Size_Excl_EP then
               Hival_Excl_EP := Hival_Incl_EP;
            end if;

            --  Now we set the actual size to be used. We want to use the
            --  bounds fudged up to include the end-points but only if this
            --  can be done without violating a specifically given size
            --  size clause or causing an unacceptable increase in size.

            --  Case of size clause given

            if Has_Size_Clause (Typ) then

               --  Use the inclusive size only if it is consistent with
               --  the explicitly specified size.

               if Size_Incl_EP <= RM_Size (Typ) then
                  Actual_Lo   := Loval_Incl_EP;
                  Actual_Hi   := Hival_Incl_EP;
                  Actual_Size := Size_Incl_EP;

               --  If the inclusive size is too large, we try excluding
               --  the end-points (will be caught later if does not work).

               else
                  Actual_Lo   := Loval_Excl_EP;
                  Actual_Hi   := Hival_Excl_EP;
                  Actual_Size := Size_Excl_EP;
               end if;

            --  Case of size clause not given

            else
               --  If we have a base type whose corresponding first subtype
               --  has an explicit size that is large enough to include our
               --  end-points, then do so. There is no point in working hard
               --  to get a base type whose size is smaller than the specified
               --  size of the first subtype.

               First_Subt := First_Subtype (Typ);

               if Has_Size_Clause (First_Subt)
                 and then Size_Incl_EP <= Esize (First_Subt)
               then
                  Actual_Size := Size_Incl_EP;
                  Actual_Lo   := Loval_Incl_EP;
                  Actual_Hi   := Hival_Incl_EP;

               --  If excluding the end-points makes the size smaller and
               --  results in a size of 8,16,32,64, then we take the smaller
               --  size. For the 64 case, this is compulsory. For the other
               --  cases, it seems reasonable. We like to include end points
               --  if we can, but not at the expense of moving to the next
               --  natural boundary of size.

               elsif Size_Incl_EP /= Size_Excl_EP
                 and then
                    (Size_Excl_EP = 8  or else
                     Size_Excl_EP = 16 or else
                     Size_Excl_EP = 32 or else
                     Size_Excl_EP = 64)
               then
                  Actual_Size := Size_Excl_EP;
                  Actual_Lo   := Loval_Excl_EP;
                  Actual_Hi   := Hival_Excl_EP;

               --  Otherwise we can definitely include the end points

               else
                  Actual_Size := Size_Incl_EP;
                  Actual_Lo   := Loval_Incl_EP;
                  Actual_Hi   := Hival_Incl_EP;
               end if;

               --  One pathological case: normally we never fudge a low bound
               --  down, since it would seem to increase the size (if it has
               --  any effect), but for ranges containing single value, or no
               --  values, the high bound can be small too large. Consider:

               --    type t is delta 2.0**(-14)
               --      range 131072.0 .. 0;

               --  That lower bound is *just* outside the range of 32 bits, and
               --  does need fudging down in this case. Note that the bounds
               --  will always have crossed here, since the high bound will be
               --  fudged down if necessary, as in the case of:

               --    type t is delta 2.0**(-14)
               --      range 131072.0 .. 131072.0;

               --  So we detect the situation by looking for crossed bounds,
               --  and if the bounds are crossed, and the low bound is greater
               --  than zero, we will always back it off by small, since this
               --  is completely harmless.

               if Actual_Lo > Actual_Hi then
                  if UR_Is_Positive (Actual_Lo) then
                     Actual_Lo   := Loval_Incl_EP - Small;
                     Actual_Size := Fsize (Actual_Lo, Actual_Hi);

                  --  And of course, we need to do exactly the same parallel
                  --  fudge for flat ranges in the negative region.

                  elsif UR_Is_Negative (Actual_Hi) then
                     Actual_Hi := Hival_Incl_EP + Small;
                     Actual_Size := Fsize (Actual_Lo, Actual_Hi);
                  end if;
               end if;
            end if;

            Set_Realval (Lo, Actual_Lo);
            Set_Realval (Hi, Actual_Hi);
         end Fudge;

      --  For the decimal case, none of this fudging is required, since there
      --  are no end-point problems in the decimal case (the end-points are
      --  always included).

      else
         Actual_Size := Fsize (Loval, Hival);
      end if;

      --  At this stage, the actual size has been calculated and the proper
      --  required bounds are stored in the low and high bounds.

      if Actual_Size > 64 then
         Error_Msg_Uint_1 := UI_From_Int (Actual_Size);
         Error_Msg_N
           ("size required (^) for type& too large, maximum is 64", Typ);
         Actual_Size := 64;
      end if;

      --  Check size against explicit given size

      if Has_Size_Clause (Typ) then
         if Actual_Size > RM_Size (Typ) then
            Error_Msg_Uint_1 := RM_Size (Typ);
            Error_Msg_Uint_2 := UI_From_Int (Actual_Size);
            Error_Msg_NE
              ("size given (^) for type& too small, minimum is ^",
               Size_Clause (Typ), Typ);

         else
            Actual_Size := UI_To_Int (Esize (Typ));
         end if;

      --  Increase size to next natural boundary if no size clause given

      else
         if Actual_Size <= 8 then
            Actual_Size := 8;
         elsif Actual_Size <= 16 then
            Actual_Size := 16;
         elsif Actual_Size <= 32 then
            Actual_Size := 32;
         else
            Actual_Size := 64;
         end if;

         Init_Esize (Typ, Actual_Size);
         Adjust_Esize_For_Alignment (Typ);
      end if;

      --  If we have a base type, then expand the bounds so that they extend to
      --  the full width of the allocated size in bits, to avoid junk range
      --  checks on intermediate computations.

      if Base_Type (Typ) = Typ then
         Set_Realval (Lo, -(Small * (Uint_2 ** (Actual_Size - 1))));
         Set_Realval (Hi,  (Small * (Uint_2 ** (Actual_Size - 1) - 1)));
      end if;

      --  Final step is to reanalyze the bounds using the proper type
      --  and set the Corresponding_Integer_Value fields of the literals.

      Set_Etype (Lo, Empty);
      Set_Analyzed (Lo, False);
      Analyze (Lo);

      --  Resolve with universal fixed if the base type, and the base type if
      --  it is a subtype. Note we can't resolve the base type with itself,
      --  that would be a reference before definition.

      if Typ = Btyp then
         Resolve (Lo, Universal_Fixed);
      else
         Resolve (Lo, Btyp);
      end if;

      --  Set corresponding integer value for bound

      Set_Corresponding_Integer_Value
        (Lo, UR_To_Uint (Realval (Lo) / Small));

      --  Similar processing for high bound

      Set_Etype (Hi, Empty);
      Set_Analyzed (Hi, False);
      Analyze (Hi);

      if Typ = Btyp then
         Resolve (Hi, Universal_Fixed);
      else
         Resolve (Hi, Btyp);
      end if;

      Set_Corresponding_Integer_Value
        (Hi, UR_To_Uint (Realval (Hi) / Small));

      --  Set type of range to correspond to bounds

      Set_Etype (Rng, Etype (Lo));

      --  Set Esize to calculated size if not set already

      if Unknown_Esize (Typ) then
         Init_Esize (Typ, Actual_Size);
      end if;

      --  Set RM_Size if not already set. If already set, check value

      declare
         Minsiz : constant Uint := UI_From_Int (Minimum_Size (Typ));

      begin
         if RM_Size (Typ) /= Uint_0 then
            if RM_Size (Typ) < Minsiz then
               Error_Msg_Uint_1 := RM_Size (Typ);
               Error_Msg_Uint_2 := Minsiz;
               Error_Msg_NE
                 ("size given (^) for type& too small, minimum is ^",
                  Size_Clause (Typ), Typ);
            end if;

         else
            Set_RM_Size (Typ, Minsiz);
         end if;
      end;
   end Freeze_Fixed_Point_Type;

   ------------------
   -- Freeze_Itype --
   ------------------

   procedure Freeze_Itype (T : Entity_Id; N : Node_Id) is
      L : List_Id;

   begin
      Set_Has_Delayed_Freeze (T);
      L := Freeze_Entity (T, Sloc (N));

      if Is_Non_Empty_List (L) then
         Insert_Actions (N, L);
      end if;
   end Freeze_Itype;

   --------------------------
   -- Freeze_Static_Object --
   --------------------------

   procedure Freeze_Static_Object (E : Entity_Id) is

      Cannot_Be_Static : exception;
      --  Exception raised if the type of a static object cannot be made
      --  static. This happens if the type depends on non-global objects.

      procedure Ensure_Expression_Is_SA (N : Node_Id);
      --  Called to ensure that an expression used as part of a type definition
      --  is statically allocatable, which means that the expression type is
      --  statically allocatable, and the expression is either static, or a
      --  reference to a library level constant.

      procedure Ensure_Type_Is_SA (Typ : Entity_Id);
      --  Called to mark a type as static, checking that it is possible
      --  to set the type as static. If it is not possible, then the
      --  exception Cannot_Be_Static is raised.

      -----------------------------
      -- Ensure_Expression_Is_SA --
      -----------------------------

      procedure Ensure_Expression_Is_SA (N : Node_Id) is
         Ent : Entity_Id;

      begin
         Ensure_Type_Is_SA (Etype (N));

         if Is_Static_Expression (N) then
            return;

         elsif Nkind (N) = N_Identifier then
            Ent := Entity (N);

            if Present (Ent)
              and then Ekind (Ent) = E_Constant
              and then Is_Library_Level_Entity (Ent)
            then
               return;
            end if;
         end if;

         raise Cannot_Be_Static;
      end Ensure_Expression_Is_SA;

      -----------------------
      -- Ensure_Type_Is_SA --
      -----------------------

      procedure Ensure_Type_Is_SA (Typ : Entity_Id) is
         N : Node_Id;
         C : Entity_Id;

      begin
         --  If type is library level, we are all set

         if Is_Library_Level_Entity (Typ) then
            return;
         end if;

         --  We are also OK if the type already marked as statically allocated,
         --  which means we processed it before.

         if Is_Statically_Allocated (Typ) then
            return;
         end if;

         --  Mark type as statically allocated

         Set_Is_Statically_Allocated (Typ);

         --  Check that it is safe to statically allocate this type

         if Is_Scalar_Type (Typ) or else Is_Real_Type (Typ) then
            Ensure_Expression_Is_SA (Type_Low_Bound (Typ));
            Ensure_Expression_Is_SA (Type_High_Bound (Typ));

         elsif Is_Array_Type (Typ) then
            N := First_Index (Typ);
            while Present (N) loop
               Ensure_Type_Is_SA (Etype (N));
               Next_Index (N);
            end loop;

            Ensure_Type_Is_SA (Component_Type (Typ));

         elsif Is_Access_Type (Typ) then
            if Ekind (Designated_Type (Typ)) = E_Subprogram_Type then

               declare
                  F : Entity_Id;
                  T : constant Entity_Id := Etype (Designated_Type (Typ));

               begin
                  if T /= Standard_Void_Type then
                     Ensure_Type_Is_SA (T);
                  end if;

                  F := First_Formal (Designated_Type (Typ));

                  while Present (F) loop
                     Ensure_Type_Is_SA (Etype (F));
                     Next_Formal (F);
                  end loop;
               end;

            else
               Ensure_Type_Is_SA (Designated_Type (Typ));
            end if;

         elsif Is_Record_Type (Typ) then
            C := First_Entity (Typ);

            while Present (C) loop
               if Ekind (C) = E_Discriminant
                 or else Ekind (C) = E_Component
               then
                  Ensure_Type_Is_SA (Etype (C));

               elsif Is_Type (C) then
                  Ensure_Type_Is_SA (C);
               end if;

               Next_Entity (C);
            end loop;

         elsif Ekind (Typ) = E_Subprogram_Type then
            Ensure_Type_Is_SA (Etype (Typ));

            C := First_Formal (Typ);
            while Present (C) loop
               Ensure_Type_Is_SA (Etype (C));
               Next_Formal (C);
            end loop;

         else
            raise Cannot_Be_Static;
         end if;
      end Ensure_Type_Is_SA;

   --  Start of processing for Freeze_Static_Object

   begin
      Ensure_Type_Is_SA (Etype (E));

      --  Reset True_Constant flag, since something strange is going on with
      --  the scoping here, and our simple value tracing may not be sufficient
      --  for this indication to be reliable. We kill the Constant_Value
      --  indication for the same reason.

      Set_Is_True_Constant (E, False);
      Set_Current_Value    (E, Empty);

   exception
      when Cannot_Be_Static =>

         --  If the object that cannot be static is imported or exported,
         --  then we give an error message saying that this object cannot
         --  be imported or exported.

         if Is_Imported (E) then
            Error_Msg_N
              ("& cannot be imported (local type is not constant)", E);

         --  Otherwise must be exported, something is wrong if compiler
         --  is marking something as statically allocated which cannot be).

         else pragma Assert (Is_Exported (E));
            Error_Msg_N
              ("& cannot be exported (local type is not constant)", E);
         end if;
   end Freeze_Static_Object;

   -----------------------
   -- Freeze_Subprogram --
   -----------------------

   procedure Freeze_Subprogram (E : Entity_Id) is
      Retype : Entity_Id;
      F      : Entity_Id;

   begin
      --  Subprogram may not have an address clause unless it is imported

      if Present (Address_Clause (E)) then
         if not Is_Imported (E) then
            Error_Msg_N
              ("address clause can only be given " &
               "for imported subprogram",
               Name (Address_Clause (E)));
         end if;
      end if;

      --  Reset the Pure indication on an imported subprogram unless an
      --  explicit Pure_Function pragma was present. We do this because
      --  otherwise it is an insidious error to call a non-pure function from
      --  pure unit and have calls mysteriously optimized away. What happens
      --  here is that the Import can bypass the normal check to ensure that
      --  pure units call only pure subprograms.

      if Is_Imported (E)
        and then Is_Pure (E)
        and then not Has_Pragma_Pure_Function (E)
      then
         Set_Is_Pure (E, False);
      end if;

      --  For non-foreign convention subprograms, this is where we create
      --  the extra formals (for accessibility level and constrained bit
      --  information). We delay this till the freeze point precisely so
      --  that we know the convention!

      if not Has_Foreign_Convention (E) then
         Create_Extra_Formals (E);
         Set_Mechanisms (E);

         --  If this is convention Ada and a Valued_Procedure, that's odd

         if Ekind (E) = E_Procedure
           and then Is_Valued_Procedure (E)
           and then Convention (E) = Convention_Ada
           and then Warn_On_Export_Import
         then
            Error_Msg_N
              ("?Valued_Procedure has no effect for convention Ada", E);
            Set_Is_Valued_Procedure (E, False);
         end if;

      --  Case of foreign convention

      else
         Set_Mechanisms (E);

         --  For foreign conventions, warn about return of an
         --  unconstrained array.

         --  Note: we *do* allow a return by descriptor for the VMS case,
         --  though here there is probably more to be done ???

         if Ekind (E) = E_Function then
            Retype := Underlying_Type (Etype (E));

            --  If no return type, probably some other error, e.g. a
            --  missing full declaration, so ignore.

            if No (Retype) then
               null;

            --  If the return type is generic, we have emitted a warning
            --  earlier on, and there is nothing else to check here. Specific
            --  instantiations may lead to erroneous behavior.

            elsif Is_Generic_Type (Etype (E)) then
               null;

            elsif Is_Array_Type (Retype)
              and then not Is_Constrained (Retype)
              and then Mechanism (E) not in Descriptor_Codes
              and then Warn_On_Export_Import
            then
               Error_Msg_N
                ("?foreign convention function& should not return " &
                  "unconstrained array", E);
               return;
            end if;
         end if;

         --  If any of the formals for an exported foreign convention
         --  subprogram have defaults, then emit an appropriate warning since
         --  this is odd (default cannot be used from non-Ada code)

         if Is_Exported (E) then
            F := First_Formal (E);
            while Present (F) loop
               if Warn_On_Export_Import
                 and then Present (Default_Value (F))
               then
                  Error_Msg_N
                    ("?parameter cannot be defaulted in non-Ada call",
                     Default_Value (F));
               end if;

               Next_Formal (F);
            end loop;
         end if;
      end if;

      --  For VMS, descriptor mechanisms for parameters are allowed only
      --  for imported subprograms.

      if OpenVMS_On_Target then
         if not Is_Imported (E) then
            F := First_Formal (E);
            while Present (F) loop
               if Mechanism (F) in Descriptor_Codes then
                  Error_Msg_N
                    ("descriptor mechanism for parameter not permitted", F);
                  Error_Msg_N
                    ("\can only be used for imported subprogram", F);
               end if;

               Next_Formal (F);
            end loop;
         end if;
      end if;

      --  Pragma Inline_Always is disallowed for dispatching subprograms
      --  because the address of such subprograms is saved in the dispatch
      --  table to support dispatching calls, and dispatching calls cannot
      --  be inlined. This is consistent with the restriction against using
      --  'Access or 'Address on an Inline_Always subprogram.

      if Is_Dispatching_Operation (E) and then Is_Always_Inlined (E) then
         Error_Msg_N
           ("pragma Inline_Always not allowed for dispatching subprograms", E);
      end if;
   end Freeze_Subprogram;

   ----------------------
   -- Is_Fully_Defined --
   ----------------------

   function Is_Fully_Defined (T : Entity_Id) return Boolean is
   begin
      if Ekind (T) = E_Class_Wide_Type then
         return Is_Fully_Defined (Etype (T));

      elsif Is_Array_Type (T) then
         return Is_Fully_Defined (Component_Type (T));

      elsif Is_Record_Type (T)
        and not Is_Private_Type (T)
      then
         --  Verify that the record type has no components with private types
         --  without completion.

         declare
            Comp : Entity_Id;

         begin
            Comp := First_Component (T);

            while Present (Comp) loop
               if not Is_Fully_Defined (Etype (Comp)) then
                  return False;
               end if;

               Next_Component (Comp);
            end loop;
            return True;
         end;

      --  LLVM local begin
      else
         return not Is_Private_Type (T)
           or else Present (Full_View (Base_Type (T)));
      --  LLVM local end
      end if;
   end Is_Fully_Defined;

   ---------------------------------
   -- Process_Default_Expressions --
   ---------------------------------

   procedure Process_Default_Expressions
     (E     : Entity_Id;
      After : in out Node_Id)
   is
      Loc    : constant Source_Ptr := Sloc (E);
      Dbody  : Node_Id;
      Formal : Node_Id;
      Dcopy  : Node_Id;
      Dnam   : Entity_Id;

   begin
      Set_Default_Expressions_Processed (E);

      --  A subprogram instance and its associated anonymous subprogram share
      --  their signature. The default expression functions are defined in the
      --  wrapper packages for the anonymous subprogram, and should not be
      --  generated again for the instance.

      if Is_Generic_Instance (E)
        and then Present (Alias (E))
        and then Default_Expressions_Processed (Alias (E))
      then
         return;
      end if;

      Formal := First_Formal (E);

      while Present (Formal) loop
         if Present (Default_Value (Formal)) then

            --  We work with a copy of the default expression because we
            --  do not want to disturb the original, since this would mess
            --  up the conformance checking.

            Dcopy := New_Copy_Tree (Default_Value (Formal));

            --  The analysis of the expression may generate insert actions,
            --  which of course must not be executed. We wrap those actions
            --  in a procedure that is not called, and later on eliminated.
            --  The following cases have no side-effects, and are analyzed
            --  directly.

            if Nkind (Dcopy) = N_Identifier
              or else Nkind (Dcopy) = N_Expanded_Name
              or else Nkind (Dcopy) = N_Integer_Literal
              or else (Nkind (Dcopy) = N_Real_Literal
                        and then not Vax_Float (Etype (Dcopy)))
              or else Nkind (Dcopy) = N_Character_Literal
              or else Nkind (Dcopy) = N_String_Literal
              or else Nkind (Dcopy) = N_Null
              or else (Nkind (Dcopy) = N_Attribute_Reference
                        and then
                       Attribute_Name (Dcopy) = Name_Null_Parameter)
            then

               --  If there is no default function, we must still do a full
               --  analyze call on the default value, to ensure that all error
               --  checks are performed, e.g. those associated with static
               --  evaluation. Note: this branch will always be taken if the
               --  analyzer is turned off (but we still need the error checks).

               --  Note: the setting of parent here is to meet the requirement
               --  that we can only analyze the expression while attached to
               --  the tree. Really the requirement is that the parent chain
               --  be set, we don't actually need to be in the tree.

               Set_Parent (Dcopy, Declaration_Node (Formal));
               Analyze (Dcopy);

               --  Default expressions are resolved with their own type if the
               --  context is generic, to avoid anomalies with private types.

               if Ekind (Scope (E)) = E_Generic_Package then
                  Resolve (Dcopy);
               else
                  Resolve (Dcopy, Etype (Formal));
               end if;

               --  If that resolved expression will raise constraint error,
               --  then flag the default value as raising constraint error.
               --  This allows a proper error message on the calls.

               if Raises_Constraint_Error (Dcopy) then
                  Set_Raises_Constraint_Error (Default_Value (Formal));
               end if;

            --  If the default is a parameterless call, we use the name of
            --  the called function directly, and there is no body to build.

            elsif Nkind (Dcopy) = N_Function_Call
              and then No (Parameter_Associations (Dcopy))
            then
               null;

            --  Else construct and analyze the body of a wrapper procedure
            --  that contains an object declaration to hold the expression.
            --  Given that this is done only to complete the analysis, it
            --  simpler to build a procedure than a function which might
            --  involve secondary stack expansion.

            else
               Dnam :=
                 Make_Defining_Identifier (Loc, New_Internal_Name ('D'));

               Dbody :=
                 Make_Subprogram_Body (Loc,
                   Specification =>
                     Make_Procedure_Specification (Loc,
                       Defining_Unit_Name => Dnam),

                   Declarations => New_List (
                     Make_Object_Declaration (Loc,
                       Defining_Identifier =>
                         Make_Defining_Identifier (Loc,
                           New_Internal_Name ('T')),
                         Object_Definition =>
                           New_Occurrence_Of (Etype (Formal), Loc),
                         Expression => New_Copy_Tree (Dcopy))),

                   Handled_Statement_Sequence =>
                     Make_Handled_Sequence_Of_Statements (Loc,
                       Statements => New_List));

               Set_Scope (Dnam, Scope (E));
               Set_Assignment_OK (First (Declarations (Dbody)));
               Set_Is_Eliminated (Dnam);
               Insert_After (After, Dbody);
               Analyze (Dbody);
               After := Dbody;
            end if;
         end if;

         Next_Formal (Formal);
      end loop;

   end Process_Default_Expressions;

   ----------------------------------------
   -- Set_Component_Alignment_If_Not_Set --
   ----------------------------------------

   procedure Set_Component_Alignment_If_Not_Set (Typ : Entity_Id) is
   begin
      --  Ignore if not base type, subtypes don't need anything

      if Typ /= Base_Type (Typ) then
         return;
      end if;

      --  Do not override existing representation

      if Is_Packed (Typ) then
         return;

      elsif Has_Specified_Layout (Typ) then
         return;

      elsif Component_Alignment (Typ) /= Calign_Default then
         return;

      else
         Set_Component_Alignment
           (Typ, Scope_Stack.Table
                  (Scope_Stack.Last).Component_Alignment_Default);
      end if;
   end Set_Component_Alignment_If_Not_Set;

   ---------------------------
   -- Set_Debug_Info_Needed --
   ---------------------------

   procedure Set_Debug_Info_Needed (T : Entity_Id) is
   begin
      if No (T)
        or else Needs_Debug_Info (T)
        or else Debug_Info_Off (T)
      then
         return;
      else
         Set_Needs_Debug_Info (T);
      end if;

      if Is_Object (T) then
         Set_Debug_Info_Needed (Etype (T));

      elsif Is_Type (T) then
         Set_Debug_Info_Needed (Etype (T));

         if Is_Record_Type (T) then
            declare
               Ent : Entity_Id := First_Entity (T);
            begin
               while Present (Ent) loop
                  Set_Debug_Info_Needed (Ent);
                  Next_Entity (Ent);
               end loop;
            end;

         elsif Is_Array_Type (T) then
            Set_Debug_Info_Needed (Component_Type (T));

            declare
               Indx : Node_Id := First_Index (T);
            begin
               while Present (Indx) loop
                  Set_Debug_Info_Needed (Etype (Indx));
                  Indx := Next_Index (Indx);
               end loop;
            end;

            if Is_Packed (T) then
               Set_Debug_Info_Needed (Packed_Array_Type (T));
            end if;

         elsif Is_Access_Type (T) then
            Set_Debug_Info_Needed (Directly_Designated_Type (T));

         elsif Is_Private_Type (T) then
            Set_Debug_Info_Needed (Full_View (T));

         elsif Is_Protected_Type (T) then
            Set_Debug_Info_Needed (Corresponding_Record_Type (T));
         end if;
      end if;
   end Set_Debug_Info_Needed;

   ------------------
   -- Undelay_Type --
   ------------------

   procedure Undelay_Type (T : Entity_Id) is
   begin
      Set_Has_Delayed_Freeze (T, False);
      Set_Freeze_Node (T, Empty);

      --  Since we don't want T to have a Freeze_Node, we don't want its
      --  Full_View or Corresponding_Record_Type to have one either.

      --  ??? Fundamentally, this whole handling is a kludge. What we really
      --  want is to be sure that for an Itype that's part of record R and is a
      --  subtype of type T, that it's frozen after the later of the freeze
      --  points of R and T. We have no way of doing that directly, so what we
      --  do is force most such Itypes to be frozen as part of freezing R via
      --  this procedure and only delay the ones that need to be delayed
      --  (mostly the designated types of access types that are defined as part
      --  of the record).

      if Is_Private_Type (T)
        and then Present (Full_View (T))
        and then Is_Itype (Full_View (T))
        and then Is_Record_Type (Scope (Full_View (T)))
      then
         Undelay_Type (Full_View (T));
      end if;

      if Is_Concurrent_Type (T)
        and then Present (Corresponding_Record_Type (T))
        and then Is_Itype (Corresponding_Record_Type (T))
        and then Is_Record_Type (Scope (Corresponding_Record_Type (T)))
      then
         Undelay_Type (Corresponding_Record_Type (T));
      end if;
   end Undelay_Type;

   ------------------
   -- Warn_Overlay --
   ------------------

   procedure Warn_Overlay
     (Expr : Node_Id;
      Typ  : Entity_Id;
      Nam  : Entity_Id)
   is
      Ent : constant Entity_Id := Entity (Nam);
      --  The object to which the address clause applies

      Init : Node_Id;
      Old  : Entity_Id := Empty;
      Decl : Node_Id;

   begin
      --  No warning if address clause overlay warnings are off

      if not Address_Clause_Overlay_Warnings then
         return;
      end if;

      --  No warning if there is an explicit initialization

      Init := Original_Node (Expression (Declaration_Node (Ent)));

      if Present (Init) and then Comes_From_Source (Init) then
         return;
      end if;

      --  We only give the warning for non-imported entities of a type for
      --  which a non-null base init proc is defined (or for access types which
      --  have implicit null initialization).

      if Present (Expr)
        and then (Has_Non_Null_Base_Init_Proc (Typ)
                    or else Is_Access_Type (Typ))
        and then not Is_Imported (Ent)
      then
         if Nkind (Expr) = N_Attribute_Reference
           and then Is_Entity_Name (Prefix (Expr))
         then
            Old := Entity (Prefix (Expr));

         elsif Is_Entity_Name (Expr)
           and then Ekind (Entity (Expr)) = E_Constant
         then
            Decl := Declaration_Node (Entity (Expr));

            if Nkind (Decl) = N_Object_Declaration
              and then Present (Expression (Decl))
              and then Nkind (Expression (Decl)) = N_Attribute_Reference
              and then Is_Entity_Name (Prefix (Expression (Decl)))
            then
               Old := Entity (Prefix (Expression (Decl)));

            elsif Nkind (Expr) = N_Function_Call then
               return;
            end if;

         --  A function call (most likely to To_Address) is probably not an
         --  overlay, so skip warning. Ditto if the function call was inlined
         --  and transformed into an entity.

         elsif Nkind (Original_Node (Expr)) = N_Function_Call then
            return;
         end if;

         Decl := Next (Parent (Expr));

         --  If a pragma Import follows, we assume that it is for the current
         --  target of the address clause, and skip the warning.

         if Present (Decl)
           and then Nkind (Decl) = N_Pragma
           and then Chars (Decl) = Name_Import
         then
            return;
         end if;

         if Present (Old) then
            Error_Msg_Node_2 := Old;
            Error_Msg_N
              ("default initialization of & may modify &?",
               Nam);
         else
            Error_Msg_N
              ("default initialization of & may modify overlaid storage?",
               Nam);
         end if;

         --  Add friendly warning if initialization comes from a packed array
         --  component.

         if Is_Record_Type (Typ)  then
            declare
               Comp : Entity_Id;

            begin
               Comp := First_Component (Typ);

               while Present (Comp) loop
                  if Nkind (Parent (Comp)) = N_Component_Declaration
                    and then Present (Expression (Parent (Comp)))
                  then
                     exit;
                  elsif Is_Array_Type (Etype (Comp))
                     and then Present (Packed_Array_Type (Etype (Comp)))
                  then
                     Error_Msg_NE
                       ("packed array component& will be initialized to zero?",
                          Nam, Comp);
                     exit;
                  else
                     Next_Component (Comp);
                  end if;
               end loop;
            end;
         end if;

         Error_Msg_N
           ("use pragma Import for & to " &
              "suppress initialization ('R'M B.1(24))?",
             Nam);
      end if;
   end Warn_Overlay;

end Freeze;
