10.2.1 Elaboration Control
This subclause defines aspects
and pragmas that help control the elaboration order of
library_items.
Legality Rules
An
elaborable construct is preelaborable unless its elaboration performs
any of the following actions:
A call to a subprogram
other than:
a static function;
an instance of Unchecked_Conversion (see
13.9);
a function declared in System.Storage_Elements
(see
13.7.1); or
the functions To_Pointer and To_Address
declared in an instance of System.Address_to_Access_Conversions (see
13.7.2).
The evaluation of a
primary
that is a
name
of an object, unless the
name
is a static expression, or statically denotes a discriminant of an enclosing
type.
The creation of an object (including a component)
that is initialized by default, if its type does not have preelaborable
initialization. Similarly, the evaluation of an
extension_aggregate
with an ancestor
subtype_mark
denoting a subtype of such a type.
The elaboration of any elaborable construct that
is not preelaborable.
A generic declaration is preelaborable unless every
instance would perform one of the above actions.
A generic body is preelaborable
only if elaboration of a corresponding instance body would not perform
any such actions, presuming that:
the actual for each discriminated formal derived
type, formal private type, or formal private extension declared within
the formal part of the generic unit is a type that does not have preelaborable
initialization, unless the Preelaborable_Initialization aspect was specified
for the formal type;
the actual for each formal type is nonstatic;
the actual for each formal object is nonstatic;
and
the actual for each formal subprogram is a user-defined
subprogram.
When the library unit aspect
(see
13.1.1) Preelaborate
of a program unit is True, the unit is said to be
preelaborated.
When the Preelaborate aspect is specified True for a library unit, all
compilation units of the library unit are preelaborated. The declaration
and body of a preelaborated library unit, and all subunits that are elaborated
as part of elaborating the library unit, shall be preelaborable. All
compilation units of a preelaborated library unit shall depend semantically
only on declared pure or preelaborated
library_items.
In addition to the places where Legality Rules normally
apply (see
12.3), these rules also apply in
the private part of an instance of a generic unit.
If
a library unit is preelaborated, then its declaration, if any, and body,
if any, are elaborated prior to all nonpreelaborated
library_items
of the partition.
The following rules specify
which entities have
preelaborable initialization, namely that
the Preelaborable_Initialization aspect of the entity is True:
The partial view of a private type or private extension,
a protected type without
entry_declarations,
a generic formal private type, or a generic formal derived type, has
preelaborable initialization if and only if the Preelaborable_Initialization
aspect has been specified True for them. A protected type with
entry_declarations
or a task type never has preelaborable initialization. The Preelaborable_Initialization
aspect of a partial view of a type may be specified as False, even if
the full view of the type has preelaborable initialization. Similarly,
a generic formal type may be specified with Preelaborable_Initialization
False, even if the actual type in an instance has preelaborable initialization.
A component (including a discriminant) of a record
or protected type has preelaborable initialization if its declaration
includes a
default_expression
whose execution does not perform any actions prohibited in preelaborable
constructs as described above, or if its declaration does not include
a default expression and its type has preelaborable initialization.
A derived type has preelaborable initialization
if its parent type has preelaborable initialization and if the noninherited
components all have preelaborable initialization. However, a controlled
type with an Initialize procedure that is not a null procedure does not
have preelaborable initialization.
A view of a type has preelaborable initialization
if it is an elementary type, an array type whose component type has preelaborable
initialization, a record type whose components all have preelaborable
initialization, or an interface type.
The following attribute is defined for a nonformal
composite subtype S declared within the visible part of a package or
a generic package, or a generic formal private subtype or formal derived
subtype:
S'Preelaborable_Initialization
This attribute is of Boolean
type, and its value reflects whether the type of S has preelaborable
initialization. The value of this attribute, the type-related Preelaborable_Initialization
aspect, may be specified for any type for which the attribute is defined.
The value shall be specified by a static expression, unless the type
is not a formal type but is nevertheless declared within a generic package.
In this latter case, the value may also be specified by references to
the Preelaborable_Initialization attribute of one or more formal types
visible at the point of the declaration of the composite type, conjoined
with
and.
If the Preelaborable_Initialization aspect is specified
True for a private type or a private extension, the full view of the
type shall have preelaborable initialization. If the aspect is specified
True for a protected type, the protected type shall not have entries,
and each component of the protected type shall have preelaborable initialization.
If the aspect is specified True for a generic formal type, then in a
generic_instantiation
the corresponding actual type shall have preelaborable initialization.
If the aspect definition includes one or more Preelaborable_Initialization
attribute_references,
then the full view of the type shall have preelaborable initialization
presuming the types mentioned in the
prefixes
of the
attribute_references
all have preelaborable initialization. For any other composite type,
the aspect shall be specified statically True or False only if it is
confirming.
In addition to the places where Legality
Rules normally apply (see
12.3), these rules
apply also in the private part of an instance of a generic unit.
Implementation Advice
In an implementation, a type declared in a preelaborated
package should have the same representation in every elaboration of a
given version of the package, whether the elaborations occur in distinct
executions of the same program, or in executions of distinct programs
or partitions that include the given version.
Static Semantics
A
pure program unit is a preelaborable program unit whose elaboration
does not perform any of the following actions:
the elaboration of a variable declaration;
the evaluation of an
allocator
of an access-to-variable type; for the purposes of this rule, the partial
view of a type is presumed to have nonvisible components whose default
initialization evaluates such an
allocator;
the elaboration of the declaration of a nonderived
named access-to-variable type unless the Storage_Size of the type has
been specified by a static expression with value zero or is defined by
the language to be zero;
the elaboration of the declaration of a nonderived
named access-to-constant type for which the Storage_Size has been specified
by an expression other than a static expression with value zero;
the elaboration of any program unit that is not
pure.
A generic declaration is pure unless every instance
would perform one of the above actions.
A generic body is pure only if elaboration of a
corresponding instance body would not perform any such actions presuming
any composite formal types have nonvisible components whose default initialization
evaluates an
allocator
of an access-to-variable type.
The Storage_Size for an anonymous access-to-variable
type declared at library level in a library unit that is declared pure
is defined to be zero.
Legality Rules
This paragraph was
deleted.
When the library unit aspect
Pure of a program unit is True, the unit is said to be
declared pure.
When the Pure aspect is specified True for a library unit, all compilation
units of the library unit are declared pure. In addition, the limited
view of any library package is declared pure. The declaration and body
of a declared pure library unit, and all subunits that are elaborated
as part of elaborating the library unit, shall be pure. All compilation
units of a declared pure library unit shall depend semantically only
on declared pure
library_items.
In addition to the places where Legality Rules normally
apply (see
12.3), these rules also apply in
the private part of an instance of a generic unit. Furthermore, the full
view of any partial view declared in the visible part of a declared pure
library unit that has any available stream attributes shall support external
streaming (see
13.13.2).
Erroneous Execution
Execution is erroneous if some operation (other
than the initialization or finalization of the object) modifies the value
of a constant object declared at library-level in a pure package.
Implementation Permissions
If a library unit is declared pure, then the implementation
is permitted to omit a call on a library-level subprogram of the library
unit if the results are not needed after the call. In addition, the implementation
may omit a call on such a subprogram and simply reuse the results produced
by an earlier call on the same subprogram, provided that none of the
parameters nor any object accessible via access values from the parameters
have any part that is of a type whose full type is an immutably limited
type, and the addresses and values of all by-reference actual parameters,
the values of all by-copy-in actual parameters, and the values of all
objects accessible via access values from the parameters, are the same
as they were at the earlier call. This permission applies even if the
subprogram produces other side effects when called.
Syntax
The following
pragmas
are defined with the given forms:
pragma Elaborate(
library_unit_name{,
library_unit_name});
pragma Elaborate_All(
library_unit_name{,
library_unit_name});
This paragraph
was deleted.
This paragraph
was deleted.
Legality Rules
If the aspect Elaborate_Body is True for a declaration,
then the declaration requires a completion (a body).
The
library_unit_name
of a
pragma
Elaborate or Elaborate_All shall denote a nonlimited view of a library
unit.
Static Semantics
A
pragma
Elaborate specifies that the body of the named library unit is elaborated
before the current
library_item.
A
pragma Elaborate_All
specifies that each
library_item
that is needed by the named library unit declaration is elaborated before
the current
library_item.
If the Elaborate_Body aspect of a library unit
is True, the body of the library unit is elaborated immediately after
its declaration.
NOTE 1 A preelaborated library unit
can have nonpreelaborable children.
NOTE 2 A library unit that is declared
pure can have impure children.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe