-- Return True if we can copy objects of this type when expanding a case
-- expression.
- function Is_Optimizable_Declaration (N : Node_Id) return Boolean;
- -- Return True if N is an object declaration that can be optimized
-
------------------
-- Is_Copy_Type --
------------------
return Is_Elementary_Type (Underlying_Type (Typ));
end Is_Copy_Type;
- --------------------------------
- -- Is_Optimizable_Declaration --
- --------------------------------
-
- function Is_Optimizable_Declaration (N : Node_Id) return Boolean is
- begin
- return Nkind (N) = N_Object_Declaration
- and then not (Is_Entity_Name (Object_Definition (N))
- and then Is_Class_Wide_Type
- (Entity (Object_Definition (N))))
- and then not Is_Return_Object (Defining_Identifier (N))
- and then not Is_Copy_Type (Typ);
- end Is_Optimizable_Declaration;
-
-- Local variables
Acts : List_Id;
Unqualified_Unconditional_Parent (N);
begin
if Nkind (Uncond_Par) = N_Simple_Return_Statement
- or else Is_Optimizable_Declaration (Uncond_Par)
+ or else (Is_Distributable_Declaration (Uncond_Par)
+ and then not Is_Copy_Type (Typ))
or else (Parent_Is_Regular_Aggregate (Uncond_Par)
and then not Is_Copy_Type (Typ))
then
elsif Nkind (Par) = N_Simple_Return_Statement then
Optimize_Return_Stmt := True;
- elsif Is_Optimizable_Declaration (Par) then
+ elsif Is_Distributable_Declaration (Par) then
Optimize_Object_Decl := True;
else
-- Return True if we can copy objects of this type when expanding an if
-- expression.
- function Is_Optimizable_Declaration (N : Node_Id) return Boolean;
- -- Return True if N is an object declaration that can be optimized
-
function OK_For_Single_Subtype (T1, T2 : Entity_Id) return Boolean;
-- Return true if it is acceptable to use a single subtype for two
-- dependent expressions of subtype T1 and T2 respectively, which are
and then not Is_By_Reference_Type (Utyp);
end Is_Copy_Type;
- --------------------------------
- -- Is_Optimizable_Declaration --
- --------------------------------
-
- function Is_Optimizable_Declaration (N : Node_Id) return Boolean is
- begin
- return Nkind (N) = N_Object_Declaration
- and then not (Is_Entity_Name (Object_Definition (N))
- and then Is_Class_Wide_Type
- (Entity (Object_Definition (N))))
- and then not Is_Return_Object (Defining_Identifier (N))
- and then not Is_Copy_Type (Typ);
- end Is_Optimizable_Declaration;
-
---------------------------
-- OK_For_Single_Subtype --
---------------------------
Unqualified_Unconditional_Parent (N);
begin
if Nkind (Uncond_Par) = N_Simple_Return_Statement
- or else Is_Optimizable_Declaration (Uncond_Par)
+ or else (Is_Distributable_Declaration (Uncond_Par)
+ and then not Is_Copy_Type (Typ))
or else (Parent_Is_Regular_Aggregate (Uncond_Par)
and then not Is_Copy_Type (Typ))
then
elsif Nkind (Par) = N_Simple_Return_Statement then
Optimize_Return_Stmt := True;
- elsif Is_Optimizable_Declaration (Par) then
+ elsif Is_Distributable_Declaration (Par) then
Optimize_Object_Decl := True;
else
and then Expansion_Delayed (Unqual_N);
end Is_Delayed_Conditional_Expression;
+ --------------------------------
+ -- Is_Distributable_Declaration --
+ --------------------------------
+
+ function Is_Distributable_Declaration (N : Node_Id) return Boolean is
+ Obj_Def : Node_Id;
+
+ begin
+ -- First limitation: distribution is not implemented for return objects
+
+ if Nkind (N) /= N_Object_Declaration
+ or else Is_Return_Object (Defining_Identifier (N))
+ then
+ return False;
+ end if;
+
+ Obj_Def := Object_Definition (N);
+
+ -- Second limitation: distribution is not implemented for CW types
+
+ if Is_Entity_Name (Obj_Def)
+ and then Is_Class_Wide_Type (Entity (Obj_Def))
+ then
+ return False;
+ end if;
+
+ -- The declaration of a variable of an unconstrained definite nonlimited
+ -- subtype cannot be distributed because the variable is mutable and the
+ -- expansion of 'Constrained must statically return False for it.
+
+ return Constant_Present (N)
+ or else not Is_Entity_Name (Obj_Def)
+ or else Is_Constrained (Entity (Obj_Def))
+ or else not Is_Definite_Subtype (Entity (Obj_Def))
+ or else Is_Inherently_Limited_Type (Entity (Obj_Def));
+ end Is_Distributable_Declaration;
+
--------------------------------------------------
-- Is_Expanded_Class_Wide_Interface_Object_Decl --
--------------------------------------------------
-- Return True if N is a type conversion, or a dereference thereof, or a
-- reference to a formal parameter.
+ function Is_Distributable_Declaration (N : Node_Id) return Boolean;
+ -- Return True if N is an object declaration that can be distributed into
+ -- the dependent expressions of a conditional expression, given that the
+ -- conditional expression is the initialization expression of N. Such a
+ -- distribution avoids a copy operation and is required for limited types
+ -- and, more generally, desirable for all by-reference types.
+
function Is_Expanded_Class_Wide_Interface_Object_Decl
(N : Node_Id) return Boolean;
-- Determine if N is the expanded code for a class-wide interface type