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) 
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.
 
 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 
pragma 
Preelaborable_Initialization has been applied to 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. 
 A 
pragma 
Preelaborate (or 
pragma 
Pure — see below) is used to specify that a library unit is 
preelaborated, 
namely that the Preelaborate aspect
 
of the library unit is True; 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:
 
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 
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 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. 
   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 composite type, 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, the protected type shall not have entries, 
and each component of the protected type shall have preelaborable initialization. 
For any other composite type, the type shall have preelaborable initialization. 
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. 
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
   A 
pure compilation unit is a preelaborable compilation 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.
   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.
 A 
pragma 
Pure is used to specify that a library unit is 
declared pure, 
namely that the Pure aspect
 of 
the library unit is True; 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 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 the aspect Elaborate_Body 
is True for a declaration (including when 
pragma 
Elaborate_Body applies), 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 sets the Elaborate_Body representation aspect of the library 
unit to which it applies to the value True. If the Elaborate_Body aspect 
of a library unit is True, the body of the library unit is elaborated 
immediately after its declaration.
 
12  A preelaborated library unit is allowed 
to have nonpreelaborable children. 
13  A library unit that is declared pure 
is allowed to have impure children. 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe