Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

8.1 Declarative Region

Static Semantics

For each of the following constructs, there is a portion of the program text called its declarative region, [within which nested declarations can occur]: 
any declaration, other than that of an enumeration type, that is not a completion [of a previous declaration];
{AI12-0094-1} an access_definition;
a block_statement;
a loop_statement;
{AI05-0255-1} a quantified_expression;
{AI95-00318-02} an extended_return_statement;
an accept_statement;
an exception_handler.
The declarative region includes the text of the construct together with additional text determined [(recursively)], as follows: 
If a declaration is included, so is its completion, if any.
If the declaration of a library unit [(including Standard — see 10.1.1)] is included, so are the declarations of any child units [(and their completions, by the previous rule)]. The child declarations occur after the declaration.
If a body_stub is included, so is the corresponding subunit.
If a type_declaration is included, then so is a corresponding record_representation_clause, if any. 
Reason: This is so that the component_declarations can be directly visible in the record_representation_clause.
The declarative region of a declaration is also called the declarative region of any view or entity declared by the declaration.
Reason: The constructs that have declarative regions are the constructs that can have declarations nested inside them. Nested declarations are declared in that declarative region. The one exception is for enumeration literals; although they are nested inside an enumeration type declaration, they behave as if they were declared at the same level as the type. 
To be honest: A declarative region does not include parent_unit_names.
Ramification: A declarative region does not include context_clauses.
A declaration occurs immediately within a declarative region if this region is the innermost declarative region that encloses the declaration (the immediately enclosing declarative region), not counting the declarative region (if any) associated with the declaration itself. 
Discussion: Don't confuse the declarative region of a declaration with the declarative region in which it immediately occurs. 
[ A declaration is local to a declarative region if the declaration occurs immediately within the declarative region.] [An entity is local to a declarative region if the entity is declared by a declaration that is local to the declarative region.] 
Ramification: "Occurs immediately within" and "local to" are synonyms (when referring to declarations).
Thus, “local to” applies to both declarations and entities, whereas “occurs immediately within” only applies to declarations. We use this term only informally; for cases where precision is required, we use the term "occurs immediately within", since it is less likely to cause confusion. 
A declaration is global to a declarative region if the declaration occurs immediately within another declarative region that encloses the declarative region. An entity is global to a declarative region if the entity is declared by a declaration that is global to the declarative region. 
1  The children of a parent library unit are inside the parent's declarative region, even though they do not occur inside the parent's declaration or body. This implies that one can use (for example) "P.Q" to refer to a child of P whose defining name is Q, and that after "use P;" Q can refer (directly) to that child.
2  As explained above and in 10.1.1, “Compilation Units - Library Units”, all library units are descendants of Standard, and so are contained in the declarative region of Standard. They are not inside the declaration or body of Standard, but they are inside its declarative region.
3  For a declarative region that comes in multiple parts, the text of the declarative region does not contain any text that might appear between the parts. Thus, when a portion of a declarative region is said to extend from one place to another in the declarative region, the portion does not contain any text that might appear between the parts of the declarative region. 
Discussion: It is necessary for the things that have a declarative region to include anything that contains declarations (except for enumeration type declarations). This includes any declaration that has a profile (that is, subprogram_declaration, subprogram_body, entry_declaration, subprogram_renaming_declaration, formal_subprogram_declaration, access-to-subprogram type_declaration), anything that has a discriminant_part (that is, various kinds of type_declaration), anything that has a component_list (that is, record type_declaration and record extension type_declaration), and finally the declarations of task and protected units and packages.

Wording Changes from Ada 83

It was necessary to extend Ada 83's definition of declarative region to take the following Ada 95 features into account: 
Child library units.
Derived types/type extensions — we need a declarative region for inherited components and also for new components.
All the kinds of types that allow discriminants.
Protected units.
Entries that have bodies instead of accept statements.
The choice_parameter_specification of an exception_handler.
The formal parameters of access-to-subprogram types.
Discriminated and access-to-subprogram type declarations need a declarative region. Enumeration type declarations cannot have one, because you don't have to say "Color.Red" to refer to the literal Red of Color. For other type declarations, it doesn't really matter whether or not there is an associated declarative region, so for simplicity, we give one to all types except enumeration types.
We now say that an accept_statement has its own declarative region, rather than being part of the declarative region of the entry_declaration, so that declarative regions are properly nested regions of text, so that it makes sense to talk about "inner declarative regions," and "...extends to the end of a declarative region." Inside an accept_statement, the name of one of the parameters denotes the parameter_specification of the accept_statement, not that of the entry_declaration. If the accept_statement is nested within a block_statement, these parameter_specifications can hide declarations of the block_statement. The semantics of such cases was unclear in RM83. 
To be honest: Unfortunately, we have the same problem for the entry name itself — it should denote the accept_statement, but accept_statements are not declarations. They should be, and they should hide the entry from all visibility within themselves. 
Note that we can't generalize this to entry_bodies, or other bodies, because the declarative_part of a body is not supposed to contain (explicit) homographs of things in the declaration. It works for accept_statements only because an accept_statement does not have a declarative_part.
To avoid confusion, we use the term “local to” only informally in Ada 95. Even RM83 used the term incorrectly (see, for example, RM83-12.3(13)).
In Ada 83, (root) library units were inside Standard; it was not clear whether the declaration or body of Standard was meant. In Ada 95, they are children of Standard, and so occur immediately within Standard's declarative region, but not within either the declaration or the body. (See RM83-8.6(2) and RM83-10.1.1(5).) 

Wording Changes from Ada 95

{AI95-00318-02} Extended_return_statement (see 6.5) is added to the list of constructs that have a declarative region. 

Extensions to Ada 2012

{AI12-0094-1} Corrigendum: access_definition is added to the list of constructs that have a declarative region. This allows parameter names declared in anonymous access type subprogram types to be the same as other names declared outside. For instance:
type Foo is record
   A : Natural;
   B : access procedure (A : Boolean);
end record;
This is now legal, as one would expect; it was illegal in previous versions of Ada as the parameter A and the component A were homographs in the same declarative region (see 8.3). Note that some implementations already allow this common sense interpretation, so this extension may in fact be used in existing code. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe