diff options
-rw-r--r-- | gcc/ada/exp_ch6.adb | 1069 | ||||
-rw-r--r-- | gcc/ada/exp_ch6.ads | 63 |
2 files changed, 758 insertions, 374 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb index 304919f..9068412 100644 --- a/gcc/ada/exp_ch6.adb +++ b/gcc/ada/exp_ch6.adb @@ -57,10 +57,12 @@ with Sem_Ch6; use Sem_Ch6; with Sem_Ch8; use Sem_Ch8; with Sem_Ch12; use Sem_Ch12; with Sem_Ch13; use Sem_Ch13; +with Sem_Eval; use Sem_Eval; with Sem_Disp; use Sem_Disp; with Sem_Dist; use Sem_Dist; with Sem_Mech; use Sem_Mech; with Sem_Res; use Sem_Res; +with Sem_Type; use Sem_Type; with Sem_Util; use Sem_Util; with Sinfo; use Sinfo; with Snames; use Snames; @@ -76,6 +78,15 @@ package body Exp_Ch6 is -- Local Subprograms -- ----------------------- + procedure Add_Access_Actual_To_Build_In_Place_Call + (Function_Call : Node_Id; + Function_Id : Entity_Id; + Return_Object : Node_Id); + -- Ada 2005 (AI-318-02): Apply the Unrestricted_Access attribute to the + -- object name given by Return_Object and add the attribute to the end of + -- the actual parameter list associated with the build-in-place function + -- call denoted by Function_Call. + procedure Check_Overriding_Operation (Subp : Entity_Id); -- Subp is a dispatching operation. Check whether it may override an -- inherited private operation, in which case its DT entry is that of @@ -143,8 +154,7 @@ package body Exp_Ch6 is function Expand_Protected_Object_Reference (N : Node_Id; - Scop : Entity_Id) - return Node_Id; + Scop : Entity_Id) return Node_Id; procedure Expand_Protected_Subprogram_Call (N : Node_Id; @@ -155,6 +165,74 @@ package body Exp_Ch6 is -- reference to the object itself, and the call becomes a call to the -- corresponding protected subprogram. + ---------------------------------------------- + -- Add_Access_Actual_To_Build_In_Place_Call -- + ---------------------------------------------- + + procedure Add_Access_Actual_To_Build_In_Place_Call + (Function_Call : Node_Id; + Function_Id : Entity_Id; + Return_Object : Node_Id) + is + Loc : constant Source_Ptr := Sloc (Function_Call); + Obj_Address : Node_Id; + Obj_Acc_Formal : Node_Id; + Param_Assoc : Node_Id; + + begin + -- Locate the implicit access parameter in the called function. Maybe + -- we should be testing for the name of the access parameter (or perhaps + -- better, each implicit formal for build-in-place could have an + -- identifying flag, or a Uint attribute to identify it). ??? + + Obj_Acc_Formal := Extra_Formals (Function_Id); + + while Present (Obj_Acc_Formal) loop + exit when Ekind (Etype (Obj_Acc_Formal)) = E_Anonymous_Access_Type; + Next_Formal_With_Extras (Obj_Acc_Formal); + end loop; + + pragma Assert (Present (Obj_Acc_Formal)); + + -- Apply Unrestricted_Access to caller's return object + + Obj_Address := + Make_Attribute_Reference (Loc, + Prefix => Return_Object, + Attribute_Name => Name_Unrestricted_Access); + + Analyze_And_Resolve (Obj_Address, Etype (Obj_Acc_Formal)); + + -- Build the parameter association for the new actual and add it to the + -- end of the function's actuals. + + Param_Assoc := + Make_Parameter_Association (Loc, + Selector_Name => New_Occurrence_Of (Obj_Acc_Formal, Loc), + Explicit_Actual_Parameter => Obj_Address); + + Set_Parent (Param_Assoc, Function_Call); + Set_Parent (Obj_Address, Param_Assoc); + + if Present (Parameter_Associations (Function_Call)) then + if Nkind (Last (Parameter_Associations (Function_Call))) = + N_Parameter_Association + then + Set_Next_Named_Actual + (Last (Parameter_Associations (Function_Call)), + Obj_Address); + else + Set_First_Named_Actual (Function_Call, Obj_Address); + end if; + + Append (Param_Assoc, To => Parameter_Associations (Function_Call)); + + else + Set_Parameter_Associations (Function_Call, New_List (Param_Assoc)); + Set_First_Named_Actual (Function_Call, Obj_Address); + end if; + end Add_Access_Actual_To_Build_In_Place_Call; + -------------------------------- -- Check_Overriding_Operation -- -------------------------------- @@ -354,7 +432,7 @@ package body Exp_Ch6 is end if; end Process; - function Traverse_Body is new Traverse_Func; + function Traverse_Body is new Traverse_Func (Process); -- Start of processing for Detect_Infinite_Recursion @@ -554,7 +632,9 @@ package body Exp_Ch6 is return; end if; - Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('T')); + Temp := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('T')); -- Use formal type for temp, unless formal type is an unconstrained -- array, in which case we don't have to worry about bounds checks, @@ -652,7 +732,18 @@ package body Exp_Ch6 is end if; elsif Ekind (Formal) = E_In_Parameter then - Init := New_Occurrence_Of (Var, Loc); + + -- Handle the case in which the actual is a type conversion + + if Nkind (Actual) = N_Type_Conversion then + if Conversion_OK (Actual) then + Init := OK_Convert_To (F_Typ, New_Occurrence_Of (Var, Loc)); + else + Init := Convert_To (F_Typ, New_Occurrence_Of (Var, Loc)); + end if; + else + Init := New_Occurrence_Of (Var, Loc); + end if; else Init := Empty; @@ -760,7 +851,9 @@ package body Exp_Ch6 is Reset_Packed_Prefix; - Temp := Make_Defining_Identifier (Loc, New_Internal_Name ('T')); + Temp := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('T')); Incod := Relocate_Node (Actual); Outcod := New_Copy_Tree (Incod); @@ -925,7 +1018,9 @@ package body Exp_Ch6 is return Entity (Actual); else - Var := Make_Defining_Identifier (Loc, New_Internal_Name ('T')); + Var := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('T')); N_Node := Make_Object_Renaming_Declaration (Loc, @@ -990,6 +1085,20 @@ package body Exp_Ch6 is Expand_Protected_Object_Reference (N, Entity (Actual))); end if; + -- Ada 2005 (AI-318-02): If the actual parameter 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 constrained + -- inherently limited result subtypes, but eventually we plan to + -- expand the allowed forms of funtions that are treated as + -- build-in-place. + + if Ada_Version >= Ada_05 + and then Is_Build_In_Place_Function_Call (Actual) + then + Make_Build_In_Place_Call_In_Anonymous_Context (Actual); + end if; + Apply_Constraint_Check (Actual, E_Formal); -- Out parameter case. No constraint checks on access type @@ -1054,9 +1163,18 @@ package body Exp_Ch6 is elsif Is_Ref_To_Bit_Packed_Array (Actual) then Add_Simple_Call_By_Copy_Code; - -- If a non-scalar actual is possibly unaligned, we need a copy + -- If a non-scalar actual is possibly bit-aligned, we need a copy + -- because the back-end cannot cope with such objects. In other + -- cases where alignment forces a copy, the back-end generates + -- it properly. It should not be generated unconditionally in the + -- front-end because it does not know precisely the alignment + -- requirements of the target, and makes too conservative an + -- estimate, leading to superfluous copies or spurious errors + -- on by-reference parameters. - elsif Is_Possibly_Unaligned_Object (Actual) + elsif Nkind (Actual) = N_Selected_Component + and then + Component_May_Be_Bit_Aligned (Entity (Selector_Name (Actual))) and then not Represented_As_Scalar (Etype (Formal)) then Add_Simple_Call_By_Copy_Code; @@ -1920,15 +2038,33 @@ package body Exp_Ch6 is and then Nkind (Parent (Parent (N))) = N_Assignment_Statement then Ass := Parent (Parent (N)); + + elsif Nkind (Parent (N)) = N_Explicit_Dereference + and then Nkind (Parent (Parent (N))) = N_Assignment_Statement + then + Ass := Parent (Parent (N)); end if; if Present (Ass) and then Is_Class_Wide_Type (Etype (Name (Ass))) then - if Etype (N) /= Root_Type (Etype (Name (Ass))) then + if Is_Access_Type (Etype (N)) then + if Designated_Type (Etype (N)) /= + Root_Type (Etype (Name (Ass))) + then + Error_Msg_NE + ("tag-indeterminate expression " + & " must have designated type& ('R'M 5.2 (6))", + N, Root_Type (Etype (Name (Ass)))); + else + Propagate_Tag (Name (Ass), N); + end if; + + elsif Etype (N) /= Root_Type (Etype (Name (Ass))) then Error_Msg_NE ("tag-indeterminate expression must have type&" - & "('R'M 5.2 (6))", N, Root_Type (Etype (Name (Ass)))); + & "('R'M 5.2 (6))", N, Root_Type (Etype (Name (Ass)))); + else Propagate_Tag (Name (Ass), N); end if; @@ -2053,6 +2189,9 @@ package body Exp_Ch6 is if Etype (Formal) /= Etype (Parent_Formal) and then Is_Scalar_Type (Etype (Formal)) and then Ekind (Formal) = E_In_Parameter + and then + not Subtypes_Statically_Match + (Etype (Parent_Formal), Etype (Actual)) and then not Raises_Constraint_Error (Actual) then Rewrite (Actual, @@ -2165,7 +2304,9 @@ package body Exp_Ch6 is Selector_Name => New_Occurrence_Of (Next_Entity (First_Entity (T)), Loc)); - Nam := Make_Explicit_Dereference (Loc, Nam); + Nam := + Make_Explicit_Dereference (Loc, + Prefix => Nam); if Present (Parameter_Associations (N)) then Parm := Parameter_Associations (N); @@ -2176,13 +2317,15 @@ package body Exp_Ch6 is Prepend (Obj, Parm); if Etype (D_T) = Standard_Void_Type then - Call := Make_Procedure_Call_Statement (Loc, - Name => Nam, - Parameter_Associations => Parm); + Call := + Make_Procedure_Call_Statement (Loc, + Name => Nam, + Parameter_Associations => Parm); else - Call := Make_Function_Call (Loc, - Name => Nam, - Parameter_Associations => Parm); + Call := + Make_Function_Call (Loc, + Name => Nam, + Parameter_Associations => Parm); end if; Set_First_Named_Actual (Call, First_Named_Actual (N)); @@ -2364,7 +2507,7 @@ package body Exp_Ch6 is -- Functions returning controlled objects need special attention if Controlled_Type (Etype (Subp)) - and then not Is_Return_By_Reference_Type (Etype (Subp)) + and then not Is_Inherently_Limited_Type (Etype (Subp)) then Expand_Ctrl_Function_Call (N); end if; @@ -2574,13 +2717,6 @@ package body Exp_Ch6 is -- If the type returned by the function is unconstrained and the -- call can be inlined, special processing is required. - procedure Find_Result; - -- For a function that returns an unconstrained type, retrieve the - -- name of the single variable that is the expression of a return - -- statement in the body of the function. Build_Body_To_Inline has - -- verified that this variable is unique, even in the presence of - -- multiple return statements. - procedure Make_Exit_Label; -- Build declaration for exit label to be used in Return statements @@ -2602,55 +2738,11 @@ package body Exp_Ch6 is procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id); -- If procedure body has no local variables, inline body without - -- creating block, otherwise rewrite call with block. + -- creating block, otherwise rewrite call with block. function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean; -- Determine whether a formal parameter is used only once in Orig_Bod - ----------------- - -- Find_Result -- - ----------------- - - procedure Find_Result is - Decl : Node_Id; - Id : Node_Id; - - function Get_Return (N : Node_Id) return Traverse_Result; - -- Recursive function to locate return statements in body. - - function Get_Return (N : Node_Id) return Traverse_Result is - begin - if Nkind (N) = N_Return_Statement then - Id := Expression (N); - return Abandon; - else - return OK; - end if; - end Get_Return; - - procedure Find_It is new Traverse_Proc (Get_Return); - - -- Start of processing for Find_Result - - begin - Find_It (Handled_Statement_Sequence (Orig_Bod)); - - -- At this point the body is unanalyzed. Traverse the list of - -- declarations to locate the defining_identifier for it. - - Decl := First (Declarations (Blk)); - - while Present (Decl) loop - if Chars (Defining_Identifier (Decl)) = Chars (Id) then - Targ1 := Defining_Identifier (Decl); - exit; - - else - Next (Decl); - end if; - end loop; - end Find_Result; - --------------------- -- Make_Exit_Label -- --------------------- @@ -2660,7 +2752,9 @@ package body Exp_Ch6 is -- Create exit label for subprogram if one does not exist yet if No (Exit_Lab) then - Lab_Id := Make_Identifier (Loc, New_Internal_Name ('L')); + Lab_Id := + Make_Identifier (Loc, + Chars => New_Internal_Name ('L')); Set_Entity (Lab_Id, Make_Defining_Identifier (Loc, Chars (Lab_Id))); Exit_Lab := Make_Label (Loc, Lab_Id); @@ -2692,11 +2786,20 @@ package body Exp_Ch6 is then A := Renamed_Object (E); + -- Rewrite the occurrence of the formal into an occurrence of + -- the actual. Also establish visibility on the proper view of + -- the actual's subtype for the body's context (if the actual's + -- subtype is private at the call point but its full view is + -- visible to the body, then the inlined tree here must be + -- analyzed with the full view). + if Is_Entity_Name (A) then Rewrite (N, New_Occurrence_Of (Entity (A), Loc)); + Check_Private_View (N); elsif Nkind (A) = N_Defining_Identifier then Rewrite (N, New_Occurrence_Of (A, Loc)); + Check_Private_View (N); else -- numeric literal Rewrite (N, New_Copy (A)); @@ -2881,7 +2984,20 @@ package body Exp_Ch6 is procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is HSS : constant Node_Id := Handled_Statement_Sequence (Blk); begin - if Is_Empty_List (Declarations (Blk)) then + -- If there is a transient scope for N, this will be the scope of the + -- actions for N, and the statements in Blk need to be within this + -- scope. For example, they need to have visibility on the constant + -- declarations created for the formals. + + -- If N needs no transient scope, and if there are no declarations in + -- the inlined body, we can do a little optimization and insert the + -- statements for the body directly after N, and rewrite N to a + -- null statement, instead of rewriting N into a full-blown block + -- statement. + + if not Scope_Is_Transient + and then Is_Empty_List (Declarations (Blk)) + then Insert_List_After (N, Statements (HSS)); Rewrite (N, Make_Null_Statement (Loc)); else @@ -2891,7 +3007,7 @@ package body Exp_Ch6 is ------------------------- -- Formal_Is_Used_Once -- - ------------------------ + ------------------------- function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean is Use_Counter : Int := 0; @@ -3009,10 +3125,14 @@ package body Exp_Ch6 is end if; -- For the unconstrained case, capture the name of the local - -- variable that holds the result. + -- variable that holds the result. This must be the first declaration + -- in the block, because its bounds cannot depend on local variables. + -- Otherwise there is no way to declare the result outside of the + -- block. Needless to say, in general the bounds will depend on the + -- actuals in the call. if Is_Unc then - Find_Result; + Targ1 := Defining_Identifier (First (Declarations (Blk))); end if; -- If this is a derived function, establish the proper return type @@ -3099,9 +3219,10 @@ package body Exp_Ch6 is if Nkind (A) = N_Type_Conversion and then Ekind (F) /= E_In_Parameter then - New_A := Make_Unchecked_Type_Conversion (Loc, - Subtype_Mark => New_Occurrence_Of (Etype (F), Loc), - Expression => Relocate_Node (Expression (A))); + New_A := + Make_Unchecked_Type_Conversion (Loc, + Subtype_Mark => New_Occurrence_Of (Etype (F), Loc), + Expression => Relocate_Node (Expression (A))); elsif Etype (F) /= Etype (A) then New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A)); @@ -3113,8 +3234,13 @@ package body Exp_Ch6 is Set_Sloc (New_A, Sloc (N)); + -- If the actual has a by-reference type, it cannot be copied, so + -- its value is captured in a renaming declaration. Otherwise + -- declare a local constant initalized with the actual. + if Ekind (F) = E_In_Parameter and then not Is_Limited_Type (Etype (A)) + and then not Is_Tagged_Type (Etype (A)) then Decl := Make_Object_Declaration (Loc, @@ -3289,8 +3415,10 @@ package body Exp_Ch6 is Typ : constant Entity_Id := Etype (N); function Returned_By_Reference return Boolean; - -- If the return type is returned through the secondary stack. that is + -- If the return type is returned through the secondary stack; that is -- by reference, we don't want to create a temp to force stack checking. + -- ???"sec stack" is not right -- Ada 95 return-by-reference object are + -- returned whereever they are. -- Shouldn't this function be moved to exp_util??? function Rhs_Of_Assign_Or_Decl (N : Node_Id) return Boolean; @@ -3312,7 +3440,7 @@ package body Exp_Ch6 is S : Entity_Id; begin - if Is_Return_By_Reference_Type (Typ) then + if Is_Inherently_Limited_Type (Typ) then return True; elsif Nkind (Parent (N)) /= N_Return_Statement then @@ -3612,8 +3740,12 @@ package body Exp_Ch6 is -- Build and set declarations for the wrapped thread body - Ent_SS := Make_Defining_Identifier (Loc, Name_uSecondary_Stack); - Ent_ATSD := Make_Defining_Identifier (Loc, Name_uProcess_ATSD); + Ent_SS := + Make_Defining_Identifier (Loc, + Chars => Name_uSecondary_Stack); + Ent_ATSD := + Make_Defining_Identifier (Loc, + Chars => Name_uProcess_ATSD); Decl_SS := Make_Object_Declaration (Loc, @@ -3649,7 +3781,9 @@ package body Exp_Ch6 is else Check_Restriction (No_Exception_Handlers, N); - Ent_EO := Make_Defining_Identifier (Loc, Name_uE); + Ent_EO := + Make_Defining_Identifier (Loc, + Chars => Name_uE); Excep_Handlers := New_List ( Make_Exception_Handler (Loc, @@ -3783,15 +3917,8 @@ package body Exp_Ch6 is if Init_Or_Norm_Scalars and then Is_Subprogram (Spec_Id) then declare F : Entity_Id; - V : constant Boolean := Validity_Checks_On; begin - -- We turn off validity checking, since we do not want any - -- check on the initializing value itself (which we know - -- may well be invalid!) - - Validity_Checks_On := False; - -- Loop through formals F := First_Formal (Spec_Id); @@ -3799,16 +3926,19 @@ package body Exp_Ch6 is if Is_Scalar_Type (Etype (F)) and then Ekind (F) = E_Out_Parameter then + -- Insert the initialization. We turn off validity checks + -- for this assignment, since we do not want any check on + -- the initial value itself (which may well be invalid). + Insert_Before_And_Analyze (First (L), Make_Assignment_Statement (Loc, - Name => New_Occurrence_Of (F, Loc), - Expression => Get_Simple_Init_Val (Etype (F), Loc))); + Name => New_Occurrence_Of (F, Loc), + Expression => Get_Simple_Init_Val (Etype (F), Loc)), + Suppress => Validity_Check); end if; Next_Formal (F); end loop; - - Validity_Checks_On := V; end; end if; @@ -3870,10 +4000,12 @@ package body Exp_Ch6 is then null; - elsif Is_Return_By_Reference_Type (Typ) then + elsif Is_Inherently_Limited_Type (Typ) then Set_Returns_By_Ref (Spec_Id); - elsif Present (Utyp) and then Controlled_Type (Utyp) then + elsif Present (Utyp) + and then (Is_Class_Wide_Type (Utyp) or else Controlled_Type (Utyp)) + then Set_Returns_By_Ref (Spec_Id); end if; end; @@ -4067,6 +4199,8 @@ package body Exp_Ch6 is Pop_Scope; end if; + -- Ada 2005 (AI-348): Generation of the null body + elsif Nkind (Specification (N)) = N_Procedure_Specification and then Null_Present (Specification (N)) then @@ -4104,8 +4238,7 @@ package body Exp_Ch6 is function Expand_Protected_Object_Reference (N : Node_Id; - Scop : Entity_Id) - return Node_Id + Scop : Entity_Id) return Node_Id is Loc : constant Source_Ptr := Sloc (N); Corr : Entity_Id; @@ -4114,7 +4247,9 @@ package body Exp_Ch6 is Proc : Entity_Id; begin - Rec := Make_Identifier (Loc, Name_uObject); + Rec := + Make_Identifier (Loc, + Chars => Name_uObject); Set_Etype (Rec, Corresponding_Record_Type (Scop)); -- Find enclosing protected operation, and retrieve its first parameter, @@ -4261,266 +4396,77 @@ package body Exp_Ch6 is end if; end Expand_Protected_Subprogram_Call; - ----------------------- - -- Freeze_Subprogram -- - ----------------------- - - procedure Freeze_Subprogram (N : Node_Id) is - Loc : constant Source_Ptr := Sloc (N); - E : constant Entity_Id := Entity (N); - - procedure Check_Overriding_Inherited_Interfaces (E : Entity_Id); - -- (Ada 2005): Check if the primitive E covers some interface already - -- implemented by some ancestor of the tagged-type associated with E. - - procedure Register_Interface_DT_Entry - (Prim : Entity_Id; - Ancestor_Iface_Prim : Entity_Id := Empty); - -- (Ada 2005): Register an interface primitive in a secondary dispatch - -- table. If Prim overrides an ancestor primitive of its associated - -- tagged-type then Ancestor_Iface_Prim indicates the entity of that - -- immediate ancestor associated with the interface. - - procedure Register_Predefined_DT_Entry (Prim : Entity_Id); - -- (Ada 2005): Register a predefined primitive in all the secondary - -- dispatch tables of its primitive type. - - ------------------------------------------- - -- Check_Overriding_Inherited_Interfaces -- - ------------------------------------------- - - procedure Check_Overriding_Inherited_Interfaces (E : Entity_Id) is - Typ : Entity_Id; - Elmt : Elmt_Id; - Prim_Op : Entity_Id; - Overriden_Op : Entity_Id := Empty; + -------------------------------- + -- Is_Build_In_Place_Function -- + -------------------------------- - begin - if Ada_Version < Ada_05 - or else not Is_Overriding_Operation (E) - or else Is_Predefined_Dispatching_Operation (E) - or else Present (Alias (E)) + function Is_Build_In_Place_Function (E : Entity_Id) return Boolean is + begin + -- For now we test whether E denotes a function or access-to-function + -- type whose result subtype is constrained and inherently limited. + -- Later this test will be revised to include unconstrained limited + -- types and composite nonlimited types in general. Functions with + -- a foreign convention or whose result type has a foreign convention + -- never qualify. + + if Ekind (E) = E_Function + or else (Ekind (E) = E_Subprogram_Type + and then Etype (E) /= Standard_Void_Type) + then + if Has_Foreign_Convention (E) + or else Has_Foreign_Convention (Etype (E)) then - return; - end if; - - -- Get the entity associated with this primitive operation - - Typ := Scope (DTC_Entity (E)); - loop - exit when Etype (Typ) = Typ - or else (Present (Full_View (Etype (Typ))) - and then Full_View (Etype (Typ)) = Typ); - - -- Climb to the immediate ancestor handling private types - - if Present (Full_View (Etype (Typ))) then - Typ := Full_View (Etype (Typ)); - else - Typ := Etype (Typ); - end if; - - if Present (Abstract_Interfaces (Typ)) then - - -- Look for the overriden subprogram in the primary dispatch - -- table of the ancestor. - - Overriden_Op := Empty; - Elmt := First_Elmt (Primitive_Operations (Typ)); - while Present (Elmt) loop - Prim_Op := Node (Elmt); - - if Chars (Prim_Op) = Chars (E) - and then Type_Conformant - (New_Id => Prim_Op, - Old_Id => E, - Skip_Controlling_Formals => True) - and then DT_Position (Prim_Op) = DT_Position (E) - and then Etype (DTC_Entity (Prim_Op)) = RTE (RE_Tag) - and then No (Abstract_Interface_Alias (Prim_Op)) - then - if Overriden_Op = Empty then - Overriden_Op := Prim_Op; - - -- Additional check to ensure that if two candidates have - -- been found then they refer to the same subprogram. - - else - declare - A1 : Entity_Id; - A2 : Entity_Id; - - begin - A1 := Overriden_Op; - while Present (Alias (A1)) loop - A1 := Alias (A1); - end loop; - - A2 := Prim_Op; - while Present (Alias (A2)) loop - A2 := Alias (A2); - end loop; - - if A1 /= A2 then - raise Program_Error; - end if; - end; - end if; - end if; - - Next_Elmt (Elmt); - end loop; - - -- If not found this is the first overriding of some abstract - -- interface. - - if Overriden_Op /= Empty then - - -- Find the entries associated with interfaces that are - -- alias of this primitive operation in the ancestor. - - Elmt := First_Elmt (Primitive_Operations (Typ)); - while Present (Elmt) loop - Prim_Op := Node (Elmt); - - if Present (Abstract_Interface_Alias (Prim_Op)) - and then Alias (Prim_Op) = Overriden_Op - then - Register_Interface_DT_Entry (E, Prim_Op); - end if; - - Next_Elmt (Elmt); - end loop; - end if; - end if; - end loop; - end Check_Overriding_Inherited_Interfaces; - - --------------------------------- - -- Register_Interface_DT_Entry -- - --------------------------------- - - procedure Register_Interface_DT_Entry - (Prim : Entity_Id; - Ancestor_Iface_Prim : Entity_Id := Empty) - is - E : Entity_Id; - Prim_Typ : Entity_Id; - Prim_Op : Entity_Id; - Iface_Typ : Entity_Id; - Iface_DT_Ptr : Entity_Id; - Iface_Tag : Entity_Id; - New_Thunk : Node_Id; - Thunk_Id : Entity_Id; - - begin - -- Nothing to do if the run-time does not give support to abstract - -- interfaces. + return False; - if not (RTE_Available (RE_Interface_Tag)) then - return; + else + return Is_Inherently_Limited_Type (Etype (E)) + and then Is_Constrained (Etype (E)); end if; - if No (Ancestor_Iface_Prim) then - Prim_Typ := Scope (DTC_Entity (Alias (Prim))); - - -- Look for the abstract interface subprogram - - E := Abstract_Interface_Alias (Prim); - while Present (E) - and then Is_Abstract (E) - and then not Is_Interface (Scope (DTC_Entity (E))) - loop - E := Alias (E); - end loop; - - Iface_Typ := Scope (DTC_Entity (E)); - - -- Generate the code of the thunk only when this primitive - -- operation is associated with a secondary dispatch table. - - if Is_Interface (Iface_Typ) then - Iface_Tag := Find_Interface_Tag - (T => Prim_Typ, - Iface => Iface_Typ); - - if Etype (Iface_Tag) = RTE (RE_Interface_Tag) then - Thunk_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('T')); - - New_Thunk := - Expand_Interface_Thunk - (N => Prim, - Thunk_Alias => Alias (Prim), - Thunk_Id => Thunk_Id); + else + return False; + end if; + end Is_Build_In_Place_Function; - Insert_After (N, New_Thunk); + ------------------------------------- + -- Is_Build_In_Place_Function_Call -- + ------------------------------------- - Iface_DT_Ptr := - Find_Interface_ADT - (T => Prim_Typ, - Iface => Iface_Typ); + function Is_Build_In_Place_Function_Call (N : Node_Id) return Boolean is + Exp_Node : Node_Id := N; + Function_Id : Entity_Id; - Insert_After (New_Thunk, - Fill_Secondary_DT_Entry (Sloc (Prim), - Prim => Prim, - Iface_DT_Ptr => Iface_DT_Ptr, - Thunk_Id => Thunk_Id)); - end if; - end if; + begin + if Nkind (Exp_Node) = N_Qualified_Expression then + Exp_Node := Expression (N); + end if; - else - Iface_Typ := - Scope (DTC_Entity (Abstract_Interface_Alias - (Ancestor_Iface_Prim))); + if Nkind (Exp_Node) /= N_Function_Call then + return False; - Iface_Tag := - Find_Interface_Tag - (T => Scope (DTC_Entity (Alias (Ancestor_Iface_Prim))), - Iface => Iface_Typ); + else + if Is_Entity_Name (Name (Exp_Node)) then + Function_Id := Entity (Name (Exp_Node)); - -- Generate the thunk only if the associated tag is an interface - -- tag. The case in which the associated tag is the primary tag - -- occurs when a tagged type is a direct derivation of an - -- interface. For example: + elsif Nkind (Name (Exp_Node)) = N_Explicit_Dereference then + Function_Id := Etype (Name (Exp_Node)); + end if; - -- type I is interface; - -- ... - -- type T is new I with ... + return Is_Build_In_Place_Function (Function_Id); + end if; + end Is_Build_In_Place_Function_Call; - if Etype (Iface_Tag) = RTE (RE_Interface_Tag) then - Thunk_Id := - Make_Defining_Identifier (Loc, - Chars => New_Internal_Name ('T')); + ----------------------- + -- Freeze_Subprogram -- + ----------------------- - if Present (Alias (Prim)) then - Prim_Op := Alias (Prim); - else - Prim_Op := Prim; - end if; + procedure Freeze_Subprogram (N : Node_Id) is + Loc : constant Source_Ptr := Sloc (N); + E : constant Entity_Id := Entity (N); - New_Thunk := - Expand_Interface_Thunk - (N => Ancestor_Iface_Prim, - Thunk_Alias => Prim_Op, - Thunk_Id => Thunk_Id); - - Insert_After (N, New_Thunk); - - Iface_DT_Ptr := - Find_Interface_ADT - (T => Scope (DTC_Entity (Prim_Op)), - Iface => Iface_Typ); - - Insert_After (New_Thunk, - Fill_Secondary_DT_Entry (Sloc (Prim), - Prim => Ancestor_Iface_Prim, - Iface_DT_Ptr => Iface_DT_Ptr, - Thunk_Id => Thunk_Id)); - end if; - end if; - end Register_Interface_DT_Entry; + procedure Register_Predefined_DT_Entry (Prim : Entity_Id); + -- (Ada 2005): Register a predefined primitive in all the secondary + -- dispatch tables of its primitive type. ---------------------------------- -- Register_Predefined_DT_Entry -- @@ -4528,47 +4474,45 @@ package body Exp_Ch6 is procedure Register_Predefined_DT_Entry (Prim : Entity_Id) is Iface_DT_Ptr : Elmt_Id; - Iface_Tag : Entity_Id; - Iface_Typ : Elmt_Id; - New_Thunk : Entity_Id; - Prim_Typ : Entity_Id; + Iface_Typ : Entity_Id; + Iface_Elmt : Elmt_Id; + Tagged_Typ : Entity_Id; Thunk_Id : Entity_Id; begin - Prim_Typ := Scope (DTC_Entity (Prim)); + Tagged_Typ := Find_Dispatching_Type (Prim); - if No (Access_Disp_Table (Prim_Typ)) - or else No (Abstract_Interfaces (Prim_Typ)) + if No (Access_Disp_Table (Tagged_Typ)) + or else No (Abstract_Interfaces (Tagged_Typ)) or else not RTE_Available (RE_Interface_Tag) then return; end if; - -- Skip the first acces-to-dispatch-table pointer since it leads + -- Skip the first access-to-dispatch-table pointer since it leads -- to the primary dispatch table. We are only concerned with the -- secondary dispatch table pointers. Note that the access-to- -- dispatch-table pointer corresponds to the first implemented -- interface retrieved below. - Iface_DT_Ptr := Next_Elmt (First_Elmt (Access_Disp_Table (Prim_Typ))); - Iface_Typ := First_Elmt (Abstract_Interfaces (Prim_Typ)); - while Present (Iface_DT_Ptr) and then Present (Iface_Typ) loop - Iface_Tag := Find_Interface_Tag (Prim_Typ, Node (Iface_Typ)); - pragma Assert (Present (Iface_Tag)); + Iface_DT_Ptr := + Next_Elmt (First_Elmt (Access_Disp_Table (Tagged_Typ))); + Iface_Elmt := First_Elmt (Abstract_Interfaces (Tagged_Typ)); + while Present (Iface_DT_Ptr) and then Present (Iface_Elmt) loop + Iface_Typ := Node (Iface_Elmt); - if Etype (Iface_Tag) = RTE (RE_Interface_Tag) then - Thunk_Id := Make_Defining_Identifier (Loc, - New_Internal_Name ('T')); + if not Is_Ancestor (Iface_Typ, Tagged_Typ) then + Thunk_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('T')); - New_Thunk := + Insert_Actions (N, New_List ( Expand_Interface_Thunk (N => Prim, Thunk_Alias => Prim, - Thunk_Id => Thunk_Id); + Thunk_Id => Thunk_Id), - Insert_After (N, New_Thunk); - Insert_After (New_Thunk, - Make_DT_Access_Action (Node (Iface_Typ), + Make_DT_Access_Action (Iface_Typ, Action => Set_Predefined_Prim_Op_Address, Args => New_List ( Unchecked_Convert_To (RTE (RE_Tag), @@ -4578,17 +4522,28 @@ package body Exp_Ch6 is Make_Attribute_Reference (Loc, Prefix => New_Reference_To (Thunk_Id, Loc), - Attribute_Name => Name_Address)))); + Attribute_Name => Name_Address))))); end if; Next_Elmt (Iface_DT_Ptr); - Next_Elmt (Iface_Typ); + Next_Elmt (Iface_Elmt); end loop; end Register_Predefined_DT_Entry; -- Start of processing for Freeze_Subprogram begin + -- We assume that imported CPP primitives correspond with objects + -- whose constructor is in the CPP side (and therefore we don't need + -- to generate code to register them in the dispatch table). + + if not Debug_Flag_QQ + and then Is_Imported (E) + and then Convention (E) = Convention_CPP + then + return; + end if; + -- When a primitive is frozen, enter its name in the corresponding -- dispatch table. If the DTC_Entity field is not set this is an -- overridden primitive that can be ignored. We suppress the @@ -4634,7 +4589,7 @@ package body Exp_Ch6 is -- a subprogram that covers an abstract interface type. if Present (Abstract_Interface_Alias (E)) then - Register_Interface_DT_Entry (E); + Register_Interface_DT_Entry (N, E); -- Common case: Primitive subprogram @@ -4649,8 +4604,6 @@ package body Exp_Ch6 is Insert_After (N, Fill_DT_Entry (Sloc (N), Prim => E)); end if; - - Check_Overriding_Inherited_Interfaces (E); end if; end if; end; @@ -4666,13 +4619,383 @@ package body Exp_Ch6 is Utyp : constant Entity_Id := Underlying_Type (Typ); begin - if Is_Return_By_Reference_Type (Typ) then + if Is_Inherently_Limited_Type (Typ) then Set_Returns_By_Ref (E); - elsif Present (Utyp) and then Controlled_Type (Utyp) then + elsif Present (Utyp) + and then (Is_Class_Wide_Type (Utyp) or else Controlled_Type (Utyp)) + then Set_Returns_By_Ref (E); end if; end; end Freeze_Subprogram; + ------------------------------------------- + -- Make_Build_In_Place_Call_In_Allocator -- + ------------------------------------------- + + procedure Make_Build_In_Place_Call_In_Allocator + (Allocator : Node_Id; + Function_Call : Node_Id) + is + Loc : Source_Ptr; + Func_Call : Node_Id := Function_Call; + Function_Id : Entity_Id; + Result_Subt : Entity_Id; + Acc_Type : constant Entity_Id := Etype (Allocator); + New_Allocator : Node_Id; + Return_Obj_Access : Entity_Id; + + begin + if Nkind (Func_Call) = N_Qualified_Expression then + Func_Call := Expression (Func_Call); + end if; + + Loc := Sloc (Function_Call); + + if Is_Entity_Name (Name (Func_Call)) then + Function_Id := Entity (Name (Func_Call)); + + elsif Nkind (Name (Func_Call)) = N_Explicit_Dereference then + Function_Id := Etype (Name (Func_Call)); + + else + raise Program_Error; + end if; + + Result_Subt := Etype (Function_Id); + + -- Replace the initialized allocator of form "new T'(Func (...))" with + -- an uninitialized allocator of form "new T", where T is the result + -- subtype of the called function. The call to the function is handled + -- separately further below. + + New_Allocator := + Make_Allocator (Loc, New_Reference_To (Result_Subt, Loc)); + Set_No_Initialization (New_Allocator); + + Rewrite (Allocator, New_Allocator); + + -- Create a new access object and initialize it to the result of the new + -- uninitialized allocator. + + Return_Obj_Access := + Make_Defining_Identifier (Loc, New_Internal_Name ('R')); + Set_Etype (Return_Obj_Access, Acc_Type); + + Insert_Action (Allocator, + Make_Object_Declaration (Loc, + Defining_Identifier => Return_Obj_Access, + Object_Definition => New_Reference_To (Acc_Type, Loc), + Expression => Relocate_Node (Allocator))); + + -- Add an implicit actual to the function call that provides access to + -- the allocated object. An unchecked conversion to the (specific) + -- result subtype of the function is inserted to handle the case where + -- the access type of the allocator has a class-wide designated type. + + Add_Access_Actual_To_Build_In_Place_Call + (Func_Call, + Function_Id, + Make_Unchecked_Type_Conversion (Loc, + Subtype_Mark => New_Reference_To (Result_Subt, Loc), + Expression => + Make_Explicit_Dereference (Loc, + Prefix => New_Reference_To (Return_Obj_Access, Loc)))); + + -- Finally, replace the allocator node with a reference to the result + -- of the function call itself (which will effectively be an access + -- to the object created by the allocator). + + Rewrite (Allocator, Make_Reference (Loc, Relocate_Node (Function_Call))); + Analyze_And_Resolve (Allocator, Acc_Type); + end Make_Build_In_Place_Call_In_Allocator; + + --------------------------------------------------- + -- Make_Build_In_Place_Call_In_Anonymous_Context -- + --------------------------------------------------- + + procedure Make_Build_In_Place_Call_In_Anonymous_Context + (Function_Call : Node_Id) + is + Loc : Source_Ptr; + Func_Call : Node_Id := Function_Call; + Function_Id : Entity_Id; + Result_Subt : Entity_Id; + Return_Obj_Id : Entity_Id; + Return_Obj_Decl : Entity_Id; + + begin + if Nkind (Func_Call) = N_Qualified_Expression then + Func_Call := Expression (Func_Call); + end if; + + Loc := Sloc (Function_Call); + + if Is_Entity_Name (Name (Func_Call)) then + Function_Id := Entity (Name (Func_Call)); + + elsif Nkind (Name (Func_Call)) = N_Explicit_Dereference then + Function_Id := Etype (Name (Func_Call)); + + else + raise Program_Error; + end if; + + Result_Subt := Etype (Function_Id); + + -- Create a temporary object to hold the function result + + Return_Obj_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('R')); + Set_Etype (Return_Obj_Id, Result_Subt); + + Return_Obj_Decl := + Make_Object_Declaration (Loc, + Defining_Identifier => Return_Obj_Id, + Aliased_Present => True, + Object_Definition => New_Reference_To (Result_Subt, Loc)); + + Set_No_Initialization (Return_Obj_Decl); + + Insert_Action (Func_Call, Return_Obj_Decl); + + -- Add an implicit actual to the function call that provides access to + -- the caller's return object. + + Add_Access_Actual_To_Build_In_Place_Call + (Func_Call, Function_Id, New_Reference_To (Return_Obj_Id, Loc)); + end Make_Build_In_Place_Call_In_Anonymous_Context; + + --------------------------------------------------- + -- Make_Build_In_Place_Call_In_Assignment -- + --------------------------------------------------- + + procedure Make_Build_In_Place_Call_In_Assignment + (Assign : Node_Id; + Function_Call : Node_Id) + is + Lhs : constant Node_Id := Name (Assign); + Loc : Source_Ptr; + Func_Call : Node_Id := Function_Call; + Function_Id : Entity_Id; + Result_Subt : Entity_Id; + Ref_Type : Entity_Id; + Ptr_Typ_Decl : Node_Id; + Def_Id : Entity_Id; + New_Expr : Node_Id; + + begin + if Nkind (Func_Call) = N_Qualified_Expression then + Func_Call := Expression (Func_Call); + end if; + + Loc := Sloc (Function_Call); + + if Is_Entity_Name (Name (Func_Call)) then + Function_Id := Entity (Name (Func_Call)); + + elsif Nkind (Name (Func_Call)) = N_Explicit_Dereference then + Function_Id := Etype (Name (Func_Call)); + + else + raise Program_Error; + end if; + + Result_Subt := Etype (Function_Id); + + -- Add an implicit actual to the function call that provides access to + -- the caller's return object. + + Add_Access_Actual_To_Build_In_Place_Call + (Func_Call, + Function_Id, + Make_Unchecked_Type_Conversion (Loc, + Subtype_Mark => New_Reference_To (Result_Subt, Loc), + Expression => Relocate_Node (Lhs))); + + -- Create an access type designating the function's result subtype + + Ref_Type := + Make_Defining_Identifier (Loc, New_Internal_Name ('A')); + + Ptr_Typ_Decl := + Make_Full_Type_Declaration (Loc, + Defining_Identifier => Ref_Type, + Type_Definition => + Make_Access_To_Object_Definition (Loc, + All_Present => True, + Subtype_Indication => + New_Reference_To (Result_Subt, Loc))); + + Insert_After_And_Analyze (Assign, Ptr_Typ_Decl); + + -- Finally, create an access object initialized to a reference to the + -- function call. + + Def_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('R')); + Set_Etype (Def_Id, Ref_Type); + + New_Expr := + Make_Reference (Loc, + Prefix => Relocate_Node (Func_Call)); + + Insert_After_And_Analyze (Ptr_Typ_Decl, + Make_Object_Declaration (Loc, + Defining_Identifier => Def_Id, + Object_Definition => New_Reference_To (Ref_Type, Loc), + Expression => New_Expr)); + + Rewrite (Assign, Make_Null_Statement (Loc)); + end Make_Build_In_Place_Call_In_Assignment; + + ---------------------------------------------------- + -- Make_Build_In_Place_Call_In_Object_Declaration -- + ---------------------------------------------------- + + procedure Make_Build_In_Place_Call_In_Object_Declaration + (Object_Decl : Node_Id; + Function_Call : Node_Id) + is + Loc : Source_Ptr; + Func_Call : Node_Id := Function_Call; + Function_Id : Entity_Id; + Result_Subt : Entity_Id; + Ref_Type : Entity_Id; + Ptr_Typ_Decl : Node_Id; + Def_Id : Entity_Id; + New_Expr : Node_Id; + + begin + if Nkind (Func_Call) = N_Qualified_Expression then + Func_Call := Expression (Func_Call); + end if; + + Loc := Sloc (Function_Call); + + if Is_Entity_Name (Name (Func_Call)) then + Function_Id := Entity (Name (Func_Call)); + + elsif Nkind (Name (Func_Call)) = N_Explicit_Dereference then + Function_Id := Etype (Name (Func_Call)); + + else + raise Program_Error; + end if; + + Result_Subt := Etype (Function_Id); + + -- Add an implicit actual to the function call that provides access to + -- the declared object. An unchecked conversion to the (specific) result + -- type of the function is inserted to handle the case where the object + -- is declared with a class-wide type. + + Add_Access_Actual_To_Build_In_Place_Call + (Func_Call, + Function_Id, + Make_Unchecked_Type_Conversion (Loc, + Subtype_Mark => New_Reference_To (Result_Subt, Loc), + Expression => New_Reference_To + (Defining_Identifier (Object_Decl), Loc))); + + -- Create an access type designating the function's result subtype + + Ref_Type := + Make_Defining_Identifier (Loc, New_Internal_Name ('A')); + + Ptr_Typ_Decl := + Make_Full_Type_Declaration (Loc, + Defining_Identifier => Ref_Type, + Type_Definition => + Make_Access_To_Object_Definition (Loc, + All_Present => True, + Subtype_Indication => + New_Reference_To (Result_Subt, Loc))); + + Insert_After_And_Analyze (Object_Decl, Ptr_Typ_Decl); + + -- Finally, create an access object initialized to a reference to the + -- function call. + + Def_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('R')); + Set_Etype (Def_Id, Ref_Type); + + New_Expr := + Make_Reference (Loc, + Prefix => Relocate_Node (Func_Call)); + + Insert_After_And_Analyze (Ptr_Typ_Decl, + Make_Object_Declaration (Loc, + Defining_Identifier => Def_Id, + Object_Definition => New_Reference_To (Ref_Type, Loc), + Expression => New_Expr)); + + Set_Expression (Object_Decl, Empty); + Set_No_Initialization (Object_Decl); + + -- If the object entity has a class-wide Etype, then we need to change + -- it to the result subtype of the function call, because otherwise the + -- object will be class-wide without an explicit intialization and won't + -- be allocated properly by the back end. It seems unclean to make such + -- a revision to the type at this point, and we should try to improve + -- this treatment when build-in-place functions with class-wide results + -- are implemented. ??? + + if Is_Class_Wide_Type (Etype (Defining_Identifier (Object_Decl))) then + Set_Etype (Defining_Identifier (Object_Decl), Result_Subt); + end if; + end Make_Build_In_Place_Call_In_Object_Declaration; + + --------------------------------- + -- Register_Interface_DT_Entry -- + --------------------------------- + + procedure Register_Interface_DT_Entry + (Related_Nod : Node_Id; + Prim : Entity_Id) + is + Loc : constant Source_Ptr := Sloc (Prim); + Iface_Typ : Entity_Id; + Tagged_Typ : Entity_Id; + Thunk_Id : Entity_Id; + + begin + -- Nothing to do if the run-time does not support abstract interfaces + + if not (RTE_Available (RE_Interface_Tag)) then + return; + end if; + + Tagged_Typ := Find_Dispatching_Type (Alias (Prim)); + Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim)); + + -- Generate the code of the thunk only if the abstract interface type is + -- not an immediate ancestor of Tagged_Type; otherwise the dispatch + -- table associated with the interface is the primary dispatch table. + + pragma Assert (Is_Interface (Iface_Typ)); + + if not Is_Ancestor (Iface_Typ, Tagged_Typ) then + Thunk_Id := + Make_Defining_Identifier (Loc, + Chars => New_Internal_Name ('T')); + + Insert_Actions (Related_Nod, New_List ( + Expand_Interface_Thunk + (N => Prim, + Thunk_Alias => Alias (Prim), + Thunk_Id => Thunk_Id), + + Fill_Secondary_DT_Entry (Sloc (Prim), + Prim => Prim, + Iface_DT_Ptr => Find_Interface_ADT (Tagged_Typ, Iface_Typ), + Thunk_Id => Thunk_Id))); + end if; + end Register_Interface_DT_Entry; + end Exp_Ch6; diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads index e36a4c2..219ce70 100644 --- a/gcc/ada/exp_ch6.ads +++ b/gcc/ada/exp_ch6.ads @@ -6,7 +6,7 @@ -- -- -- S p e c -- -- -- --- Copyright (C) 1992,1993,1994,1995 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 -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -40,9 +40,70 @@ package Exp_Ch6 is -- This procedure contains common processing for Expand_N_Function_Call, -- Expand_N_Procedure_Statement, and Expand_N_Entry_Call. + 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 + -- access-to-function type whose result must be built in place; otherwise + -- returns False. Currently this is restricted to the subset of functions + -- whose result subtype is a constrained inherently limited type. + + 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 + -- that requires handling as a build-in-place call or is a qualified + -- expression applied to such a call; otherwise returns False. + 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) + procedure Make_Build_In_Place_Call_In_Allocator + (Allocator : Node_Id; + Function_Call : Node_Id); + -- Ada 2005 (AI-318-02): Handle a call to a build-in-place function that + -- occurs as the expression initializing an allocator, by passing access + -- to the allocated object as an additional parameter of the function call. + -- A new access object is declared that is initialized to the result of the + -- allocator, passed to the function, and the allocator is rewritten to + -- refer to that access object. Function_Call must denote either an + -- N_Function_Call node for which Is_Build_In_Place_Call is True, or else + -- an N_Qualified_Expression node applied to such a function call. + + procedure Make_Build_In_Place_Call_In_Anonymous_Context + (Function_Call : Node_Id); + -- Ada 2005 (AI-318-02): Handle a call to a build-in-place function that + -- occurs in a context that does not provide a separate object. A temporary + -- object is created to act as the return object and an access to the + -- temporary is passed as an additional parameter of the call. This occurs + -- in contexts such as subprogram call actuals and object renamings. + -- Function_Call must denote either an N_Function_Call node for which + -- Is_Build_In_Place_Call is True, or else an N_Qualified_Expression node + -- applied to such a function call. + + procedure Make_Build_In_Place_Call_In_Assignment + (Assign : Node_Id; + Function_Call : Node_Id); + -- 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 + -- access to the left-hand sid as an additional parameter of the function + -- 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 + -- is True, or an N_Qualified_Expression node applied to such a function + -- call. + + procedure Make_Build_In_Place_Call_In_Object_Declaration + (Object_Decl : Node_Id; + Function_Call : Node_Id); + -- Ada 2005 (AI-318-02): Handle a call to a build-in-place function that + -- occurs as the expression initializing an object declaration by + -- passing access to the declared object as an additional parameter of the + -- function call. Function_Call must 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 call. + + procedure Register_Interface_DT_Entry + (Related_Nod : Node_Id; + Prim : Entity_Id); + -- Ada 2005 (AI-251): Register a primitive in a secondary dispatch table. + -- Related_Nod is the node after which the expanded code will be inserted. + end Exp_Ch6; |