Ada Reference Manual (Ada 2022) — Legal Information

# 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/2
with_clause ::= limited_with_clause | nonlimited_with_clause
4.1/2
limited_with_clause ::= limited [private] with library_unit_name {, library_unit_name};
4.2/2
nonlimited_with_clause ::= [private] 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/2
A library_item (and the corresponding library unit) is named in a with_clause if it is denoted by a library_unit_name in the with_clause. A library_item (and the corresponding library unit) is mentioned in a with_clause if it is named in the with_clause or if it is denoted by 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/2
If a with_clause of a given compilation_unit mentions a private child of some library unit, then the given compilation_unit shall be one of:
9/2
the declaration, body, or subunit of a private descendant of that library unit;
10/2
the body or subunit of a public descendant of that library unit, but not a subprogram body acting as a subprogram declaration (see 10.1.4); or
11/2
the declaration of a public descendant of that library unit, in which case the with_clause shall include the reserved word private.
12/5
A name denoting a library_item (or the corresponding declaration for a child of a generic within an instance — see 10.1.1), if it is visible only due to being mentioned in one or more with_clauses of a unit U that include the reserved word private, shall appear only within:
13/2
a private part;
14/5
a body of a public descendant of U, but not within the subprogram_specification of a body of a subprogram that is a public descendant of U;
15/5
a private descendant of U or its body; or
16/2
a pragma within a context clause.
17/2
A library_item mentioned in a limited_with_clause shall be the implicit declaration of the limited view of a library package, not the declaration of a subprogram, generic unit, generic instance, or a renaming.
18/2
A limited_with_clause shall not appear on a library_unit_body, subunit, or library_unit_renaming_declaration.
19/2
A limited_with_clause that names a library package shall not appear:
20/3
in the context_clause for the explicit declaration of the named library package or any of its descendants;
21/3
within a context_clause for a library_item that is within the scope of a nonlimited_with_clause that mentions the same library package; or
22/3
within a context_clause for a library_item that is within the scope of a use_clause that names an entity declared within the declarative region of the library package.
23/2
NOTE A library_item mentioned in a nonlimited_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 nonlimited_with_clause, then the corresponding declaration nested within each visible instance is visible within the compilation unit. Similarly, a library_item mentioned in a limited_with_clause of a compilation unit is visible within the compilation unit and thus can be used to form expanded names.

#### Examples

24/5
Examples of use of with clauses, limited with clauses, and private with clauses:
25/2
package Office is
end Office;
26/2
with Ada.Strings.Unbounded;
package Office.Locations is
type Location is new Ada.Strings.Unbounded.Unbounded_String;
end Office.Locations;
27/2
limited with Office.Departments; -- types are incomplete
private with Office.Locations; -- only visible in private part
package Office.Employees is
type Employee is private;
28/2
function Dept_Of(Emp : Employee) return access Departments.Department;
procedure Assign_Dept(Emp : in out Employee;
Dept : access Departments.Department);
29/2
...
private
type Employee is
record
Dept : access Departments.Department;
Loc : Locations.Location;
...
end record;
end Office.Employees;
30/5
limited with Office.Employees;
package Office.Departments is
type Department is ...;
31/2
function Manager_Of(Dept : Department) return access Employees.Employee;
procedure Assign_Manager(Dept : in out Department;
Mgr : access Employees.Employee);
...
end Office.Departments;
32/5
The limited_with_clause can be used to support mutually dependent abstractions that are split across multiple packages. In this case, an employee is assigned to a department, and a department has a manager who is an employee. If a with_clause with the reserved word private appears on one library unit and mentions a second library unit, it provides visibility to the second library unit, but restricts that visibility to the private part and body of the first unit. The compiler checks that no use is made of the second unit in the visible part of the first unit.

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe