with Atree; use Atree;
with Checks; use Checks;
with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
with Exp_Ch7; use Exp_Ch7;
with Exp_Ch11; use Exp_Ch11;
with Hostparm; use Hostparm;
with Inline; use Inline;
with Itypes; use Itypes;
with Lib; use Lib;
with Namet; use Namet;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Opt; use Opt;
with Restrict; use Restrict;
with Sem; use Sem;
with Sem_Ch8; use Sem_Ch8;
with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Stand; use Stand;
with Stringt; use Stringt;
with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Urealp; use Urealp;
with Validsw; use Validsw;
package body Exp_Util is
function Build_Task_Array_Image
(Loc : Source_Ptr;
Id_Ref : Node_Id;
A_Type : Entity_Id;
Dyn : Boolean := False)
return Node_Id;
function Build_Task_Image_Function
(Loc : Source_Ptr;
Decls : List_Id;
Stats : List_Id;
Res : Entity_Id)
return Node_Id;
procedure Build_Task_Image_Prefix
(Loc : Source_Ptr;
Len : out Entity_Id;
Res : out Entity_Id;
Pos : out Entity_Id;
Prefix : Entity_Id;
Sum : Node_Id;
Decls : in out List_Id;
Stats : in out List_Id);
function Build_Task_Record_Image
(Loc : Source_Ptr;
Id_Ref : Node_Id;
Dyn : Boolean := False)
return Node_Id;
function Make_CW_Equivalent_Type
(T : Entity_Id;
E : Node_Id)
return Entity_Id;
function Make_Literal_Range
(Loc : Source_Ptr;
Literal_Typ : Entity_Id)
return Node_Id;
function New_Class_Wide_Subtype
(CW_Typ : Entity_Id;
N : Node_Id)
return Entity_Id;
procedure Adjust_Condition (N : Node_Id) is
begin
if No (N) then
return;
end if;
declare
Loc : constant Source_Ptr := Sloc (N);
T : constant Entity_Id := Etype (N);
Ti : Entity_Id;
begin
if No (T) or else not Is_Boolean_Type (T) then
return;
end if;
if Validity_Checks_On and Validity_Check_Tests then
Ensure_Valid (N);
end if;
if Base_Type (T) = Standard_Boolean then
return;
end if;
if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
if Esize (T) <= Esize (Standard_Integer) then
Ti := Standard_Integer;
else
Ti := Standard_Long_Long_Integer;
end if;
Rewrite (N,
Make_Op_Ne (Loc,
Left_Opnd => Unchecked_Convert_To (Ti, N),
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Enum_Rep,
Prefix =>
New_Occurrence_Of (First_Literal (T), Loc))));
Analyze_And_Resolve (N, Standard_Boolean);
else
Rewrite (N, Convert_To (Standard_Boolean, N));
Analyze_And_Resolve (N, Standard_Boolean);
end if;
end;
end Adjust_Condition;
procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
begin
if Etype (N) /= Standard_Boolean then
return;
end if;
if Base_Type (T) = Standard_Boolean then
return;
else
declare
KP : constant Node_Kind := Nkind (Parent (N));
begin
if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
return;
elsif KP in N_Op_Boolean
or else KP = N_And_Then
or else KP = N_Or_Else
or else KP = N_Op_Not
then
return;
else
Set_Analyzed (N);
Rewrite (N, Convert_To (T, N));
Analyze_And_Resolve (N, T);
end if;
end;
end if;
end Adjust_Result_Type;
procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
Fnode : Node_Id := Freeze_Node (T);
begin
Ensure_Freeze_Node (T);
Fnode := Freeze_Node (T);
if not Present (Actions (Fnode)) then
Set_Actions (Fnode, New_List);
end if;
Append (N, Actions (Fnode));
end Append_Freeze_Action;
procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
Fnode : constant Node_Id := Freeze_Node (T);
begin
if No (L) then
return;
else
if No (Actions (Fnode)) then
Set_Actions (Fnode, L);
else
Append_List (L, Actions (Fnode));
end if;
end if;
end Append_Freeze_Actions;
function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
begin
return
Make_Procedure_Call_Statement (Loc,
Name => New_Reference_To (RTE (RE), Loc));
end Build_Runtime_Call;
function Build_Task_Array_Image
(Loc : Source_Ptr;
Id_Ref : Node_Id;
A_Type : Entity_Id;
Dyn : Boolean := False)
return Node_Id
is
Dims : constant Nat := Number_Dimensions (A_Type);
Temps : array (1 .. Dims) of Entity_Id;
Indx : Node_Id;
Len : Entity_Id;
Pos : Entity_Id;
Pref : Entity_Id;
P_Nam : Node_Id;
Res : Entity_Id;
Val : Node_Id;
Sum : Node_Id;
T : Entity_Id;
Decls : List_Id := New_List;
Stats : List_Id := New_List;
begin
Pref := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
if Dyn then
Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
P_Nam :=
Make_String_Literal (Loc, Strval => String_From_Name_Buffer);
else
P_Nam :=
Make_Explicit_Dereference (Loc,
Prefix => Make_Identifier (Loc, Name_uTask_Id));
end if;
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Pref,
Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression => P_Nam));
Indx := First_Index (A_Type);
Val := First (Expressions (Id_Ref));
for J in 1 .. Dims loop
T := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
Temps (J) := T;
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => T,
Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Image,
Prefix =>
New_Occurrence_Of (Etype (Indx), Loc),
Expressions => New_List (
New_Copy_Tree (Val)))));
Next_Index (Indx);
Next (Val);
end loop;
Sum := Make_Integer_Literal (Loc, Dims + 1);
Sum :=
Make_Op_Add (Loc,
Left_Opnd => Sum,
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix =>
New_Occurrence_Of (Pref, Loc),
Expressions => New_List (Make_Integer_Literal (Loc, 1))));
for J in 1 .. Dims loop
Sum :=
Make_Op_Add (Loc,
Left_Opnd => Sum,
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix =>
New_Occurrence_Of (Temps (J), Loc),
Expressions => New_List (Make_Integer_Literal (Loc, 1))));
end loop;
Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Indexed_Component (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
Expression =>
Make_Character_Literal (Loc,
Chars => Name_Find,
Char_Literal_Value =>
Char_Code (Character'Pos ('(')))));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd => Make_Integer_Literal (Loc, 1))));
for J in 1 .. Dims loop
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Slice (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Discrete_Range =>
Make_Range (Loc,
Low_Bound => New_Occurrence_Of (Pos, Loc),
High_Bound => Make_Op_Subtract (Loc,
Left_Opnd =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix =>
New_Occurrence_Of (Temps (J), Loc),
Expressions =>
New_List (Make_Integer_Literal (Loc, 1)))),
Right_Opnd => Make_Integer_Literal (Loc, 1)))),
Expression => New_Occurrence_Of (Temps (J), Loc)));
if J < Dims then
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix => New_Occurrence_Of (Temps (J), Loc),
Expressions =>
New_List (Make_Integer_Literal (Loc, 1))))));
Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Indexed_Component (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
Expression =>
Make_Character_Literal (Loc,
Chars => Name_Find,
Char_Literal_Value =>
Char_Code (Character'Pos (',')))));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd => Make_Integer_Literal (Loc, 1))));
end if;
end loop;
Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Indexed_Component (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Expressions => New_List (New_Occurrence_Of (Len, Loc))),
Expression =>
Make_Character_Literal (Loc,
Chars => Name_Find,
Char_Literal_Value =>
Char_Code (Character'Pos (')')))));
return Build_Task_Image_Function (Loc, Decls, Stats, Res);
end Build_Task_Array_Image;
function Build_Task_Image_Decls
(Loc : Source_Ptr;
Id_Ref : Node_Id;
A_Type : Entity_Id)
return List_Id
is
T_Id : Entity_Id := Empty;
Decl : Node_Id;
Decls : List_Id := New_List;
Expr : Node_Id := Empty;
Fun : Node_Id := Empty;
Is_Dyn : constant Boolean :=
Nkind (Parent (Id_Ref)) = N_Assignment_Statement
and then Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
begin
if Global_Discard_Names then
T_Id :=
Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
return
New_List (
Make_Object_Declaration (Loc,
Defining_Identifier => T_Id,
Object_Definition =>
New_Occurrence_Of (RTE (RE_Task_Image_Type), Loc)));
else
if Nkind (Id_Ref) = N_Identifier
or else Nkind (Id_Ref) = N_Defining_Identifier
then
T_Id :=
Make_Defining_Identifier (Loc,
New_External_Name (Chars (Id_Ref), 'I'));
Get_Name_String (Chars (Id_Ref));
Expr :=
Make_Allocator (Loc,
Expression =>
Make_Qualified_Expression (Loc,
Subtype_Mark =>
New_Occurrence_Of (Standard_String, Loc),
Expression =>
Make_String_Literal
(Loc, Strval => String_From_Name_Buffer)));
elsif Nkind (Id_Ref) = N_Selected_Component then
T_Id :=
Make_Defining_Identifier (Loc,
New_External_Name (Chars (Selector_Name (Id_Ref)), 'I'));
Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
elsif Nkind (Id_Ref) = N_Indexed_Component then
T_Id :=
Make_Defining_Identifier (Loc,
New_External_Name (Chars (A_Type), 'I'));
Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
end if;
end if;
if Present (Fun) then
Append (Fun, Decls);
Expr :=
Make_Function_Call (Loc,
Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
end if;
Decl := Make_Object_Declaration (Loc,
Defining_Identifier => T_Id,
Object_Definition =>
New_Occurrence_Of (RTE (RE_Task_Image_Type), Loc),
Expression => Expr);
Append (Decl, Decls);
return Decls;
end Build_Task_Image_Decls;
function Build_Task_Image_Function
(Loc : Source_Ptr;
Decls : List_Id;
Stats : List_Id;
Res : Entity_Id)
return Node_Id
is
Spec : Node_Id;
begin
Append_To (Stats,
Make_Return_Statement (Loc,
Expression =>
Make_Allocator (Loc,
Expression =>
Make_Qualified_Expression (Loc,
Subtype_Mark =>
New_Occurrence_Of (Standard_String, Loc),
Expression => New_Occurrence_Of (Res, Loc)))));
Spec := Make_Function_Specification (Loc,
Defining_Unit_Name =>
Make_Defining_Identifier (Loc, New_Internal_Name ('F')),
Subtype_Mark => New_Occurrence_Of (RTE (RE_Task_Image_Type), Loc));
return Make_Subprogram_Body (Loc,
Specification => Spec,
Declarations => Decls,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements => Stats));
end Build_Task_Image_Function;
procedure Build_Task_Image_Prefix
(Loc : Source_Ptr;
Len : out Entity_Id;
Res : out Entity_Id;
Pos : out Entity_Id;
Prefix : Entity_Id;
Sum : Node_Id;
Decls : in out List_Id;
Stats : in out List_Id)
is
begin
Len := Make_Defining_Identifier (Loc, New_Internal_Name ('L'));
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Len,
Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
Expression => Sum));
Res := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Res,
Object_Definition =>
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints =>
New_List (
Make_Range (Loc,
Low_Bound => Make_Integer_Literal (Loc, 1),
High_Bound => New_Occurrence_Of (Len, Loc)))))));
Pos := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Pos,
Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix => New_Occurrence_Of (Prefix, Loc),
Expressions =>
New_List (Make_Integer_Literal (Loc, 1)))));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Slice (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Discrete_Range =>
Make_Range (Loc,
Low_Bound => Make_Integer_Literal (Loc, 1),
High_Bound => New_Occurrence_Of (Pos, Loc))),
Expression => New_Occurrence_Of (Prefix, Loc)));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd => Make_Integer_Literal (Loc, 1))));
end Build_Task_Image_Prefix;
function Build_Task_Record_Image
(Loc : Source_Ptr;
Id_Ref : Node_Id;
Dyn : Boolean := False)
return Node_Id
is
Len : Entity_Id;
Pos : Entity_Id;
Res : Entity_Id;
Pref : Entity_Id;
P_Nam : Node_Id;
Sum : Node_Id;
Sel : Entity_Id;
Decls : List_Id := New_List;
Stats : List_Id := New_List;
begin
Pref := Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
if Dyn then
Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
P_Nam :=
Make_String_Literal (Loc, Strval => String_From_Name_Buffer);
else
P_Nam :=
Make_Explicit_Dereference (Loc,
Prefix => Make_Identifier (Loc, Name_uTask_Id));
end if;
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Pref,
Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression => P_Nam));
Sel := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
Get_Name_String (Chars (Selector_Name (Id_Ref)));
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => Sel,
Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression =>
Make_String_Literal (Loc, Strval => String_From_Name_Buffer)));
Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
Sum :=
Make_Op_Add (Loc,
Left_Opnd => Sum,
Right_Opnd =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Length,
Prefix =>
New_Occurrence_Of (Pref, Loc),
Expressions => New_List (Make_Integer_Literal (Loc, 1))));
Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Indexed_Component (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
Expression =>
Make_Character_Literal (Loc,
Chars => Name_Find,
Char_Literal_Value =>
Char_Code (Character'Pos ('.')))));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Pos, Loc),
Expression =>
Make_Op_Add (Loc,
Left_Opnd => New_Occurrence_Of (Pos, Loc),
Right_Opnd => Make_Integer_Literal (Loc, 1))));
Append_To (Stats,
Make_Assignment_Statement (Loc,
Name => Make_Slice (Loc,
Prefix => New_Occurrence_Of (Res, Loc),
Discrete_Range =>
Make_Range (Loc,
Low_Bound => New_Occurrence_Of (Pos, Loc),
High_Bound => New_Occurrence_Of (Len, Loc))),
Expression => New_Occurrence_Of (Sel, Loc)));
return Build_Task_Image_Function (Loc, Decls, Stats, Res);
end Build_Task_Record_Image;
procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
Act_ST : Entity_Id;
begin
Act_ST := Get_Actual_Subtype (Exp);
if Act_ST = Etype (Exp) then
return;
else
Rewrite (Exp,
Convert_To (Act_ST, Relocate_Node (Exp)));
Analyze_And_Resolve (Exp, Act_ST);
end if;
end Convert_To_Actual_Subtype;
function Current_Sem_Unit_Declarations return List_Id is
U : Node_Id := Unit (Cunit (Current_Sem_Unit));
Decls : List_Id;
begin
if Nkind (U) = N_Package_Body then
U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
end if;
if Nkind (U) = N_Package_Declaration then
U := Specification (U);
Decls := Visible_Declarations (U);
if No (Decls) then
Decls := New_List;
Set_Visible_Declarations (U, Decls);
end if;
else
Decls := Declarations (U);
if No (Decls) then
Decls := New_List;
Set_Declarations (U, Decls);
end if;
end if;
return Decls;
end Current_Sem_Unit_Declarations;
function Duplicate_Subexpr
(Exp : Node_Id;
Name_Req : Boolean := False)
return Node_Id
is
begin
Remove_Side_Effects (Exp, Name_Req);
return New_Copy_Tree (Exp);
end Duplicate_Subexpr;
function Duplicate_Subexpr_No_Checks
(Exp : Node_Id;
Name_Req : Boolean := False)
return Node_Id
is
New_Exp : Node_Id;
begin
Remove_Side_Effects (Exp, Name_Req);
New_Exp := New_Copy_Tree (Exp);
Remove_Checks (New_Exp);
return New_Exp;
end Duplicate_Subexpr_No_Checks;
function Duplicate_Subexpr_Move_Checks
(Exp : Node_Id;
Name_Req : Boolean := False)
return Node_Id
is
New_Exp : Node_Id;
begin
Remove_Side_Effects (Exp, Name_Req);
New_Exp := New_Copy_Tree (Exp);
Remove_Checks (Exp);
return New_Exp;
end Duplicate_Subexpr_Move_Checks;
procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
IR : Node_Id;
P : Node_Id;
begin
if Is_Itype (Typ) then
IR := Make_Itype_Reference (Sloc (N));
Set_Itype (IR, Typ);
if not In_Open_Scopes (Scope (Typ))
and then Is_Subprogram (Current_Scope)
and then Scope (Current_Scope) /= Standard_Standard
then
P := Parent (N);
while Present (P)
and then Nkind (P) /= N_Subprogram_Body
loop
P := Parent (P);
end loop;
if Present (P) then
Insert_Action (P, IR);
else
Insert_Action (N, IR);
end if;
else
Insert_Action (N, IR);
end if;
end if;
end Ensure_Defined;
procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
begin
if No (Cond) then
Cond := Cond1;
else
Cond :=
Make_And_Then (Sloc (Cond1),
Left_Opnd => Cond,
Right_Opnd => Cond1);
end if;
end Evolve_And_Then;
procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
begin
if No (Cond) then
Cond := Cond1;
else
Cond :=
Make_Or_Else (Sloc (Cond1),
Left_Opnd => Cond,
Right_Opnd => Cond1);
end if;
end Evolve_Or_Else;
procedure Expand_Subtype_From_Expr
(N : Node_Id;
Unc_Type : Entity_Id;
Subtype_Indic : Node_Id;
Exp : Node_Id)
is
Loc : constant Source_Ptr := Sloc (N);
Exp_Typ : constant Entity_Id := Etype (Exp);
T : Entity_Id;
begin
if not Expander_Active
and then (No (Etype (Exp))
or else Base_Type (Etype (Exp)) /= Standard_String)
then
return;
end if;
if Nkind (Exp) = N_Slice then
declare
Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
begin
Rewrite (Subtype_Indic,
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Reference_To (Unc_Type, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => New_List
(New_Reference_To (Slice_Type, Loc)))));
Force_Evaluation (Low_Bound (Scalar_Range (Slice_Type)));
Force_Evaluation (High_Bound (Scalar_Range (Slice_Type)));
end;
elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
Rewrite (Subtype_Indic,
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Reference_To (Unc_Type, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => New_List (
Make_Literal_Range (Loc,
Literal_Typ => Exp_Typ)))));
elsif Is_Constrained (Exp_Typ)
and then not Is_Class_Wide_Type (Unc_Type)
then
if Is_Itype (Exp_Typ) then
T := Exp_Typ;
else
T :=
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('T'));
Insert_Action (N,
Make_Subtype_Declaration (Loc,
Defining_Identifier => T,
Subtype_Indication => New_Reference_To (Exp_Typ, Loc)));
Set_Is_Itype (T);
Set_Associated_Node_For_Itype (T, Exp);
end if;
Rewrite (Subtype_Indic, New_Reference_To (T, Loc));
elsif Is_Private_Type (Unc_Type)
and then Has_Unknown_Discriminants (Unc_Type)
and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
or else Is_Constrained (Underlying_Type (Unc_Type)))
then
null;
else
Remove_Side_Effects (Exp);
Rewrite (Subtype_Indic,
Make_Subtype_From_Expr (Exp, Unc_Type));
end if;
end Expand_Subtype_From_Expr;
function Find_Prim_Op (T : Entity_Id; Name : Name_Id) return Entity_Id is
Prim : Elmt_Id;
Typ : Entity_Id := T;
begin
if Is_Class_Wide_Type (Typ) then
Typ := Root_Type (Typ);
end if;
Typ := Underlying_Type (Typ);
Prim := First_Elmt (Primitive_Operations (Typ));
while Chars (Node (Prim)) /= Name loop
Next_Elmt (Prim);
pragma Assert (Present (Prim));
end loop;
return Node (Prim);
end Find_Prim_Op;
procedure Force_Evaluation (Exp : Node_Id; Name_Req : Boolean := False) is
begin
Remove_Side_Effects (Exp, Name_Req, Variable_Ref => True);
end Force_Evaluation;
procedure Generate_Poll_Call (N : Node_Id) is
begin
if not Polling_Required then
return;
else
Insert_Before_And_Analyze (N,
Make_Procedure_Call_Statement (Sloc (N),
Name => New_Occurrence_Of (RTE (RE_Poll), Sloc (N))));
end if;
end Generate_Poll_Call;
function Homonym_Number (Subp : Entity_Id) return Nat is
Count : Nat;
Hom : Entity_Id;
begin
Count := 1;
Hom := Homonym (Subp);
while Present (Hom) loop
if Scope (Hom) = Scope (Subp) then
Count := Count + 1;
end if;
Hom := Homonym (Hom);
end loop;
return Count;
end Homonym_Number;
function In_Unconditional_Context (Node : Node_Id) return Boolean is
P : Node_Id;
begin
P := Node;
while Present (P) loop
case Nkind (P) is
when N_Subprogram_Body =>
return True;
when N_If_Statement =>
return False;
when N_Loop_Statement =>
return False;
when N_Case_Statement =>
return False;
when others =>
P := Parent (P);
end case;
end loop;
return False;
end In_Unconditional_Context;
procedure Insert_Action (Assoc_Node : Node_Id; Ins_Action : Node_Id) is
begin
if Present (Ins_Action) then
Insert_Actions (Assoc_Node, New_List (Ins_Action));
end if;
end Insert_Action;
procedure Insert_Action
(Assoc_Node : Node_Id; Ins_Action : Node_Id; Suppress : Check_Id)
is
begin
Insert_Actions (Assoc_Node, New_List (Ins_Action), Suppress);
end Insert_Action;
procedure Insert_Actions (Assoc_Node : Node_Id; Ins_Actions : List_Id) is
N : Node_Id;
P : Node_Id;
Wrapped_Node : Node_Id := Empty;
begin
if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
return;
end if;
if In_Default_Expression then
return;
end if;
if Is_Record_Type (Current_Scope)
and then not Is_Frozen (Current_Scope)
then
if No (Scope_Stack.Table
(Scope_Stack.Last).Pending_Freeze_Actions)
then
Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
Ins_Actions;
else
Append_List
(Ins_Actions,
Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
end if;
return;
end if;
if Nkind (Assoc_Node) in N_Subexpr
and then (Nkind (Assoc_Node) in N_Raise_xxx_Error
or else Etype (Assoc_Node) /= Standard_Void_Type)
and then (Nkind (Assoc_Node) /= N_Attribute_Reference
or else
not Is_Procedure_Attribute_Name
(Attribute_Name (Assoc_Node)))
then
P := Assoc_Node; N := Parent (Assoc_Node);
else
P := Assoc_Node;
N := Empty;
end if;
if Scope_Is_Transient then
Wrapped_Node := Node_To_Be_Wrapped;
end if;
loop
pragma Assert (Present (P));
case Nkind (P) is
when N_And_Then | N_Or_Else =>
if N = Right_Opnd (P) then
if Present (Actions (P)) then
Insert_List_After_And_Analyze
(Last (Actions (P)), Ins_Actions);
else
Set_Actions (P, Ins_Actions);
Analyze_List (Actions (P));
end if;
return;
end if;
when N_Conditional_Expression =>
declare
ThenX : constant Node_Id := Next (First (Expressions (P)));
ElseX : constant Node_Id := Next (ThenX);
begin
if N = ThenX then
if Present (Then_Actions (P)) then
Insert_List_After_And_Analyze
(Last (Then_Actions (P)), Ins_Actions);
else
Set_Then_Actions (P, Ins_Actions);
Analyze_List (Then_Actions (P));
end if;
return;
elsif N = ElseX then
if Present (Else_Actions (P)) then
Insert_List_After_And_Analyze
(Last (Else_Actions (P)), Ins_Actions);
else
Set_Else_Actions (P, Ins_Actions);
Analyze_List (Else_Actions (P));
end if;
return;
else
null;
end if;
end;
when N_Iteration_Scheme |
N_Elsif_Part
=>
if N = Condition (P) then
if Present (Condition_Actions (P)) then
Insert_List_After_And_Analyze
(Last (Condition_Actions (P)), Ins_Actions);
else
Set_Condition_Actions (P, Ins_Actions);
Set_Parent (Ins_Actions, P);
Analyze_List (Condition_Actions (P));
end if;
return;
end if;
when
N_Procedure_Call_Statement |
N_Statement_Other_Than_Procedure_Call |
N_Pragma |
N_At_Clause |
N_Attribute_Definition_Clause |
N_Enumeration_Representation_Clause |
N_Record_Representation_Clause |
N_Abstract_Subprogram_Declaration |
N_Entry_Body |
N_Exception_Declaration |
N_Exception_Renaming_Declaration |
N_Formal_Object_Declaration |
N_Formal_Subprogram_Declaration |
N_Formal_Type_Declaration |
N_Full_Type_Declaration |
N_Function_Instantiation |
N_Generic_Function_Renaming_Declaration |
N_Generic_Package_Declaration |
N_Generic_Package_Renaming_Declaration |
N_Generic_Procedure_Renaming_Declaration |
N_Generic_Subprogram_Declaration |
N_Implicit_Label_Declaration |
N_Incomplete_Type_Declaration |
N_Number_Declaration |
N_Object_Declaration |
N_Object_Renaming_Declaration |
N_Package_Body |
N_Package_Body_Stub |
N_Package_Declaration |
N_Package_Instantiation |
N_Package_Renaming_Declaration |
N_Private_Extension_Declaration |
N_Private_Type_Declaration |
N_Procedure_Instantiation |
N_Protected_Body_Stub |
N_Protected_Type_Declaration |
N_Single_Task_Declaration |
N_Subprogram_Body |
N_Subprogram_Body_Stub |
N_Subprogram_Declaration |
N_Subprogram_Renaming_Declaration |
N_Subtype_Declaration |
N_Task_Body |
N_Task_Body_Stub |
N_Task_Type_Declaration |
N_Freeze_Entity
=>
if not Is_List_Member (P) then
null;
elsif Nkind (Parent (P)) = N_Component_Association then
null;
elsif Nkind (Parent (P)) = N_Variant
or else Nkind (Parent (P)) = N_Record_Definition
then
null;
elsif Nkind (Parent (P)) = N_Loop_Statement
and then not Comes_From_Source (Parent (P))
and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
and then
Scope (Entity (First (Ins_Actions))) /= Current_Scope
then
null;
elsif P = Wrapped_Node then
Store_Before_Actions_In_Scope (Ins_Actions);
return;
else
Insert_List_Before_And_Analyze (P, Ins_Actions);
return;
end if;
when
N_Raise_xxx_Error =>
if Etype (P) = Standard_Void_Type then
if P = Wrapped_Node then
Store_Before_Actions_In_Scope (Ins_Actions);
else
Insert_List_Before_And_Analyze (P, Ins_Actions);
end if;
return;
else
null;
end if;
when
N_Component_Association =>
if Nkind (Parent (P)) = N_Aggregate
and then Present (Aggregate_Bounds (Parent (P)))
and then Nkind (First (Choices (P))) = N_Others_Choice
then
if No (Loop_Actions (P)) then
Set_Loop_Actions (P, Ins_Actions);
Analyze_List (Ins_Actions);
else
declare
Decl : Node_Id := Assoc_Node;
begin
while Present (Decl) loop
exit when Parent (Decl) = P
and then Is_List_Member (Decl)
and then
List_Containing (Decl) = Loop_Actions (P);
Decl := Parent (Decl);
end loop;
if Present (Decl) then
Insert_List_Before_And_Analyze
(Decl, Ins_Actions);
else
Insert_List_After_And_Analyze
(Last (Loop_Actions (P)), Ins_Actions);
end if;
end;
end if;
return;
else
null;
end if;
when
N_Attribute_Reference =>
if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
if P = Wrapped_Node then
Store_Before_Actions_In_Scope (Ins_Actions);
else
Insert_List_Before_And_Analyze (P, Ins_Actions);
end if;
return;
else
null;
end if;
when
N_Abortable_Part |
N_Accept_Alternative |
N_Access_Definition |
N_Access_Function_Definition |
N_Access_Procedure_Definition |
N_Access_To_Object_Definition |
N_Aggregate |
N_Allocator |
N_Case_Statement_Alternative |
N_Character_Literal |
N_Compilation_Unit |
N_Compilation_Unit_Aux |
N_Component_Clause |
N_Component_Declaration |
N_Component_List |
N_Constrained_Array_Definition |
N_Decimal_Fixed_Point_Definition |
N_Defining_Character_Literal |
N_Defining_Identifier |
N_Defining_Operator_Symbol |
N_Defining_Program_Unit_Name |
N_Delay_Alternative |
N_Delta_Constraint |
N_Derived_Type_Definition |
N_Designator |
N_Digits_Constraint |
N_Discriminant_Association |
N_Discriminant_Specification |
N_Empty |
N_Entry_Body_Formal_Part |
N_Entry_Call_Alternative |
N_Entry_Declaration |
N_Entry_Index_Specification |
N_Enumeration_Type_Definition |
N_Error |
N_Exception_Handler |
N_Expanded_Name |
N_Explicit_Dereference |
N_Extension_Aggregate |
N_Floating_Point_Definition |
N_Formal_Decimal_Fixed_Point_Definition |
N_Formal_Derived_Type_Definition |
N_Formal_Discrete_Type_Definition |
N_Formal_Floating_Point_Definition |
N_Formal_Modular_Type_Definition |
N_Formal_Ordinary_Fixed_Point_Definition |
N_Formal_Package_Declaration |
N_Formal_Private_Type_Definition |
N_Formal_Signed_Integer_Type_Definition |
N_Function_Call |
N_Function_Specification |
N_Generic_Association |
N_Handled_Sequence_Of_Statements |
N_Identifier |
N_In |
N_Index_Or_Discriminant_Constraint |
N_Indexed_Component |
N_Integer_Literal |
N_Itype_Reference |
N_Label |
N_Loop_Parameter_Specification |
N_Mod_Clause |
N_Modular_Type_Definition |
N_Not_In |
N_Null |
N_Op_Abs |
N_Op_Add |
N_Op_And |
N_Op_Concat |
N_Op_Divide |
N_Op_Eq |
N_Op_Expon |
N_Op_Ge |
N_Op_Gt |
N_Op_Le |
N_Op_Lt |
N_Op_Minus |
N_Op_Mod |
N_Op_Multiply |
N_Op_Ne |
N_Op_Not |
N_Op_Or |
N_Op_Plus |
N_Op_Rem |
N_Op_Rotate_Left |
N_Op_Rotate_Right |
N_Op_Shift_Left |
N_Op_Shift_Right |
N_Op_Shift_Right_Arithmetic |
N_Op_Subtract |
N_Op_Xor |
N_Operator_Symbol |
N_Ordinary_Fixed_Point_Definition |
N_Others_Choice |
N_Package_Specification |
N_Parameter_Association |
N_Parameter_Specification |
N_Pragma_Argument_Association |
N_Procedure_Specification |
N_Protected_Body |
N_Protected_Definition |
N_Qualified_Expression |
N_Range |
N_Range_Constraint |
N_Real_Literal |
N_Real_Range_Specification |
N_Record_Definition |
N_Reference |
N_Selected_Component |
N_Signed_Integer_Type_Definition |
N_Single_Protected_Declaration |
N_Slice |
N_String_Literal |
N_Subprogram_Info |
N_Subtype_Indication |
N_Subunit |
N_Task_Definition |
N_Terminate_Alternative |
N_Triggering_Alternative |
N_Type_Conversion |
N_Unchecked_Expression |
N_Unchecked_Type_Conversion |
N_Unconstrained_Array_Definition |
N_Unused_At_End |
N_Unused_At_Start |
N_Use_Package_Clause |
N_Use_Type_Clause |
N_Variant |
N_Variant_Part |
N_Validate_Unchecked_Conversion |
N_With_Clause |
N_With_Type_Clause
=>
null;
end case;
if P = Wrapped_Node then
Store_Before_Actions_In_Scope (Ins_Actions);
return;
end if;
N := P;
if Nkind (Parent (N)) = N_Subunit then
P := Corresponding_Stub (Parent (N));
else
P := Parent (N);
end if;
end loop;
end Insert_Actions;
procedure Insert_Actions
(Assoc_Node : Node_Id; Ins_Actions : List_Id; Suppress : Check_Id)
is
begin
if Suppress = All_Checks then
declare
Svg : constant Suppress_Record := Scope_Suppress;
begin
Scope_Suppress := (others => True);
Insert_Actions (Assoc_Node, Ins_Actions);
Scope_Suppress := Svg;
end;
else
declare
Svg : constant Boolean := Get_Scope_Suppress (Suppress);
begin
Set_Scope_Suppress (Suppress, True);
Insert_Actions (Assoc_Node, Ins_Actions);
Set_Scope_Suppress (Suppress, Svg);
end;
end if;
end Insert_Actions;
procedure Insert_Actions_After
(Assoc_Node : Node_Id;
Ins_Actions : List_Id)
is
begin
if Scope_Is_Transient
and then Assoc_Node = Node_To_Be_Wrapped
then
Store_After_Actions_In_Scope (Ins_Actions);
else
Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
end if;
end Insert_Actions_After;
procedure Insert_Library_Level_Action (N : Node_Id) is
Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
begin
New_Scope (Cunit_Entity (Main_Unit));
if No (Actions (Aux)) then
Set_Actions (Aux, New_List (N));
else
Append (N, Actions (Aux));
end if;
Analyze (N);
Pop_Scope;
end Insert_Library_Level_Action;
procedure Insert_Library_Level_Actions (L : List_Id) is
Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
begin
if Is_Non_Empty_List (L) then
New_Scope (Cunit_Entity (Main_Unit));
if No (Actions (Aux)) then
Set_Actions (Aux, L);
Analyze_List (L);
else
Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
end if;
Pop_Scope;
end if;
end Insert_Library_Level_Actions;
function Inside_Init_Proc return Boolean is
S : Entity_Id;
begin
S := Current_Scope;
while S /= Standard_Standard loop
if Chars (S) = Name_uInit_Proc then
return True;
else
S := Scope (S);
end if;
end loop;
return False;
end Inside_Init_Proc;
function Is_Ref_To_Bit_Packed_Array (P : Node_Id) return Boolean is
Result : Boolean;
Expr : Node_Id;
begin
if Nkind (P) = N_Indexed_Component
or else
Nkind (P) = N_Selected_Component
then
if Is_Bit_Packed_Array (Etype (Prefix (P))) then
Result := True;
else
Result := Is_Ref_To_Bit_Packed_Array (Prefix (P));
end if;
if Result and then Nkind (P) = N_Indexed_Component then
Expr := First (Expressions (P));
while Present (Expr) loop
Force_Evaluation (Expr);
Next (Expr);
end loop;
end if;
return Result;
else
return False;
end if;
end Is_Ref_To_Bit_Packed_Array;
function Is_Ref_To_Bit_Packed_Slice (P : Node_Id) return Boolean is
begin
if Nkind (P) = N_Slice
and then Is_Bit_Packed_Array (Etype (Prefix (P)))
then
return True;
elsif Nkind (P) = N_Indexed_Component
or else
Nkind (P) = N_Selected_Component
then
return Is_Ref_To_Bit_Packed_Slice (Prefix (P));
else
return False;
end if;
end Is_Ref_To_Bit_Packed_Slice;
function Is_Renamed_Object (N : Node_Id) return Boolean is
Pnod : constant Node_Id := Parent (N);
Kind : constant Node_Kind := Nkind (Pnod);
begin
if Kind = N_Object_Renaming_Declaration then
return True;
elsif Kind = N_Indexed_Component
or else Kind = N_Selected_Component
then
return Is_Renamed_Object (Pnod);
else
return False;
end if;
end Is_Renamed_Object;
function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
begin
return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
or else
(Is_Private_Type (T) and then Present (Full_View (T))
and then not Is_Tagged_Type (Full_View (T))
and then Is_Derived_Type (Full_View (T))
and then Etype (Full_View (T)) /= T);
end Is_Untagged_Derivation;
procedure Kill_Dead_Code (N : Node_Id) is
begin
if Present (N) then
Remove_Handler_Entries (N);
Remove_Warning_Messages (N);
if Nkind (N) = N_Block_Statement
or else Nkind (N) = N_Subprogram_Body
or else Nkind (N) = N_Package_Body
then
Kill_Dead_Code (Declarations (N));
Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
if Nkind (N) = N_Subprogram_Body then
Set_Is_Eliminated (Defining_Entity (N));
end if;
elsif Nkind (N) = N_If_Statement then
Kill_Dead_Code (Then_Statements (N));
Kill_Dead_Code (Elsif_Parts (N));
Kill_Dead_Code (Else_Statements (N));
elsif Nkind (N) = N_Loop_Statement then
Kill_Dead_Code (Statements (N));
elsif Nkind (N) = N_Case_Statement then
declare
Alt : Node_Id := First (Alternatives (N));
begin
while Present (Alt) loop
Kill_Dead_Code (Statements (Alt));
Next (Alt);
end loop;
end;
elsif Nkind (N) in N_Generic_Instantiation then
Remove_Dead_Instance (N);
end if;
Delete_Tree (N);
end if;
end Kill_Dead_Code;
procedure Kill_Dead_Code (L : List_Id) is
N : Node_Id;
begin
if Is_Non_Empty_List (L) then
loop
N := Remove_Head (L);
exit when No (N);
Kill_Dead_Code (N);
end loop;
end if;
end Kill_Dead_Code;
function Known_Non_Negative (Opnd : Node_Id) return Boolean is
begin
if Is_OK_Static_Expression (Opnd)
and then Expr_Value (Opnd) >= 0
then
return True;
else
declare
Lo : constant Node_Id := Type_Low_Bound (Etype (Opnd));
begin
return
Is_OK_Static_Expression (Lo) and then Expr_Value (Lo) >= 0;
end;
end if;
end Known_Non_Negative;
Integer_Sized_Small : Ureal;
Long_Integer_Sized_Small : Ureal;
First_Time_For_THFO : Boolean := True;
function Target_Has_Fixed_Ops
(Left_Typ : Entity_Id;
Right_Typ : Entity_Id;
Result_Typ : Entity_Id)
return Boolean
is
function Is_Fractional_Type (Typ : Entity_Id) return Boolean;
function Is_Fractional_Type (Typ : Entity_Id) return Boolean is
begin
if Esize (Typ) = Standard_Integer_Size then
return Small_Value (Typ) = Integer_Sized_Small;
elsif Esize (Typ) = Standard_Long_Integer_Size then
return Small_Value (Typ) = Long_Integer_Sized_Small;
else
return False;
end if;
end Is_Fractional_Type;
begin
if not Fractional_Fixed_Ops_On_Target then
return False;
end if;
if First_Time_For_THFO then
First_Time_For_THFO := False;
Integer_Sized_Small :=
UR_From_Components
(Num => Uint_1,
Den => UI_From_Int (Standard_Integer_Size - 1),
Rbase => 2);
Long_Integer_Sized_Small :=
UR_From_Components
(Num => Uint_1,
Den => UI_From_Int (Standard_Long_Integer_Size - 1),
Rbase => 2);
end if;
return Is_Fractional_Type (Base_Type (Left_Typ))
and then Is_Fractional_Type (Base_Type (Right_Typ))
and then Is_Fractional_Type (Base_Type (Result_Typ))
and then Esize (Left_Typ) = Esize (Right_Typ)
and then Esize (Left_Typ) = Esize (Result_Typ);
end Target_Has_Fixed_Ops;
function Make_CW_Equivalent_Type
(T : Entity_Id;
E : Node_Id)
return Entity_Id
is
Loc : constant Source_Ptr := Sloc (E);
Root_Typ : constant Entity_Id := Root_Type (T);
Equiv_Type : Entity_Id;
Range_Type : Entity_Id;
Str_Type : Entity_Id;
List_Def : List_Id := Empty_List;
Constr_Root : Entity_Id;
Sizexpr : Node_Id;
begin
if not Has_Discriminants (Root_Typ) then
Constr_Root := Root_Typ;
else
Constr_Root :=
Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Append_To (List_Def,
Make_Subtype_Declaration (Loc,
Defining_Identifier => Constr_Root,
Subtype_Indication =>
Make_Subtype_From_Expr (E, Root_Typ)));
end if;
Range_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('G'));
Sizexpr :=
Make_Op_Subtract (Loc,
Left_Opnd =>
Make_Attribute_Reference (Loc,
Prefix =>
OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
Attribute_Name => Name_Size),
Right_Opnd =>
Make_Attribute_Reference (Loc,
Prefix => New_Reference_To (Constr_Root, Loc),
Attribute_Name => Name_Size));
Set_Paren_Count (Sizexpr, 1);
Append_To (List_Def,
Make_Subtype_Declaration (Loc,
Defining_Identifier => Range_Type,
Subtype_Indication =>
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Reference_To (RTE (RE_Storage_Offset), Loc),
Constraint => Make_Range_Constraint (Loc,
Range_Expression =>
Make_Range (Loc,
Low_Bound => Make_Integer_Literal (Loc, 1),
High_Bound =>
Make_Op_Divide (Loc,
Left_Opnd => Sizexpr,
Right_Opnd => Make_Integer_Literal (Loc,
Intval => System_Storage_Unit)))))));
Str_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('S'));
Append_To (List_Def,
Make_Subtype_Declaration (Loc,
Defining_Identifier => Str_Type,
Subtype_Indication =>
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Reference_To (RTE (RE_Storage_Array), Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints =>
New_List (New_Reference_To (Range_Type, Loc))))));
Equiv_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('T'));
Set_Is_Frozen (Equiv_Type);
Set_Ekind (Equiv_Type, E_Record_Type);
Set_Parent_Subtype (Equiv_Type, Constr_Root);
Append_To (List_Def,
Make_Full_Type_Declaration (Loc,
Defining_Identifier => Equiv_Type,
Type_Definition =>
Make_Record_Definition (Loc,
Component_List => Make_Component_List (Loc,
Component_Items => New_List (
Make_Component_Declaration (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc, Name_uParent),
Subtype_Indication => New_Reference_To (Constr_Root, Loc)),
Make_Component_Declaration (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('C')),
Subtype_Indication => New_Reference_To (Str_Type, Loc))),
Variant_Part => Empty))));
Insert_Actions (E, List_Def);
return Equiv_Type;
end Make_CW_Equivalent_Type;
function Make_Literal_Range
(Loc : Source_Ptr;
Literal_Typ : Entity_Id)
return Node_Id
is
Lo : Node_Id :=
New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
begin
Set_Analyzed (Lo, False);
return
Make_Range (Loc,
Low_Bound => Lo,
High_Bound =>
Make_Op_Subtract (Loc,
Left_Opnd =>
Make_Op_Add (Loc,
Left_Opnd => New_Copy_Tree (Lo),
Right_Opnd =>
Make_Integer_Literal (Loc,
String_Literal_Length (Literal_Typ))),
Right_Opnd => Make_Integer_Literal (Loc, 1)));
end Make_Literal_Range;
function Make_Subtype_From_Expr
(E : Node_Id;
Unc_Typ : Entity_Id)
return Node_Id
is
Loc : constant Source_Ptr := Sloc (E);
List_Constr : List_Id := New_List;
D : Entity_Id;
Full_Subtyp : Entity_Id;
Priv_Subtyp : Entity_Id;
Utyp : Entity_Id;
Full_Exp : Node_Id;
begin
if Is_Private_Type (Unc_Typ)
and then Has_Unknown_Discriminants (Unc_Typ)
then
Utyp := Underlying_Type (Unc_Typ);
Full_Subtyp := Make_Defining_Identifier (Loc,
New_Internal_Name ('C'));
Full_Exp :=
Unchecked_Convert_To
(Utyp, Duplicate_Subexpr_No_Checks (E));
Set_Parent (Full_Exp, Parent (E));
Priv_Subtyp :=
Make_Defining_Identifier (Loc, New_Internal_Name ('P'));
Insert_Action (E,
Make_Subtype_Declaration (Loc,
Defining_Identifier => Full_Subtyp,
Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp)));
Set_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
Set_Etype (Priv_Subtyp, Unc_Typ);
Set_Scope (Priv_Subtyp, Full_Subtyp);
Set_Is_Constrained (Priv_Subtyp);
Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
Set_Is_Itype (Priv_Subtyp);
Set_Associated_Node_For_Itype (Priv_Subtyp, E);
if Is_Tagged_Type (Priv_Subtyp) then
Set_Class_Wide_Type
(Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
Set_Primitive_Operations (Priv_Subtyp,
Primitive_Operations (Unc_Typ));
end if;
Set_Full_View (Priv_Subtyp, Full_Subtyp);
return New_Reference_To (Priv_Subtyp, Loc);
elsif Is_Array_Type (Unc_Typ) then
for J in 1 .. Number_Dimensions (Unc_Typ) loop
Append_To (List_Constr,
Make_Range (Loc,
Low_Bound =>
Make_Attribute_Reference (Loc,
Prefix => Duplicate_Subexpr_No_Checks (E),
Attribute_Name => Name_First,
Expressions => New_List (
Make_Integer_Literal (Loc, J))),
High_Bound =>
Make_Attribute_Reference (Loc,
Prefix => Duplicate_Subexpr_No_Checks (E),
Attribute_Name => Name_Last,
Expressions => New_List (
Make_Integer_Literal (Loc, J)))));
end loop;
elsif Is_Class_Wide_Type (Unc_Typ) then
declare
CW_Subtype : Entity_Id;
EQ_Typ : Entity_Id := Empty;
begin
if Expander_Active and then not Java_VM then
EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
end if;
CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
Set_Equivalent_Type (CW_Subtype, EQ_Typ);
Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
return New_Occurrence_Of (CW_Subtype, Loc);
end;
else
D := First_Discriminant (Unc_Typ);
while (Present (D)) loop
Append_To (List_Constr,
Make_Selected_Component (Loc,
Prefix => Duplicate_Subexpr_No_Checks (E),
Selector_Name => New_Reference_To (D, Loc)));
Next_Discriminant (D);
end loop;
end if;
return
Make_Subtype_Indication (Loc,
Subtype_Mark => New_Reference_To (Unc_Typ, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => List_Constr));
end Make_Subtype_From_Expr;
function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
begin
if not Stack_Checking_Enabled then
return False;
elsif not Size_Known_At_Compile_Time (Typ) then
return False;
elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
return False;
elsif Is_Array_Type (Typ)
and then Present (Packed_Array_Type (Typ))
then
return May_Generate_Large_Temp (Packed_Array_Type (Typ));
else
return True;
end if;
end May_Generate_Large_Temp;
function New_Class_Wide_Subtype
(CW_Typ : Entity_Id;
N : Node_Id)
return Entity_Id
is
Res : Entity_Id := Create_Itype (E_Void, N);
Res_Name : constant Name_Id := Chars (Res);
Res_Scope : Entity_Id := Scope (Res);
begin
Copy_Node (CW_Typ, Res);
Set_Sloc (Res, Sloc (N));
Set_Is_Itype (Res);
Set_Associated_Node_For_Itype (Res, N);
Set_Is_Public (Res, False); Set_Public_Status (Res);
Set_Chars (Res, Res_Name);
Set_Scope (Res, Res_Scope);
Set_Ekind (Res, E_Class_Wide_Subtype);
Set_Next_Entity (Res, Empty);
Set_Etype (Res, Base_Type (CW_Typ));
Set_Freeze_Node (Res, Empty);
return (Res);
end New_Class_Wide_Subtype;
procedure Remove_Side_Effects
(Exp : Node_Id;
Name_Req : Boolean := False;
Variable_Ref : Boolean := False)
is
Loc : constant Source_Ptr := Sloc (Exp);
Exp_Type : constant Entity_Id := Etype (Exp);
Svg_Suppress : constant Suppress_Record := Scope_Suppress;
Def_Id : Entity_Id;
Ref_Type : Entity_Id;
Res : Node_Id;
Ptr_Typ_Decl : Node_Id;
New_Exp : Node_Id;
E : Node_Id;
function Side_Effect_Free (N : Node_Id) return Boolean;
function Side_Effect_Free (L : List_Id) return Boolean;
function Mutable_Dereference (N : Node_Id) return Boolean;
function Mutable_Dereference (N : Node_Id) return Boolean is
begin
return Nkind (N) = N_Selected_Component
and then Is_Access_Type (Etype (Prefix (N)))
and then not Is_Access_Constant (Etype (Prefix (N)))
and then Variable_Ref;
end Mutable_Dereference;
function Side_Effect_Free (N : Node_Id) return Boolean is
K : constant Node_Kind := Nkind (N);
begin
if K = N_Attribute_Reference then
return Side_Effect_Free (Expressions (N))
and then (Is_Entity_Name (Prefix (N))
or else Side_Effect_Free (Prefix (N)));
elsif Is_Entity_Name (N)
and then Ekind (Entity (N)) /= E_Function
and then (not Is_Volatile (Entity (N)) or else Name_Req)
then
if Ekind (Entity (N)) = E_Constant then
return True;
elsif Variable_Ref then
return not Is_Variable (N);
else
return True;
end if;
elsif Compile_Time_Known_Value (N) then
return True;
elsif (K = N_Integer_Literal
or else K = N_Real_Literal
or else K = N_Character_Literal
or else K = N_String_Literal
or else K = N_Null)
and then not Raises_Constraint_Error (N)
then
return True;
elsif K = N_Type_Conversion or else K = N_Qualified_Expression then
return Side_Effect_Free (Expression (N));
elsif K = N_Unchecked_Type_Conversion then
if Safe_Unchecked_Type_Conversion (N) then
return Side_Effect_Free (Expression (N));
else
return False;
end if;
elsif K in N_Unary_Op then
return Side_Effect_Free (Right_Opnd (N));
elsif K in N_Binary_Op then
return Side_Effect_Free (Left_Opnd (N))
and then Side_Effect_Free (Right_Opnd (N));
elsif K = N_Explicit_Dereference
or else K = N_Selected_Component
then
return Side_Effect_Free (Prefix (N))
and then not Mutable_Dereference (Prefix (N));
elsif K = N_Indexed_Component then
return Side_Effect_Free (Prefix (N))
and then Side_Effect_Free (Expressions (N));
elsif K = N_Unchecked_Expression then
return Side_Effect_Free (Expression (N));
elsif K = N_Function_Call
and then Nkind (Name (N)) = N_Identifier
and then Chars (Name (N)) = Name_uRep_To_Pos
then
return True;
else
return False;
end if;
end Side_Effect_Free;
function Side_Effect_Free (L : List_Id) return Boolean is
N : Node_Id;
begin
if L = No_List or else L = Error_List then
return True;
else
N := First (L);
while Present (N) loop
if not Side_Effect_Free (N) then
return False;
else
Next (N);
end if;
end loop;
return True;
end if;
end Side_Effect_Free;
begin
if Side_Effect_Free (Exp) or else not Expander_Active then
return;
end if;
Scope_Suppress := (others => True);
if Nkind (Exp) = N_Explicit_Dereference then
Def_Id :=
Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Res :=
Make_Explicit_Dereference (Loc, New_Reference_To (Def_Id, Loc));
Insert_Action (Exp,
Make_Object_Declaration (Loc,
Defining_Identifier => Def_Id,
Object_Definition =>
New_Reference_To (Etype (Prefix (Exp)), Loc),
Constant_Present => True,
Expression => Relocate_Node (Prefix (Exp))));
elsif Nkind (Exp) = N_Type_Conversion
and then (not Is_Elementary_Type (Underlying_Type (Exp_Type))
or else Nkind (Parent (Exp)) = N_Assignment_Statement)
then
Remove_Side_Effects (Expression (Exp), Variable_Ref);
Scope_Suppress := Svg_Suppress;
return;
elsif Is_Object_Reference (Exp)
and then Nkind (Exp) /= N_Function_Call
and then not Variable_Ref
and then (Name_Req
or else not Is_Entity_Name (Exp)
or else not Is_Volatile (Entity (Exp)))
and then not Is_Class_Wide_Type (Exp_Type)
then
Def_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
if Nkind (Exp) = N_Selected_Component
and then Nkind (Prefix (Exp)) = N_Function_Call
and then Is_Array_Type (Etype (Exp))
then
Res :=
Make_Selected_Component (Loc,
Prefix => New_Occurrence_Of (Def_Id, Loc),
Selector_Name => Selector_Name (Exp));
Insert_Action (Exp,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Def_Id,
Subtype_Mark =>
New_Reference_To (Base_Type (Etype (Prefix (Exp))), Loc),
Name => Relocate_Node (Prefix (Exp))));
else
Res := New_Reference_To (Def_Id, Loc);
Insert_Action (Exp,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Def_Id,
Subtype_Mark => New_Reference_To (Exp_Type, Loc),
Name => Relocate_Node (Exp)));
end if;
elsif Is_Elementary_Type (Exp_Type) then
Def_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Set_Etype (Def_Id, Exp_Type);
Res := New_Reference_To (Def_Id, Loc);
E :=
Make_Object_Declaration (Loc,
Defining_Identifier => Def_Id,
Object_Definition => New_Reference_To (Exp_Type, Loc),
Constant_Present => True,
Expression => Relocate_Node (Exp));
Set_Assignment_OK (E);
Insert_Action (Exp, E);
elsif (Nkind (Exp) = N_Unchecked_Type_Conversion
and then not Safe_Unchecked_Type_Conversion (Exp))
then
if Controlled_Type (Etype (Exp)) then
Def_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Res := New_Reference_To (Def_Id, Loc);
Insert_Action (Exp,
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Def_Id,
Subtype_Mark => New_Reference_To (Exp_Type, Loc),
Name => Relocate_Node (Exp)));
else
Def_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Set_Etype (Def_Id, Exp_Type);
Res := New_Reference_To (Def_Id, Loc);
E :=
Make_Object_Declaration (Loc,
Defining_Identifier => Def_Id,
Object_Definition => New_Reference_To (Exp_Type, Loc),
Constant_Present => True,
Expression => Relocate_Node (Exp));
Set_Assignment_OK (E);
Insert_Action (Exp, E);
end if;
else
Ref_Type := Make_Defining_Identifier (Loc, New_Internal_Name ('A'));
Ptr_Typ_Decl :=
Make_Full_Type_Declaration (Loc,
Defining_Identifier => Ref_Type,
Type_Definition =>
Make_Access_To_Object_Definition (Loc,
All_Present => True,
Subtype_Indication =>
New_Reference_To (Exp_Type, Loc)));
E := Exp;
Insert_Action (Exp, Ptr_Typ_Decl);
Def_Id := Make_Defining_Identifier (Loc, New_Internal_Name ('R'));
Set_Etype (Def_Id, Exp_Type);
Res :=
Make_Explicit_Dereference (Loc,
Prefix => New_Reference_To (Def_Id, Loc));
if Nkind (E) = N_Explicit_Dereference then
New_Exp := Relocate_Node (Prefix (E));
else
E := Relocate_Node (E);
New_Exp := Make_Reference (Loc, E);
end if;
if Nkind (E) = N_Aggregate and then Expansion_Delayed (E) then
Set_Expansion_Delayed (E, False);
Set_Analyzed (E, False);
end if;
Insert_Action (Exp,
Make_Object_Declaration (Loc,
Defining_Identifier => Def_Id,
Object_Definition => New_Reference_To (Ref_Type, Loc),
Expression => New_Exp));
end if;
Set_Assignment_OK (Res, Assignment_OK (Exp));
Rewrite (Exp, Res);
Analyze_And_Resolve (Exp, Exp_Type);
Scope_Suppress := Svg_Suppress;
end Remove_Side_Effects;
function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
Otyp : Entity_Id;
Ityp : Entity_Id;
Oalign : Uint;
Ialign : Uint;
Pexp : constant Node_Id := Parent (Exp);
begin
if (Nkind (Pexp) = N_Assignment_Statement
and then Expression (Pexp) = Exp)
or else Nkind (Pexp) = N_Object_Declaration
or else Nkind (Pexp) = N_Object_Renaming_Declaration
then
return True;
elsif Nkind (Pexp) = N_Selected_Component
and then Prefix (Pexp) = Exp
then
if No (Etype (Pexp)) then
return True;
else
return
not Has_Discriminants (Etype (Pexp))
or else Is_Constrained (Etype (Pexp));
end if;
end if;
if Present (Etype (Exp)) then
Otyp := Etype (Exp);
else
Otyp := Entity (Subtype_Mark (Exp));
end if;
Ityp := Etype (Expression (Exp));
Oalign := No_Uint;
Ialign := No_Uint;
if Present (Underlying_Type (Otyp)) then
Otyp := Underlying_Type (Otyp);
end if;
if Present (Underlying_Type (Ityp)) then
Ityp := Underlying_Type (Ityp);
end if;
if Is_Concurrent_Type (Otyp) then
Otyp := Corresponding_Record_Type (Otyp);
end if;
if Is_Concurrent_Type (Ityp) then
Ityp := Corresponding_Record_Type (Ityp);
end if;
if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
return True;
elsif Size_Known_At_Compile_Time (Otyp)
and then not May_Generate_Large_Temp (Otyp)
and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
then
return True;
elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
return True;
elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
return True;
elsif Is_Packed_Array_Type (Otyp)
or else Is_Packed_Array_Type (Ityp)
then
return True;
end if;
if Present (Alignment_Clause (Otyp)) then
Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
elsif Is_Array_Type (Otyp)
and then Present (Alignment_Clause (Component_Type (Otyp)))
then
Oalign := Expr_Value (Expression (Alignment_Clause
(Component_Type (Otyp))));
end if;
if Present (Alignment_Clause (Ityp)) then
Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
elsif Is_Array_Type (Ityp)
and then Present (Alignment_Clause (Component_Type (Ityp)))
then
Ialign := Expr_Value (Expression (Alignment_Clause
(Component_Type (Ityp))));
end if;
if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
return True;
elsif Ialign /= No_Uint and then Oalign /= No_Uint
and then Ialign <= Oalign
then
return True;
else
return False;
end if;
end Safe_Unchecked_Type_Conversion;
procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
Loc : constant Source_Ptr := Sloc (N);
Asn : Node_Id;
begin
if Present (Elaboration_Entity (Spec_Id)) then
if Nkind (Parent (N)) = N_Compilation_Unit then
null;
else
Check_Restriction (No_Elaboration_Code, N);
Asn :=
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (Elaboration_Entity (Spec_Id), Loc),
Expression => New_Occurrence_Of (Standard_True, Loc));
if Nkind (Parent (N)) = N_Subunit then
Insert_After (Corresponding_Stub (Parent (N)), Asn);
else
Insert_After (N, Asn);
end if;
Analyze (Asn);
end if;
end if;
end Set_Elaboration_Flag;
procedure Wrap_Cleanup_Procedure (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Stseq : constant Node_Id := Handled_Statement_Sequence (N);
Stmts : constant List_Id := Statements (Stseq);
begin
if Abort_Allowed then
Prepend_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Defer));
Append_To (Stmts, Build_Runtime_Call (Loc, RE_Abort_Undefer));
end if;
end Wrap_Cleanup_Procedure;
end Exp_Util;