(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Type expressions for the Compcert C and Clight languages *)
Require Archi.
(** * Syntax of types *)
(** Compcert C types are similar to those of C.  They include numeric types, pointers, arrays, function types, and composite types (struct and union).  Numeric types (integers and floats) fully specify the bit size of the type.  An integer type is a pair of a signed/unsigned flag and a bit size: 8, 16, or 32 bits, or the special [IBool] size standing for the C99 [_Bool] type.  64-bit integers are treated separately. *)
Inductive signedness : Type :=
| Signed: signedness
| Unsigned: signedness.
Inductive intsize : Type :=
| I8: intsize
| I16: intsize
| I32: intsize
| IBool: intsize.
(** Float types come in two sizes: 32 bits (single precision) and 64-bit (double precision). *)
Inductive floatsize : Type :=
| F32: floatsize
| F64: floatsize.
(** Every type carries a set of attributes.  Currently, only two attributes are modeled: [volatile] and [_Alignas(n)] (from ISO C 2011). *)
Record attr : Type := mk_attr {
attr_volatile: bool;
attr_alignas: option N         (**r log2 of required alignment *)
}.
Definition noattr := {| attr_volatile := false; attr_alignas := None |}.
(** The syntax of type expressions.  Some points to note: - Array types [Tarray n] carry the size [n] of the array. Arrays with unknown sizes are represented by pointer types. - Function types [Tfunction targs tres] specify the number and types of the function arguments (list [targs]), and the type of the function result ([tres]).  Variadic functions and old-style unprototyped functions are not supported. *)
Inductive type : Type :=
| Tvoid: type                                    (**r the [void] type *)
| Tint: intsize -> signedness -> attr -> type    (**r integer types *)
| Tlong: signedness -> attr -> type              (**r 64-bit integer types *)
| Tfloat: floatsize -> attr -> type              (**r floating-point types *)
| Tpointer: type -> attr -> type                 (**r pointer types ([*ty]) *)
| Tarray: type -> Z -> attr -> type              (**r array types ([ty[len]]) *)
| Tfunction: typelist -> type -> calling_convention -> type    (**r function types *)
| Tstruct: ident -> attr -> type                 (**r struct types *)
| Tunion: ident -> attr -> type                  (**r union types *)
with typelist : Type :=
| Tnil: typelist
| Tcons: type -> typelist -> typelist.

(* Specifications: *)
Lemma intsize_eq: forall (s1 s2: intsize), {s1=s2} + {s1<>s2}.
Lemma alignof_two_p:
forall env t, exists n, alignof env t = two_power_nat n.
Lemma alignof_pos:
forall env t, alignof env t > 0.
Lemma intsize_eq: forall (s1 s2: intsize), {s1=s2} + {s1<>s2}.
Lemma alignof_two_p:
forall env t, exists n, alignof env t = two_power_nat n.
Lemma alignof_pos:
forall env t, alignof env t > 0.