Skip to main content

3.1 Declarations


This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue


The language defines several kinds of named entities that are declared by declarations. The entity's name is defined by the declaration, usually by a defining_identifier, but sometimes by a defining_character_literal or defining_operator_symbol. There are also entities that are not directly declared; some of these are elements of other entities, or are allocated dynamically. Such entities can be denoted using indexed_component, selected_component, or dereference names (see 4.1).


Some entities are always anonymous. For instance, a type is never named (the name represents the first subtype). We don't mention those here as this paragraph is about named entities.


There are several forms of declaration. A basic_declaration is a form of declaration defined as follows.



basic_declaration ::=
type_declaration | subtype_declaration
| object_declaration | number_declaration
| subprogram_declaration | abstract_subprogram_declaration
| null_procedure_declaration | expression_function_declaration
| package_declaration | renaming_declaration
| exception_declaration | generic_declaration
| generic_instantiation

defining_identifier ::= identifier

Static Semantics


A declaration is a language construct that associates a name with (a view of) an entity. A declaration may appear explicitly in the program text (an explicit declaration), or may be supposed to occur at a given place in the text as a consequence of the semantics of another construct (an implicit declaration).


An implicit declaration generally declares a predefined or inherited operation associated with the definition of a type. This term is used primarily when allowing explicit declarations to override implicit declarations, as part of a type declaration.


Term entry: declaration — language construct that associates a name with (a view of) an entity
Note: A declaration can appear explicitly in the program text (an explicit declaration), or can be supposed to occur at a given place in the text as a consequence of the semantics of another construct (an implicit declaration).


Each of the following is defined to be a declaration: any basic_declaration; an enumeration_literal_specification; a discriminant_specification; a component_declaration; a defining_identifier of an iterated_component_association; a loop_parameter_specification; a defining_identifier of a chunk_specification; an iterator_specification; a defining_identifier of an iterator_parameter_specification; a parameter_specification; a subprogram_body; an extended_return_object_declaration; an entry_declaration; an entry_index_specification; a choice_parameter_specification; a generic_formal_parameter_declaration.


This list (when basic_declaration is expanded out) contains all syntactic categories that end in "_declaration" or "_specification", except for program unit _specifications. Moreover, it contains subprogram_body. A subprogram_body is a declaration, whether or not it completes a previous declaration. This is a bit strange, subprogram_body is not part of the syntax of basic_declaration or library_unit_declaration. A renaming-as-body is considered a declaration. An accept_statement is not considered a declaration. Completions are sometimes declarations, and sometimes not.


All declarations contain a definition for a view of an entity. A view consists of an identification of the entity (the entity of the view), plus view-specific characteristics that affect the use of the entity through that view (such as mode of access to an object, formal parameter names and defaults for a subprogram, or visibility to components of a type). In most cases, a declaration also contains the definition for the entity itself (a renaming_declaration is an example of a declaration that does not define a new entity, but instead defines a view of an existing entity (see 8.5)).


Term entry: view of an entity — representation of an entity that reveals some or all of the properties of the entity
Note: A single entity can have multiple views.


Most declarations define a view (of some entity) whose view-specific characteristics are unchanging for the life of the view. However, subtypes are somewhat unusual in that they inherit characteristics from whatever view of their type is currently visible. Hence, a subtype is not a view of a type; it is more of an indirect reference. By contrast, a private type provides a single, unchanging (partial) view of its full type.


When it is clear from context, the term object is used in place of view of an object. Similarly, the terms type and subtype are used in place of view of a type and view of a subtype, respectively.


Rules interpreted at compile time generally refer to views of entities, rather than the entities themselves. This is necessary to preserve privacy; characteristics that are not visible should not be used in compile-time rules. Thus, Static Semantics and Legality Rules generally implicitly have “view of”. Legality Rules that need to look into the private part are the exception to this interpretation.


On the other hand, run-time rules can work either way, so “view of” should not be assumed in Dynamic Semantics rules.


For example, a reference to the components of an object in a rule that is interpreted at compile time would not apply to components that are not visible. On the other hand, a reference to the components of an object in a dynamic semantics rule would apply to all components of the object, visible or not, including (for tagged objects) components which are not components of the nominal type of the object (see 3.9.1). Other terms, such as “subcomponent” and “part”, are interpreted analogously.


For each declaration, the language rules define a certain region of text called the scope of the declaration (see 8.2). Most declarations associate an identifier with a declared entity. Within its scope, and only there, there are places where it is possible to use the identifier to refer to the declaration, the view it defines, and the associated entity; these places are defined by the visibility rules (see 8.3). At such places the identifier is said to be a name of the entity (the direct_name or selector_name); the name is said to denote the declaration, the view, and the associated entity (see 8.6). The declaration is said to declare the name, the view, and in most cases, the entity itself.


As an alternative to an identifier, an enumeration literal can be declared with a character_literal as its name (see 3.5.1), and a function can be declared with an operator_symbol as its name (see 6.1).


The syntax rules use the terms defining_identifier, defining_character_literal, and defining_operator_symbol for the defining occurrence of a name; these are collectively called defining names. The terms direct_name and selector_name are used for usage occurrences of identifiers, character_literals, and operator_symbols. These are collectively called usage names.


To be honest: The terms identifier, character_literal, and operator_symbol are used directly in contexts where the normal visibility rules do not apply (such as the identifier that appears after the end of a task_body). Analogous conventions apply to the use of designator, which is the collective term for identifier and operator_symbol.

Dynamic Semantics


The process by which a construct achieves its run-time effect is called execution. This process is also called elaboration for declarations and evaluation for expressions. One of the terms execution, elaboration, or evaluation is defined by this Reference Manual for each construct that has a run-time effect.


Term entry: execution — process by which a construct achieves its run-time effect
Note: Execution of a declaration is also called elaboration. Execution of an expression is also called evaluation.


To be honest: The term elaboration is also used for the execution of certain constructs that are not declarations, and the term evaluation is used for the execution of certain constructs that are not expressions. For example, subtype_indications are elaborated, and ranges are evaluated.


For bodies, execution and elaboration are both explicitly defined. When we refer specifically to the execution of a body, we mean the explicit definition of execution for that kind of body, not its elaboration.


Technically, "the execution of a declaration" and "the elaboration of a declaration" are synonymous. We use the term "elaboration" of a construct when we know the construct is elaborable. When we are talking about more arbitrary constructs, we use the term "execution". For example, we use the term "erroneous execution", to refer to any erroneous execution, including erroneous elaboration or evaluation.


When we explicitly define evaluation or elaboration for a construct, we are implicitly defining execution of that construct.


We also use the term "execution" for things like statements, which are executable, but neither elaborable nor evaluable. We considered using the term "execution" only for nonelaborable, nonevaluable constructs, and defining the term "action" to mean what we have defined "execution" to mean. We rejected this idea because we thought three terms that mean the same thing was enough — four would be overkill. Thus, the term "action" is used only informally in the standard (except where it is defined as part of a larger term, such as "protected action").


Term entry: elaboration — process by which a declaration achieves its run-time effect
Note: Elaboration is one of the forms of execution.


Term entry: evaluation — process by which an expression achieves its run-time effect
Note: Evaluation is one of the forms of execution.


To be honest: A construct is elaborable if elaboration is defined for it. A construct is evaluable if evaluation is defined for it. A construct is executable if execution is defined for it.


Don't confuse “elaborable” with “preelaborable” (defined in 10.2.1).


Evaluation of an evaluable construct produces a result that is either a value, a denotation, or a range. The following are evaluable: expression; name prefix; range; entry_index_specification; and possibly discrete_range. The last one is curious — RM83 uses the term “evaluation of a discrete_range”, but never defines it. One might presume that the evaluation of a discrete_range consists of the evaluation of the range or the subtype_indication, depending on what it is. But subtype_indications are not evaluated; they are elaborated.


Intuitively, an executable construct is one that has a defined run-time effect (which may be null). Since execution includes elaboration and evaluation as special cases, all elaborable and all evaluable constructs are also executable. Hence, most constructs in Ada are executable. An important exception is that the constructs inside a generic unit are not executable directly, but rather are used as a template for (generally) executable constructs in instances of the generic.


NOTE At compile time, the declaration of an entity declares the entity. At run time, the elaboration of the declaration creates the entity.


Syntactic categories for declarations are named either entity_declaration (if they include a trailing semicolon) or entity_specification (if not).


The various kinds of named entities that can be declared are as follows: an object (including components and parameters), a named number, a type (the name always refers to its first subtype), a subtype, a subprogram (including enumeration literals and operators), a single entry, an entry family, a package, a protected or task unit (which corresponds to either a type or a single object), an exception, a generic unit, a label, and the name of a statement.


Identifiers are also associated with names of pragmas, arguments to pragmas, and with attributes, but these are not user-definable.

Wording Changes from Ada 83


The syntax rule for defining_identifier is new. It is used for the defining occurrence of an identifier. Usage occurrences use the direct_name or selector_name syntactic categories. Each occurrence of an identifier (or simple_name), character_literal, or operator_symbol in the Ada 83 syntax rules is handled as follows in Ada 95:


For declarations that come in “two parts” (program unit declaration plus body, private or incomplete type plus full type, deferred constant plus full constant), we consider both to be defining occurrences. Thus, for example, the syntax for package_body uses defining_identifier after the reserved word body, as opposed to direct_name.


The defining occurrence of a statement name is in its implicit declaration, not where it appears in the program text. Considering the statement name itself to be the defining occurrence would complicate the visibility rules.


The phrase “visible by selection” is not used in Ada 95. It is subsumed by simply “visible” and the Name Resolution Rules for selector_names.


(Note that in Ada 95, a declaration is visible at all places where one could have used a selector_name, not just at places where a selector_name was actually used. Thus, the places where a declaration is directly visible are a subset of the places where it is visible. See Clause 8 for details.)


We use the term “declaration” to cover _specifications that declare (views of) objects, such as parameter_specifications. In Ada 83, these are referred to as a “form of declaration”, but it is not entirely clear that they are considered simply “declarations”.


RM83 contains an incomplete definition of "elaborated" in this subclause: it defines "elaborated" for declarations, declarative_parts, declarative_items and compilation_units, but "elaboration" is defined elsewhere for various other constructs. To make matters worse, Ada 95 has a different set of elaborable constructs. Instead of correcting the list, it is more maintainable to refer to the term "elaborable," which is defined in a distributed manner.


RM83 uses the term “has no other effect” to describe an elaboration that doesn't do anything except change the state from not-yet-elaborated to elaborated. This was a confusing wording, because the answer to “other than what?” was to be found many pages away. In Ada 95, we change this wording to “has no effect” (for things that truly do nothing at run time), and “has no effect other than to establish that so-and-so can happen without failing the Elaboration_Check” (for things where it matters).


We make it clearer that the term "execution" covers elaboration and evaluation as special cases. This was implied in RM83. For example, "erroneous execution" can include any execution, and RM83-9.4(3) has, "The task designated by any other task object depends on the master whose execution creates the task object;" the elaboration of the master's declarative_part is doing the task creation.

Wording Changes from Ada 95


Added extended_return_statement to the list of declarations.


Added null procedures (see 6.7) to the syntax.

Wording Changes from Ada 2005


Added expression functions (see 6.8) to the syntax.