@@ -771,6 +771,13 @@ package body Tree_Walk is
771
771
is
772
772
Args : constant Irep := Make_Argument_List;
773
773
774
+ -- A formal access parameter cannot be mode out (an Ada rule) and
775
+ -- an actual corresponding to the formal access parameter must be an
776
+ -- access type (again an Ada rule and checked by the front end).
777
+ -- Therefore, the actual parameter will be a goto pointer type and
778
+ -- does not need wrapping into a pointer. Since the mode of a formal
779
+ -- access parameter cannot be out or in out the Wrap_Argument function
780
+ -- will not wrap the corresponding actual parameter.
774
781
function Wrap_Argument (Base : Irep; Is_Out : Boolean) return Irep is
775
782
(if Is_Out
776
783
then Make_Address_Of (Base)
@@ -4977,38 +4984,60 @@ package body Tree_Walk is
4977
4984
Param_Iter : Node_Id := First (Parameter_Specifications (N));
4978
4985
begin
4979
4986
while Present (Param_Iter) loop
4980
- if not (Nkind (Parameter_Type (Param_Iter)) in N_Has_Etype) then
4981
- return Report_Unhandled_Node_Type
4982
- (N,
4983
- " Do_Subprogram_Specification" ,
4984
- " Param iter type not have etype" );
4985
- end if ;
4986
4987
declare
4987
- Is_Out : constant Boolean := Out_Present (Param_Iter);
4988
+ Param_Sort : constant Node_Id := Parameter_Type (Param_Iter);
4989
+ begin
4990
+ if not (Nkind (Param_Sort)
4991
+ in N_Has_Etype | N_Access_Definition)
4992
+ then
4993
+ return Report_Unhandled_Node_Type
4994
+ (N,
4995
+ " Do_Subprogram_Specification" ,
4996
+ " Param iter is not an access parameter or has no etype" );
4997
+ end if ;
4998
+ declare
4999
+ Is_Out : constant Boolean := Out_Present (Param_Iter);
4988
5000
4989
- Param_Name : constant String :=
4990
- Unique_Name (Defining_Identifier (Param_Iter));
5001
+ -- A subprogram can have a formal access parameter of the form
5002
+ -- procedure P (Ptr_To_ObjectOf_Type_T : access T);
5003
+ Is_Access_Param : constant Boolean :=
5004
+ Nkind (Param_Sort) = N_Access_Definition;
4991
5005
4992
- Param_Type_Base : constant Irep :=
4993
- Do_Type_Reference (Etype (Parameter_Type (Param_Iter)));
4994
- Param_Type : constant Irep :=
4995
- (if Is_Out
4996
- then Make_Pointer_Type (Param_Type_Base)
4997
- else Param_Type_Base);
4998
- Param_Irep : constant Irep := Make_Code_Parameter
4999
- (Source_Location => Get_Source_Location (Param_Iter),
5000
- I_Type => Param_Type,
5001
- Identifier => Param_Name,
5002
- Base_Name => Param_Name,
5003
- This => False,
5004
- Default_Value => Ireps.Empty);
5005
- begin
5006
- Append_Parameter (Param_List, Param_Irep);
5007
- New_Parameter_Symbol_Entry (Name_Id => Intern (Param_Name),
5008
- BaseName => Param_Name,
5009
- Symbol_Type => Param_Type,
5010
- A_Symbol_Table => Global_Symbol_Table);
5011
- Next (Param_Iter);
5006
+ Param_Name : constant String :=
5007
+ Unique_Name (Defining_Identifier (Param_Iter));
5008
+
5009
+ Param_Ada_Type : constant Node_Id :=
5010
+ (if Is_Access_Param then
5011
+ Etype (Subtype_Mark (Param_Sort))
5012
+ else
5013
+ Etype (Parameter_Type (Param_Iter)));
5014
+
5015
+ Param_Type_Base : constant Irep :=
5016
+ Do_Type_Reference (Param_Ada_Type);
5017
+
5018
+ -- If the formal parameter is mode out or in out,
5019
+ -- or is an access parameter, it is made into a pointer
5020
+ Param_Type : constant Irep :=
5021
+ (if Is_Out or Is_Access_Param then
5022
+ Make_Pointer_Type (Param_Type_Base)
5023
+ else Param_Type_Base);
5024
+ Param_Irep : constant Irep := Make_Code_Parameter
5025
+ (Source_Location => Get_Source_Location (Param_Iter),
5026
+ I_Type => Param_Type,
5027
+ Identifier => Param_Name,
5028
+ Base_Name => Param_Name,
5029
+ This => False,
5030
+ Default_Value => Ireps.Empty);
5031
+ begin
5032
+ Append_Parameter (Param_List, Param_Irep);
5033
+ New_Parameter_Symbol_Entry
5034
+ (Name_Id => Intern (Param_Name),
5035
+ BaseName => Param_Name,
5036
+ Symbol_Type => Param_Type,
5037
+ A_Symbol_Table => Global_Symbol_Table);
5038
+
5039
+ Next (Param_Iter);
5040
+ end ;
5012
5041
end ;
5013
5042
end loop ;
5014
5043
return Make_Code_Type
0 commit comments