aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_dist.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_dist.adb')
-rw-r--r--gcc/ada/sem_dist.adb294
1 files changed, 210 insertions, 84 deletions
diff --git a/gcc/ada/sem_dist.adb b/gcc/ada/sem_dist.adb
index aee306d..8314e6c 100644
--- a/gcc/ada/sem_dist.adb
+++ b/gcc/ada/sem_dist.adb
@@ -105,6 +105,55 @@ package body Sem_Dist is
end if;
end Add_Stub_Constructs;
+ ---------------------------------------
+ -- Build_RAS_Primitive_Specification --
+ ---------------------------------------
+
+ function Build_RAS_Primitive_Specification
+ (Subp_Spec : Node_Id;
+ Remote_Object_Type : Node_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Subp_Spec);
+
+ Primitive_Spec : constant Node_Id :=
+ Copy_Specification (Loc,
+ Spec => Subp_Spec,
+ New_Name => Name_Call);
+
+ Subtype_Mark_For_Self : Node_Id;
+
+ begin
+ if No (Parameter_Specifications (Primitive_Spec)) then
+ Set_Parameter_Specifications (Primitive_Spec, New_List);
+ end if;
+
+ if Nkind (Remote_Object_Type) in N_Entity then
+ Subtype_Mark_For_Self :=
+ New_Occurrence_Of (Remote_Object_Type, Loc);
+ else
+ Subtype_Mark_For_Self := Remote_Object_Type;
+ end if;
+
+ Prepend_To (
+ Parameter_Specifications (Primitive_Spec),
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, Name_uS),
+ Parameter_Type =>
+ Make_Access_Definition (Loc,
+ Subtype_Mark =>
+ Subtype_Mark_For_Self)));
+
+ -- Trick later semantic analysis into considering this
+ -- operation as a primitive (dispatching) operation of
+ -- tagged type Obj_Type.
+
+ Set_Comes_From_Source (
+ Defining_Unit_Name (Primitive_Spec), True);
+
+ return Primitive_Spec;
+ end Build_RAS_Primitive_Specification;
+
-------------------------
-- Full_Qualified_Name --
-------------------------
@@ -295,7 +344,6 @@ package body Sem_Dist is
Async_E : Entity_Id;
All_Calls_Remote_E : Entity_Id;
Attribute_Subp : Entity_Id;
- Local_Addr : Node_Id;
begin
-- Check if we have to expand the access attribute
@@ -329,17 +377,11 @@ package body Sem_Dist is
All_Calls_Remote_E :=
Boolean_Literals (Has_All_Calls_Remote (RS_Pkg_E));
- Local_Addr :=
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (Remote_Subp, Loc),
- Attribute_Name => Name_Address);
-
Tick_Access_Conv_Call :=
Make_Function_Call (Loc,
Name => New_Occurrence_Of (Attribute_Subp, Loc),
Parameter_Associations =>
New_List (
- Local_Addr,
Make_String_Literal (Loc, Full_Qualified_Name (RS_Pkg_E)),
Build_Subprogram_Id (Loc, Remote_Subp),
New_Occurrence_Of (Async_E, Loc),
@@ -354,78 +396,165 @@ package body Sem_Dist is
------------------------------------
procedure Process_Remote_AST_Declaration (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- User_Type : constant Node_Id := Defining_Identifier (N);
- Fat_Type : constant Entity_Id :=
+ Loc : constant Source_Ptr := Sloc (N);
+ User_Type : constant Node_Id := Defining_Identifier (N);
+ Scop : constant Entity_Id := Scope (User_Type);
+ Is_RCI : constant Boolean :=
+ Is_Remote_Call_Interface (Scop);
+ Is_RT : constant Boolean :=
+ Is_Remote_Types (Scop);
+ Type_Def : constant Node_Id := Type_Definition (N);
+
+ Parameter : Node_Id;
+ Is_Degenerate : Boolean;
+ -- True iff this RAS has an access formal parameter (see
+ -- Exp_Dist.Add_RAS_Dereference_TSS for details).
+
+ Subpkg : constant Entity_Id :=
+ Make_Defining_Identifier
+ (Loc, New_Internal_Name ('S'));
+ Subpkg_Decl : Node_Id;
+ Vis_Decls : constant List_Id := New_List;
+ Priv_Decls : constant List_Id := New_List;
+
+ Obj_Type : constant Entity_Id :=
+ Make_Defining_Identifier
+ (Loc, New_External_Name (
+ Chars (User_Type), 'R'));
+
+
+ Full_Obj_Type : constant Entity_Id :=
+ Make_Defining_Identifier
+ (Loc, Chars (Obj_Type));
+
+ RACW_Type : constant Entity_Id :=
+ Make_Defining_Identifier
+ (Loc, New_External_Name (
+ Chars (User_Type), 'P'));
+
+ Fat_Type : constant Entity_Id :=
Make_Defining_Identifier
(Loc, Chars (User_Type));
- New_Type_Decl : Node_Id;
+ Fat_Type_Decl : Node_Id;
begin
- -- We add a record type declaration for the equivalent fat pointer type
- New_Type_Decl :=
+ -- The tagged private type, primitive operation and RACW
+ -- type associated with a RAS need to all be declared in
+ -- a subpackage of the one that contains the RAS declaration,
+ -- because the primitive of the object type, and the associated
+ -- primitive of the stub type, need to be dispatching operations
+ -- of these types, and the profile of the RAS might contain
+ -- tagged types declared in the same scope.
+
+ Append_To (Vis_Decls,
+ Make_Private_Type_Declaration (Loc,
+ Defining_Identifier => Obj_Type,
+ Abstract_Present => True,
+ Tagged_Present => True,
+ Limited_Present => True));
+
+ Append_To (Priv_Decls,
Make_Full_Type_Declaration (Loc,
- Defining_Identifier => Fat_Type,
- Type_Definition =>
+ Defining_Identifier =>
+ Full_Obj_Type,
+ Type_Definition =>
Make_Record_Definition (Loc,
- Component_List =>
- Make_Component_List (Loc,
- Component_Items => New_List (
-
- Make_Component_Declaration (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Name_Ras),
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication =>
- New_Occurrence_Of (RTE (RE_Unsigned_64), Loc))),
-
- Make_Component_Declaration (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Name_Origin),
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication =>
- New_Reference_To (Standard_Integer, Loc))),
-
- Make_Component_Declaration (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Name_Receiver),
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication =>
- New_Reference_To (RTE (RE_Unsigned_64), Loc))),
-
- Make_Component_Declaration (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Name_Subp_Id),
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication =>
- New_Reference_To (Standard_Natural, Loc))),
-
- Make_Component_Declaration (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Name_Async),
- Component_Definition =>
- Make_Component_Definition (Loc,
- Aliased_Present => False,
- Subtype_Indication =>
- New_Reference_To (Standard_Boolean, Loc)))))));
-
- Insert_After (N, New_Type_Decl);
+ Abstract_Present => True,
+ Tagged_Present => True,
+ Limited_Present => True,
+ Null_Present => True,
+ Component_List => Empty)));
+
+ Is_Degenerate := False;
+ Parameter := First (Parameter_Specifications (Type_Def));
+ Parameters : while Present (Parameter) loop
+ if Nkind (Parameter_Type (Parameter)) = N_Access_Definition then
+ Error_Msg_N ("formal parameter& has anonymous access type?",
+ Defining_Identifier (Parameter));
+ Is_Degenerate := True;
+ exit Parameters;
+ end if;
+ Next (Parameter);
+ end loop Parameters;
+
+ if Is_Degenerate then
+ Error_Msg_NE (
+ "remote access-to-subprogram type& can only be null?",
+ Defining_Identifier (Parameter), User_Type);
+ -- The only legal value for a RAS with a formal parameter of an
+ -- anonymous access type is null, because it cannot be
+ -- subtype-Conformant with any legal remote subprogram declaration.
+ -- In this case, we cannot generate a corresponding primitive
+ -- operation.
+
+ else
+ Append_To (Vis_Decls,
+ Make_Abstract_Subprogram_Declaration (Loc,
+ Specification => Build_RAS_Primitive_Specification (
+ Subp_Spec => Type_Def,
+ Remote_Object_Type => Obj_Type)));
+ end if;
+
+ Append_To (Vis_Decls,
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => RACW_Type,
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present => True,
+ Subtype_Indication =>
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Occurrence_Of (Obj_Type, Loc),
+ Attribute_Name =>
+ Name_Class))));
+ Set_Is_Remote_Call_Interface (RACW_Type, Is_RCI);
+ Set_Is_Remote_Types (RACW_Type, Is_RT);
+ -- ??? Object RPC receiver generation should be bypassed for this
+ -- RACW type, since actually calls will be received by the package
+ -- RPC receiver for the designated RCI subprogram.
+
+ Subpkg_Decl :=
+ Make_Package_Declaration (Loc,
+ Make_Package_Specification (Loc,
+ Defining_Unit_Name =>
+ Subpkg,
+ Visible_Declarations =>
+ Vis_Decls,
+ Private_Declarations =>
+ Priv_Decls,
+ End_Label =>
+ New_Occurrence_Of (Subpkg, Loc)));
+ Set_Is_Remote_Call_Interface (Subpkg, Is_RCI);
+ Set_Is_Remote_Types (Subpkg, Is_RT);
+ Insert_After_And_Analyze (N, Subpkg_Decl);
+
+ -- Many parts of the analyzer and expander expect
+ -- that the fat pointer type used to implement remote
+ -- access to subprogram types be a record.
+ -- Note: The structure of this type must be kept consistent
+ -- with the code generated by Remote_AST_Null_Value for the
+ -- corresponding 'null' expression.
+
+ Fat_Type_Decl := Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Fat_Type,
+ Type_Definition =>
+ Make_Record_Definition (Loc,
+ Component_List =>
+ Make_Component_List (Loc,
+ Component_Items => New_List (
+ Make_Component_Declaration (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, Name_Ras),
+ Component_Definition =>
+ Make_Component_Definition (Loc,
+ Aliased_Present =>
+ False,
+ Subtype_Indication =>
+ New_Occurrence_Of (RACW_Type, Loc)))))));
Set_Equivalent_Type (User_Type, Fat_Type);
Set_Corresponding_Remote_Type (Fat_Type, User_Type);
+ Insert_After_And_Analyze (Subpkg_Decl, Fat_Type_Decl);
-- The reason we suppress the initialization procedure is that we know
-- that no initialization is required (even if Initialize_Scalars mode
@@ -506,8 +635,7 @@ package body Sem_Dist is
-- Remote_AST_E_Dereference --
------------------------------
- function Remote_AST_E_Dereference (P : Node_Id) return Boolean
- is
+ function Remote_AST_E_Dereference (P : Node_Id) return Boolean is
ET : constant Entity_Id := Etype (P);
begin
@@ -534,12 +662,11 @@ package body Sem_Dist is
-- Remote_AST_I_Dereference --
------------------------------
- function Remote_AST_I_Dereference (P : Node_Id) return Boolean
- is
+ function Remote_AST_I_Dereference (P : Node_Id) return Boolean is
ET : constant Entity_Id := Etype (P);
Deref : Node_Id;
- begin
+ begin
if Comes_From_Source (P)
and then (Is_Remote_Call_Interface (ET)
or else Is_Remote_Types (ET))
@@ -563,9 +690,8 @@ package body Sem_Dist is
---------------------------
function Remote_AST_Null_Value
- (N : Node_Id;
- Typ : Entity_Id)
- return Boolean
+ (N : Node_Id;
+ Typ : Entity_Id) return Boolean
is
Loc : constant Source_Ptr := Sloc (N);
Target_Type : Entity_Id;
@@ -603,12 +729,12 @@ package body Sem_Dist is
Rewrite (N,
Make_Aggregate (Loc,
- Expressions => New_List (
- Make_Integer_Literal (Loc, 0), -- Ras
- Make_Integer_Literal (Loc, 0), -- Origin
- Make_Integer_Literal (Loc, 0), -- Receiver
- Make_Integer_Literal (Loc, 0), -- Subp_Id
- New_Occurrence_Of (Standard_False, Loc)))); -- Asyn
+ Component_Associations => New_List (
+ Make_Component_Association (Loc,
+ Choices => New_List (
+ Make_Identifier (Loc, Name_Ras)),
+ Expression =>
+ Make_Null (Loc)))));
Analyze_And_Resolve (N, Target_Type);
return True;
end Remote_AST_Null_Value;