-- Defined in constants and variables. Set if there is an address clause
-- that causes the entity to overlay a constant object.
+-- Overridden_Inherited_Operation
+-- Defined in subprograms and enumeration literals. When set on a
+-- subprogram S, indicates an inherited subprogram that S overrides.
+-- In the case of a privately declared explicit subprogram E that
+-- overrides a private inherited subprogram, and the inherited
+-- subprogram itself overrides another inherited subprogram declared
+-- for a private extension, the field on E will reference the subprogram
+-- inherited by the private extension. This field is used for properly
+-- handling visibility for such privately declared subprograms. This
+-- field is always Empty for enumeration literal entities.
+
-- Overridden_Operation
-- Defined in subprograms. For overriding operations, points to the
--- user-defined parent subprogram that is being overridden.
+-- user-defined parent subprogram from which the inherited subprogram
+-- that is being overridden is derived.
-- Package_Instantiation
-- Defined in packages and generic packages. When defined, this field
-- Enumeration_Pos
-- Enumeration_Rep
-- Alias
+ -- Overridden_Inherited_Operation
-- Enumeration_Rep_Expr
-- Interface_Name $$$
-- Renamed_Object $$$
-- Subps_Index (non-generic case only)
-- Interface_Alias
-- LSP_Subprogram (non-generic case only)
+ -- Overridden_Inherited_Operation
-- Overridden_Operation
-- Wrapped_Entity (non-generic case only)
-- Extra_Formals
-- Extra_Accessibility_Of_Result
-- Last_Entity
-- Subps_Index
+ -- Overridden_Inherited_Operation
-- Overridden_Operation
-- Linker_Section_Pragma
-- Contract
-- Subps_Index (non-generic case only)
-- Interface_Alias
-- LSP_Subprogram (non-generic case only)
+ -- Overridden_Inherited_Operation
-- Overridden_Operation (never for init proc)
-- Wrapped_Entity (non-generic case only)
-- Extra_Formals
Original_Protected_Subprogram,
Original_Record_Component,
Overlays_Constant,
+ Overridden_Inherited_Operation,
Overridden_Operation,
Package_Instantiation,
Packed_Array_Impl_Type,
Sm (Enumeration_Rep_Expr, Node_Id),
Sm (Esize, Uint),
Sm (Alignment, Unat),
+ Sm (Overridden_Inherited_Operation, Node_Id),
Sm (Interface_Name, Node_Id)));
Ab (Subprogram_Kind, Overloadable_Kind,
Sm (Is_Machine_Code_Subprogram, Flag),
Sm (Last_Entity, Node_Id),
Sm (Linker_Section_Pragma, Node_Id),
+ Sm (Overridden_Inherited_Operation, Node_Id),
Sm (Overridden_Operation, Node_Id),
Sm (Protected_Body_Subprogram, Node_Id),
Sm (No_Raise, Flag),
-- may be candidates, so that Try_Primitive_Operations can examine
-- them if no real primitive is found.
- function Is_Private_Overriding (Op : Entity_Id) return Boolean;
+ function Is_Callable_Private_Overriding
+ (Op : Entity_Id) return Boolean;
-- An operation that overrides an inherited operation in the private
-- part of its package may be hidden, but if the inherited operation
- -- is visible a direct call to it will dispatch to the private one,
- -- which is therefore a valid candidate.
+ -- that it overrides is visible, then a direct call to it will
+ -- dispatch to the private one, which is therefore a valid candidate.
+ -- Returns True if the operation can be called from outside the
+ -- enclosing package.
function Names_Match
(Obj_Type : Entity_Id;
return Op_List;
end Extended_Primitive_Ops;
- ---------------------------
- -- Is_Private_Overriding --
- ---------------------------
+ ------------------------------------
+ -- Is_Callable_Private_Overriding --
+ ------------------------------------
- function Is_Private_Overriding (Op : Entity_Id) return Boolean is
+ function Is_Callable_Private_Overriding
+ (Op : Entity_Id) return Boolean
+ is
Visible_Op : Entity_Id;
begin
-- have found what we're looking for.
if not Is_Hidden (Visible_Op)
- or else not Is_Hidden (Overridden_Operation (Op))
+ or else
+ (Present (Overridden_Inherited_Operation (Op))
+ and then not Is_Hidden
+ (Overridden_Inherited_Operation (Op)))
then
return True;
end if;
end loop;
return False;
- end Is_Private_Overriding;
+ end Is_Callable_Private_Overriding;
-----------------
-- Names_Match --
-- Do not consider hidden primitives unless the type is in an
-- open scope or we are within an instance, where visibility
- -- is known to be correct, or else if this is an overriding
- -- operation in the private part for an inherited operation.
+ -- is known to be correct, or else if this is an operation
+ -- declared in the private part that overrides a visible
+ -- inherited operation.
or else (Is_Hidden (Prim_Op)
and then not Is_Immediately_Visible (Obj_Type)
and then not In_Instance
- and then not Is_Private_Overriding (Prim_Op))
+ and then
+ not Is_Callable_Private_Overriding (Prim_Op))
then
goto Continue;
end if;
and then Present (Find_Dispatching_Type (Alias (S)))
and then Is_Interface (Find_Dispatching_Type (Alias (S)))
then
- -- For private types, when the full-view is processed we propagate to
- -- the full view the non-overridden entities whose attribute "alias"
- -- references an interface primitive. These entities were added by
- -- Derive_Subprograms to ensure that interface primitives are
- -- covered.
-
- -- Inside_Freeze_Actions is non zero when S corresponds with an
- -- internal entity that links an interface primitive with its
- -- covering primitive through attribute Interface_Alias (see
- -- Add_Internal_Interface_Entities).
-
- if Inside_Freezing_Actions = 0
- and then Is_Package_Or_Generic_Package (Current_Scope)
- and then In_Private_Part (Current_Scope)
- and then Parent_Kind (E) = N_Private_Extension_Declaration
- and then Nkind (Parent (S)) = N_Full_Type_Declaration
- and then Full_View (Defining_Identifier (Parent (E)))
- = Defining_Identifier (Parent (S))
- and then Alias (E) = Alias (S)
- then
- Check_Operation_From_Private_View (S, E);
- Set_Is_Dispatching_Operation (S);
+ declare
+ Private_Operation_Exported_By_Visible_Part : constant Boolean :=
+ Is_Package_Or_Generic_Package (Current_Scope)
+ and then In_Private_Part (Current_Scope)
+ and then Parent_Kind (E) = N_Private_Extension_Declaration
+ and then Nkind (Parent (S)) = N_Full_Type_Declaration
+ and then Full_View (Defining_Identifier (Parent (E)))
+ = Defining_Identifier (Parent (S));
+
+ begin
+ -- For private types, when the full view is processed we propagate
+ -- to the full view the nonoverridden entities whose attribute
+ -- "alias" references an interface primitive. These entities were
+ -- added by Derive_Subprograms to ensure that interface primitives
+ -- are covered.
+
+ -- Inside_Freeze_Actions is nonzero when S corresponds to an
+ -- internal entity that links an interface primitive with its
+ -- covering primitive through attribute Interface_Alias (see
+ -- Add_Internal_Interface_Entities).
+
+ if Inside_Freezing_Actions = 0
+ and then Private_Operation_Exported_By_Visible_Part
+ and then Alias (E) = Alias (S)
+ then
+ Check_Operation_From_Private_View (S, E);
+ Set_Is_Dispatching_Operation (S);
- -- Common case
+ -- Common case
- else
- Enter_Overloaded_Entity (S);
- Check_Dispatching_Operation (S, Empty);
- Check_For_Primitive_Subprogram (Is_Primitive_Subp);
- end if;
+ else
+ Enter_Overloaded_Entity (S);
+ Check_Dispatching_Operation (S, Empty);
+ Check_For_Primitive_Subprogram (Is_Primitive_Subp);
+ end if;
+
+ if Private_Operation_Exported_By_Visible_Part
+ and then Type_Conformant (E, S)
+ then
+ -- Record the actual inherited subprogram that's being
+ -- overridden.
+
+ Set_Overridden_Inherited_Operation (S, E);
+ end if;
+ end;
return;
end if;
and then not Is_Dispatch_Table_Wrapper (S)))
then
Set_Overridden_Operation (S, Alias (E));
+
+ -- Record the actual inherited subprogram that's being
+ -- overridden. In the case where a subprogram declared
+ -- in a private part overrides an inherited subprogram
+ -- that itself is also declared in the private part,
+ -- and that subprogram in turns overrides a subprogram
+ -- declared in a package visible part (inherited via
+ -- a private extension), we record the visible subprogram
+ -- as the overridden one, so that we can determine
+ -- visibility properly for prefixed calls to the
+ -- subprogram made from outside the package. (See
+ -- Try_Primitive_Operation in Sem_Ch4.)
+
+ if Present (Overridden_Inherited_Operation (E)) then
+ Set_Overridden_Inherited_Operation
+ (S, Overridden_Inherited_Operation (E));
+ else
+ Set_Overridden_Inherited_Operation (S, E);
+ end if;
+
Inherit_Subprogram_Contract (S, Alias (E));
Set_Is_Ada_2022_Only (S, Is_Ada_2022_Only (Alias (E)));