10.2.1 Elaboration Control
This subclause defines pragmas
that help control the elaboration order of
library_items.
Syntax
The form of a
pragma
Preelaborate is as follows:
pragma Preelaborate[(
library_unit_name)];
A
pragma
Preelaborate is a library unit pragma.
The form of a
pragma
Preelaborable_Initialization is as follows:
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.
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)
of a type that does not have preelaborable initialization. Similarly,
the evaluation of an
extension_aggregate
with an ancestor
subtype_mark
denoting a subtype of such a type.
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 formal private type (or extension)
declared within the formal part of the generic unit is a private type
(or extension) that does not have preelaborable initialization;
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.
If a
pragma
Preelaborate (or
pragma
Pure — see below) applies to a library unit, then it is
preelaborated.
If a library unit is preelaborated, then its declaration,
if any, and body, if any, are elaborated prior to all non-preelaborated
library_items
of the partition. 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.
In addition
to the places where Legality Rules normally apply (see
12.3),
this rule applies also in the private part of an instance of a generic
unit. In addition, all compilation units of a preelaborated library unit
shall depend semantically only on compilation units of other preelaborated
library units.
The following rules specify
which entities have
preelaborable initialization:
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, have
preelaborable initialization if and only if the
pragma
Preelaborable_Initialization has been applied to them. A protected type
with
entry_declarations
or a task type never 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 (in the case
of a derived record extension) if the non-inherited components all have
preelaborable initialization. However, a user-defined controlled type
with an overriding Initialize 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.
A
pragma
Preelaborable_Initialization specifies that a type has preelaborable
initialization. This pragma shall appear in the visible part of a package
or generic package.
If the pragma appears in the first list of
basic_declarative_items
of a
package_specification,
then the
direct_name
shall denote the first subtype of a private type, private extension,
or protected type that is not an interface type and is without
entry_declarations,
and the type shall be declared immediately within the same package as
the
pragma.
If the
pragma
is applied to a private type or a private extension, the full view of
the type shall have preelaborable initialization. If the
pragma
is applied to a protected type, each component of the protected type
shall have preelaborable initialization. In addition to the places where
Legality Rules normally apply, 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.
Syntax
The form of a
pragma
Pure is as follows:
pragma Pure[(
library_unit_name)];
A
pragma
Pure is a library unit pragma.
Static Semantics
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 non-visible components whose default
initialization evaluates such an
allocator;
the elaboration of the declaration of a 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 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 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.
A
pragma
Pure is used to declare that a library unit is pure. If a
pragma
Pure applies to a library unit, then its compilation units shall be pure,
and they shall depend semantically only on compilation units of other
library units that are declared pure. Furthermore, the full view of any
partial view declared in the visible part of the library unit that has
any available stream attributes shall support external streaming (see
13.13.2).
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
are of a 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 form of a
pragma
Elaborate, Elaborate_All, or Elaborate_Body is as follows:
pragma Elaborate(
library_unit_name{,
library_unit_name});
pragma Elaborate_All(
library_unit_name{,
library_unit_name});
pragma Elaborate_Body[(
library_unit_name)];
A
pragma
Elaborate_Body is a library unit pragma.
Legality Rules
If a
pragma
Elaborate_Body applies to 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.
A
pragma Elaborate_Body
specifies that the body of the library unit is elaborated immediately
after its declaration.
12 A preelaborated library unit is allowed
to have non-preelaborable children.
13 A library unit that is declared pure
is allowed to have impure children.