diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-22 12:50:35 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-22 12:50:35 +0000 |
commit | 005366f73940ec02cd9d74d82e61ad390e2130eb (patch) | |
tree | e30d8fa127f2a8d0f8e2223bd9662d6dc7888059 /gcc/ada/exp_ch4.adb | |
parent | 0131155887c89c985954d139c31a92422997f165 (diff) | |
download | gcc-005366f73940ec02cd9d74d82e61ad390e2130eb.tar.gz |
2015-05-22 Eric Botcazou <ebotcazou@adacore.com>
* sprint.adb (Source_Dump): When generating debug files, deal
with the case of a stand-alone package instantiation by dumping
together the spec and the body in the common debug file.
2015-05-22 Robert Dewar <dewar@adacore.com>
* sem_ch13.adb (Minimum_Size): Size is zero for null range
discrete subtype.
2015-05-22 Hristian Kirtchev <kirtchev@adacore.com>
* einfo.adb (Anonymous_Master): This attribute now applies
to package and subprogram bodies.
(Set_Anonymous_Master): This attribute now applies to package and
subprogram bodies.
(Write_Field36_Name): Add output for package and subprogram bodies.
* einfo.ads Update the documentation on attribute Anonymous_Master
along with occurrences in entities.
* exp_ch4.adb (Create_Anonymous_Master): Reimplemented to
handle spec and body anonymous masters of the same unit.
(Current_Anonymous_Master): Reimplemented. Handle a
package instantiation that acts as a compilation unit.
(Insert_And_Analyze): Reimplemented.
2015-05-22 Ed Schonberg <schonberg@adacore.com>
* sem_ch10.adb (Analyze_With_Clause): A limited_with_clause on a
predefined unit is treated as a regular with_clause.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223557 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r-- | gcc/ada/exp_ch4.adb | 171 |
1 files changed, 105 insertions, 66 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index c268968dd03..9f3be7eb272 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -416,82 +416,134 @@ package body Exp_Ch4 is function Current_Anonymous_Master return Entity_Id is function Create_Anonymous_Master - (Unit_Id : Entity_Id; - Decls : List_Id) return Entity_Id; - -- Create a new anonymous finalization master for a unit denoted by - -- Unit_Id. The declaration of the master along with any specialized - -- initialization is inserted at the top of declarative list Decls. - -- Return the entity of the anonymous master. + (Unit_Id : Entity_Id; + Unit_Decl : Node_Id) return Entity_Id; + -- Create a new anonymous master for a compilation unit denoted by its + -- entity Unit_Id and declaration Unit_Decl. The declaration of the new + -- master along with any specialized initialization is inserted at the + -- top of the unit's declarations (see body for special cases). Return + -- the entity of the anonymous master. ----------------------------- -- Create_Anonymous_Master -- ----------------------------- function Create_Anonymous_Master - (Unit_Id : Entity_Id; - Decls : List_Id) return Entity_Id + (Unit_Id : Entity_Id; + Unit_Decl : Node_Id) return Entity_Id is - First_Decl : Node_Id := Empty; - -- The first declaration of list Decls. This variable is used when - -- inserting various actions. + Insert_Nod : Node_Id := Empty; + -- The point of insertion into the declarative list of the unit. All + -- nodes are inserted before Insert_Nod. - procedure Insert_And_Analyze (Action : Node_Id); - -- Insert arbitrary node Action in declarative list Decl and analyze - -- it. + procedure Insert_And_Analyze (Decls : List_Id; N : Node_Id); + -- Insert arbitrary node N in declarative list Decls and analyze it ------------------------ -- Insert_And_Analyze -- ------------------------ - procedure Insert_And_Analyze (Action : Node_Id) is + procedure Insert_And_Analyze (Decls : List_Id; N : Node_Id) is begin - -- The list is already populated, the actions are inserted at the - -- top of the list, preserving their order. + -- The declarative list is already populated, the nodes are + -- inserted at the top of the list, preserving their order. - if Present (First_Decl) then - Insert_Before_And_Analyze (First_Decl, Action); + if Present (Insert_Nod) then + Insert_Before (Insert_Nod, N); -- Otherwise append to the declarations to preserve order else - Append_To (Decls, Action); - Analyze (Action); + Append_To (Decls, N); end if; + + Analyze (N); end Insert_And_Analyze; -- Local variables - Loc : constant Source_Ptr := Sloc (Unit_Id); - FM_Id : Entity_Id; + Loc : constant Source_Ptr := Sloc (Unit_Id); + Spec_Id : constant Entity_Id := Corresponding_Spec_Of (Unit_Decl); + Decls : List_Id; + FM_Id : Entity_Id; + Pref : Character; + Unit_Spec : Node_Id; -- Start of processing for Create_Anonymous_Master begin - if Present (Decls) then - First_Decl := First (Decls); + -- Find the declarative list of the unit + + if Nkind (Unit_Decl) = N_Package_Declaration then + Unit_Spec := Specification (Unit_Decl); + Decls := Visible_Declarations (Unit_Spec); + + if No (Decls) then + Decls := New_List (Make_Null_Statement (Loc)); + Set_Visible_Declarations (Unit_Spec, Decls); + end if; + + -- Package or subprogram body + + -- ??? A subprogram declaration that acts as a compilation unit may + -- contain a formal parameter of an anonymous access-to-controlled + -- type initialized by an allocator. + + -- procedure Comp_Unit_Proc (Param : access Ctrl := new Ctrl); + + -- There is no suitable place to create the anonymous master as the + -- subprogram is not in a declarative list. + + else + Decls := Declarations (Unit_Decl); + + if No (Decls) then + Decls := New_List (Make_Null_Statement (Loc)); + Set_Declarations (Unit_Decl, Decls); + end if; end if; + -- The anonymous master and all initialization actions are inserted + -- before the first declaration (if any). + + Insert_Nod := First (Decls); + -- Since the anonymous master and all its initialization actions are -- inserted at top level, use the scope of the unit when analyzing. - Push_Scope (Unit_Id); + Push_Scope (Spec_Id); - -- Create the anonymous master + -- Step 1: Anonymous master creation + + -- Use a unique prefix in case the same unit requires two anonymous + -- masters, one for the spec (S) and one for the body (B). + + if Ekind_In (Unit_Id, E_Function, E_Package, E_Procedure) then + Pref := 'S'; + else + Pref := 'B'; + end if; FM_Id := Make_Defining_Identifier (Loc, - Chars => New_External_Name (Chars (Unit_Id), "AM")); + New_External_Name + (Related_Id => Chars (Unit_Id), + Suffix => "AM", + Prefix => Pref)); + Set_Anonymous_Master (Unit_Id, FM_Id); -- Generate: -- <FM_Id> : Finalization_Master; - Insert_And_Analyze - (Make_Object_Declaration (Loc, + Insert_And_Analyze (Decls, + Make_Object_Declaration (Loc, Defining_Identifier => FM_Id, Object_Definition => New_Occurrence_Of (RTE (RE_Finalization_Master), Loc))); + -- Step 2: Initialization actions + -- Do not set the base pool and mode of operation on .NET/JVM since -- those targets do not support pools and all VM masters defaulted to -- heterogeneous. @@ -502,8 +554,8 @@ package body Exp_Ch4 is -- Set_Base_Pool -- (<FM_Id>, Global_Pool_Object'Unrestricted_Access); - Insert_And_Analyze - (Make_Procedure_Call_Statement (Loc, + Insert_And_Analyze (Decls, + Make_Procedure_Call_Statement (Loc, Name => New_Occurrence_Of (RTE (RE_Set_Base_Pool), Loc), Parameter_Associations => New_List ( @@ -516,8 +568,8 @@ package body Exp_Ch4 is -- Generate: -- Set_Is_Heterogeneous (<FM_Id>); - Insert_And_Analyze - (Make_Procedure_Call_Statement (Loc, + Insert_And_Analyze (Decls, + Make_Procedure_Call_Statement (Loc, Name => New_Occurrence_Of (RTE (RE_Set_Is_Heterogeneous), Loc), Parameter_Associations => New_List ( @@ -530,48 +582,35 @@ package body Exp_Ch4 is -- Local declarations - Unit_Decl : constant Node_Id := Unit (Cunit (Current_Sem_Unit)); - Unit_Id : constant Entity_Id := Corresponding_Spec_Of (Unit_Decl); - Decls : List_Id; - FM_Id : Entity_Id; - Unit_Spec : Node_Id; + Unit_Decl : Node_Id; + Unit_Id : Entity_Id; -- Start of processing for Current_Anonymous_Master begin - FM_Id := Anonymous_Master (Unit_Id); - - -- Create a new anonymous master when allocating an object of anonymous - -- access-to-controlled type for the first time. - - if No (FM_Id) then + Unit_Decl := Unit (Cunit (Current_Sem_Unit)); + Unit_Id := Defining_Entity (Unit_Decl); - -- Find the declarative list of the current unit + -- The compilation unit is a package instantiation. In this case the + -- anonymous master is associated with the package spec as both the + -- spec and body appear at the same level. - if Nkind (Unit_Decl) = N_Package_Declaration then - Unit_Spec := Specification (Unit_Decl); - Decls := Visible_Declarations (Unit_Spec); - - if No (Decls) then - Decls := New_List; - Set_Visible_Declarations (Unit_Spec, Decls); - end if; + if Nkind (Unit_Decl) = N_Package_Body + and then Nkind (Original_Node (Unit_Decl)) = N_Package_Instantiation + then + Unit_Id := Corresponding_Spec (Unit_Decl); + Unit_Decl := Unit_Declaration_Node (Unit_Id); + end if; - -- Package or subprogram body + if Present (Anonymous_Master (Unit_Id)) then + return Anonymous_Master (Unit_Id); - else - Decls := Declarations (Unit_Decl); - - if No (Decls) then - Decls := New_List; - Set_Declarations (Unit_Decl, Decls); - end if; - end if; + -- Create a new anonymous master when allocating an object of anonymous + -- access-to-controlled type for the first time. - FM_Id := Create_Anonymous_Master (Unit_Id, Decls); + else + return Create_Anonymous_Master (Unit_Id, Unit_Decl); end if; - - return FM_Id; end Current_Anonymous_Master; -------------------------------- |