From patchwork Thu Sep 9 09:51:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 64272 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 86CF0B6F06 for ; Thu, 9 Sep 2010 19:52:00 +1000 (EST) Received: (qmail 13344 invoked by alias); 9 Sep 2010 09:51:57 -0000 Received: (qmail 13324 invoked by uid 22791); 9 Sep 2010 09:51:53 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 09 Sep 2010 09:51:46 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 8AE14CB021E; Thu, 9 Sep 2010 11:51:44 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DSAshriTAFIT; Thu, 9 Sep 2010 11:51:44 +0200 (CEST) Received: from saumur.act-europe.fr (saumur.act-europe.fr [10.10.0.183]) by mel.act-europe.fr (Postfix) with ESMTP id 7724BCB01F8; Thu, 9 Sep 2010 11:51:44 +0200 (CEST) Received: by saumur.act-europe.fr (Postfix, from userid 525) id 55B15D9BA8; Thu, 9 Sep 2010 11:51:44 +0200 (CEST) Date: Thu, 9 Sep 2010 11:51:44 +0200 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Ed Schonberg Subject: [Ada] Master entities in Ada2005 Message-ID: <20100909095144.GA20580@adacore.com> Mime-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.9i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org When a type includes tasks, a master entity is created in the scope, to be used by the runtime during activation. In general the master is the immedidate scope in which the type is declared, but in Ada2005, in the presence of synchronized classwide interfaces, the immediate scope of an anonymous access type may be a transient scope, which has no run-time presence. In this case, the scope of the master is the innermost scope that comes from source. The following must compile quietly: --- package Pack09 is type Node_Type is limited interface; type Node_Ref is access all Node_Type'Class; function Parent (Node : Node_Type) return Node_Ref is abstract; type Node_Cursor is limited interface; function Has_Element (Position : Node_Cursor) return Boolean is abstract; function Element (Position : Node_Cursor) return Node_Ref is abstract; function Next (Position : Node_Cursor) return Node_Cursor is abstract; function First_Child (Node : Node_Type) return Node_Cursor'Class is abstract; function F (Node : Node_Ref) return Boolean; end Pack09; --- package body Pack09 is function F (Node : Node_Ref) return Boolean is begin return Node.Parent.First_Child.Element = Node and then not Node.Parent.First_Child.Next.Has_Element; end F; end Pack09; Tested on x86_64-pc-linux-gnu, committed on trunk 2010-09-09 Ed Schonberg * exp_ch9.ads (Find_Master_Scope): New function, extracted from Build_Master_Entity, to find the proper scope for the master entity of a type that may contain tasks, in the presence of transient scopes. * exp_ch9.adb (Build_Master_Entity) Use new function. * exp_ch3.adb (Build_Class_Wide_Master): ditto. Index: exp_ch9.adb =================================================================== --- exp_ch9.adb (revision 164055) +++ exp_ch9.adb (working copy) @@ -2481,31 +2481,7 @@ package body Exp_Ch9 is S : Entity_Id; begin - S := Scope (E); - - -- Ada 2005 (AI-287): Do not set/get the has_master_entity reminder - -- in internal scopes, unless present already.. Required for nested - -- limited aggregates, where the expansion of task components may - -- generate inner blocks. If the block is the rewriting of a call - -- or the scope is an extended return statement this is valid master. - -- The master in an extended return is only used within the return, - -- and is subsequently overwritten in Move_Activation_Chain, but it - -- must exist now. - - if Ada_Version >= Ada_05 then - while Is_Internal (S) loop - if Nkind (Parent (S)) = N_Block_Statement - and then - Nkind (Original_Node (Parent (S))) = N_Procedure_Call_Statement - then - exit; - elsif Ekind (S) = E_Return_Statement then - exit; - else - S := Scope (S); - end if; - end loop; - end if; + S := Find_Master_Scope (E); -- Nothing to do if we already built a master entity for this scope -- or if there is no task hierarchy. @@ -2534,14 +2510,7 @@ package body Exp_Ch9 is Insert_Before (P, Decl); Analyze (Decl); - -- Ada 2005 (AI-287): Set the has_master_entity reminder in the - -- non-internal scope selected above. - - if Ada_Version >= Ada_05 then - Set_Has_Master_Entity (S); - else - Set_Has_Master_Entity (Scope (E)); - end if; + Set_Has_Master_Entity (S); -- Now mark the containing scope as a task master @@ -11136,6 +11105,43 @@ package body Exp_Ch9 is Make_Integer_Literal (Loc, 0))); end Family_Size; + ----------------------- + -- Find_Master_Scope -- + ----------------------- + + function Find_Master_Scope (E : Entity_Id) return Entity_Id is + S : Entity_Id; + + begin + -- In Ada2005, the master is the innermost enclosing scope that is not + -- transient. If the enclosing block is the rewriting of a call or the + -- scope is an extended return statement this is valid master. The + -- master in an extended return is only used within the return, and is + -- subsequently overwritten in Move_Activation_Chain, but it must exist + -- now before that overwriting occurs. + + S := Scope (E); + + if Ada_Version >= Ada_05 then + while Is_Internal (S) loop + if Nkind (Parent (S)) = N_Block_Statement + and then + Nkind (Original_Node (Parent (S))) = N_Procedure_Call_Statement + then + exit; + + elsif Ekind (S) = E_Return_Statement then + exit; + + else + S := Scope (S); + end if; + end loop; + end if; + + return S; + end Find_Master_Scope; + ----------------------------------- -- Find_Task_Or_Protected_Pragma -- ----------------------------------- Index: exp_ch9.ads =================================================================== --- exp_ch9.ads (revision 164000) +++ exp_ch9.ads (working copy) @@ -263,6 +263,15 @@ package Exp_Ch9 is -- return the external version of a protected operation, which locks -- the object before invoking the internal protected subprogram body. + function Find_Master_Scope (E : Entity_Id) return Entity_Id; + -- When a type includes tasks, a master entity is created in the scope, to + -- be used by the runtime during activation. In general the master is the + -- immediate scope in which the type is declared, but in Ada2005, in the + -- presence of synchronized classwide interfaces, the immediate scope of + -- an anonymous access type may be a transient scope, which has no run-time + -- presence. In this case, the scope of the master is the innermost scope + -- that comes from source. + function First_Protected_Operation (D : List_Id) return Node_Id; -- Given the declarations list for a protected body, find the -- first protected operation body. Index: exp_ch3.adb =================================================================== --- exp_ch3.adb (revision 164059) +++ exp_ch3.adb (working copy) @@ -41,8 +41,8 @@ with Exp_Strm; use Exp_Strm; with Exp_Tss; use Exp_Tss; with Exp_Util; use Exp_Util; with Freeze; use Freeze; -with Nlists; use Nlists; with Namet; use Namet; +with Nlists; use Nlists; with Nmake; use Nmake; with Opt; use Opt; with Restrict; use Restrict; @@ -792,6 +792,7 @@ package body Exp_Ch3 is Decl : Node_Id; P : Node_Id; Par : Node_Id; + Scop : Entity_Id; begin -- Nothing to do if there is no task hierarchy @@ -810,9 +811,11 @@ package body Exp_Ch3 is P := Parent (T); end if; + Scop := Find_Master_Scope (T); + -- Nothing to do if we already built a master entity for this scope - if not Has_Master_Entity (Scope (T)) then + if not Has_Master_Entity (Scop) then -- First build the master entity -- _Master : constant Master_Id := Current_Master.all; @@ -828,9 +831,9 @@ package body Exp_Ch3 is Make_Explicit_Dereference (Loc, New_Reference_To (RTE (RE_Current_Master), Loc))); + Set_Has_Master_Entity (Scop); Insert_Action (P, Decl); Analyze (Decl); - Set_Has_Master_Entity (Scope (T)); -- Now mark the containing scope as a task master. Masters -- associated with return statements are already marked at