mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-02 06:40:25 +08:00
einfo.ads (Abstract_Interface_Alias): Renamed as Interface_Alias.
2008-05-26 Javier Miranda <miranda@adacore.com> * einfo.ads (Abstract_Interface_Alias): Renamed as Interface_Alias. (Set_Abstract_Interface_Alias): Renamed as Set_Interface_Alias. (Is_Internal): Adding documentation on internal entities that have attribute Interface_Alias (old attribute Abstract_Interface_Alias) * einfo.adb (Abstract_Interface_Alias): Renamed as Interface_Alias. (Set_Abstract_Interface_Alias): Renamed as Set_Interface_Alias. Added assertion to force entities with this attribute to have attribute Is_Internal set to True. (Next_Tag_Component): Simplify assertion using attribute Is_Tag. * sem_ch3.adb (Derive_Interface_Subprograms): This subprogram has been renamed as Derive_Progenitor_Subprograms. In addition, its code is a new implementation. (Add_Interface_Tag_Components): Remove special management of synchronized interfaces. (Analyze_Interface_Declaration): Minor reformating (Build_Derived_Record_Type): Minor reformating (Check_Abstract_Overriding): Avoid reporting error in case of abstract predefined primitive inherited from interface type because the body of internally generated predefined primitives of tagged types are generated later by Freeze_Type (Derive_Subprogram): Avoid generating an internal name if the parent subprogram overrides an interface primitive. (Derive_Subprograms): New implementation that keeps separate the management of tagged types not implementing interfaces, from tagged types that implement interfaces. (Is_Progenitor): New implementation. (Process_Full_View): Add documentation (Record_Type_Declaration): Replace call to Derive_Interface_Subprograms by call to Derive_Progenitor_Subprograms. * sem_ch6.ads (Is_Interface_Conformant): New subprogram. (Check_Subtype_Conformant, Subtype_Conformant): Adding new argument Skip_Controlling_Formals. * sem_ch6.adb (Is_Interface_Conformant): New subprogram. (Check_Conventions): New implementation. Remove local subprogram Skip_Check. Remove formal Search_From of routine Check_Convention. (Check_Subtype_Conformant, Subtype_Conformant): Adding new argument Skip_Controlling_Formals. (New_Overloaded_Entity): Enable addition of predefined dispatching operations. * sem_disp.ads (Find_Primitive_Covering_Interface): New subprogram. * sem_disp.adb (Check_Dispatching_Operation): Disable registering the task body procedure as a primitive of the corresponding tagged type. (Check_Operation_From_Private_Type): Avoid adding twice an entity to the list of primitives. (Find_Primitive_Covering_Interface): New subprogram. (Override_Dispatching_Operation): Add documentation. * sem_type.adb (Covers): Minor reformatings * sem_util.ads (Collect_Abstract_Interfaces): Renamed as Collect_Interfaces. Rename formal. (Has_Abstract_Interfaces): Renamed as Has_Interfaces. (Implements_Interface): New subprogram. (Is_Parent): Removed. (Primitive_Names_Match): New subprogram. (Remove_Homonym): Moved here from Derive_Interface_Subprograms. (Ultimate_Alias): New subprogram. * sem_util.adb (Collect_Abstract_Interfaces): Renamed as Collect_Interfaces. Remove special management for synchronized types. Rename formal. Remove internal subprograms Interface_Present_In_Parent and Add_Interface. (Has_Abstract_Interfaces): Renamed as Has_Interfaces. Replace assertion on non-record types by code to return false in such case. (Implements_Interface): New subprogram. (Is_Parent): Removed. No special management is now required for synchronized types covering interfaces. (Primitive_Names_Match): New subprogram. (Remove_Homonym): Moved here from Derive_Interface_Subprograms. (Ultimate_Alias): New subprogram. * exp_ch3.adb (Add_Internal_Interface_Entities): New subprogram. Add internal entities associated with secondary dispatch tables to the list of tagged type primitives that are not interfaces. (Freeze_Record_Type): Add new call to Add_Internal_Interface_Entities (Make_Predefined_Primitive_Specs): Code reorganization to improve the management of predefined equality operator. In addition, if the type has an equality function corresponding with a primitive defined in an interface type, the inherited equality is abstract as well, and no body can be created for it. * exp_disp.ads (Is_Predefined_Dispatching_Operation): Moved from exp_util to exp_disp. (Is_Predefined_Interface_Primitive): New subprogram. Returns True if an entity corresponds with one of the predefined primitives required to implement interfaces. Update copyright notice. * exp_disp.adb (Set_All_DT_Position): Add assertion. Exclude from the final check on abstract subprograms all the primitives associated with interface primitives because they must be visible in the public and private part. (Write_DT): Use Find_Dispatching_Type to locate the name of the interface type. This allows the use of this routine, for debugging purposes, when the tagged type is not fully decorated. (Is_Predefined_Dispatching_Operation): Moved from exp_util to exp_disp. Factorize code calling new subprogram Is_Predefined_Interface_Primitive. (Is_Predefined_Interface_Primitive): New subprogram. Returns True if an entity corresponds with one of the predefined primitives required to implement interfaces. * exp_util.adb (Find_Interface_ADT): New implementation (Find_Interface): Removed. * sprint.adb (Sprint_Node_Actual): Generate missing output for the list of interfaces associated with nodes N_Formal_Derived_Type_Definition and N_Private_Extension_Declaration. From-SVN: r135923
This commit is contained in:
parent
e5f005e18c
commit
ce2b6ba521
@ -208,8 +208,8 @@ package body Einfo is
|
||||
|
||||
-- Spec_PPC_List Node24
|
||||
|
||||
-- Abstract_Interface_Alias Node25
|
||||
-- Abstract_Interfaces Elist25
|
||||
-- Interface_Alias Node25
|
||||
-- Interfaces Elist25
|
||||
-- Debug_Renaming_Link Node25
|
||||
-- DT_Offset_To_Top_Func Node25
|
||||
-- Task_Body_Procedure Node25
|
||||
@ -544,18 +544,6 @@ package body Einfo is
|
||||
-- Attribute Access Functions --
|
||||
--------------------------------
|
||||
|
||||
function Abstract_Interfaces (Id : E) return L is
|
||||
begin
|
||||
pragma Assert (Is_Record_Type (Id));
|
||||
return Elist25 (Id);
|
||||
end Abstract_Interfaces;
|
||||
|
||||
function Abstract_Interface_Alias (Id : E) return E is
|
||||
begin
|
||||
pragma Assert (Is_Subprogram (Id));
|
||||
return Node25 (Id);
|
||||
end Abstract_Interface_Alias;
|
||||
|
||||
function Accept_Address (Id : E) return L is
|
||||
begin
|
||||
return Elist21 (Id);
|
||||
@ -1538,6 +1526,18 @@ package body Einfo is
|
||||
return Flag232 (Id);
|
||||
end Implemented_By_Entry;
|
||||
|
||||
function Interfaces (Id : E) return L is
|
||||
begin
|
||||
pragma Assert (Is_Record_Type (Id));
|
||||
return Elist25 (Id);
|
||||
end Interfaces;
|
||||
|
||||
function Interface_Alias (Id : E) return E is
|
||||
begin
|
||||
pragma Assert (Is_Subprogram (Id));
|
||||
return Node25 (Id);
|
||||
end Interface_Alias;
|
||||
|
||||
function In_Package_Body (Id : E) return B is
|
||||
begin
|
||||
return Flag48 (Id);
|
||||
@ -2941,21 +2941,6 @@ package body Einfo is
|
||||
-- Attribute Set Procedures --
|
||||
------------------------------
|
||||
|
||||
procedure Set_Abstract_Interfaces (Id : E; V : L) is
|
||||
begin
|
||||
pragma Assert (Is_Record_Type (Id));
|
||||
Set_Elist25 (Id, V);
|
||||
end Set_Abstract_Interfaces;
|
||||
|
||||
procedure Set_Abstract_Interface_Alias (Id : E; V : E) is
|
||||
begin
|
||||
pragma Assert
|
||||
(Is_Hidden (Id)
|
||||
and then
|
||||
(Ekind (Id) = E_Procedure or else Ekind (Id) = E_Function));
|
||||
Set_Node25 (Id, V);
|
||||
end Set_Abstract_Interface_Alias;
|
||||
|
||||
procedure Set_Accept_Address (Id : E; V : L) is
|
||||
begin
|
||||
Set_Elist21 (Id, V);
|
||||
@ -3961,6 +3946,22 @@ package body Einfo is
|
||||
Set_Flag232 (Id, V);
|
||||
end Set_Implemented_By_Entry;
|
||||
|
||||
procedure Set_Interfaces (Id : E; V : L) is
|
||||
begin
|
||||
pragma Assert (Is_Record_Type (Id));
|
||||
Set_Elist25 (Id, V);
|
||||
end Set_Interfaces;
|
||||
|
||||
procedure Set_Interface_Alias (Id : E; V : E) is
|
||||
begin
|
||||
pragma Assert
|
||||
(Is_Internal (Id)
|
||||
and then Is_Hidden (Id)
|
||||
and then (Ekind (Id) = E_Procedure
|
||||
or else Ekind (Id) = E_Function));
|
||||
Set_Node25 (Id, V);
|
||||
end Set_Interface_Alias;
|
||||
|
||||
procedure Set_In_Package_Body (Id : E; V : B := True) is
|
||||
begin
|
||||
Set_Flag48 (Id, V);
|
||||
@ -7296,11 +7297,9 @@ package body Einfo is
|
||||
|
||||
function Next_Tag_Component (Id : E) return E is
|
||||
Comp : Entity_Id;
|
||||
Typ : constant Entity_Id := Scope (Id);
|
||||
|
||||
begin
|
||||
pragma Assert (Ekind (Id) = E_Component
|
||||
and then Is_Tagged_Type (Typ));
|
||||
pragma Assert (Is_Tag (Id));
|
||||
|
||||
Comp := Next_Entity (Id);
|
||||
while Present (Comp) loop
|
||||
@ -8600,13 +8599,13 @@ package body Einfo is
|
||||
|
||||
when E_Procedure |
|
||||
E_Function =>
|
||||
Write_Str ("Abstract_Interface_Alias");
|
||||
Write_Str ("Interface_Alias");
|
||||
|
||||
when E_Record_Type |
|
||||
E_Record_Subtype |
|
||||
E_Record_Type_With_Private |
|
||||
E_Record_Subtype_With_Private =>
|
||||
Write_Str ("Abstract_Interfaces");
|
||||
Write_Str ("Interfaces");
|
||||
|
||||
when Task_Kind =>
|
||||
Write_Str ("Task_Body_Procedure");
|
||||
|
@ -293,18 +293,6 @@ package Einfo is
|
||||
-- type, and if assertions are enabled, an attempt to set the attribute on a
|
||||
-- subtype will raise an assert error.
|
||||
|
||||
-- Abstract_Interfaces (Elist25)
|
||||
-- Present in record types and subtypes. List of abstract interfaces
|
||||
-- implemented by a tagged type that are not already implemented by the
|
||||
-- ancestors (Ada 2005: AI-251).
|
||||
|
||||
-- Abstract_Interface_Alias (Node25)
|
||||
-- Present in subprograms that cover a primitive operation of an abstract
|
||||
-- interface type. Can be set only if the Is_Hidden flag is also set,
|
||||
-- since such entities are always hidden. Points to its associated
|
||||
-- interface subprogram. It is used to register the subprogram in
|
||||
-- secondary dispatch table of the interface (Ada 2005: AI-251).
|
||||
|
||||
-- Accept_Address (Elist21)
|
||||
-- Present in entries. If an accept has a statement sequence, then an
|
||||
-- address variable is created, which is used to hold the address of the
|
||||
@ -364,12 +352,12 @@ package Einfo is
|
||||
-- Alias (Node18)
|
||||
-- Present in overloaded entities (literals, subprograms, entries) and
|
||||
-- subprograms that cover a primitive operation of an abstract interface
|
||||
-- (that is, subprograms with the Abstract_Interface_Alias attribute).
|
||||
-- In case of overloaded entities it points to the parent subprogram of
|
||||
-- a derived subprogram. In case of abstract interface subprograms it
|
||||
-- points to the subprogram that covers the abstract interface primitive.
|
||||
-- Also used for a subprogram renaming, where it points to the renamed
|
||||
-- subprogram. Always empty for entries.
|
||||
-- (that is, subprograms with the Interface_Alias attribute). In case of
|
||||
-- overloaded entities it points to the parent subprogram of a derived
|
||||
-- subprogram. In case of abstract interface subprograms it points to the
|
||||
-- subprogram that covers the abstract interface primitive. Also used for
|
||||
-- a subprogram renaming, where it points to the renamed subprogram.
|
||||
-- Always empty for entries.
|
||||
|
||||
-- Alignment (Uint14)
|
||||
-- Present in entities for types and also in constants, variables
|
||||
@ -1837,6 +1825,18 @@ package Einfo is
|
||||
-- Applies to functions and procedures. Set if pragma Implemented_By_
|
||||
-- Entry is applied on the subprogram entity.
|
||||
|
||||
-- Interfaces (Elist25)
|
||||
-- Present in record types and subtypes. List of abstract interfaces
|
||||
-- implemented by a tagged type that are not already implemented by the
|
||||
-- ancestors (Ada 2005: AI-251).
|
||||
|
||||
-- Interface_Alias (Node25)
|
||||
-- Present in subprograms that cover a primitive operation of an abstract
|
||||
-- interface type. Can be set only if the Is_Hidden flag is also set,
|
||||
-- since such entities are always hidden. Points to its associated
|
||||
-- interface subprogram. It is used to register the subprogram in
|
||||
-- secondary dispatch table of the interface (Ada 2005: AI-251).
|
||||
|
||||
-- In_Package_Body (Flag48)
|
||||
-- Present in package entities. Set on the entity that denotes the
|
||||
-- package (the defining occurrence of the package declaration) while
|
||||
@ -2259,6 +2259,10 @@ package Einfo is
|
||||
-- 3) Object declarations generated by the expander that are implicitly
|
||||
-- imported or exported so that they can be marked in Sprint output.
|
||||
--
|
||||
-- 4) Internal entities in the list of primitives of tagged types that
|
||||
-- are used to handle secondary dispatch tables. These entities have
|
||||
-- also the attribute Interface_Alias.
|
||||
--
|
||||
-- Is_Interrupt_Handler (Flag89)
|
||||
-- Present in procedures. Set if a pragma Interrupt_Handler applies
|
||||
-- to the procedure. The procedure must be parameterless, and on all
|
||||
@ -5018,7 +5022,7 @@ package Einfo is
|
||||
-- Generic_Renamings (Elist23) (for an instance)
|
||||
-- Inner_Instances (Elist23) (generic function only)
|
||||
-- Protection_Object (Node23) (for concurrent kind)
|
||||
-- Abstract_Interface_Alias (Node25)
|
||||
-- Interface_Alias (Node25)
|
||||
-- Overridden_Operation (Node26)
|
||||
-- Extra_Formals (Node28)
|
||||
-- Body_Needed_For_SAL (Flag40)
|
||||
@ -5279,7 +5283,7 @@ package Einfo is
|
||||
-- Inner_Instances (Elist23) (for generic proc)
|
||||
-- Protection_Object (Node23) (for concurrent kind)
|
||||
-- Spec_PPC_List (Node24) (non-generic case only)
|
||||
-- Abstract_Interface_Alias (Node25)
|
||||
-- Interface_Alias (Node25)
|
||||
-- Static_Initialization (Node26) (init_proc only)
|
||||
-- Overridden_Operation (Node26)
|
||||
-- Wrapped_Entity (Node27) (non-generic case only)
|
||||
@ -5363,7 +5367,7 @@ package Einfo is
|
||||
-- Discriminant_Constraint (Elist21)
|
||||
-- Corresponding_Remote_Type (Node22)
|
||||
-- Stored_Constraint (Elist23)
|
||||
-- Abstract_Interfaces (Elist25)
|
||||
-- Interfaces (Elist25)
|
||||
-- Component_Alignment (special) (base type only)
|
||||
-- C_Pass_By_Copy (Flag125) (base type only)
|
||||
-- Has_Dispatch_Table (Flag220) (base tagged type only)
|
||||
@ -5397,7 +5401,7 @@ package Einfo is
|
||||
-- Discriminant_Constraint (Elist21)
|
||||
-- Private_View (Node22)
|
||||
-- Stored_Constraint (Elist23)
|
||||
-- Abstract_Interfaces (Elist25)
|
||||
-- Interfaces (Elist25)
|
||||
-- Has_Completion (Flag26)
|
||||
-- Has_Record_Rep_Clause (Flag65) (base type only)
|
||||
-- Has_External_Tag_Rep_Clause (Flag110)
|
||||
@ -5746,13 +5750,11 @@ package Einfo is
|
||||
-- section contains the functions used to obtain attribute values which
|
||||
-- correspond to values in fields or flags in the entity itself.
|
||||
|
||||
function Abstract_Interfaces (Id : E) return L;
|
||||
function Accept_Address (Id : E) return L;
|
||||
function Access_Disp_Table (Id : E) return L;
|
||||
function Actual_Subtype (Id : E) return E;
|
||||
function Address_Taken (Id : E) return B;
|
||||
function Alias (Id : E) return E;
|
||||
function Abstract_Interface_Alias (Id : E) return E;
|
||||
function Alignment (Id : E) return U;
|
||||
function Associated_Final_Chain (Id : E) return E;
|
||||
function Associated_Formal_Package (Id : E) return E;
|
||||
@ -5920,6 +5922,8 @@ package Einfo is
|
||||
function In_Private_Part (Id : E) return B;
|
||||
function In_Use (Id : E) return B;
|
||||
function Inner_Instances (Id : E) return L;
|
||||
function Interfaces (Id : E) return L;
|
||||
function Interface_Alias (Id : E) return E;
|
||||
function Interface_Name (Id : E) return N;
|
||||
function Is_AST_Entry (Id : E) return B;
|
||||
function Is_Abstract_Subprogram (Id : E) return B;
|
||||
@ -6305,14 +6309,12 @@ package Einfo is
|
||||
-- Attribute Set Procedures --
|
||||
------------------------------
|
||||
|
||||
procedure Set_Abstract_Interfaces (Id : E; V : L);
|
||||
procedure Set_Accept_Address (Id : E; V : L);
|
||||
procedure Set_Access_Disp_Table (Id : E; V : L);
|
||||
procedure Set_Dispatch_Table_Wrapper (Id : E; V : E);
|
||||
procedure Set_Actual_Subtype (Id : E; V : E);
|
||||
procedure Set_Address_Taken (Id : E; V : B := True);
|
||||
procedure Set_Alias (Id : E; V : E);
|
||||
procedure Set_Abstract_Interface_Alias (Id : E; V : E);
|
||||
procedure Set_Alignment (Id : E; V : U);
|
||||
procedure Set_Associated_Final_Chain (Id : E; V : E);
|
||||
procedure Set_Associated_Formal_Package (Id : E; V : E);
|
||||
@ -6474,10 +6476,12 @@ package Einfo is
|
||||
procedure Set_Hiding_Loop_Variable (Id : E; V : E);
|
||||
procedure Set_Homonym (Id : E; V : E);
|
||||
procedure Set_Implemented_By_Entry (Id : E; V : B := True);
|
||||
procedure Set_Interfaces (Id : E; V : L);
|
||||
procedure Set_In_Package_Body (Id : E; V : B := True);
|
||||
procedure Set_In_Private_Part (Id : E; V : B := True);
|
||||
procedure Set_In_Use (Id : E; V : B := True);
|
||||
procedure Set_Inner_Instances (Id : E; V : L);
|
||||
procedure Set_Interface_Alias (Id : E; V : E);
|
||||
procedure Set_Interface_Name (Id : E; V : N);
|
||||
procedure Set_Is_AST_Entry (Id : E; V : B := True);
|
||||
procedure Set_Is_Abstract_Subprogram (Id : E; V : B := True);
|
||||
@ -6954,12 +6958,10 @@ package Einfo is
|
||||
-- subprograms meeting the requirements documented in the section on
|
||||
-- XEINFO may be referenced in this section.
|
||||
|
||||
pragma Inline (Abstract_Interfaces);
|
||||
pragma Inline (Accept_Address);
|
||||
pragma Inline (Access_Disp_Table);
|
||||
pragma Inline (Actual_Subtype);
|
||||
pragma Inline (Address_Taken);
|
||||
pragma Inline (Abstract_Interface_Alias);
|
||||
pragma Inline (Alias);
|
||||
pragma Inline (Alignment);
|
||||
pragma Inline (Associated_Final_Chain);
|
||||
@ -7122,10 +7124,12 @@ package Einfo is
|
||||
pragma Inline (Hiding_Loop_Variable);
|
||||
pragma Inline (Homonym);
|
||||
pragma Inline (Implemented_By_Entry);
|
||||
pragma Inline (Interfaces);
|
||||
pragma Inline (In_Package_Body);
|
||||
pragma Inline (In_Private_Part);
|
||||
pragma Inline (In_Use);
|
||||
pragma Inline (Inner_Instances);
|
||||
pragma Inline (Interface_Alias);
|
||||
pragma Inline (Interface_Name);
|
||||
pragma Inline (Is_AST_Entry);
|
||||
pragma Inline (Is_Abstract_Subprogram);
|
||||
@ -7380,12 +7384,10 @@ package Einfo is
|
||||
pragma Inline (Init_Esize);
|
||||
pragma Inline (Init_RM_Size);
|
||||
|
||||
pragma Inline (Set_Abstract_Interfaces);
|
||||
pragma Inline (Set_Accept_Address);
|
||||
pragma Inline (Set_Access_Disp_Table);
|
||||
pragma Inline (Set_Actual_Subtype);
|
||||
pragma Inline (Set_Address_Taken);
|
||||
pragma Inline (Set_Abstract_Interface_Alias);
|
||||
pragma Inline (Set_Alias);
|
||||
pragma Inline (Set_Alignment);
|
||||
pragma Inline (Set_Associated_Final_Chain);
|
||||
@ -7547,10 +7549,12 @@ package Einfo is
|
||||
pragma Inline (Set_Hiding_Loop_Variable);
|
||||
pragma Inline (Set_Homonym);
|
||||
pragma Inline (Set_Implemented_By_Entry);
|
||||
pragma Inline (Set_Interfaces);
|
||||
pragma Inline (Set_In_Package_Body);
|
||||
pragma Inline (Set_In_Private_Part);
|
||||
pragma Inline (Set_In_Use);
|
||||
pragma Inline (Set_Inner_Instances);
|
||||
pragma Inline (Set_Interface_Alias);
|
||||
pragma Inline (Set_Interface_Name);
|
||||
pragma Inline (Set_Is_AST_Entry);
|
||||
pragma Inline (Set_Is_Abstract_Subprogram);
|
||||
|
@ -2573,7 +2573,7 @@ package body Exp_Aggr is
|
||||
-- Ada 2005 (AI-251): If tagged type has progenitors we must
|
||||
-- also initialize tags of the secondary dispatch tables.
|
||||
|
||||
if Has_Abstract_Interfaces (Base_Type (Typ)) then
|
||||
if Has_Interfaces (Base_Type (Typ)) then
|
||||
Init_Secondary_Tags
|
||||
(Typ => Base_Type (Typ),
|
||||
Target => Target,
|
||||
@ -3080,7 +3080,7 @@ package body Exp_Aggr is
|
||||
-- abstract interfaces we must also initialize the tags of the
|
||||
-- secondary dispatch tables.
|
||||
|
||||
if Has_Abstract_Interfaces (Base_Type (Typ)) then
|
||||
if Has_Interfaces (Base_Type (Typ)) then
|
||||
Init_Secondary_Tags
|
||||
(Typ => Base_Type (Typ),
|
||||
Target => Target,
|
||||
@ -5369,7 +5369,7 @@ package body Exp_Aggr is
|
||||
-- If the tagged types covers interface types we need to initialize all
|
||||
-- hidden components containing pointers to secondary dispatch tables.
|
||||
|
||||
elsif Is_Tagged_Type (Typ) and then Has_Abstract_Interfaces (Typ) then
|
||||
elsif Is_Tagged_Type (Typ) and then Has_Interfaces (Typ) then
|
||||
Convert_To_Assignments (N, Typ);
|
||||
|
||||
-- If some components are mutable, the size of the aggregate component
|
||||
|
@ -299,7 +299,7 @@ package body Exp_Ch13 is
|
||||
-- its secondary dispatch table and therefore the code generator
|
||||
-- has nothing else to do with this freezing node.
|
||||
|
||||
Delete := Present (Abstract_Interface_Alias (E));
|
||||
Delete := Present (Interface_Alias (E));
|
||||
end if;
|
||||
|
||||
-- Analyze actions generated by freezing. The init_proc contains source
|
||||
|
@ -57,6 +57,7 @@ with Sem_Disp; use Sem_Disp;
|
||||
with Sem_Eval; use Sem_Eval;
|
||||
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 Stand; use Stand;
|
||||
@ -2166,7 +2167,7 @@ package body Exp_Ch3 is
|
||||
-- If the interface is a parent of Rec_Type it shares the primary
|
||||
-- dispatch table and hence there is no need to build the function
|
||||
|
||||
if not Is_Parent (Node (Iface_Elmt), Rec_Type) then
|
||||
if not Is_Ancestor (Node (Iface_Elmt), Rec_Type) then
|
||||
Build_Offset_To_Top_Function (Iface_Comp => Node (Comp_Elmt));
|
||||
end if;
|
||||
|
||||
@ -2304,7 +2305,7 @@ package body Exp_Ch3 is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then not Is_Interface (Rec_Type)
|
||||
and then Has_Abstract_Interfaces (Rec_Type)
|
||||
and then Has_Interfaces (Rec_Type)
|
||||
then
|
||||
Init_Secondary_Tags
|
||||
(Typ => Rec_Type,
|
||||
@ -2398,8 +2399,7 @@ package body Exp_Ch3 is
|
||||
|
||||
if not Is_Imported (Prim)
|
||||
and then Convention (Prim) = Convention_CPP
|
||||
and then not Present (Abstract_Interface_Alias
|
||||
(Prim))
|
||||
and then not Present (Interface_Alias (Prim))
|
||||
then
|
||||
Register_Primitive (Loc,
|
||||
Prim => Prim,
|
||||
@ -2421,7 +2421,7 @@ package body Exp_Ch3 is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then not Is_Interface (Rec_Type)
|
||||
and then Has_Abstract_Interfaces (Rec_Type)
|
||||
and then Has_Interfaces (Rec_Type)
|
||||
and then Has_Discriminants (Etype (Rec_Type))
|
||||
and then Is_Variable_Size_Record (Etype (Rec_Type))
|
||||
then
|
||||
@ -4421,7 +4421,7 @@ package body Exp_Ch3 is
|
||||
and then
|
||||
(Is_Class_Wide_Type (Etype (Expr))
|
||||
or else
|
||||
not Is_Parent (Root_Type (Typ), Etype (Expr)))
|
||||
not Is_Ancestor (Root_Type (Typ), Etype (Expr)))
|
||||
and then Comes_From_Source (Def_Id)
|
||||
and then VM_Target = No_VM
|
||||
then
|
||||
@ -5321,6 +5321,105 @@ package body Exp_Ch3 is
|
||||
------------------------
|
||||
|
||||
procedure Freeze_Record_Type (N : Node_Id) is
|
||||
|
||||
procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id);
|
||||
-- Add to the list of primitives of Tagged_Types the internal entities
|
||||
-- associated with interface primitives that are located in secondary
|
||||
-- dispatch tables.
|
||||
|
||||
-------------------------------------
|
||||
-- Add_Internal_Interface_Entities --
|
||||
-------------------------------------
|
||||
|
||||
procedure Add_Internal_Interface_Entities (Tagged_Type : Entity_Id) is
|
||||
Elmt : Elmt_Id;
|
||||
Iface : Entity_Id;
|
||||
Iface_Elmt : Elmt_Id;
|
||||
Iface_Prim : Entity_Id;
|
||||
Ifaces_List : Elist_Id;
|
||||
New_Subp : Entity_Id := Empty;
|
||||
Prim : Entity_Id;
|
||||
|
||||
begin
|
||||
pragma Assert (Ada_Version >= Ada_05
|
||||
and then Is_Record_Type (Tagged_Type)
|
||||
and then Is_Tagged_Type (Tagged_Type)
|
||||
and then Has_Interfaces (Tagged_Type)
|
||||
and then not Is_Interface (Tagged_Type));
|
||||
|
||||
Collect_Interfaces (Tagged_Type, Ifaces_List);
|
||||
|
||||
Iface_Elmt := First_Elmt (Ifaces_List);
|
||||
while Present (Iface_Elmt) loop
|
||||
Iface := Node (Iface_Elmt);
|
||||
|
||||
-- Exclude from this processing interfaces that are parents
|
||||
-- of Tagged_Type because their primitives are located in the
|
||||
-- primary dispatch table (and hence no auxiliary internal
|
||||
-- entities are required to handle secondary dispatch tables
|
||||
-- in such case).
|
||||
|
||||
if not Is_Ancestor (Iface, Tagged_Type) then
|
||||
Elmt := First_Elmt (Primitive_Operations (Iface));
|
||||
while Present (Elmt) loop
|
||||
Iface_Prim := Node (Elmt);
|
||||
|
||||
if not Is_Predefined_Dispatching_Operation (Iface_Prim) then
|
||||
Prim :=
|
||||
Find_Primitive_Covering_Interface
|
||||
(Tagged_Type => Tagged_Type,
|
||||
Iface_Prim => Iface_Prim);
|
||||
|
||||
pragma Assert (Present (Prim));
|
||||
|
||||
Derive_Subprogram
|
||||
(New_Subp => New_Subp,
|
||||
Parent_Subp => Iface_Prim,
|
||||
Derived_Type => Tagged_Type,
|
||||
Parent_Type => Iface);
|
||||
|
||||
-- Ada 2005 (AI-251): Decorate internal entity Iface_Subp
|
||||
-- associated with interface types. These entities are
|
||||
-- only registered in the list of primitives of its
|
||||
-- corresponding tagged type because they are only used
|
||||
-- to fill the contents of the secondary dispatch tables.
|
||||
-- Therefore they are removed from the homonym chains.
|
||||
|
||||
Set_Is_Hidden (New_Subp);
|
||||
Set_Is_Internal (New_Subp);
|
||||
Set_Alias (New_Subp, Prim);
|
||||
Set_Is_Abstract_Subprogram (New_Subp,
|
||||
Is_Abstract_Subprogram (Prim));
|
||||
Set_Interface_Alias (New_Subp, Iface_Prim);
|
||||
|
||||
-- Internal entities associated with interface types are
|
||||
-- only registered in the list of primitives of the
|
||||
-- tagged type. They are only used to fill the contents
|
||||
-- of the secondary dispatch tables. Therefore they are
|
||||
-- not needed in the homonym chains.
|
||||
|
||||
Remove_Homonym (New_Subp);
|
||||
|
||||
-- Hidden entities associated with interfaces must have
|
||||
-- set the Has_Delay_Freeze attribute to ensure that, in
|
||||
-- case of locally defined tagged types (or compiling
|
||||
-- with static dispatch tables generation disabled) the
|
||||
-- corresponding entry of the secondary dispatch table is
|
||||
-- filled when such entity is frozen.
|
||||
|
||||
Set_Has_Delayed_Freeze (New_Subp);
|
||||
end if;
|
||||
|
||||
Next_Elmt (Elmt);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Iface_Elmt);
|
||||
end loop;
|
||||
end Add_Internal_Interface_Entities;
|
||||
|
||||
-- Local variables
|
||||
|
||||
Def_Id : constant Node_Id := Entity (N);
|
||||
Type_Decl : constant Node_Id := Parent (Def_Id);
|
||||
Comp : Entity_Id;
|
||||
@ -5343,6 +5442,8 @@ package body Exp_Ch3 is
|
||||
Wrapper_Body_List : List_Id := No_List;
|
||||
Null_Proc_Decl_List : List_Id := No_List;
|
||||
|
||||
-- Start of processing for Freeze_Record_Type
|
||||
|
||||
begin
|
||||
-- Build discriminant checking functions if not a derived type (for
|
||||
-- derived types that are not tagged types, always use the discriminant
|
||||
@ -5545,6 +5646,17 @@ package body Exp_Ch3 is
|
||||
Insert_Actions (N, Null_Proc_Decl_List);
|
||||
end if;
|
||||
|
||||
-- Ada 2005 (AI-251): Add internal entities associated with
|
||||
-- secondary dispatch tables to the list of primitives of tagged
|
||||
-- types that are not interfaces
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then not Is_Interface (Def_Id)
|
||||
and then Has_Interfaces (Def_Id)
|
||||
then
|
||||
Add_Internal_Interface_Entities (Def_Id);
|
||||
end if;
|
||||
|
||||
Set_Is_Frozen (Def_Id);
|
||||
Set_All_DT_Position (Def_Id);
|
||||
|
||||
@ -6678,7 +6790,7 @@ package body Exp_Ch3 is
|
||||
-- Initialize the pointer to the secondary DT associated with the
|
||||
-- interface.
|
||||
|
||||
if not Is_Parent (Iface, Typ) then
|
||||
if not Is_Ancestor (Iface, Typ) then
|
||||
Append_To (Stmts_List,
|
||||
Make_Assignment_Statement (Loc,
|
||||
Name =>
|
||||
@ -6776,7 +6888,7 @@ package body Exp_Ch3 is
|
||||
-- Don't need to set any value if this interface shares
|
||||
-- the primary dispatch table.
|
||||
|
||||
if not Is_Parent (Iface, Typ) then
|
||||
if not Is_Ancestor (Iface, Typ) then
|
||||
Append_To (Stmts_List,
|
||||
Build_Set_Static_Offset_To_Top (Loc,
|
||||
Iface_Tag => New_Reference_To (Iface_Tag, Loc),
|
||||
@ -7499,27 +7611,42 @@ package body Exp_Ch3 is
|
||||
-- User-defined equality
|
||||
|
||||
elsif Chars (Node (Prim)) = Name_Op_Eq
|
||||
and then (No (Alias (Node (Prim)))
|
||||
or else Nkind (Unit_Declaration_Node (Node (Prim))) =
|
||||
N_Subprogram_Renaming_Declaration)
|
||||
and then Etype (First_Formal (Node (Prim))) =
|
||||
Etype (Next_Formal (First_Formal (Node (Prim))))
|
||||
and then Base_Type (Etype (Node (Prim))) = Standard_Boolean
|
||||
then
|
||||
Eq_Needed := False;
|
||||
exit;
|
||||
if No (Alias (Node (Prim)))
|
||||
or else Nkind (Unit_Declaration_Node (Node (Prim))) =
|
||||
N_Subprogram_Renaming_Declaration
|
||||
then
|
||||
Eq_Needed := False;
|
||||
exit;
|
||||
|
||||
-- If the parent is not an interface type and has an abstract
|
||||
-- equality function, the inherited equality is abstract as well,
|
||||
-- and no body can be created for it.
|
||||
-- If the parent is not an interface type and has an abstract
|
||||
-- equality function, the inherited equality is abstract as
|
||||
-- well, and no body can be created for it.
|
||||
|
||||
elsif Chars (Node (Prim)) = Name_Op_Eq
|
||||
and then not Is_Interface (Etype (Tag_Typ))
|
||||
and then Present (Alias (Node (Prim)))
|
||||
and then Is_Abstract_Subprogram (Alias (Node (Prim)))
|
||||
then
|
||||
Eq_Needed := False;
|
||||
exit;
|
||||
elsif not Is_Interface (Etype (Tag_Typ))
|
||||
and then Present (Alias (Node (Prim)))
|
||||
and then Is_Abstract_Subprogram (Alias (Node (Prim)))
|
||||
then
|
||||
Eq_Needed := False;
|
||||
exit;
|
||||
|
||||
-- If the type has an equality function corresponding with
|
||||
-- a primitive defined in an interface type, the inherited
|
||||
-- equality is abstract as well, and no body can be created
|
||||
-- for it.
|
||||
|
||||
elsif Present (Alias (Node (Prim)))
|
||||
and then Comes_From_Source (Ultimate_Alias (Node (Prim)))
|
||||
and then
|
||||
Is_Interface
|
||||
(Find_Dispatching_Type (Ultimate_Alias (Node (Prim))))
|
||||
then
|
||||
Eq_Needed := False;
|
||||
exit;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Prim);
|
||||
@ -7663,7 +7790,7 @@ package body Exp_Ch3 is
|
||||
and then Is_Limited_Record (Etype (Tag_Typ)))
|
||||
or else
|
||||
(Is_Concurrent_Record_Type (Tag_Typ)
|
||||
and then Has_Abstract_Interfaces (Tag_Typ))
|
||||
and then Has_Interfaces (Tag_Typ))
|
||||
then
|
||||
Append_To (Res,
|
||||
Make_Subprogram_Declaration (Loc,
|
||||
@ -8116,7 +8243,7 @@ package body Exp_Ch3 is
|
||||
((Is_Interface (Etype (Tag_Typ))
|
||||
and then Is_Limited_Record (Etype (Tag_Typ)))
|
||||
or else (Is_Concurrent_Record_Type (Tag_Typ)
|
||||
and then Has_Abstract_Interfaces (Tag_Typ)))
|
||||
and then Has_Interfaces (Tag_Typ)))
|
||||
and then RTE_Available (RE_Select_Specific_Data)
|
||||
then
|
||||
Append_To (Res, Make_Disp_Asynchronous_Select_Body (Tag_Typ));
|
||||
|
@ -9210,7 +9210,7 @@ package body Exp_Ch4 is
|
||||
-- Obj1 in Iface'Class; -- Compile time error
|
||||
|
||||
if not Is_Class_Wide_Type (Left_Type)
|
||||
and then (Is_Parent (Etype (Right_Type), Left_Type)
|
||||
and then (Is_Ancestor (Etype (Right_Type), Left_Type)
|
||||
or else (Is_Interface (Etype (Right_Type))
|
||||
and then Interface_Present_In_Ancestor
|
||||
(Typ => Left_Type,
|
||||
|
@ -4728,7 +4728,7 @@ package body Exp_Ch6 is
|
||||
Tagged_Typ := Find_Dispatching_Type (Prim);
|
||||
|
||||
if No (Access_Disp_Table (Tagged_Typ))
|
||||
or else not Has_Abstract_Interfaces (Tagged_Typ)
|
||||
or else not Has_Interfaces (Tagged_Typ)
|
||||
or else not RTE_Available (RE_Interface_Tag)
|
||||
or else Restriction_Active (No_Dispatching_Calls)
|
||||
then
|
||||
@ -4856,7 +4856,7 @@ package body Exp_Ch6 is
|
||||
-- table slot.
|
||||
|
||||
if not Is_Interface (Typ)
|
||||
or else Present (Abstract_Interface_Alias (Subp))
|
||||
or else Present (Interface_Alias (Subp))
|
||||
then
|
||||
if Is_Predefined_Dispatching_Operation (Subp) then
|
||||
Register_Predefined_DT_Entry (Subp);
|
||||
|
@ -32,6 +32,7 @@ with Exp_Ch3; use Exp_Ch3;
|
||||
with Exp_Ch11; use Exp_Ch11;
|
||||
with Exp_Ch6; use Exp_Ch6;
|
||||
with Exp_Dbug; use Exp_Dbug;
|
||||
with Exp_Disp; use Exp_Disp;
|
||||
with Exp_Sel; use Exp_Sel;
|
||||
with Exp_Smem; use Exp_Smem;
|
||||
with Exp_Tss; use Exp_Tss;
|
||||
@ -1880,11 +1881,11 @@ package body Exp_Ch9 is
|
||||
Iface := Etype (Iface);
|
||||
end loop Examine_Parents;
|
||||
|
||||
if Present (Abstract_Interfaces
|
||||
if Present (Interfaces
|
||||
(Corresponding_Record_Type (Scope (Proc_Nam))))
|
||||
then
|
||||
Iface_Elmt := First_Elmt
|
||||
(Abstract_Interfaces
|
||||
(Interfaces
|
||||
(Corresponding_Record_Type (Scope (Proc_Nam))));
|
||||
Examine_Interfaces : while Present (Iface_Elmt) loop
|
||||
Iface := Node (Iface_Elmt);
|
||||
@ -7091,7 +7092,7 @@ package body Exp_Ch9 is
|
||||
-- an interface.
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Present (Abstract_Interfaces (
|
||||
and then Present (Interfaces (
|
||||
Corresponding_Record_Type (Pid)))
|
||||
then
|
||||
Disp_Op_Body :=
|
||||
@ -7178,8 +7179,7 @@ package body Exp_Ch9 is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Present (Protected_Definition (Parent (Pid)))
|
||||
and then Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type (Pid)))
|
||||
and then Present (Interfaces (Corresponding_Record_Type (Pid)))
|
||||
then
|
||||
declare
|
||||
Vis_Decl : Node_Id :=
|
||||
@ -7630,10 +7630,10 @@ package body Exp_Ch9 is
|
||||
if Ada_Version >= Ada_05
|
||||
and then Present (Visible_Declarations (Pdef))
|
||||
and then Present (Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Pdef))))
|
||||
and then Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Pdef)))))
|
||||
(Defining_Identifier (Parent (Pdef))))
|
||||
and then Present (Interfaces
|
||||
(Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Pdef)))))
|
||||
then
|
||||
declare
|
||||
Current_Node : Node_Id := Rec_Decl;
|
||||
@ -7750,8 +7750,7 @@ package body Exp_Ch9 is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then
|
||||
Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type (Prot_Typ)))
|
||||
Present (Interfaces (Corresponding_Record_Type (Prot_Typ)))
|
||||
then
|
||||
Sub :=
|
||||
Make_Subprogram_Declaration (Loc,
|
||||
@ -9535,8 +9534,7 @@ package body Exp_Ch9 is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Present (Task_Definition (Parent (Ttyp)))
|
||||
and then Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type (Ttyp)))
|
||||
and then Present (Interfaces (Corresponding_Record_Type (Ttyp)))
|
||||
then
|
||||
declare
|
||||
Current_Node : Node_Id;
|
||||
@ -10030,10 +10028,10 @@ package body Exp_Ch9 is
|
||||
if Ada_Version >= Ada_05
|
||||
and then Present (Taskdef)
|
||||
and then Present (Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Taskdef))))
|
||||
and then Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Taskdef)))))
|
||||
(Defining_Identifier (Parent (Taskdef))))
|
||||
and then Present (Interfaces
|
||||
(Corresponding_Record_Type
|
||||
(Defining_Identifier (Parent (Taskdef)))))
|
||||
then
|
||||
declare
|
||||
Current_Node : Node_Id := Rec_Decl;
|
||||
@ -10087,7 +10085,6 @@ package body Exp_Ch9 is
|
||||
|
||||
declare
|
||||
L : constant List_Id := Freeze_Entity (Rec_Ent, Loc);
|
||||
|
||||
begin
|
||||
if Is_Non_Empty_List (L) then
|
||||
Insert_List_After (Body_Decl, L);
|
||||
@ -11576,7 +11573,7 @@ package body Exp_Ch9 is
|
||||
if Has_Entry
|
||||
or else Has_Interrupt_Handler (Ptyp)
|
||||
or else Has_Attach_Handler (Ptyp)
|
||||
or else Has_Abstract_Interfaces (Protect_Rec)
|
||||
or else Has_Interfaces (Protect_Rec)
|
||||
then
|
||||
declare
|
||||
Pkg_Id : constant RTU_Id :=
|
||||
|
@ -1080,7 +1080,7 @@ package body Exp_Disp is
|
||||
-- a parent of the type of the actual because in this case the
|
||||
-- interface primitives are located in the primary dispatch table.
|
||||
|
||||
elsif Is_Parent (Formal_Typ, Actual_Typ) then
|
||||
elsif Is_Ancestor (Formal_Typ, Actual_Typ) then
|
||||
null;
|
||||
|
||||
-- Implicit conversion to the class-wide formal type to force
|
||||
@ -1126,7 +1126,7 @@ package body Exp_Disp is
|
||||
-- a parent of the type of the actual because in this case the
|
||||
-- interface primitives are located in the primary dispatch table.
|
||||
|
||||
elsif Is_Parent (Formal_DDT, Actual_DDT) then
|
||||
elsif Is_Ancestor (Formal_DDT, Actual_DDT) then
|
||||
null;
|
||||
|
||||
else
|
||||
@ -1450,6 +1450,50 @@ package body Exp_Disp is
|
||||
and then not Restriction_Active (No_Dispatching_Calls);
|
||||
end Has_DT;
|
||||
|
||||
-----------------------------------------
|
||||
-- Is_Predefined_Dispatching_Operation --
|
||||
-----------------------------------------
|
||||
|
||||
function Is_Predefined_Dispatching_Operation
|
||||
(E : Entity_Id) return Boolean
|
||||
is
|
||||
TSS_Name : TSS_Name_Type;
|
||||
|
||||
begin
|
||||
if not Is_Dispatching_Operation (E) then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
Get_Name_String (Chars (E));
|
||||
|
||||
-- Most predefined primitives have internally generated names. Equality
|
||||
-- must be treated differently; the predefined operation is recognized
|
||||
-- as a homogeneous binary operator that returns Boolean.
|
||||
|
||||
if Name_Len > TSS_Name_Type'Last then
|
||||
TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
|
||||
.. Name_Len));
|
||||
if Chars (E) = Name_uSize
|
||||
or else Chars (E) = Name_uAlignment
|
||||
or else TSS_Name = TSS_Stream_Read
|
||||
or else TSS_Name = TSS_Stream_Write
|
||||
or else TSS_Name = TSS_Stream_Input
|
||||
or else TSS_Name = TSS_Stream_Output
|
||||
or else
|
||||
(Chars (E) = Name_Op_Eq
|
||||
and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
|
||||
or else Chars (E) = Name_uAssign
|
||||
or else TSS_Name = TSS_Deep_Adjust
|
||||
or else TSS_Name = TSS_Deep_Finalize
|
||||
or else Is_Predefined_Interface_Primitive (E)
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return False;
|
||||
end Is_Predefined_Dispatching_Operation;
|
||||
|
||||
-------------------------------------
|
||||
-- Is_Predefined_Dispatching_Alias --
|
||||
-------------------------------------
|
||||
@ -1475,6 +1519,21 @@ package body Exp_Disp is
|
||||
return False;
|
||||
end Is_Predefined_Dispatching_Alias;
|
||||
|
||||
---------------------------------------
|
||||
-- Is_Predefined_Interface_Primitive --
|
||||
---------------------------------------
|
||||
|
||||
function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean is
|
||||
begin
|
||||
return Ada_Version >= Ada_05
|
||||
and then (Chars (E) = Name_uDisp_Asynchronous_Select or else
|
||||
Chars (E) = Name_uDisp_Conditional_Select or else
|
||||
Chars (E) = Name_uDisp_Get_Prim_Op_Kind or else
|
||||
Chars (E) = Name_uDisp_Get_Task_Id or else
|
||||
Chars (E) = Name_uDisp_Requeue or else
|
||||
Chars (E) = Name_uDisp_Timed_Select);
|
||||
end Is_Predefined_Interface_Primitive;
|
||||
|
||||
----------------------------------------
|
||||
-- Make_Disp_Asynchronous_Select_Body --
|
||||
----------------------------------------
|
||||
@ -3401,7 +3460,7 @@ package body Exp_Disp is
|
||||
or else Is_Controlled (Typ)
|
||||
or else Restriction_Active (No_Dispatching_Calls)
|
||||
or else not Is_Limited_Type (Typ)
|
||||
or else not Has_Abstract_Interfaces (Typ)
|
||||
or else not Has_Interfaces (Typ)
|
||||
or else not Build_Thunks
|
||||
then
|
||||
-- No OSD table required
|
||||
@ -3429,11 +3488,11 @@ package body Exp_Disp is
|
||||
while Present (Prim_Elmt) loop
|
||||
Prim := Node (Prim_Elmt);
|
||||
|
||||
if Present (Abstract_Interface_Alias (Prim))
|
||||
if Present (Interface_Alias (Prim))
|
||||
and then Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim)) = Iface
|
||||
(Interface_Alias (Prim)) = Iface
|
||||
then
|
||||
Prim_Alias := Abstract_Interface_Alias (Prim);
|
||||
Prim_Alias := Interface_Alias (Prim);
|
||||
|
||||
E := Prim;
|
||||
while Present (Alias (E)) loop
|
||||
@ -3544,31 +3603,29 @@ package body Exp_Disp is
|
||||
Prim := Node (Prim_Elmt);
|
||||
|
||||
if not Is_Predefined_Dispatching_Operation (Prim)
|
||||
and then Present (Abstract_Interface_Alias (Prim))
|
||||
and then Present (Interface_Alias (Prim))
|
||||
and then not Is_Abstract_Subprogram (Alias (Prim))
|
||||
and then not Is_Imported (Alias (Prim))
|
||||
and then Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim)) = Iface
|
||||
(Interface_Alias (Prim)) = Iface
|
||||
|
||||
-- Generate the code of the thunk only if the abstract
|
||||
-- interface type is not an immediate ancestor of
|
||||
-- Tagged_Type; otherwise the DT associated with the
|
||||
-- interface is the primary DT.
|
||||
|
||||
and then not Is_Parent (Iface, Typ)
|
||||
and then not Is_Ancestor (Iface, Typ)
|
||||
then
|
||||
if not Build_Thunks then
|
||||
Pos :=
|
||||
UI_To_Int
|
||||
(DT_Position (Abstract_Interface_Alias (Prim)));
|
||||
UI_To_Int (DT_Position (Interface_Alias (Prim)));
|
||||
Prim_Table (Pos) := Alias (Prim);
|
||||
else
|
||||
Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
|
||||
|
||||
if Present (Thunk_Id) then
|
||||
Pos :=
|
||||
UI_To_Int
|
||||
(DT_Position (Abstract_Interface_Alias (Prim)));
|
||||
UI_To_Int (DT_Position (Interface_Alias (Prim)));
|
||||
|
||||
Prim_Table (Pos) := Thunk_Id;
|
||||
Append_To (Result, Thunk_Code);
|
||||
@ -3843,7 +3900,7 @@ package body Exp_Disp is
|
||||
|
||||
-- Ada 2005 (AI-251): Build the secondary dispatch tables
|
||||
|
||||
if Has_Abstract_Interfaces (Typ) then
|
||||
if Has_Interfaces (Typ) then
|
||||
Collect_Interface_Components (Typ, Typ_Comps);
|
||||
|
||||
Suffix_Index := 0;
|
||||
@ -4438,7 +4495,7 @@ package body Exp_Disp is
|
||||
|
||||
-- Count the number of interface types implemented by Typ
|
||||
|
||||
Collect_Abstract_Interfaces (Typ, Typ_Ifaces);
|
||||
Collect_Interfaces (Typ, Typ_Ifaces);
|
||||
|
||||
AI := First_Elmt (Typ_Ifaces);
|
||||
while Present (AI) loop
|
||||
@ -4460,7 +4517,7 @@ package body Exp_Disp is
|
||||
begin
|
||||
AI := First_Elmt (Typ_Ifaces);
|
||||
while Present (AI) loop
|
||||
if Is_Parent (Node (AI), Typ) then
|
||||
if Is_Ancestor (Node (AI), Typ) then
|
||||
Sec_DT_Tag :=
|
||||
New_Reference_To (DT_Ptr, Loc);
|
||||
else
|
||||
@ -4471,7 +4528,7 @@ package body Exp_Disp is
|
||||
|
||||
while Ekind (Node (Elmt)) = E_Constant
|
||||
and then not
|
||||
Is_Parent (Node (AI), Related_Type (Node (Elmt)))
|
||||
Is_Ancestor (Node (AI), Related_Type (Node (Elmt)))
|
||||
loop
|
||||
pragma Assert (Has_Thunks (Node (Elmt)));
|
||||
Next_Elmt (Elmt);
|
||||
@ -4582,7 +4639,7 @@ package body Exp_Disp is
|
||||
if Ada_Version >= Ada_05
|
||||
and then Has_DT (Typ)
|
||||
and then Is_Concurrent_Record_Type (Typ)
|
||||
and then Has_Abstract_Interfaces (Typ)
|
||||
and then Has_Interfaces (Typ)
|
||||
and then Nb_Prim > 0
|
||||
and then not Is_Abstract_Type (Typ)
|
||||
and then not Is_Controlled (Typ)
|
||||
@ -4999,7 +5056,7 @@ package body Exp_Disp is
|
||||
Prim := Node (Prim_Elmt);
|
||||
|
||||
if Is_Imported (Prim)
|
||||
or else Present (Abstract_Interface_Alias (Prim))
|
||||
or else Present (Interface_Alias (Prim))
|
||||
or else Is_Predefined_Dispatching_Operation (Prim)
|
||||
then
|
||||
null;
|
||||
@ -5015,7 +5072,7 @@ package body Exp_Disp is
|
||||
|
||||
if not Is_Predefined_Dispatching_Operation (E)
|
||||
and then not Is_Abstract_Subprogram (E)
|
||||
and then not Present (Abstract_Interface_Alias (E))
|
||||
and then not Present (Interface_Alias (E))
|
||||
then
|
||||
pragma Assert
|
||||
(UI_To_Int (DT_Position (Prim)) <= Nb_Prim);
|
||||
@ -5225,11 +5282,10 @@ package body Exp_Disp is
|
||||
Copy_Secondary_DTs (Etype (Typ));
|
||||
end if;
|
||||
|
||||
if Present (Abstract_Interfaces (Typ))
|
||||
and then not Is_Empty_Elmt_List
|
||||
(Abstract_Interfaces (Typ))
|
||||
if Present (Interfaces (Typ))
|
||||
and then not Is_Empty_Elmt_List (Interfaces (Typ))
|
||||
then
|
||||
Iface := First_Elmt (Abstract_Interfaces (Typ));
|
||||
Iface := First_Elmt (Interfaces (Typ));
|
||||
E := First_Entity (Typ);
|
||||
while Present (E)
|
||||
and then Present (Node (Sec_DT_Ancestor))
|
||||
@ -5392,7 +5448,7 @@ package body Exp_Disp is
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Is_Concurrent_Record_Type (Typ)
|
||||
and then Has_Abstract_Interfaces (Typ)
|
||||
and then Has_Interfaces (Typ)
|
||||
then
|
||||
Append_List_To (Result,
|
||||
Make_Select_Specific_Data_Table (Typ));
|
||||
@ -5547,7 +5603,7 @@ package body Exp_Disp is
|
||||
|
||||
-- Look for primitive overriding an abstract interface subprogram
|
||||
|
||||
if Present (Abstract_Interface_Alias (Prim))
|
||||
if Present (Interface_Alias (Prim))
|
||||
and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
|
||||
then
|
||||
Prim_Pos := DT_Position (Alias (Prim));
|
||||
@ -5626,7 +5682,7 @@ package body Exp_Disp is
|
||||
|
||||
-- Collect the components associated with secondary dispatch tables
|
||||
|
||||
if Has_Abstract_Interfaces (Typ) then
|
||||
if Has_Interfaces (Typ) then
|
||||
Collect_Interface_Components (Typ, Typ_Comps);
|
||||
end if;
|
||||
|
||||
@ -5777,7 +5833,7 @@ package body Exp_Disp is
|
||||
|
||||
-- 2) Generate the secondary tag entities
|
||||
|
||||
if Has_Abstract_Interfaces (Typ) then
|
||||
if Has_Interfaces (Typ) then
|
||||
Suffix_Index := 0;
|
||||
|
||||
-- For each interface type we build an unique external name
|
||||
@ -6071,7 +6127,7 @@ package body Exp_Disp is
|
||||
return;
|
||||
end if;
|
||||
|
||||
if not Present (Abstract_Interface_Alias (Prim)) then
|
||||
if not Present (Interface_Alias (Prim)) then
|
||||
Tag_Typ := Scope (DTC_Entity (Prim));
|
||||
Pos := DT_Position (Prim);
|
||||
Tag := First_Tag_Component (Tag_Typ);
|
||||
@ -6128,13 +6184,13 @@ package body Exp_Disp is
|
||||
|
||||
else
|
||||
Tag_Typ := Find_Dispatching_Type (Alias (Prim));
|
||||
Iface_Typ := Find_Dispatching_Type (Abstract_Interface_Alias (Prim));
|
||||
Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));
|
||||
|
||||
pragma Assert (Is_Interface (Iface_Typ));
|
||||
|
||||
Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code);
|
||||
|
||||
if not Is_Parent (Iface_Typ, Tag_Typ)
|
||||
if not Is_Ancestor (Iface_Typ, Tag_Typ)
|
||||
and then Present (Thunk_Code)
|
||||
then
|
||||
-- Comment needed on why checks are suppressed. This is not just
|
||||
@ -6151,7 +6207,7 @@ package body Exp_Disp is
|
||||
Iface_DT_Ptr := Node (Iface_DT_Elmt);
|
||||
pragma Assert (Has_Thunks (Iface_DT_Ptr));
|
||||
|
||||
Iface_Prim := Abstract_Interface_Alias (Prim);
|
||||
Iface_Prim := Interface_Alias (Prim);
|
||||
Pos := DT_Position (Iface_Prim);
|
||||
Tag := First_Tag_Component (Iface_Typ);
|
||||
L := New_List;
|
||||
@ -6263,7 +6319,7 @@ package body Exp_Disp is
|
||||
-- Primitive operations covering abstract interfaces are
|
||||
-- allocated later
|
||||
|
||||
elsif Present (Abstract_Interface_Alias (Op)) then
|
||||
elsif Present (Interface_Alias (Op)) then
|
||||
null;
|
||||
|
||||
-- Predefined dispatching operations are completely safe. They
|
||||
@ -6343,6 +6399,8 @@ package body Exp_Disp is
|
||||
-- Start of processing for Set_All_DT_Position
|
||||
|
||||
begin
|
||||
pragma Assert (Present (First_Tag_Component (Typ)));
|
||||
|
||||
-- Set the DT_Position for each primitive operation. Perform some
|
||||
-- sanity checks to avoid to build completely inconsistent dispatch
|
||||
-- tables.
|
||||
@ -6498,17 +6556,14 @@ package body Exp_Disp is
|
||||
|
||||
-- Overriding primitives of ancestor abstract interfaces
|
||||
|
||||
elsif Present (Abstract_Interface_Alias (Prim))
|
||||
and then Is_Parent
|
||||
(Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim)),
|
||||
Typ)
|
||||
elsif Present (Interface_Alias (Prim))
|
||||
and then Is_Ancestor
|
||||
(Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
|
||||
then
|
||||
pragma Assert (DT_Position (Prim) = No_Uint
|
||||
and then Present (DTC_Entity
|
||||
(Abstract_Interface_Alias (Prim))));
|
||||
and then Present (DTC_Entity (Interface_Alias (Prim))));
|
||||
|
||||
E := Abstract_Interface_Alias (Prim);
|
||||
E := Interface_Alias (Prim);
|
||||
Set_DT_Position (Prim, DT_Position (E));
|
||||
|
||||
pragma Assert
|
||||
@ -6520,11 +6575,11 @@ package body Exp_Disp is
|
||||
-- Overriding primitives must use the same entry as the
|
||||
-- overridden primitive.
|
||||
|
||||
elsif not Present (Abstract_Interface_Alias (Prim))
|
||||
elsif not Present (Interface_Alias (Prim))
|
||||
and then Present (Alias (Prim))
|
||||
and then Chars (Prim) = Chars (Alias (Prim))
|
||||
and then Find_Dispatching_Type (Alias (Prim)) /= Typ
|
||||
and then Is_Parent
|
||||
and then Is_Ancestor
|
||||
(Find_Dispatching_Type (Alias (Prim)), Typ)
|
||||
and then Present (DTC_Entity (Alias (Prim)))
|
||||
then
|
||||
@ -6554,7 +6609,7 @@ package body Exp_Disp is
|
||||
|
||||
-- Primitives covering interface primitives are handled later
|
||||
|
||||
elsif Present (Abstract_Interface_Alias (Prim)) then
|
||||
elsif Present (Interface_Alias (Prim)) then
|
||||
null;
|
||||
|
||||
else
|
||||
@ -6583,16 +6638,15 @@ package body Exp_Disp is
|
||||
Prim := Node (Prim_Elmt);
|
||||
|
||||
if DT_Position (Prim) = No_Uint
|
||||
and then Present (Abstract_Interface_Alias (Prim))
|
||||
and then Present (Interface_Alias (Prim))
|
||||
then
|
||||
pragma Assert (Present (Alias (Prim))
|
||||
and then Find_Dispatching_Type (Alias (Prim)) = Typ);
|
||||
|
||||
-- Check if this entry will be placed in the primary DT
|
||||
|
||||
if Is_Parent (Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim)),
|
||||
Typ)
|
||||
if Is_Ancestor
|
||||
(Find_Dispatching_Type (Interface_Alias (Prim)), Typ)
|
||||
then
|
||||
pragma Assert (DT_Position (Alias (Prim)) /= No_Uint);
|
||||
Set_DT_Position (Prim, DT_Position (Alias (Prim)));
|
||||
@ -6601,9 +6655,9 @@ package body Exp_Disp is
|
||||
|
||||
else
|
||||
pragma Assert
|
||||
(DT_Position (Abstract_Interface_Alias (Prim)) /= No_Uint);
|
||||
(DT_Position (Interface_Alias (Prim)) /= No_Uint);
|
||||
Set_DT_Position (Prim,
|
||||
DT_Position (Abstract_Interface_Alias (Prim)));
|
||||
DT_Position (Interface_Alias (Prim)));
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@ -6666,14 +6720,16 @@ package body Exp_Disp is
|
||||
-- point of declaration, but for inherited operations it must
|
||||
-- be done when building the dispatch table.
|
||||
|
||||
-- Ada 2005 (AI-251): Hidden entities associated with abstract
|
||||
-- interface primitives are not taken into account because the
|
||||
-- check is done with the aliased primitive.
|
||||
-- Ada 2005 (AI-251): Primitives associated with interfaces are
|
||||
-- excluded from this check because interfaces must be visible in
|
||||
-- the public and private part (RM 7.3 (7.3/2))
|
||||
|
||||
if Is_Abstract_Type (Typ)
|
||||
and then Is_Abstract_Subprogram (Prim)
|
||||
and then Present (Alias (Prim))
|
||||
and then not Present (Abstract_Interface_Alias (Prim))
|
||||
and then not Is_Interface
|
||||
(Find_Dispatching_Type (Ultimate_Alias (Prim)))
|
||||
and then not Present (Interface_Alias (Prim))
|
||||
and then Is_Derived_Type (Typ)
|
||||
and then In_Private_Part (Current_Scope)
|
||||
and then
|
||||
@ -6789,16 +6845,14 @@ package body Exp_Disp is
|
||||
Prim : Entity_Id)
|
||||
is
|
||||
begin
|
||||
if Present (Abstract_Interface_Alias (Prim))
|
||||
if Present (Interface_Alias (Prim))
|
||||
and then Is_Interface
|
||||
(Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim)))
|
||||
(Find_Dispatching_Type (Interface_Alias (Prim)))
|
||||
then
|
||||
Set_DTC_Entity (Prim,
|
||||
Find_Interface_Tag
|
||||
(T => Tagged_Type,
|
||||
Iface => Find_Dispatching_Type
|
||||
(Abstract_Interface_Alias (Prim))));
|
||||
Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
|
||||
else
|
||||
Set_DTC_Entity (Prim,
|
||||
First_Tag_Component (Tagged_Type));
|
||||
@ -6927,12 +6981,12 @@ package body Exp_Disp is
|
||||
Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
|
||||
end if;
|
||||
|
||||
if Present (Abstract_Interface_Alias (Prim)) then
|
||||
if Present (Interface_Alias (Prim)) then
|
||||
Write_Str (", AI_Alias of ");
|
||||
Write_Name (Chars (Scope (DTC_Entity
|
||||
(Abstract_Interface_Alias (Prim)))));
|
||||
Write_Name
|
||||
(Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
|
||||
Write_Char (':');
|
||||
Write_Int (Int (Abstract_Interface_Alias (Prim)));
|
||||
Write_Int (Int (Interface_Alias (Prim)));
|
||||
end if;
|
||||
|
||||
Write_Str (")");
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
|
||||
-- Copyright (C) 1992-2008, 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- --
|
||||
@ -212,6 +212,13 @@ package Exp_Disp is
|
||||
-- Otherwise they are set to the defining identifier and the subprogram
|
||||
-- body of the generated thunk.
|
||||
|
||||
function Is_Predefined_Dispatching_Operation (E : Entity_Id) return Boolean;
|
||||
-- Ada 2005 (AI-251): Determines if E is a predefined primitive operation
|
||||
|
||||
function Is_Predefined_Interface_Primitive (E : Entity_Id) return Boolean;
|
||||
-- Ada 2005 (AI-345): Returns True if E is one of the predefined primitives
|
||||
-- required to implement interfaces.
|
||||
|
||||
function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id;
|
||||
-- Expand the declarations for the Dispatch Table. The node N is the
|
||||
-- declaration that forces the generation of the table. It is used to place
|
||||
|
@ -45,6 +45,7 @@ with Rtsfind; use Rtsfind;
|
||||
with Sem; use Sem;
|
||||
with Sem_Eval; use Sem_Eval;
|
||||
with Sem_Res; use Sem_Res;
|
||||
with Sem_Type; use Sem_Type;
|
||||
with Sem_Util; use Sem_Util;
|
||||
with Sinfo; use Sinfo;
|
||||
with Sinput; use Sinput;
|
||||
@ -165,7 +166,7 @@ package body Exp_Intr is
|
||||
-- If the result type is not parent of Tag_Arg then we need to
|
||||
-- locate the tag of the secondary dispatch table.
|
||||
|
||||
if not Is_Parent (Etype (Result_Typ), Etype (Tag_Arg)) then
|
||||
if not Is_Ancestor (Etype (Result_Typ), Etype (Tag_Arg)) then
|
||||
pragma Assert (not Is_Interface (Etype (Tag_Arg)));
|
||||
|
||||
Iface_Tag :=
|
||||
|
@ -1386,73 +1386,8 @@ package body Exp_Util is
|
||||
(T : Entity_Id;
|
||||
Iface : Entity_Id) return Elmt_Id
|
||||
is
|
||||
ADT : Elmt_Id;
|
||||
Found : Boolean := False;
|
||||
Typ : Entity_Id := T;
|
||||
|
||||
procedure Find_Secondary_Table (Typ : Entity_Id);
|
||||
-- Internal subprogram used to recursively climb to the ancestors
|
||||
|
||||
--------------------------
|
||||
-- Find_Secondary_Table --
|
||||
--------------------------
|
||||
|
||||
procedure Find_Secondary_Table (Typ : Entity_Id) is
|
||||
AI_Elmt : Elmt_Id;
|
||||
AI : Node_Id;
|
||||
|
||||
begin
|
||||
pragma Assert (Typ /= Iface);
|
||||
|
||||
-- Climb to the ancestor (if any) handling synchronized interface
|
||||
-- derivations and private types
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ) then
|
||||
declare
|
||||
Iface_List : constant List_Id := Abstract_Interface_List (Typ);
|
||||
|
||||
begin
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Find_Secondary_Table (Etype (First (Iface_List)));
|
||||
end if;
|
||||
end;
|
||||
|
||||
elsif Present (Full_View (Etype (Typ))) then
|
||||
if Full_View (Etype (Typ)) /= Typ then
|
||||
Find_Secondary_Table (Full_View (Etype (Typ)));
|
||||
end if;
|
||||
|
||||
elsif Etype (Typ) /= Typ then
|
||||
Find_Secondary_Table (Etype (Typ));
|
||||
end if;
|
||||
|
||||
-- Traverse the list of interfaces implemented by the type
|
||||
|
||||
if not Found
|
||||
and then Present (Abstract_Interfaces (Typ))
|
||||
and then not Is_Empty_Elmt_List (Abstract_Interfaces (Typ))
|
||||
then
|
||||
AI_Elmt := First_Elmt (Abstract_Interfaces (Typ));
|
||||
while Present (AI_Elmt) loop
|
||||
AI := Node (AI_Elmt);
|
||||
|
||||
if AI = Iface or else Is_Ancestor (Iface, AI) then
|
||||
Found := True;
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Document what is going on here, why four Next's???
|
||||
|
||||
Next_Elmt (ADT);
|
||||
Next_Elmt (ADT);
|
||||
Next_Elmt (ADT);
|
||||
Next_Elmt (ADT);
|
||||
Next_Elmt (AI_Elmt);
|
||||
end loop;
|
||||
end if;
|
||||
end Find_Secondary_Table;
|
||||
|
||||
-- Start of processing for Find_Interface_ADT
|
||||
ADT : Elmt_Id;
|
||||
Typ : Entity_Id := T;
|
||||
|
||||
begin
|
||||
pragma Assert (Is_Interface (Iface));
|
||||
@ -1481,11 +1416,23 @@ package body Exp_Util is
|
||||
(not Is_Class_Wide_Type (Typ)
|
||||
and then Ekind (Typ) /= E_Incomplete_Type);
|
||||
|
||||
ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
|
||||
pragma Assert (Present (Node (ADT)));
|
||||
Find_Secondary_Table (Typ);
|
||||
pragma Assert (Found);
|
||||
return ADT;
|
||||
if Is_Ancestor (Iface, Typ) then
|
||||
return First_Elmt (Access_Disp_Table (Typ));
|
||||
|
||||
else
|
||||
ADT :=
|
||||
Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
|
||||
while Present (ADT)
|
||||
and then Present (Related_Type (Node (ADT)))
|
||||
and then Related_Type (Node (ADT)) /= Iface
|
||||
and then not Is_Ancestor (Iface, Related_Type (Node (ADT)))
|
||||
loop
|
||||
Next_Elmt (ADT);
|
||||
end loop;
|
||||
|
||||
pragma Assert (Present (Related_Type (Node (ADT))));
|
||||
return ADT;
|
||||
end if;
|
||||
end Find_Interface_ADT;
|
||||
|
||||
------------------------
|
||||
@ -1500,14 +1447,6 @@ package body Exp_Util is
|
||||
Found : Boolean := False;
|
||||
Typ : Entity_Id := T;
|
||||
|
||||
Is_Primary_Tag : Boolean := False;
|
||||
|
||||
Is_Sync_Typ : Boolean := False;
|
||||
-- In case of non concurrent-record-types each parent-type has the
|
||||
-- tags associated with the interface types that are not implemented
|
||||
-- by the ancestors; concurrent-record-types have their whole list of
|
||||
-- interface tags (and this case requires some special management).
|
||||
|
||||
procedure Find_Tag (Typ : Entity_Id);
|
||||
-- Internal subprogram used to recursively climb to the ancestors
|
||||
|
||||
@ -1524,32 +1463,15 @@ package body Exp_Util is
|
||||
-- therefore shares the main tag.
|
||||
|
||||
if Typ = Iface then
|
||||
if Is_Sync_Typ then
|
||||
Is_Primary_Tag := True;
|
||||
else
|
||||
pragma Assert
|
||||
(Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
|
||||
AI_Tag := First_Tag_Component (Typ);
|
||||
end if;
|
||||
|
||||
pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
|
||||
AI_Tag := First_Tag_Component (Typ);
|
||||
Found := True;
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- Handle synchronized interface derivations
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ) then
|
||||
declare
|
||||
Iface_List : constant List_Id := Abstract_Interface_List (Typ);
|
||||
begin
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Find_Tag (Etype (First (Iface_List)));
|
||||
end if;
|
||||
end;
|
||||
|
||||
-- Climb to the root type handling private types
|
||||
|
||||
elsif Present (Full_View (Etype (Typ))) then
|
||||
if Present (Full_View (Etype (Typ))) then
|
||||
if Full_View (Etype (Typ)) /= Typ then
|
||||
Find_Tag (Full_View (Etype (Typ)));
|
||||
end if;
|
||||
@ -1561,19 +1483,16 @@ package body Exp_Util is
|
||||
-- Traverse the list of interfaces implemented by the type
|
||||
|
||||
if not Found
|
||||
and then Present (Abstract_Interfaces (Typ))
|
||||
and then not (Is_Empty_Elmt_List (Abstract_Interfaces (Typ)))
|
||||
and then Present (Interfaces (Typ))
|
||||
and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
|
||||
then
|
||||
-- Skip the tag associated with the primary table
|
||||
|
||||
if not Is_Sync_Typ then
|
||||
pragma Assert
|
||||
(Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
|
||||
AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
|
||||
pragma Assert (Present (AI_Tag));
|
||||
end if;
|
||||
pragma Assert (Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
|
||||
AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
|
||||
pragma Assert (Present (AI_Tag));
|
||||
|
||||
AI_Elmt := First_Elmt (Abstract_Interfaces (Typ));
|
||||
AI_Elmt := First_Elmt (Interfaces (Typ));
|
||||
while Present (AI_Elmt) loop
|
||||
AI := Node (AI_Elmt);
|
||||
|
||||
@ -1624,149 +1543,10 @@ package body Exp_Util is
|
||||
Typ := Non_Limited_View (Typ);
|
||||
end if;
|
||||
|
||||
if not Is_Concurrent_Record_Type (Typ) then
|
||||
Find_Tag (Typ);
|
||||
pragma Assert (Found);
|
||||
return AI_Tag;
|
||||
|
||||
-- Concurrent record types
|
||||
|
||||
else
|
||||
Is_Sync_Typ := True;
|
||||
AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
|
||||
Find_Tag (Typ);
|
||||
pragma Assert (Found);
|
||||
|
||||
if Is_Primary_Tag then
|
||||
return First_Tag_Component (Typ);
|
||||
else
|
||||
return AI_Tag;
|
||||
end if;
|
||||
end if;
|
||||
end Find_Interface_Tag;
|
||||
|
||||
--------------------
|
||||
-- Find_Interface --
|
||||
--------------------
|
||||
|
||||
function Find_Interface
|
||||
(T : Entity_Id;
|
||||
Comp : Entity_Id) return Entity_Id
|
||||
is
|
||||
AI_Tag : Entity_Id;
|
||||
Found : Boolean := False;
|
||||
Iface : Entity_Id;
|
||||
Typ : Entity_Id := T;
|
||||
|
||||
Is_Sync_Typ : Boolean := False;
|
||||
-- In case of non concurrent-record-types each parent-type has the
|
||||
-- tags associated with the interface types that are not implemented
|
||||
-- by the ancestors; concurrent-record-types have their whole list of
|
||||
-- interface tags (and this case requires some special management).
|
||||
|
||||
procedure Find_Iface (Typ : Entity_Id);
|
||||
-- Internal subprogram used to recursively climb to the ancestors
|
||||
|
||||
----------------
|
||||
-- Find_Iface --
|
||||
----------------
|
||||
|
||||
procedure Find_Iface (Typ : Entity_Id) is
|
||||
AI_Elmt : Elmt_Id;
|
||||
|
||||
begin
|
||||
-- Climb to the root type
|
||||
|
||||
-- Handle synchronized interface derivations
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ) then
|
||||
declare
|
||||
Iface_List : constant List_Id := Abstract_Interface_List (Typ);
|
||||
begin
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Find_Iface (Etype (First (Iface_List)));
|
||||
end if;
|
||||
end;
|
||||
|
||||
-- Handle the common case
|
||||
|
||||
elsif Etype (Typ) /= Typ then
|
||||
pragma Assert (not Present (Full_View (Etype (Typ))));
|
||||
Find_Iface (Etype (Typ));
|
||||
end if;
|
||||
|
||||
-- Traverse the list of interfaces implemented by the type
|
||||
|
||||
if not Found
|
||||
and then Present (Abstract_Interfaces (Typ))
|
||||
and then not (Is_Empty_Elmt_List (Abstract_Interfaces (Typ)))
|
||||
then
|
||||
-- Skip the tag associated with the primary table
|
||||
|
||||
if not Is_Sync_Typ then
|
||||
pragma Assert
|
||||
(Etype (First_Tag_Component (Typ)) = RTE (RE_Tag));
|
||||
AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
|
||||
pragma Assert (Present (AI_Tag));
|
||||
end if;
|
||||
|
||||
AI_Elmt := First_Elmt (Abstract_Interfaces (Typ));
|
||||
while Present (AI_Elmt) loop
|
||||
if AI_Tag = Comp then
|
||||
Iface := Node (AI_Elmt);
|
||||
Found := True;
|
||||
return;
|
||||
end if;
|
||||
|
||||
AI_Tag := Next_Tag_Component (AI_Tag);
|
||||
Next_Elmt (AI_Elmt);
|
||||
end loop;
|
||||
end if;
|
||||
end Find_Iface;
|
||||
|
||||
-- Start of processing for Find_Interface
|
||||
|
||||
begin
|
||||
-- Handle private types
|
||||
|
||||
if Has_Private_Declaration (Typ)
|
||||
and then Present (Full_View (Typ))
|
||||
then
|
||||
Typ := Full_View (Typ);
|
||||
end if;
|
||||
|
||||
-- Handle access types
|
||||
|
||||
if Is_Access_Type (Typ) then
|
||||
Typ := Directly_Designated_Type (Typ);
|
||||
end if;
|
||||
|
||||
-- Handle task and protected types implementing interfaces
|
||||
|
||||
if Is_Concurrent_Type (Typ) then
|
||||
Typ := Corresponding_Record_Type (Typ);
|
||||
end if;
|
||||
|
||||
if Is_Class_Wide_Type (Typ) then
|
||||
Typ := Etype (Typ);
|
||||
end if;
|
||||
|
||||
-- Handle entities from the limited view
|
||||
|
||||
if Ekind (Typ) = E_Incomplete_Type then
|
||||
pragma Assert (Present (Non_Limited_View (Typ)));
|
||||
Typ := Non_Limited_View (Typ);
|
||||
end if;
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ) then
|
||||
Is_Sync_Typ := True;
|
||||
AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
|
||||
end if;
|
||||
|
||||
Find_Iface (Typ);
|
||||
Find_Tag (Typ);
|
||||
pragma Assert (Found);
|
||||
return Iface;
|
||||
end Find_Interface;
|
||||
return AI_Tag;
|
||||
end Find_Interface_Tag;
|
||||
|
||||
------------------
|
||||
-- Find_Prim_Op --
|
||||
@ -3062,55 +2842,6 @@ package body Exp_Util is
|
||||
and then Is_Library_Level_Entity (Typ);
|
||||
end Is_Library_Level_Tagged_Type;
|
||||
|
||||
-----------------------------------------
|
||||
-- Is_Predefined_Dispatching_Operation --
|
||||
-----------------------------------------
|
||||
|
||||
function Is_Predefined_Dispatching_Operation (E : Entity_Id) return Boolean
|
||||
is
|
||||
TSS_Name : TSS_Name_Type;
|
||||
|
||||
begin
|
||||
if not Is_Dispatching_Operation (E) then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
Get_Name_String (Chars (E));
|
||||
|
||||
-- Most predefined primitives have internally generated names. Equality
|
||||
-- must be treated differently; the predefined operation is recognized
|
||||
-- as a homogeneous binary operator that returns Boolean.
|
||||
|
||||
if Name_Len > TSS_Name_Type'Last then
|
||||
TSS_Name := TSS_Name_Type (Name_Buffer (Name_Len - TSS_Name'Length + 1
|
||||
.. Name_Len));
|
||||
if Chars (E) = Name_uSize
|
||||
or else Chars (E) = Name_uAlignment
|
||||
or else TSS_Name = TSS_Stream_Read
|
||||
or else TSS_Name = TSS_Stream_Write
|
||||
or else TSS_Name = TSS_Stream_Input
|
||||
or else TSS_Name = TSS_Stream_Output
|
||||
or else
|
||||
(Chars (E) = Name_Op_Eq
|
||||
and then Etype (First_Entity (E)) = Etype (Last_Entity (E)))
|
||||
or else Chars (E) = Name_uAssign
|
||||
or else TSS_Name = TSS_Deep_Adjust
|
||||
or else TSS_Name = TSS_Deep_Finalize
|
||||
or else (Ada_Version >= Ada_05
|
||||
and then (Chars (E) = Name_uDisp_Asynchronous_Select
|
||||
or else Chars (E) = Name_uDisp_Conditional_Select
|
||||
or else Chars (E) = Name_uDisp_Get_Prim_Op_Kind
|
||||
or else Chars (E) = Name_uDisp_Get_Task_Id
|
||||
or else Chars (E) = Name_uDisp_Requeue
|
||||
or else Chars (E) = Name_uDisp_Timed_Select))
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return False;
|
||||
end Is_Predefined_Dispatching_Operation;
|
||||
|
||||
----------------------------------
|
||||
-- Is_Possibly_Unaligned_Object --
|
||||
----------------------------------
|
||||
|
@ -342,13 +342,6 @@ package Exp_Util is
|
||||
-- declarations and/or allocations when the type is indefinite (including
|
||||
-- class-wide).
|
||||
|
||||
function Find_Interface
|
||||
(T : Entity_Id;
|
||||
Comp : Entity_Id) return Entity_Id;
|
||||
-- Ada 2005 (AI-251): Given a tagged type and one of its components
|
||||
-- associated with the secondary dispatch table of an abstract interface
|
||||
-- type, return the associated abstract interface type.
|
||||
|
||||
function Find_Interface_ADT
|
||||
(T : Entity_Id;
|
||||
Iface : Entity_Id) return Elmt_Id;
|
||||
@ -462,9 +455,6 @@ package Exp_Util is
|
||||
-- Return True if Typ is a library level tagged type. Currently we use
|
||||
-- this information to build statically allocated dispatch tables.
|
||||
|
||||
function Is_Predefined_Dispatching_Operation (E : Entity_Id) return Boolean;
|
||||
-- Ada 2005 (AI-251): Determines if E is a predefined primitive operation
|
||||
|
||||
function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean;
|
||||
-- Determine whether the node P is a reference to a bit packed array, i.e.
|
||||
-- whether the designated object is a component of a bit packed array, or a
|
||||
|
@ -30,6 +30,7 @@ with Einfo; use Einfo;
|
||||
with Elists; use Elists;
|
||||
with Errout; use Errout;
|
||||
with Exp_Ch7; use Exp_Ch7;
|
||||
with Exp_Disp; use Exp_Disp;
|
||||
with Exp_Pakd; use Exp_Pakd;
|
||||
with Exp_Util; use Exp_Util;
|
||||
with Exp_Tss; use Exp_Tss;
|
||||
|
@ -1150,16 +1150,14 @@ package body Lib.Xref is
|
||||
New_Entry (Tref);
|
||||
|
||||
if Is_Record_Type (Ent)
|
||||
and then Present (Abstract_Interfaces (Ent))
|
||||
and then Present (Interfaces (Ent))
|
||||
then
|
||||
-- Add an entry for each one of the given interfaces
|
||||
-- implemented by type Ent.
|
||||
|
||||
declare
|
||||
Elmt : Elmt_Id;
|
||||
|
||||
Elmt : Elmt_Id := First_Elmt (Interfaces (Ent));
|
||||
begin
|
||||
Elmt := First_Elmt (Abstract_Interfaces (Ent));
|
||||
while Present (Elmt) loop
|
||||
New_Entry (Node (Elmt));
|
||||
Next_Elmt (Elmt);
|
||||
@ -2032,13 +2030,11 @@ package body Lib.Xref is
|
||||
-- Additional information for types with progenitors
|
||||
|
||||
if Is_Record_Type (XE.Ent)
|
||||
and then Present (Abstract_Interfaces (XE.Ent))
|
||||
and then Present (Interfaces (XE.Ent))
|
||||
then
|
||||
declare
|
||||
Elmt : Elmt_Id;
|
||||
|
||||
Elmt : Elmt_Id := First_Elmt (Interfaces (XE.Ent));
|
||||
begin
|
||||
Elmt := First_Elmt (Abstract_Interfaces (XE.Ent));
|
||||
while Present (Elmt) loop
|
||||
Check_Type_Reference (Node (Elmt), True);
|
||||
Next_Elmt (Elmt);
|
||||
|
@ -28,7 +28,7 @@ with Debug; use Debug;
|
||||
with Einfo; use Einfo;
|
||||
with Elists; use Elists;
|
||||
with Errout; use Errout;
|
||||
with Exp_Util; use Exp_Util;
|
||||
with Exp_Disp; use Exp_Disp;
|
||||
with Fname; use Fname;
|
||||
with Lib; use Lib;
|
||||
with Namet; use Namet;
|
||||
|
@ -9268,7 +9268,7 @@ package body Sem_Ch12 is
|
||||
-- Now verify that the actual includes all other ancestors of
|
||||
-- the formal.
|
||||
|
||||
Elmt := First_Elmt (Abstract_Interfaces (A_Gen_T));
|
||||
Elmt := First_Elmt (Interfaces (A_Gen_T));
|
||||
while Present (Elmt) loop
|
||||
if not Interface_Present_In_Ancestor
|
||||
(Act_T, Get_Instance_Of (Node (Elmt)))
|
||||
@ -9575,7 +9575,6 @@ package body Sem_Ch12 is
|
||||
|
||||
function Is_Tagged_Ancestor (T1, T2 : Entity_Id) return Boolean
|
||||
is
|
||||
Interfaces : Elist_Id;
|
||||
Intfc_Elmt : Elmt_Id;
|
||||
|
||||
begin
|
||||
@ -9599,9 +9598,7 @@ package body Sem_Ch12 is
|
||||
-- progenitors.
|
||||
|
||||
else
|
||||
Interfaces := Abstract_Interfaces (T2);
|
||||
|
||||
Intfc_Elmt := First_Elmt (Interfaces);
|
||||
Intfc_Elmt := First_Elmt (Interfaces (T2));
|
||||
while Present (Intfc_Elmt) loop
|
||||
if Is_Ancestor (T1, Node (Intfc_Elmt)) then
|
||||
return True;
|
||||
|
1459
gcc/ada/sem_ch3.adb
1459
gcc/ada/sem_ch3.adb
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
with Nlists; use Nlists;
|
||||
with Types; use Types;
|
||||
|
||||
package Sem_Ch3 is
|
||||
package Sem_Ch3 is
|
||||
procedure Analyze_Component_Declaration (N : Node_Id);
|
||||
procedure Analyze_Incomplete_Type_Decl (N : Node_Id);
|
||||
procedure Analyze_Itype_Reference (N : Node_Id);
|
||||
|
@ -3525,7 +3525,6 @@ package body Sem_Ch4 is
|
||||
Error_Msg_NE ("no selector& for}", N, Sel);
|
||||
|
||||
Check_Misspelled_Selector (Type_To_Use, Sel);
|
||||
|
||||
end if;
|
||||
|
||||
Set_Entity (Sel, Any_Id);
|
||||
@ -6443,14 +6442,14 @@ package body Sem_Ch4 is
|
||||
-- primitive is also in this list of primitive operations and
|
||||
-- will be used instead.
|
||||
|
||||
if (Present (Abstract_Interface_Alias (Prim_Op))
|
||||
and then Is_Ancestor (Find_Dispatching_Type
|
||||
(Alias (Prim_Op)), Corr_Type))
|
||||
if (Present (Interface_Alias (Prim_Op))
|
||||
and then Is_Ancestor (Find_Dispatching_Type
|
||||
(Alias (Prim_Op)), Corr_Type))
|
||||
or else
|
||||
|
||||
-- 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.
|
||||
-- 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.
|
||||
|
||||
(Is_Hidden (Prim_Op)
|
||||
and then not Is_Immediately_Visible (Obj_Type)
|
||||
|
@ -33,6 +33,7 @@ with Expander; use Expander;
|
||||
with Exp_Ch6; use Exp_Ch6;
|
||||
with Exp_Ch7; use Exp_Ch7;
|
||||
with Exp_Ch9; use Exp_Ch9;
|
||||
with Exp_Disp; use Exp_Disp;
|
||||
with Exp_Tss; use Exp_Tss;
|
||||
with Exp_Util; use Exp_Util;
|
||||
with Fname; use Fname;
|
||||
@ -1827,7 +1828,7 @@ package body Sem_Ch6 is
|
||||
and then Ekind (Etype (First_Entity (Spec_Id))) = E_Record_Type
|
||||
and then Is_Tagged_Type (Etype (First_Entity (Spec_Id)))
|
||||
and then
|
||||
Present (Abstract_Interfaces (Etype (First_Entity (Spec_Id))))
|
||||
Present (Interfaces (Etype (First_Entity (Spec_Id))))
|
||||
and then
|
||||
Present
|
||||
(Corresponding_Concurrent_Type
|
||||
@ -2471,8 +2472,8 @@ package body Sem_Ch6 is
|
||||
if (Ekind (Formal_Typ) = E_Protected_Type
|
||||
or else Ekind (Formal_Typ) = E_Task_Type)
|
||||
and then Present (Corresponding_Record_Type (Formal_Typ))
|
||||
and then Present (Abstract_Interfaces
|
||||
(Corresponding_Record_Type (Formal_Typ)))
|
||||
and then Present (Interfaces
|
||||
(Corresponding_Record_Type (Formal_Typ)))
|
||||
then
|
||||
Set_Etype (Formal,
|
||||
Corresponding_Record_Type (Formal_Typ));
|
||||
@ -3506,18 +3507,9 @@ package body Sem_Ch6 is
|
||||
-----------------------
|
||||
|
||||
procedure Check_Conventions (Typ : Entity_Id) is
|
||||
Ifaces_List : Elist_Id;
|
||||
|
||||
function Skip_Check (Op : Entity_Id) return Boolean;
|
||||
pragma Inline (Skip_Check);
|
||||
-- A small optimization: skip the predefined dispatching operations,
|
||||
-- since they always have the same convention. Also do not consider
|
||||
-- abstract primitives since those are left by an erroneous overriding.
|
||||
-- This function returns True for any operation that is thus exempted
|
||||
-- exempted from checking.
|
||||
|
||||
procedure Check_Convention
|
||||
(Op : Entity_Id;
|
||||
Search_From : Elmt_Id);
|
||||
procedure Check_Convention (Op : Entity_Id);
|
||||
-- Verify that the convention of inherited dispatching operation Op is
|
||||
-- consistent among all subprograms it overrides. In order to minimize
|
||||
-- the search, Search_From is utilized to designate a specific point in
|
||||
@ -3527,89 +3519,62 @@ package body Sem_Ch6 is
|
||||
-- Check_Convention --
|
||||
----------------------
|
||||
|
||||
procedure Check_Convention
|
||||
(Op : Entity_Id;
|
||||
Search_From : Elmt_Id)
|
||||
is
|
||||
procedure Error_Msg_Operation (Op : Entity_Id);
|
||||
-- Emit a continuation to an error message depicting the kind, name,
|
||||
-- convention and source location of subprogram Op.
|
||||
procedure Check_Convention (Op : Entity_Id) is
|
||||
Iface_Elmt : Elmt_Id;
|
||||
Iface_Prim_Elmt : Elmt_Id;
|
||||
Iface_Prim : Entity_Id;
|
||||
|
||||
-------------------------
|
||||
-- Error_Msg_Operation --
|
||||
-------------------------
|
||||
begin
|
||||
Iface_Elmt := First_Elmt (Ifaces_List);
|
||||
while Present (Iface_Elmt) loop
|
||||
Iface_Prim_Elmt :=
|
||||
First_Elmt (Primitive_Operations (Node (Iface_Elmt)));
|
||||
while Present (Iface_Prim_Elmt) loop
|
||||
Iface_Prim := Node (Iface_Prim_Elmt);
|
||||
|
||||
procedure Error_Msg_Operation (Op : Entity_Id) is
|
||||
begin
|
||||
Error_Msg_Name_1 := Chars (Op);
|
||||
if Is_Interface_Conformant (Typ, Iface_Prim, Op)
|
||||
and then Convention (Iface_Prim) /= Convention (Op)
|
||||
then
|
||||
Error_Msg_N
|
||||
("inconsistent conventions in primitive operations", Typ);
|
||||
|
||||
-- Error messages of primitive subprograms do not contain a
|
||||
-- convention attribute since the convention may have been first
|
||||
-- inherited from a parent subprogram, then changed by a pragma.
|
||||
Error_Msg_Name_1 := Chars (Op);
|
||||
Error_Msg_Name_2 := Get_Convention_Name (Convention (Op));
|
||||
Error_Msg_Sloc := Sloc (Op);
|
||||
|
||||
if Comes_From_Source (Op) then
|
||||
Error_Msg_Sloc := Sloc (Op);
|
||||
Error_Msg_N
|
||||
("\ primitive % defined #", Typ);
|
||||
if Comes_From_Source (Op) then
|
||||
if not Is_Overriding_Operation (Op) then
|
||||
Error_Msg_N ("\\primitive % defined #", Typ);
|
||||
else
|
||||
Error_Msg_N ("\\overridding operation % with " &
|
||||
"convention % defined #", Typ);
|
||||
end if;
|
||||
|
||||
else
|
||||
Error_Msg_Name_2 := Get_Convention_Name (Convention (Op));
|
||||
else pragma Assert (Present (Alias (Op)));
|
||||
Error_Msg_Sloc := Sloc (Alias (Op));
|
||||
Error_Msg_N ("\\inherited operation % with " &
|
||||
"convention % defined #", Typ);
|
||||
end if;
|
||||
|
||||
if Present (Abstract_Interface_Alias (Op)) then
|
||||
Error_Msg_Sloc := Sloc (Abstract_Interface_Alias (Op));
|
||||
Error_Msg_Name_1 := Chars (Op);
|
||||
Error_Msg_Name_2 :=
|
||||
Get_Convention_Name (Convention (Iface_Prim));
|
||||
Error_Msg_Sloc := Sloc (Iface_Prim);
|
||||
Error_Msg_N ("\\overridden operation % with " &
|
||||
"convention % defined #", Typ);
|
||||
|
||||
else pragma Assert (Present (Alias (Op)));
|
||||
Error_Msg_Sloc := Sloc (Alias (Op));
|
||||
Error_Msg_N ("\\inherited operation % with " &
|
||||
"convention % defined #", Typ);
|
||||
-- Avoid cascading errors
|
||||
|
||||
return;
|
||||
end if;
|
||||
end if;
|
||||
end Error_Msg_Operation;
|
||||
|
||||
-- Local variables
|
||||
Next_Elmt (Iface_Prim_Elmt);
|
||||
end loop;
|
||||
|
||||
Second_Prim_Op : Entity_Id;
|
||||
Second_Prim_Op_Elmt : Elmt_Id;
|
||||
|
||||
-- Start of processing for Check_Convention
|
||||
|
||||
begin
|
||||
Second_Prim_Op_Elmt := Next_Elmt (Search_From);
|
||||
while Present (Second_Prim_Op_Elmt) loop
|
||||
Second_Prim_Op := Node (Second_Prim_Op_Elmt);
|
||||
|
||||
if not Skip_Check (Second_Prim_Op)
|
||||
and then Chars (Second_Prim_Op) = Chars (Op)
|
||||
and then Type_Conformant (Second_Prim_Op, Op)
|
||||
and then Convention (Second_Prim_Op) /= Convention (Op)
|
||||
then
|
||||
Error_Msg_N
|
||||
("inconsistent conventions in primitive operations", Typ);
|
||||
|
||||
Error_Msg_Operation (Op);
|
||||
Error_Msg_Operation (Second_Prim_Op);
|
||||
|
||||
-- Avoid cascading errors
|
||||
|
||||
return;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Second_Prim_Op_Elmt);
|
||||
Next_Elmt (Iface_Elmt);
|
||||
end loop;
|
||||
end Check_Convention;
|
||||
|
||||
----------------
|
||||
-- Skip_Check --
|
||||
----------------
|
||||
|
||||
function Skip_Check (Op : Entity_Id) return Boolean is
|
||||
begin
|
||||
return Is_Predefined_Dispatching_Operation (Op)
|
||||
or else Is_Abstract_Subprogram (Op);
|
||||
end Skip_Check;
|
||||
|
||||
-- Local variables
|
||||
|
||||
Prim_Op : Entity_Id;
|
||||
@ -3618,6 +3583,12 @@ package body Sem_Ch6 is
|
||||
-- Start of processing for Check_Conventions
|
||||
|
||||
begin
|
||||
if not Has_Interfaces (Typ) then
|
||||
return;
|
||||
end if;
|
||||
|
||||
Collect_Interfaces (Typ, Ifaces_List);
|
||||
|
||||
-- The algorithm checks every overriding dispatching operation against
|
||||
-- all the corresponding overridden dispatching operations, detecting
|
||||
-- differences in conventions.
|
||||
@ -3627,13 +3598,10 @@ package body Sem_Ch6 is
|
||||
Prim_Op := Node (Prim_Op_Elmt);
|
||||
|
||||
-- A small optimization: skip the predefined dispatching operations
|
||||
-- since they always have the same convention. Also avoid processing
|
||||
-- of abstract primitives left from an erroneous overriding.
|
||||
-- since they always have the same convention.
|
||||
|
||||
if not Skip_Check (Prim_Op) then
|
||||
Check_Convention
|
||||
(Op => Prim_Op,
|
||||
Search_From => Prim_Op_Elmt);
|
||||
if not Is_Predefined_Dispatching_Operation (Prim_Op) then
|
||||
Check_Convention (Prim_Op);
|
||||
end if;
|
||||
|
||||
Next_Elmt (Prim_Op_Elmt);
|
||||
@ -4497,15 +4465,17 @@ package body Sem_Ch6 is
|
||||
------------------------------
|
||||
|
||||
procedure Check_Subtype_Conformant
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Err_Loc : Node_Id := Empty)
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Err_Loc : Node_Id := Empty;
|
||||
Skip_Controlling_Formals : Boolean := False)
|
||||
is
|
||||
Result : Boolean;
|
||||
pragma Warnings (Off, Result);
|
||||
begin
|
||||
Check_Conformance
|
||||
(New_Id, Old_Id, Subtype_Conformant, True, Result, Err_Loc);
|
||||
(New_Id, Old_Id, Subtype_Conformant, True, Result, Err_Loc,
|
||||
Skip_Controlling_Formals => Skip_Controlling_Formals);
|
||||
end Check_Subtype_Conformant;
|
||||
|
||||
---------------------------
|
||||
@ -5795,6 +5765,76 @@ package body Sem_Ch6 is
|
||||
end loop;
|
||||
end Install_Formals;
|
||||
|
||||
-----------------------------
|
||||
-- Is_Interface_Conformant --
|
||||
-----------------------------
|
||||
|
||||
function Is_Interface_Conformant
|
||||
(Tagged_Type : Entity_Id;
|
||||
Iface_Prim : Entity_Id;
|
||||
Prim : Entity_Id) return Boolean
|
||||
is
|
||||
begin
|
||||
pragma Assert (Is_Subprogram (Iface_Prim)
|
||||
and then Is_Subprogram (Prim)
|
||||
and then Is_Dispatching_Operation (Iface_Prim)
|
||||
and then Is_Dispatching_Operation (Prim));
|
||||
|
||||
pragma Assert (Is_Interface (Find_Dispatching_Type (Iface_Prim))
|
||||
or else (Present (Alias (Iface_Prim))
|
||||
and then
|
||||
Is_Interface
|
||||
(Find_Dispatching_Type (Ultimate_Alias (Iface_Prim)))));
|
||||
|
||||
if Prim = Iface_Prim
|
||||
or else not Is_Subprogram (Prim)
|
||||
or else Ekind (Prim) /= Ekind (Iface_Prim)
|
||||
or else not Is_Dispatching_Operation (Prim)
|
||||
or else Scope (Prim) /= Scope (Tagged_Type)
|
||||
or else No (Find_Dispatching_Type (Prim))
|
||||
or else Base_Type (Find_Dispatching_Type (Prim)) /= Tagged_Type
|
||||
or else not Primitive_Names_Match (Iface_Prim, Prim)
|
||||
then
|
||||
return False;
|
||||
|
||||
-- Case of a procedure, or a function not returning an interface
|
||||
|
||||
elsif Ekind (Iface_Prim) = E_Procedure
|
||||
or else Etype (Prim) = Etype (Iface_Prim)
|
||||
or else not Is_Interface (Etype (Iface_Prim))
|
||||
then
|
||||
return Type_Conformant (Prim, Iface_Prim,
|
||||
Skip_Controlling_Formals => True);
|
||||
|
||||
-- Case of a function returning an interface
|
||||
|
||||
elsif Implements_Interface (Etype (Prim), Etype (Iface_Prim)) then
|
||||
declare
|
||||
Ret_Typ : constant Entity_Id := Etype (Prim);
|
||||
Is_Conformant : Boolean;
|
||||
|
||||
begin
|
||||
-- Temporarly set both entities returning exactly the same type to
|
||||
-- be able to call Type_Conformant (because that routine has no
|
||||
-- machinery to handle interfaces).
|
||||
|
||||
Set_Etype (Prim, Etype (Iface_Prim));
|
||||
|
||||
Is_Conformant :=
|
||||
Type_Conformant (Prim, Iface_Prim,
|
||||
Skip_Controlling_Formals => True);
|
||||
|
||||
-- Restore proper decoration of returned type
|
||||
|
||||
Set_Etype (Prim, Ret_Typ);
|
||||
|
||||
return Is_Conformant;
|
||||
end;
|
||||
end if;
|
||||
|
||||
return False;
|
||||
end Is_Interface_Conformant;
|
||||
|
||||
---------------------------------
|
||||
-- Is_Non_Overriding_Operation --
|
||||
---------------------------------
|
||||
@ -6422,7 +6462,7 @@ package body Sem_Ch6 is
|
||||
N_Task_Type_Declaration,
|
||||
N_Protected_Type_Declaration)
|
||||
then
|
||||
Collect_Abstract_Interfaces (Typ, Ifaces_List);
|
||||
Collect_Interfaces (Typ, Ifaces_List);
|
||||
|
||||
if not Is_Empty_Elmt_List (Ifaces_List) then
|
||||
Overridden_Subp :=
|
||||
@ -6555,7 +6595,6 @@ package body Sem_Ch6 is
|
||||
and then Is_Dispatching_Operation (Alias (S))
|
||||
and then Present (Find_Dispatching_Type (Alias (S)))
|
||||
and then Is_Interface (Find_Dispatching_Type (Alias (S)))
|
||||
and then not Is_Predefined_Dispatching_Operation (Alias (S))
|
||||
then
|
||||
goto Add_New_Entity;
|
||||
end if;
|
||||
@ -7669,10 +7708,15 @@ package body Sem_Ch6 is
|
||||
-- Subtype_Conformant --
|
||||
------------------------
|
||||
|
||||
function Subtype_Conformant (New_Id, Old_Id : Entity_Id) return Boolean is
|
||||
function Subtype_Conformant
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Skip_Controlling_Formals : Boolean := False) return Boolean
|
||||
is
|
||||
Result : Boolean;
|
||||
begin
|
||||
Check_Conformance (New_Id, Old_Id, Subtype_Conformant, False, Result);
|
||||
Check_Conformance (New_Id, Old_Id, Subtype_Conformant, False, Result,
|
||||
Skip_Controlling_Formals => Skip_Controlling_Formals);
|
||||
return Result;
|
||||
end Subtype_Conformant;
|
||||
|
||||
|
@ -111,9 +111,10 @@ package Sem_Ch6 is
|
||||
-- Is_Primitive indicates whether the subprogram is primitive.
|
||||
|
||||
procedure Check_Subtype_Conformant
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Err_Loc : Node_Id := Empty);
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Err_Loc : Node_Id := Empty;
|
||||
Skip_Controlling_Formals : Boolean := False);
|
||||
-- Check that two callable entities (subprograms, entries, literals)
|
||||
-- are subtype conformant, post error message if not (RM 6.3.1(16))
|
||||
-- the flag being placed on the Err_Loc node if it is specified, and
|
||||
@ -173,6 +174,14 @@ package Sem_Ch6 is
|
||||
-- procedure is also used to get visibility to the formals when analyzing
|
||||
-- preconditions and postconditions appearing in the spec.
|
||||
|
||||
function Is_Interface_Conformant
|
||||
(Tagged_Type : Entity_Id;
|
||||
Iface_Prim : Entity_Id;
|
||||
Prim : Entity_Id) return Boolean;
|
||||
-- Returns true if both primitives have a matching name and they are also
|
||||
-- type conformant. Special management is done for functions returning
|
||||
-- interfaces.
|
||||
|
||||
function Mode_Conformant (New_Id, Old_Id : Entity_Id) return Boolean;
|
||||
-- Determine whether two callable entities (subprograms, entries,
|
||||
-- literals) are mode conformant (RM 6.3.1(15))
|
||||
@ -212,7 +221,10 @@ package Sem_Ch6 is
|
||||
procedure Set_Formal_Mode (Formal_Id : Entity_Id);
|
||||
-- Set proper Ekind to reflect formal mode (in, out, in out)
|
||||
|
||||
function Subtype_Conformant (New_Id, Old_Id : Entity_Id) return Boolean;
|
||||
function Subtype_Conformant
|
||||
(New_Id : Entity_Id;
|
||||
Old_Id : Entity_Id;
|
||||
Skip_Controlling_Formals : Boolean := False) return Boolean;
|
||||
-- Determine whether two callable entities (subprograms, entries,
|
||||
-- literals) are subtype conformant (RM6.3.1(16)).
|
||||
|
||||
|
@ -2417,16 +2417,16 @@ package body Sem_Ch9 is
|
||||
|
||||
if Present (Interface_List (N))
|
||||
or else (Is_Tagged_Type (Priv_T)
|
||||
and then Has_Abstract_Interfaces
|
||||
(Priv_T, Use_Full_View => False))
|
||||
and then Has_Interfaces
|
||||
(Priv_T, Use_Full_View => False))
|
||||
then
|
||||
if Is_Tagged_Type (Priv_T) then
|
||||
Collect_Abstract_Interfaces
|
||||
Collect_Interfaces
|
||||
(Priv_T, Priv_T_Ifaces, Use_Full_View => False);
|
||||
end if;
|
||||
|
||||
if Is_Tagged_Type (T) then
|
||||
Collect_Abstract_Interfaces (T, Full_T_Ifaces);
|
||||
Collect_Interfaces (T, Full_T_Ifaces);
|
||||
end if;
|
||||
|
||||
Iface := Find_Hidden_Interface (Priv_T_Ifaces, Full_T_Ifaces);
|
||||
|
@ -618,6 +618,19 @@ package body Sem_Disp is
|
||||
Tagged_Type := Corresponding_Record_Type (Tagged_Type);
|
||||
end if;
|
||||
|
||||
-- (AI-345): The task body procedure is not a primitive of the tagged
|
||||
-- type
|
||||
|
||||
if Present (Tagged_Type)
|
||||
and then Is_Concurrent_Record_Type (Tagged_Type)
|
||||
and then Present (Corresponding_Concurrent_Type (Tagged_Type))
|
||||
and then Is_Task_Type (Corresponding_Concurrent_Type (Tagged_Type))
|
||||
and then Subp = Get_Task_Body_Procedure
|
||||
(Corresponding_Concurrent_Type (Tagged_Type))
|
||||
then
|
||||
return;
|
||||
end if;
|
||||
|
||||
-- If Subp is derived from a dispatching operation then it should
|
||||
-- always be treated as dispatching. In this case various checks
|
||||
-- below will be bypassed. Makes sure that late declarations for
|
||||
@ -870,6 +883,10 @@ package body Sem_Disp is
|
||||
-- Now it should be a correct primitive operation, put it in the list
|
||||
|
||||
if Present (Old_Subp) then
|
||||
|
||||
-- If the type has interfaces we complete this check after we
|
||||
-- set attribute Is_Dispatching_Operation
|
||||
|
||||
Check_Subtype_Conformant (Subp, Old_Subp);
|
||||
|
||||
if (Chars (Subp) = Name_Initialize
|
||||
@ -902,7 +919,7 @@ package body Sem_Disp is
|
||||
Prim := Node (Elmt);
|
||||
|
||||
if Present (Alias (Prim))
|
||||
and then Present (Abstract_Interface_Alias (Prim))
|
||||
and then Present (Interface_Alias (Prim))
|
||||
and then Alias (Prim) = Subp
|
||||
then
|
||||
Register_Primitive (Sloc (Prim),
|
||||
@ -933,6 +950,78 @@ package body Sem_Disp is
|
||||
|
||||
Set_Is_Dispatching_Operation (Subp, True);
|
||||
|
||||
-- Ada 2005 (AI-251): If the type implements interfaces we must check
|
||||
-- subtype conformance against all the interfaces covered by this
|
||||
-- primitive.
|
||||
|
||||
if Present (Old_Subp)
|
||||
and then Has_Interfaces (Tagged_Type)
|
||||
then
|
||||
declare
|
||||
Ifaces_List : Elist_Id;
|
||||
Iface_Elmt : Elmt_Id;
|
||||
Iface_Prim_Elmt : Elmt_Id;
|
||||
Iface_Prim : Entity_Id;
|
||||
Ret_Typ : Entity_Id;
|
||||
|
||||
begin
|
||||
Collect_Interfaces (Tagged_Type, Ifaces_List);
|
||||
|
||||
Iface_Elmt := First_Elmt (Ifaces_List);
|
||||
while Present (Iface_Elmt) loop
|
||||
if not Is_Ancestor (Node (Iface_Elmt), Tagged_Type) then
|
||||
Iface_Prim_Elmt :=
|
||||
First_Elmt (Primitive_Operations (Node (Iface_Elmt)));
|
||||
while Present (Iface_Prim_Elmt) loop
|
||||
Iface_Prim := Node (Iface_Prim_Elmt);
|
||||
|
||||
if Is_Interface_Conformant
|
||||
(Tagged_Type, Iface_Prim, Subp)
|
||||
then
|
||||
-- Handle procedures, functions whose return type
|
||||
-- matches, or functions not returning interfaces
|
||||
|
||||
if Ekind (Subp) = E_Procedure
|
||||
or else Etype (Iface_Prim) = Etype (Subp)
|
||||
or else not Is_Interface (Etype (Iface_Prim))
|
||||
then
|
||||
Check_Subtype_Conformant
|
||||
(New_Id => Subp,
|
||||
Old_Id => Iface_Prim,
|
||||
Err_Loc => Subp,
|
||||
Skip_Controlling_Formals => True);
|
||||
|
||||
-- Handle functions returning interfaces
|
||||
|
||||
elsif Implements_Interface
|
||||
(Etype (Subp), Etype (Iface_Prim))
|
||||
then
|
||||
-- Temporarily force both entities to return the
|
||||
-- same type. Required because Subtype_Conformant
|
||||
-- does not handle this case.
|
||||
|
||||
Ret_Typ := Etype (Iface_Prim);
|
||||
Set_Etype (Iface_Prim, Etype (Subp));
|
||||
|
||||
Check_Subtype_Conformant
|
||||
(New_Id => Subp,
|
||||
Old_Id => Iface_Prim,
|
||||
Err_Loc => Subp,
|
||||
Skip_Controlling_Formals => True);
|
||||
|
||||
Set_Etype (Iface_Prim, Ret_Typ);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Iface_Prim_Elmt);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Iface_Elmt);
|
||||
end loop;
|
||||
end;
|
||||
end if;
|
||||
|
||||
if not Body_Is_Last_Primitive then
|
||||
Set_DT_Position (Subp, No_Uint);
|
||||
|
||||
@ -1083,7 +1172,13 @@ package body Sem_Disp is
|
||||
if Derives_From (Node (Op1)) then
|
||||
|
||||
if No (Prev) then
|
||||
Prepend_Elmt (Subp, New_Prim);
|
||||
|
||||
-- Avoid adding it to the list of primitives if already there!
|
||||
|
||||
if Node (Op2) /= Subp then
|
||||
Prepend_Elmt (Subp, New_Prim);
|
||||
end if;
|
||||
|
||||
else
|
||||
Insert_Elmt_After (Subp, Prev);
|
||||
end if;
|
||||
@ -1302,6 +1397,38 @@ package body Sem_Disp is
|
||||
return Empty;
|
||||
end Find_Dispatching_Type;
|
||||
|
||||
---------------------------------------
|
||||
-- Find_Primitive_Covering_Interface --
|
||||
---------------------------------------
|
||||
|
||||
function Find_Primitive_Covering_Interface
|
||||
(Tagged_Type : Entity_Id;
|
||||
Iface_Prim : Entity_Id) return Entity_Id
|
||||
is
|
||||
E : Entity_Id;
|
||||
|
||||
begin
|
||||
pragma Assert (Is_Interface (Find_Dispatching_Type (Iface_Prim))
|
||||
or else (Present (Alias (Iface_Prim))
|
||||
and then
|
||||
Is_Interface
|
||||
(Find_Dispatching_Type (Ultimate_Alias (Iface_Prim)))));
|
||||
|
||||
E := Current_Entity (Iface_Prim);
|
||||
while Present (E) loop
|
||||
if Is_Subprogram (E)
|
||||
and then Is_Dispatching_Operation (E)
|
||||
and then Is_Interface_Conformant (Tagged_Type, Iface_Prim, E)
|
||||
then
|
||||
return E;
|
||||
end if;
|
||||
|
||||
E := Homonym (E);
|
||||
end loop;
|
||||
|
||||
return Empty;
|
||||
end Find_Primitive_Covering_Interface;
|
||||
|
||||
---------------------------
|
||||
-- Is_Dynamically_Tagged --
|
||||
---------------------------
|
||||
@ -1425,7 +1552,7 @@ package body Sem_Disp is
|
||||
Replace_Elmt (Elmt, New_Op);
|
||||
|
||||
if Ada_Version >= Ada_05
|
||||
and then Has_Abstract_Interfaces (Tagged_Type)
|
||||
and then Has_Interfaces (Tagged_Type)
|
||||
then
|
||||
-- Ada 2005 (AI-251): Update the attribute alias of all the aliased
|
||||
-- entities of the overridden primitive to reference New_Op, and also
|
||||
@ -1434,6 +1561,8 @@ package body Sem_Disp is
|
||||
-- operations that it implements (for operations inherited from the
|
||||
-- parent itself, this check is made when building the derived type).
|
||||
|
||||
-- Note: This code is only executed in case of late overriding
|
||||
|
||||
Elmt := First_Elmt (Primitive_Operations (Tagged_Type));
|
||||
while Present (Elmt) loop
|
||||
Prim := Node (Elmt);
|
||||
@ -1445,14 +1574,14 @@ package body Sem_Disp is
|
||||
-- reading attributes in entities that are not yet fully decorated
|
||||
|
||||
elsif Is_Subprogram (Prim)
|
||||
and then Present (Abstract_Interface_Alias (Prim))
|
||||
and then Present (Interface_Alias (Prim))
|
||||
and then Alias (Prim) = Prev_Op
|
||||
and then Present (Etype (New_Op))
|
||||
then
|
||||
Set_Alias (Prim, New_Op);
|
||||
Check_Subtype_Conformant (New_Op, Prim);
|
||||
Set_Is_Abstract_Subprogram
|
||||
(Prim, Is_Abstract_Subprogram (New_Op));
|
||||
Set_Is_Abstract_Subprogram (Prim,
|
||||
Is_Abstract_Subprogram (New_Op));
|
||||
|
||||
-- Ensure that this entity will be expanded to fill the
|
||||
-- corresponding entry in its dispatch table.
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- --
|
||||
-- S p e c --
|
||||
-- --
|
||||
-- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
|
||||
-- Copyright (C) 1992-2008, 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- --
|
||||
@ -69,6 +69,14 @@ package Sem_Disp is
|
||||
-- Check whether a subprogram is dispatching, and find the tagged
|
||||
-- type of the controlling argument or arguments.
|
||||
|
||||
function Find_Primitive_Covering_Interface
|
||||
(Tagged_Type : Entity_Id;
|
||||
Iface_Prim : Entity_Id) return Entity_Id;
|
||||
-- Search in the homonym chain for the primitive of Tagged_Type that
|
||||
-- covers Iface_Prim. The homonym chain traversal is required to catch
|
||||
-- primitives associated with the partial view of private types when
|
||||
-- processing the corresponding full view.
|
||||
|
||||
function Is_Dynamically_Tagged (N : Node_Id) return Boolean;
|
||||
-- Used to determine whether a call is dispatching, i.e. if is an
|
||||
-- an expression of a class_Wide type, or a call to a function with
|
||||
|
@ -421,7 +421,7 @@ package body Sem_Type is
|
||||
|
||||
elsif Is_Hidden (E)
|
||||
and then Is_Subprogram (E)
|
||||
and then Present (Abstract_Interface_Alias (E))
|
||||
and then Present (Interface_Alias (E))
|
||||
then
|
||||
-- Ada 2005 (AI-251): If this primitive operation corresponds with
|
||||
-- an immediate ancestor interface there is no need to add it to the
|
||||
@ -431,10 +431,10 @@ package body Sem_Type is
|
||||
-- subprograms which are in fact the same.
|
||||
|
||||
if not Is_Ancestor
|
||||
(Find_Dispatching_Type (Abstract_Interface_Alias (E)),
|
||||
(Find_Dispatching_Type (Interface_Alias (E)),
|
||||
Find_Dispatching_Type (E))
|
||||
then
|
||||
Add_One_Interp (N, Abstract_Interface_Alias (E), T);
|
||||
Add_One_Interp (N, Interface_Alias (E), T);
|
||||
end if;
|
||||
|
||||
return;
|
||||
@ -783,7 +783,7 @@ package body Sem_Type is
|
||||
|
||||
-- Literals are compatible with types in a given "class"
|
||||
|
||||
elsif (T2 = Universal_Integer and then Is_Integer_Type (T1))
|
||||
elsif (T2 = Universal_Integer and then Is_Integer_Type (T1))
|
||||
or else (T2 = Universal_Real and then Is_Real_Type (T1))
|
||||
or else (T2 = Universal_Fixed and then Is_Fixed_Point_Type (T1))
|
||||
or else (T2 = Any_Fixed and then Is_Fixed_Point_Type (T1))
|
||||
@ -849,9 +849,9 @@ package body Sem_Type is
|
||||
-- Note: test for presence of E is defense against previous error.
|
||||
|
||||
if Present (E)
|
||||
and then Present (Abstract_Interfaces (E))
|
||||
and then Present (Interfaces (E))
|
||||
then
|
||||
Elmt := First_Elmt (Abstract_Interfaces (E));
|
||||
Elmt := First_Elmt (Interfaces (E));
|
||||
while Present (Elmt) loop
|
||||
if Is_Ancestor (Etype (T1), Node (Elmt)) then
|
||||
return True;
|
||||
@ -1032,7 +1032,7 @@ package body Sem_Type is
|
||||
return True;
|
||||
|
||||
elsif Is_Type (T1)
|
||||
and then Is_Generic_Actual_Type (T1)
|
||||
and then Is_Generic_Actual_Type (T1)
|
||||
and then Full_View_Covers (T2, T1)
|
||||
then
|
||||
return True;
|
||||
@ -2251,11 +2251,11 @@ package body Sem_Type is
|
||||
end if;
|
||||
|
||||
loop
|
||||
if Present (Abstract_Interfaces (E))
|
||||
and then Present (Abstract_Interfaces (E))
|
||||
and then not Is_Empty_Elmt_List (Abstract_Interfaces (E))
|
||||
if Present (Interfaces (E))
|
||||
and then Present (Interfaces (E))
|
||||
and then not Is_Empty_Elmt_List (Interfaces (E))
|
||||
then
|
||||
Elmt := First_Elmt (Abstract_Interfaces (E));
|
||||
Elmt := First_Elmt (Interfaces (E));
|
||||
while Present (Elmt) loop
|
||||
AI := Node (Elmt);
|
||||
|
||||
@ -2334,7 +2334,7 @@ package body Sem_Type is
|
||||
if Etype (AI) = Iface_Typ then
|
||||
return True;
|
||||
|
||||
elsif Present (Abstract_Interfaces (Etype (AI)))
|
||||
elsif Present (Interfaces (Etype (AI)))
|
||||
and then Iface_Present_In_Ancestor (Etype (AI))
|
||||
then
|
||||
return True;
|
||||
|
@ -29,6 +29,7 @@ with Checks; use Checks;
|
||||
with Debug; use Debug;
|
||||
with Errout; use Errout;
|
||||
with Elists; use Elists;
|
||||
with Exp_Disp; use Exp_Disp;
|
||||
with Exp_Tss; use Exp_Tss;
|
||||
with Exp_Util; use Exp_Util;
|
||||
with Fname; use Fname;
|
||||
@ -1235,48 +1236,20 @@ package body Sem_Util is
|
||||
end if;
|
||||
end Check_VMS;
|
||||
|
||||
---------------------------------
|
||||
-- Collect_Abstract_Interfaces --
|
||||
---------------------------------
|
||||
------------------------
|
||||
-- Collect_Interfaces --
|
||||
------------------------
|
||||
|
||||
procedure Collect_Abstract_Interfaces
|
||||
(T : Entity_Id;
|
||||
Ifaces_List : out Elist_Id;
|
||||
Exclude_Parent_Interfaces : Boolean := False;
|
||||
Use_Full_View : Boolean := True)
|
||||
procedure Collect_Interfaces
|
||||
(T : Entity_Id;
|
||||
Ifaces_List : out Elist_Id;
|
||||
Exclude_Parents : Boolean := False;
|
||||
Use_Full_View : Boolean := True)
|
||||
is
|
||||
procedure Add_Interface (Iface : Entity_Id);
|
||||
-- Add the interface it if is not already in the list
|
||||
|
||||
procedure Collect (Typ : Entity_Id);
|
||||
-- Subsidiary subprogram used to traverse the whole list
|
||||
-- of directly and indirectly implemented interfaces
|
||||
|
||||
function Interface_Present_In_Parent
|
||||
(Typ : Entity_Id;
|
||||
Iface : Entity_Id) return Boolean;
|
||||
-- Typ must be a tagged record type/subtype and Iface must be an
|
||||
-- abstract interface type. This function is used to check if Typ
|
||||
-- or some parent of Typ implements Iface.
|
||||
|
||||
-------------------
|
||||
-- Add_Interface --
|
||||
-------------------
|
||||
|
||||
procedure Add_Interface (Iface : Entity_Id) is
|
||||
Elmt : Elmt_Id;
|
||||
|
||||
begin
|
||||
Elmt := First_Elmt (Ifaces_List);
|
||||
while Present (Elmt) and then Node (Elmt) /= Iface loop
|
||||
Next_Elmt (Elmt);
|
||||
end loop;
|
||||
|
||||
if No (Elmt) then
|
||||
Append_Elmt (Iface, Ifaces_List);
|
||||
end if;
|
||||
end Add_Interface;
|
||||
|
||||
-------------
|
||||
-- Collect --
|
||||
-------------
|
||||
@ -1284,7 +1257,6 @@ package body Sem_Util is
|
||||
procedure Collect (Typ : Entity_Id) is
|
||||
Ancestor : Entity_Id;
|
||||
Full_T : Entity_Id;
|
||||
Iface_List : List_Id;
|
||||
Id : Node_Id;
|
||||
Iface : Entity_Id;
|
||||
|
||||
@ -1300,27 +1272,10 @@ package body Sem_Util is
|
||||
Full_T := Full_View (Typ);
|
||||
end if;
|
||||
|
||||
Iface_List := Abstract_Interface_List (Full_T);
|
||||
|
||||
-- Include the ancestor if we are generating the whole list of
|
||||
-- abstract interfaces.
|
||||
|
||||
-- In concurrent types the ancestor interface (if any) is the
|
||||
-- first element of the list of interface types.
|
||||
|
||||
if Is_Concurrent_Type (Full_T)
|
||||
or else Is_Concurrent_Record_Type (Full_T)
|
||||
then
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Ancestor := Etype (First (Iface_List));
|
||||
Collect (Ancestor);
|
||||
|
||||
if not Exclude_Parent_Interfaces then
|
||||
Add_Interface (Ancestor);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
elsif Etype (Full_T) /= Typ
|
||||
if Etype (Full_T) /= Typ
|
||||
|
||||
-- Protect the frontend against wrong sources. For example:
|
||||
|
||||
@ -1339,27 +1294,16 @@ package body Sem_Util is
|
||||
Collect (Ancestor);
|
||||
|
||||
if Is_Interface (Ancestor)
|
||||
and then not Exclude_Parent_Interfaces
|
||||
and then not Exclude_Parents
|
||||
then
|
||||
Add_Interface (Ancestor);
|
||||
Append_Unique_Elmt (Ancestor, Ifaces_List);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Traverse the graph of ancestor interfaces
|
||||
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Id := First (Iface_List);
|
||||
|
||||
-- In concurrent types the ancestor interface (if any) is the
|
||||
-- first element of the list of interface types and we have
|
||||
-- already processed them while climbing to the root type.
|
||||
|
||||
if Is_Concurrent_Type (Full_T)
|
||||
or else Is_Concurrent_Record_Type (Full_T)
|
||||
then
|
||||
Next (Id);
|
||||
end if;
|
||||
|
||||
if Is_Non_Empty_List (Abstract_Interface_List (Full_T)) then
|
||||
Id := First (Abstract_Interface_List (Full_T));
|
||||
while Present (Id) loop
|
||||
Iface := Etype (Id);
|
||||
|
||||
@ -1369,13 +1313,14 @@ package body Sem_Util is
|
||||
-- type Wrong is new I and O with null record; -- ERROR
|
||||
|
||||
if Is_Interface (Iface) then
|
||||
if Exclude_Parent_Interfaces
|
||||
and then Interface_Present_In_Parent (T, Iface)
|
||||
if Exclude_Parents
|
||||
and then Etype (T) /= T
|
||||
and then Interface_Present_In_Ancestor (Etype (T), Iface)
|
||||
then
|
||||
null;
|
||||
else
|
||||
Collect (Iface);
|
||||
Add_Interface (Iface);
|
||||
Collect (Iface);
|
||||
Append_Unique_Elmt (Iface, Ifaces_List);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@ -1384,40 +1329,13 @@ package body Sem_Util is
|
||||
end if;
|
||||
end Collect;
|
||||
|
||||
---------------------------------
|
||||
-- Interface_Present_In_Parent --
|
||||
---------------------------------
|
||||
|
||||
function Interface_Present_In_Parent
|
||||
(Typ : Entity_Id;
|
||||
Iface : Entity_Id) return Boolean
|
||||
is
|
||||
Aux : Entity_Id := Typ;
|
||||
Iface_List : List_Id;
|
||||
|
||||
begin
|
||||
if Is_Concurrent_Type (Typ)
|
||||
or else Is_Concurrent_Record_Type (Typ)
|
||||
then
|
||||
Iface_List := Abstract_Interface_List (Typ);
|
||||
|
||||
if Is_Non_Empty_List (Iface_List) then
|
||||
Aux := Etype (First (Iface_List));
|
||||
else
|
||||
return False;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return Interface_Present_In_Ancestor (Aux, Iface);
|
||||
end Interface_Present_In_Parent;
|
||||
|
||||
-- Start of processing for Collect_Abstract_Interfaces
|
||||
-- Start of processing for Collect_Interfaces
|
||||
|
||||
begin
|
||||
pragma Assert (Is_Tagged_Type (T) or else Is_Concurrent_Type (T));
|
||||
Ifaces_List := New_Elmt_List;
|
||||
Collect (T);
|
||||
end Collect_Abstract_Interfaces;
|
||||
end Collect_Interfaces;
|
||||
|
||||
----------------------------------
|
||||
-- Collect_Interface_Components --
|
||||
@ -1526,7 +1444,7 @@ package body Sem_Util is
|
||||
-- Start of processing for Collect_Interfaces_Info
|
||||
|
||||
begin
|
||||
Collect_Abstract_Interfaces (T, Ifaces_List);
|
||||
Collect_Interfaces (T, Ifaces_List);
|
||||
Collect_Interface_Components (T, Comps_List);
|
||||
|
||||
-- Search for the record component and tag associated with each
|
||||
@ -1542,7 +1460,7 @@ package body Sem_Util is
|
||||
-- Associate the primary tag component and the primary dispatch table
|
||||
-- with all the interfaces that are parents of T
|
||||
|
||||
if Is_Parent (Iface, T) then
|
||||
if Is_Ancestor (Iface, T) then
|
||||
Append_Elmt (First_Tag_Component (T), Components_List);
|
||||
Append_Elmt (Node (First_Elmt (Access_Disp_Table (T))), Tags_List);
|
||||
|
||||
@ -1555,7 +1473,7 @@ package body Sem_Util is
|
||||
Comp_Iface := Related_Type (Node (Comp_Elmt));
|
||||
|
||||
if Comp_Iface = Iface
|
||||
or else Is_Parent (Iface, Comp_Iface)
|
||||
or else Is_Ancestor (Iface, Comp_Iface)
|
||||
then
|
||||
Append_Elmt (Node (Comp_Elmt), Components_List);
|
||||
Append_Elmt (Search_Tag (Comp_Iface), Tags_List);
|
||||
@ -4085,83 +4003,6 @@ package body Sem_Util is
|
||||
return Task_Body_Procedure (Underlying_Type (Root_Type (E)));
|
||||
end Get_Task_Body_Procedure;
|
||||
|
||||
-----------------------------
|
||||
-- Has_Abstract_Interfaces --
|
||||
-----------------------------
|
||||
|
||||
function Has_Abstract_Interfaces
|
||||
(T : Entity_Id;
|
||||
Use_Full_View : Boolean := True) return Boolean
|
||||
is
|
||||
Typ : Entity_Id;
|
||||
|
||||
begin
|
||||
-- Handle concurrent types
|
||||
|
||||
if Is_Concurrent_Type (T) then
|
||||
Typ := Corresponding_Record_Type (T);
|
||||
else
|
||||
Typ := T;
|
||||
end if;
|
||||
|
||||
if not Present (Typ)
|
||||
or else not Is_Tagged_Type (Typ)
|
||||
then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
pragma Assert (Is_Record_Type (Typ));
|
||||
|
||||
-- Handle private types
|
||||
|
||||
if Use_Full_View
|
||||
and then Present (Full_View (Typ))
|
||||
then
|
||||
Typ := Full_View (Typ);
|
||||
end if;
|
||||
|
||||
-- Handle concurrent record types
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ)
|
||||
and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
|
||||
loop
|
||||
if Is_Interface (Typ)
|
||||
or else
|
||||
(Is_Record_Type (Typ)
|
||||
and then Present (Abstract_Interfaces (Typ))
|
||||
and then not Is_Empty_Elmt_List (Abstract_Interfaces (Typ)))
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
|
||||
exit when Etype (Typ) = Typ
|
||||
|
||||
-- Handle private types
|
||||
|
||||
or else (Present (Full_View (Etype (Typ)))
|
||||
and then Full_View (Etype (Typ)) = Typ)
|
||||
|
||||
-- Protect the frontend against wrong source with cyclic
|
||||
-- derivations
|
||||
|
||||
or else Etype (Typ) = T;
|
||||
|
||||
-- Climb to the ancestor type handling private types
|
||||
|
||||
if Present (Full_View (Etype (Typ))) then
|
||||
Typ := Full_View (Etype (Typ));
|
||||
else
|
||||
Typ := Etype (Typ);
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return False;
|
||||
end Has_Abstract_Interfaces;
|
||||
|
||||
-----------------------
|
||||
-- Has_Access_Values --
|
||||
-----------------------
|
||||
@ -4616,6 +4457,82 @@ package body Sem_Util is
|
||||
and then Includes_Infinities (Scalar_Range (E));
|
||||
end Has_Infinities;
|
||||
|
||||
--------------------
|
||||
-- Has_Interfaces --
|
||||
--------------------
|
||||
|
||||
function Has_Interfaces
|
||||
(T : Entity_Id;
|
||||
Use_Full_View : Boolean := True) return Boolean
|
||||
is
|
||||
Typ : Entity_Id;
|
||||
|
||||
begin
|
||||
-- Handle concurrent types
|
||||
|
||||
if Is_Concurrent_Type (T) then
|
||||
Typ := Corresponding_Record_Type (T);
|
||||
else
|
||||
Typ := T;
|
||||
end if;
|
||||
|
||||
if not Present (Typ)
|
||||
or else not Is_Record_Type (Typ)
|
||||
or else not Is_Tagged_Type (Typ)
|
||||
then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
-- Handle private types
|
||||
|
||||
if Use_Full_View
|
||||
and then Present (Full_View (Typ))
|
||||
then
|
||||
Typ := Full_View (Typ);
|
||||
end if;
|
||||
|
||||
-- Handle concurrent record types
|
||||
|
||||
if Is_Concurrent_Record_Type (Typ)
|
||||
and then Is_Non_Empty_List (Abstract_Interface_List (Typ))
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
|
||||
loop
|
||||
if Is_Interface (Typ)
|
||||
or else
|
||||
(Is_Record_Type (Typ)
|
||||
and then Present (Interfaces (Typ))
|
||||
and then not Is_Empty_Elmt_List (Interfaces (Typ)))
|
||||
then
|
||||
return True;
|
||||
end if;
|
||||
|
||||
exit when Etype (Typ) = Typ
|
||||
|
||||
-- Handle private types
|
||||
|
||||
or else (Present (Full_View (Etype (Typ)))
|
||||
and then Full_View (Etype (Typ)) = Typ)
|
||||
|
||||
-- Protect the frontend against wrong source with cyclic
|
||||
-- derivations
|
||||
|
||||
or else Etype (Typ) = T;
|
||||
|
||||
-- Climb to the ancestor type handling private types
|
||||
|
||||
if Present (Full_View (Etype (Typ))) then
|
||||
Typ := Full_View (Etype (Typ));
|
||||
else
|
||||
Typ := Etype (Typ);
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return False;
|
||||
end Has_Interfaces;
|
||||
|
||||
------------------------
|
||||
-- Has_Null_Exclusion --
|
||||
------------------------
|
||||
@ -5219,6 +5136,56 @@ package body Sem_Util is
|
||||
end if;
|
||||
end Has_Tagged_Component;
|
||||
|
||||
--------------------------
|
||||
-- Implements_Interface --
|
||||
--------------------------
|
||||
|
||||
function Implements_Interface
|
||||
(Typ_Ent : Entity_Id;
|
||||
Iface_Ent : Entity_Id;
|
||||
Exclude_Parents : Boolean := False) return Boolean
|
||||
is
|
||||
Ifaces_List : Elist_Id;
|
||||
Elmt : Elmt_Id;
|
||||
Iface : Entity_Id;
|
||||
Typ : Entity_Id;
|
||||
|
||||
begin
|
||||
if Is_Class_Wide_Type (Typ_Ent) then
|
||||
Typ := Etype (Typ_Ent);
|
||||
else
|
||||
Typ := Typ_Ent;
|
||||
end if;
|
||||
|
||||
if Is_Class_Wide_Type (Iface_Ent) then
|
||||
Iface := Etype (Iface_Ent);
|
||||
else
|
||||
Iface := Iface_Ent;
|
||||
end if;
|
||||
|
||||
if not Has_Interfaces (Typ) then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
Collect_Interfaces (Typ, Ifaces_List);
|
||||
|
||||
Elmt := First_Elmt (Ifaces_List);
|
||||
while Present (Elmt) loop
|
||||
if Is_Ancestor (Node (Elmt), Typ)
|
||||
and then Exclude_Parents
|
||||
then
|
||||
null;
|
||||
|
||||
elsif Node (Elmt) = Iface then
|
||||
return True;
|
||||
end if;
|
||||
|
||||
Next_Elmt (Elmt);
|
||||
end loop;
|
||||
|
||||
return False;
|
||||
end Implements_Interface;
|
||||
|
||||
-----------------
|
||||
-- In_Instance --
|
||||
-----------------
|
||||
@ -6524,33 +6491,6 @@ package body Sem_Util is
|
||||
end if;
|
||||
end Is_OK_Variable_For_Out_Formal;
|
||||
|
||||
---------------
|
||||
-- Is_Parent --
|
||||
---------------
|
||||
|
||||
function Is_Parent
|
||||
(E1 : Entity_Id;
|
||||
E2 : Entity_Id) return Boolean
|
||||
is
|
||||
Iface_List : List_Id;
|
||||
T : Entity_Id := E2;
|
||||
|
||||
begin
|
||||
if Is_Concurrent_Type (T)
|
||||
or else Is_Concurrent_Record_Type (T)
|
||||
then
|
||||
Iface_List := Abstract_Interface_List (E2);
|
||||
|
||||
if Is_Empty_List (Iface_List) then
|
||||
return False;
|
||||
end if;
|
||||
|
||||
T := Etype (First (Iface_List));
|
||||
end if;
|
||||
|
||||
return Is_Ancestor (E1, T);
|
||||
end Is_Parent;
|
||||
|
||||
-----------------------------------
|
||||
-- Is_Partially_Initialized_Type --
|
||||
-----------------------------------
|
||||
@ -8494,6 +8434,48 @@ package body Sem_Util is
|
||||
return Trace_Components (Type_Id, False);
|
||||
end Private_Component;
|
||||
|
||||
---------------------------
|
||||
-- Primitive_Names_Match --
|
||||
---------------------------
|
||||
|
||||
function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean is
|
||||
|
||||
function Non_Internal_Name (E : Entity_Id) return Name_Id;
|
||||
-- Given an internal name, returns the corresponding non-internal name
|
||||
|
||||
------------------------
|
||||
-- Non_Internal_Name --
|
||||
------------------------
|
||||
|
||||
function Non_Internal_Name (E : Entity_Id) return Name_Id is
|
||||
begin
|
||||
Get_Name_String (Chars (E));
|
||||
Name_Len := Name_Len - 1;
|
||||
return Name_Find;
|
||||
end Non_Internal_Name;
|
||||
|
||||
-- Start of processing for Primitive_Names_Match
|
||||
|
||||
begin
|
||||
pragma Assert (Present (E1) and then Present (E2));
|
||||
|
||||
return Chars (E1) = Chars (E2)
|
||||
or else
|
||||
(not Is_Internal_Name (Chars (E1))
|
||||
and then Is_Internal_Name (Chars (E2))
|
||||
and then Non_Internal_Name (E2) = Chars (E1))
|
||||
or else
|
||||
(not Is_Internal_Name (Chars (E2))
|
||||
and then Is_Internal_Name (Chars (E1))
|
||||
and then Non_Internal_Name (E1) = Chars (E2))
|
||||
or else
|
||||
(Is_Predefined_Dispatching_Operation (E1)
|
||||
and then Is_Predefined_Dispatching_Operation (E2)
|
||||
and then Same_TSS (E1, E2))
|
||||
or else
|
||||
(Is_Init_Proc (E1) and then Is_Init_Proc (E2));
|
||||
end Primitive_Names_Match;
|
||||
|
||||
-----------------------
|
||||
-- Process_End_Label --
|
||||
-----------------------
|
||||
@ -8703,6 +8685,32 @@ package body Sem_Util is
|
||||
return Token_Node;
|
||||
end Real_Convert;
|
||||
|
||||
--------------------
|
||||
-- Remove_Homonym --
|
||||
--------------------
|
||||
|
||||
procedure Remove_Homonym (E : Entity_Id) is
|
||||
Prev : Entity_Id := Empty;
|
||||
H : Entity_Id;
|
||||
|
||||
begin
|
||||
if E = Current_Entity (E) then
|
||||
if Present (Homonym (E)) then
|
||||
Set_Current_Entity (Homonym (E));
|
||||
else
|
||||
Set_Name_Entity_Id (Chars (E), Empty);
|
||||
end if;
|
||||
else
|
||||
H := Current_Entity (E);
|
||||
while Present (H) and then H /= E loop
|
||||
Prev := H;
|
||||
H := Homonym (H);
|
||||
end loop;
|
||||
|
||||
Set_Homonym (Prev, Homonym (E));
|
||||
end if;
|
||||
end Remove_Homonym;
|
||||
|
||||
---------------------
|
||||
-- Rep_To_Pos_Flag --
|
||||
---------------------
|
||||
@ -9745,6 +9753,22 @@ package body Sem_Util is
|
||||
return Scope_Depth (Enclosing_Dynamic_Scope (Btyp));
|
||||
end Type_Access_Level;
|
||||
|
||||
--------------------
|
||||
-- Ultimate_Alias --
|
||||
--------------------
|
||||
-- To do: add occurrences calling this new subprogram
|
||||
|
||||
function Ultimate_Alias (Prim : Entity_Id) return Entity_Id is
|
||||
E : Entity_Id := Prim;
|
||||
|
||||
begin
|
||||
while Present (Alias (E)) loop
|
||||
E := Alias (E);
|
||||
end loop;
|
||||
|
||||
return E;
|
||||
end Ultimate_Alias;
|
||||
|
||||
--------------------------
|
||||
-- Unit_Declaration_Node --
|
||||
--------------------------
|
||||
|
@ -152,14 +152,14 @@ package Sem_Util is
|
||||
-- with OpenVMS ports. The argument is the construct in question
|
||||
-- and is used to post the error message.
|
||||
|
||||
procedure Collect_Abstract_Interfaces
|
||||
(T : Entity_Id;
|
||||
Ifaces_List : out Elist_Id;
|
||||
Exclude_Parent_Interfaces : Boolean := False;
|
||||
Use_Full_View : Boolean := True);
|
||||
procedure Collect_Interfaces
|
||||
(T : Entity_Id;
|
||||
Ifaces_List : out Elist_Id;
|
||||
Exclude_Parents : Boolean := False;
|
||||
Use_Full_View : Boolean := True);
|
||||
-- Ada 2005 (AI-251): Collect whole list of abstract interfaces that are
|
||||
-- directly or indirectly implemented by T. Exclude_Parent_Interfaces is
|
||||
-- used to avoid addition of inherited interfaces to the generated list.
|
||||
-- directly or indirectly implemented by T. Exclude_Parents is used to
|
||||
-- avoid the addition of inherited interfaces to the generated list.
|
||||
-- Use_Full_View is used to collect the interfaces using the full-view
|
||||
-- (if available).
|
||||
|
||||
@ -498,14 +498,6 @@ package Sem_Util is
|
||||
-- as an access type internally, this function tests only for access types
|
||||
-- known to the programmer. See also Has_Tagged_Component.
|
||||
|
||||
function Has_Abstract_Interfaces
|
||||
(T : Entity_Id;
|
||||
Use_Full_View : Boolean := True) return Boolean;
|
||||
-- Where T is a concurrent type or a record type, returns true if T covers
|
||||
-- any abstract interface types. In case of private types the argument
|
||||
-- Use_Full_View controls if the check is done using its full view (if
|
||||
-- available).
|
||||
|
||||
type Alignment_Result is (Known_Compatible, Unknown, Known_Incompatible);
|
||||
-- Result of Has_Compatible_Alignment test, description found below. Note
|
||||
-- that the values are arranged in increasing order of problematicness.
|
||||
@ -542,6 +534,14 @@ package Sem_Util is
|
||||
-- Determines if the range of the floating-point type E includes
|
||||
-- infinities. Returns False if E is not a floating-point type.
|
||||
|
||||
function Has_Interfaces
|
||||
(T : Entity_Id;
|
||||
Use_Full_View : Boolean := True) return Boolean;
|
||||
-- Where T is a concurrent type or a record type, returns true if T covers
|
||||
-- any abstract interface types. In case of private types the argument
|
||||
-- Use_Full_View controls if the check is done using its full view (if
|
||||
-- available).
|
||||
|
||||
function Has_Null_Exclusion (N : Node_Id) return Boolean;
|
||||
-- Determine whether node N has a null exclusion
|
||||
|
||||
@ -572,6 +572,12 @@ package Sem_Util is
|
||||
-- component is present. This function is used to check if '=' has to be
|
||||
-- expanded into a bunch component comparisons.
|
||||
|
||||
function Implements_Interface
|
||||
(Typ_Ent : Entity_Id;
|
||||
Iface_Ent : Entity_Id;
|
||||
Exclude_Parents : Boolean := False) return Boolean;
|
||||
-- Returns true if the Typ implements interface Iface
|
||||
|
||||
function In_Instance return Boolean;
|
||||
-- Returns True if the current scope is within a generic instance
|
||||
|
||||
@ -716,13 +722,6 @@ package Sem_Util is
|
||||
-- is a variable (in the Is_Variable sense) with a non-tagged type
|
||||
-- target are considered view conversions and hence variables.
|
||||
|
||||
function Is_Parent
|
||||
(E1 : Entity_Id;
|
||||
E2 : Entity_Id) return Boolean;
|
||||
-- Determine whether E1 is a parent of E2. For a concurrent type, the
|
||||
-- parent is the first element of its list of interface types; for other
|
||||
-- types, this function provides the same result as Is_Ancestor.
|
||||
|
||||
function Is_Partially_Initialized_Type (Typ : Entity_Id) return Boolean;
|
||||
-- Typ is a type entity. This function returns true if this type is
|
||||
-- partly initialized, meaning that an object of the type is at least
|
||||
@ -951,6 +950,13 @@ package Sem_Util is
|
||||
-- For convenience, qualified expressions applied to object names
|
||||
-- are also allowed as actuals for this function.
|
||||
|
||||
function Primitive_Names_Match (E1, E2 : Entity_Id) return Boolean;
|
||||
-- Returns True if the names of both entities correspond with matching
|
||||
-- primitives. This routine includes support for the case in which one
|
||||
-- or both entities correspond with entities built by Derive_Subprogram
|
||||
-- with a special name to avoid being overriden (ie. return true in case
|
||||
-- of entities with names "nameP" and "name" or viceversa).
|
||||
|
||||
function Private_Component (Type_Id : Entity_Id) return Entity_Id;
|
||||
-- Returns some private component (if any) of the given Type_Id.
|
||||
-- Used to enforce the rules on visibility of operations on composite
|
||||
@ -974,6 +980,9 @@ package Sem_Util is
|
||||
-- S is a possibly signed syntactically valid real literal. The result
|
||||
-- returned is an N_Real_Literal node representing the literal value.
|
||||
|
||||
procedure Remove_Homonym (E : Entity_Id);
|
||||
-- Removes E from the homonym chain
|
||||
|
||||
function Rep_To_Pos_Flag (E : Entity_Id; Loc : Source_Ptr) return Node_Id;
|
||||
-- This is used to construct the second argument in a call to Rep_To_Pos
|
||||
-- which is Standard_True if range checks are enabled (E is an entity to
|
||||
@ -1147,6 +1156,10 @@ package Sem_Util is
|
||||
function Type_Access_Level (Typ : Entity_Id) return Uint;
|
||||
-- Return the accessibility level of Typ
|
||||
|
||||
function Ultimate_Alias (Prim : Entity_Id) return Entity_Id;
|
||||
-- Return the last entity in the chain of aliased entities of Prim.
|
||||
-- If Prim has no alias return Prim.
|
||||
|
||||
function Unit_Declaration_Node (Unit_Id : Entity_Id) return Node_Id;
|
||||
-- Unit_Id is the simple name of a program unit, this function returns the
|
||||
-- corresponding xxx_Declaration node for the entity. Also applies to the
|
||||
|
@ -1577,6 +1577,11 @@ package body Sprint is
|
||||
Write_Str_With_Col_Check_Sloc ("new ");
|
||||
Sprint_Node (Subtype_Mark (Node));
|
||||
|
||||
if Present (Interface_List (Node)) then
|
||||
Write_Str_With_Col_Check (" and ");
|
||||
Sprint_And_List (Interface_List (Node));
|
||||
end if;
|
||||
|
||||
if Private_Present (Node) then
|
||||
Write_Str_With_Col_Check (" with private");
|
||||
end if;
|
||||
@ -2442,6 +2447,12 @@ package body Sprint is
|
||||
|
||||
Write_Str_With_Col_Check (" is new ");
|
||||
Sprint_Node (Subtype_Indication (Node));
|
||||
|
||||
if Present (Interface_List (Node)) then
|
||||
Write_Str_With_Col_Check (" and ");
|
||||
Sprint_And_List (Interface_List (Node));
|
||||
end if;
|
||||
|
||||
Write_Str_With_Col_Check (" with private;");
|
||||
|
||||
when N_Procedure_Call_Statement =>
|
||||
|
Loading…
x
Reference in New Issue
Block a user