Contents Index Search Previous Next
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.]
{child
(of a library unit)} A library unit is
a
child of its parent unit. The
root library units are
the children of the predefined library package Standard.
1.a
Ramification: Standard
is a library unit.
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
{library unit} 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''.
{compilation unit}
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))].
9.a
Discussion:
In this example:
9.b
with Ada.Text_IO;
package P is
...
end P;
9.c
the term ``compilation unit''
can refer to this text: ``with Ada.Text_IO; package P is
... end P;'' or to this text: ``package P is ...
end P;''. We use this shorthand because it corresponds to common
usage.
9.d
We like to use the word ``unit''
for declaration-plus-body things, and ``item'' for declaration or body
separately (as in declarative_item).
The terms ``compilation_unit,''
``compilation unit,'' and ``subunit''
are exceptions to this rule. We considered changing ``compilation_unit,''
``compilation unit'' to ``compilation_item,''
``compilation item,'' respectively, but we decided not to.
10
{parent declaration (of a
library_item)} {parent
declaration (of a library unit)} 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.
{root
library unit} 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.
{parent unit (of a library unit)} The
parent unit of a
library_item
or library unit is the library unit declared by its parent declaration.
10.a
Discussion: The declaration
and body of Standard are presumed to exist from the beginning of time,
as it were. There is no way to actually write them, since there is no
syntactic way to indicate lack of a parent. An attempt to compile a package
Standard would result in Standard.Standard.
10.b
Reason: Library units
(other than Standard) have ``parent declarations'' and ``parent units''.
Subunits have ``parent bodies''. We didn't bother to define the other
possibilities: parent body of a library unit, parent declaration of a
subunit, parent unit of a subunit. These are not needed, and might get
in the way of a correct definition of ``child.''
11
[The children of a library unit occur immediately
within the declarative region of the declaration of the library unit.]
{ancestor (of a 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.)]
{descendant} The
descendant
relation is the inverse of the ancestor relation.
11.a
Reason: These definitions
are worded carefully to avoid defining subunits as children. Only library
units can be children.
11.b
We use the unadorned term ``ancestors''
here to concisely define both ``ancestor unit'' and ``ancestor declaration.''
12
{public library unit}
{public declaration of a library
unit} {private library
unit} {private declaration
of a library unit} 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.
{public
descendant (of a library unit)} The
public
descendants of a library unit are the library unit itself, and the
public descendants of its public children.
{private
descendant (of a library unit)} Its other
descendants are
private descendants.
12.a
Discussion: The first
concept defined here is that a library_item
is either public or private (not in relation to anything else -- it's
just a property of the library unit). The second concept is that a library_item
is a public descendant or private descendant of a given ancestor.
A given library_item can be a public
descendant of one of its ancestors, but a private descendant of some
other ancestor.
12.b
A subprogram declared by a subprogram_body
(as opposed to a subprogram_declaration)
is always public, since the syntax rules disallow the reserved word private
on a body.
12.c
Note that a private library
unit is a public descendant of itself, but a private descendant
of its parent. This is because it is visible outside itself -- its privateness
means that it is not visible outside its parent.
12.d
Private children of Standard
are legal, and follow the normal rules. It is intended that implementations
might have some method for taking an existing environment, and treating
it as a package to be ``imported'' into another environment, treating
children of Standard in the imported environment as children of the imported
package.
12.e
Ramification:
Suppose we have a public library unit A, a private library unit A.B,
and a public library unit A.B.C. A.B.C is a public descendant of itself
and of A.B, but a private descendant of A; since A.B is private to A,
we don't allow A.B.C to escape outside A either. This is similar to the
situation that would occur with physical nesting, like this:
12.f
package A is
private
package B is
package C is
end C;
private
end B;
end A;
12.g
Here, A.B.C is visible outside
itself and outside A.B, but not outside A. (Note that this example is
intended to illustrate the visibility of program units from the outside;
the visibility within child units is not quite identical to that of physically
nested units, since child units are nested after their parent's declaration.)
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.
14.a
Discussion: We could
have allowed nested program units to be children of other program units;
their semantics would make sense. We disallow them to keep things simpler
and because they wouldn't be particularly useful.
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.
16.a
Discussion: A child of
an instance of a given generic unit will often be an instance of a (generic)
child of the given generic unit. This is not required, however.
16.b
Reason:
Instances are forbidden from having noninstance children for two
reasons:
16.c
- 1.
-
We want all source code that can depend on information from the private
part of a library unit to be inside the "subsystem" rooted
at the library unit. If an instance of a generic unit were allowed to
have a noninstance as a child, the source code of that child might depend
on information from the private part of the generic unit, even though
it is outside the subsystem rooted at the generic unit.
16.d
- 2.
-
Disallowing noninstance children simplifies the description of the semantics
of children of generic packages.
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.]
19.a
Implementation Note: Within
the child, like anything nested in a generic unit, one can make up-level
references to the current instance of its parent, and thereby gain access
to the formal parameters of the parent, to the types declared in the
parent, etc. This ``nesting'' model applies even within the generic_formal_part
of the child, as it does for a generic child of a nongeneric unit.
19.b
Ramification: Suppose
P is a generic library package, and P.C is a generic child of P. P.C
can be instantiated inside the declarative region of P. Outside P, P.C
can be mentioned only in a with_clause.
Conceptually, an instance I of P is a package that has a nested generic
unit called I.C. Mentioning P.C in a with_clause
allows I.C to be instantiated. I need not be a library unit, and the
instantiation of I.C need not be a library unit. If I is a library unit,
and an instance of I.C is a child of I, then this instance has to be
called something other than C.
20
A library subprogram shall not override a primitive
subprogram.
20.a
Reason: This prevents
certain obscure anomalies. For example, if a library subprogram were
to override a subprogram declared in its parent package, then in a compilation
unit that depends indirectly on the library subprogram, the library
subprogram could hide the overridden operation from all visibility, but
the library subprogram itself would not be visible.
20.b
Note that even without this
rule, such subprograms would be illegal for tagged types, because of
the freezing rules.
21
The defining name of a function that is a compilation
unit shall not be an operator_symbol.
21.a
Reason: Since overloading
is not permitted among compilation units, it seems unlikely that it would
be useful to define one as an operator. Note that a subunit could be
renamed within its parent to be an operator.
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.]
25.a
26
{semantic dependence (of one
compilation unit upon another)} {dependence
(semantic)} 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.
26.a
Discussion: The ``if
any'' in the third sentence is necessary because library subprograms
are not required to have a subprogram_declaration.
26.b
To be honest: If a given
compilation unit contains a choice_parameter_specification,
then the given compilation unit depends semantically upon the declaration
of Ada.Exceptions.
26.c
If a given compilation unit
contains a pragma with an argument
of a type defined in another compilation unit, then the given compilation
unit depends semantically upon the other compilation unit.
26.d
Discussion: For example,
a compilation unit containing X'Address depends semantically upon the
declaration of package System.
26.e
For the Address attribute, this
fixes a hole in Ada 83. Note that in almost all cases, the dependence
will need to exist due to with_clauses,
even without this rule. Hence, the rule has very little effect on programmers.
26.f
Note that the semantic dependence
does not have the same effect as a with_clause;
in order to denote a declaration in one of those packages, a with_clause
will generally be needed.
26.g
Note that no special rule is
needed for an attribute_definition_clause,
since an expression after use will require semantic dependence
upon the compilation unit containing the type_declaration
of interest.
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.
27.a
Ramification: Such pragmas
cannot have any arguments that are names,
by a previous rule of this subclause. A compilation
can even be entirely empty, which is probably not useful.
27.b
Some interesting properties
of the three kinds of dependence: The elaboration dependences also include
the semantic dependences, except that subunits are taken together with
their parents. The semantic dependences partly determine the order in
which the compilation units appear in the environment at compile time.
At run time, the order is partly determined by the elaboration dependences.
27.c
The
model whereby a child is inside its parent's declarative region, after
the parent's declaration, as explained in 8.1,
has the following ramifications:
27.d
- The restrictions
on ``early'' use of a private type (RM83-7.4.1(4)) or a deferred constant
(RM83-7.4.3(2)) do not apply to uses in child units, because they follow
the full declaration.
27.e
- A library subprogram
is never primitive, even if its profile includes a type declared immediately
within the parent's package_specification,
because the child is not declared immediately within the same package_specification
as the type (so it doesn't declare a new primitive subprogram), and because
the child is forbidden from overriding an old primitive subprogram. It
is immediately within the same declarative region, but not the same package_specification.
Thus, for a tagged type, it is not possible to call a child subprogram
in a dispatching manner. (This is also forbidden by the freezing rules.)
Similarly, it is not possible for the user to declare primitive subprograms
of the types declared in the declaration of Standard, such as Integer
(even if the rules were changed to allow a library unit whose name is
an operator symbol).
27.f
- When the parent
unit is ``used'' the simple names of the with'd child units are directly
visible (see 8.4, ``Use
Clauses'').
27.g
- When a parent
body with's its own child, the defining name of the child is directly
visible, and the parent body is not allowed to include a declaration
of a homograph of the child unit immediately within the declarative_part
of the body (RM83-8.3(17)).
27.h
Note that ``declaration of a
library unit'' is different from ``library_unit_declaration''
-- the former includes subprogram_body.
Also, we sometimes really mean ``declaration of a view of a library unit'',
which includes library_unit_renaming_declarations.
27.i
The visibility rules generally
imply that the renamed view of a library_unit_renaming_declaration
has to be mentioned in a with_clause
of the library_unit_renaming_declaration.
27.j
To be honest: The real
rule is that the renamed library unit has to be visible in the library_unit_renaming_declaration.
27.k
Reason: In most cases,
``has to be visible'' means there has to be a with_clause.
However, it is possible in obscure cases to avoid the need for a with_clause;
in particular, a compilation unit such as ``package P.Q renames
P;'' is legal with no with_clauses
(though not particularly interesting). ASCII is physically nested in
Standard, and so is not a library unit, and cannot be renamed as a library
unit.
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.
35.a
Discussion:
Example of a generic package with children:
35.b
generic
type Element is private;
with function Image(E : Element) return String;
package Generic_Bags is
type Bag is limited private; -- A bag of Elements.
procedure Add(B : in out Bag; E : Element);
function Bag_Image(B : Bag) return String;
private
type Bag is ...;
end Generic_Bags;
35.c
generic
package Generic_Bags.Generic_Iterators is
... -- various additional operations on Bags.
35.d
generic
with procedure Use_Element(E : in Element);
-- Called once per bag element.
procedure Iterate(B : in Bag);
end Generic_Bags.Generic_Iterators;
35.e
A
package that instantiates the above generic units:
35.f
with Generic_Bags;
with Generic_Bags.Generic_Iterators;
package My_Abstraction is
type My_Type is ...;
function Image(X : My_Type) return String;
package Bags_Of_My_Type is new Generic_Bags(My_Type, Image);
package Iterators_Of_Bags_Of_My_Type is new Bags_Of_My_Type.Generic_Iterators;
end My_Abstraction;
35.g
In the above example, Bags_Of_My_Type
has a nested generic unit called Generic_Iterators. The second with_clause
makes that nested unit visible.
35.h
Here
we show how the generic body could depend on one of its own children:
35.i
with Generic_Bags.Generic_Iterators;
package body Generic_Bags is
procedure Add(B : in out Bag; E : Element) is ... end Add;
35.j
package Iters is new Generic_Iterators;
35.k
function Bag_Image(B : Bag) return String is
Buffer : String(1..10_000);
Last : Integer := 0;
35.l
procedure Append_Image(E : in Element) is
Im : constant String := Image(E);
begin
if Last /= 0 then -- Insert a comma.
Last := Last + 1;
Buffer(Last) := ',';
end if;
Buffer(Last+1 .. Last+Im'Length) := Im;
Last := Last + Im'Length;
end Append_Image;
35.m
procedure Append_All is new Iters.Iterate(Append_Image);
begin
Append_All(B);
return Buffer(1..Last);
end Bag_Image;
end Generic_Bags;
Extensions to Ada 83
35.n
{extensions to Ada 83}
The syntax rule for library_item
is modified to allow the reserved word private before a library_unit_declaration.
35.o
Children (other than children
of Standard) are new in Ada 95.
35.p
Library unit renaming is new
in Ada 95.
Wording Changes from Ada 83
35.q
Standard is considered a library
unit in Ada 95. This simplifies the descriptions, since it implies that
the parent of each library unit is a library unit. (Standard itself has
no parent, of course.) As in Ada 83, the language does not define any
way to recompile Standard, since the name given in the declaration of
a library unit is always interpreted in relation to Standard. That is,
an attempt to compile a package Standard would result in Standard.Standard.
Contents Index Search Previous Next Legal