Commit f937473f by Robert Dewar Committed by Arnaud Charlet

einfo.ads, einfo.adb: (First_Component_Or_Discriminant): New function

2007-04-06  Robert Dewar  <dewar@adacore.com>
	    Thomas Quinot  <quinot@adacore.com>
	    Ed Schonberg  <schonberg@adacore.com>
	    Bob Duff  <duff@adacore.com>

	* einfo.ads, einfo.adb: (First_Component_Or_Discriminant): New function
	(Next_Component_Or_Discriminant): New function and procedure
	(First_Index, First_Literal, Master_Id,
	Set_First_Index, Set_First_Literal, Set_Master_Id):
	Add missing Ekind assertions.
	(Is_Access_Protected_Subprogram_Type): New predicate.
	(Has_RACW): New entity flag, set on package entities to indicate that
	the package contains the declaration of a remote accecss-to-classwide
	type.
	(E_Return_Statement): This node type has the Finalization_Chain_Entity
	attribute, in case the result type has controlled parts.
	(Requires_Overriding): Add this new flag, because "requires
	overriding" is subtly different from "is abstract" (see AI-228).
	(Is_Abstract): Split Is_Abstract flag into Is_Abstract_Subprogram and
	Is_Abstract_Type. Make sure these are called only when appropriate.
	(Has_Pragma_Unreferenced_Objects): New flag

	* exp_ch5.adb (Expand_N_Assignment_Statement): If the left-hand side is
	class-wide, the tag of the right-hand side must be an exact match, not
	an ancestor of that of the object on left-hand side.
	(Move_Activation_Chain): New procedure to create the call to
	System.Tasking.Stages.Move_Activation_Chain.
	(Expand_N_Extended_Return_Statement): Generate code to call
	System.Finalization_Implementation.Move_Final_List at the end of a
	return statement if the function's result type has controlled parts.
	Move asserts to Build_In_Place_Formal.
	(Move_Final_List): New function to create the call statement.
	(Expand_N_Assignment_Statement): In case of assignment to a class-wide
	tagged type, replace generation of call to the run-time subprogram
	CW_Membership by call to Build_CW_Membership.
	(Expand_N_Return_Statement): Replace generation of call to the run-time
	subprogram Get_Access_Level by call to Build_Get_Access_Level.
	(Expand_N_Simple_Function_Return): Replace generation of call to the
	run-time subprogram Get_Access_Level by call to Build_Get_Access_Level.

	* exp_ch6.ads, exp_ch6.adb (Expand_Call): Use new predicate
	Is_Access_Protected_Subprogram_Type, to handle both named and anonymous
	access to protected operations.
	(Add_Task_Actuals_To_Build_In_Place_Call): New procedure to add the
	master and chain actual parameters to a build-in-place function call
	involving tasks.
	(BIP_Formal_Suffix): Add new enumeration literals to complete the case
	statement.
	(Make_Build_In_Place_Call_In_Allocator,
	Make_Build_In_Place_Call_In_Anonymous_Context,
	Make_Build_In_Place_Call_In_Assignment,
	Make_Build_In_Place_Call_In_Object_Declaration): Call
	Add_Task_Actuals_To_Build_In_Place_Call with the appropriate master.
	(Expand_Inlined_Call): If the subprogram is a null procedure, or a
	stubbed procedure with a null body, replace the call with a null
	statement without using the full inlining machinery, for efficiency
	and to avoid invalid values in source file table entries.

	* exp_ch8.adb (Expand_N_Object_Renaming_Declaration): Add support for
	renamings of calls to build-in-place functions.

	* rtsfind.adb (RTE_Record_Component_Available): New subprogram that
	provides the functionality of RTE_Available to record components.
	(RTU_Entity): The function Entity has been renamed to RTU_Entity
	to avoid undesired overloading.
	(Entity): New subprogram that returns the entity for the referened
	unit. If this unit has not been loaded, it returns Empty.
	(RE_Activation_Chain_Access, RE_Move_Activation_Chain): New entities.
	Remove no longer used entities.
	(RE_Finalizable_Ptr_Ptr, RE_Move_Final_List): New entities.
	(RE_Type_Specific_Data): New entity.
	(RE_Move_Any_Value): New entity.
	(RE_TA_A, RE_Get_Any_Type): New entities.
	(RE_Access_Level, RE_Dispatch_Table, E_Default_Prim_Op_Count,
	 RE_Prims_Ptr, RE_RC_Offset, RE_Remotely_Callable,
	 RE_DT_Typeinfo_Ptr_Size, RE_Cstring_Ptr, RE_DT_Expanded_Name): Added.
	(Entity): New subprogram that returns the entity for the referened
	unit. If this unit has not been loaded, it returns Empty.
	(RTE): Addition of a new formal that extends the search to the scopes
	of the record types found in the chain of the package.

	* sem_ch6.ads, sem_ch6.adb (Check_Overriding_Indicator): Print
	"abstract subprograms must be visible" message, whether or not the type
	is an interface; that is, remove the special case for interface types.
	(Analyze_Function_Return): Remove error message "return of task objects
	is not yet implemented" because this is now implemented.
	(Create_Extra_Formals): Add the extra master and activation chain
	formals in case the result type has tasks.
	Remove error message "return of limited controlled objects is not yet
	implemented".
	(Create_Extra_Formals): Add the extra caller's finalization list formal
	in case the result type has controlled parts.
	(Process_Formals): In case of access formal types there is no need
	to continue with the analysis of the formals if we already notified
	errors.
	(Check_Overriding_Indicator): Add code to check overriding of predefined
	operators.
	(Create_Extra_Formals): Prevent creation of useless Extra_Constrained
	flags for formals that do not require them,.
	(Enter_Overloaded_Entity): Do not give -gnatwh warning message unless
	hidden entity is use visible or directly visible.
	(Analyze_Abstract_Subprogram_Declaration,Analyze_Subprogram_Body,
	Analyze_Subprogram_Declaration,Analyze_Subprogram_Specification,
	Check_Conventions,Check_Delayed_Subprogram,Make_Inequality_Operator,
	New_Overloaded_Entity): Split Is_Abstract flag into
	Is_Abstract_Subprogram and Is_Abstract_Type.

	* s-finimp.ads, s-finimp.adb (Move_Final_List): New procedure to move
	a return statement's finalization list to the caller's list, used for
	build-in-place functions with result type with controlled parts.
	Remove no longer used entities.

	* s-taskin.ads (Activation_Chain): Remove pragma Volatile. It is no
	longer needed, because the full type is now limited, and therefore a
	pass-by-reference type.
	(Foreign_Task_Level): New constant.

	* s-tassta.ads, s-tassta.adb (Move_Activation_Chain): New procedure to
	move tasks from the activation chain belonging to a return statement to
	the one passed in by the caller, and update the master to the one
	passed in by the caller.
	(Vulnerable_Complete_Master, Check_Unactivated_Tasks): Check the master
	of unactivated tasks, so we don't kill the ones that are being returned
	by a build-in-place function.
	(Create_Task): Ignore AI-280 for foreign threads.

From-SVN: r123558
parent 9dac0a42
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -40,21 +40,83 @@ package Exp_Ch6 is ...@@ -40,21 +40,83 @@ package Exp_Ch6 is
-- This procedure contains common processing for Expand_N_Function_Call, -- This procedure contains common processing for Expand_N_Function_Call,
-- Expand_N_Procedure_Statement, and Expand_N_Entry_Call. -- Expand_N_Procedure_Statement, and Expand_N_Entry_Call.
procedure Freeze_Subprogram (N : Node_Id);
-- generate the appropriate expansions related to Subprogram freeze
-- nodes (e. g. the filling of the corresponding Dispatch Table for
-- Primitive Operations)
-- The following type defines the various forms of allocation used for the
-- results of build-in-place function calls.
type BIP_Allocation_Form is
(Unspecified,
Caller_Allocation,
Secondary_Stack,
Global_Heap,
User_Storage_Pool);
type BIP_Formal_Kind is
-- Ada 2005 (AI-318-02): This type defines the kinds of implicit extra
-- formals created for build-in-place functions. The order of the above
-- enumeration literals matches the order in which the formals are
-- declared. See Sem_Ch6.Create_Extra_Formals.
(BIP_Alloc_Form,
-- Present if result subtype is unconstrained. Indicates whether the
-- return object is allocated by the caller or callee, and if the
-- callee, whether to use the secondary stack or the heap. See
-- Create_Extra_Formals.
BIP_Final_List,
-- Present if result type has controlled parts. Pointer to caller's
-- finalization list.
BIP_Master,
-- Present if result type contains tasks. Master associated with
-- calling context.
BIP_Activation_Chain,
-- Present if result type contains tasks. Caller's activation chain.
BIP_Object_Access);
-- Present for all build-in-place functions. Address at which to place
-- the return object, or null if BIP_Alloc_Form indicates
-- allocated by callee.
-- ??? We also need to be able to pass in some way to access a
-- user-defined storage pool at some point. And perhaps a constrained
-- flag.
function BIP_Formal_Suffix (Kind : BIP_Formal_Kind) return String;
-- Ada 2005 (AI-318-02): Returns a string to be used as the suffix of names
-- for build-in-place formal parameters of the given kind.
function Build_In_Place_Formal
(Func : Entity_Id;
Kind : BIP_Formal_Kind) return Entity_Id;
-- Ada 2005 (AI-318-02): Locates and returns the entity for the implicit
-- build-in-place formal parameter of the given kind associated with the
-- function Func, and returns its Entity_Id. It is a bug if not found; the
-- caller should ensure this is called only when the extra formal exists.
function Is_Build_In_Place_Function (E : Entity_Id) return Boolean; function Is_Build_In_Place_Function (E : Entity_Id) return Boolean;
-- Ada 2005 (AI-318-02): Returns True if E denotes a function or an -- Ada 2005 (AI-318-02): Returns True if E denotes a function, generic
-- access-to-function type whose result must be built in place; otherwise -- function, or access-to-function type whose result must be built in
-- returns False. Currently this is restricted to the subset of functions -- place; otherwise returns False. For Ada 2005, this is currently
-- whose result subtype is a constrained inherently limited type. -- restricted to the set of functions whose result subtype is an inherently
-- limited type. In Ada 95, this must be False for inherently limited
-- result types (but currently returns False for all Ada 95 functions).
-- Eventually we plan to support build-in-place for nonlimited types.
-- Build-in-place is usually more efficient for large things, and less
-- efficient for small things. However, we never use build-in-place if the
-- convention is other than Ada, because that would disturb mixed-language
-- programs. Note that for the non-inherently-limited cases, we must make
-- the same decision for Ada 95 and 2005, so that mixed-dialect programs
-- will work.
function Is_Build_In_Place_Function_Call (N : Node_Id) return Boolean; function Is_Build_In_Place_Function_Call (N : Node_Id) return Boolean;
-- Ada 2005 (AI-318-02): Returns True if N denotes a call to a function -- Ada 2005 (AI-318-02): Returns True if N denotes a call to a function
-- that requires handling as a build-in-place call or is a qualified -- that requires handling as a build-in-place call or is a qualified
-- expression applied to such a call; otherwise returns False. -- expression applied to such a call; otherwise returns False.
procedure Freeze_Subprogram (N : Node_Id); function Is_Build_In_Place_Function_Return (N : Node_Id) return Boolean;
-- generate the appropriate expansions related to Subprogram freeze -- Ada 2005 (AI-318-02): Returns True if N is an N_Return_Statement or
-- nodes (e. g. the filling of the corresponding Dispatch Table for -- N_Extended_Return_Statement and it applies to a build-in-place function
-- Primitive Operations) -- or generic function.
procedure Make_Build_In_Place_Call_In_Allocator procedure Make_Build_In_Place_Call_In_Allocator
(Allocator : Node_Id; (Allocator : Node_Id;
...@@ -84,7 +146,7 @@ package Exp_Ch6 is ...@@ -84,7 +146,7 @@ package Exp_Ch6 is
Function_Call : Node_Id); Function_Call : Node_Id);
-- Ada 2005 (AI-318-02): Handle a call to a build-in-place function that -- Ada 2005 (AI-318-02): Handle a call to a build-in-place function that
-- occurs as the right-hand side of an assignment statement by passing -- occurs as the right-hand side of an assignment statement by passing
-- access to the left-hand sid as an additional parameter of the function -- access to the left-hand side as an additional parameter of the function
-- call. Assign must denote a N_Assignment_Statement. Function_Call must -- call. Assign must denote a N_Assignment_Statement. Function_Call must
-- denote either an N_Function_Call node for which Is_Build_In_Place_Call -- denote either an N_Function_Call node for which Is_Build_In_Place_Call
-- is True, or an N_Qualified_Expression node applied to such a function -- is True, or an N_Qualified_Expression node applied to such a function
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 1992-2004 Free Software Foundation, Inc. -- -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -26,10 +26,12 @@ ...@@ -26,10 +26,12 @@
with Atree; use Atree; with Atree; use Atree;
with Einfo; use Einfo; with Einfo; use Einfo;
with Exp_Ch6; use Exp_Ch6;
with Exp_Dbug; use Exp_Dbug; with Exp_Dbug; use Exp_Dbug;
with Exp_Util; use Exp_Util; with Exp_Util; use Exp_Util;
with Freeze; use Freeze; with Freeze; use Freeze;
with Nlists; use Nlists; with Nlists; use Nlists;
with Opt; use Opt;
with Sem; use Sem; with Sem; use Sem;
with Sem_Ch8; use Sem_Ch8; with Sem_Ch8; use Sem_Ch8;
with Sinfo; use Sinfo; with Sinfo; use Sinfo;
...@@ -268,6 +270,19 @@ package body Exp_Ch8 is ...@@ -268,6 +270,19 @@ package body Exp_Ch8 is
end if; end if;
end if; end if;
-- Ada 2005 (AI-318-02): If the renamed object is a call to a build-in-
-- place function, then a temporary return object needs to be created
-- and access to it must be passed to the function. Currently we limit
-- such functions to those with inherently limited result subtypes, but
-- eventually we plan to expand the functions that are treated as
-- build-in-place to include other composite result types.
if Ada_Version >= Ada_05
and then Is_Build_In_Place_Function_Call (Nam)
then
Make_Build_In_Place_Call_In_Anonymous_Context (Nam);
end if;
-- Create renaming entry for debug information -- Create renaming entry for debug information
Decl := Debug_Renaming_Declaration (N); Decl := Debug_Renaming_Declaration (N);
......
...@@ -168,7 +168,7 @@ package body System.Finalization_Implementation is ...@@ -168,7 +168,7 @@ package body System.Finalization_Implementation is
Nb_Link : Short_Short_Integer) Nb_Link : Short_Short_Integer)
is is
begin begin
-- Simple case: attachement to a one way list -- Simple case: attachment to a one way list
if Nb_Link = 1 then if Nb_Link = 1 then
Obj.Next := L; Obj.Next := L;
...@@ -176,7 +176,7 @@ package body System.Finalization_Implementation is ...@@ -176,7 +176,7 @@ package body System.Finalization_Implementation is
-- Dynamically allocated objects: they are attached to a doubly linked -- Dynamically allocated objects: they are attached to a doubly linked
-- list, so that an element can be finalized at any moment by means of -- list, so that an element can be finalized at any moment by means of
-- an unchecked deallocation. Attachement is protected against -- an unchecked deallocation. Attachment is protected against
-- multi-threaded access. -- multi-threaded access.
elsif Nb_Link = 2 then elsif Nb_Link = 2 then
...@@ -203,7 +203,7 @@ package body System.Finalization_Implementation is ...@@ -203,7 +203,7 @@ package body System.Finalization_Implementation is
raise; raise;
end Locked_Processing; end Locked_Processing;
-- Attachement of arrays to the final list (used only for objects -- Attachment of arrays to the final list (used only for objects
-- returned by function). Obj, in this case is the last element, -- returned by function). Obj, in this case is the last element,
-- but all other elements are already threaded after it. We just -- but all other elements are already threaded after it. We just
-- attach the rest of the final list at the end of the array list. -- attach the rest of the final list at the end of the array list.
...@@ -231,32 +231,6 @@ package body System.Finalization_Implementation is ...@@ -231,32 +231,6 @@ package body System.Finalization_Implementation is
end Attach_To_Final_List; end Attach_To_Final_List;
--------------------- ---------------------
-- Deep_Tag_Adjust --
---------------------
procedure Deep_Tag_Adjust
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Short_Short_Integer)
is
V : constant SFR.Finalizable_Ptr := To_Finalizable_Ptr (A);
Controller : constant RC_Ptr := Get_Deep_Controller (A);
begin
if Controller /= null then
Adjust (Controller.all);
Attach_To_Final_List (L, Controller.all, B);
end if;
-- Is controlled
if V.all in Finalizable then
Adjust (V.all);
Attach_To_Final_List (L, Finalizable (V.all), 1);
end if;
end Deep_Tag_Adjust;
---------------------
-- Deep_Tag_Attach -- -- Deep_Tag_Attach --
---------------------- ----------------------
...@@ -280,74 +254,6 @@ package body System.Finalization_Implementation is ...@@ -280,74 +254,6 @@ package body System.Finalization_Implementation is
end if; end if;
end Deep_Tag_Attach; end Deep_Tag_Attach;
-----------------------
-- Deep_Tag_Finalize --
-----------------------
procedure Deep_Tag_Finalize
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Boolean)
is
pragma Warnings (Off, L);
V : constant SFR.Finalizable_Ptr := To_Finalizable_Ptr (A);
Controller : constant RC_Ptr := Get_Deep_Controller (A);
begin
if Controller /= null then
if B then
Finalize_One (Controller.all);
else
Finalize (Controller.all);
end if;
end if;
-- Is controlled
if V.all in Finalizable then
if B then
Finalize_One (V.all);
else
Finalize (V.all);
end if;
end if;
end Deep_Tag_Finalize;
-------------------------
-- Deep_Tag_Initialize --
-------------------------
procedure Deep_Tag_Initialize
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Short_Short_Integer)
is
V : constant SFR.Finalizable_Ptr := To_Finalizable_Ptr (A);
Controller : constant RC_Ptr := Get_Deep_Controller (A);
begin
-- This procedure should not be called if the object has no
-- controlled components
if Controller = null then
raise Program_Error;
-- Has controlled components
else
Initialize (Controller.all);
Attach_To_Final_List (L, Controller.all, B);
end if;
-- Is controlled
if V.all in Finalizable then
Initialize (V.all);
Attach_To_Final_List (Controller.F, Finalizable (Controller.all), 1);
end if;
end Deep_Tag_Initialize;
----------------------------- -----------------------------
-- Detach_From_Final_List -- -- Detach_From_Final_List --
----------------------------- -----------------------------
...@@ -441,7 +347,7 @@ package body System.Finalization_Implementation is ...@@ -441,7 +347,7 @@ package body System.Finalization_Implementation is
-- programs using controlled types heavily. -- programs using controlled types heavily.
if System.Restrictions.Abort_Allowed then if System.Restrictions.Abort_Allowed then
X := To_Ptr (System.Soft_Links.Get_Current_Excep.all).Id; X := To_Ptr (SSL.Get_Current_Excep.all).Id;
end if; end if;
while P /= null loop while P /= null loop
...@@ -554,6 +460,34 @@ package body System.Finalization_Implementation is ...@@ -554,6 +460,34 @@ package body System.Finalization_Implementation is
Object.My_Address := Object'Address; Object.My_Address := Object'Address;
end Initialize; end Initialize;
---------------------
-- Move_Final_List --
---------------------
procedure Move_Final_List
(From : in out SFR.Finalizable_Ptr;
To : Finalizable_Ptr_Ptr)
is
begin
-- This is currently called at the end of the return statement, and the
-- caller does NOT defer aborts. We need to defer aborts to prevent
-- mangling the finalization lists.
SSL.Abort_Defer.all;
-- Put the return statement's finalization list onto the caller's one,
-- thus transferring responsibility for finalization of the return
-- object to the caller.
Attach_To_Final_List (To.all, From.all, Nb_Link => 3);
-- Empty the return statement's finalization list, so that when the
-- cleanup code executes, there will be nothing to finalize.
From := null;
SSL.Abort_Undefer.all;
end Move_Final_List;
------------------------- -------------------------
-- Raise_From_Finalize -- -- Raise_From_Finalize --
------------------------- -------------------------
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2006 Free Software Foundation, Inc. -- -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -51,15 +51,15 @@ package System.Finalization_Implementation is ...@@ -51,15 +51,15 @@ package System.Finalization_Implementation is
Collection_Finalization_Started : constant SFR.Finalizable_Ptr := Collection_Finalization_Started : constant SFR.Finalizable_Ptr :=
To_Finalizable_Ptr (SSE.To_Address (1)); To_Finalizable_Ptr (SSE.To_Address (1));
-- This is used to implement the rule in RM-4.8(10.2/2) that requires an -- This is used to implement the rule in RM 4.8(10.2/2) that requires an
-- allocator to raise Program_Error if the collection finalization has -- allocator to raise Program_Error if the collection finalization has
-- already started. See also Ada.Finalization.List_Controller. Finalize on -- already started. See also Ada.Finalization.List_Controller. Finalize on
-- List_Controller first sets the list to Collection_Finalization_Started, -- List_Controller first sets the list to Collection_Finalization_Started,
-- to indicate that finalization has started. An allocator will call -- to indicate that finalization has started. An allocator will call
-- Attach_To_Final_List, which checks for the special value and raises -- Attach_To_Final_List, which checks for the special value and raises
-- Program_Error if appropriate. The value of -- Program_Error if appropriate. The Collection_Finalization_Started value
-- Collection_Finalization_Started must be different from 'Access of any -- must be different from 'Access of any finalizable object, and different
-- finalizable object, and different from null. See AI-280. -- from null. See AI-280.
Global_Final_List : SFR.Finalizable_Ptr; Global_Final_List : SFR.Finalizable_Ptr;
-- This list stores the controlled objects defined in library-level -- This list stores the controlled objects defined in library-level
...@@ -72,60 +72,52 @@ package System.Finalization_Implementation is ...@@ -72,60 +72,52 @@ package System.Finalization_Implementation is
(L : in out SFR.Finalizable_Ptr; (L : in out SFR.Finalizable_Ptr;
Obj : in out SFR.Finalizable; Obj : in out SFR.Finalizable;
Nb_Link : Short_Short_Integer); Nb_Link : Short_Short_Integer);
-- Attach finalizable object Obj to the linked list L. Nb_Link controls -- Attach finalizable object Obj to the linked list L. Nb_Link controls the
-- the number of link of the linked_list, and can be either 0 for no -- number of link of the linked_list, and is one of: 0 for no attachment, 1
-- attachement, 1 for simple linked lists or 2 for doubly linked lists -- for simple linked lists or 2 for doubly linked lists or even 3 for a
-- or even 3 for a simple attachement of a whole array of elements. -- simple attachment of a whole array of elements. Attachment to a simply
-- Attachement to a simply linked list is not protected against -- linked list is not protected against concurrent access and should only
-- concurrent access and should only be used in contexts where it -- be used in contexts where it doesn't matter, such as for objects
-- doesn't matter, such as for objects allocated on the stack. In the -- allocated on the stack. In the case of an attachment on a doubly linked
-- case of an attachment on a doubly linked list, L must not be null -- list, L must not be null and Obj will be inserted AFTER the first
-- and Obj will be inserted AFTER the first element and the attachment -- element and the attachment is protected against concurrent call.
-- is protected against concurrent call. Typically used to attach to -- Typically used to attach to a dynamically allocated object to a
-- a dynamically allocated object to a List_Controller (whose first -- List_Controller (whose first element is always a dummy element)
-- element is always a dummy element)
type Finalizable_Ptr_Ptr is access all SFR.Finalizable_Ptr;
-- A pointer to a finalization list. This is used as the type of the extra
-- implicit formal which are passed to build-in-place functions that return
-- controlled types (see Sem_Ch6). That extra formal is then passed on to
-- Move_Final_List (below).
procedure Move_Final_List
(From : in out SFR.Finalizable_Ptr;
To : Finalizable_Ptr_Ptr);
-- Move all objects on From list to To list. This is used to implement
-- build-in-place function returns. The return object is initially placed
-- on a finalization list local to the return statement, in case the
-- return statement is left prematurely (due to raising an exception,
-- being aborted, or a goto or exit statement). Once the return statement
-- has completed successfully, Move_Final_List is called to move the
-- return object to the caller's finalization list.
procedure Finalize_List (L : SFR.Finalizable_Ptr); procedure Finalize_List (L : SFR.Finalizable_Ptr);
-- Call Finalize on each element of the list L; -- Call Finalize on each element of the list L;
procedure Finalize_One (Obj : in out SFR.Finalizable); procedure Finalize_One (Obj : in out SFR.Finalizable);
-- Call Finalize on Obj and remove its final list. -- Call Finalize on Obj and remove its final list
--------------------- ---------------------
-- Deep Procedures -- -- Deep Procedures --
--------------------- ---------------------
procedure Deep_Tag_Initialize
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Short_Short_Integer);
-- Generic initialize for tagged objects with controlled components.
-- A is the address of the object, L the finalization list when it needs
-- to be attached and B the attachement level (see Attach_To_Final_List).
procedure Deep_Tag_Adjust
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Short_Short_Integer);
-- Generic adjust for tagged objects with controlled components.
-- A is the address of the object, L the finalization list when it needs
-- to be attached and B the attachement level (see Attach_To_Final_List).
procedure Deep_Tag_Finalize
(L : in out SFR.Finalizable_Ptr;
A : System.Address;
B : Boolean);
-- Generic finalize for tagged objects with controlled components.
-- A is the address of the object, L the finalization list when it needs
-- to be attached and B the attachement level (see Attach_To_Final_List).
procedure Deep_Tag_Attach procedure Deep_Tag_Attach
(L : in out SFR.Finalizable_Ptr; (L : in out SFR.Finalizable_Ptr;
A : System.Address; A : System.Address;
B : Short_Short_Integer); B : Short_Short_Integer);
-- Generic attachement for tagged objects with controlled components. -- Generic attachment for tagged objects with controlled components.
-- A is the address of the object, L the finalization list when it needs -- A is the address of the object, L the finalization list when it needs
-- to be attached and B the attachement level (see Attach_To_Final_List). -- to be attached and B the attachment level (see Attach_To_Final_List).
----------------------------- -----------------------------
-- Record Controller Types -- -- Record Controller Types --
...@@ -141,11 +133,11 @@ package System.Finalization_Implementation is ...@@ -141,11 +133,11 @@ package System.Finalization_Implementation is
end record; end record;
procedure Initialize (Object : in out Limited_Record_Controller); procedure Initialize (Object : in out Limited_Record_Controller);
-- Does nothing. -- Does nothing currently.
procedure Finalize (Object : in out Limited_Record_Controller); procedure Finalize (Object : in out Limited_Record_Controller);
-- Finalize the controlled components of the enclosing record by -- Finalize the controlled components of the enclosing record by following
-- following the list starting at Object.F. -- the list starting at Object.F.
type Record_Controller is type Record_Controller is
new Limited_Record_Controller with record new Limited_Record_Controller with record
...@@ -156,13 +148,13 @@ package System.Finalization_Implementation is ...@@ -156,13 +148,13 @@ package System.Finalization_Implementation is
-- Initialize the field My_Address to the Object'Address -- Initialize the field My_Address to the Object'Address
procedure Adjust (Object : in out Record_Controller); procedure Adjust (Object : in out Record_Controller);
-- Adjust the components and their finalization pointers by subtracting -- Adjust the components and their finalization pointers by subtracting by
-- by the offset of the target and the source addresses of the assignment. -- the offset of the target and the source addresses of the assignment.
-- Inherit Finalize from Limited_Record_Controller -- Inherit Finalize from Limited_Record_Controller
procedure Detach_From_Final_List (Obj : in out SFR.Finalizable); procedure Detach_From_Final_List (Obj : in out SFR.Finalizable);
-- Remove the specified object from its Final list, which must be a -- Remove the specified object from its Final list, which must be a doubly
-- doubly linked list. -- linked list.
end System.Finalization_Implementation; end System.Finalization_Implementation;
...@@ -364,10 +364,12 @@ package System.Tasking is ...@@ -364,10 +364,12 @@ package System.Tasking is
------------------------------------ ------------------------------------
type Activation_Chain is limited private; type Activation_Chain is limited private;
-- Comment required ??? -- Linked list of to-be-activated tasks, linked through
-- Activation_Link. The order of tasks on the list is irrelevant, because
-- the priority rules will ensure that they actually start activating in
-- priority order.
type Activation_Chain_Access is access all Activation_Chain; type Activation_Chain_Access is access all Activation_Chain;
-- Comment required ???
type Task_Procedure_Access is access procedure (Arg : System.Address); type Task_Procedure_Access is access procedure (Arg : System.Address);
...@@ -651,11 +653,14 @@ package System.Tasking is ...@@ -651,11 +653,14 @@ package System.Tasking is
-- Normally, a task starts out with internal master nesting level one -- Normally, a task starts out with internal master nesting level one
-- larger than external master nesting level. It is incremented to one by -- larger than external master nesting level. It is incremented to one by
-- Enter_Master, which is called in the task body only if the compiler -- Enter_Master, which is called in the task body only if the compiler
-- thinks the task may have dependent tasks. It is set to for the -- thinks the task may have dependent tasks. It is set to 1 for the
-- environment task, the level 2 is reserved for server tasks of the -- environment task, the level 2 is reserved for server tasks of the
-- run-time system (the so called "independent tasks"), and the level 3 is -- run-time system (the so called "independent tasks"), and the level 3 is
-- for the library level tasks. -- for the library level tasks. Foreign threads which are detected by
-- the run-time have a level of 0, allowing these tasks to be easily
-- distinguished if needed.
Foreign_Task_Level : constant Master_Level := 0;
Environment_Task_Level : constant Master_Level := 1; Environment_Task_Level : constant Master_Level := 1;
Independent_Task_Level : constant Master_Level := 2; Independent_Task_Level : constant Master_Level := 2;
Library_Task_Level : constant Master_Level := 3; Library_Task_Level : constant Master_Level := 3;
...@@ -1062,14 +1067,14 @@ package System.Tasking is ...@@ -1062,14 +1067,14 @@ package System.Tasking is
private private
Null_Task : constant Task_Id := null; Null_Task : constant Task_Id := null;
type Activation_Chain is record type Activation_Chain is limited record
T_ID : Task_Id; T_ID : Task_Id;
end record; end record;
pragma Volatile (Activation_Chain);
-- Activation_chain is an in-out parameter of initialization procedures -- Activation_Chain is an in-out parameter of initialization procedures and
-- and it must be passed by reference because the init proc may terminate -- it must be passed by reference because the init proc may terminate
-- abnormally after creating task components, and these must be properly -- abnormally after creating task components, and these must be properly
-- registered for removal (Expunge_Unactivated_Tasks). -- registered for removal (Expunge_Unactivated_Tasks). The "limited" forces
-- Activation_Chain to be a by-reference type; see RM-6.2(4).
end System.Tasking; end System.Tasking;
...@@ -149,6 +149,9 @@ package body System.Tasking.Stages is ...@@ -149,6 +149,9 @@ package body System.Tasking.Stages is
-- trigger an automatic stack alignment suitable for GCC's assumptions if -- trigger an automatic stack alignment suitable for GCC's assumptions if
-- need be. -- need be.
-- "Vulnerable_..." in the procedure names below means they must be called
-- with abort deferred.
procedure Vulnerable_Complete_Task (Self_ID : Task_Id); procedure Vulnerable_Complete_Task (Self_ID : Task_Id);
-- Complete the calling task. This procedure must be called with -- Complete the calling task. This procedure must be called with
-- abort deferred. It should only be called by Complete_Task and -- abort deferred. It should only be called by Complete_Task and
...@@ -520,9 +523,11 @@ package body System.Tasking.Stages is ...@@ -520,9 +523,11 @@ package body System.Tasking.Stages is
begin begin
-- If Master is greater than the current master, it means that Master -- If Master is greater than the current master, it means that Master
-- has already awaited its dependent tasks. This raises Program_Error, -- has already awaited its dependent tasks. This raises Program_Error,
-- by 4.8(10.3/2). See AI-280. -- by 4.8(10.3/2). See AI-280. Ignore this check for foreign threads.
if Master > Self_ID.Master_Within then if Self_ID.Master_of_Task /= Foreign_Task_Level
and then Master > Self_ID.Master_Within
then
raise Program_Error with raise Program_Error with
"create task after awaiting termination"; "create task after awaiting termination";
end if; end if;
...@@ -877,6 +882,53 @@ package body System.Tasking.Stages is ...@@ -877,6 +882,53 @@ package body System.Tasking.Stages is
end if; end if;
end Free_Task; end Free_Task;
---------------------------
-- Move_Activation_Chain --
---------------------------
procedure Move_Activation_Chain
(From, To : Activation_Chain_Access;
New_Master : Master_ID)
is
Self_ID : constant Task_Id := STPO.Self;
C : Task_Id;
begin
pragma Debug
(Debug.Trace (Self_ID, "Move_Activation_Chain", 'C'));
-- Nothing to do if From is empty, and we can check that without
-- deferring aborts.
C := From.all.T_ID;
if C = null then
return;
end if;
Initialization.Defer_Abort (Self_ID);
-- Loop through the From chain, changing their Master_of_Task
-- fields, and to find the end of the chain.
loop
C.Master_of_Task := New_Master;
exit when C.Common.Activation_Link = null;
C := C.Common.Activation_Link;
end loop;
-- Hook From in at the start of To
C.Common.Activation_Link := To.all.T_ID;
To.all.T_ID := From.all.T_ID;
-- Set From to empty
From.all.T_ID := null;
Initialization.Undefer_Abort (Self_ID);
end Move_Activation_Chain;
------------------ ------------------
-- Task_Wrapper -- -- Task_Wrapper --
------------------ ------------------
...@@ -1407,7 +1459,7 @@ package body System.Tasking.Stages is ...@@ -1407,7 +1459,7 @@ package body System.Tasking.Stages is
C := All_Tasks_List; C := All_Tasks_List;
while C /= null loop while C /= null loop
if C.Common.Activator = Self_ID then if C.Common.Activator = Self_ID and then C.Master_of_Task = CM then
return False; return False;
end if; end if;
...@@ -1449,13 +1501,24 @@ package body System.Tasking.Stages is ...@@ -1449,13 +1501,24 @@ package body System.Tasking.Stages is
-- zero for new tasks, and the task should not exit the -- zero for new tasks, and the task should not exit the
-- sleep-loops that use this count until the count reaches zero. -- sleep-loops that use this count until the count reaches zero.
-- While we're counting, if we run across any unactivated tasks that
-- belong to this master, we summarily terminate them as required by
-- RM-9.2(6).
Lock_RTS; Lock_RTS;
Write_Lock (Self_ID); Write_Lock (Self_ID);
C := All_Tasks_List; C := All_Tasks_List;
while C /= null loop while C /= null loop
if C.Common.Activator = Self_ID then
-- Terminate unactivated (never-to-be activated) tasks
if C.Common.Activator = Self_ID and then C.Master_of_Task = CM then
pragma Assert (C.Common.State = Unactivated); pragma Assert (C.Common.State = Unactivated);
-- Usually, C.Common.Activator = Self_ID implies C.Master_of_Task
-- = CM. The only case where C is pending activation by this
-- task, but the master of C is not CM is in Ada 2005, when C is
-- part of a return object of a build-in-place function.
Write_Lock (C); Write_Lock (C);
C.Common.Activator := null; C.Common.Activator := null;
...@@ -1465,6 +1528,8 @@ package body System.Tasking.Stages is ...@@ -1465,6 +1528,8 @@ package body System.Tasking.Stages is
Unlock (C); Unlock (C);
end if; end if;
-- Count it if dependent on this master
if C.Common.Parent = Self_ID and then C.Master_of_Task = CM then if C.Common.Parent = Self_ID and then C.Master_of_Task = CM then
Write_Lock (C); Write_Lock (C);
...@@ -1733,9 +1798,9 @@ package body System.Tasking.Stages is ...@@ -1733,9 +1798,9 @@ package body System.Tasking.Stages is
-- Complete the calling task -- Complete the calling task
-- This procedure must be called with abort deferred. (That's why the -- This procedure must be called with abort deferred. It should only be
-- name has "Vulnerable" in it.) It should only be called by Complete_Task -- called by Complete_Task and Finalize_Global_Tasks (for the environment
-- and Finalize_Global_Tasks (for the environment task). -- task).
-- The effect is similar to that of Complete_Master. Differences include -- The effect is similar to that of Complete_Master. Differences include
-- the closing of entries here, and computation of the number of active -- the closing of entries here, and computation of the number of active
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 1992-2005, Free Software Foundation, Inc. -- -- Copyright (C) 1992-2006, Free Software Foundation, Inc. --
-- -- -- --
-- GNARL is free software; you can redistribute it and/or modify it under -- -- GNARL is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -143,6 +143,8 @@ package System.Tasking.Stages is ...@@ -143,6 +143,8 @@ package System.Tasking.Stages is
-- it is not needed if priority-based scheduling is supported, since all -- it is not needed if priority-based scheduling is supported, since all
-- the activated tasks synchronize on the activators lock before they -- the activated tasks synchronize on the activators lock before they
-- start activating and so they should start activating in priority order. -- start activating and so they should start activating in priority order.
-- ??? Actually, the body of this package DOES reverse the chain, so I
-- don't understand the above comment.
procedure Complete_Activation; procedure Complete_Activation;
-- Compiler interface only. Do not call from within the RTS. -- Compiler interface only. Do not call from within the RTS.
...@@ -255,6 +257,22 @@ package System.Tasking.Stages is ...@@ -255,6 +257,22 @@ package System.Tasking.Stages is
-- if T has terminated. Do nothing in the other case. It is called from -- if T has terminated. Do nothing in the other case. It is called from
-- Unchecked_Deallocation, for objects that are or contain tasks. -- Unchecked_Deallocation, for objects that are or contain tasks.
procedure Move_Activation_Chain
(From, To : Activation_Chain_Access;
New_Master : Master_ID);
-- Compiler interface only. Do not call from within the RTS.
-- Move all tasks on From list to To list, and change their Master_of_Task
-- to be New_Master. This is used to implement build-in-place function
-- returns. Tasks that are part of the return object are initially placed
-- on an activation chain local to the return statement, and their master
-- is the return statement, in case the return statement is left
-- prematurely (due to raising an exception, being aborted, or a goto or
-- exit statement). Once the return statement has completed successfully,
-- Move_Activation_Chain is called to move them to the caller's activation
-- chain, and change their master to the one passed in by the caller. If
-- that doesn't happen, they will never be activated, and will become
-- terminated on leaving the return statement.
function Terminated (T : Task_Id) return Boolean; function Terminated (T : Task_Id) return Boolean;
-- This is called by the compiler to implement the 'Terminated attribute. -- This is called by the compiler to implement the 'Terminated attribute.
-- Though is not required to be so by the ARM, we choose to synchronize -- Though is not required to be so by the ARM, we choose to synchronize
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
with Types; use Types; with Types; use Types;
package Sem_Ch6 is package Sem_Ch6 is
type Conformance_Type is
(Type_Conformant, Mode_Conformant, Subtype_Conformant, Fully_Conformant);
-- Conformance type used in conformance checks between specs and bodies,
-- and for overriding. The literals match the RM definitions of the
-- corresponding terms.
procedure Analyze_Abstract_Subprogram_Declaration (N : Node_Id); procedure Analyze_Abstract_Subprogram_Declaration (N : Node_Id);
procedure Analyze_Extended_Return_Statement (N : Node_Id); procedure Analyze_Extended_Return_Statement (N : Node_Id);
procedure Analyze_Function_Call (N : Node_Id); procedure Analyze_Function_Call (N : Node_Id);
...@@ -39,7 +45,8 @@ package Sem_Ch6 is ...@@ -39,7 +45,8 @@ package Sem_Ch6 is
function Analyze_Subprogram_Specification (N : Node_Id) return Entity_Id; function Analyze_Subprogram_Specification (N : Node_Id) return Entity_Id;
-- Analyze subprogram specification in both subprogram declarations -- Analyze subprogram specification in both subprogram declarations
-- and body declarations. Returns the defining entity for the spec. -- and body declarations. Returns the defining entity for the
-- specification N.
procedure Cannot_Inline (Msg : String; N : Node_Id; Subp : Entity_Id); procedure Cannot_Inline (Msg : String; N : Node_Id; Subp : Entity_Id);
-- This procedure is called if the node N, an instance of a call to -- This procedure is called if the node N, an instance of a call to
...@@ -55,9 +62,9 @@ package Sem_Ch6 is ...@@ -55,9 +62,9 @@ package Sem_Ch6 is
-- their respective counterparts. -- their respective counterparts.
procedure Check_Delayed_Subprogram (Designator : Entity_Id); procedure Check_Delayed_Subprogram (Designator : Entity_Id);
-- Designator can be a E_Subrpgram_Type, E_Procedure or E_Function. If a -- Designator can be a E_Subprogram_Type, E_Procedure or E_Function. If a
-- type in its profile depends on a private type without a full -- type in its profile depends on a private type without a full
-- declaration, indicate that the subprogram is delayed. -- declaration, indicate that the subprogram or type is delayed.
procedure Check_Discriminant_Conformance procedure Check_Discriminant_Conformance
(N : Node_Id; (N : Node_Id;
...@@ -112,6 +119,16 @@ package Sem_Ch6 is ...@@ -112,6 +119,16 @@ package Sem_Ch6 is
-- the flag being placed on the Err_Loc node if it is specified, and -- the flag being placed on the Err_Loc node if it is specified, and
-- on the appropriate component of the New_Id construct if not. -- on the appropriate component of the New_Id construct if not.
function Conforming_Types
(T1 : Entity_Id;
T2 : Entity_Id;
Ctype : Conformance_Type;
Get_Inst : Boolean := False) return Boolean;
-- Check that the types of two formal parameters are conforming. In most
-- cases this is just a name comparison, but within an instance it involves
-- generic actual types, and in the presence of anonymous access types
-- it must examine the designated types.
procedure Create_Extra_Formals (E : Entity_Id); procedure Create_Extra_Formals (E : Entity_Id);
-- For each parameter of a subprogram or entry that requires an additional -- For each parameter of a subprogram or entry that requires an additional
-- formal (such as for access parameters and indefinite discriminated -- formal (such as for access parameters and indefinite discriminated
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment