13.5.1 Record Representation Clauses
A
record_representation_clause
specifies the storage representation of records and record extensions,
that is, the order, position, and size of components (including discriminants,
if any).
Syntax
Name Resolution Rules
Legality Rules
If the
component_local_name
is a
direct_name,
the
local_name
shall denote a component of the type. For a record extension, the component
shall not be inherited, and shall not be a discriminant that corresponds
to a discriminant of the parent type. If the
component_local_name
has an
attribute_designator,
the
direct_name
of the
local_name
shall denote either the declaration of the type or a component of the
type, and the
attribute_designator
shall denote an implementation-defined implicit component of the type.
If the nondefault
bit ordering applies to the type, then either:
the value of
last_bit
shall be less than the size of the largest machine scalar; or
the value of
first_bit
shall be zero and the value of
last_bit
+ 1 shall be a multiple of System.Storage_Unit.
Static Semantics
If the nondefault
bit ordering applies to the type then the layout is determined as follows:
the
component_clauses
for which the value of
last_bit
is greater than or equal to the size of the largest machine scalar directly
specify the position and size of the corresponding component;
A
record_representation_clause
for a record extension does not override the layout of the parent part;
if the layout was specified for the parent type, it is inherited by the
record extension.
Implementation Permissions
An implementation may generate implementation-defined
components (for example, one containing the offset of another component).
An implementation may generate names that denote such implementation-defined
components; such names shall be implementation-defined
attribute_references.
An implementation may allow such implementation-defined names to be used
in
record_representation_clauses.
An implementation can restrict such
component_clauses
in any manner it sees fit.
If a
record_representation_clause
is given for an untagged derived type, the storage place attributes for
all of the components of the derived type may differ from those of the
corresponding components of the parent type, even for components whose
storage place is not specified explicitly in the
record_representation_clause.
Implementation Advice
An implementation should support machine scalars
that correspond to all of the integer, floating point, and address formats
supported by the machine.
An implementation should support storage places
that can be extracted with a load, mask, shift sequence of machine code,
and set with a load, shift, mask, store sequence, given the available
machine instructions and run-time model.
A storage place should be supported if its size
is equal to the Size of the component subtype, and it starts and ends
on a boundary that obeys the Alignment of the component subtype.
For a component with a subtype whose Size is less
than the word size, any storage place that does not cross an aligned
word boundary should be supported.
An implementation may reserve a storage place for
the tag field of a tagged type, and disallow other components from overlapping
that place.
An implementation need not support a
component_clause
for a component of an extension part if the storage place is not after
the storage places of all components of the parent type, whether or not
those storage places had been specified.
11 If no
component_clause
is given for a component, then the choice of the storage place for the
component is left to the implementation. If
component_clauses
are given for all components, the
record_representation_clause
completely specifies the representation of the type and will be obeyed
exactly by the implementation.
Examples
Example of specifying
the layout of a record type:
Word : constant := 4; -- storage element is byte, 4 bytes per word
type State is (A,M,W,P);
type Mode is (Fix, Dec, Exp, Signif);
type Byte_Mask is array (0..7) of Boolean;
type State_Mask is array (State) of Boolean;
type Mode_Mask is array (Mode) of Boolean;
type Program_Status_Word is
record
System_Mask : Byte_Mask;
Protection_Key : Integer range 0 .. 3;
Machine_State : State_Mask;
Interrupt_Cause : Interruption_Code;
Ilc : Integer range 0 .. 3;
Cc : Integer range 0 .. 3;
Program_Mask : Mode_Mask;
Inst_Address : Address;
end record;
for Program_Status_Word use
record
System_Mask at 0*Word range 0 .. 7;
Protection_Key at 0*Word range 10 .. 11; -- bits 8,9 unused
Machine_State at 0*Word range 12 .. 15;
Interrupt_Cause at 0*Word range 16 .. 31;
Ilc at 1*Word range 0 .. 1; -- second word
Cc at 1*Word range 2 .. 3;
Program_Mask at 1*Word range 4 .. 7;
Inst_Address at 1*Word range 8 .. 31;
end record;
for Program_Status_Word'Size use 8*System.Storage_Unit;
for Program_Status_Word'Alignment use 8;
12
Note on the example: The
record_representation_clause
defines the record layout. The Size clause guarantees that (at least)
eight storage elements are used for objects of the type. The Alignment
clause guarantees that aliased, imported, or exported objects of the
type will have addresses divisible by eight.