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.