1
[Subunits are like child units, with these (important) differences: subunits support the separate compilation of bodies only (not declarations); the parent contains a body_stub to indicate the existence and place of each of its subunits; declarations appearing in the parent's body can be visible within the subunits.]
2
body_stub::= subprogram_body_stub | package_body_stub | task_body_stub | protected_body_stub
3/2
{20218AI95−00218−03} subprogram_body_stub::=
[overriding_indicator]
subprogram_specification is separate;
3.a
Discussion: Although this syntax allows a parent_unit_name, that is disallowed by 10.1.1, "10.1.1 Compilation Units - Library Units".
4
package_body_stub::= package body defining_identifier is separate;
5
task_body_stub::= task body defining_identifier is separate;
6
protected_body_stub::= protected body defining_identifier is separate;
7
subunit::= separate (parent_unit_name) proper_body
8/2
{00243AI95−00243−01} {parent body (of a subunit)} The parent body of a subunit is the body of the program unit denoted by its parent_unit_name. {subunit} The term subunit is used to refer to a subunit and also to the proper_body of a subunit. The subunits of a program unit include any subunit that names that program unit as its parent, as well as any subunit that names such a subunit as its parent (recursively).{subunit (of a program unit)} 8.a.1/2
Reason: {00243AI95−00243−01} We want any rule that applies to a subunit to apply to a subunit of a subunit as well.
9
The parent body of a subunit shall be present in the current environment, and shall contain a corresponding body_stub with the same defining_identifier as the subunit.
9.a
Discussion: This can't be a Name Resolution Rule, because a subunit is not a complete context.
10/2
A package_body_stub shall be the completion of a package_declaration (see 7.1) or generic_package_declaration (see 12.1); a task_body_stub (see 10.1.3) shall be the completion of a task declaration; a protected_body_stub (see 10.1.3) shall be the completion of a protected declaration.
11
In contrast, a subprogram_body_stub need not be the completion of a previous declaration, [in which case the _stub declares the subprogram]. If the _stub is a completion, it shall be the completion of a subprogram_declaration or generic_subprogram_declaration. The profile of a subprogram_body_stub that completes a declaration shall conform fully to that of the declaration. {full conformance (required)} 11.a
Discussion: The part about subprogram_body_stubs echoes the corresponding rule for subprogram_bodies in 6.3, "6.3 Subprogram Bodies".
12
A subunit that corresponds to a body_stub shall be of the same kind (package_, subprogram_, task_, or protected_) as the body_stub. The profile of a subprogram_body subunit shall be fully conformant to that of the corresponding body_stub. {full conformance (required)} 13
A body_stub shall appear immediately within the declarative_part of a compilation unit body. This rule does not apply within an instance of a generic unit.
13.a
Discussion: {methodological restriction} This is a methodological restriction; that is, it is not necessary for the semantics of the language to make sense.
14
The defining_identifiers of all body_stubs that appear immediately within a particular declarative_part shall be distinct.
15
For each body_stub, there shall be a subunit containing the corresponding proper_body.
NOTES
16
4 The rules in 10.1.4, "10.1.4 The Compilation Process" say that a body_stub is equivalent to the corresponding proper_body. This implies:
17
- Visibility within a subunit is the visibility that would be obtained at the place of the corresponding body_stub (within the parent body) if the context_clause of the subunit were appended to that of the parent body.
17.a
Ramification: Recursively. Note that this transformation might make the parent illegal; hence it is not a true equivalence, but applies only to visibility within the subunit.
18
- The effect of the elaboration of a body_stub is to elaborate the subunit.
18.a
Ramification: The elaboration of a subunit is part of its parent body's elaboration, whereas the elaboration of a child unit is not part of its parent declaration's elaboration.
18.b
Ramification: A library_item that is mentioned in a with_clause of a subunit can be hidden (from direct visibility) by a declaration (with the same identifier) given in the subunit. Moreover, such a library_item can even be hidden by a declaration given within the parent body since a library unit is declared in its parent's declarative region; this however does not affect the interpretation of the with_clauses themselves, since only library_items are visible or directly visible in with_clauses.
18.c
The body of a protected operation cannot be a subunit. This follows from the syntax rules. The body of a protected unit can be a subunit.
19
The package Parent is first written without subunits:
20
package Parent is procedure Inner; end Parent;
21
with Ada.Text_IO; package body Parent is Variable : String := "Hello, there."; procedure Inner is begin Ada.Text_IO.Put_Line(Variable); end Inner; end Parent;
22
The body of procedure Inner may be turned into a subunit by rewriting the package body as follows (with the declaration of Parent remaining the same):
23
package body Parent is Variable : String := "Hello, there."; procedure Inner is separate; end Parent;
24
with Ada.Text_IO; separate(Parent) procedure Inner is begin Ada.Text_IO.Put_Line(Variable); end Inner;
24.a
{extensions to Ada 83} Subunits of the same ancestor library unit are no longer restricted to have distinct identifiers. Instead, we require only that the full expanded names be distinct.
24.b/2
{20218AI95−00218−03} {extensions to Ada 95} An overriding_indicator (see 8.3.1) is allowed on a subprogram stub.
24.c/2
{00243AI95−00243−01} Clarified that a subunit of a subunit is still a subunit.