8.3 Visibility
1
[
{visibility rules}
The
visibility rules, given below, determine
which declarations are visible and directly visible at each place within
a program. The visibility rules apply to both explicit and implicit declarations.]
Static Semantics
2
{visibility (direct)}
{directly visible}
{directly visible}
A declaration is defined to be
directly visible
at places where a
name consisting of only
an
identifier or
operator_symbol
is sufficient to denote the declaration; that is, no
selected_component
notation or special context (such as preceding => in a named association)
is necessary to denote the declaration.
{visible}
A declaration is defined to be
visible wherever
it is directly visible, as well as at other places where some
name
(such as a
selected_component) can denote
the declaration.
3
The syntactic category direct_name
is used to indicate contexts where direct visibility is required. The
syntactic category selector_name is used to
indicate contexts where visibility, but not direct visibility, is required.
4
{visibility (immediate)}
{visibility (use
clause)} There are two kinds of direct
visibility:
immediate visibility and
use-visibility.
{immediately
visible} A declaration is immediately
visible at a place if it is directly visible because the place is within
its immediate scope.
{use-visible}
A declaration is use-visible if it is directly visible
because of a
use_clause (see
8.4).
Both conditions can apply.
5
{hiding}
A declaration can be
hidden, either from direct
visibility, or from all visibility, within certain parts of its scope.
{hidden from all visibility}
Where
hidden from all visibility, it is not
visible at all (neither using a
direct_name
nor a
selector_name).
{hidden
from direct visibility} Where
hidden
from direct visibility, only direct visibility is lost; visibility
using a
selector_name is still possible.
6
[
{overloaded}
Two or more declarations are
overloaded if
they all have the same defining name and there is a place where they
are all directly visible.]
6.a
Ramification: Note that a name
can have more than one possible interpretation even if it denotes a non-overloadable
entity. For example, if there are two functions F that return records,
both containing a component called C, then the name F.C has two possible
interpretations, even though component declarations are not overloadable.
7
{overloadable}
The declarations of callable entities [(including
enumeration literals)] are
overloadable[, meaning that overloading
is allowed for them].
7.a
Ramification: A generic_declaration
is not overloadable within its own generic_formal_part.
This follows from the rules about when a name
denotes a current instance. See AI83-00286. This implies that within
a generic_formal_part, outer declarations
with the same defining name are hidden from direct visibility. It also
implies that if a generic formal parameter has the same defining name
as the generic itself, the formal parameter hides the generic from direct
visibility.
8
{homograph}
Two declarations are
homographs if they have
the same defining name, and, if both are overloadable, their profiles
are type conformant.
{type conformance
[partial]} [An inner declaration hides any
outer homograph from direct visibility.]
8.a/2
Glossary entry: {Overriding
operation} An overriding operation is one that replaces an inherited
primitive operation. Operations may be marked explicitly as overriding
or not overriding.
9/1
{
8652/0025}
{
AI95-00044-01}
[Two homographs are not generally allowed immediately within the same
declarative region unless one
overrides the other (see Legality
Rules below).]
{override}
The only declarations that
are {overridable} overridable
are the implicit declarations for predefined operators and inherited
primitive subprograms. A declaration overrides another homograph
that occurs immediately within the same declarative region in the following
cases:
10/1
- {8652/0025}
{AI95-00044-01}
A declaration that is not overridable overrides
one that is overridable An explicit declaration
overrides an implicit declaration of a primitive subprogram, [regardless
of which declaration occurs first];
10.a/1
Ramification: {
8652/0025}
{
AI95-00044-01}
And regardless of whether the
non-overridable explicit
declaration is overloadable or not.
For example,
statement_identifiers are covered by this
rule.
10.b
The “regardless of which declaration occurs
first” is there because the explicit declaration could be a primitive
subprogram of a partial view, and then the full view might inherit a
homograph. We are saying that the explicit one wins (within its scope),
even though the implicit one comes later.
10.c
If the overriding declaration is also a subprogram,
then it is a primitive subprogram.
10.d
As explained in
7.3.1,
“
Private Operations”, some inherited
primitive subprograms are never declared. Such subprograms cannot be
overridden, although they can be reached by dispatching calls in the
case of a tagged type.
11
- The implicit declaration of an inherited
operator overrides that of a predefined operator;
11.a
Ramification: In a previous version of
Ada 9X, we tried to avoid the notion of predefined operators, and say
that they were inherited from some magical root type. However, this seemed
like too much mechanism. Therefore, a type can have a predefined "+"
as well as an inherited "+". The above rule says the inherited
one wins.
11.b
The “regardless of which declaration occurs
first” applies here as well, in the case where
derived_type_declaration
in the visible part of a public library unit derives from a private type
declared in the parent unit, and the full view of the parent type has
additional predefined operators, as explained in
7.3.1,
“
Private Operations”. Those predefined
operators can be overridden by inherited subprograms implicitly declared
earlier.
12
- An implicit declaration of an inherited
subprogram overrides a previous implicit declaration of an inherited
subprogram.
12.1/2
- {AI95-00251-01}
If two or more homographs are implicitly declared
at the same place:
12.2/2
- {AI95-00251-01}
If at least one is a subprogram that is neither
a null procedure nor an abstract subprogram, and does not require overriding
(see 3.9.3), then they override those that
are null procedures, abstract subprograms, or require overriding. If
more than one such homograph remains that is not thus overridden, then
they are all hidden from all visibility.
12.3/2
- {AI95-00251-01}
Otherwise (all are null procedures, abstract subprograms,
or require overriding), then any null procedure overrides all abstract
subprograms and all subprograms that require overriding; if more than
one such homograph remains that is not thus overridden, then if they
are all fully conformant with one another, one is chosen arbitrarily;
if not, they are all hidden from all visibility. {full
conformance (required)}
12.a/2
Discussion:
In the case where the implementation arbitrarily chooses one overrider
from among a group of inherited subprograms, users should not be able
to determine which member was chosen, as the set of inherited subprograms
which are chosen from must be fully conformant. This rule is needed in
order to allow
12.b/2
package Outer is
package P1 is
type Ifc1 is interface;
procedure Null_Procedure (X : Ifc1) is null;
procedure Abstract_Subp (X : Ifc1) is abstract;
end P1;
12.c/2
package P2 is
type Ifc2 is interface;
procedure Null_Procedure (X : Ifc2) is null;
procedure Abstract_Subp (X : Ifc2) is abstract;
end P2;
12.d/2
type T is abstract new P1.Ifc1 and P2.Ifc2 with null record;
end Outer;
12.e/2
without requiring that
T explicitly override any of its inherited operations.
12.f/2
Full conformance is required
here, as we cannot allow the parameter names to differ. If they did differ,
the routine which was selected for overriding could be determined by
using named parameter notation in a call.
12.g/2
When the subprograms do
not conform, we chose not to adopt the “use clause” rule
which would make them all visible resulting in likely ambiguity. If we
had used such a rule, any successful calls would be confusing; and the
fact that there are no Beaujolais-like effect to worry about means we
can consider other rules. The hidden-from-all-visibility homographs are
still inherited by further derivations, which avoids order-of-declaration
dependencies and other anomalies.
12.h/2
We have to be careful
to not include arbitrary selection if the routines have real bodies.
(This can happen in generics, see the example in the incompatibilities
section below.) We don't want the ability to successfully call routines
where the body executed depends on the compiler or a phase of the moon.
12.i/2
Note that if the type
is concrete, abstract subprograms are inherited as subprograms that require
overriding. We include functions that require overriding as well; these
don't have real bodies, so they can use the more liberal rules.
13
- [For an implicit declaration of a
primitive subprogram in a generic unit, there is a copy of this declaration
in an instance.] However, a whole new set of primitive subprograms is
implicitly declared for each type declared within the visible part of
the instance. These new declarations occur immediately after the type
declaration, and override the copied ones. [The copied ones can be called
only from within the instance; the new ones can be called only from outside
the instance, although for tagged types, the body of a new one can be
executed by a call to an old one.]
13.a
Discussion: In addition, this is also
stated redundantly (again), and is repeated, in
12.3,
“
Generic Instantiation”. The rationale
for the rule is explained there.
14
{visible}
{hidden from all
visibility [distributed]} A declaration
is visible within its scope, except where hidden from all visibility,
as follows:
15
- {hidden
from all visibility (for overridden declaration) [partial]}
An overridden declaration is hidden from all visibility
within the scope of the overriding declaration.
15.a
Ramification: We have to talk about the
scope of the overriding declaration, not its visibility, because it hides
even when it is itself hidden.
15.b
Note that the scope of an explicit subprogram_declaration
does not start until after its profile.
16
- {hidden
from all visibility (within the declaration itself) [partial]}
A declaration is hidden from all visibility until
the end of the declaration, except:
17
- For a record type or record
extension, the declaration is hidden from all visibility only until the
reserved word record;
18/2
- {AI-00345-01}
For a package_declaration, task
declaration, protected declaration, generic_package_declaration,
or subprogram_body, the declaration is hidden
from all visibility only until the reserved word is of the declaration;.
18.a
Ramification: We're talking about the
is of the construct itself, here, not some random is that
might appear in a generic_formal_part.
18.1/2
- {AI-00345-01}
For a task declaration or protected declaration,
the declaration is hidden from all visibility only until the reserved
word with of the declaration if there is one, or the reserved
word is of the declaration if there is no with.
18.b/2
To be honest: If
there is neither a with nor is, then the exception does
not apply and the name is hidden from all visibility until the end of
the declaration. This oddity was inherited from Ada 95.
18.c/2
Reason: We need
the “with or is” rule so that the visibility
within an interface_list does not vary by
construct. That would make it harder to complete private extensions and
would complicate implementations.
19
- {hidden
from all visibility (for a declaration completed by a subsequent declaration)
[partial]} If the completion of a declaration
is a declaration, then within the scope of the completion, the first
declaration is hidden from all visibility. Similarly, a discriminant_specification
or parameter_specification is hidden within
the scope of a corresponding discriminant_specification
or parameter_specification of a corresponding
completion, or of a corresponding accept_statement.
19.a
Ramification: This rule means, for example,
that within the scope of a full_type_declaration
that completes a private_type_declaration,
the name of the type will denote the full_type_declaration,
and therefore the full view of the type. On the other hand, if the completion
is not a declaration, then it doesn't hide anything, and you can't denote
it.
20/2
- {AI95-00217-06}
{AI95-00412-01}
{hidden from all visibility (by lack
of a with_clause) [partial]} The declaration
of a library unit (including a library_unit_renaming_declaration)
is hidden from all visibility except at
places outside that
are within its declarative region that are
not or within the scope of a nonlimited_ with_clause
that mentions it. The limited view of a library
package is hidden from all visibility at places that are not within the
scope of a limited_with_clause that mentions
it; in addition, the limited view is hidden from all visibility within
the declarative region of the package, as well as within the scope of
any nonlimited_with_clause that mentions the
package. Where the declaration of the limited view of a package is visible,
any name that denotes the package denotes the limited view, including
those provided by a package renaming. [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.] Such a nested declaration is hidden
from all visibility except at places that are within the scope of a with_clause
that mentions the child.
20.a/2
Discussion: {
AI95-00217-06}
This is the rule that prevents
with_clauses
from being transitive; the [immediate] scope includes indirect semantic
dependents.
This rule also prevents the limited
view of a package from being visible in the same place as the full view
of the package, which prevents various ripple effects.
20.1/2
- {AI95-00217-06}
{AI95-00412-01}
[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.] Such
a nested declaration is hidden from all visibility except at places that
are within the scope of a with_clause that
mentions the child.
21
{directly
visible} {immediately
visible} {visibility
(direct)} {visibility
(immediate)} A declaration with a
defining_identifier
or
defining_operator_symbol is immediately
visible [(and hence directly visible)] within its immediate scope
{hidden
from direct visibility [distributed]}
except where hidden from direct visibility, as follows:
22
- {hidden
from direct visibility (by an inner homograph) [partial]}
A declaration is hidden from direct visibility within
the immediate scope of a homograph of the declaration, if the homograph
occurs within an inner declarative region;
23
- {hidden
from direct visibility (where hidden from all visibility) [partial]}
A declaration is also hidden from direct visibility
where hidden from all visibility.
23.1/2
{
AI95-00195-01}
{
AI95-00408-01}
{visible (attribute_
[partial]} An attribute_definition_clause
is visible everywhere within its scope.
Name Resolution Rules
24
{possible interpretation
(for direct_names) [partial]} A
direct_name
shall resolve to denote a directly visible declaration whose defining
name is the same as the
direct_name.
{possible
interpretation (for selector_names) [partial]} A
selector_name shall resolve to denote a visible
declaration whose defining name is the same as the
selector_name.
24.a
Discussion: "The same as" has
the obvious meaning here, so for +, the possible interpretations are
declarations whose defining name is "+" (an operator_symbol).
25
These rules on visibility and direct visibility do
not apply in a
context_clause, a
parent_unit_name,
or a
pragma that appears at the place of a
compilation_unit. For those contexts, see
the rules in
10.1.6, “
Environment-Level
Visibility Rules”.
25.a
Ramification: Direct visibility is irrelevant
for
character_literals. In terms of overload
resolution
character_literals are similar
to other literals, like
null — see
4.2.
For
character_literals, there is no need to
worry about hiding, since there is no way to declare homographs.
Legality Rules
26/2
{
8652/0025}
{
8652/0026} {
AI95-00044-01}
{
AI95-00150-01}
{
AI95-00377-01}
A non-overridable An
explicit declaration is illegal if there is a homograph occurring
immediately within the same declarative region that is visible at the
place of the declaration, and is not hidden from all visibility by the
non-overridable explicit
declaration.
In addition, a type extension is illegal
if somewhere within its immediate scope it has two visible components
with the same name. Similarly, the
context_clause
for a
compilation unit subunit
is illegal if it mentions (in a
with_clause)
some library unit, and there is a homograph of the library unit that
is visible at the place of the
compilation unit corresponding
stub, and the homograph and the mentioned library unit are both
declared immediately within the same declarative region.
{generic
contract issue [partial]} These rules
also apply to dispatching operations declared in the visible part of
an instance of a generic unit. However, they do not apply to other overloadable
declarations in an instance[; such declarations may have type conformant
profiles in the instance, so long as the corresponding declarations in
the generic were not type conformant].
{type
conformance [partial]}
26.a
Discussion:
Normally, these rules just mean you can't explicitly declare two
homographs immediately within the same declarative region. The wording
is designed to handle the following special cases:
26.b
- If the second declaration completes
the first one, the second declaration is legal.
26.c
- If
the body of a library unit contains an explicit homograph of a child
of that same library unit, this is illegal only if the body mentions
the child in its context_clause, or if some
subunit mentions the child. Here's an example:
26.d
package P is
end P;
26.e
package P.Q is
end P.Q;
26.f
package body P is
Q : Integer; -- OK; we cannot see package P.Q here.
procedure Sub is separate;
end P;
26.g
with P.Q;
separate(P)
procedure Sub is -- Illegal.
begin
null;
end Sub;
26.h
If package body P said "with P.Q;",
then it would be illegal to declare the homograph Q: Integer. But it
does not, so the body of P is OK. However, the subunit would be able
to see both P.Q's, and is therefore illegal.
26.i
A previous version of Ada 9X allowed the subunit,
and said that references to P.Q would tend to be ambiguous. However,
that was a bad idea, because it requires overload resolution to resolve
references to directly visible non-overloadable homographs, which is
something compilers have never before been required to do.
26.i.1/1
- {8652/0026}
{8652/0102}
{AI95-00150-01}
{AI95-00157-01}
If a type_extension
contains a component with the same name as a component in an ancestor
type, there must be no place where both components are visible. For instance:
26.i.2/1
package A is
type T is tagged private;
package B is
type NT is new T with record
I: Integer; -- Illegal because T.I is visible in the body.
end record; -- T.I is not visible here.
end B;
private
type T is tagged record
I: Integer; -- Illegal because T.I is visible in the body.
end record;
end A;
26.i.3/2
{
AI95-00114-01}
package A is
package body A is
package body B is
-- T.I becomes visible here.
end B;
end A;
26.i.4/1
package A.C is
type NT2 is new A.T with record
I: Integer; -- Illegal because T.I is visible in the private part.
end record; -- T.I is not visible here.
private
-- T.I is visible here.
end A.C;
26.i.5/1
with A;
package D is
type NT3 is new A.T with record
I: Integer; -- Legal because T.I is never visible in this package.
end record;
end D;
26.i.6/1
with D;
package A.E is
type NT4 is new D.NT3 with null record;
X : NT4;
I1 : Integer := X.I; -- D.NT3.I
I2 : Integer := D.NT3(X).I; -- D.NT3.I
I3 : Integer := A.T(X).I; -- A.T.I
end A.E;
26.i.7/1
{8652/0102}
{AI95-00157-01}
D.NT3 can have a component I because the component
I of the parent type is never visible. The parent component exists, of
course, but is never declared for the type D.NT3. In the child package
A.E, the component I of A.T is visible, but that does not change the
fact that the A.T.I component was never declared for type D.NT3. Thus,
A.E.NT4 does not (visibly) inherit the component I from A.T, while it
does inherit the component I from D.NT3. Of course, both components exist,
and can be accessed by a type conversion as shown above. This behavior
stems from the fact that every characteristic of a type (including components)
must be declared somewhere in the innermost declarative region containing
the type — if the characteristic is never visible in that declarative
region, it is never declared. Therefore, such characteristics do not
suddenly become available even if they are in fact visible in some other
scope. See 7.3.1 for more on the rules.
26.i.8/2
- {AI95-00377-01}
It is illegal to mention both an explicit child
of an instance, and a child of the generic from which the instance was
instantiated. This is easier to understand with an example:
26.i.9/2
generic
package G1 is
end G1;
26.i.10/2
generic
package G1.G2 is
end G1.G2;
26.i.11/2
with G1;
package I1 is new G1;
26.i.12/2
package I1.G2 renames ...
26.i.13/2
with G1.G2;
with I1.G2; -- Illegal
package Bad is ...
26.i.14/2
The context clause for
Bad is illegal as I1 has an implicit declaration of I1.G2 based on the
generic child G1.G2, as well as the mention of the explicit child I1.G2.
As in the previous cases, this is illegal only if the context clause
makes both children visible; the explicit child can be mentioned as long
as the generic child is not (and vice-versa).
26.j
Note that we need to be careful which things
we make "hidden from all visibility" versus which things we
make simply illegal for names to denote. The distinction is subtle. The
rules that disallow names denoting components within a type declaration
(see
3.7) do not make the components invisible
at those places, so that the above rule makes components with the same
name illegal. The same is true for the rule that disallows names denoting
formal parameters within a
formal_part (see
6.1).
26.k
Discussion: The part about instances
is from AI83-00012. The reason it says “overloadable declarations”
is because we don't want it to apply to type extensions that appear in
an instance; components are not overloadable.
27
5 Visibility for compilation units follows
from the definition of the environment in
10.1.4,
except that it is necessary to apply a
with_clause
to obtain visibility to a
library_unit_declaration
or
library_unit_renaming_declaration.
28
6 In addition to the visibility rules given
above, the meaning of the occurrence of a
direct_name
or
selector_name at a given place in the text
can depend on the overloading rules (see
8.6).
29
7 Not all contexts where an identifier,
character_literal, or operator_symbol
are allowed require visibility of a corresponding declaration. Contexts
where visibility is not required are identified by using one of these
three syntactic categories directly in a syntax rule, rather than using
direct_name or selector_name.
29.a
Ramification:
An identifier, character_literal
or operator_symbol that occurs in one of the
following contexts is not required to denote a visible or directly visible
declaration:
29.b
1.
A defining name.
29.c
2.
The identifiers or operator_symbol
that appear after the reserved word end in a proper_body.
Similarly for “end loop”, etc.
29.d
3.
An attribute_designator.
29.e
4.
A pragma identifier.
29.f
5.
A pragma_argument_identifier.
29.g
6.
An identifier specific to a pragma used in
a pragma argument.
29.h
The visibility rules have nothing to do with
the above cases; the meanings of such things are defined elsewhere. Reserved
words are not identifiers; the visibility
rules don't apply to them either.
29.i
Because of the way we have defined "declaration",
it is possible for a usage name to denote a subprogram_body,
either within that body, or (for a non-library unit) after it (since
the body hides the corresponding declaration, if any). Other bodies do
not work that way. Completions of type_ and
deferred_constant_declarations do work that
way. Accept_statements are never denoted,
although the parameter_specifications in their
profiles can be.
29.j
The scope of a
subprogram does not start until after its profile. Thus, the following
is legal:
29.k
X : constant Integer := 17;
...
package P is
procedure X(Y : in Integer := X);
end P;
29.l
The body of the subprogram will probably be
illegal, however, since the constant X will be hidden by then.
29.m
The rule is different
for generic subprograms, since they are not overloadable; the following
is illegal:
29.n
X : constant Integer := 17;
package P is
generic
Z : Integer := X; -- Illegal!
procedure X(Y : in Integer := X); -- Illegal!
end P;
29.o
The constant X is hidden from direct visibility
by the generic declaration.
Extensions to Ada 83
29.p
{
extensions to Ada 83}
Declarations
with the same defining name as that of a subprogram or entry being defined
are nevertheless visible within the subprogram specification or entry
declaration.
Wording Changes from Ada 83
29.q
The term “visible by selection”
is no longer defined. We use the terms “directly visible”
and “visible” (among other things). There are only two regions
of text that are of interest, here: the region in which a declaration
is visible, and the region in which it is directly visible.
29.r
Visibility is defined only for declarations.
Incompatibilities With Ada 95
29.s/2
{
AI95-00251-01}
{incompatibilities with Ada 95} Added
rules to handle the inheritance and overriding of multiple homographs
for a single type declaration, in order to support multiple inheritance
from interfaces. The new rules are intended to be compatible with the
existing rules so that programs that do not use interfaces do not change
their legality. However, there is a very rare case where this is not
true:
29.t/2
generic
type T1 is private;
type T2 is private;
package G is
type T is null record;
procedure P (X : T; Y : T1);
procedure P (X : T; Z : T2);
end G; ]
29.u/2
package I is new G (Integer, Integer); -- Exports homographs of P.
29.v/2
type D is new I.T; -- Both Ps are inherited.
29.w/2
Obj : D;
29.x/2
P (Obj, Z => 10); -- Legal in Ada 95, illegal in Ada 2005.
29.y/2
The call to P would resolve
in Ada 95 by using the parameter name, while the procedures P would be
hidden from all visibility in Ada 2005 and thus would not resolve. This
case doesn't seem worth making the rules any more complex than they already
are.
29.z/2
{
AI95-00377-01}
[Amendment Correction: A with_clause
is illegal if it would create a homograph of an implicitly declared generic
child (see 10.1.1). An Ada 95 compiler could
have allowed this, but which unit of the two units involved would be
denoted wasn't specified, so any successful use isn't portable. Removing
one of the two with_clauses involved will
fix the problem.
Wording Changes from Ada 95
29.aa/2
{
8652/0025}
{
AI95-00044-01}
Corrigendum: Clarified the overriding rules
so that "/=" and statement_identifiers
are covered.
29.bb/2
{
8652/0026}
{
AI95-00150-01}
Corrigendum: Clarified that is it never
possible for two components with the same name to be visible; any such
program is illegal.
29.cc/2
{
AI95-00195-01}
{
AI95-00408-01}
The visibility of an attribute_definition_clause
is defined so that it can be used by the stream attribute availability
rules (see 13.13.2).
29.dd/2