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. 
 
14  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;
15  
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. 
 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe