dwww Home | Show directory contents | Find package


                10   Program Structure and Compilation Issues


1/3 The overall structure of programs and the facilities for separate
compilation are described in this clause. A program is a set of partitions,
each of which may execute in a separate address space, possibly on a separate
computer.

2   As explained below, a partition is constructed from library units.
Syntactically, the declaration of a library unit is a library_item, as is the
body of a library unit. An implementation may support a concept of a program
library (or simply, a "library"), which contains library_items and their
subunits. Library units may be organized into a hierarchy of children,
grandchildren, and so on.

3/3 This clause has two subclauses: 10.1, "Separate Compilation" discusses
compile-time issues related to separate compilation. 10.2, "
Program Execution" discusses issues related to what is traditionally known as
"link time" and "run time" - building and executing partitions.


10.1 Separate Compilation


1   A program unit is either a package, a task unit, a protected unit, a
protected entry, a generic unit, or an explicitly declared subprogram other
than an enumeration literal. Certain kinds of program units can be separately
compiled. Alternatively, they can appear physically nested within other
program units.

2   The text of a program can be submitted to the compiler in one or more
compilations. Each compilation is a succession of compilation_units. A
compilation_unit contains either the declaration, the body, or a renaming of a
program unit. The representation for a compilation is implementation-defined.

3   A library unit is a separately compiled program unit, and is always a
package, subprogram, or generic unit. Library units may have other (logically
nested) library units as children, and may have other program units physically
nested within them. A root library unit, together with its children and
grandchildren and so on, form a subsystem.


                         Implementation Permissions

4   An implementation may impose implementation-defined restrictions on
compilations that contain multiple compilation_units.


10.1.1 Compilation Units - Library Units


1   A library_item is a compilation unit that is the declaration, body, or
renaming of a library unit. Each library unit (except Standard) has a parent
unit, which is a library package or generic library package. A library unit is
a child of its parent unit. The root library units are the children of the
predefined library package Standard.


                                   Syntax

2       compilation ::= {compilation_unit}

3       compilation_unit ::= 
            context_clause library_item
          | context_clause subunit

4       library_item ::= [private] library_unit_declaration
          | library_unit_body
          | [private] library_unit_renaming_declaration

5       library_unit_declaration ::= 
             subprogram_declaration   | package_declaration
           | generic_declaration      | generic_instantiation

6       library_unit_renaming_declaration ::= 
           package_renaming_declaration
         | generic_renaming_declaration
         | subprogram_renaming_declaration

7       library_unit_body ::= subprogram_body | package_body

8       parent_unit_name ::= name

8.1/2   An overriding_indicator is not allowed in a subprogram_declaration,
        generic_instantiation, or subprogram_renaming_declaration that
        declares a library unit.

9   A library unit is a program unit that is declared by a library_item. When
a program unit is a library unit, the prefix "library" is used to refer to it
(or "generic library" if generic), as well as to its declaration and body, as
in "library procedure", "library package_body", or "generic library package".
The term compilation unit is used to refer to a compilation_unit. When the
meaning is clear from context, the term is also used to refer to the
library_item of a compilation_unit or to the proper_body of a subunit (that
is, the compilation_unit without the context_clause and the separate
(parent_unit_name)).

10  The parent declaration of a library_item (and of the library unit) is the
declaration denoted by the parent_unit_name, if any, of the defining_program_-
unit_name of the library_item. If there is no parent_unit_name, the parent
declaration is the declaration of Standard, the library_item is a root
library_item, and the library unit (renaming) is a root library unit
(renaming). The declaration and body of Standard itself have no parent
declaration. The parent unit of a library_item or library unit is the library
unit declared by its parent declaration.

11  The children of a library unit occur immediately within the declarative
region of the declaration of the library unit. The ancestors of a library unit
are itself, its parent, its parent's parent, and so on. (Standard is an
ancestor of every library unit.) The descendant relation is the inverse of the
ancestor relation.

12  A library_unit_declaration or a library_unit_renaming_declaration is
private if the declaration is immediately preceded by the reserved word
private; it is otherwise public. A library unit is private or public according
to its declaration. The public descendants of a library unit are the library
unit itself, and the public descendants of its public children. Its other
descendants are private descendants.

12.1/2 For each library package_declaration in the environment, there is an
implicit declaration of a limited view of that library package. The limited
view of a package contains:

12.2/3   * For each package_declaration occurring immediately within the
        visible part, a declaration of the limited view of that package, with
        the same defining_program_unit_name.

12.3/3   * For each type_declaration occurring immediately within the visible
        part that is not an incomplete_type_declaration, an incomplete view of
        the type with no discriminant_part; if the type_declaration is tagged,
        then the view is a tagged incomplete view.

12.4/2 The limited view of a library package_declaration is private if that
library package_declaration is immediately preceded by the reserved word
private.

12.5/2 There is no syntax for declaring limited views of packages, because
they are always implicit. The implicit declaration of a limited view of a
library package is not the declaration of a library unit (the library
package_declaration is); nonetheless, it is a library_item. The implicit
declaration of the limited view of a library package forms an (implicit)
compilation unit whose context_clause is empty.

12.6/2 A library package_declaration is the completion of the declaration of
its limited view.


                               Legality Rules

13  The parent unit of a library_item shall be a library package or generic
library package.

14  If a defining_program_unit_name of a given declaration or body has a
parent_unit_name, then the given declaration or body shall be a library_item.
The body of a program unit shall be a library_item if and only if the
declaration of the program unit is a library_item. In a library_unit_renaming_-
declaration, the (old) name shall denote a library_item.

15/2 A parent_unit_name (which can be used within a
defining_program_unit_name of a library_item and in the separate clause of a
subunit), and each of its prefixes, shall not denote a renaming_declaration.
On the other hand, a name that denotes a library_unit_renaming_declaration is
allowed in a nonlimited_with_clause and other places where the name of a
library unit is allowed.

16  If a library package is an instance of a generic package, then every child
of the library package shall either be itself an instance or be a renaming of
a library unit.

17/3 A child of a generic library package shall either be itself a generic
unit or be a renaming of some other child of the same generic unit.

18  A child of a parent generic package shall be instantiated or renamed only
within the declarative region of the parent generic.

19/2 For each child C of some parent generic package P, there is a
corresponding declaration C nested immediately within each instance of P. For
the purposes of this rule, if a child C itself has a child D, each
corresponding declaration for C has a corresponding child D. The corresponding
declaration for a child within an instance is visible only within the scope of
a with_clause that mentions the (original) child generic unit.

20  A library subprogram shall not override a primitive subprogram.

21  The defining name of a function that is a compilation unit shall not be an
operator_symbol.


                              Static Semantics

22  A subprogram_renaming_declaration that is a
library_unit_renaming_declaration is a renaming-as-declaration, not a
renaming-as-body.

23  There are two kinds of dependences among compilation units:

24    * The semantic dependences (see below) are the ones needed to check the
        compile-time rules across compilation unit boundaries; a compilation
        unit depends semantically on the other compilation units needed to
        determine its legality. The visibility rules are based on the semantic
        dependences.

25    * The elaboration dependences (see 10.2) determine the order of
        elaboration of library_items.

26/2 A library_item depends semantically upon its parent declaration. A
subunit depends semantically upon its parent body. A library_unit_body depends
semantically upon the corresponding library_unit_declaration, if any. The
declaration of the limited view of a library package depends semantically upon
the declaration of the limited view of its parent. The declaration of a
library package depends semantically upon the declaration of its limited view.
A compilation unit depends semantically upon each library_item mentioned in a
with_clause of the compilation unit. In addition, if a given compilation unit
contains an attribute_reference of a type defined in another compilation unit,
then the given compilation unit depends semantically upon the other
compilation unit. The semantic dependence relationship is transitive.


                              Dynamic Semantics

26.1/2 The elaboration of the declaration of the limited view of a package has
no effect.

        NOTES

27      1  A simple program may consist of a single compilation unit. A
        compilation need not have any compilation units; for example, its text
        can consist of pragmas.

28      2  The designator of a library function cannot be an operator_symbol,
        but a nonlibrary renaming_declaration is allowed to rename a library
        function as an operator. Within a partition, two library subprograms
        are required to have distinct names and hence cannot overload each
        other. However, renaming_declarations are allowed to define overloaded
        names for such subprograms, and a locally declared subprogram is
        allowed to overload a library subprogram. The expanded name Standard.L
        can be used to denote a root library unit L (unless the declaration of
        Standard is hidden) since root library unit declarations occur
        immediately within the declarative region of package Standard.


                                  Examples

29  Examples of library units:

30      package Rational_Numbers.IO is  -- public child of Rational_Numbers, see 7.1
           procedure Put(R : in  Rational);
           procedure Get(R : out Rational);
        end Rational_Numbers.IO;

31      private procedure Rational_Numbers.Reduce(R : in out Rational);
                                        -- private child of Rational_Numbers

32      with Rational_Numbers.Reduce;   -- refer to a private child
        package body Rational_Numbers is
           ...
        end Rational_Numbers;

33      with Rational_Numbers.IO; use Rational_Numbers;
        with Ada.Text_io;               -- see A.10
        procedure Main is               -- a root library procedure
           R : Rational;
        begin
           R := 5/3;                    -- construct a rational number, see 7.1
           Ada.Text_IO.Put("The answer is: ");
           IO.Put(R);
           Ada.Text_IO.New_Line;
        end Main;

34      with Rational_Numbers.IO;
        package Rational_IO renames Rational_Numbers.IO;
                                        -- a library unit renaming declaration

35  Each of the above library_items can be submitted to the compiler
separately.


10.1.2 Context Clauses - With Clauses


1   A context_clause is used to specify the library_items whose names are
needed within a compilation unit.


                                   Syntax

2       context_clause ::= {context_item}

3       context_item ::= with_clause | use_clause

4/2     with_clause ::= limited_with_clause | nonlimited_with_clause

4.1/2   limited_with_clause ::= limited [private] with library_unit_name
         {, library_unit_name};

4.2/2   nonlimited_with_clause ::= [private] with library_unit_name
         {, library_unit_name};


                            Name Resolution Rules

5   The scope of a with_clause that appears on a library_unit_declaration or
library_unit_renaming_declaration consists of the entire declarative region of
the declaration, which includes all children and subunits. The scope of a
with_clause that appears on a body consists of the body, which includes all
subunits.

6/2 A library_item (and the corresponding library unit) is named in a
with_clause if it is denoted by a library_unit_name in the with_clause. A
library_item (and the corresponding library unit) is mentioned in a
with_clause if it is named in the with_clause or if it is denoted by a
prefix in the with_clause.

7   Outside its own declarative region, the declaration or renaming of a
library unit can be visible only within the scope of a with_clause that
mentions it. The visibility of the declaration or renaming of a library unit
otherwise follows from its placement in the environment.


                               Legality Rules

8/2 If a with_clause of a given compilation_unit mentions a private child of
some library unit, then the given compilation_unit shall be one of:

9/2   * the declaration, body, or subunit of a private descendant of that
        library unit;

10/2   * the body or subunit of a public descendant of that library unit, but
        not a subprogram body acting as a subprogram declaration (see 10.1.4
        ); or

11/2   * the declaration of a public descendant of that library unit, in which
        case the with_clause shall include the reserved word private.

12/3 A name denoting a library_item (or the corresponding declaration for a
child of a generic within an instance - see 10.1.1), if it is visible only due
to being mentioned in one or more with_clauses that include the reserved word
private, shall appear only within:

13/2   * a private part;

14/2   * a body, but not within the subprogram_specification of a library
        subprogram body;

15/2   * a private descendant of the unit on which one of these with_clauses
        appear; or

16/2   * a pragma within a context clause.

17/2 A library_item mentioned in a limited_with_clause shall be the implicit
declaration of the limited view of a library package, not the declaration of a
subprogram, generic unit, generic instance, or a renaming.

18/2 A limited_with_clause shall not appear on a library_unit_body, subunit,
or library_unit_renaming_declaration.

19/2 A limited_with_clause that names a library package shall not appear:

20/3   * in the context_clause for the explicit declaration of the named
        library package or any of its descendants;

21/3   * within a context_clause for a library_item that is within the scope
        of a nonlimited_with_clause that mentions the same library package; or

22/3   * within a context_clause for a library_item that is within the scope
        of a use_clause that names an entity declared within the declarative
        region of the library package.

        NOTES

23/2    3  A library_item mentioned in a nonlimited_with_clause of a
        compilation unit is visible within the compilation unit and hence acts
        just like an ordinary declaration. Thus, within a compilation unit
        that mentions its declaration, the name of a library package can be
        given in use_clauses and can be used to form expanded names, a library
        subprogram can be called, and instances of a generic library unit can
        be declared. If a child of a parent generic package is mentioned in a
        nonlimited_with_clause, then the corresponding declaration nested
        within each visible instance is visible within the compilation unit.
        Similarly, a library_item mentioned in a limited_with_clause of a
        compilation unit is visible within the compilation unit and thus can
        be used to form expanded names.


                                  Examples

24/2    package Office is
        end Office;

25/2    with Ada.Strings.Unbounded;
        package Office.Locations is
           type Location is new Ada.Strings.Unbounded.Unbounded_String;
        end Office.Locations;

26/2    limited with Office.Departments;  -- types are incomplete
        private with Office.Locations;    -- only visible in private part
        package Office.Employees is
           type Employee is private;

27/2       function Dept_Of(Emp : Employee) return access Departments.Department;
           procedure Assign_Dept(Emp  : in out Employee;
                                 Dept : access Departments.Department);

28/2       ...
        private
           type Employee is
              record
                 Dept : access Departments.Department;
                 Loc : Locations.Location;
                 ...
              end record;
        end Office.Employees;

29/2    limited with Office.Employees;
        package Office.Departments is
           type Department is private;

30/2       function Manager_Of(Dept : Department) return access Employees.Employee;
           procedure Assign_Manager(Dept : in out Department;
                                    Mgr  : access Employees.Employee);
           ...
        end Office.Departments;

31/2 The limited_with_clause may be used to support mutually dependent
abstractions that are split across multiple packages. In this case, an
employee is assigned to a department, and a department has a manager who is an
employee. If a with_clause with the reserved word private appears on one
library unit and mentions a second library unit, it provides visibility to the
second library unit, but restricts that visibility to the private part and
body of the first unit. The compiler checks that no use is made of the second
unit in the visible part of the first unit.


10.1.3 Subunits of Compilation Units


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.


                                   Syntax

2       body_stub ::= subprogram_body_stub | package_body_stub
         | task_body_stub | protected_body_stub

3/3     subprogram_body_stub ::= 
           [overriding_indicator]
           subprogram_specification is separate
              [aspect_specification];

4/3     package_body_stub ::= 
           package body defining_identifier is separate
              [aspect_specification];

5/3     task_body_stub ::= 
           task body defining_identifier is separate
              [aspect_specification];

6/3     protected_body_stub ::= 
           protected body defining_identifier is separate
              [aspect_specification];

7       subunit ::= separate (parent_unit_name) proper_body


                               Legality Rules

8/2 The parent body of a subunit is the body of the program unit denoted by
its parent_unit_name. 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).

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.

10/3 A package_body_stub shall be the completion of a package_declaration or
generic_package_declaration; a task_body_stub shall be the completion of a
task declaration; a protected_body_stub 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.

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.

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.

14  The defining_identifiers of all body_stubs that appear immediately within
a particular declarative_part shall be distinct.


                           Post-Compilation Rules

15  For each body_stub, there shall be a subunit containing the corresponding
proper_body.

        NOTES

16      4  The rules in 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.

18        * The effect of the elaboration of a body_stub is to elaborate the
            subunit.


                                  Examples

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;


10.1.4 The Compilation Process


1   Each compilation unit submitted to the compiler is compiled in the context
of an environment declarative_part (or simply, an environment), which is a
conceptual declarative_part that forms the outermost declarative region of the
context of any compilation. At run time, an environment forms the
declarative_part of the body of the environment task of a partition (see
10.2, "Program Execution").

2   The declarative_items of the environment are library_items appearing in an
order such that there are no forward semantic dependences. Each included
subunit occurs in place of the corresponding stub. The visibility rules apply
as if the environment were the outermost declarative region, except that with_-
clauses are needed to make declarations of library units visible (see 10.1.2).

3/2 The mechanisms for creating an environment and for adding and replacing
compilation units within an environment are implementation defined. The
mechanisms for adding a compilation unit mentioned in a limited_with_clause to
an environment are implementation defined.


                            Name Resolution Rules

4/3 If a library_unit_body that is a subprogram_body is submitted to the
compiler, it is interpreted only as a completion if a
library_unit_declaration with the same defining_program_unit_name already
exists in the environment for a subprogram other than an instance of a generic
subprogram or for a generic subprogram (even if the profile of the body is not
type conformant with that of the declaration); otherwise, the
subprogram_body is interpreted as both the declaration and body of a library
subprogram.


                               Legality Rules

5   When a compilation unit is compiled, all compilation units upon which it
depends semantically shall already exist in the environment; the set of these
compilation units shall be consistent in the sense that the new compilation
unit shall not semantically depend (directly or indirectly) on two different
versions of the same compilation unit, nor on an earlier version of itself.


                         Implementation Permissions

6/2 The implementation may require that a compilation unit be legal before it
can be mentioned in a limited_with_clause or it can be inserted into the
environment.

7/3 When a compilation unit that declares or renames a library unit is added
to the environment, the implementation may remove from the environment any
preexisting library_item or subunit with the same full expanded name. When a
compilation unit that is a subunit or the body of a library unit is added to
the environment, the implementation may remove from the environment any
preexisting version of the same compilation unit. When a compilation unit that
contains a body_stub is added to the environment, the implementation may
remove any preexisting library_item or subunit with the same full expanded
name as the body_stub. When a given compilation unit is removed from the
environment, the implementation may also remove any compilation unit that
depends semantically upon the given one. If the given compilation unit
contains the body of a subprogram for which aspect Inline is True, the
implementation may also remove any compilation unit containing a call to that
subprogram.

        NOTES

8       5  The rules of the language are enforced across compilation and
        compilation unit boundaries, just as they are enforced within a single
        compilation unit.

9       6  An implementation may support a concept of a library, which
        contains library_items. If multiple libraries are supported, the
        implementation has to define how a single environment is constructed
        when a compilation unit is submitted to the compiler. Naming conflicts
        between different libraries might be resolved by treating each library
        as the root of a hierarchy of child library units.

10      7  A compilation unit containing an instantiation of a separately
        compiled generic unit does not semantically depend on the body of the
        generic unit. Therefore, replacing the generic body in the environment
        does not result in the removal of the compilation unit containing the
        instantiation.


10.1.5 Pragmas and Program Units


1   This subclause discusses pragmas related to program units, library units,
and compilations.


                            Name Resolution Rules

2   Certain pragmas are defined to be program unit pragmas. A name given as
the argument of a program unit pragma shall resolve to denote the declarations
or renamings of one or more program units that occur immediately within the
declarative region or compilation in which the pragma immediately occurs, or
it shall resolve to denote the declaration of the immediately enclosing
program unit (if any); the pragma applies to the denoted program unit(s). If
there are no names given as arguments, the pragma applies to the immediately
enclosing program unit.


                               Legality Rules

3   A program unit pragma shall appear in one of these places:

4     * At the place of a compilation_unit, in which case the pragma shall
        immediately follow in the same compilation (except for other pragmas)
        a library_unit_declaration that is a subprogram_declaration, generic_-
        subprogram_declaration, or generic_instantiation, and the pragma shall
        have an argument that is a name denoting that declaration.

5/1   * Immediately within the visible part of a program unit and before any
        nested declaration (but not within a generic formal part), in which
        case the argument, if any, shall be a direct_name that denotes the
        immediately enclosing program unit declaration.

6     * At the place of a declaration other than the first, of a
        declarative_part or program unit declaration, in which case the
        pragma shall have an argument, which shall be a direct_name that
        denotes one or more of the following (and nothing else): a subprogram_-
        declaration, a generic_subprogram_declaration, or a
        generic_instantiation, of the same declarative_part or program unit
        declaration.

7/3 Certain program unit pragmas are defined to be library unit pragmas. If a
library unit pragma applies to a program unit, the program unit shall be a
library unit.


                              Static Semantics

7.1/1 A library unit pragma that applies to a generic unit does not apply to
its instances, unless a specific rule for the pragma specifies the contrary.


                           Post-Compilation Rules

8   Certain pragmas are defined to be configuration pragmas; they shall appear
before the first compilation_unit of a compilation. They are generally used to
select a partition-wide or system-wide option. The pragma applies to all
compilation_units appearing in the compilation, unless there are none, in
which case it applies to all future compilation_units compiled into the same
environment.


                         Implementation Permissions

9/2 An implementation may require that configuration pragmas that select
partition-wide or system-wide options be compiled when the environment
contains no library_items other than those of the predefined environment. In
this case, the implementation shall still accept configuration pragmas in
individual compilations that confirm the initially selected partition-wide or
system-wide options.


                            Implementation Advice

10/1 When applied to a generic unit, a program unit pragma that is not a
library unit pragma should apply to each instance of the generic unit for
which there is not an overriding pragma applied directly to the instance.


10.1.6 Environment-Level Visibility Rules


1   The normal visibility rules do not apply within a parent_unit_name or a
context_clause, nor within a pragma that appears at the place of a compilation
unit. The special visibility rules for those contexts are given here.


                              Static Semantics

2/2 Within the parent_unit_name at the beginning of an explicit library_item,
and within a nonlimited_with_clause, the only declarations that are visible
are those that are explicit library_items of the environment, and the only
declarations that are directly visible are those that are explicit root
library_items of the environment. Within a limited_with_clause, the only
declarations that are visible are those that are the implicit declaration of
the limited view of a library package of the environment, and the only
declarations that are directly visible are those that are the implicit
declaration of the limited view of a root library package.

3   Within a use_clause or pragma that is within a context_clause, each
library_item mentioned in a previous with_clause of the same context_clause is
visible, and each root library_item so mentioned is directly visible. In
addition, within such a use_clause, if a given declaration is visible or
directly visible, each declaration that occurs immediately within the given
declaration's visible part is also visible. No other declarations are visible
or directly visible.

4   Within the parent_unit_name of a subunit, library_items are visible as
they are in the parent_unit_name of a library_item; in addition, the
declaration corresponding to each body_stub in the environment is also
visible.

5   Within a pragma that appears at the place of a compilation unit, the
immediately preceding library_item and each of its ancestors is visible. The
ancestor root library_item is directly visible.

6/2 Notwithstanding the rules of 4.1.3, an expanded name in a with_clause, a
pragma in a context_clause, or a pragma that appears at the place of a
compilation unit may consist of a prefix that denotes a generic package and a
selector_name that denotes a child of that generic package. (The child is
necessarily a generic unit; see 10.1.1.)


10.2 Program Execution


1   An Ada program consists of a set of partitions, which can execute in
parallel with one another, possibly in a separate address space, and possibly
on a separate computer.


                           Post-Compilation Rules

2   A partition is a program or part of a program that can be invoked from
outside the Ada implementation. For example, on many systems, a partition
might be an executable file generated by the system linker. The user can
explicitly assign library units to a partition. The assignment is done in an
implementation-defined manner. The compilation units included in a partition
are those of the explicitly assigned library units, as well as other
compilation units needed by those library units. The compilation units needed
by a given compilation unit are determined as follows (unless specified
otherwise via an implementation-defined pragma, or by some other
implementation-defined means):

3     * A compilation unit needs itself;

4     * If a compilation unit is needed, then so are any compilation units
        upon which it depends semantically;

5     * If a library_unit_declaration is needed, then so is any corresponding
        library_unit_body;

6/2   * If a compilation unit with stubs is needed, then so are any
        corresponding subunits;

6.1/2   * If the (implicit) declaration of the limited view of a library
        package is needed, then so is the explicit declaration of the library
        package.

7   The user can optionally designate (in an implementation-defined manner)
one subprogram as the main subprogram for the partition. A main subprogram, if
specified, shall be a subprogram.

8   Each partition has an anonymous environment task, which is an implicit
outermost task whose execution elaborates the library_items of the environment
declarative_part, and then calls the main subprogram, if there is one. A
partition's execution is that of its tasks.

9   The order of elaboration of library units is determined primarily by the
elaboration dependences. There is an elaboration dependence of a given
library_item upon another if the given library_item or any of its subunits
depends semantically on the other library_item. In addition, if a given
library_item or any of its subunits has a pragma Elaborate or Elaborate_All
that names another library unit, then there is an elaboration dependence of
the given library_item upon the body of the other library unit, and, for
Elaborate_All only, upon each library_item needed by the declaration of the
other library unit.

10  The environment task for a partition has the following structure:

11      task Environment_Task;

12      task body Environment_Task is
            ... (1) -- The environment declarative_part
                    -- (that is, the sequence of library_items) goes here.
        begin
            ... (2) -- Call the main subprogram, if there is one.
        end Environment_Task;

13  The environment declarative_part at (1) is a sequence of
declarative_items consisting of copies of the library_items included in the
partition. The order of elaboration of library_items is the order in which
they appear in the environment declarative_part:

14    * The order of all included library_items is such that there are no
        forward elaboration dependences.

15/3   * Any included library_unit_declaration for which aspect Elaborate_Body
        is True (including when a pragma Elaborate_Body applies) is
        immediately followed by its library_unit_body, if included.

16    * All library_items declared pure occur before any that are not declared
        pure.

17    * All preelaborated library_items occur before any that are not
        preelaborated.

18  There shall be a total order of the library_items that obeys the above
rules. The order is otherwise implementation defined.

19  The full expanded names of the library units and subunits included in a
given partition shall be distinct.

20  The sequence_of_statements of the environment task (see (2) above)
consists of either:

21    * A call to the main subprogram, if the partition has one. If the main
        subprogram has parameters, they are passed; where the actuals come
        from is implementation defined. What happens to the result of a main
        function is also implementation defined.

22  or:

23    * A null_statement, if there is no main subprogram.

24  The mechanisms for building and running partitions are implementation
defined. These might be combined into one operation, as, for example, in
dynamic linking, or "load-and-go" systems.


                              Dynamic Semantics

25  The execution of a program consists of the execution of a set of
partitions. Further details are implementation defined. The execution of a
partition starts with the execution of its environment task, ends when the
environment task terminates, and includes the executions of all tasks of the
partition. The execution of the (implicit) task_body of the environment task
acts as a master for all other tasks created as part of the execution of the
partition. When the environment task completes (normally or abnormally), it
waits for the termination of all such tasks, and then finalizes any remaining
objects of the partition.


                          Bounded (Run-Time) Errors

26  Once the environment task has awaited the termination of all other tasks
of the partition, any further attempt to create a task (during finalization)
is a bounded error, and may result in the raising of Program_Error either upon
creation or activation of the task. If such a task is activated, it is not
specified whether the task is awaited prior to termination of the environment
task.


                         Implementation Requirements

27  The implementation shall ensure that all compilation units included in a
partition are consistent with one another, and are legal according to the
rules of the language.


                         Implementation Permissions

28/3 The kind of partition described in this subclause is known as an active
partition. An implementation is allowed to support other kinds of partitions,
with implementation-defined semantics.

29  An implementation may restrict the kinds of subprograms it supports as
main subprograms. However, an implementation is required to support all main
subprograms that are public parameterless library procedures.

30  If the environment task completes abnormally, the implementation may abort
any dependent tasks.

        NOTES

31      8  An implementation may provide inter-partition communication
        mechanism(s) via special packages and pragmas. Standard pragmas for
        distribution and methods for specifying inter-partition communication
        are defined in Annex E, "Distributed Systems". If no such mechanisms
        are provided, then each partition is isolated from all others, and
        behaves as a program in and of itself.

32      9  Partitions are not required to run in separate address spaces. For
        example, an implementation might support dynamic linking via the
        partition concept.

33      10  An order of elaboration of library_items that is consistent with
        the partial ordering defined above does not always ensure that each
        library_unit_body is elaborated before any other compilation unit
        whose elaboration necessitates that the library_unit_body be already
        elaborated. (In particular, there is no requirement that the body of a
        library unit be elaborated as soon as possible after the
        library_unit_declaration is elaborated, unless the pragmas in
        subclause 10.2.1 are used.)

34      11  A partition (active or otherwise) need not have a main subprogram.
        In such a case, all the work done by the partition would be done by
        elaboration of various library_items, and by tasks created by that
        elaboration. Passive partitions, which cannot have main subprograms,
        are defined in Annex E, "Distributed Systems".


10.2.1 Elaboration Control


1   This subclause defines pragmas that help control the elaboration order of
library_items.


                                   Syntax

2       The form of a pragma Preelaborate is as follows:

3         pragma Preelaborate[(library_unit_name)];

4       A pragma Preelaborate is a library unit pragma.

4.1/2   The form of a pragma Preelaborable_Initialization is as follows:

4.2/2     pragma Preelaborable_Initialization(direct_name);


                               Legality Rules

5   An elaborable construct is preelaborable unless its elaboration performs
any of the following actions:

6     * The execution of a statement other than a null_statement.

7     * A call to a subprogram other than a static function.

8     * The evaluation of a primary that is a name of an object, unless the
        name is a static expression, or statically denotes a discriminant of
        an enclosing type.

9/3   * The creation of an object (including a component) that is initialized
        by default, if its type does not have preelaborable initialization.
        Similarly, the evaluation of an extension_aggregate with an ancestor
        subtype_mark denoting a subtype of such a type.

10/2 A generic body is preelaborable only if elaboration of a corresponding
instance body would not perform any such actions, presuming that:

10.1/3   * the actual for each discriminated formal derived type, formal
        private type, or formal private extension declared within the formal
        part of the generic unit is a type that does not have preelaborable
        initialization, unless pragma Preelaborable_Initialization has been
        applied to the formal type;

10.2/2   * the actual for each formal type is nonstatic;

10.3/2   * the actual for each formal object is nonstatic; and

10.4/2   * the actual for each formal subprogram is a user-defined subprogram.

11/3 A pragma Preelaborate (or pragma Pure - see below) is used to specify
that a library unit is preelaborated, namely that the Preelaborate aspect of
the library unit is True; all compilation units of the library unit are
preelaborated. The declaration and body of a preelaborated library unit, and
all subunits that are elaborated as part of elaborating the library unit,
shall be preelaborable. All compilation units of a preelaborated library unit
shall depend semantically only on declared pure or preelaborated
library_items. In addition to the places where Legality Rules normally apply
(see 12.3), these rules also apply in the private part of an instance of a
generic unit. If a library unit is preelaborated, then its declaration, if
any, and body, if any, are elaborated prior to all nonpreelaborated
library_items of the partition.

11.1/2 The following rules specify which entities have preelaborable
initialization:

11.2/3   * The partial view of a private type or private extension, a
        protected type without entry_declarations, a generic formal private
        type, or a generic formal derived type, has preelaborable
        initialization if and only if the pragma Preelaborable_Initialization
        has been applied to them. A protected type with entry_declarations or
        a task type never has preelaborable initialization.

11.3/2   * A component (including a discriminant) of a record or protected
        type has preelaborable initialization if its declaration includes a
        default_expression whose execution does not perform any actions
        prohibited in preelaborable constructs as described above, or if its
        declaration does not include a default expression and its type has
        preelaborable initialization.

11.4/3   * A derived type has preelaborable initialization if its parent type
        has preelaborable initialization and if the noninherited components
        all have preelaborable initialization. However, a controlled type with
        an Initialize procedure that is not a null procedure does not have
        preelaborable initialization.

11.5/2   * A view of a type has preelaborable initialization if it is an
        elementary type, an array type whose component type has preelaborable
        initialization, a record type whose components all have preelaborable
        initialization, or an interface type.

11.6/2 A pragma Preelaborable_Initialization specifies that a type has
preelaborable initialization. This pragma shall appear in the visible part of
a package or generic package.

11.7/3 If the pragma appears in the first list of basic_declarative_items of a
package_specification, then the direct_name shall denote the first subtype of
a composite type, and the type shall be declared immediately within the same
package as the pragma. If the pragma is applied to a private type or a private
extension, the full view of the type shall have preelaborable initialization.
If the pragma is applied to a protected type, the protected type shall not
have entries, and each component of the protected type shall have
preelaborable initialization. For any other composite type, the type shall
have preelaborable initialization. In addition to the places where
Legality Rules normally apply (see 12.3), these rules apply also in the
private part of an instance of a generic unit.

11.8/2 If the pragma appears in a generic_formal_part, then the direct_name
shall denote a generic formal private type or a generic formal derived type
declared in the same generic_formal_part as the pragma. In a
generic_instantiation the corresponding actual type shall have preelaborable
initialization.


                            Implementation Advice

12  In an implementation, a type declared in a preelaborated package should
have the same representation in every elaboration of a given version of the
package, whether the elaborations occur in distinct executions of the same
program, or in executions of distinct programs or partitions that include the
given version.


                                   Syntax

13      The form of a pragma Pure is as follows:

14        pragma Pure[(library_unit_name)];

15      A pragma Pure is a library unit pragma.


                              Static Semantics

15.1/3 A pure compilation unit is a preelaborable compilation unit whose
elaboration does not perform any of the following actions:

15.2/2   * the elaboration of a variable declaration;

15.3/2   * the evaluation of an allocator of an access-to-variable type; for
        the purposes of this rule, the partial view of a type is presumed to
        have nonvisible components whose default initialization evaluates such
        an allocator;

15.4/3   * the elaboration of the declaration of a nonderived named
        access-to-variable type unless the Storage_Size of the type has been
        specified by a static expression with value zero or is defined by the
        language to be zero;

15.5/3   * the elaboration of the declaration of a nonderived named
        access-to-constant type for which the Storage_Size has been specified
        by an expression other than a static expression with value zero.

15.6/3 A generic body is pure only if elaboration of a corresponding instance
body would not perform any such actions presuming any composite formal types
have nonvisible components whose default initialization evaluates an
allocator of an access-to-variable type.

15.7/2 The Storage_Size for an anonymous access-to-variable type declared at
library level in a library unit that is declared pure is defined to be zero.


                               Legality Rules

16/2 This paragraph was deleted.

17/3 A pragma Pure is used to specify that a library unit is declared pure,
namely that the Pure aspect of the library unit is True; all compilation units
of the library unit are declared pure. In addition, the limited view of any
library package is declared pure. The declaration and body of a declared pure
library unit, and all subunits that are elaborated as part of elaborating the
library unit, shall be pure. All compilation units of a declared pure library
unit shall depend semantically only on declared pure library_items. In
addition to the places where Legality Rules normally apply (see 12.3), these
rules also apply in the private part of an instance of a generic unit.
Furthermore, the full view of any partial view declared in the visible part of
a declared pure library unit that has any available stream attributes shall
support external streaming (see 13.13.2).


                             Erroneous Execution

17.1/4 Execution is erroneous if some operation (other than the initialization
or finalization of the object) modifies the value of a constant object
declared at library-level in a pure package.


                         Implementation Permissions

18/3 If a library unit is declared pure, then the implementation is permitted
to omit a call on a library-level subprogram of the library unit if the
results are not needed after the call. In addition, the implementation may
omit a call on such a subprogram and simply reuse the results produced by an
earlier call on the same subprogram, provided that none of the parameters nor
any object accessible via access values from the parameters have any part that
is of a type whose full type is an immutably limited type, and the addresses
and values of all by-reference actual parameters, the values of all by-copy-in
actual parameters, and the values of all objects accessible via access values
from the parameters, are the same as they were at the earlier call. This
permission applies even if the subprogram produces other side effects when
called.


                                   Syntax

19      The form of a pragma Elaborate, Elaborate_All, or Elaborate_Body is as
        follows:

20        pragma Elaborate(library_unit_name{, library_unit_name});

21        pragma Elaborate_All(library_unit_name{, library_unit_name});

22        pragma Elaborate_Body[(library_unit_name)];

23      A pragma Elaborate or Elaborate_All is only allowed within a
        context_clause.

24      A pragma Elaborate_Body is a library unit pragma.


                               Legality Rules

25/3 If the aspect Elaborate_Body is True for a declaration (including when
pragma Elaborate_Body applies), then the declaration requires a completion (a
body).

25.1/2 The library_unit_name of a pragma Elaborate or Elaborate_All shall
denote a nonlimited view of a library unit.


                              Static Semantics

26/3 A pragma Elaborate specifies that the body of the named library unit is
elaborated before the current library_item. A pragma Elaborate_All specifies
that each library_item that is needed by the named library unit declaration is
elaborated before the current library_item.

26.1/3 A pragma Elaborate_Body sets the Elaborate_Body representation aspect
of the library unit to which it applies to the value True. If the
Elaborate_Body aspect of a library unit is True, the body of the library unit
is elaborated immediately after its declaration.

        NOTES

27      12  A preelaborated library unit is allowed to have nonpreelaborable
        children.

28      13  A library unit that is declared pure is allowed to have impure
        children.

Generated by dwww version 1.15 on Thu May 23 19:08:15 CEST 2024.