The meaning of the occurrence of an identifier at a given place in the text is defined by the visibility rules and also, in the case of overloaded declarations, by the overloading rules. The identifiers considered in this chapter include any identifier other than a reserved word, an attribute designator, a pragma identifier, the identifier of a pragma argument, or an identifier given as a pragma argument. The places considered in this chapter are those where a lexical element (such as an identifier) occurs. The overloaded declarations considered in this chapter are those for subprograms, enumeration literals, and single entries.
For each identifier and at each place in the text, the visibility rules determine a set of declarations (with this identifier) that define possible meanings of an occurrence of the identifier. A declaration is said to be visible at a given place in the text when, according to the visibility rules, the declaration defines a possible meaning of this occurrence. Two cases arise.
A declaration is only visible within a certain part of its scope; this part starts at the end of the declaration except in a package specification, in which case it starts at the reserved word is given after the identifier of the package specification. (This rule applies, in particular, for implicit declarations.)
Visibility is either by selection or direct. A declaration is visible by selection at places that are defined as follows.
Where it is not visible by selection, a visible declaration is said to be directly visible. A declaration is directly visible within a certain part of its immediate scope; this part extends to the end of the immediate scope of the declaration, but excludes places where the declaration is hidden as explained below. In addition, a declaration occurring immediately within the visible part of a package can be made directly visible by means of a use clause according to the rules described in section 8.4. (See also section 8.6 for the visibility of library units.)
A declaration is said to be hidden within (part of) an inner declarative region if the inner region contains a homograph of this declaration; the outer declaration is then hidden within the immediate scope of the inner homograph. Each of two declarations is said to be a homograph of the other if both declarations have the same identifier and overloading is allowed for at most one of the two. If overloading is allowed for both declarations, then each of the two is a homograph of the other if they have the same identifier, operator symbol, or character literal, as well as the same parameter and result type profile (see 6.6).
Within the specification of a subprogram, every declaration with the same designator as the subprogram is hidden; the same holds within a generic instantiation that declares a subprogram, and within an entry declaration or the formal part of an accept statement; where hidden in this manner, a declaration is visible neither by selection nor directly.
Two declarations that occur immediately within the same declarative region must not be homographs, unless either or both of the following requirements are met: (a) exactly one of them is the implicit declaration of a predefined operation; (b) exactly one of them is the implicit declaration of a derived subprogram. In such cases, a predefined operation is always hidden by the other homograph; a derived subprogram hides a predefined operation, but is hidden by any other homograph. Where hidden in this manner, an implicit declaration is hidden within the entire scope of the other declaration (regardless of which declaration occurs first); the implicit declaration is visible neither by selection nor directly.
Whenever a declaration with a certain identifier is visible from a given point, the identifier and the declared entity (if any) are also said to be visible from that point. Direct visibility and visibility by selection are likewise defined for character literals and operator symbols. An operator is directly visible if and only if the corresponding operator declaration is directly visible. Finally, the notation associated with a basic operation is directly visible within the entire scope of this operation.
procedure P is A, B : BOOLEAN; procedure Q is C : BOOLEAN; B : BOOLEAN; -- an inner homograph of B begin ... B := A; -- means Q.B := P.A; C := P.B; -- means Q.C := P.B; end; begin ... A := B; -- means P.A := P.B; end;
Note on the visibility of library units:
The visibility of library units is determined by with clauses (see 10.1.1) and by the fact that library units are implicitly declared in the package STANDARD (see 8.6).
Note on homographs:
The same identifier may occur in different declarations and may thus be associated with different entities, even if the scopes of these declarations overlap. Overlap of the scopes of declarations with the same identifier can result from overloading of subprograms and of enumeration literals. Such overlaps can also occur for entities declared in package visible parts and for entries, record components, and parameters, where there is overlap of the scopes of the enclosing package declarations, task declarations, record type declarations, subprogram declarations, renaming declarations, or generic declarations. Finally overlapping scopes can result from nesting.
Note on immediate scope, hiding, and visibility:
The rules defining immediate scope, hiding, and visibility imply that a reference to an identifier within its own declaration is illegal (except for packages and generic packages). The identifier hides outer homographs within its immediate scope, that is, from the start of the declaration; on the other hand, the identifier is visible only after the end of the declaration. For this reason, all but the last of the following declarations are illegal:
K : INTEGER := K * K; -- illegal T : T; -- illegal procedure P(X : P); -- illegal procedure Q(X : REAL := Q); -- illegal, even if there is a function named Q procedure R(R : REAL); -- an inner declaration is legal (although confusing)
References: accept statement, aggregate, appropriate for a type, argument, basic operation, character literal, component association, component declaration, compound delimiter, declaration, declarative region, designate, discriminant constraint, discriminant specification, entry call, entry declaration, entry family, enumeration literal specification, expanded name, extends, formal parameter, generic association, generic formal parameter, generic instantiation, generic package, generic parameter declaration, generic unit, identifier, immediate scope, implicit declaration, lexical element, library unit, object, occur immediately within, operator, operator symbol, overloading, and 8.7, package, parameter, parameter association, parameter specification, pragma, program unit, record type, reserved word, scope, selected component, selector, simple name, subprogram, subprogram call, subprogram declaration, subprogram specification, task type, task unit, type, type declaration, use clause, visible part.
Rationale references: 11.3 Visibility Rules
Style Guide references: 4.1.3 Functions, 4.1.4 Packages, 4.2.1 Minimization of Interfaces, 4.2.3 Restricting Visibility, 5.7.1 The Use Clause, 5.7.3 Overloaded Subprograms
Address any questions or comments to firstname.lastname@example.org.