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 the category can be restricted 
to only nonlimited types or to only tagged types. Similarly, the category 
for a formal incomplete type is all types but the category can be restricted 
to only tagged types; unlike other formal types, the actual type does 
not need to be able to be frozen (see 
13.14). 
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 ancestor type 
shall be a limited interface if the reserved word 
synchronized 
appears.
 
  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 formal type is nonlimited, the actual type shall be nonlimited. 
The actual type for a formal derived type shall be tagged if and only 
if the formal derived type is a private extension. If the reserved word 
synchronized appears in the declaration of the formal derived 
type, the actual type shall be a synchronized tagged type. 
If a formal private or derived subtype is definite, 
then the actual subtype shall also be definite. 
  A 
formal_incomplete_type_declaration 
declares a formal incomplete type. The only view of a formal incomplete 
type is an incomplete view. Thus, a formal incomplete type is subject 
to the same usage restrictions as any other incomplete type — see 
3.10.1.
 
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.
 
   When enforcing Legality Rules, for the purposes 
of determining within a generic body whether a type is unconstrained 
in any partial view, a discriminated subtype is considered to have a 
constrained partial view if it is a descendant of an untagged generic 
formal private or derived type.
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.
   The category determined for a formal incomplete 
type is the category of all types, unless the 
formal_type_declaration 
includes the reserved word 
tagged; in this case, it is the category 
of all tagged types.
 
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.
 For a formal derived type, the characteristics (including 
components, but excluding discriminants if there is a new 
discriminant_part), 
predefined operators, and inherited user-defined primitive subprograms 
are determined by its ancestor type and its progenitor types (if any), 
in the same way that those of a derived type are determined by those 
of its parent type and its progenitor types (see 
3.4 
and 
7.3.1).
 
 In an instance, the copy of an implicit declaration 
of a primitive subprogram of a formal derived type 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 and even if it is never declared 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 has 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. 
 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe