Commit 47cc8d6b by Ed Schonberg Committed by Arnaud Charlet

exp_ch3.adb (Make_Controlling_Function_Wrappers): generate wrapper a wrapper…

exp_ch3.adb (Make_Controlling_Function_Wrappers): generate wrapper a wrapper when the full view of the controlling type of an...

2007-04-20  Ed Schonberg  <schonberg@adacore.com>
	    Javier Miranda  <miranda@adacore.com>
	    Robert Dewar  <dewar@adacore.com>

	* exp_ch3.adb (Make_Controlling_Function_Wrappers): generate wrapper a
	wrapper when the full view of the controlling type of an inherited
	function that dispatches on result implements interfaces.
	(Expand_N_Object_Declaration): In cases where the type of the
	declaration is anonymous access, create finalization list for it.
	(Expand_N_Object_Declaration): Generate a persistent_bss directive only
	if the object has no explicit initialization, to match description of
	functionality of pragam Persistent_BSS.
	(Build_Equivalent_Array_Aggregate, Build_Equivalent_Record_Aggregate):
	new function to build static aggregates, to replace initialization call
	when static initialization is desired.
	(Freeze_Type): Generate a list controller for an access type whenever
	its designated type has controlled anonymous access discriminants.
	(Build_Equivalent_Aggregate): New procedure to compute a static
	aggregate to be used as default initialization for composite types,
	instead of a generating a call to the initialization procedure for the
	type.
	(Build_Initialization_Call): When available, replace a call to the
	initialization procedure with a copy of the equivalent static aggregate
	for the type.
	(Expand_N_Object_Declaration):  Use New_Occurrence_Of in generated
	declarations for objects of a class-wide interface type, rather than
	just identifiers, to prevent visibility problems.
	(Expand_N_Object_Declaration): When expanding the declaration for an
	object of a class-wide interface type, preserve the homonym chain of
	the original entity before exchanging it with that of the generated
	renaming declaration.
	(Freeze_Enumeration_Type): Don't raise CE if No_Exception_Propagation
	active, because there is no way to handle the exception.
	(Freeze_Record_Type): In case of CPP_Class types add a call to Make_DT
	to do a minimum decoration of the Access_Disp_Table list.
	(Expand_Record_Controller): Avoid the addition of the controller between
	the component containing the tag of a secondary dispatch table and its
	adjacent component that stores the offset to the base of the object.
	This latter component is only generated when the parent type has
	discriminants ---documented in Add_Interface_Tag_Components).
	(Apply_Array_Size_Check): Removed, no longer needed.
	(Expand_N_Full_Type_Declaration): If the type has anonymous access
	components, create a Master_Entity for it only if it contains tasks.
	(Build_Init_Procedure): Suppress the tag assignment compiling under
	no run-time mode.
	(Freeze_Record_Type): Remove code associated with creation of dispatch
	table.
	(Init_Secondary_Tags): Update type of actuals when generating calls to
	Ada.Tags.Set_Offset_To_Top
	(Stream_Operation_OK): Disable use of streams compiling under no
	run-time mode
	(Expand_N_Object_Declaration): Don't do Initialize_Scalars initalization
	if Has_Init_Expression set.
	(Build_Init_Procedure): Replace call to Fill_DT_Entry by call to
	Register_Primitive, which provides the same functionality.
	(Requires_Init_Proc): Return false in case of interface types.
	(Add_Secondary_Tables): Use the new attribute Related_Interface to
	cleanup the code.
	(Predefined_Primitive_Freeze): Do not assume that an internal entity
	is always associated with a predefined primitive because the internal
	entities associated with interface types are not predefined primitives.
	Therefore, the call to Is_Internal is replaced by a call to the
	function Is_Predefined_Dispatching_Operation.
	(Make_Eq_If): When generating the list of comparisons for the
	components of a given variant, omit the controller component that is
	present if the variant has controlled components.

From-SVN: r125396
parent 822033eb
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 1992-2006, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -42,8 +42,8 @@ with Exp_Strm; use Exp_Strm; ...@@ -42,8 +42,8 @@ with Exp_Strm; use Exp_Strm;
with Exp_Tss; use Exp_Tss; with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util; with Exp_Util; use Exp_Util;
with Freeze; use Freeze; with Freeze; use Freeze;
with Hostparm; use Hostparm;
with Nlists; use Nlists; with Nlists; use Nlists;
with Namet; use Namet;
with Nmake; use Nmake; with Nmake; use Nmake;
with Opt; use Opt; with Opt; use Opt;
with Restrict; use Restrict; with Restrict; use Restrict;
...@@ -62,6 +62,7 @@ with Sem_Util; use Sem_Util; ...@@ -62,6 +62,7 @@ with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo; with Sinfo; use Sinfo;
with Stand; use Stand; with Stand; use Stand;
with Snames; use Snames; with Snames; use Snames;
with Targparm; use Targparm;
with Tbuild; use Tbuild; with Tbuild; use Tbuild;
with Ttypes; use Ttypes; with Ttypes; use Ttypes;
with Validsw; use Validsw; with Validsw; use Validsw;
...@@ -92,6 +93,22 @@ package body Exp_Ch3 is ...@@ -92,6 +93,22 @@ package body Exp_Ch3 is
-- of the type. Otherwise new identifiers are created, with the source -- of the type. Otherwise new identifiers are created, with the source
-- names of the discriminants. -- names of the discriminants.
function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id;
-- This function builds a static aggregate that can serve as the initial
-- value for an array type whose bounds are static, and whose component
-- type is a composite type that has a static equivalent aggregate.
-- The equivalent array aggregate is used both for object initialization
-- and for component initialization, when used in the following function.
function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id;
-- This function builds a static aggregate that can serve as the initial
-- value for a record type whose components are scalar and initialized
-- with compile-time values, or arrays with similarc initialization or
-- defaults. When possible, initialization of an object of the type can
-- be achieved by using a copy of the aggregate as an initial value, thus
-- removing the implicit call that would otherwise constitute elaboration
-- code.
function Build_Master_Renaming function Build_Master_Renaming
(N : Node_Id; (N : Node_Id;
T : Entity_Id) return Entity_Id; T : Entity_Id) return Entity_Id;
...@@ -121,10 +138,10 @@ package body Exp_Ch3 is ...@@ -121,10 +138,10 @@ package body Exp_Ch3 is
-- and attach it to the TSS list -- and attach it to the TSS list
procedure Check_Stream_Attributes (Typ : Entity_Id); procedure Check_Stream_Attributes (Typ : Entity_Id);
-- Check that if a limited extension has a parent with user-defined -- Check that if a limited extension has a parent with user-defined stream
-- stream attributes, and does not itself have user-definer -- attributes, and does not itself have user-defined stream-attributes,
-- stream-attributes, then any limited component of the extension also -- then any limited component of the extension also has the corresponding
-- has the corresponding user-defined stream attributes. -- user-defined stream attributes.
procedure Clean_Task_Names procedure Clean_Task_Names
(Typ : Entity_Id; (Typ : Entity_Id;
...@@ -167,6 +184,12 @@ package body Exp_Ch3 is ...@@ -167,6 +184,12 @@ package body Exp_Ch3 is
-- Treat user-defined stream operations as renaming_as_body if the -- Treat user-defined stream operations as renaming_as_body if the
-- subprogram they rename is not frozen when the type is frozen. -- subprogram they rename is not frozen when the type is frozen.
procedure Initialization_Warning (E : Entity_Id);
-- If static elaboration of the package is requested, indicate
-- when a type does meet the conditions for static initialization. If
-- E is a type, it has components that have no static initialization.
-- if E is an entity, its initial expression is not compile-time known.
function Init_Formals (Typ : Entity_Id) return List_Id; function Init_Formals (Typ : Entity_Id) return List_Id;
-- This function builds the list of formals for an initialization routine. -- This function builds the list of formals for an initialization routine.
-- The first formal is always _Init with the given type. For task value -- The first formal is always _Init with the given type. For task value
...@@ -187,23 +210,23 @@ package body Exp_Ch3 is ...@@ -187,23 +210,23 @@ package body Exp_Ch3 is
(E : Entity_Id; (E : Entity_Id;
CL : Node_Id; CL : Node_Id;
Discr : Entity_Id := Empty) return List_Id; Discr : Entity_Id := Empty) return List_Id;
-- Building block for variant record equality. Defined to share the -- Building block for variant record equality. Defined to share the code
-- code between the tagged and non-tagged case. Given a Component_List -- between the tagged and non-tagged case. Given a Component_List node CL,
-- node CL, it generates an 'if' followed by a 'case' statement that -- it generates an 'if' followed by a 'case' statement that compares all
-- compares all components of local temporaries named X and Y (that -- components of local temporaries named X and Y (that are declared as
-- are declared as formals at some upper level). E provides the Sloc to be -- formals at some upper level). E provides the Sloc to be used for the
-- used for the generated code. Discr is used as the case statement switch -- generated code. Discr is used as the case statement switch in the case
-- in the case of Unchecked_Union equality. -- of Unchecked_Union equality.
function Make_Eq_If function Make_Eq_If
(E : Entity_Id; (E : Entity_Id;
L : List_Id) return Node_Id; L : List_Id) return Node_Id;
-- Building block for variant record equality. Defined to share the -- Building block for variant record equality. Defined to share the code
-- code between the tagged and non-tagged case. Given the list of -- between the tagged and non-tagged case. Given the list of components
-- components (or discriminants) L, it generates a return statement -- (or discriminants) L, it generates a return statement that compares all
-- that compares all components of local temporaries named X and Y -- components of local temporaries named X and Y (that are declared as
-- (that are declared as formals at some upper level). E provides the Sloc -- formals at some upper level). E provides the Sloc to be used for the
-- to be used for the generated code. -- generated code.
procedure Make_Predefined_Primitive_Specs procedure Make_Predefined_Primitive_Specs
(Tag_Typ : Entity_Id; (Tag_Typ : Entity_Id;
...@@ -222,32 +245,31 @@ package body Exp_Ch3 is ...@@ -222,32 +245,31 @@ package body Exp_Ch3 is
-- typSI provides result of 'Input attribute -- typSI provides result of 'Input attribute
-- typSO provides result of 'Output attribute -- typSO provides result of 'Output attribute
-- --
-- The following entries are additionally present for non-limited -- The following entries are additionally present for non-limited tagged
-- tagged types, and implement additional dispatching operations -- types, and implement additional dispatching operations for predefined
-- for predefined operations: -- operations:
-- --
-- _equality implements "=" operator -- _equality implements "=" operator
-- _assign implements assignment operation -- _assign implements assignment operation
-- typDF implements deep finalization -- typDF implements deep finalization
-- typDA implements deep adust -- typDA implements deep adjust
-- --
-- The latter two are empty procedures unless the type contains some -- The latter two are empty procedures unless the type contains some
-- controlled components that require finalization actions (the deep -- controlled components that require finalization actions (the deep
-- in the name refers to the fact that the action applies to components). -- in the name refers to the fact that the action applies to components).
-- --
-- The list is returned in Predef_List. The Parameter Renamed_Eq -- The list is returned in Predef_List. The Parameter Renamed_Eq either
-- either returns the value Empty, or else the defining unit name -- returns the value Empty, or else the defining unit name for the
-- for the predefined equality function in the case where the type -- predefined equality function in the case where the type has a primitive
-- has a primitive operation that is a renaming of predefined equality -- operation that is a renaming of predefined equality (but only if there
-- (but only if there is also an overriding user-defined equality -- is also an overriding user-defined equality function). The returned
-- function). The returned Renamed_Eq will be passed to the -- Renamed_Eq will be passed to the corresponding parameter of
-- corresponding parameter of Predefined_Primitive_Bodies. -- Predefined_Primitive_Bodies.
function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean; function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
-- returns True if there are representation clauses for type T that -- returns True if there are representation clauses for type T that are not
-- are not inherited. If the result is false, the init_proc and the -- inherited. If the result is false, the init_proc and the discriminant
-- discriminant_checking functions of the parent can be reused by -- checking functions of the parent can be reused by a derived type.
-- a derived type.
procedure Make_Controlling_Function_Wrappers procedure Make_Controlling_Function_Wrappers
(Tag_Typ : Entity_Id; (Tag_Typ : Entity_Id;
...@@ -308,7 +330,7 @@ package body Exp_Ch3 is ...@@ -308,7 +330,7 @@ package body Exp_Ch3 is
function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id; function Predefined_Primitive_Freeze (Tag_Typ : Entity_Id) return List_Id;
-- Freeze entities of all predefined primitive operations. This is needed -- Freeze entities of all predefined primitive operations. This is needed
-- because the bodies of these operations do not normally do any freezeing. -- because the bodies of these operations do not normally do any freezing.
function Stream_Operation_OK function Stream_Operation_OK
(Typ : Entity_Id; (Typ : Entity_Id;
...@@ -323,12 +345,12 @@ package body Exp_Ch3 is ...@@ -323,12 +345,12 @@ package body Exp_Ch3 is
-- Adjust_Discriminants -- -- Adjust_Discriminants --
-------------------------- --------------------------
-- This procedure attempts to define subtypes for discriminants that -- This procedure attempts to define subtypes for discriminants that are
-- are more restrictive than those declared. Such a replacement is -- more restrictive than those declared. Such a replacement is possible if
-- possible if we can demonstrate that values outside the restricted -- we can demonstrate that values outside the restricted range would cause
-- range would cause constraint errors in any case. The advantage of -- constraint errors in any case. The advantage of restricting the
-- restricting the discriminant types in this way is tha the maximum -- discriminant types in this way is that the maximum size of the variant
-- size of the variant record can be calculated more conservatively. -- record can be calculated more conservatively.
-- An example of a situation in which we can perform this type of -- An example of a situation in which we can perform this type of
-- restriction is the following: -- restriction is the following:
...@@ -581,7 +603,7 @@ package body Exp_Ch3 is ...@@ -581,7 +603,7 @@ package body Exp_Ch3 is
-- Start of processing for Build_Array_Init_Proc -- Start of processing for Build_Array_Init_Proc
begin begin
if Suppress_Init_Proc (A_Type) then if Suppress_Init_Proc (A_Type) or else Is_Value_Type (Comp_Type) then
return; return;
end if; end if;
...@@ -592,7 +614,7 @@ package body Exp_Ch3 is ...@@ -592,7 +614,7 @@ package body Exp_Ch3 is
-- 1. The component type has an initialization procedure -- 1. The component type has an initialization procedure
-- 2. The component type needs simple initialization -- 2. The component type needs simple initialization
-- 3. Tasks are present -- 3. Tasks are present
-- 4. The type is marked as a publc entity -- 4. The type is marked as a public entity
-- The reason for the public entity test is to deal properly with the -- The reason for the public entity test is to deal properly with the
-- Initialize_Scalars pragma. This pragma can be set in the client and -- Initialize_Scalars pragma. This pragma can be set in the client and
...@@ -644,7 +666,7 @@ package body Exp_Ch3 is ...@@ -644,7 +666,7 @@ package body Exp_Ch3 is
-- Set inlined unless controlled stuff or tasks around, in which -- Set inlined unless controlled stuff or tasks around, in which
-- case we do not want to inline, because nested stuff may cause -- case we do not want to inline, because nested stuff may cause
-- difficulties in interunit inlining, and furthermore there is -- difficulties in inter-unit inlining, and furthermore there is
-- in any case no point in inlining such complex init procs. -- in any case no point in inlining such complex init procs.
if not Has_Task (Proc_Id) if not Has_Task (Proc_Id)
...@@ -666,6 +688,15 @@ package body Exp_Ch3 is ...@@ -666,6 +688,15 @@ package body Exp_Ch3 is
and then Nkind (First (Body_Stmts)) = N_Null_Statement and then Nkind (First (Body_Stmts)) = N_Null_Statement
then then
Set_Is_Null_Init_Proc (Proc_Id); Set_Is_Null_Init_Proc (Proc_Id);
else
-- Try to build a static aggregate to initialize statically
-- objects of the type. This can only be done for constrained
-- one-dimensional arrays with static bounds.
Set_Static_Initialization
(Proc_Id,
Build_Equivalent_Array_Aggregate (First_Subtype (A_Type)));
end if; end if;
end if; end if;
end Build_Array_Init_Proc; end Build_Array_Init_Proc;
...@@ -688,9 +719,9 @@ package body Exp_Ch3 is ...@@ -688,9 +719,9 @@ package body Exp_Ch3 is
return; return;
end if; end if;
-- Find declaration that created the access type: either a -- Find declaration that created the access type: either a type
-- type declaration, or an object declaration with an -- declaration, or an object declaration with an access definition,
-- access definition, in which case the type is anonymous. -- in which case the type is anonymous.
if Is_Itype (T) then if Is_Itype (T) then
P := Associated_Node_For_Itype (T); P := Associated_Node_For_Itype (T);
...@@ -702,9 +733,9 @@ package body Exp_Ch3 is ...@@ -702,9 +733,9 @@ package body Exp_Ch3 is
if not Has_Master_Entity (Scope (T)) then if not Has_Master_Entity (Scope (T)) then
-- first build the master entity -- First build the master entity
-- _Master : constant Master_Id := Current_Master.all; -- _Master : constant Master_Id := Current_Master.all;
-- and insert it just before the current declaration -- and insert it just before the current declaration.
Decl := Decl :=
Make_Object_Declaration (Loc, Make_Object_Declaration (Loc,
...@@ -716,7 +747,7 @@ package body Exp_Ch3 is ...@@ -716,7 +747,7 @@ package body Exp_Ch3 is
Make_Explicit_Dereference (Loc, Make_Explicit_Dereference (Loc,
New_Reference_To (RTE (RE_Current_Master), Loc))); New_Reference_To (RTE (RE_Current_Master), Loc)));
Insert_Before (P, Decl); Insert_Action (P, Decl);
Analyze (Decl); Analyze (Decl);
Set_Has_Master_Entity (Scope (T)); Set_Has_Master_Entity (Scope (T));
...@@ -775,12 +806,12 @@ package body Exp_Ch3 is ...@@ -775,12 +806,12 @@ package body Exp_Ch3 is
function Build_Case_Statement function Build_Case_Statement
(Case_Id : Entity_Id; (Case_Id : Entity_Id;
Variant : Node_Id) return Node_Id; Variant : Node_Id) return Node_Id;
-- Build a case statement containing only two alternatives. The -- Build a case statement containing only two alternatives. The first
-- first alternative corresponds exactly to the discrete choices -- alternative corresponds exactly to the discrete choices given on the
-- given on the variant with contains the components that we are -- variant with contains the components that we are generating the
-- generating the checks for. If the discriminant is one of these -- checks for. If the discriminant is one of these return False. The
-- return False. The second alternative is an OTHERS choice that -- second alternative is an OTHERS choice that will return True
-- will return True indicating the discriminant did not match. -- indicating the discriminant did not match.
function Build_Dcheck_Function function Build_Dcheck_Function
(Case_Id : Entity_Id; (Case_Id : Entity_Id;
...@@ -811,8 +842,8 @@ package body Exp_Ch3 is ...@@ -811,8 +842,8 @@ package body Exp_Ch3 is
begin begin
Case_Node := New_Node (N_Case_Statement, Loc); Case_Node := New_Node (N_Case_Statement, Loc);
-- Replace the discriminant which controls the variant, with the -- Replace the discriminant which controls the variant, with the name
-- name of the formal of the checking function. -- of the formal of the checking function.
Set_Expression (Case_Node, Set_Expression (Case_Node,
Make_Identifier (Loc, Chars (Case_Id))); Make_Identifier (Loc, Chars (Case_Id)));
...@@ -1054,25 +1085,194 @@ package body Exp_Ch3 is ...@@ -1054,25 +1085,194 @@ package body Exp_Ch3 is
return Parameter_List; return Parameter_List;
end Build_Discriminant_Formals; end Build_Discriminant_Formals;
--------------------------------------
-- Build_Equivalent_Array_Aggregate --
--------------------------------------
function Build_Equivalent_Array_Aggregate (T : Entity_Id) return Node_Id is
Loc : constant Source_Ptr := Sloc (T);
Comp_Type : constant Entity_Id := Component_Type (T);
Index_Type : constant Entity_Id := Etype (First_Index (T));
Proc : constant Entity_Id := Base_Init_Proc (T);
Lo, Hi : Node_Id;
Aggr : Node_Id;
Expr : Node_Id;
begin
if not Is_Constrained (T)
or else Number_Dimensions (T) > 1
or else No (Proc)
then
Initialization_Warning (T);
return Empty;
end if;
Lo := Type_Low_Bound (Index_Type);
Hi := Type_High_Bound (Index_Type);
if not Compile_Time_Known_Value (Lo)
or else not Compile_Time_Known_Value (Hi)
then
Initialization_Warning (T);
return Empty;
end if;
if Is_Record_Type (Comp_Type)
and then Present (Base_Init_Proc (Comp_Type))
then
Expr := Static_Initialization (Base_Init_Proc (Comp_Type));
if No (Expr) then
Initialization_Warning (T);
return Empty;
end if;
else
Initialization_Warning (T);
return Empty;
end if;
Aggr := Make_Aggregate (Loc, No_List, New_List);
Set_Etype (Aggr, T);
Set_Aggregate_Bounds (Aggr,
Make_Range (Loc,
Low_Bound => New_Copy (Lo),
High_Bound => New_Copy (Hi)));
Set_Parent (Aggr, Parent (Proc));
Append_To (Component_Associations (Aggr),
Make_Component_Association (Loc,
Choices =>
New_List (
Make_Range (Loc,
Low_Bound => New_Copy (Lo),
High_Bound => New_Copy (Hi))),
Expression => Expr));
if Static_Array_Aggregate (Aggr) then
return Aggr;
else
Initialization_Warning (T);
return Empty;
end if;
end Build_Equivalent_Array_Aggregate;
---------------------------------------
-- Build_Equivalent_Record_Aggregate --
---------------------------------------
function Build_Equivalent_Record_Aggregate (T : Entity_Id) return Node_Id is
Agg : Node_Id;
Comp : Entity_Id;
-- Start of processing for Build_Equivalent_Record_Aggregate
begin
if not Is_Record_Type (T)
or else Has_Discriminants (T)
or else Is_Limited_Type (T)
or else Has_Non_Standard_Rep (T)
then
Initialization_Warning (T);
return Empty;
end if;
Comp := First_Component (T);
-- A null record needs no warning
if No (Comp) then
return Empty;
end if;
while Present (Comp) loop
-- Array components are acceptable if initialized by a positional
-- aggregate with static components.
if Is_Array_Type (Etype (Comp)) then
declare
Comp_Type : constant Entity_Id := Component_Type (Etype (Comp));
begin
if Nkind (Parent (Comp)) /= N_Component_Declaration
or else No (Expression (Parent (Comp)))
or else Nkind (Expression (Parent (Comp))) /= N_Aggregate
then
Initialization_Warning (T);
return Empty;
elsif Is_Scalar_Type (Component_Type (Etype (Comp)))
and then
(not Compile_Time_Known_Value (Type_Low_Bound (Comp_Type))
or else not Compile_Time_Known_Value
(Type_High_Bound (Comp_Type)))
then
Initialization_Warning (T);
return Empty;
elsif
not Static_Array_Aggregate (Expression (Parent (Comp)))
then
Initialization_Warning (T);
return Empty;
end if;
end;
elsif Is_Scalar_Type (Etype (Comp)) then
if Nkind (Parent (Comp)) /= N_Component_Declaration
or else No (Expression (Parent (Comp)))
or else not Compile_Time_Known_Value (Expression (Parent (Comp)))
then
Initialization_Warning (T);
return Empty;
end if;
-- For now, other types are excluded
else
Initialization_Warning (T);
return Empty;
end if;
Next_Component (Comp);
end loop;
-- All components have static initialization. Build positional
-- aggregate from the given expressions or defaults.
Agg := Make_Aggregate (Sloc (T), New_List, New_List);
Set_Parent (Agg, Parent (T));
Comp := First_Component (T);
while Present (Comp) loop
Append
(New_Copy_Tree (Expression (Parent (Comp))), Expressions (Agg));
Next_Component (Comp);
end loop;
Analyze_And_Resolve (Agg, T);
return Agg;
end Build_Equivalent_Record_Aggregate;
------------------------------- -------------------------------
-- Build_Initialization_Call -- -- Build_Initialization_Call --
------------------------------- -------------------------------
-- References to a discriminant inside the record type declaration -- References to a discriminant inside the record type declaration can
-- can appear either in the subtype_indication to constrain a -- appear either in the subtype_indication to constrain a record or an
-- record or an array, or as part of a larger expression given for -- array, or as part of a larger expression given for the initial value
-- the initial value of a component. In both of these cases N appears -- of a component. In both of these cases N appears in the record
-- in the record initialization procedure and needs to be replaced by -- initialization procedure and needs to be replaced by the formal
-- the formal parameter of the initialization procedure which -- parameter of the initialization procedure which corresponds to that
-- corresponds to that discriminant. -- discriminant.
-- In the example below, references to discriminants D1 and D2 in proc_1 -- In the example below, references to discriminants D1 and D2 in proc_1
-- are replaced by references to formals with the same name -- are replaced by references to formals with the same name
-- (discriminals) -- (discriminals)
-- A similar replacement is done for calls to any record -- A similar replacement is done for calls to any record initialization
-- initialization procedure for any components that are themselves -- procedure for any components that are themselves of a record type.
-- of a record type.
-- type R (D1, D2 : Integer) is record -- type R (D1, D2 : Integer) is record
-- X : Integer := F * D1; -- X : Integer := F * D1;
...@@ -1113,8 +1313,12 @@ package body Exp_Ch3 is ...@@ -1113,8 +1313,12 @@ package body Exp_Ch3 is
-- Nothing to do if the Init_Proc is null, unless Initialize_Scalars -- Nothing to do if the Init_Proc is null, unless Initialize_Scalars
-- is active (in which case we make the call anyway, since in the -- is active (in which case we make the call anyway, since in the
-- actual compiled client it may be non null). -- actual compiled client it may be non null).
-- Also nothing to do for value types.
if Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars then if (Is_Null_Init_Proc (Proc) and then not Init_Or_Norm_Scalars)
or else Is_Value_Type (Typ)
or else Is_Value_Type (Component_Type (Typ))
then
return Empty_List; return Empty_List;
end if; end if;
...@@ -1199,9 +1403,9 @@ package body Exp_Ch3 is ...@@ -1199,9 +1403,9 @@ package body Exp_Ch3 is
while Present (Discr) loop while Present (Discr) loop
-- If this is a discriminated concurrent type, the init_proc -- If this is a discriminated concurrent type, the init_proc
-- for the corresponding record is being called. Use that -- for the corresponding record is being called. Use that type
-- type directly to find the discriminant value, to handle -- directly to find the discriminant value, to handle properly
-- properly intervening renamed discriminants. -- intervening renamed discriminants.
declare declare
T : Entity_Id := Full_Type; T : Entity_Id := Full_Type;
...@@ -1248,11 +1452,10 @@ package body Exp_Ch3 is ...@@ -1248,11 +1452,10 @@ package body Exp_Ch3 is
Prefix => New_Copy (Prefix (Id_Ref)), Prefix => New_Copy (Prefix (Id_Ref)),
Attribute_Name => Name_Unrestricted_Access); Attribute_Name => Name_Unrestricted_Access);
-- Otherwise make a copy of the default expression. Note -- Otherwise make a copy of the default expression. Note that
-- that we use the current Sloc for this, because we do not -- we use the current Sloc for this, because we do not want the
-- want the call to appear to be at the declaration point. -- call to appear to be at the declaration point. Within the
-- Within the expression, replace discriminants with their -- expression, replace discriminants with their discriminals.
-- discriminals.
else else
Arg := Arg :=
...@@ -1263,9 +1466,9 @@ package body Exp_Ch3 is ...@@ -1263,9 +1466,9 @@ package body Exp_Ch3 is
if Is_Constrained (Full_Type) then if Is_Constrained (Full_Type) then
Arg := Duplicate_Subexpr_No_Checks (Arg); Arg := Duplicate_Subexpr_No_Checks (Arg);
else else
-- The constraints come from the discriminant default -- The constraints come from the discriminant default exps,
-- exps, they must be reevaluated, so we use New_Copy_Tree -- they must be reevaluated, so we use New_Copy_Tree but we
-- but we ensure the proper Sloc (for any embedded calls). -- ensure the proper Sloc (for any embedded calls).
Arg := New_Copy_Tree (Arg, New_Sloc => Loc); Arg := New_Copy_Tree (Arg, New_Sloc => Loc);
end if; end if;
...@@ -1324,6 +1527,7 @@ package body Exp_Ch3 is ...@@ -1324,6 +1527,7 @@ package body Exp_Ch3 is
-- If the enclosing type is an extension with new controlled -- If the enclosing type is an extension with new controlled
-- components, it has his own record controller. If the parent -- components, it has his own record controller. If the parent
-- also had a record controller, attach it to the new one. -- also had a record controller, attach it to the new one.
-- Build_Init_Statements relies on the fact that in this specific -- Build_Init_Statements relies on the fact that in this specific
-- case the last statement of the result is the attach call to -- case the last statement of the result is the attach call to
-- the controller. If this is changed, it must be synchronized. -- the controller. If this is changed, it must be synchronized.
...@@ -1428,11 +1632,11 @@ package body Exp_Ch3 is ...@@ -1428,11 +1632,11 @@ package body Exp_Ch3 is
Set_Tag : Entity_Id := Empty; Set_Tag : Entity_Id := Empty;
function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id; function Build_Assignment (Id : Entity_Id; N : Node_Id) return List_Id;
-- Build a assignment statement node which assigns to record -- Build a assignment statement node which assigns to record component
-- component its default expression if defined. The left hand side -- its default expression if defined. The assignment left hand side is
-- of the assignment is marked Assignment_OK so that initialization -- marked Assignment_OK so that initialization of limited private
-- of limited private records works correctly, Return also the -- records works correctly, Return also the adjustment call for
-- adjustment call for controlled objects -- controlled objects
procedure Build_Discriminant_Assignments (Statement_List : List_Id); procedure Build_Discriminant_Assignments (Statement_List : List_Id);
-- If the record has discriminants, adds assignment statements to -- If the record has discriminants, adds assignment statements to
...@@ -1472,7 +1676,7 @@ package body Exp_Ch3 is ...@@ -1472,7 +1676,7 @@ package body Exp_Ch3 is
-- parent of a type with discriminants has secondary dispatch tables. -- parent of a type with discriminants has secondary dispatch tables.
procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id); procedure Build_Record_Checks (S : Node_Id; Check_List : List_Id);
-- Add range checks to components of disciminated records. S is a -- Add range checks to components of discriminated records. S is a
-- subtype indication of a record component. Check_List is a list -- subtype indication of a record component. Check_List is a list
-- to which the check actions are appended. -- to which the check actions are appended.
...@@ -1480,10 +1684,10 @@ package body Exp_Ch3 is ...@@ -1480,10 +1684,10 @@ package body Exp_Ch3 is
(T : Entity_Id) return Boolean; (T : Entity_Id) return Boolean;
-- Determines if a component needs simple initialization, given its type -- Determines if a component needs simple initialization, given its type
-- T. This is the same as Needs_Simple_Initialization except for the -- T. This is the same as Needs_Simple_Initialization except for the
-- following difference: the types Tag, Interface_Tag, and Vtable_Ptr -- following difference: the types Tag and Interface_Tag, that are
-- which are access types which would normally require simple -- access types which would normally require simple initialization to
-- initialization to null, do not require initialization as components, -- null, do not require initialization as components, since they are
-- since they are explicitly initialized by other means. -- explicitly initialized by other means.
procedure Constrain_Array procedure Constrain_Array
(SI : Node_Id; (SI : Node_Id;
...@@ -1497,12 +1701,12 @@ package body Exp_Ch3 is ...@@ -1497,12 +1701,12 @@ package body Exp_Ch3 is
(Index : Node_Id; (Index : Node_Id;
S : Node_Id; S : Node_Id;
Check_List : List_Id); Check_List : List_Id);
-- Called from Build_Record_Checks.
-- Process an index constraint in a constrained array declaration. -- Process an index constraint in a constrained array declaration.
-- The constraint can be a subtype name, or a range with or without -- The constraint can be a subtype name, or a range with or without
-- an explicit subtype mark. The index is the corresponding index of the -- an explicit subtype mark. The index is the corresponding index of the
-- unconstrained array. S is the range expression. Check_List is a list -- unconstrained array. S is the range expression. Check_List is a list
-- to which the check actions are appended. -- to which the check actions are appended (called from
-- Build_Record_Checks).
function Parent_Subtype_Renaming_Discrims return Boolean; function Parent_Subtype_Renaming_Discrims return Boolean;
-- Returns True for base types N that rename discriminants, else False -- Returns True for base types N that rename discriminants, else False
...@@ -1570,9 +1774,9 @@ package body Exp_Ch3 is ...@@ -1570,9 +1774,9 @@ package body Exp_Ch3 is
end if; end if;
end if; end if;
-- Take a copy of Exp to ensure that later copies of this -- Take a copy of Exp to ensure that later copies of this component
-- component_declaration in derived types see the original tree, -- declaration in derived types see the original tree, not a node
-- not a node rewritten during expansion of the init_proc. -- rewritten during expansion of the init_proc.
Exp := New_Copy_Tree (Exp); Exp := New_Copy_Tree (Exp);
...@@ -1584,10 +1788,10 @@ package body Exp_Ch3 is ...@@ -1584,10 +1788,10 @@ package body Exp_Ch3 is
Set_No_Ctrl_Actions (First (Res)); Set_No_Ctrl_Actions (First (Res));
-- Adjust the tag if tagged (because of possible view conversions). -- Adjust the tag if tagged (because of possible view conversions).
-- Suppress the tag adjustment when Java_VM because JVM tags are -- Suppress the tag adjustment when VM_Target because VM tags are
-- represented implicitly in objects. -- represented implicitly in objects.
if Is_Tagged_Type (Typ) and then not Java_VM then if Is_Tagged_Type (Typ) and then VM_Target = No_VM then
Append_To (Res, Append_To (Res,
Make_Assignment_Statement (Loc, Make_Assignment_Statement (Loc,
Name => Name =>
...@@ -1602,8 +1806,8 @@ package body Exp_Ch3 is ...@@ -1602,8 +1806,8 @@ package body Exp_Ch3 is
(Node (First_Elmt (Access_Disp_Table (Typ))), Loc)))); (Node (First_Elmt (Access_Disp_Table (Typ))), Loc))));
end if; end if;
-- Adjust the component if controlled except if it is an -- Adjust the component if controlled except if it is an aggregate
-- aggregate that will be expanded inline -- that will be expanded inline
if Kind = N_Qualified_Expression then if Kind = N_Qualified_Expression then
Kind := Nkind (Expression (N)); Kind := Nkind (Expression (N));
...@@ -1611,6 +1815,7 @@ package body Exp_Ch3 is ...@@ -1611,6 +1815,7 @@ package body Exp_Ch3 is
if Controlled_Type (Typ) if Controlled_Type (Typ)
and then not (Kind = N_Aggregate or else Kind = N_Extension_Aggregate) and then not (Kind = N_Aggregate or else Kind = N_Extension_Aggregate)
and then not Is_Inherently_Limited_Type (Typ)
then then
Append_List_To (Res, Append_List_To (Res,
Make_Adjust_Call ( Make_Adjust_Call (
...@@ -1839,8 +2044,9 @@ package body Exp_Ch3 is ...@@ -1839,8 +2044,9 @@ package body Exp_Ch3 is
if Typ = Rec_Type then if Typ = Rec_Type then
Body_Node := New_Node (N_Subprogram_Body, Loc); Body_Node := New_Node (N_Subprogram_Body, Loc);
Func_Id := Make_Defining_Identifier (Loc, Func_Id :=
New_Internal_Name ('F')); Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('F'));
Set_DT_Offset_To_Top_Func (E, Func_Id); Set_DT_Offset_To_Top_Func (E, Func_Id);
...@@ -1908,9 +2114,8 @@ package body Exp_Ch3 is ...@@ -1908,9 +2114,8 @@ package body Exp_Ch3 is
return; return;
end if; end if;
-- Skip the first _Tag, which is the main tag of the -- Skip the first _Tag, which is the main tag of the tagged type.
-- tagged type. Following tags correspond with abstract -- Following tags correspond with abstract interfaces.
-- interfaces.
ADT := Next_Elmt (First_Elmt (Access_Disp_Table (Rec_Type))); ADT := Next_Elmt (First_Elmt (Access_Disp_Table (Rec_Type)));
...@@ -1961,7 +2166,8 @@ package body Exp_Ch3 is ...@@ -1961,7 +2166,8 @@ package body Exp_Ch3 is
and then not Is_CPP_Class (Rec_Type) and then not Is_CPP_Class (Rec_Type)
then then
Set_Tag := Set_Tag :=
Make_Defining_Identifier (Loc, New_Internal_Name ('P')); Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('P'));
Append_To (Parameters, Append_To (Parameters,
Make_Parameter_Specification (Loc, Make_Parameter_Specification (Loc,
...@@ -2021,18 +2227,19 @@ package body Exp_Ch3 is ...@@ -2021,18 +2227,19 @@ package body Exp_Ch3 is
-- Add here the assignment to instantiate the Tag -- Add here the assignment to instantiate the Tag
-- The assignement corresponds to the code: -- The assignment corresponds to the code:
-- _Init._Tag := Typ'Tag; -- _Init._Tag := Typ'Tag;
-- Suppress the tag assignment when Java_VM because JVM tags are -- Suppress the tag assignment when VM_Target because VM tags are
-- represented implicitly in objects. It is also suppressed in -- represented implicitly in objects. It is also suppressed in case
-- case of CPP_Class types because in this case the tag is -- of CPP_Class types because in this case the tag is initialized in
-- initialized in the C++ side. -- the C++ side.
if Is_Tagged_Type (Rec_Type) if Is_Tagged_Type (Rec_Type)
and then not Is_CPP_Class (Rec_Type) and then not Is_CPP_Class (Rec_Type)
and then not Java_VM and then VM_Target = No_VM
and then not No_Run_Time_Mode
then then
Init_Tag := Init_Tag :=
Make_Assignment_Statement (Loc, Make_Assignment_Statement (Loc,
...@@ -2048,10 +2255,11 @@ package body Exp_Ch3 is ...@@ -2048,10 +2255,11 @@ package body Exp_Ch3 is
-- The tag must be inserted before the assignments to other -- The tag must be inserted before the assignments to other
-- components, because the initial value of the component may -- components, because the initial value of the component may
-- depend ot the tag (eg. through a dispatching operation on -- depend on the tag (eg. through a dispatching operation on
-- an access to the current type). The tag assignment is not done -- an access to the current type). The tag assignment is not done
-- when initializing the parent component of a type extension, -- when initializing the parent component of a type extension,
-- because in that case the tag is set in the extension. -- because in that case the tag is set in the extension.
-- Extensions of imported C++ classes add a final complication, -- Extensions of imported C++ classes add a final complication,
-- because we cannot inhibit tag setting in the constructor for -- because we cannot inhibit tag setting in the constructor for
-- the parent. In that case we insert the tag initialization -- the parent. In that case we insert the tag initialization
...@@ -2065,6 +2273,10 @@ package body Exp_Ch3 is ...@@ -2065,6 +2273,10 @@ package body Exp_Ch3 is
Prepend_To (Body_Stmts, Init_Tag); Prepend_To (Body_Stmts, Init_Tag);
-- CPP_Class: In this case the dispatch table of the parent was
-- built in the C++ side and we copy the table of the parent to
-- initialize the new dispatch table.
else else
declare declare
Nod : Node_Id := First (Body_Stmts); Nod : Node_Id := First (Body_Stmts);
...@@ -2110,12 +2322,10 @@ package body Exp_Ch3 is ...@@ -2110,12 +2322,10 @@ package body Exp_Ch3 is
Insert_After (Nod, Init_Tag); Insert_After (Nod, Init_Tag);
-- We have inherited the whole contents of the DT table -- We have inherited table of the parent from the CPP side.
-- from the CPP side. Therefore all our previous initia- -- Now we fill the slots associated with Ada primitives.
-- lization has been lost and we must refill entries -- This needs more work to avoid its execution each time
-- associated with Ada primitives. This needs more work -- an object is initialized???
-- to avoid its execution each time an object is
-- initialized???
declare declare
E : Elmt_Id; E : Elmt_Id;
...@@ -2131,8 +2341,9 @@ package body Exp_Ch3 is ...@@ -2131,8 +2341,9 @@ package body Exp_Ch3 is
and then not Present (Abstract_Interface_Alias and then not Present (Abstract_Interface_Alias
(Prim)) (Prim))
then then
Insert_After (Init_Tag, Register_Primitive (Loc,
Fill_DT_Entry (Loc, Prim)); Prim => Prim,
Ins_Nod => Init_Tag);
end if; end if;
Next_Elmt (E); Next_Elmt (E);
...@@ -2141,11 +2352,13 @@ package body Exp_Ch3 is ...@@ -2141,11 +2352,13 @@ package body Exp_Ch3 is
end; end;
end if; end if;
-- Ada 2005 (AI-251): Initialization of all the tags -- Ada 2005 (AI-251): Initialization of all the tags corresponding
-- corresponding with abstract interfaces -- with abstract interfaces
if Ada_Version >= Ada_05 if VM_Target = No_VM
and then Ada_Version >= Ada_05
and then not Is_Interface (Rec_Type) and then not Is_Interface (Rec_Type)
and then Has_Abstract_Interfaces (Rec_Type)
then then
Init_Secondary_Tags Init_Secondary_Tags
(Typ => Rec_Type, (Typ => Rec_Type,
...@@ -2174,7 +2387,12 @@ package body Exp_Ch3 is ...@@ -2174,7 +2387,12 @@ package body Exp_Ch3 is
if List_Length (Body_Stmts) = 1 if List_Length (Body_Stmts) = 1
and then Nkind (First (Body_Stmts)) = N_Null_Statement and then Nkind (First (Body_Stmts)) = N_Null_Statement
and then VM_Target /= CLI_Target
then then
-- Even though the init proc may be null at this time it might get
-- some stuff added to it later by the CIL backend, so always keep
-- it when VM_Target = CLI_Target.
Set_Is_Null_Init_Proc (Proc_Id); Set_Is_Null_Init_Proc (Proc_Id);
end if; end if;
end Build_Init_Procedure; end Build_Init_Procedure;
...@@ -2309,15 +2527,16 @@ package body Exp_Ch3 is ...@@ -2309,15 +2527,16 @@ package body Exp_Ch3 is
-- the _Parent field is attached to it when the attachment -- the _Parent field is attached to it when the attachment
-- can occur. It does not work to simply initialize the -- can occur. It does not work to simply initialize the
-- controller first: it must be initialized after the parent -- controller first: it must be initialized after the parent
-- if the parent holds discriminants that can be used -- if the parent holds discriminants that can be used to
-- to compute the offset of the controller. We assume here -- compute the offset of the controller. We assume here that
-- that the last statement of the initialization call is the -- the last statement of the initialization call is the
-- attachment of the parent (see Build_Initialization_Call) -- attachment of the parent (see Build_Initialization_Call)
if Chars (Id) = Name_uController if Chars (Id) = Name_uController
and then Rec_Type /= Etype (Rec_Type) and then Rec_Type /= Etype (Rec_Type)
and then Has_Controlled_Component (Etype (Rec_Type)) and then Has_Controlled_Component (Etype (Rec_Type))
and then Has_New_Controlled_Component (Rec_Type) and then Has_New_Controlled_Component (Rec_Type)
and then Present (Last (Statement_List))
then then
Insert_List_Before (Last (Statement_List), Stmts); Insert_List_Before (Last (Statement_List), Stmts);
else else
...@@ -2334,7 +2553,6 @@ package body Exp_Ch3 is ...@@ -2334,7 +2553,6 @@ package body Exp_Ch3 is
-- Second pass: components with per-object constraints -- Second pass: components with per-object constraints
Decl := First_Non_Pragma (Component_Items (Comp_List)); Decl := First_Non_Pragma (Component_Items (Comp_List));
while Present (Decl) loop while Present (Decl) loop
Loc := Sloc (Decl); Loc := Sloc (Decl);
Id := Defining_Identifier (Decl); Id := Defining_Identifier (Decl);
...@@ -2372,7 +2590,6 @@ package body Exp_Ch3 is ...@@ -2372,7 +2590,6 @@ package body Exp_Ch3 is
if Present (Variant_Part (Comp_List)) then if Present (Variant_Part (Comp_List)) then
Alt_List := New_List; Alt_List := New_List;
Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List))); Variant := First_Non_Pragma (Variants (Variant_Part (Comp_List)));
while Present (Variant) loop while Present (Variant) loop
Loc := Sloc (Variant); Loc := Sloc (Variant);
Append_To (Alt_List, Append_To (Alt_List,
...@@ -2381,7 +2598,6 @@ package body Exp_Ch3 is ...@@ -2381,7 +2598,6 @@ package body Exp_Ch3 is
New_Copy_List (Discrete_Choices (Variant)), New_Copy_List (Discrete_Choices (Variant)),
Statements => Statements =>
Build_Init_Statements (Component_List (Variant)))); Build_Init_Statements (Component_List (Variant))));
Next_Non_Pragma (Variant); Next_Non_Pragma (Variant);
end loop; end loop;
...@@ -2623,7 +2839,7 @@ package body Exp_Ch3 is ...@@ -2623,7 +2839,7 @@ package body Exp_Ch3 is
end if; end if;
-- Check if we have done some trivial renaming of the parent -- Check if we have done some trivial renaming of the parent
-- discriminants, i.e. someting like -- discriminants, i.e. something like
-- --
-- type DT (X1,X2: int) is new PT (X1,X2); -- type DT (X1,X2: int) is new PT (X1,X2);
...@@ -2711,6 +2927,9 @@ package body Exp_Ch3 is ...@@ -2711,6 +2927,9 @@ package body Exp_Ch3 is
if Is_CPP_Class (Rec_Id) then if Is_CPP_Class (Rec_Id) then
return False; return False;
elsif Is_Interface (Rec_Id) then
return False;
elsif not Restriction_Active (No_Initialize_Scalars) elsif not Restriction_Active (No_Initialize_Scalars)
and then Is_Public (Rec_Id) and then Is_Public (Rec_Id)
then then
...@@ -2749,6 +2968,10 @@ package body Exp_Ch3 is ...@@ -2749,6 +2968,10 @@ package body Exp_Ch3 is
begin begin
Rec_Type := Defining_Identifier (N); Rec_Type := Defining_Identifier (N);
if Is_Value_Type (Rec_Type) then
return;
end if;
-- This may be full declaration of a private type, in which case -- This may be full declaration of a private type, in which case
-- the visible entity is a record, and the private entity has been -- the visible entity is a record, and the private entity has been
-- exchanged with it in the private part of the current package. -- exchanged with it in the private part of the current package.
...@@ -2824,6 +3047,9 @@ package body Exp_Ch3 is ...@@ -2824,6 +3047,9 @@ package body Exp_Ch3 is
if not Debug_Generated_Code then if not Debug_Generated_Code then
Set_Debug_Info_Off (Proc_Id); Set_Debug_Info_Off (Proc_Id);
end if; end if;
Set_Static_Initialization
(Proc_Id, Build_Equivalent_Record_Aggregate (Rec_Type));
end if; end if;
end Build_Record_Init_Proc; end Build_Record_Init_Proc;
...@@ -2834,9 +3060,10 @@ package body Exp_Ch3 is ...@@ -2834,9 +3060,10 @@ package body Exp_Ch3 is
-- Generates the following subprogram: -- Generates the following subprogram:
-- procedure Assign -- procedure Assign
-- (Source, Target : Array_Type, -- (Source, Target : Array_Type,
-- Left_Lo, Left_Hi, Right_Lo, Right_Hi : Index; -- Left_Lo, Left_Hi : Index;
-- Rev : Boolean) -- Right_Lo, Right_Hi : Index;
-- Rev : Boolean)
-- is -- is
-- Li1 : Index; -- Li1 : Index;
-- Ri1 : Index; -- Ri1 : Index;
...@@ -2851,21 +3078,21 @@ package body Exp_Ch3 is ...@@ -2851,21 +3078,21 @@ package body Exp_Ch3 is
-- end if; -- end if;
-- loop -- loop
-- if Rev then -- if Rev then
-- exit when Li1 < Left_Lo; -- exit when Li1 < Left_Lo;
-- else -- else
-- exit when Li1 > Left_Hi; -- exit when Li1 > Left_Hi;
-- end if; -- end if;
-- Target (Li1) := Source (Ri1); -- Target (Li1) := Source (Ri1);
-- if Rev then -- if Rev then
-- Li1 := Index'pred (Li1); -- Li1 := Index'pred (Li1);
-- Ri1 := Index'pred (Ri1); -- Ri1 := Index'pred (Ri1);
-- else -- else
-- Li1 := Index'succ (Li1); -- Li1 := Index'succ (Li1);
-- Ri1 := Index'succ (Ri1); -- Ri1 := Index'succ (Ri1);
-- end if; -- end if;
-- end loop; -- end loop;
-- end Assign; -- end Assign;
...@@ -3161,11 +3388,12 @@ package body Exp_Ch3 is ...@@ -3161,11 +3388,12 @@ package body Exp_Ch3 is
-- return False; -- return False;
-- end if; -- end if;
-- end case; -- end case;
-- return True; -- return True;
-- end _Equality; -- end _Equality;
procedure Build_Variant_Record_Equality (Typ : Entity_Id) is procedure Build_Variant_Record_Equality (Typ : Entity_Id) is
Loc : constant Source_Ptr := Sloc (Typ); Loc : constant Source_Ptr := Sloc (Typ);
F : constant Entity_Id := F : constant Entity_Id :=
Make_Defining_Identifier (Loc, Make_Defining_Identifier (Loc,
...@@ -3179,9 +3407,9 @@ package body Exp_Ch3 is ...@@ -3179,9 +3407,9 @@ package body Exp_Ch3 is
Make_Defining_Identifier (Loc, Make_Defining_Identifier (Loc,
Chars => Name_Y); Chars => Name_Y);
Def : constant Node_Id := Parent (Typ); Def : constant Node_Id := Parent (Typ);
Comps : constant Node_Id := Component_List (Type_Definition (Def)); Comps : constant Node_Id := Component_List (Type_Definition (Def));
Stmts : constant List_Id := New_List; Stmts : constant List_Id := New_List;
Pspecs : constant List_Id := New_List; Pspecs : constant List_Id := New_List;
begin begin
...@@ -3539,6 +3767,7 @@ package body Exp_Ch3 is ...@@ -3539,6 +3767,7 @@ package body Exp_Ch3 is
-- processing for type Ref. -- processing for type Ref.
and then Convention (Designated_Type (Def_Id)) /= Convention_Java and then Convention (Designated_Type (Def_Id)) /= Convention_Java
and then Convention (Designated_Type (Def_Id)) /= Convention_CIL
then then
Build_Class_Wide_Master (Def_Id); Build_Class_Wide_Master (Def_Id);
end if; end if;
...@@ -3593,7 +3822,7 @@ package body Exp_Ch3 is ...@@ -3593,7 +3822,7 @@ package body Exp_Ch3 is
Next_Entity (Comp); Next_Entity (Comp);
end loop; end loop;
-- If found we add a renaming reclaration of master_id and we -- If found we add a renaming declaration of master_id and we
-- associate it to each anonymous access type component. Do -- associate it to each anonymous access type component. Do
-- nothing if the access type already has a master. This will be -- nothing if the access type already has a master. This will be
-- the case if the array type is the packed array created for a -- the case if the array type is the packed array created for a
...@@ -3601,8 +3830,14 @@ package body Exp_Ch3 is ...@@ -3601,8 +3830,14 @@ package body Exp_Ch3 is
-- expanding the declaration for T. -- expanding the declaration for T.
if Present (Comp) if Present (Comp)
and then Ekind (Typ) = E_Anonymous_Access_Type
and then not Restriction_Active (No_Task_Hierarchy) and then not Restriction_Active (No_Task_Hierarchy)
and then No (Master_Id (Typ)) and then No (Master_Id (Typ))
-- Do not consider run-times with no tasking support
and then RTE_Available (RE_Current_Master)
and then Has_Task (Non_Limited_Designated_Type (Typ))
then then
Build_Master_Entity (Def_Id); Build_Master_Entity (Def_Id);
M_Id := Build_Master_Renaming (N, Def_Id); M_Id := Build_Master_Renaming (N, Def_Id);
...@@ -3692,13 +3927,14 @@ package body Exp_Ch3 is ...@@ -3692,13 +3927,14 @@ package body Exp_Ch3 is
-- For all types, we call an initialization procedure if there is one -- For all types, we call an initialization procedure if there is one
procedure Expand_N_Object_Declaration (N : Node_Id) is procedure Expand_N_Object_Declaration (N : Node_Id) is
Def_Id : constant Entity_Id := Defining_Identifier (N); Def_Id : constant Entity_Id := Defining_Identifier (N);
Expr : constant Node_Id := Expression (N); Expr : constant Node_Id := Expression (N);
Loc : constant Source_Ptr := Sloc (N); Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (Def_Id); Typ : constant Entity_Id := Etype (Def_Id);
Expr_Q : Node_Id; Expr_Q : Node_Id;
Id_Ref : Node_Id; Id_Ref : Node_Id;
New_Ref : Node_Id; New_Ref : Node_Id;
BIP_Call : Boolean := False;
begin begin
-- Don't do anything for deferred constants. All proper actions will -- Don't do anything for deferred constants. All proper actions will
...@@ -3724,6 +3960,16 @@ package body Exp_Ch3 is ...@@ -3724,6 +3960,16 @@ package body Exp_Ch3 is
Build_Master_Entity (Def_Id); Build_Master_Entity (Def_Id);
end if; end if;
-- Build a list controller for declarations of the form
-- Obj : access Some_Type [:= Expression];
if Ekind (Typ) = E_Anonymous_Access_Type
and then Is_Controlled (Directly_Designated_Type (Typ))
and then No (Associated_Final_Chain (Typ))
then
Build_Final_List (N, Typ);
end if;
-- Default initialization required, and no expression present -- Default initialization required, and no expression present
if No (Expr) then if No (Expr) then
...@@ -3799,6 +4045,7 @@ package body Exp_Ch3 is ...@@ -3799,6 +4045,7 @@ package body Exp_Ch3 is
if Has_Non_Null_Base_Init_Proc (Typ) if Has_Non_Null_Base_Init_Proc (Typ)
and then not No_Initialization (N) and then not No_Initialization (N)
and then not Is_Value_Type (Typ)
then then
-- The call to the initialization procedure does NOT freeze the -- The call to the initialization procedure does NOT freeze the
-- object being initialized. This is because the call is not a -- object being initialized. This is because the call is not a
...@@ -3811,19 +4058,34 @@ package body Exp_Ch3 is ...@@ -3811,19 +4058,34 @@ package body Exp_Ch3 is
Set_Must_Not_Freeze (Id_Ref); Set_Must_Not_Freeze (Id_Ref);
Set_Assignment_OK (Id_Ref); Set_Assignment_OK (Id_Ref);
Insert_Actions_After (N, declare
Build_Initialization_Call (Loc, Id_Ref, Typ)); Init_Expr : constant Node_Id :=
Static_Initialization (Base_Init_Proc (Typ));
begin
if Present (Init_Expr) then
Set_Expression
(N, New_Copy_Tree (Init_Expr, New_Scope => Current_Scope));
return;
else
Initialization_Warning (Id_Ref);
Insert_Actions_After (N,
Build_Initialization_Call (Loc, Id_Ref, Typ));
end if;
end;
-- If simple initialization is required, then set an appropriate -- If simple initialization is required, then set an appropriate
-- simple initialization expression in place. This special -- simple initialization expression in place. This special
-- initialization is required even though No_Init_Flag is present. -- initialization is required even though No_Init_Flag is present,
-- but is not needed if there was an explicit initialization.
-- An internally generated temporary needs no initialization because -- An internally generated temporary needs no initialization because
-- it will be assigned subsequently. In particular, there is no point -- it will be assigned subsequently. In particular, there is no point
-- in applying Initialize_Scalars to such a temporary. -- in applying Initialize_Scalars to such a temporary.
elsif Needs_Simple_Initialization (Typ) elsif Needs_Simple_Initialization (Typ)
and then not Is_Internal (Def_Id) and then not Is_Internal (Def_Id)
and then not Has_Init_Expression (N)
then then
Set_No_Initialization (N, False); Set_No_Initialization (N, False);
Set_Expression (N, Get_Simple_Init_Val (Typ, Loc, Esize (Def_Id))); Set_Expression (N, Get_Simple_Init_Val (Typ, Loc, Esize (Def_Id)));
...@@ -3835,6 +4097,7 @@ package body Exp_Ch3 is ...@@ -3835,6 +4097,7 @@ package body Exp_Ch3 is
if Persistent_BSS_Mode if Persistent_BSS_Mode
and then Comes_From_Source (N) and then Comes_From_Source (N)
and then Is_Potentially_Persistent_Type (Typ) and then Is_Potentially_Persistent_Type (Typ)
and then not Has_Init_Expression (N)
and then Is_Library_Level_Entity (Def_Id) and then Is_Library_Level_Entity (Def_Id)
then then
declare declare
...@@ -3878,13 +4141,14 @@ package body Exp_Ch3 is ...@@ -3878,13 +4141,14 @@ package body Exp_Ch3 is
-- call to a build-in-place function, then access to the declared -- call to a build-in-place function, then access to the declared
-- object must be passed to the function. Currently we limit such -- object must be passed to the function. Currently we limit such
-- functions to those with constrained limited result subtypes, -- functions to those with constrained limited result subtypes,
-- but eventually we plan to expand the allowed forms of funtions -- but eventually we plan to expand the allowed forms of functions
-- that are treated as build-in-place. -- that are treated as build-in-place.
if Ada_Version >= Ada_05 if Ada_Version >= Ada_05
and then Is_Build_In_Place_Function_Call (Expr_Q) and then Is_Build_In_Place_Function_Call (Expr_Q)
then then
Make_Build_In_Place_Call_In_Object_Declaration (N, Expr_Q); Make_Build_In_Place_Call_In_Object_Declaration (N, Expr_Q);
BIP_Call := True;
end if; end if;
-- In most cases, we must check that the initial value meets any -- In most cases, we must check that the initial value meets any
...@@ -3937,8 +4201,9 @@ package body Exp_Ch3 is ...@@ -3937,8 +4201,9 @@ package body Exp_Ch3 is
Object_Definition => Object_Definition =>
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
Prefix => Make_Identifier (Loc, Prefix =>
Chars (Root_Type (Etype (Def_Id)))), New_Occurrence_Of
(Root_Type (Etype (Def_Id)), Loc),
Attribute_Name => Name_Class), Attribute_Name => Name_Class),
Expression => Expression =>
...@@ -3966,8 +4231,8 @@ package body Exp_Ch3 is ...@@ -3966,8 +4231,8 @@ package body Exp_Ch3 is
Subtype_Mark => Subtype_Mark =>
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
Prefix => Prefix =>
Make_Identifier (Loc, New_Occurrence_Of
Chars => Chars (Root_Type (Etype (Def_Id)))), (Root_Type (Etype (Def_Id)), Loc),
Attribute_Name => Name_Class), Attribute_Name => Name_Class),
Name => Name =>
...@@ -4003,66 +4268,41 @@ package body Exp_Ch3 is ...@@ -4003,66 +4268,41 @@ package body Exp_Ch3 is
-- correct replacement of the object declaration by this -- correct replacement of the object declaration by this
-- object renaming declaration (because such definings -- object renaming declaration (because such definings
-- identifier have been previously added by Enter_Name to -- identifier have been previously added by Enter_Name to
-- the current scope). -- the current scope). We must preserve the homonym chain
-- of the source entity as well.
Set_Chars (Defining_Identifier (N), Chars (Def_Id)); Set_Chars (Defining_Identifier (N), Chars (Def_Id));
Set_Homonym (Defining_Identifier (N), Homonym (Def_Id));
Exchange_Entities (Defining_Identifier (N), Def_Id); Exchange_Entities (Defining_Identifier (N), Def_Id);
return; return;
end; end;
end if; end if;
-- If the type is controlled we attach the object to the final -- If the type is controlled and not limited then the target is
-- list and adjust the target after the copy. This -- adjusted after the copy and attached to the finalization list.
-- ??? incomplete sentence -- However, no adjustment is done in the case where the object was
-- initialized by a call to a function whose result is built in
if Controlled_Type (Typ) then -- place, since no copy occurred. (We eventually plan to support
declare -- in-place function results for some nonlimited types. ???)
Flist : Node_Id;
F : Entity_Id;
begin
-- Attach the result to a dummy final list which will never
-- be finalized if Delay_Finalize_Attachis set. It is
-- important to attach to a dummy final list rather than not
-- attaching at all in order to reset the pointers coming
-- from the initial value. Equivalent code exists in the
-- sec-stack case in Exp_Ch4.Expand_N_Allocator.
if Delay_Finalize_Attach (N) then
F :=
Make_Defining_Identifier (Loc, New_Internal_Name ('F'));
Insert_Action (N,
Make_Object_Declaration (Loc,
Defining_Identifier => F,
Object_Definition =>
New_Reference_To (RTE (RE_Finalizable_Ptr), Loc)));
Flist := New_Reference_To (F, Loc);
else
Flist := Find_Final_List (Def_Id);
end if;
-- Adjustment is only needed when the controlled type is not if Controlled_Type (Typ)
-- limited. and then not Is_Limited_Type (Typ)
and then not BIP_Call
if not Is_Limited_Type (Typ) then then
Insert_Actions_After (N, Insert_Actions_After (N,
Make_Adjust_Call ( Make_Adjust_Call (
Ref => New_Reference_To (Def_Id, Loc), Ref => New_Reference_To (Def_Id, Loc),
Typ => Base_Type (Typ), Typ => Base_Type (Typ),
Flist_Ref => Flist, Flist_Ref => Find_Final_List (Def_Id),
With_Attach => Make_Integer_Literal (Loc, 1))); With_Attach => Make_Integer_Literal (Loc, 1)));
end if;
end;
end if; end if;
-- For tagged types, when an init value is given, the tag has to -- For tagged types, when an init value is given, the tag has to
-- be re-initialized separately in order to avoid the propagation -- be re-initialized separately in order to avoid the propagation
-- of a wrong tag coming from a view conversion unless the type -- of a wrong tag coming from a view conversion unless the type
-- is class wide (in this case the tag comes from the init value). -- is class wide (in this case the tag comes from the init value).
-- Suppress the tag assignment when Java_VM because JVM tags are -- Suppress the tag assignment when VM_Target because VM tags are
-- represented implicitly in objects. Ditto for types that are -- represented implicitly in objects. Ditto for types that are
-- CPP_CLASS, and for initializations that are aggregates, because -- CPP_CLASS, and for initializations that are aggregates, because
-- they have to have the right tag. -- they have to have the right tag.
...@@ -4070,7 +4310,7 @@ package body Exp_Ch3 is ...@@ -4070,7 +4310,7 @@ package body Exp_Ch3 is
if Is_Tagged_Type (Typ) if Is_Tagged_Type (Typ)
and then not Is_Class_Wide_Type (Typ) and then not Is_Class_Wide_Type (Typ)
and then not Is_CPP_Class (Typ) and then not Is_CPP_Class (Typ)
and then not Java_VM and then VM_Target = No_VM
and then Nkind (Expr) /= N_Aggregate and then Nkind (Expr) /= N_Aggregate
then then
-- The re-assignment of the tag has to be done even if the -- The re-assignment of the tag has to be done even if the
...@@ -4159,13 +4399,6 @@ package body Exp_Ch3 is ...@@ -4159,13 +4399,6 @@ package body Exp_Ch3 is
end if; end if;
end if; end if;
-- For array type, check for size too large
-- We really need this for record types too???
if Is_Array_Type (Typ) then
Apply_Array_Size_Check (N, Typ);
end if;
exception exception
when RE_Not_Available => when RE_Not_Available =>
return; return;
...@@ -4311,15 +4544,25 @@ package body Exp_Ch3 is ...@@ -4311,15 +4544,25 @@ package body Exp_Ch3 is
if not Is_Tagged_Type (T) then if not Is_Tagged_Type (T) then
Insert_Before (First_Comp, Comp_Decl); Insert_Before (First_Comp, Comp_Decl);
-- if T is a tagged type, place controller declaration after -- if T is a tagged type, place controller declaration after parent
-- parent field and after eventual tags of implemented -- field and after eventual tags of interface types.
-- interfaces, if present.
else else
while Present (First_Comp) while Present (First_Comp)
and then and then
(Chars (Defining_Identifier (First_Comp)) = Name_uParent (Chars (Defining_Identifier (First_Comp)) = Name_uParent
or else Is_Tag (Defining_Identifier (First_Comp))) or else Is_Tag (Defining_Identifier (First_Comp))
-- Ada 2005 (AI-251): The following condition covers secondary
-- tags but also the adjacent component contanining the offset
-- to the base of the object (component generated if the parent
-- has discriminants ---see Add_Interface_Tag_Components). This
-- is required to avoid the addition of the controller between
-- the secondary tag and its adjacent component.
or else Present
(Related_Interface
(Defining_Identifier (First_Comp))))
loop loop
Next (First_Comp); Next (First_Comp);
end loop; end loop;
...@@ -4336,7 +4579,7 @@ package body Exp_Ch3 is ...@@ -4336,7 +4579,7 @@ package body Exp_Ch3 is
end if; end if;
end if; end if;
New_Scope (T); Push_Scope (T);
Analyze (Comp_Decl); Analyze (Comp_Decl);
Set_Ekind (Ent, E_Component); Set_Ekind (Ent, E_Component);
Init_Component_Location (Ent); Init_Component_Location (Ent);
...@@ -4441,6 +4684,7 @@ package body Exp_Ch3 is ...@@ -4441,6 +4684,7 @@ package body Exp_Ch3 is
if Has_Task (Typ) if Has_Task (Typ)
and then not Restriction_Active (No_Implicit_Heap_Allocations) and then not Restriction_Active (No_Implicit_Heap_Allocations)
and then not Global_Discard_Names and then not Global_Discard_Names
and then VM_Target = No_VM
then then
Set_Uses_Sec_Stack (Proc_Id); Set_Uses_Sec_Stack (Proc_Id);
end if; end if;
...@@ -4471,8 +4715,8 @@ package body Exp_Ch3 is ...@@ -4471,8 +4715,8 @@ package body Exp_Ch3 is
-- If this is an anonymous array created for a declaration with -- If this is an anonymous array created for a declaration with
-- an initial value, its init_proc will never be called. The -- an initial value, its init_proc will never be called. The
-- initial value itself may have been expanded into assign- -- initial value itself may have been expanded into assignments,
-- ments, in which case the object declaration is carries the -- in which case the object declaration is carries the
-- No_Initialization flag. -- No_Initialization flag.
if Is_Itype (Base) if Is_Itype (Base)
...@@ -4655,6 +4899,8 @@ package body Exp_Ch3 is ...@@ -4655,6 +4899,8 @@ package body Exp_Ch3 is
-- case and there is no obligation to raise Constraint_Error here!) We -- case and there is no obligation to raise Constraint_Error here!) We
-- also do this if pragma Restrictions (No_Exceptions) is active. -- also do this if pragma Restrictions (No_Exceptions) is active.
-- Is this right??? What about No_Exception_Propagation???
-- Representations are signed -- Representations are signed
if Enumeration_Rep (First_Literal (Typ)) < 0 then if Enumeration_Rep (First_Literal (Typ)) < 0 then
...@@ -4727,7 +4973,6 @@ package body Exp_Ch3 is ...@@ -4727,7 +4973,6 @@ package body Exp_Ch3 is
else else
Ent := First_Literal (Typ); Ent := First_Literal (Typ);
while Present (Ent) loop while Present (Ent) loop
Append_To (Lst, Append_To (Lst,
Make_Case_Statement_Alternative (Loc, Make_Case_Statement_Alternative (Loc,
...@@ -4747,7 +4992,7 @@ package body Exp_Ch3 is ...@@ -4747,7 +4992,7 @@ package body Exp_Ch3 is
-- In normal mode, add the others clause with the test -- In normal mode, add the others clause with the test
if not Restriction_Active (No_Exception_Handlers) then if not No_Exception_Handlers_Set then
Append_To (Lst, Append_To (Lst,
Make_Case_Statement_Alternative (Loc, Make_Case_Statement_Alternative (Loc,
Discrete_Choices => New_List (Make_Others_Choice (Loc)), Discrete_Choices => New_List (Make_Others_Choice (Loc)),
...@@ -4759,8 +5004,8 @@ package body Exp_Ch3 is ...@@ -4759,8 +5004,8 @@ package body Exp_Ch3 is
Expression => Expression =>
Make_Integer_Literal (Loc, -1))))); Make_Integer_Literal (Loc, -1)))));
-- If Restriction (No_Exceptions_Handlers) is active then we always -- If either of the restrictions No_Exceptions_Handlers/Propagation is
-- return -1 (since we cannot usefully raise Constraint_Error in -- active then return -1 (we cannot usefully raise Constraint_Error in
-- this case). See description above for further details. -- this case). See description above for further details.
else else
...@@ -4907,18 +5152,18 @@ package body Exp_Ch3 is ...@@ -4907,18 +5152,18 @@ package body Exp_Ch3 is
Next_Component (Comp); Next_Component (Comp);
end loop; end loop;
-- Creation of the Dispatch Table. Note that a Dispatch Table is -- Creation of the Dispatch Table. Note that a Dispatch Table is built
-- created for regular tagged types as well as for Ada types deriving -- for regular tagged types as well as for Ada types deriving from a C++
-- from a C++ Class, but not for tagged types directly corresponding to -- Class, but not for tagged types directly corresponding to C++ classes
-- the C++ classes. In the later case we assume that the Vtable is -- In the later case we assume that it is created in the C++ side and we
-- created in the C++ side and we just use it. -- just use it.
if Is_Tagged_Type (Def_Id) then if Is_Tagged_Type (Def_Id) then
if Is_CPP_Class (Def_Id) then if Is_CPP_Class (Def_Id) then
-- Because of the new C++ ABI compatibility we now allow the -- Because of the new C++ ABI compatibility we now allow the
-- programer to use the Ada tag (and in this case we must do -- programmer to use the Ada tag (and in this case we must do
-- the normal expansion of the tag) -- the normal expansion of the tag)
if Etype (First_Component (Def_Id)) = RTE (RE_Tag) if Etype (First_Component (Def_Id)) = RTE (RE_Tag)
...@@ -4930,42 +5175,51 @@ package body Exp_Ch3 is ...@@ -4930,42 +5175,51 @@ package body Exp_Ch3 is
Set_All_DT_Position (Def_Id); Set_All_DT_Position (Def_Id);
Set_Default_Constructor (Def_Id); Set_Default_Constructor (Def_Id);
-- With CPP_Class types Make_DT does a minimum decoration of the
-- Access_Disp_Table list.
if VM_Target = No_VM then
Append_Freeze_Actions (Def_Id, Make_DT (Def_Id));
end if;
else else
-- Usually inherited primitives are not delayed but the first Ada if not Static_Dispatch_Tables then
-- extension of a CPP_Class is an exception since the address of
-- the inherited subprogram has to be inserted in the new Ada
-- Dispatch Table and this is a freezing action (usually the
-- inherited primitive address is inserted in the DT by
-- Inherit_DT)
-- Similarly, if this is an inherited operation whose parent is
-- not frozen yet, it is not in the DT of the parent, and we
-- generate an explicit freeze node for the inherited operation,
-- so that it is properly inserted in the DT of the current type.
declare -- Usually inherited primitives are not delayed but the first
Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Def_Id)); -- Ada extension of a CPP_Class is an exception since the
Subp : Entity_Id; -- address of the inherited subprogram has to be inserted in
-- the new Ada Dispatch Table and this is a freezing action.
begin -- Similarly, if this is an inherited operation whose parent is
while Present (Elmt) loop -- not frozen yet, it is not in the DT of the parent, and we
Subp := Node (Elmt); -- generate an explicit freeze node for the inherited operation
-- so that it is properly inserted in the DT of the current
if Present (Alias (Subp)) then -- type.
if Is_CPP_Class (Etype (Def_Id)) then
Set_Has_Delayed_Freeze (Subp); declare
Elmt : Elmt_Id := First_Elmt (Primitive_Operations (Def_Id));
elsif Has_Delayed_Freeze (Alias (Subp)) Subp : Entity_Id;
and then not Is_Frozen (Alias (Subp))
then begin
Set_Is_Frozen (Subp, False); while Present (Elmt) loop
Set_Has_Delayed_Freeze (Subp); Subp := Node (Elmt);
if Present (Alias (Subp)) then
if Is_CPP_Class (Etype (Def_Id)) then
Set_Has_Delayed_Freeze (Subp);
elsif Has_Delayed_Freeze (Alias (Subp))
and then not Is_Frozen (Alias (Subp))
then
Set_Is_Frozen (Subp, False);
Set_Has_Delayed_Freeze (Subp);
end if;
end if; end if;
end if;
Next_Elmt (Elmt); Next_Elmt (Elmt);
end loop; end loop;
end; end;
end if;
if Underlying_Type (Etype (Def_Id)) = Def_Id then if Underlying_Type (Etype (Def_Id)) = Def_Id then
Expand_Tagged_Root (Def_Id); Expand_Tagged_Root (Def_Id);
...@@ -5016,7 +5270,7 @@ package body Exp_Ch3 is ...@@ -5016,7 +5270,7 @@ package body Exp_Ch3 is
Insert_Actions (N, Null_Proc_Decl_List); Insert_Actions (N, Null_Proc_Decl_List);
end if; end if;
Set_Is_Frozen (Def_Id, True); Set_Is_Frozen (Def_Id);
Set_All_DT_Position (Def_Id); Set_All_DT_Position (Def_Id);
-- Add the controlled component before the freezing actions -- Add the controlled component before the freezing actions
...@@ -5026,90 +5280,12 @@ package body Exp_Ch3 is ...@@ -5026,90 +5280,12 @@ package body Exp_Ch3 is
Expand_Record_Controller (Def_Id); Expand_Record_Controller (Def_Id);
end if; end if;
-- Suppress creation of a dispatch table when Java_VM because the -- Build the dispatch table. Suppress its creation when VM_Target
-- dispatching mechanism is handled internally by the JVM. -- because the dispatching mechanism is handled internally by the
-- VMs.
if not Java_VM then
-- Ada 2005 (AI-251): Build the secondary dispatch tables
declare
ADT : Elist_Id := Access_Disp_Table (Def_Id);
procedure Add_Secondary_Tables (Typ : Entity_Id);
-- Internal subprogram, recursively climb to the ancestors
--------------------------
-- Add_Secondary_Tables --
--------------------------
procedure Add_Secondary_Tables (Typ : Entity_Id) is
E : Entity_Id;
Iface : Elmt_Id;
Result : List_Id;
Suffix_Index : Int;
begin
-- Climb to the ancestor (if any) handling private types
if Is_Concurrent_Record_Type (Typ) then
if Present (Abstract_Interface_List (Typ)) then
Add_Secondary_Tables
(Etype (First (Abstract_Interface_List (Typ))));
end if;
elsif Present (Full_View (Etype (Typ))) then
if Full_View (Etype (Typ)) /= Typ then
Add_Secondary_Tables (Full_View (Etype (Typ)));
end if;
elsif Etype (Typ) /= Typ then
Add_Secondary_Tables (Etype (Typ));
end if;
if Present (Abstract_Interfaces (Typ))
and then
not Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
then
Iface := First_Elmt (Abstract_Interfaces (Typ));
Suffix_Index := 0;
E := First_Entity (Typ);
while Present (E) loop
if Is_Tag (E) and then Chars (E) /= Name_uTag then
Make_Secondary_DT
(Typ => Def_Id,
Ancestor_Typ => Typ,
Suffix_Index => Suffix_Index,
Iface => Node (Iface),
AI_Tag => E,
Acc_Disp_Tables => ADT,
Result => Result);
Append_Freeze_Actions (Def_Id, Result);
Suffix_Index := Suffix_Index + 1;
Next_Elmt (Iface);
end if;
Next_Entity (E);
end loop;
end if;
end Add_Secondary_Tables;
-- Start of processing to build secondary dispatch tables
begin
-- Handle private types
if Present (Full_View (Def_Id)) then
Add_Secondary_Tables (Full_View (Def_Id));
else
Add_Secondary_Tables (Def_Id);
end if;
Set_Access_Disp_Table (Def_Id, ADT); if VM_Target = No_VM then
Append_Freeze_Actions (Def_Id, Make_DT (Def_Id)); Append_Freeze_Actions (Def_Id, Make_DT (Def_Id));
end;
end if; end if;
-- Make sure that the primitives Initialize, Adjust and Finalize -- Make sure that the primitives Initialize, Adjust and Finalize
...@@ -5204,7 +5380,14 @@ package body Exp_Ch3 is ...@@ -5204,7 +5380,14 @@ package body Exp_Ch3 is
end if; end if;
Adjust_Discriminants (Def_Id); Adjust_Discriminants (Def_Id);
Build_Record_Init_Proc (Type_Decl, Def_Id);
if VM_Target = No_VM or else not Is_Interface (Def_Id) then
-- Do not need init for interfaces on e.g. CIL since they're
-- abstract. Helps operation of peverify (the PE Verify tool).
Build_Record_Init_Proc (Type_Decl, Def_Id);
end if;
-- For tagged type, build bodies of primitive operations. Note that we -- For tagged type, build bodies of primitive operations. Note that we
-- do this after building the record initialization experiment, since -- do this after building the record initialization experiment, since
...@@ -5350,7 +5533,7 @@ package body Exp_Ch3 is ...@@ -5350,7 +5533,7 @@ package body Exp_Ch3 is
New_C := New_Copy (Old_C); New_C := New_Copy (Old_C);
Set_Parent (New_C, Parent (Old_C)); Set_Parent (New_C, Parent (Old_C));
New_Scope (Def_Id); Push_Scope (Def_Id);
Enter_Name (New_C); Enter_Name (New_C);
End_Scope; End_Scope;
end if; end if;
...@@ -5491,7 +5674,7 @@ package body Exp_Ch3 is ...@@ -5491,7 +5674,7 @@ package body Exp_Ch3 is
Chars => New_External_Name (Chars (Def_Id), 'P')); Chars => New_External_Name (Chars (Def_Id), 'P'));
-- We put the code associated with the pools in the entity -- We put the code associated with the pools in the entity
-- that has the later freeze node, usually the acces type -- that has the later freeze node, usually the access type
-- but it can also be the designated_type; because the pool -- but it can also be the designated_type; because the pool
-- code requires both those types to be frozen -- code requires both those types to be frozen
...@@ -5573,7 +5756,8 @@ package body Exp_Ch3 is ...@@ -5573,7 +5756,8 @@ package body Exp_Ch3 is
null; null;
elsif (Controlled_Type (Desig_Type) elsif (Controlled_Type (Desig_Type)
and then Convention (Desig_Type) /= Convention_Java) and then Convention (Desig_Type) /= Convention_Java
and then Convention (Desig_Type) /= Convention_CIL)
or else or else
(Is_Incomplete_Or_Private_Type (Desig_Type) (Is_Incomplete_Or_Private_Type (Desig_Type)
and then No (Full_View (Desig_Type)) and then No (Full_View (Desig_Type))
...@@ -5596,6 +5780,11 @@ package body Exp_Ch3 is ...@@ -5596,6 +5780,11 @@ package body Exp_Ch3 is
or else (Is_Array_Type (Desig_Type) or else (Is_Array_Type (Desig_Type)
and then not Is_Frozen (Desig_Type) and then not Is_Frozen (Desig_Type)
and then Controlled_Type (Component_Type (Desig_Type))) and then Controlled_Type (Component_Type (Desig_Type)))
-- The designated type has controlled anonymous access
-- discriminants.
or else Has_Controlled_Coextensions (Desig_Type)
then then
Set_Associated_Final_Chain (Def_Id, Set_Associated_Final_Chain (Def_Id,
Make_Defining_Identifier (Loc, Make_Defining_Identifier (Loc,
...@@ -5818,7 +6007,7 @@ package body Exp_Ch3 is ...@@ -5818,7 +6007,7 @@ package body Exp_Ch3 is
-- For signed integer types that have no negative values, either -- For signed integer types that have no negative values, either
-- there is room for negative values, or there is not. If there -- there is room for negative values, or there is not. If there
-- is, then all 1 bits may be interpretecd as minus one, which is -- is, then all 1 bits may be interpreted as minus one, which is
-- certainly invalid. Alternatively it is treated as the largest -- certainly invalid. Alternatively it is treated as the largest
-- positive value, in which case the observation for modular types -- positive value, in which case the observation for modular types
-- still applies. -- still applies.
...@@ -6012,9 +6201,10 @@ package body Exp_Ch3 is ...@@ -6012,9 +6201,10 @@ package body Exp_Ch3 is
---------------- ----------------
function In_Runtime (E : Entity_Id) return Boolean is function In_Runtime (E : Entity_Id) return Boolean is
S1 : Entity_Id := Scope (E); S1 : Entity_Id;
begin begin
S1 := Scope (E);
while Scope (S1) /= Standard_Standard loop while Scope (S1) /= Standard_Standard loop
S1 := Scope (S1); S1 := Scope (S1);
end loop; end loop;
...@@ -6022,6 +6212,66 @@ package body Exp_Ch3 is ...@@ -6022,6 +6212,66 @@ package body Exp_Ch3 is
return Chars (S1) = Name_System or else Chars (S1) = Name_Ada; return Chars (S1) = Name_System or else Chars (S1) = Name_Ada;
end In_Runtime; end In_Runtime;
----------------------------
-- Initialization_Warning --
----------------------------
procedure Initialization_Warning (E : Entity_Id) is
Warning_Needed : Boolean;
begin
Warning_Needed := False;
if Ekind (Current_Scope) = E_Package
and then Static_Elaboration_Desired (Current_Scope)
then
if Is_Type (E) then
if Is_Record_Type (E) then
if Has_Discriminants (E)
or else Is_Limited_Type (E)
or else Has_Non_Standard_Rep (E)
then
Warning_Needed := True;
else
-- Verify that at least one component has an initializtion
-- expression. No need for a warning on a type if all its
-- components have no initialization.
declare
Comp : Entity_Id;
begin
Comp := First_Component (E);
while Present (Comp) loop
if Ekind (Comp) = E_Discriminant
or else
(Nkind (Parent (Comp)) = N_Component_Declaration
and then Present (Expression (Parent (Comp))))
then
Warning_Needed := True;
exit;
end if;
Next_Component (Comp);
end loop;
end;
end if;
if Warning_Needed then
Error_Msg_N
("Objects of the type cannot be initialized " &
"statically by default?",
Parent (E));
end if;
end if;
else
Error_Msg_N ("Object cannot be initialized statically?", E);
end if;
end if;
end Initialization_Warning;
------------------ ------------------
-- Init_Formals -- -- Init_Formals --
------------------ ------------------
...@@ -6218,7 +6468,7 @@ package body Exp_Ch3 is ...@@ -6218,7 +6468,7 @@ package body Exp_Ch3 is
New_Reference_To (Tag_Comp, Loc)), New_Reference_To (Tag_Comp, Loc)),
Attribute_Name => Name_Position)), Attribute_Name => Name_Position)),
Unchecked_Convert_To (RTE (RE_Address), Unchecked_Convert_To (RTE (RE_Offset_To_Top_Function_Ptr),
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
Prefix => New_Reference_To Prefix => New_Reference_To
(DT_Offset_To_Top_Func (Tag_Comp), Loc), (DT_Offset_To_Top_Func (Tag_Comp), Loc),
...@@ -6284,8 +6534,7 @@ package body Exp_Ch3 is ...@@ -6284,8 +6534,7 @@ package body Exp_Ch3 is
New_Reference_To (Tag_Comp, Loc)), New_Reference_To (Tag_Comp, Loc)),
Attribute_Name => Name_Position)), Attribute_Name => Name_Position)),
New_Reference_To Make_Null (Loc))));
(RTE (RE_Null_Address), Loc))));
end if; end if;
end if; end if;
end Initialize_Tag; end Initialize_Tag;
...@@ -6342,7 +6591,7 @@ package body Exp_Ch3 is ...@@ -6342,7 +6591,7 @@ package body Exp_Ch3 is
Loc)), Loc)),
New_Occurrence_Of (Standard_True, Loc), New_Occurrence_Of (Standard_True, Loc),
Make_Integer_Literal (Loc, Uint_0), Make_Integer_Literal (Loc, Uint_0),
New_Reference_To (RTE (RE_Null_Address), Loc)))); Make_Null (Loc))));
end if; end if;
if Present (Abstract_Interfaces (Typ)) if Present (Abstract_Interfaces (Typ))
...@@ -6435,8 +6684,12 @@ package body Exp_Ch3 is ...@@ -6435,8 +6684,12 @@ package body Exp_Ch3 is
-- Input constructed by the expander. The test for Comes_From_Source -- Input constructed by the expander. The test for Comes_From_Source
-- is needed to distinguish inherited operations from renamings -- is needed to distinguish inherited operations from renamings
-- (which also have Alias set). -- (which also have Alias set).
-- The function may be abstract, or require_Overriding may be set
-- for it, because tests for null extensions may already have reset
-- the Is_Abstract_Subprogram_Flag.
if Is_Abstract_Subprogram (Subp) if (Is_Abstract_Subprogram (Subp)
or else Requires_Overriding (Subp))
and then Present (Alias (Subp)) and then Present (Alias (Subp))
and then not Is_Abstract_Subprogram (Alias (Subp)) and then not Is_Abstract_Subprogram (Alias (Subp))
and then not Comes_From_Source (Subp) and then not Comes_From_Source (Subp)
...@@ -6660,13 +6913,18 @@ package body Exp_Ch3 is ...@@ -6660,13 +6913,18 @@ package body Exp_Ch3 is
while Present (C) loop while Present (C) loop
Field_Name := Chars (Defining_Identifier (C)); Field_Name := Chars (Defining_Identifier (C));
-- The tags must not be compared they are not part of the value. -- The tags must not be compared: they are not part of the value.
-- Ditto for the controller component, if present.
-- Note also that in the following, we use Make_Identifier for -- Note also that in the following, we use Make_Identifier for
-- the component names. Use of New_Reference_To to identify the -- the component names. Use of New_Reference_To to identify the
-- components would be incorrect because the wrong entities for -- components would be incorrect because the wrong entities for
-- discriminants could be picked up in the private type case. -- discriminants could be picked up in the private type case.
if Field_Name /= Name_uTag then if Field_Name /= Name_uTag
and then
Field_Name /= Name_uController
then
Evolve_Or_Else (Cond, Evolve_Or_Else (Cond,
Make_Op_Ne (Loc, Make_Op_Ne (Loc,
Left_Opnd => Left_Opnd =>
...@@ -6918,13 +7176,12 @@ package body Exp_Ch3 is ...@@ -6918,13 +7176,12 @@ package body Exp_Ch3 is
Next_Elmt (Prim); Next_Elmt (Prim);
end loop; end loop;
-- If a renaming of predefined equality was found -- If a renaming of predefined equality was found but there was no
-- but there was no user-defined equality (so Eq_Needed -- user-defined equality (so Eq_Needed is still true), then set the
-- is still true), then set the name back to Name_Op_Eq. -- name back to Name_Op_Eq. But in the case where a user-defined
-- But in the case where a user-defined equality was -- equality was located after such a renaming, then the predefined
-- located after such a renaming, then the predefined -- equality function is still needed, so Eq_Needed must be set back
-- equality function is still needed, so Eq_Needed must -- to True.
-- be set back to True.
if Eq_Name /= Name_Op_Eq then if Eq_Name /= Name_Op_Eq then
if Eq_Needed then if Eq_Needed then
...@@ -6957,10 +7214,10 @@ package body Exp_Ch3 is ...@@ -6957,10 +7214,10 @@ package body Exp_Ch3 is
while Present (Prim) loop while Present (Prim) loop
-- Any renamings of equality that appeared before an -- Any renamings of equality that appeared before an
-- overriding equality must be updated to refer to -- overriding equality must be updated to refer to the
-- the entity for the predefined equality, otherwise -- entity for the predefined equality, otherwise calls via
-- calls via the renaming would get incorrectly -- the renaming would get incorrectly resolved to call the
-- resolved to call the user-defined equality function. -- user-defined equality function.
if Is_Predefined_Eq_Renaming (Node (Prim)) then if Is_Predefined_Eq_Renaming (Node (Prim)) then
Set_Alias (Node (Prim), Renamed_Eq); Set_Alias (Node (Prim), Renamed_Eq);
...@@ -6994,7 +7251,9 @@ package body Exp_Ch3 is ...@@ -6994,7 +7251,9 @@ package body Exp_Ch3 is
Parameter_Type => New_Reference_To (Tag_Typ, Loc))))); Parameter_Type => New_Reference_To (Tag_Typ, Loc)))));
end if; end if;
-- Generate the declarations for the following primitive operations: -- Ada 2005: Generate declarations for the following primitive
-- operations for limited interfaces and synchronized types that
-- implement a limited interface.
-- disp_asynchronous_select -- disp_asynchronous_select
-- disp_conditional_select -- disp_conditional_select
...@@ -7002,14 +7261,16 @@ package body Exp_Ch3 is ...@@ -7002,14 +7261,16 @@ package body Exp_Ch3 is
-- disp_get_task_id -- disp_get_task_id
-- disp_timed_select -- disp_timed_select
-- for limited interfaces and synchronized types that implement a -- These operations cannot be implemented on VM targets, so we simply
-- limited interface. -- disable their generation in this case. We also disable generation
-- of these bodies if No_Dispatching_Calls is active.
if Ada_Version >= Ada_05 if Ada_Version >= Ada_05
and then VM_Target = No_VM
and then and then
((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ)) ((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ))
or else (Is_Concurrent_Record_Type (Tag_Typ) or else (Is_Concurrent_Record_Type (Tag_Typ)
and then Has_Abstract_Interfaces (Tag_Typ))) and then Has_Abstract_Interfaces (Tag_Typ)))
then then
Append_To (Res, Append_To (Res,
Make_Subprogram_Declaration (Loc, Make_Subprogram_Declaration (Loc,
...@@ -7037,13 +7298,12 @@ package body Exp_Ch3 is ...@@ -7037,13 +7298,12 @@ package body Exp_Ch3 is
Make_Disp_Timed_Select_Spec (Tag_Typ))); Make_Disp_Timed_Select_Spec (Tag_Typ)));
end if; end if;
-- Specs for finalization actions that may be required in case a -- Specs for finalization actions that may be required in case a future
-- future extension contain a controlled element. We generate those -- extension contain a controlled element. We generate those only for
-- only for root tagged types where they will get dummy bodies or -- root tagged types where they will get dummy bodies or when the type
-- when the type has controlled components and their body must be -- has controlled components and their body must be generated. It is
-- generated. It is also impossible to provide those for tagged -- also impossible to provide those for tagged types defined within
-- types defined within s-finimp since it would involve circularity -- s-finimp since it would involve circularity problems
-- problems
if In_Finalization_Root (Tag_Typ) then if In_Finalization_Root (Tag_Typ) then
null; null;
...@@ -7081,8 +7341,8 @@ package body Exp_Ch3 is ...@@ -7081,8 +7341,8 @@ package body Exp_Ch3 is
function Needs_Simple_Initialization (T : Entity_Id) return Boolean is function Needs_Simple_Initialization (T : Entity_Id) return Boolean is
begin begin
-- Check for private type, in which case test applies to the -- Check for private type, in which case test applies to the underlying
-- underlying type of the private type. -- type of the private type.
if Is_Private_Type (T) then if Is_Private_Type (T) then
declare declare
...@@ -7196,12 +7456,11 @@ package body Exp_Ch3 is ...@@ -7196,12 +7456,11 @@ package body Exp_Ch3 is
begin begin
Set_Is_Public (Id, Is_Public (Tag_Typ)); Set_Is_Public (Id, Is_Public (Tag_Typ));
-- The internal flag is set to mark these declarations because -- The internal flag is set to mark these declarations because they have
-- they have specific properties. First they are primitives even -- specific properties. First, they are primitives even if they are not
-- if they are not defined in the type scope (the freezing point -- defined in the type scope (the freezing point is not necessarily in
-- is not necessarily in the same scope), furthermore the -- the same scope). Second, the predefined equality can be overridden by
-- predefined equality can be overridden by a user-defined -- a user-defined equality, no body will be generated in this case.
-- equality, no body will be generated in this case.
Set_Is_Internal (Id); Set_Is_Internal (Id);
...@@ -7223,18 +7482,18 @@ package body Exp_Ch3 is ...@@ -7223,18 +7482,18 @@ package body Exp_Ch3 is
New_Reference_To (Ret_Type, Loc)); New_Reference_To (Ret_Type, Loc));
end if; end if;
-- If body case, return empty subprogram body. Note that this is -- If body case, return empty subprogram body. Note that this is ill-
-- ill-formed, because there is not even a null statement, and -- formed, because there is not even a null statement, and certainly not
-- certainly not a return in the function case. The caller is -- a return in the function case. The caller is expected to do surgery
-- expected to do surgery on the body to add the appropriate stuff. -- on the body to add the appropriate stuff.
if For_Body then if For_Body then
return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty); return Make_Subprogram_Body (Loc, Spec, Empty_List, Empty);
-- For the case of Input/Output attributes applied to an abstract type, -- For the case of Input/Output attributes applied to an abstract type,
-- generate abstract specifications. These will never be called, -- generate abstract specifications. These will never be called, but we
-- but we need the slots allocated in the dispatching table so -- need the slots allocated in the dispatching table so that attributes
-- that typ'Class'Input and typ'Class'Output will work properly. -- typ'Class'Input and typ'Class'Output will work properly.
elsif (Is_TSS (Name, TSS_Stream_Input) elsif (Is_TSS (Name, TSS_Stream_Input)
or else or else
...@@ -7381,8 +7640,8 @@ package body Exp_Ch3 is ...@@ -7381,8 +7640,8 @@ package body Exp_Ch3 is
Append_To (Res, Decl); Append_To (Res, Decl);
end if; end if;
-- Skip bodies of _Input and _Output for the abstract case, since -- Skip bodies of _Input and _Output for the abstract case, since the
-- the corresponding specs are abstract (see Predef_Spec_Or_Body) -- corresponding specs are abstract (see Predef_Spec_Or_Body).
if not Is_Abstract_Type (Tag_Typ) then if not Is_Abstract_Type (Tag_Typ) then
if Stream_Operation_OK (Tag_Typ, TSS_Stream_Input) if Stream_Operation_OK (Tag_Typ, TSS_Stream_Input)
...@@ -7402,7 +7661,9 @@ package body Exp_Ch3 is ...@@ -7402,7 +7661,9 @@ package body Exp_Ch3 is
end if; end if;
end if; end if;
-- Generate the bodies for the following primitive operations: -- Ada 2005: Generate bodies for the following primitive operations for
-- limited interfaces and synchronized types that implement a limited
-- interface.
-- disp_asynchronous_select -- disp_asynchronous_select
-- disp_conditional_select -- disp_conditional_select
...@@ -7410,12 +7671,15 @@ package body Exp_Ch3 is ...@@ -7410,12 +7671,15 @@ package body Exp_Ch3 is
-- disp_get_task_id -- disp_get_task_id
-- disp_timed_select -- disp_timed_select
-- for limited interfaces and synchronized types that implement a -- The interface versions will have null bodies
-- limited interface. The interface versions will have null bodies.
-- These operations cannot be implemented on VM targets, so we simply
-- disable their generation in this case. We also disable generation
-- of these bodies if No_Dispatching_Calls is active.
if Ada_Version >= Ada_05 if Ada_Version >= Ada_05
and then and then VM_Target = No_VM
not Restriction_Active (No_Dispatching_Calls) and then not Restriction_Active (No_Dispatching_Calls)
and then and then
((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ)) ((Is_Interface (Tag_Typ) and then Is_Limited_Record (Tag_Typ))
or else (Is_Concurrent_Record_Type (Tag_Typ) or else (Is_Concurrent_Record_Type (Tag_Typ)
...@@ -7607,7 +7871,7 @@ package body Exp_Ch3 is ...@@ -7607,7 +7871,7 @@ package body Exp_Ch3 is
begin begin
Prim := First_Elmt (Primitive_Operations (Tag_Typ)); Prim := First_Elmt (Primitive_Operations (Tag_Typ));
while Present (Prim) loop while Present (Prim) loop
if Is_Internal (Node (Prim)) then if Is_Predefined_Dispatching_Operation (Node (Prim)) then
Frnodes := Freeze_Entity (Node (Prim), Loc); Frnodes := Freeze_Entity (Node (Prim), Loc);
if Present (Frnodes) then if Present (Frnodes) then
...@@ -7654,6 +7918,7 @@ package body Exp_Ch3 is ...@@ -7654,6 +7918,7 @@ package body Exp_Ch3 is
or else Is_Synchronized_Interface (Typ))) or else Is_Synchronized_Interface (Typ)))
and then not Restriction_Active (No_Streams) and then not Restriction_Active (No_Streams)
and then not Restriction_Active (No_Dispatch) and then not Restriction_Active (No_Dispatch)
and then not No_Run_Time_Mode
and then RTE_Available (RE_Tag) and then RTE_Available (RE_Tag)
and then RTE_Available (RE_Root_Stream_Type); and then RTE_Available (RE_Root_Stream_Type);
end Stream_Operation_OK; end Stream_Operation_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment