12.5.1 Formal Private and Derived Types
In its most general form, the category determined
for a formal private type is all types, but it can be restricted to only
nonlimited types or to only tagged types. The category determined for
a formal derived type is the derivation class rooted at the ancestor
type.
Syntax
formal_private_type_definition ::= [[
abstract]
tagged] [
limited]
private
Legality Rules
The
ancestor
subtype of a formal derived type is the subtype denoted by the
subtype_mark
of the
formal_derived_type_definition.
For a formal derived type declaration, the reserved words
with private
shall appear if and only if the ancestor type is a tagged type; in this
case the formal derived type is a private extension of the ancestor type
and the ancestor shall not be a class-wide type. Similarly, an
interface_list
or the optional reserved words
abstract or
synchronized
shall appear only if the ancestor type is a tagged type. The reserved
word
limited or
synchronized shall appear only if the ancestor
type and any progenitor types are limited types. The reserved word
synchronized
shall appear (rather than
limited) if the ancestor type or any
of the progenitor types are synchronized interfaces.
The actual type for a formal derived type shall
be a descendant of the ancestor type and every progenitor of the formal
type. If the reserved word synchronized appears in the declaration
of the formal derived type, the actual type shall be a synchronized tagged
type.
If the formal subtype is definite, then the actual
subtype shall also be definite.
If the ancestor subtype is constrained, the actual
subtype shall be constrained, and shall be statically compatible with
the ancestor;
If the ancestor subtype is an unconstrained access
or composite subtype, the actual subtype shall be unconstrained.
If the ancestor subtype is an unconstrained discriminated
subtype, then the actual shall have the same number of discriminants,
and each discriminant of the actual shall correspond to a discriminant
of the ancestor, in the sense of
3.7.
If the ancestor subtype is an access subtype, the
actual subtype shall exclude null if and only if the ancestor subtype
excludes null.
The actual type shall be a type with the same number
of discriminants.
The actual subtype shall be unconstrained.
The subtype of each discriminant of the actual
type shall statically match the subtype of the corresponding discriminant
of the formal type.
For a generic formal type with an
unknown_discriminant_part,
the actual may, but need not, have discriminants, and may be definite
or indefinite.
Static Semantics
The category determined
for a formal private type is as follows:
Type Definition Determined Category
limited private the category of all types
private the category of all nonlimited types
tagged limited private the category of all tagged types
tagged private the category of all nonlimited tagged types
The presence of the reserved word abstract
determines whether the actual type may be abstract.
A formal private or derived type is a private or
derived type, respectively. A formal derived tagged type is a private
extension. A formal private or derived type is abstract if the reserved
word abstract appears in its declaration.
If the ancestor type is a composite type that is
not an array type, the formal type inherits components from the ancestor
type (including discriminants if a new
discriminant_part
is not specified), as for a derived type defined by a
derived_type_definition
(see
3.4 and
7.3.1).
For a formal derived type, the predefined operators
and inherited user-defined subprograms are determined by the ancestor
type and any progenitor types, and are implicitly declared at the earliest
place, if any, immediately within the declarative region in which the
formal type is declared, where the corresponding primitive subprogram
of the ancestor or progenitor is visible (see
7.3.1).
In an instance, the copy of such an implicit declaration declares a view
of the corresponding primitive subprogram of the ancestor or progenitor
of the formal derived type, even if this primitive has been overridden
for the actual type. When the ancestor or progenitor of the formal derived
type is itself a formal type, the copy of the implicit declaration declares
a view of the corresponding copied operation of the ancestor or progenitor.
In the case of a formal private extension, however, the tag of the formal
type is that of the actual type, so if the tag in a call is statically
determined to be that of the formal type, the body executed will be that
corresponding to the actual type.
For a
prefix
S that denotes a formal indefinite subtype, the following attribute is
defined:
S'Definite
S'Definite yields True if the
actual subtype corresponding to S is definite; otherwise it yields False.
The value of this attribute is of the predefined type Boolean.
Dynamic Semantics
In the case where
a formal type is tagged with unknown discriminants, and the actual type
is a class-wide type T'Class:
For the purposes of defining the primitive operations
of the formal type, each of the primitive operations of the actual type
is considered to be a subprogram (with an intrinsic calling convention
— see
6.3.1) whose body consists of
a dispatching call upon the corresponding operation of
T, with
its formal parameters as the actual parameters. If it is a function,
the result of the dispatching call is returned.
If the corresponding operation of
T has
no controlling formal parameters, then the controlling tag value is determined
by the context of the call, according to the rules for tag-indeterminate
calls (see
3.9.2 and
5.2).
In the case where the tag would be statically determined to be that of
the formal type, the call raises Program_Error. If such a function is
renamed, any call on the renaming raises Program_Error.
9 In accordance
with the general rule that the actual type shall belong to the category
determined for the formal (see
12.5, “
Formal
Types”):
If the formal type is nonlimited,
then so shall be the actual;
For a formal derived type, the actual
shall be in the class rooted at the ancestor subtype.
10 The actual type can be abstract only
if the formal type is abstract (see
3.9.3).
11 If the formal has a
discriminant_part,
the actual can be either definite or indefinite. Otherwise, the actual
has to be definite.