Contents Index Previous Next
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.]
Language Design Principles
1.a
{one-pass context_clauses}
The reader should be able to understand a context_clause
without looking ahead. Similarly, when compiling a context_clause,
the compiler should not have to look ahead at subsequent context_items,
nor at the compilation unit to which the context_clause
is attached. (We have not completely achieved this.)
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
{scope (of a with_clause)}
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].
5.a
Discussion: Suppose a with_clause
of a public library unit mentions one of its private siblings. (This
is only allowed on the body of the public library unit.) We considered
making the scope of that with_clause
not include the visible part of the public library unit. (This would
only matter for a subprogram_body,
since those are the only kinds of body that have a visible part, and
only if the subprogram_body completes
a subprogram_declaration, since
otherwise the with_clause would
be illegal.) We did not put in such a rule for two reasons: (1) It would
complicate the wording of the rules, because we would have to split each
with_clause into pieces, in order
to correctly handle ``with P, Q;'' where P is public and Q is
private. (2) The conformance rules prevent any problems. It doesn't matter
if a type name in the spec of the body denotes the completion of a private_type_declaration.
5.b
A with_clause
also affects visibility within subsequent use_clauses
and pragmas of the same context_clause,
even though those are not in the scope of the with_clause.
6
{mentioned in a with_clause}
{with_clause (mentioned in)}
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.
6.a
Discussion: With_clauses
control the visibility of declarations or renamings of library units.
Mentioning a root library unit in a with_clause
makes its declaration directly visible. Mentioning a non-root library
unit makes its declaration visible. See Section 8 for details.
6.b
Note that this rule implies that
``with A.B.C;'' is equivalent to ``with A, A.B, A.B.C;''
The reason for making a with_clause
apply to all the ancestor units is to avoid ``visibility holes'' -- situations
in which an inner program unit is visible while an outer one is not.
Visibility holes would cause semantic complexity and implementation difficulty.
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.
8.a
Reason: The purpose of
this rule is to prevent a private child from being visible (or even semantically
depended-on) from outside the subsystem rooted at its parent.
8.b
Discussion: This rule violates
the one-pass context_clauses Language
Design Principle. We rationalize this by saying that at least that Language
Design Principle works for legal compilation units.
8.c
Example:
8.d
package A is
end A;
8.e
package A.B is
end A.B;
8.f
private package A.B.C is
end A.B.C;
8.g
package A.B.C.D is
end A.B.C.D;
8.h
with A.B.C; -- (1)
private package A.B.X is
end A.B.X;
8.i
package A.B.Y is
end A.B.Y;
8.j
with A.B.C; -- (2)
package body A.B.Y is
end A.B.Y;
8.k
(1) is OK because it's a private
child of A.B -- it would be illegal if we made A.B.X a public child of
A.B. (2) is OK because it's the body of a child of A.B. It would be illegal
to say ``with A.B.C;'' on any library_item
whose name does not start with ``A.B''. Note that mentioning A.B.C.D
in a with_clause automatically mentions
A.B.C as well, so ``with A.B.C.D;'' is illegal in the same places
as ``with A.B.C;''.
8.l
To be honest: For the purposes
of this rule, if a subprogram_body
has no preceding subprogram_declaration,
the subprogram_body should be considered
a declaration and not a body. Thus, it is illegal for such a subprogram_body
to mention one of its siblings in a with_clause
if the sibling is a private library unit.
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.
9.a
Ramification: The rules
given for with_clauses are such
that the same effect is obtained whether the name of a library unit is
mentioned once or more than once by the applicable with_clauses,
or even within a given with_clause.
9.b
If a with_clause
mentions a library_unit_renaming_declaration,
it only ``mentions'' the prefixes
appearing explicitly in the with_clause
(and the renamed view itself); the with_clause
is not defined to mention the ancestors of the renamed entity. Thus,
if X renames Y.Z, then ``with X;'' does not make the declarations of
Y or Z visible. Note that this does not cause the dreaded visibility
holes mentioned above.
Extensions to Ada 83
9.c
{extensions to Ada 83}
The syntax rule for with_clause
is modified to allow expanded name notation.
9.d
A use_clause
in a context_clause may be for a
package (or type) nested in a library package.
Wording Changes from Ada 83
9.e
The syntax rule for context_clause
is modified to more closely reflect the semantics. The Ada 83 syntax
rule implies that the use_clauses
that appear immediately after a particular with_clause
are somehow attached to that with_clause,
which is not true. The new syntax allows a use_clause
to appear first, but that is prevented by a textual rule that already
exists in Ada 83.
9.f
The concept of ``scope of a with_clause''
(which is a region of text) replaces RM83's notion of ``apply to'' (a
with_clause applies to a library_item)
The visibility rules are interested in a region of text, not in a set
of compilation units.
9.g
No need to define ``apply to'' for use_clauses.
Their semantics are fully covered by the ``scope (of a use_clause)''
definition in 8.4.
Contents Index Previous Next Legal