diff options
Diffstat (limited to 'gcc/ada/sem_ch6.ads')
-rw-r--r-- | gcc/ada/sem_ch6.ads | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads index 7ebbcaa..4ef5b65 100644 --- a/gcc/ada/sem_ch6.ads +++ b/gcc/ada/sem_ch6.ads @@ -190,6 +190,14 @@ package Sem_Ch6 is -- Use the subprogram specification in the body to retrieve the previous -- subprogram declaration, if any. + procedure Freeze_Extra_Formals (E : Entity_Id); + -- Given a subprogram, subprogram type, or entry, flag E to indicate that + -- its extra formals (if any) are known (by setting Extra_Formals_Known). + -- This subprogram serves three purposes: (1) Document the places where + -- the extra formals are known, (2) Ensure that extra formals are added + -- only once, and (3) Provide a convenient place for setting a debugger + -- breakpoint to locate when extra formals are known. + function Fully_Conformant (New_Id, Old_Id : Entity_Id) return Boolean; -- Determine whether two callable entities (subprograms, entries, -- literals) are fully conformant (RM 6.3.1(17)) @@ -299,4 +307,156 @@ package Sem_Ch6 is procedure Valid_Operator_Definition (Designator : Entity_Id); -- Verify that an operator definition has the proper number of formals + ------------------------------------ + -- Deferred_Extra_Formals_Support -- + ------------------------------------ + + -- This package provides support for deferring the addition of extra + -- formals to subprograms, entries, and subprogram types; it also provides + -- support for deferring the addition of extra actuals to direct calls to + -- subprograms and entries, and indirect calls through subprogram types. + -- The addition of the extra formals and actuals is deferred until the + -- underlying type of all the parameters and result types of registered + -- subprograms, entries, and subprogram types is known. + + -- Functional Description + -- ---------------------- + -- + -- When Create_Extra_Formals identifies that the underlying type of + -- some parameter or result type of an entity E is not available, E is + -- registered by this package, and the addition of its extra formals is + -- deferred. As part of this registration, the types of all the params + -- and result types of E with no underlying type are also registered. + -- + -- When Expand_Call_Helper identifies that the underlying type of some + -- parameter or result type of a called entity is not available, the call + -- is registered by Register_Deferred_Extra_Formals_Call, and the addition + -- of its extra actuals is deferred. + -- + -- When the full type declaration of some registered type T is analyzed, + -- the subprogram Add_Deferred_Extra_Params is invoked; this subprogram + -- does the following actions: + -- 1) Check all the registered entities (subprograms, entries, and + -- subprogram types); for each registered entity that has all its + -- underlying types available, call Create_Extra_Formals, and + -- unregister the entity. + -- 2) Check all the registered calls; for each registered call that + -- has available the underlying type of all the parameters and result + -- types of the called entity, call Create_Extra_Actuals, and + -- unregister the call. + -- 3) Unregister T. + -- + -- Example 1 + -- --------- + -- A package spec has a private type declaration T, and declarations of + -- expression functions and/or primitives with class-wide conditions + -- invoking primitives of type T before the full view of T is defined. + -- + -- As part of processing the early freezing of the called subprograms + -- (and as part of processing the calls) the functions are registered as + -- subprograms with deferred extra formals, and the calls are registered + -- as calls with deferred extra actuals. + -- + -- When the full type declaration of T is analyzed, extra formals are + -- added to all the registered subprograms, and extra actuals are added + -- to all the registered calls with deferred extra actuals. + -- + -- Example 2 + -- --------- + -- The specification of package P has a limited_with_clause on package Q, + -- and the type of the formals of subprograms defined in P are types + -- defined in Q. + -- + -- When compiling the spec of P, similarly to the previous example, + -- subprograms with incomplete formals are registered as subprograms + -- with deferred extra formals; if the spec of P has calls to these + -- subprograms, then these calls are registered as calls with deferred + -- extra actuals. That is, when the analysis of package P completes, + -- deferred extra formals and actuals have not been added. + -- + -- When another compilation unit is analyzed (including the body of + -- package P), and a regular with-clause on Q is processed, when the + -- full type declaration of deferred entities is analyzed, deferred + -- extra formals and deferred extra actuals are added. + -- + -- This machinery relies on the GNAT Compilation Model; that is, when + -- we analyze the spec of P (for which we generally don't generate code), + -- it is safe to complete the compilation and still have entities with + -- deferred extra formals, and calls with deferred extra actuals. + -- + -- The body package P generally has a regular with-clause on package Q. + -- Hence, when we compile the body of package P, the implicit dependence + -- on its package spec causes the analysis of the spec of P (thus + -- registering deferred entities), followed by the analysis of context + -- clauses in the body of P. When the regular with-clause on package Q + -- is analyzed, we add the extra formals and extra actuals to deferred + -- entities. Thus, the generated code will have all the needed formals. + -- + -- The (still) unsupported case is when the body of package P does not + -- have a regular with-clause on package Q (AI05-0151-1/08). This case + -- is left documented in the front-end sources by means of calls to + -- the following subprograms: Is_Unsupported_Extra_Formals_Entity, and + -- Is_Unsupported_Extra_Actuals_Call. + + package Deferred_Extra_Formals_Support is + + procedure Add_Deferred_Extra_Params (Typ : Entity_Id); + -- Check all the registered subprograms, entries, and subprogram types + -- with deferred addition of their extra formals; if the underlying + -- types of all their formals is available then add their extra formals. + -- Check also all the registered calls with deferred addition of their + -- extra actuals; add their extra actuals if the underlying types of all + -- their parameters and result types are available. Finally unregister + -- Typ from the list of types used for the deferral of extra formals/ + -- actuals. + + procedure Register_Deferred_Extra_Formals_Entity (Id : Entity_Id); + -- Register the given subprogram, entry, or subprogram type to defer the + -- addition of its extra formals. + + procedure Register_Deferred_Extra_Formals_Call + (Call_Node : Node_Id; + Scope_Id : Entity_Id); + -- Register the given call, performed from the given scope, to defer the + -- addition of its extra actuals. + + function Has_Deferred_Extra_Formals (Typ : Entity_Id) return Boolean; + -- Return True if there some registered subprogram, subprogram type, or + -- entry with deferred extra formals that has some formal type or + -- result type of type Typ (i.e. which depends on the given type to + -- add its extra formals). + + function Is_Deferred_Extra_Formals_Entity + (Id : Entity_Id) return Boolean; + -- Return True if Id is a subprogram, subprogram type, or entry that has + -- been registered to defer the addition of its extra formals. + + function Is_Unsupported_Extra_Formals_Entity + (Id : Entity_Id) return Boolean; + -- Id is a subprogram, subprogram type, or entry. Return True if Id is + -- unsupported for deferring the addition of its extra formals; that is, + -- it is defined in a compilation unit that is a package body or a + -- subprogram body, and the underlying type of some of its parameters + -- or result type is not available. + -- + -- The context for this case is an unsupported case of AI05-0151-1/08 + -- that allows incomplete tagged types as parameter and result types. + -- More concretely, a type T is visible in a package spec through a + -- limited_with_clause, and the body of the package has no regular + -- with_clause. In such a case, the machinery for deferring the + -- addition of extra formals does not work because the underlying + -- type of the type is not seen during the compilation of the + -- package body. + -- + -- The purpose of this function is to facilitate locating in the sources + -- the places where the front end performs the current (incomplete) + -- management of such case (to facilitate further work) ??? + + function Is_Unsupported_Extra_Actuals_Call + (Call_Node : Node_Id; Id : Entity_Id) return Boolean; + -- Same as previous function but applicable to a call to the given + -- entity Id. + + end Deferred_Extra_Formals_Support; + end Sem_Ch6; |