Version 1.5 of ais/ai-00401.txt

Unformatted version of ais/ai-00401.txt version 1.5
Other versions for file ais/ai-00401.txt

!standard 3.4(01)          05-05-05 AI95-00401/04
!standard 3.4(03)
!standard 3.4(05)
!standard 3.4(08)
!standard 3.4(17)
!standard 3.4(18)
!standard 3.4(22)
!standard 3.4(23)
!standard 3.4(23.1)
!standard 3.4(27)
!standard 3.4(35)
!standard 3.4.1(02)
!standard 7.3(16)
!standard 7.3(20)
!standard 9.1(9.1)
!standard 9.4(11)
!standard 12.5.1(05)
!standard 12.5.1(15)
!standard 12.5.1(21)
!standard 12.5.5(04)
!class amendment 05-01-25
!status Amendment 200Y 05-03-01
!status ARG Approved 7-0-3 05-02-13
!status work item 05-01-25
!status received 05-01-25
!priority High
!difficulty Medium
!subject Terminology for interfaces
!summary
(See proposal.)
!problem
The current wording calls "interface ancestor" an interface that is mentioned in an interface_list. This terminology is used in the description of derived types, interface types, private extensions, task and protected objects and types, and formal derived types.
It causes some confusion because the term "ancestor" is already a technical term in Ada 95, with a subtly different meaning. For example, a type is an ancestor of itself, but the "interface ancestor" relationship doesn't have that same property. In some cases where the word "ancestor" is used alone, it is unclear whether it is a shorthand for "interface ancestor" or a bona fide usage of the technical term. Also, the description of private extensions and formal private types makes use of the phrase "ancestor subtype" in context where interfaces also play a role, creating even more obscurity.
This terminology issue was briefly discussed in the context of AI 251, but at the time no good alternative was proposed, and it's only when reading the integrated manual that the ambiguities become obvious.
!proposal
We propose to call "progenitor" an interface mentioned in an interface_list. We then define "ancestor" to mean "parent or progenitor, any level". Most of the rules that use the words "parent" or "ancestor" remain valid with this definition, although in a few cases we need to say "parent or progenitor".
While the wording changes are numerous, they are mostly limited to 3.4 and 12.5.1. Note that not all changes are terminology changes; some are just plugging holes. For instance, there are a number of places where the wording say "parent" for rules that should also apply to interfaces. In other cases the new terminology fixes wording that was otherwise wrong or incomprehensible, depending on how the word "ancestor" was interpreted.
!wording
Change 3.4(1) to read:
A derived_type_definition defines a new type (and its first subtype) whose characteristics are derived from those of a parent type{, and possibly from progenitor types}.
Change 3.4(3) to read:
An interface_subtype_mark in an interface_list names a *progenitor subtype*; its type is the *progenitor type*. The parent_subtype_indication defines the parent subtype; its type is the parent type. A derived type has one parent type and zero or more {progenitor} types.
Change 3.4(5) to read:
If there is a record_extension_part, the derived type is called a record extension of the parent type. A record_extension_part {(and an interface_list)} shall be provided if and only if the parent type is a tagged type.
Change 3.4(8) to read:
Each class of types that includes the parent type {or a progenitor type} also includes the derived type.
Change 3.4(17) to read:
For each user-defined primitive subprogram (other than a user-defined equality operator -- see below) of the parent type {or of a progenitor type} that already exists at the place of the derived_type_definition, there exists a corresponding inherited primitive subprogram of the derived type with the same defining name. Primitive user-defined equality operators of the parent type are also inherited by the derived type, except when the derived type is a nonlimited record extension, and the inherited operator would have a profile that is type conformant with the profile of the corresponding predefined equality operator; in this case, the user-defined equality operator is not inherited, but is rather incorporated into the implementation of the predefined equality operator of the record extension (see 4.5.2).
Change 3.4(18) to read:
The profile of an inherited subprogram (including an inherited enumeration literal) is obtained from the profile of the corresponding (user-defined) primitive subprogram of the parent {or progenitor} type, after systematic replacement of each subtype of its profile (see 6.1) that is of the parent {or progenitor} type with a corresponding subtype of the derived type. For a given subtype of the parent {or progenitor} type, the corresponding subtype of the derived type is defined as follows:
Change 3.4(22) to read:
The same formal parameters have default_expressions in the profile of the inherited subprogram. Any type mismatch due to the systematic replacement of the parent {or progenitor} type by the derived type is handled as part of the normal type conversion associated with parameter passing -- see 6.4.1.
Change 3.4(23) to read:
If a primitive subprogram of the parent {or progenitor} type is visible at the place of the derived_type_definition, then the corresponding inherited subprogram is implicitly declared immediately after the derived_type_definition. Otherwise, the inherited subprogram is implicitly declared later or not at all, as explained in 7.3.1.
Delete the paragraph added after 3.4(23) by AI95-00251.
Change 3.4(27) to read (this includes the changes of AI-391):
For the execution of a call on an inherited subprogram, a call on the corresponding primitive subprogram of the parent {or progenitor} type is performed; the normal conversion of each actual parameter to the subtype of the corresponding formal parameter (see 6.4.1) performs any necessary type conversion as well. If the result type of the inherited subprogram is the derived type, the result of calling the {subprogram of the parent or progenitor} is converted to the derived type, or in the case of a null extension, extended to the derived type using the equivalent of an extension_aggregate with the original result as the ancestor_part and null record as the record_component_association_list.
Change the paragraph added after 3.4(35) by AI95-00251 to read:
An interface type which has a {progenitor type} "is derived from" that type. A derived_type_definition, however, never defines an interface type.
Change the second sentence of 3.4.1(2) as modified by AI95-00251 to read:
A derived type, interface type, type extension, task type, protected type, or formal derived type is also derived from each of its progenitor types, if any.
Change 7.3(16) to read:
A private extension inherits components (including discriminants unless there is a new discriminant_part specified) and user-defined primitive subprograms from its ancestor type {and its progenitor types (if any)}, in the same way that a record extension inherits components and user-defined primitive subprograms from its parent type {and its progenitor types} (see 3.4).
Add after 7.3(20):
The progenitor types specified in a private_extension_declaration and the progenitor types specified in the corresponding declaration of a record extension given in the private part need not be the same -- the only requirement is that the private extension must be descended from each interface from which the record extension is descended.
Delete the first paragraph added after 9.1(9.1) by AI95-00345.
Delete the sentence added to 9.4(11) by AI95-00345. (That, is revert to the original wording of RM95.)
Change 12.5.1(5) to read:
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 word abstract shall appear only if the ancestor type is a tagged type.
Change the paragraph added after 12.5.1(5) by AI95-00251 to read:
The actual type for a generic formal derived type shall be a descendant of every {progenitor} of the formal type.
Change 12.5.1(21) to read:
For a formal derived type, the predefined operators and inherited user-defined subprograms are determined by the ancestor type {and the 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.
Change 12.5.5(4) (a section introduced by AI95-00251) to read:
The actual type shall be a descendant of every {progenitor} of the formal type.
!discussion
(See proposal.)
!example
!corrigendum 3.4(01)
Replace the paragraph:
A derived_type_definition defines a new type (and its first subtype) whose characteristics are derived from those of a parent type.
by:
A derived_type_definition defines a new type (and its first subtype) whose characteristics are derived from those of a parent type, and possibly from progenitor types.
!corrigendum 3.4(03)
Replace the paragraph:
The parent_subtype_indication defines the parent subtype; its type is the parent type.
by:
The parent_subtype_indication defines the parent subtype; its type is the parent type. The interface_list defines the progenitor types (see 3.9.4). A derived type has one parent type and zero or more progenitor types.
!corrigendum 3.4(05)
Replace the paragraph:
If there is a record_extension_part, the derived type is called a record extension of the parent type. A record_extension_part shall be provided if and only if the parent type is a tagged type.
by:
If there is a record_extension_part, the derived type is called a record extension of the parent type. A record_extension_part (and an interface_list) shall be provided if and only if the parent type is a tagged type.
!corrigendum 3.4(08)
Replace the paragraph:
by:
!corrigendum 3.4(17)
Replace the paragraph:
by:
!corrigendum 3.4(18)
Replace the paragraph:
The profile of an inherited subprogram (including an inherited enumeration literal) is obtained from the profile of the corresponding (user-defined) primitive subprogram of the parent type, after systematic replacement of each subtype of its profile (see 6.1) that is of the parent type with a corresponding subtype of the derived type. For a given subtype of the parent type, the corresponding subtype of the derived type is defined as follows:
by:
The profile of an inherited subprogram (including an inherited enumeration literal) is obtained from the profile of the corresponding (user-defined) primitive subprogram of the parent or progenitor type, after systematic replacement of each subtype of its profile (see 6.1) that is of the parent or progenitor type with a corresponding subtype of the derived type. For a given subtype of the parent or progenitor type, the corresponding subtype of the derived type is defined as follows:
!corrigendum 3.4(22)
Replace the paragraph:
The same formal parameters have default_expressions in the profile of the inherited subprogram. Any type mismatch due to the systematic replacement of the parent type by the derived type is handled as part of the normal type conversion associated with parameter passing -- see 6.4.1.
by:
The same formal parameters have default_expressions in the profile of the inherited subprogram. Any type mismatch due to the systematic replacement of the parent or progenitor type by the derived type is handled as part of the normal type conversion associated with parameter passing -- see 6.4.1.
!corrigendum 3.4(23)
Replace the paragraph:
If a primitive subprogram of the parent type is visible at the place of the derived_type_definition, then the corresponding inherited subprogram is implicitly declared immediately after the derived_type_definition. Otherwise, the inherited subprogram is implicitly declared later or not at all, as explained in 7.3.1.
by:
If a primitive subprogram of the parent or progenitor type is visible at the place of the derived_type_definition, then the corresponding inherited subprogram is implicitly declared immediately after the derived_type_definition. Otherwise, the inherited subprogram is implicitly declared later or not at all, as explained in 7.3.1.
!comment the paragraph added by AI-251 is deleted.
!corrigendum 3.4(27)
Replace the paragraph:
For the execution of a call on an inherited subprogram, a call on the corresponding primitive subprogram of the parent type is performed; the normal conversion of each actual parameter to the subtype of the corresponding formal parameter (see 6.4.1) performs any necessary type conversion as well. If the result type of the inherited subprogram is the derived type, the result of calling the parent's subprogram is converted to the derived type.
by:
For the execution of a call on an inherited subprogram, a call on the corresponding primitive subprogram of the parent or progenitor type is performed; the normal conversion of each actual parameter to the subtype of the corresponding formal parameter (see 6.4.1) performs any necessary type conversion as well. If the result type of the inherited subprogram is the derived type, the result of calling the subprogram of the parent or progenitor is converted to the derived type, or in the case of a null extension, extended to the derived type using the equivalent of an extension_aggregate with the original result as the ancestor_part and null record as the record_component_association_list.
!corrigendum 3.4(35)
Insert after the paragraph:
17 If the reserved word abstract is given in the declaration of a type, the type is abstract (see 3.9.3).
the new paragraph:
18 An interface type which has a progenitor type "is derived from" that type. A derived_type_definition, however, never defines an interface type.
!corrigendum 3.4.1(02)
Replace the paragraph:
A derived type is derived from its parent type directly; it is derived indirectly from any type from which its parent type is derived. The derivation class of types for a type T (also called the class rooted at T) is the set consisting of T (the root type of the class) and all types derived from T (directly or indirectly) plus any associated universal or class-wide types (defined below).
by:
A derived type is derived from its parent type directly; it is derived indirectly from any type from which its parent type is derived. A derived type, interface type, type extension, task type, protected type, or formal derived type is also derived from each of its progenitor types, if any. The derivation class of types for a type T (also called the class rooted at T) is the set consisting of T (the root type of the class) and all types derived from T (directly or indirectly) plus any associated universal or class-wide types (defined below).
!corrigendum 7.3(16)
Replace the paragraph:
A private extension inherits components (including discriminants unless there is a new discriminant_part specified) and user-defined primitive subprograms from its ancestor type, in the same way that a record extension inherits components and user-defined primitive subprograms from its parent type (see 3.4).
by:
A private extension inherits components (including discriminants unless there is a new discriminant_part specified) and user-defined primitive subprograms from its ancestor type and its progenitor types (if any), in the same way that a record extension inherits components and user-defined primitive subprograms from its parent type and its progenitor types (see 3.4).
!corrigendum 7.3(20)
Insert after the paragraph:
7 The ancestor type specified in a private_extension_declaration and the parent type specified in the corresponding declaration of a record extension given in the private part need not be the same — the parent type of the full view can be any descendant of the ancestor type. In this case, for a primitive subprogram that is inherited from the ancestor type and not overridden, the formal parameter names and default expressions (if any) come from the corresponding primitive subprogram of the specified ancestor type, while the body comes from the corresponding primitive subprogram of the parent type of the full view. See 3.9.2.
the new paragraph:
8 The progenitor types specified in a private_extension_declaration and the progenitor types specified in the corresponding declaration of a record extension given in the private part need not be the same — the only requirement is that the private extension must be descended from each interface from which the record extension is descended.
!corrigendum 9.1(9.1/1)
Insert after the paragraph:
For a task declaration without a task_definition, a task_definition without task_items is assumed.
the new paragraphs:
For a task_type_declaration, if the first parameter of a primitive inherited subprogram is of the task type or an access parameter designating the task type, and there is an entry_declaration for a single entry with the same identifier within the task_type_declaration, having a profile that is type conformant with that of the inherited subprogram after omitting this first parameter, the inherited subprogram is said to be implemented by the conforming task entry.
Legality Rules
A task declaration requires a completion, which shall be a task_body, and every task_body shall be the completion of some task declaration.
Each interface_subtype_mark of an interface_list appearing within a task_type_declaration shall denote a limited interface type that is not a protected interface.
For each primitive subprogram inherited by the type declared by a task_type_declaration, at most one of the following shall apply:
If neither applies, the inherited subprogram shall be a null procedure.
!corrigendum 9.4(11)
Insert after the paragraph:
A protected_definition defines a protected type and its first subtype. The list of protected_operation_declarations of a protected_definition, together with the known_discriminant_part, if any, is called the visible part of the protected unit. The optional list of protected_element_declarations after the reserved word private is called the private part of the protected unit.
the new paragraphs:
For a protected_type_declaration, the first parameter of a primitive inherited subprogram is of the protected type or an access parameter designating the protected type, and there is a protected_operation_declaration for a protected subprogram or single entry with the same identifier within the protected_type_declaration, having a profile that is type conformant with that of the inherited subprogram after omitting this first parameter, the inherited subprogram is said to be implemented by the conforming protected subprogram or entry.
Legality Rules
A protected declaration requires a completion, which shall be a protected_body, and every protected_body shall be the completion of some protected declaration.
Each interface_subtype_mark of an interface_list appearing within a protected_type_declaration shall denote a limited interface type that is not a task interface.
For each primitive subprogram inherited by the type declared by a protected_type_declaration, at most one of the following shall apply:
If neither applies, the inherited subprogram is a null procedure.
If an inherited subprogram is implemented by a protected procedure or an entry, then the first parameter of the inherited subprogram shall be of mode out or in out, or an access-to-variable parameter.
!corrigendum 12.5.1(05)
Replace the paragraph:
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, the optional reserved word abstract shall appear only if the ancestor type is a tagged type.
by:
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 word abstract shall appear only if the ancestor type is a tagged type.
The actual type for a generic formal derived type shall be a descendant of every progenitor of the formal type.
!corrigendum 12.5.1(21)
Replace the paragraph:
For a formal derived type, the predefined operators and inherited user-defined subprograms are determined by the ancestor type, and are implicitly declared at the earliest place, if any, within the immediate scope of the formal type, where the corresponding primitive subprogram of the ancestor 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 of the formal derived type, even if this primitive has been overridden for the actual type. When the ancestor 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. 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.
by:
For a formal derived type, the predefined operators and inherited user-defined subprograms are determined by the ancestor type and the 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.
!corrigendum 12.5.5(01)
!comment Just a dummy to trigger a conflict; the wording change is only in
!commentt paragraph 4.
@drepl The actual type shall be a descendant of every ancestor of the formal type. @dby The actual type shall be a descendant of every progenitor of the formal type.
!example
(See AI-251 and AI-345 for examples.)
!ACATS test
This is just terminology and minor glitches; any ACATS tests should be covered by those for the original AIs.
!appendix

****************************************************************

Questions? Ask the ACAA Technical Agent