aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch3.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_ch3.adb')
-rw-r--r--gcc/ada/exp_ch3.adb671
1 files changed, 500 insertions, 171 deletions
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 82a58b7..0b601c5 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2020, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -37,6 +37,7 @@ with Exp_Ch9; use Exp_Ch9;
with Exp_Dbug; use Exp_Dbug;
with Exp_Disp; use Exp_Disp;
with Exp_Dist; use Exp_Dist;
+with Exp_Put_Image;
with Exp_Smem; use Exp_Smem;
with Exp_Strm; use Exp_Strm;
with Exp_Tss; use Exp_Tss;
@@ -183,11 +184,11 @@ package body Exp_Ch3 is
-- 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; Proc_Id : Entity_Id) return List_Id;
-- This function builds the list of formals for an initialization routine.
-- The first formal is always _Init with the given type. For task value
-- record types and types containing tasks, three additional formals are
- -- added:
+ -- added and Proc_Id is decorated with attribute Has_Master_Entity:
--
-- _Master : Master_Id
-- _Chain : in out Activation_Chain
@@ -265,6 +266,7 @@ package body Exp_Ch3 is
-- typSW provides result of 'Write attribute
-- typSI provides result of 'Input attribute
-- typSO provides result of 'Output attribute
+ -- typPI provides result of 'Put_Image attribute
--
-- The following entries are additionally present for non-limited tagged
-- types, and implement additional dispatching operations for predefined
@@ -513,6 +515,76 @@ package body Exp_Ch3 is
end loop;
end Adjust_Discriminants;
+ ------------------------------------------
+ -- Build_Access_Subprogram_Wrapper_Body --
+ ------------------------------------------
+
+ procedure Build_Access_Subprogram_Wrapper_Body
+ (Decl : Node_Id;
+ New_Decl : Node_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (Decl);
+ Actuals : constant List_Id := New_List;
+ Type_Def : constant Node_Id := Type_Definition (Decl);
+ Type_Id : constant Entity_Id := Defining_Identifier (Decl);
+ Spec_Node : constant Node_Id :=
+ Copy_Subprogram_Spec (Specification (New_Decl));
+ -- This copy creates new identifiers for formals and subprogram.
+
+ Act : Node_Id;
+ Body_Node : Node_Id;
+ Call_Stmt : Node_Id;
+ Ptr : Entity_Id;
+
+ begin
+ if not Expander_Active then
+ return;
+ end if;
+
+ -- Create List of actuals for indirect call. The last parameter of the
+ -- subprogram declaration is the access value for the indirect call.
+
+ Act := First (Parameter_Specifications (Spec_Node));
+
+ while Present (Act) loop
+ exit when Act = Last (Parameter_Specifications (Spec_Node));
+ Append_To (Actuals,
+ Make_Identifier (Loc, Chars (Defining_Identifier (Act))));
+ Next (Act);
+ end loop;
+
+ Ptr :=
+ Defining_Identifier
+ (Last (Parameter_Specifications (Specification (New_Decl))));
+
+ if Nkind (Type_Def) = N_Access_Procedure_Definition then
+ Call_Stmt := Make_Procedure_Call_Statement (Loc,
+ Name =>
+ Make_Explicit_Dereference
+ (Loc, New_Occurrence_Of (Ptr, Loc)),
+ Parameter_Associations => Actuals);
+ else
+ Call_Stmt := Make_Simple_Return_Statement (Loc,
+ Expression =>
+ Make_Function_Call (Loc,
+ Name => Make_Explicit_Dereference
+ (Loc, New_Occurrence_Of (Ptr, Loc)),
+ Parameter_Associations => Actuals));
+ end if;
+
+ Body_Node := Make_Subprogram_Body (Loc,
+ Specification => Spec_Node,
+ Declarations => New_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Call_Stmt)));
+
+ -- Place body in list of freeze actions for the type.
+
+ Ensure_Freeze_Node (Type_Id);
+ Append_Freeze_Actions (Type_Id, New_List (Body_Node));
+ end Build_Access_Subprogram_Wrapper_Body;
+
---------------------------
-- Build_Array_Init_Proc --
---------------------------
@@ -728,7 +800,7 @@ package body Exp_Ch3 is
end if;
Body_Stmts := Init_One_Dimension (1);
- Parameters := Init_Formals (A_Type);
+ Parameters := Init_Formals (A_Type, Proc_Id);
Discard_Node (
Make_Subprogram_Body (Loc,
@@ -1209,6 +1281,17 @@ package body Exp_Ch3 is
then
Initialization_Warning (T);
return Empty;
+
+ -- We need to return empty if the type has predicates because
+ -- this would otherwise duplicate calls to the predicate
+ -- function. If the type hasn't been frozen before being
+ -- referenced in the current record, the extraneous call to
+ -- the predicate function would be inserted somewhere before
+ -- the predicate function is elaborated, which would result in
+ -- an invalid tree.
+
+ elsif Has_Predicates (Etype (Comp)) then
+ return Empty;
end if;
elsif Is_Scalar_Type (Etype (Comp)) then
@@ -1893,8 +1976,8 @@ package body Exp_Ch3 is
-- traversing the expression. ???
if Kind = N_Attribute_Reference
- and then Nam_In (Attribute_Name (Default), Name_Unchecked_Access,
- Name_Unrestricted_Access)
+ and then Attribute_Name (Default) in Name_Unchecked_Access
+ | Name_Unrestricted_Access
and then Is_Entity_Name (Prefix (Default))
and then Is_Type (Entity (Prefix (Default)))
and then Entity (Prefix (Default)) = Rec_Type
@@ -1957,7 +2040,7 @@ package body Exp_Ch3 is
end if;
if Needs_Finalization (Typ)
- and then not (Nkind_In (Kind, N_Aggregate, N_Extension_Aggregate))
+ and then Kind not in N_Aggregate | N_Extension_Aggregate
and then not Is_Build_In_Place_Function_Call (Exp)
then
Adj_Call :=
@@ -1978,9 +2061,7 @@ package body Exp_Ch3 is
-- which provides for a better error message.
if Comes_From_Source (Exp)
- and then Has_Predicates (Typ)
- and then not Predicate_Checks_Suppressed (Empty)
- and then not Predicates_Ignored (Typ)
+ and then Predicate_Enabled (Typ)
then
Append (Make_Predicate_Check (Typ, Exp), Res);
end if;
@@ -2230,8 +2311,9 @@ package body Exp_Ch3 is
Prefix =>
Make_Selected_Component (Loc,
Prefix =>
- Unchecked_Convert_To (Acc_Type,
- Make_Identifier (Loc, Name_uO)),
+ Make_Explicit_Dereference (Loc,
+ Unchecked_Convert_To (Acc_Type,
+ Make_Identifier (Loc, Name_uO))),
Selector_Name =>
New_Occurrence_Of (Iface_Comp, Loc)),
Attribute_Name => Name_Position))))));
@@ -2410,7 +2492,7 @@ package body Exp_Ch3 is
Proc_Spec_Node := New_Node (N_Procedure_Specification, Loc);
Set_Defining_Unit_Name (Proc_Spec_Node, Proc_Id);
- Parameters := Init_Formals (Rec_Type);
+ Parameters := Init_Formals (Rec_Type, Proc_Id);
Append_List_To (Parameters,
Build_Discriminant_Formals (Rec_Type, True));
@@ -2824,16 +2906,16 @@ package body Exp_Ch3 is
---------------------------
function Build_Init_Statements (Comp_List : Node_Id) return List_Id is
- Checks : constant List_Id := New_List;
- Actions : List_Id := No_List;
- Counter_Id : Entity_Id := Empty;
- Comp_Loc : Source_Ptr;
- Decl : Node_Id;
- Has_POC : Boolean;
- Id : Entity_Id;
- Parent_Stmts : List_Id;
- Stmts : List_Id;
- Typ : Entity_Id;
+ Checks : constant List_Id := New_List;
+ Actions : List_Id := No_List;
+ Counter_Id : Entity_Id := Empty;
+ Comp_Loc : Source_Ptr;
+ Decl : Node_Id;
+ Has_Late_Init_Comp : Boolean;
+ Id : Entity_Id;
+ Parent_Stmts : List_Id;
+ Stmts : List_Id;
+ Typ : Entity_Id;
procedure Increment_Counter (Loc : Source_Ptr);
-- Generate an "increment by one" statement for the current counter
@@ -2844,6 +2926,12 @@ package body Exp_Ch3 is
-- creates a new defining Id, adds an object declaration and sets
-- the Id generator for the next variant.
+ function Requires_Late_Initialization
+ (Decl : Node_Id;
+ Rec_Type : Entity_Id) return Boolean;
+ -- Return whether the given Decl requires late initialization, as
+ -- defined by 3.3.1 (8.1/5).
+
-----------------------
-- Increment_Counter --
-----------------------
@@ -2890,6 +2978,158 @@ package body Exp_Ch3 is
Make_Integer_Literal (Loc, 0)));
end Make_Counter;
+ ----------------------------------
+ -- Requires_Late_Initialization --
+ ----------------------------------
+
+ function Requires_Late_Initialization
+ (Decl : Node_Id;
+ Rec_Type : Entity_Id) return Boolean
+ is
+ References_Current_Instance : Boolean := False;
+ Has_Access_Discriminant : Boolean := False;
+ Has_Internal_Call : Boolean := False;
+
+ function Find_Access_Discriminant
+ (N : Node_Id) return Traverse_Result;
+ -- Look for a name denoting an access discriminant
+
+ function Find_Current_Instance
+ (N : Node_Id) return Traverse_Result;
+ -- Look for a reference to the current instance of the type
+
+ function Find_Internal_Call
+ (N : Node_Id) return Traverse_Result;
+ -- Look for an internal protected function call
+
+ ------------------------------
+ -- Find_Access_Discriminant --
+ ------------------------------
+
+ function Find_Access_Discriminant
+ (N : Node_Id) return Traverse_Result is
+ begin
+ if Is_Entity_Name (N)
+ and then Denotes_Discriminant (N)
+ and then Is_Access_Type (Etype (N))
+ then
+ Has_Access_Discriminant := True;
+ return Abandon;
+ else
+ return OK;
+ end if;
+ end Find_Access_Discriminant;
+
+ ---------------------------
+ -- Find_Current_Instance --
+ ---------------------------
+
+ function Find_Current_Instance
+ (N : Node_Id) return Traverse_Result is
+ begin
+ if Nkind (N) = N_Attribute_Reference
+ and then Is_Access_Type (Etype (N))
+ and then Is_Entity_Name (Prefix (N))
+ and then Is_Type (Entity (Prefix (N)))
+ then
+ References_Current_Instance := True;
+ return Abandon;
+ else
+ return OK;
+ end if;
+ end Find_Current_Instance;
+
+ ------------------------
+ -- Find_Internal_Call --
+ ------------------------
+
+ function Find_Internal_Call (N : Node_Id) return Traverse_Result is
+
+ function Call_Scope (N : Node_Id) return Entity_Id;
+ -- Return the scope enclosing a given call node N
+
+ ----------------
+ -- Call_Scope --
+ ----------------
+
+ function Call_Scope (N : Node_Id) return Entity_Id is
+ Nam : constant Node_Id := Name (N);
+ begin
+ if Nkind (Nam) = N_Selected_Component then
+ return Scope (Entity (Prefix (Nam)));
+ else
+ return Scope (Entity (Nam));
+ end if;
+ end Call_Scope;
+
+ begin
+ if Nkind (N) = N_Function_Call
+ and then Call_Scope (N)
+ = Corresponding_Concurrent_Type (Rec_Type)
+ then
+ Has_Internal_Call := True;
+ return Abandon;
+ else
+ return OK;
+ end if;
+ end Find_Internal_Call;
+
+ procedure Search_Access_Discriminant is new
+ Traverse_Proc (Find_Access_Discriminant);
+
+ procedure Search_Current_Instance is new
+ Traverse_Proc (Find_Current_Instance);
+
+ procedure Search_Internal_Call is new
+ Traverse_Proc (Find_Internal_Call);
+
+ begin
+ -- A component of an object is said to require late initialization
+ -- if:
+
+ -- it has an access discriminant value constrained by a per-object
+ -- expression;
+
+ if Has_Access_Constraint (Defining_Identifier (Decl))
+ and then No (Expression (Decl))
+ then
+ return True;
+
+ elsif Present (Expression (Decl)) then
+
+ -- it has an initialization expression that includes a name
+ -- denoting an access discriminant;
+
+ Search_Access_Discriminant (Expression (Decl));
+
+ if Has_Access_Discriminant then
+ return True;
+ end if;
+
+ -- or it has an initialization expression that includes a
+ -- reference to the current instance of the type either by
+ -- name...
+
+ Search_Current_Instance (Expression (Decl));
+
+ if References_Current_Instance then
+ return True;
+ end if;
+
+ -- ...or implicitly as the target object of a call.
+
+ if Is_Protected_Record_Type (Rec_Type) then
+ Search_Internal_Call (Expression (Decl));
+
+ if Has_Internal_Call then
+ return True;
+ end if;
+ end if;
+ end if;
+
+ return False;
+ end Requires_Late_Initialization;
+
-- Start of processing for Build_Init_Statements
begin
@@ -2943,10 +3183,9 @@ package body Exp_Ch3 is
-- Loop through components, skipping pragmas, in 2 steps. The first
-- step deals with regular components. The second step deals with
- -- components that have per object constraints and no explicit
- -- initialization.
+ -- components that require late initialization.
- Has_POC := False;
+ Has_Late_Init_Comp := False;
-- First pass : regular components
@@ -2959,11 +3198,11 @@ package body Exp_Ch3 is
Id := Defining_Identifier (Decl);
Typ := Etype (Id);
- -- Leave any processing of per-object constrained component for
- -- the second pass.
+ -- Leave any processing of component requiring late initialization
+ -- for the second pass.
- if Has_Access_Constraint (Id) and then No (Expression (Decl)) then
- Has_POC := True;
+ if Requires_Late_Initialization (Decl, Rec_Type) then
+ Has_Late_Init_Comp := True;
-- Regular component cases
@@ -3004,10 +3243,10 @@ package body Exp_Ch3 is
elsif Ekind (Scope (Id)) = E_Record_Type
and then Present (Corresponding_Concurrent_Type (Scope (Id)))
- and then Nam_In (Chars (Id), Name_uCPU,
- Name_uDispatching_Domain,
- Name_uPriority,
- Name_uSecondary_Stack_Size)
+ and then Chars (Id) in Name_uCPU
+ | Name_uDispatching_Domain
+ | Name_uPriority
+ | Name_uSecondary_Stack_Size
then
declare
Exp : Node_Id;
@@ -3265,19 +3504,21 @@ package body Exp_Ch3 is
Make_Initialize_Protection (Rec_Type));
end if;
- -- Second pass: components with per-object constraints
+ -- Second pass: components that require late initialization
- if Has_POC then
+ if Has_Late_Init_Comp then
Decl := First_Non_Pragma (Component_Items (Comp_List));
while Present (Decl) loop
Comp_Loc := Sloc (Decl);
Id := Defining_Identifier (Decl);
Typ := Etype (Id);
- if Has_Access_Constraint (Id)
- and then No (Expression (Decl))
- then
- if Has_Non_Null_Base_Init_Proc (Typ) then
+ if Requires_Late_Initialization (Decl, Rec_Type) then
+ if Present (Expression (Decl)) then
+ Append_List_To (Stmts,
+ Build_Assignment (Id, Expression (Decl)));
+
+ elsif Has_Non_Null_Base_Init_Proc (Typ) then
Append_List_To (Stmts,
Build_Initialization_Call (Comp_Loc,
Make_Selected_Component (Comp_Loc,
@@ -3300,7 +3541,6 @@ package body Exp_Ch3 is
Increment_Counter (Comp_Loc);
end if;
-
elsif Component_Needs_Simple_Initialization (Typ) then
Append_List_To (Stmts,
Build_Assignment
@@ -4454,6 +4694,8 @@ package body Exp_Ch3 is
procedure Check_Attr (Nam : Name_Id; TSS_Nam : TSS_Name_Type) is
begin
+ -- Move this check to sem???
+
if not Stream_Attribute_Available (Etype (Comp), TSS_Nam) then
Error_Msg_Name_1 := Nam;
Error_Msg_N
@@ -4503,6 +4745,47 @@ package body Exp_Ch3 is
end if;
end Clean_Task_Names;
+ ----------------------------------------
+ -- Ensure_Activation_Chain_And_Master --
+ ----------------------------------------
+
+ procedure Ensure_Activation_Chain_And_Master (Obj_Decl : Node_Id) is
+ Def_Id : constant Entity_Id := Defining_Identifier (Obj_Decl);
+ Expr : constant Node_Id := Expression (Obj_Decl);
+ Expr_Q : Node_Id;
+ Typ : constant Entity_Id := Etype (Def_Id);
+
+ begin
+ pragma Assert (Nkind (Obj_Decl) = N_Object_Declaration);
+
+ if Has_Task (Typ) or else Might_Have_Tasks (Typ) then
+ Build_Activation_Chain_Entity (Obj_Decl);
+
+ if Has_Task (Typ) then
+ Build_Master_Entity (Def_Id);
+
+ -- Handle objects initialized with BIP function calls
+
+ elsif Present (Expr) then
+ if Nkind (Expr) = N_Qualified_Expression then
+ Expr_Q := Expression (Expr);
+ else
+ Expr_Q := Expr;
+ end if;
+
+ if Is_Build_In_Place_Function_Call (Expr_Q)
+ or else Present (Unqual_BIP_Iface_Function_Call (Expr_Q))
+ or else
+ (Nkind (Expr_Q) = N_Reference
+ and then
+ Is_Build_In_Place_Function_Call (Prefix (Expr_Q)))
+ then
+ Build_Master_Entity (Def_Id);
+ end if;
+ end if;
+ end if;
+ end Ensure_Activation_Chain_And_Master;
+
------------------------------
-- Expand_Freeze_Array_Type --
------------------------------
@@ -4670,6 +4953,7 @@ package body Exp_Ch3 is
Ent : Entity_Id;
Fent : Entity_Id;
Is_Contiguous : Boolean;
+ Index_Typ : Entity_Id;
Ityp : Entity_Id;
Last_Repval : Uint;
Lst : List_Id;
@@ -4686,81 +4970,99 @@ package body Exp_Ch3 is
Ent := First_Literal (Typ);
Last_Repval := Enumeration_Rep (Ent);
-
+ Num := 1;
Next_Literal (Ent);
+
while Present (Ent) loop
if Enumeration_Rep (Ent) - Last_Repval /= 1 then
Is_Contiguous := False;
- exit;
else
Last_Repval := Enumeration_Rep (Ent);
end if;
+ Num := Num + 1;
Next_Literal (Ent);
end loop;
if Is_Contiguous then
Set_Has_Contiguous_Rep (Typ);
- Ent := First_Literal (Typ);
- Num := 1;
- Lst := New_List (New_Occurrence_Of (Ent, Sloc (Ent)));
+
+ -- Now build a subtype declaration
+
+ -- subtype typI is new Natural range 0 .. num - 1
+
+ Index_Typ :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_External_Name (Chars (Typ), 'I'));
+
+ Append_Freeze_Action (Typ,
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => Index_Typ,
+ Subtype_Indication =>
+ Make_Subtype_Indication (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Standard_Natural, Loc),
+ Constraint =>
+ Make_Range_Constraint (Loc,
+ Range_Expression =>
+ Make_Range (Loc,
+ Low_Bound =>
+ Make_Integer_Literal (Loc, 0),
+ High_Bound =>
+ Make_Integer_Literal (Loc, Num - 1))))));
+
+ Set_Enum_Pos_To_Rep (Typ, Index_Typ);
else
-- Build list of literal references
Lst := New_List;
- Num := 0;
-
Ent := First_Literal (Typ);
while Present (Ent) loop
Append_To (Lst, New_Occurrence_Of (Ent, Sloc (Ent)));
- Num := Num + 1;
Next_Literal (Ent);
end loop;
- end if;
-
- -- Now build an array declaration
- -- typA : array (Natural range 0 .. num - 1) of ctype :=
- -- (v, v, v, v, v, ....)
+ -- Now build an array declaration
- -- where ctype is the corresponding integer type. If the representation
- -- is contiguous, we only keep the first literal, which provides the
- -- offset for Pos_To_Rep computations.
+ -- typA : constant array (Natural range 0 .. num - 1) of typ :=
+ -- (v, v, v, v, v, ....)
- Arr :=
- Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (Typ), 'A'));
+ Arr :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_External_Name (Chars (Typ), 'A'));
- Append_Freeze_Action (Typ,
- Make_Object_Declaration (Loc,
- Defining_Identifier => Arr,
- Constant_Present => True,
-
- Object_Definition =>
- Make_Constrained_Array_Definition (Loc,
- Discrete_Subtype_Definitions => New_List (
- Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Occurrence_Of (Standard_Natural, Loc),
- Constraint =>
- Make_Range_Constraint (Loc,
- Range_Expression =>
- Make_Range (Loc,
- Low_Bound =>
- Make_Integer_Literal (Loc, 0),
- High_Bound =>
- Make_Integer_Literal (Loc, Num - 1))))),
-
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication => New_Occurrence_Of (Typ, Loc))),
+ Append_Freeze_Action (Typ,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Arr,
+ Constant_Present => True,
+
+ Object_Definition =>
+ Make_Constrained_Array_Definition (Loc,
+ Discrete_Subtype_Definitions => New_List (
+ Make_Subtype_Indication (Loc,
+ Subtype_Mark =>
+ New_Occurrence_Of (Standard_Natural, Loc),
+ Constraint =>
+ Make_Range_Constraint (Loc,
+ Range_Expression =>
+ Make_Range (Loc,
+ Low_Bound =>
+ Make_Integer_Literal (Loc, 0),
+ High_Bound =>
+ Make_Integer_Literal (Loc, Num - 1))))),
+
+ Component_Definition =>
+ Make_Component_Definition (Loc,
+ Aliased_Present => False,
+ Subtype_Indication => New_Occurrence_Of (Typ, Loc))),
- Expression =>
- Make_Aggregate (Loc,
- Expressions => Lst)));
+ Expression =>
+ Make_Aggregate (Loc,
+ Expressions => Lst)));
- Set_Enum_Pos_To_Rep (Typ, Arr);
+ Set_Enum_Pos_To_Rep (Typ, Arr);
+ end if;
-- Now we build the function that converts representation values to
-- position values. This function has the form:
@@ -4806,7 +5108,7 @@ package body Exp_Ch3 is
if Esize (Typ) <= Standard_Integer_Size then
Ityp := Standard_Integer;
else
- Ityp := Universal_Integer;
+ Ityp := Standard_Long_Long_Integer;
end if;
-- Representations are unsigned
@@ -5503,7 +5805,7 @@ package body Exp_Ch3 is
-- limited-with'ed package, we need to use the nonlimited view in
-- case it has tasks.
- if Ekind (Desig_Typ) in Incomplete_Kind
+ if Is_Incomplete_Type (Desig_Typ)
and then Present (Non_Limited_View (Desig_Typ))
then
Desig_Typ := Non_Limited_View (Desig_Typ);
@@ -5513,7 +5815,7 @@ package body Exp_Ch3 is
-- record parameter for an entry declaration. No master is created
-- for such a type.
- if Comes_From_Source (N) and then Has_Task (Desig_Typ) then
+ if Has_Task (Desig_Typ) then
Build_Master_Entity (Ptr_Typ);
Build_Master_Renaming (Ptr_Typ);
@@ -5527,12 +5829,11 @@ package body Exp_Ch3 is
-- Suppress the master creation for access types created for entry
-- formal parameters (parameter block component types). Seems like
-- suppression should be more general for compiler-generated types,
- -- but testing Comes_From_Source, like the code above does, may be
- -- too general in this case (affects some test output)???
+ -- but testing Comes_From_Source may be too general in this case
+ -- (affects some test output)???
elsif not Is_Param_Block_Component_Type (Ptr_Typ)
and then Is_Limited_Class_Wide_Type (Desig_Typ)
- and then Tasking_Allowed
then
Build_Class_Wide_Master (Ptr_Typ);
end if;
@@ -5579,7 +5880,7 @@ package body Exp_Ch3 is
declare
Comp : Entity_Id;
First : Boolean;
- M_Id : Entity_Id;
+ M_Id : Entity_Id := Empty;
Typ : Entity_Id;
begin
@@ -5597,7 +5898,10 @@ package body Exp_Ch3 is
Typ := Etype (Comp);
if Ekind (Typ) = E_Anonymous_Access_Type
- and then Has_Task (Available_View (Designated_Type (Typ)))
+ and then
+ (Has_Task (Available_View (Designated_Type (Typ)))
+ or else
+ Might_Have_Tasks (Available_View (Designated_Type (Typ))))
and then No (Master_Id (Typ))
then
-- Ensure that the record or array type have a _master
@@ -5612,6 +5916,7 @@ package body Exp_Ch3 is
-- Reuse the same master to service any additional types
else
+ pragma Assert (Present (M_Id));
Set_Master_Id (Typ, M_Id);
end if;
end if;
@@ -6431,9 +6736,9 @@ package body Exp_Ch3 is
and then Building_Static_Dispatch_Tables
and then Is_Library_Level_Entity (Def_Id)
and then Is_Library_Level_Tagged_Type (Base_Typ)
- and then Ekind_In (Base_Typ, E_Record_Type,
- E_Protected_Type,
- E_Task_Type)
+ and then Ekind (Base_Typ) in E_Record_Type
+ | E_Protected_Type
+ | E_Task_Type
and then not Has_Dispatch_Table (Base_Typ)
then
declare
@@ -6458,15 +6763,12 @@ package body Exp_Ch3 is
Init_After := Make_Shared_Var_Procs (N);
end if;
- -- If tasks being declared, make sure we have an activation chain
+ -- If tasks are being declared, make sure we have an activation chain
-- defined for the tasks (has no effect if we already have one), and
- -- also that a Master variable is established and that the appropriate
- -- enclosing construct is established as a task master.
+ -- also that a Master variable is established (and that the appropriate
+ -- enclosing construct is established as a task master).
- if Has_Task (Typ) then
- Build_Activation_Chain_Entity (N);
- Build_Master_Entity (Def_Id);
- end if;
+ Ensure_Activation_Chain_And_Master (N);
-- If No_Implicit_Heap_Allocations or No_Implicit_Task_Allocations
-- restrictions are active then default-sized secondary stacks are
@@ -6483,11 +6785,11 @@ package body Exp_Ch3 is
-- of the stacks in this scenario, the stacks of the first array are
-- not counted.
- if Has_Task (Typ)
+ if (Has_Task (Typ) or else Might_Have_Tasks (Typ))
and then not Restriction_Active (No_Secondary_Stack)
and then (Restriction_Active (No_Implicit_Heap_Allocations)
or else Restriction_Active (No_Implicit_Task_Allocations))
- and then not (Ekind_In (Ekind (Typ), E_Array_Type, E_Array_Subtype)
+ and then not (Ekind (Typ) in E_Array_Type | E_Array_Subtype
and then (Has_Init_Expression (N)))
then
declare
@@ -6609,9 +6911,13 @@ package body Exp_Ch3 is
-- An aggregate that must be built in place is not resolved and
-- expanded until the enclosing construct is expanded. This will
-- happen when the aggregate is limited and the declared object
- -- has a following address clause.
+ -- has a following address clause; it happens also when generating
+ -- C code for an aggregate that has an alignment or address clause
+ -- (see Analyze_Object_Declaration).
- if Is_Limited_Type (Typ) and then not Analyzed (Expr) then
+ if (Is_Limited_Type (Typ) or else Modify_Tree_For_C)
+ and then not Analyzed (Expr)
+ then
Resolve (Expr, Typ);
end if;
@@ -7150,21 +7456,32 @@ package body Exp_Ch3 is
Chars =>
New_External_Name (Chars (Def_Id), Suffix => "L"));
- Level_Expr : Node_Id;
Level_Decl : Node_Id;
+ Level_Expr : Node_Id;
begin
Set_Ekind (Level, Ekind (Def_Id));
Set_Etype (Level, Standard_Natural);
Set_Scope (Level, Scope (Def_Id));
- if No (Expr) then
-
- -- Set accessibility level of null
+ -- Set accessibility level of null
+ if No (Expr) then
Level_Expr :=
Make_Integer_Literal (Loc, Scope_Depth (Standard_Standard));
+ -- When the expression of the object is a function which returns
+ -- an anonymous access type the master of the call is the object
+ -- being initialized instead of the type.
+
+ elsif Nkind (Expr) = N_Function_Call
+ and then Ekind (Etype (Name (Expr))) = E_Anonymous_Access_Type
+ then
+ Level_Expr := Make_Integer_Literal (Loc,
+ Object_Access_Level (Def_Id));
+
+ -- General case
+
else
Level_Expr := Dynamic_Accessibility_Level (Expr);
end if;
@@ -7196,6 +7513,7 @@ package body Exp_Ch3 is
and then Has_DIC (Typ)
and then Present (DIC_Procedure (Typ))
and then not Has_Init_Expression (N)
+ and then not Is_Imported (Def_Id)
then
declare
DIC_Call : constant Node_Id := Build_DIC_Call (Loc, Def_Id, Typ);
@@ -7241,9 +7559,7 @@ package body Exp_Ch3 is
-- debug information, even though it is defined by a generated
-- renaming that does not come from source.
- if Comes_From_Source (Defining_Identifier (N)) then
- Set_Debug_Info_Needed (Defining_Identifier (N));
- end if;
+ Set_Debug_Info_Defining_Id (N);
-- Now call the routine to generate debug info for the renaming
@@ -7268,10 +7584,7 @@ package body Exp_Ch3 is
-- Expand_N_Subtype_Indication --
---------------------------------
- -- Add a check on the range of the subtype. The static case is partially
- -- duplicated by Process_Range_Expr_In_Decl in Sem_Ch3, but we still need
- -- to check here for the static case in order to avoid generating
- -- extraneous expanded code. Also deal with validity checking.
+ -- Add a check on the range of the subtype and deal with validity checking
procedure Expand_N_Subtype_Indication (N : Node_Id) is
Ran : constant Node_Id := Range_Expression (Constraint (N));
@@ -7282,7 +7595,12 @@ package body Exp_Ch3 is
Validity_Check_Range (Range_Expression (Constraint (N)));
end if;
- if Nkind_In (Parent (N), N_Constrained_Array_Definition, N_Slice) then
+ -- Do not duplicate the work of Process_Range_Expr_In_Decl in Sem_Ch3
+
+ if Nkind (Parent (N)) in N_Constrained_Array_Definition | N_Slice
+ and then Nkind (Parent (Parent (N))) not in
+ N_Full_Type_Declaration | N_Object_Declaration
+ then
Apply_Range_Check (Ran, Typ);
end if;
end Expand_N_Subtype_Indication;
@@ -7714,7 +8032,7 @@ package body Exp_Ch3 is
-- See GNAT Pool packages in the Run-Time for more details
- elsif Ekind_In (Def_Id, E_Access_Type, E_General_Access_Type) then
+ elsif Ekind (Def_Id) in E_Access_Type | E_General_Access_Type then
declare
Loc : constant Source_Ptr := Sloc (N);
Desig_Type : constant Entity_Id := Designated_Type (Def_Id);
@@ -7833,61 +8151,44 @@ package body Exp_Ch3 is
elsif Ada_Version >= Ada_2012
and then Present (Associated_Storage_Pool (Def_Id))
-
- -- Omit this check for the case of a configurable run-time that
- -- does not provide package System.Storage_Pools.Subpools.
-
- and then RTE_Available (RE_Root_Storage_Pool_With_Subpools)
+ and then RTU_Loaded (System_Storage_Pools_Subpools)
then
declare
Loc : constant Source_Ptr := Sloc (Def_Id);
Pool : constant Entity_Id :=
Associated_Storage_Pool (Def_Id);
- RSPWS : constant Entity_Id :=
- RTE (RE_Root_Storage_Pool_With_Subpools);
begin
-- It is known that the accessibility level of the access
-- type is deeper than that of the pool.
if Type_Access_Level (Def_Id) > Object_Access_Level (Pool)
+ and then Is_Class_Wide_Type (Etype (Pool))
and then not Accessibility_Checks_Suppressed (Def_Id)
and then not Accessibility_Checks_Suppressed (Pool)
then
- -- Static case: the pool is known to be a descendant of
- -- Root_Storage_Pool_With_Subpools.
-
- if Is_Ancestor (RSPWS, Etype (Pool)) then
- Error_Msg_N
- ("??subpool access type has deeper accessibility "
- & "level than pool", Def_Id);
-
- Append_Freeze_Action (Def_Id,
- Make_Raise_Program_Error (Loc,
- Reason => PE_Accessibility_Check_Failed));
-
- -- Dynamic case: when the pool is of a class-wide type,
- -- it may or may not support subpools depending on the
- -- path of derivation. Generate:
+ -- When the pool is of a class-wide type, it may or may
+ -- not support subpools depending on the path of
+ -- derivation. Generate:
-- if Def_Id in RSPWS'Class then
-- raise Program_Error;
-- end if;
- elsif Is_Class_Wide_Type (Etype (Pool)) then
- Append_Freeze_Action (Def_Id,
- Make_If_Statement (Loc,
- Condition =>
- Make_In (Loc,
- Left_Opnd => New_Occurrence_Of (Pool, Loc),
- Right_Opnd =>
- New_Occurrence_Of
- (Class_Wide_Type (RSPWS), Loc)),
-
- Then_Statements => New_List (
- Make_Raise_Program_Error (Loc,
- Reason => PE_Accessibility_Check_Failed))));
- end if;
+ Append_Freeze_Action (Def_Id,
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_In (Loc,
+ Left_Opnd => New_Occurrence_Of (Pool, Loc),
+ Right_Opnd =>
+ New_Occurrence_Of
+ (Class_Wide_Type
+ (RTE
+ (RE_Root_Storage_Pool_With_Subpools)),
+ Loc)),
+ Then_Statements => New_List (
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Accessibility_Check_Failed))));
end if;
end;
end if;
@@ -8019,7 +8320,7 @@ package body Exp_Ch3 is
-- subtypes to which these checks do not apply.
elsif Has_Invariants (Def_Id) then
- if Within_Internal_Subprogram
+ if not Predicate_Check_In_Scope (Def_Id)
or else (Ekind (Current_Scope) = E_Function
and then Is_Predicate_Function (Current_Scope))
then
@@ -8397,7 +8698,7 @@ package body Exp_Ch3 is
-- If the initial value is null or an aggregate, qualify it with the
-- underlying type in order to provide a proper context.
- if Nkind_In (Expr, N_Aggregate, N_Null) then
+ if Nkind (Expr) in N_Aggregate | N_Null then
Expr :=
Make_Qualified_Expression (Loc,
Subtype_Mark => New_Occurrence_Of (Under_Typ, Loc),
@@ -8639,7 +8940,8 @@ package body Exp_Ch3 is
-- Init_Formals --
------------------
- function Init_Formals (Typ : Entity_Id) return List_Id is
+ function Init_Formals (Typ : Entity_Id; Proc_Id : Entity_Id) return List_Id
+ is
Loc : constant Source_Ptr := Sloc (Typ);
Unc_Arr : constant Boolean :=
Is_Array_Type (Typ) and then not Is_Constrained (Typ);
@@ -8648,9 +8950,11 @@ package body Exp_Ch3 is
or else (Is_Record_Type (Typ)
and then Is_Protected_Record_Type (Typ));
With_Task : constant Boolean :=
- Has_Task (Typ)
- or else (Is_Record_Type (Typ)
- and then Is_Task_Record_Type (Typ));
+ not Global_No_Tasking
+ and then
+ (Has_Task (Typ)
+ or else (Is_Record_Type (Typ)
+ and then Is_Task_Record_Type (Typ)));
Formals : List_Id;
begin
@@ -8679,6 +8983,8 @@ package body Exp_Ch3 is
Parameter_Type =>
New_Occurrence_Of (RTE (RE_Master_Id), Loc)));
+ Set_Has_Master_Entity (Proc_Id);
+
-- Add _Chain (not done for sequential elaboration policy, see
-- comment for Create_Restricted_Task_Sequential in s-tarest.ads).
@@ -9013,6 +9319,8 @@ package body Exp_Ch3 is
end loop;
pragma Assert (Present (Comp));
+
+ -- Move this check to sem???
Error_Msg_Node_2 := Comp;
Error_Msg_NE
("parent type & with dynamic component & cannot be parent"
@@ -9559,10 +9867,9 @@ package body Exp_Ch3 is
begin
-- Build equality code with a user-defined operator, if
-- available, and with the predefined "=" otherwise. For
- -- compatibility with older Ada versions, and preserve the
- -- workings of some ASIS tools, we also use the predefined
- -- operation if the component-type equality is abstract,
- -- rather than raising Program_Error.
+ -- compatibility with older Ada versions, we also use the
+ -- predefined operation if the component-type equality is
+ -- abstract, rather than raising Program_Error.
if Ada_Version < Ada_2012 then
Next_Test := Make_Op_Ne (Loc, Lhs, Rhs);
@@ -9901,6 +10208,8 @@ package body Exp_Ch3 is
-- Set to True if Tag_Typ has a primitive that renames the predefined
-- equality operator. Used to implement (RM 8-5-4(8)).
+ use Exp_Put_Image;
+
-- Start of processing for Make_Predefined_Primitive_Specs
begin
@@ -9918,6 +10227,17 @@ package body Exp_Ch3 is
Ret_Type => Standard_Long_Long_Integer));
+ -- Spec of Put_Image
+
+ if Enable_Put_Image (Tag_Typ)
+ and then No (TSS (Tag_Typ, TSS_Put_Image))
+ then
+ Append_To (Res, Predef_Spec_Or_Body (Loc,
+ Tag_Typ => Tag_Typ,
+ Name => Make_TSS_Name (Tag_Typ, TSS_Put_Image),
+ Profile => Build_Put_Image_Profile (Loc, Tag_Typ)));
+ end if;
+
-- Specs for dispatching stream attributes
declare
@@ -10216,15 +10536,13 @@ package body Exp_Ch3 is
New_Ref : Node_Id;
begin
- -- This expansion activity is called during analysis, but cannot
- -- be applied in ASIS mode when other expansion is disabled.
+ -- This expansion activity is called during analysis.
if Is_Tagged_Type (Typ)
and then not Is_Class_Wide_Type (Typ)
and then not Is_CPP_Class (Typ)
and then Tagged_Type_Expansion
and then Nkind (Expr) /= N_Aggregate
- and then not ASIS_Mode
and then (Nkind (Expr) /= N_Qualified_Expression
or else Nkind (Expression (Expr)) /= N_Aggregate)
then
@@ -10429,6 +10747,8 @@ package body Exp_Ch3 is
pragma Warnings (Off, Ent);
+ use Exp_Put_Image;
+
begin
pragma Assert (not Is_Interface (Tag_Typ));
@@ -10511,6 +10831,15 @@ package body Exp_Ch3 is
Append_To (Res, Decl);
+ -- Body of Put_Image
+
+ if Enable_Put_Image (Tag_Typ)
+ and then No (TSS (Tag_Typ, TSS_Put_Image))
+ then
+ Build_Record_Put_Image_Procedure (Loc, Tag_Typ, Decl, Ent);
+ Append_To (Res, Decl);
+ end if;
+
-- Bodies for Dispatching stream IO routines. We need these only for
-- non-limited types (in the limited case there is no dispatching).
-- We also skip them if dispatching or finalization are not available