(** ** Size and alignment for composite definitions *)
(** The alignment for a structure or union is the max of the alignment of its members. *)
Fixpoint alignof_composite (env: composite_env) (m: members) : Z :=
match m with
| nil => 1
| (id, t) :: m' => Z.max (alignof env t) (alignof_composite env m')
end.
(** The size of a structure corresponds to its layout: fields are laid out consecutively, and padding is inserted to align each field to the alignment for its type. *)
Fixpoint sizeof_struct (env: composite_env) (cur: Z) (m: members) : Z :=
match m with
| nil => cur
| (id, t) :: m' => sizeof_struct env (align cur (alignof env t) + sizeof env t) m'
end.
(** The size of an union is the max of the sizes of its members. *)
Fixpoint sizeof_union (env: composite_env) (m: members) : Z :=
match m with
| nil => 0
| (id, t) :: m' => Z.max (sizeof env t) (sizeof_union env m')
end.

(* Specifications: *)
Lemma alignof_composite_two_p:
forall env m, exists n, alignof_composite env m = two_power_nat n.
Lemma alignof_composite_pos:
forall env m a, align_attr a (alignof_composite env m) > 0.
Lemma sizeof_struct_incr:
forall env m cur, cur <= sizeof_struct env cur m.
Lemma sizeof_union_pos:
forall env m, 0 <= sizeof_union env m.
Lemma alignof_composite_two_p:
forall env m, exists n, alignof_composite env m = two_power_nat n.
Lemma alignof_composite_pos:
forall env m a, align_attr a (alignof_composite env m) > 0.
Lemma sizeof_struct_incr:
forall env m cur, cur <= sizeof_struct env cur m.
Lemma sizeof_union_pos:
forall env m, 0 <= sizeof_union env m.