

            Section 10: Program Structure and Compilation Issues


1     The overall structure of programs and the facilities for separate
compilation are described in this section. 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     This section has two clauses: 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

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.


                               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    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 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    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. The
renaming of a child of a generic package shall occur only within the
declarative region of the generic package.

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

19    For each declaration or renaming of a generic unit as a child of some
parent generic package, there is a corresponding declaration nested
immediately within each instance of the parent. This declaration is visible
only within the scope of a with_clause that mentions the 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    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. 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.

      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     with_clause ::= 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     A library_item is mentioned in a with_clause if it is denoted by a
library_unit_name or 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     If a with_clause of a given compilation_unit mentions a private child of
some library unit, then the given compilation_unit shall be either the
declaration of a private descendant of that library unit or the body or
subunit of a (public or private) descendant of that library unit.

      NOTES

9     3  A library_item mentioned in a 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 with_clause, then
      the corresponding declaration nested within each visible instance is
      visible within the compilation 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     subprogram_body_stub ::= subprogram_specification is separate;

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


                               Legality Rules

8     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.

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    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     The mechanisms for creating an environment and for adding and replacing
compilation units within an environment are implementation defined.


                            Name Resolution Rules

4/1   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     The implementation may require that a compilation unit be legal before
inserting it into the environment.

7     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 with the same defining_program_unit_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 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 to which a pragma Inline
applies, 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 declaration 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     Certain program unit pragmas are defined to be library unit pragmas. The
name, if any, in a library unit pragma shall denote the declaration of 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.


                            Implementation Advice

7.2/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.


                           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     An implementation may place restrictions on configuration pragmas, so
long as it allows them when the environment contains no library_items other
than those of the predefined environment.


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     Within the parent_unit_name at the beginning of a library_item, and
within a with_clause, the only declarations that are visible are those that
are library_items of the environment, and the only declarations that are
directly visible are those that are root library_items of the environment.
Notwithstanding the rules of 4.1.3, an expanded name in a with_clause 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.)

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.




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     If a compilation unit with stubs is needed, then so are any
      corresponding subunits.

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 mentions 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    Any included library_unit_declaration to which 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    The kind of partition described in this clause 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.


                               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     The creation of a default-initialized object (including a component) of
      a descendant of a private type, private extension, controlled type, task
      type, or protected type with entry_declarations; similarly the
      evaluation of an extension_aggregate with an ancestor subtype_mark
      denoting a subtype of such a type.

10    A generic body is preelaborable only if elaboration of a corresponding
instance body would not perform any such actions, presuming that the actual
for each formal private type (or extension) is a private type (or extension),
and the actual for each formal subprogram is a user-defined subprogram.

11/1  If a pragma Preelaborate (or pragma Pure - see below) applies to a
library unit, then it is preelaborated. If a library unit is preelaborated,
then its declaration, if any, and body, if any, are elaborated prior to all
non-preelaborated library_items of the partition. 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. In addition to the
places where Legality Rules normally apply (see 12.3), this rule applies also
in the private part of an instance of a generic unit. In addition, all
compilation units of a preelaborated library unit shall depend semantically
only on compilation units of other preelaborated library units.


                            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.


                               Legality Rules

16    A pure library_item is a preelaborable library_item that does not
contain the declaration of any variable or named access type, except within a
subprogram, generic subprogram, task unit, or protected unit.

17    A pragma Pure is used to declare that a library unit is pure. If a
pragma Pure applies to a library unit, then its compilation units shall be
pure, and they shall depend semantically only on compilation units of other
library units that are declared pure.


                         Implementation Permissions

18    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. Similarly, it may omit such a call and
simply reuse the results produced by an earlier call on the same subprogram,
provided that none of the parameters are of a limited type, and the addresses
and values of all by-reference actual parameters, and the values of all
by-copy-in actual 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    If a pragma Elaborate_Body applies to a declaration, then the
declaration requires a completion (a body).


                              Static Semantics

26    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. A pragma Elaborate_Body specifies
that the body of the library unit is elaborated immediately after its
declaration.

      NOTES

27    12  A preelaborated library unit is allowed to have non-preelaborable
      children.

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

