10.2. Subunits of Compilation Units

[PREVIOUS][UP][NEXT]

A subunit is used for the separate compilation of the proper body of a program unit declared within another compilation unit. This method of splitting a program permits hierarchical program development.

    body_stub ::=
         subprogram_specification is separate;
       | package body package_simple_name is separate;
       | task body task_simple_name is separate; 

    subunit ::=
         separate (parent_unit_name) proper_body 

A body stub is only allowed as the body of a program unit (a subprogram, a package, a task unit, or a generic unit) if the body stub occurs immediately within either the specification of a library package or the declarative part of another compilation unit.

If the body of a program unit is a body stub, a separately compiled subunit containing the corresponding proper body is required. In the case of a subprogram, the subprogram specifications given in the proper body and in the body stub must conform (see 6.3.1).

Each subunit mentions the name of its parent unit, that is, the compilation unit where the corresponding body stub is given. If the parent unit is a library unit, it is called the ancestor library unit. If the parent unit is itself a subunit, the parent unit name must be given in full as an expanded name, starting with the simple name of the ancestor library unit. The simple names of all subunits that have the same ancestor library unit must be distinct identifiers.

Visibility within the proper body of a subunit is the visibility that would be obtained at the place of the corresponding body stub (within the parent unit) if the with clauses and use clauses of the subunit were appended to the context clause of the parent unit. If the parent unit is itself a subunit, then the same rule is used to define the visibility within the proper body of the parent unit.

The effect of the elaboration of a body stub is to elaborate the proper body of the subunit.

Notes:

Two subunits of different library units in the same program library need not have distinct identifiers. In any case, their full expanded names are distinct, since the simple names of library units are distinct and since the simple names of all subunits that have a given library unit as ancestor unit are also distinct. By means of renaming declarations, overloaded subprogram names that rename (distinct) subunits can be introduced.

A library unit that is named by the with clause of a subunit can be hidden by a declaration (with the same identifier) given in the proper body of the subunit. Moreover, such a library unit can even be hidden by a declaration given within a parent unit since a library unit acts as if declared in STANDARD; this however does not affect the interpretation of the with clauses themselves, since only names of library units can appear in with clauses.

References: compilation unit, conform, context clause, declaration, declarative part, direct visibility, elaboration, expanded name, generic body, generic unit, hidden declaration, identifier, library unit, local declaration, name, occur immediately within, overloading, package, package body, package specification, program, program unit, proper body, renaming declaration, separate compilation, simple name, subprogram, subprogram body, subprogram specification, task, task body, task unit, use clause, visibility, with clause.

Sub-topics:

10.2.1. Examples of Subunits

[UP]

The procedure TOP is first written as a compilation unit without subunits.

    with TEXT_IO;
    procedure TOP is 

       type REAL is digits 10;
       R, S : REAL := 1.0; 

       package FACILITY is
          PI : constant := 3.14159_26536;
          function  F(X : REAL) return REAL;
          procedure G(Y, Z : REAL);
       end FACILITY; 

       package body FACILITY is
          --  some local declarations followed by  

          function F(X : REAL) return REAL is
          begin
             --  sequence of statements of F
             ...
          end F; 
          procedure G(Y, Z : REAL) is
             --  local procedures using TEXT_IO
             ...
          begin
             --  sequence of statements of G
             ...
          end G;
       end FACILITY; 

       procedure TRANSFORM(U : in out REAL) is
          use FACILITY;
       begin
          U := F(U);
          ...
       end TRANSFORM;
    begin -- TOP  
       TRANSFORM(R);
       ...
       FACILITY.G(R, S);
    end TOP;                                                                          

The body of the package FACILITY and that of the procedure TRANSFORM can be made into separate subunits of TOP. Similarly, the body of the procedure G can be made into a subunit of FACILITY as follows.

Example 3:

    procedure TOP is 

       type REAL is digits 10;
       R, S : REAL := 1.0; 

       package FACILITY is
          PI : constant := 3.14159_26536;
          function  F(X : REAL) return REAL;
          procedure G(Y, Z : REAL);
       end FACILITY; 

     package body FACILITY is separate;                 --  stub of FACILITY
     procedure TRANSFORM(U : in out REAL) is separate;  --  stub of TRANSFORM

    begin  --  TOP
       TRANSFORM(R);
       ...
       FACILITY.G(R, S);
    end TOP; 

    ------------------------------------------------- 

    separate (TOP)
    procedure TRANSFORM(U : in out REAL) is
       use FACILITY;
    begin
       U := F(U);
       ...   
    end TRANSFORM; 

    ------------------------------------------------- 

    separate (TOP)
    package body FACILITY is
       --  some local declarations followed by 

       function F(X : REAL) return REAL is
       begin
          --  sequence of statements of F
          ...
       end F; 

       procedure G(Y, Z : REAL) is separate;              -- stub of G
    end FACILITY;                                                                      

    ------------------------------------------------- 

    with TEXT_IO;
    separate (TOP.FACILITY)  --  full name of FACILITY
    procedure G(Y, Z : REAL) is
       --  local procedures using TEXT_IO
       ...
    begin
       --  sequence of statements of G
       ...
    end G; 

In the above example TRANSFORM and FACILITY are subunits of TOP, and G is a subunit of FACILITY. The visibility in the split version is the same as in the initial version except for one change: since TEXT_IO is only used within G, the corresponding with clause is written for G instead of for TOP. Apart from this change, the same identifiers are visible at corresponding program points in the two versions. For example, all of the following are (directly) visible within the proper body of the subunit G: the procedure TOP, the type REAL, the variables R and S, the package FACILITY and the contained named number PI and subprograms F and G.

References: body stub, compilation unit, identifier, local declaration, named number, package, package body, procedure, procedure body, proper body, subprogram, type, variable, visibility, with clause.


[INDEX][CONTENTS]