procedure Freeze_And_Append
(Ent : Entity_Id;
- Loc : Source_Ptr;
+ N : Node_Id;
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.
+ -- nodes to Result, modifying Result from No_List if necessary. N has
+ -- the same usage as in Freeze_Entity.
procedure Freeze_Enumeration_Type (Typ : Entity_Id);
-- Freeze enumeration type. The Esize field is set as processing
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).
+ -- 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.
+ -- 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
-- subsidiary entities have the flag set as required.
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.
+ -- 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;
-- 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;
if Comes_From_Source (Subp)
and then not Is_Frozen (Subp)
then
- Flist := Freeze_Entity (Subp, Loc);
+ Flist := Freeze_Entity (Subp, After);
Process_Flist;
end if;
end if;
if not Is_Frozen (E) then
- Flist := Freeze_Entity (E, Loc);
+ Flist := Freeze_Entity (E, After);
Process_Flist;
end if;
procedure Freeze_And_Append
(Ent : Entity_Id;
- Loc : Source_Ptr;
+ N : Node_Id;
Result : in out List_Id)
is
- L : constant List_Id := Freeze_Entity (Ent, Loc);
+ L : constant List_Id := Freeze_Entity (Ent, N);
begin
if Is_Non_Empty_List (L) then
if Result = No_List then
-------------------
procedure Freeze_Before (N : Node_Id; T : Entity_Id) is
- Freeze_Nodes : constant List_Id := Freeze_Entity (T, Sloc (N));
+ Freeze_Nodes : constant List_Id := Freeze_Entity (T, N);
begin
if Is_Non_Empty_List (Freeze_Nodes) then
Insert_Actions (N, Freeze_Nodes);
-- Freeze_Entity --
-------------------
- function Freeze_Entity (E : Entity_Id; Loc : Source_Ptr) return List_Id is
+ function Freeze_Entity (E : Entity_Id; N : Node_Id) return List_Id is
+ Loc : constant Source_Ptr := Sloc (N);
Test_E : Entity_Id := E;
Comp : Entity_Id;
F_Node : Node_Id;
Undelay_Type (Etype (Comp));
end if;
- Freeze_And_Append (Etype (Comp), Loc, Result);
+ Freeze_And_Append (Etype (Comp), N, Result);
-- Check for error of component clause given for variable
-- sized type. We have to delay this test till this point,
then
if Is_Entity_Name (Expression (Alloc)) then
Freeze_And_Append
- (Entity (Expression (Alloc)), Loc, Result);
+ (Entity (Expression (Alloc)), N, Result);
elsif
Nkind (Expression (Alloc)) = N_Subtype_Indication
then
Freeze_And_Append
(Entity (Subtype_Mark (Expression (Alloc))),
- Loc, Result);
+ N, Result);
end if;
elsif Is_Itype (Designated_Type (Etype (Comp))) then
else
Freeze_And_Append
- (Designated_Type (Etype (Comp)), Loc, Result);
+ (Designated_Type (Etype (Comp)), N, Result);
end if;
end if;
end;
then
Freeze_And_Append
(Designated_Type
- (Component_Type (Etype (Comp))), Loc, Result);
+ (Component_Type (Etype (Comp))), N, Result);
end if;
Prev := Comp;
-- Set OK_To_Reorder_Components depending on debug flags
- if Rec = Base_Type (Rec)
- and then Convention (Rec) = Convention_Ada
- then
+ if Is_Base_Type (Rec) and then Convention (Rec) = Convention_Ada then
if (Has_Discriminants (Rec) and then Debug_Flag_Dot_V)
or else
(not Has_Discriminants (Rec) and then Debug_Flag_Dot_R)
if Ekind (Rec) = E_Record_Type then
if Present (Corresponding_Remote_Type (Rec)) then
- Freeze_And_Append
- (Corresponding_Remote_Type (Rec), Loc, Result);
+ Freeze_And_Append (Corresponding_Remote_Type (Rec), N, Result);
end if;
Comp := First_Component (Rec);
end;
end if;
+ -- Deal with delayed aspect specifications. At the point of occurrence
+ -- of the aspect definition, we preanalyzed the argument, to capture
+ -- the visibility at that point, but the actual analysis of the aspect
+ -- is required to be delayed to the freeze point, so we evalute the
+ -- pragma or attribute definition clause in the tree at this point.
+
+ if Has_Delayed_Aspects (E) then
+ declare
+ Ritem : Node_Id;
+ Aitem : Node_Id;
+
+ begin
+ Ritem := First_Rep_Item (E);
+ while Present (Ritem) loop
+ if Nkind (Ritem) = N_Aspect_Specification then
+ Aitem := Aspect_Rep_Item (Ritem);
+ pragma Assert (Is_Delayed_Aspect (Aitem));
+ Set_Parent (Aitem, Ritem);
+ Analyze (Aitem);
+ end if;
+
+ Next_Rep_Item (Ritem);
+ end loop;
+ end;
+ end if;
+
-- Here to freeze the entity
Result := No_List;
Formal := First_Formal (E);
while Present (Formal) loop
F_Type := Etype (Formal);
- Freeze_And_Append (F_Type, Loc, Result);
+ Freeze_And_Append (F_Type, N, Result);
if Is_Private_Type (F_Type)
and then Is_Private_Type (Base_Type (F_Type))
if Is_Itype (Etype (Formal))
and then Ekind (F_Type) = E_Subprogram_Type
then
- Freeze_And_Append (F_Type, Loc, Result);
+ Freeze_And_Append (F_Type, N, Result);
end if;
end if;
-- Freeze return type
R_Type := Etype (E);
- Freeze_And_Append (R_Type, Loc, Result);
+ Freeze_And_Append (R_Type, N, Result);
-- Check suspicious return type for C function
-- Must freeze its parent first if it is a derived subprogram
if Present (Alias (E)) then
- Freeze_And_Append (Alias (E), Loc, Result);
+ Freeze_And_Append (Alias (E), N, Result);
end if;
-- We don't freeze internal subprograms, because we don't normally
if Present (Etype (E))
and then Ekind (E) /= E_Generic_Function
then
- Freeze_And_Append (Etype (E), Loc, Result);
+ Freeze_And_Append (Etype (E), N, Result);
end if;
-- Special processing for objects created by object declaration
end if;
-- If ancestor subtype present, freeze that first. Note that this
- -- will also get the base type frozen.
+ -- will also get the base type frozen. Need RM reference ???
Atype := Ancestor_Subtype (E);
if Present (Atype) then
- Freeze_And_Append (Atype, Loc, Result);
+ Freeze_And_Append (Atype, N, Result);
- -- Otherwise freeze the base type of the entity before freezing
- -- the entity itself (RM 13.14(15)).
+ -- No ancestor subtype present
- elsif E /= Base_Type (E) then
- Freeze_And_Append (Base_Type (E), Loc, Result);
+ else
+ -- See if we have a nearest ancestor that has a predicate.
+ -- That catches the case of derived type with a predicate.
+ -- Need RM reference here ???
+
+ Atype := Nearest_Ancestor (E);
+
+ if Present (Atype) and then Has_Predicates (Atype) then
+ Freeze_And_Append (Atype, N, Result);
+ end if;
+
+ -- Freeze base type before freezing the entity (RM 13.14(15))
+
+ if E /= Base_Type (E) then
+ Freeze_And_Append (Base_Type (E), N, Result);
+ end if;
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);
+ Freeze_And_Append (Etype (E), N, Result);
+ Freeze_And_Append (First_Subtype (Etype (E)), N, Result);
end if;
-- For array type, freeze index types and component type first
-- with a non-standard representation.
begin
- Freeze_And_Append (Ctyp, Loc, Result);
+ Freeze_And_Append (Ctyp, N, Result);
Indx := First_Index (E);
while Present (Indx) loop
- Freeze_And_Append (Etype (Indx), Loc, Result);
+ Freeze_And_Append (Etype (Indx), N, Result);
if Is_Enumeration_Type (Etype (Indx))
and then Has_Non_Standard_Rep (Etype (Indx))
end;
end if;
- -- 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 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));
and then Ekind (E) /= E_String_Literal_Subtype
then
Create_Packed_Array_Type (E);
- Freeze_And_Append (Packed_Array_Type (E), Loc, Result);
+ Freeze_And_Append (Packed_Array_Type (E), N, Result);
-- Size information of packed array type is copied to the
-- array type, since this is really the representation. But
-- frozen as well (RM 13.14(15))
elsif Is_Class_Wide_Type (E) then
- Freeze_And_Append (Root_Type (E), Loc, Result);
+ Freeze_And_Append (Root_Type (E), N, Result);
-- If the base type of the class-wide type is still incomplete,
-- the class-wide remains unfrozen as well. This is legal when
if Ekind (E) = E_Class_Wide_Subtype
and then Present (Equivalent_Type (E))
then
- Freeze_And_Append (Equivalent_Type (E), Loc, Result);
+ Freeze_And_Append (Equivalent_Type (E), N, Result);
end if;
-- For a record (sub)type, freeze all the component types (RM
elsif Is_Concurrent_Type (E) then
if Present (Corresponding_Record_Type (E)) then
Freeze_And_Append
- (Corresponding_Record_Type (E), Loc, Result);
+ (Corresponding_Record_Type (E), N, Result);
end if;
Comp := First_Entity (E);
while Present (Comp) loop
if Is_Type (Comp) then
- Freeze_And_Append (Comp, Loc, Result);
+ Freeze_And_Append (Comp, N, Result);
elsif (Ekind (Comp)) /= E_Function then
if Is_Itype (Etype (Comp))
Undelay_Type (Etype (Comp));
end if;
- Freeze_And_Append (Etype (Comp), Loc, Result);
+ Freeze_And_Append (Etype (Comp), N, Result);
end if;
Next_Entity (Comp);
-- 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);
and then Present (Underlying_Full_View (Full))
then
Freeze_And_Append
- (Underlying_Full_View (Full), Loc, Result);
+ (Underlying_Full_View (Full), N, Result);
end if;
- Freeze_And_Append (Full, Loc, Result);
+ Freeze_And_Append (Full, N, Result);
if Has_Delayed_Freeze (E) then
F_Node := Freeze_Node (Full);
end if;
end if;
- Freeze_And_Append (Etype (Formal), Loc, Result);
+ Freeze_And_Append (Etype (Formal), N, Result);
Next_Formal (Formal);
end loop;
elsif Is_Access_Protected_Subprogram_Type (E) then
if Present (Equivalent_Type (E)) then
- Freeze_And_Append (Equivalent_Type (E), Loc, Result);
+ Freeze_And_Append (Equivalent_Type (E), N, Result);
end if;
end if;
-- 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 Is_Ordinary_Fixed_Point_Type (E) and then Is_Base_Type (E) then
if Small_Value (E) < Ureal_2_M_80 then
Error_Msg_Name_1 := Name_Small;
Error_Msg_N
elsif Is_Access_Type (E) then
+ -- If a pragma Default_Storage_Pool applies, and this type has no
+ -- Storage_Pool or Storage_Size clause (which must have occurred
+ -- before the freezing point), then use the default. This applies
+ -- only to base types.
+
+ if Present (Default_Pool)
+ and then Is_Base_Type (E)
+ and then not Has_Storage_Size_Clause (E)
+ and then No (Associated_Storage_Pool (E))
+ then
+ -- Case of pragma Default_Storage_Pool (null)
+
+ if Nkind (Default_Pool) = N_Null then
+ Set_No_Pool_Assigned (E);
+
+ -- Case of pragma Default_Storage_Pool (storage_pool_NAME)
+
+ else
+ Set_Associated_Storage_Pool (E, Entity (Default_Pool));
+ end if;
+ end if;
+
-- Check restriction for standard storage pool
if No (Associated_Storage_Pool (E)) then
-- since obviously the first subtype depends on its own base type.
if Is_Type (E) then
- Freeze_And_Append (First_Subtype (E), Loc, Result);
+ Freeze_And_Append (First_Subtype (E), N, 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
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);
+ Freeze_And_Append (Class_Wide_Type (E), N, Result);
end if;
end if;
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;
+ N : constant Node_Id := 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);
+ Freeze_And_Append (Desig_Typ, N, Freeze_Nodes);
end if;
if Present (Typ) then
- Freeze_And_Append (Typ, Loc, Freeze_Nodes);
+ Freeze_And_Append (Typ, N, Freeze_Nodes);
end if;
if Present (Nam) then
- Freeze_And_Append (Nam, Loc, Freeze_Nodes);
+ Freeze_And_Append (Nam, N, 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 the expression is within a top-level pragma, as for a pre-
+ -- condition on a library-level subprogram, nothing to do.
- if Is_Record_Type (Scope (Current_Scope)) then
+ if not Is_Compilation_Unit (Current_Scope)
+ and then 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;
+ Freeze_Nodes;
else
Append_List (Freeze_Nodes,
Scope_Stack.Table (Pos).Pending_Freeze_Actions);
begin
Set_Has_Delayed_Freeze (T);
- L := Freeze_Entity (T, Sloc (N));
+ L := Freeze_Entity (T, N);
if Is_Non_Empty_List (L) then
Insert_Actions (N, L);