# Types

Types can be created in several ways:

- fundamental types can be accessed using `gccjit.Context.get_type()`:

      int_type = ctxt.get_type(gccjit.TypeKind.INT)

  See `gccjit.TypeKind` for the available types.

  You can get int types of specific sizes (in bytes) using `gccjit.Context.get_int_type()`:

      int_type = ctxt.get_int_type(4, is_signed=True)

- derived types can be accessed by calling methods on an existing type:

      const_int_star = int_type.get_const().get_pointer()
      int_const_star = int_type.get_pointer().get_const()

- by creating structures (see below).

class `gccjit.``Type`
  `get_pointer`()

    Given type T get type T*.

    Return type: | `gccjit.Type`

  `get_const`()

    Given type T get type const T.

    Return type: | `gccjit.Type`

  `get_volatile`()

    Given type T get type volatile T.

    Return type: | `gccjit.Type`

## Standard types

`gccjit.Context.``get_type`(self, type_enum)

  Look up one of the standard types (see `gccjit.TypeKind`):

      int_type = ctxt.get_type(gccjit.TypeKind.INT)

  Parameters: | type_enum (`gccjit.TypeKind`) – Which type to lookup

class `gccjit.``TypeKind`
  `VOID`

    C’s “void” type.

  `VOID_PTR`

    C’s “void *”.

  `BOOL`

    C++’s bool type; also C99’s “_Bool” type, aka “bool” if using stdbool.h.

  `CHAR`
  `SIGNED_CHAR`
  `UNSIGNED_CHAR`

    C’s “char” (of some signedness) and the variants where the signedness is specified.

  `SHORT`
  `UNSIGNED_SHORT`

    C’s “short” (signed) and “unsigned short”.

  `INT`
  `UNSIGNED_INT`

    C’s “int” (signed) and “unsigned int”:

        int_type = ctxt.get_type(gccjit.TypeKind.INT)

  `LONG`
  `UNSIGNED_LONG`

    C’s “long” (signed) and “unsigned long”.

  `LONG_LONG`
  `UNSIGNED_LONG_LONG`

    C99’s “long long” (signed) and “unsigned long long”.

  `FLOAT`
  `DOUBLE`
  `LONG_DOUBLE`

    Floating-point types

  `CONST_CHAR_PTR`

    C type: (const char *):

        const_char_p = ctxt.get_type(gccjit.TypeKind.CONST_CHAR_PTR)

  `SIZE_T`

    The C “size_t” type.

  `FILE_PTR`

    C type: (FILE *)

`gccjit.Context.``get_int_type`(self, num_bytes, is_signed)

  Look up an integet type of the given size:

      int_type = ctxt.get_int_type(4, is_signed=True)

## Structures

You can model C struct types by creating `gccjit.Struct` and `gccjit.Field` instances, in either order:

- by creating the fields, then the structure. For example, to model:

      struct coord {double x; double y; };

  you could call:

      field_x = ctxt.new_field(double_type, b'x')
      field_y = ctxt.new_field(double_type, b'y')
      coord = ctxt.new_struct(b'coord', [field_x, field_y])

  (see `gccjit.Context.new_field()` and `gccjit.Context.new_struct()`), or

- by creating the structure, then populating it with fields, typically to allow modelling self-referential structs such as:

      struct node { int m_hash; struct node *m_next; };

  like this:

      node = ctxt.new_struct(b'node')
      node_ptr = node.get_pointer()
      field_hash = ctxt.new_field(int_type, b'm_hash')
      field_next = ctxt.new_field(node_ptr, b'm_next')
      node.set_fields([field_hash, field_next])

  (see `gccjit.Struct.set_fields()`)

class `gccjit.``Field`

class `gccjit.``Struct`
  `set_fields`(fields, loc=None)

    Populate the fields of a formerly-opaque struct type. This can only be called once on a given struct type.