Expressions

Rvalues

class gccjit::rvalue

A gccjit::rvalue is an expression that can be computed. It is a subclass of gccjit::object, and is a thin wrapper around gcc_jit_rvalue * from the C API.

It can be simple, e.g.:

  • an integer value e.g. 0 or 42
  • a string literal e.g. “Hello world”
  • a variable e.g. i. These are also lvalues (see below).

or compound e.g.:

  • a unary expression e.g. !cond
  • a binary expression e.g. (a + b)
  • a function call e.g. get_distance (&player_ship, &target)
  • etc.

Every rvalue has an associated type, and the API will check to ensure that types match up correctly (otherwise the context will emit an error).

gccjit::type gccjit::rvalue::get_type()

Get the type of this rvalue.

Simple expressions

gccjit::rvalue gccjit::context::new_rvalue(gccjit::type numeric_type, int value) const

Given a numeric type (integer or floating point), build an rvalue for the given constant int value.

gccjit::rvalue gccjit::context::new_rvalue(gccjit::type numeric_type, long value) const

Given a numeric type (integer or floating point), build an rvalue for the given constant long value.

gccjit::rvalue gccjit::context::zero(gccjit::type numeric_type) const

Given a numeric type (integer or floating point), get the rvalue for zero. Essentially this is just a shortcut for:

ctxt.new_rvalue (numeric_type, 0)
gccjit::rvalue gccjit::context::one(gccjit::type numeric_type) const

Given a numeric type (integer or floating point), get the rvalue for zero. Essentially this is just a shortcut for:

ctxt.new_rvalue (numeric_type, 1)
gccjit::rvalue gccjit::context::new_rvalue(gccjit::type numeric_type, double value) const

Given a numeric type (integer or floating point), build an rvalue for the given constant double value.

gccjit::rvalue gccjit::context::new_rvalue(gccjit::type pointer_type, void* value) const

Given a pointer type, build an rvalue for the given address.

gccjit::rvalue gccjit::context::new_rvalue(const std::string& value) const

Generate an rvalue of type GCC_JIT_TYPE_CONST_CHAR_PTR for the given string. This is akin to a string literal.

Unary Operations

gccjit::rvalue gccjit::context::new_unary_op(enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)

Build a unary operation out of an input rvalue.

Parameter loc is optional.

This is a thin wrapper around the C API’s gcc_jit_context_new_unary_op() and the available unary operations are documented there.

There are shorter ways to spell the various specific kinds of unary operation:

gccjit::rvalue gccjit::context::new_minus(gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)

Negate an arithmetic value; for example:

gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);

builds the equivalent of this C expression:

-pi
gccjit::rvalue new_bitwise_negate(gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)

Bitwise negation of an integer value (one’s complement); for example:

gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);

builds the equivalent of this C expression:

~a
gccjit::rvalue new_logical_negate(gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)

Logical negation of an arithmetic or pointer value; for example:

gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);

builds the equivalent of this C expression:

!cond

The most concise way to spell them is with overloaded operators:

gccjit::rvalue operator-(gccjit::rvalue a)
gccjit::rvalue negpi = -pi;
gccjit::rvalue operator~(gccjit::rvalue a)
gccjit::rvalue mask = ~a;
gccjit::rvalue operator!(gccjit::rvalue a)
gccjit::rvalue guard = !cond;

Binary Operations

gccjit::rvalue gccjit::context::new_binary_op(enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)

Build a binary operation out of two constituent rvalues.

Parameter loc is optional.

This is a thin wrapper around the C API’s gcc_jit_context_new_binary_op() and the available binary operations are documented there.

There are shorter ways to spell the various specific kinds of binary operation:

gccjit::rvalue gccjit::context::new_plus(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_minus(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_mult(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_divide(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_modulo(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_bitwise_and(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_bitwise_xor(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_bitwise_or(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_logical_and(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_logical_or(gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)

The most concise way to spell them is with overloaded operators:

gccjit::rvalue operator+(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue sum = a + b;
gccjit::rvalue operator-(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue diff = a - b;
gccjit::rvalue operator*(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue prod = a * b;
gccjit::rvalue operator/(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue result = a / b;
gccjit::rvalue operator%(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue mod = a % b;
gccjit::rvalue operator&(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue x = a & b;
gccjit::rvalue operator^(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue x = a ^ b;
gccjit::rvalue operator|(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue x = a | b;
gccjit::rvalue operator&&(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = a && b;
gccjit::rvalue operator||(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = a || b;

These can of course be combined, giving a terse way to build compound expressions:

gccjit::rvalue discriminant = (b * b) - (four * a * c);

Comparisons

gccjit::rvalue gccjit::context::new_comparison(enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)

Build a boolean rvalue out of the comparison of two other rvalues.

Parameter loc is optional.

This is a thin wrapper around the C API’s gcc_jit_context_new_comparison() and the available kinds of comparison are documented there.

There are shorter ways to spell the various specific kinds of binary operation:

gccjit::rvalue gccjit::context::new_eq(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_ne(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_lt(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_le(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_gt(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
gccjit::rvalue gccjit::context::new_ge(gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)

The most concise way to spell them is with overloaded operators:

gccjit::rvalue operator==(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = (a == ctxt.zero (t_int));
gccjit::rvalue operator!=(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = (i != j);
gccjit::rvalue operator<(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = i < n;
gccjit::rvalue operator<=(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = i <= n;
gccjit::rvalue operator>(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = (ch > limit);
gccjit::rvalue operator>=(gccjit::rvalue a, gccjit::rvalue b)
gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));

Function calls

gcc_jit_rvalue* gcc_jit_context_new_call(gcc_jit_context* ctxt, gcc_jit_location* loc, gcc_jit_function* func, int numargs, gcc_jit_rvalue** args)

Given a function and the given table of argument rvalues, construct a call to the function, with the result as an rvalue.

Note

gccjit::context::new_call() merely builds a gccjit::rvalue i.e. an expression that can be evaluated, perhaps as part of a more complicated expression. The call won’t happen unless you add a statement to a function that evaluates the expression.

For example, if you want to call a function and discard the result (or to call a function with void return type), use gccjit::block::add_eval():

/* Add "(void)printf (arg0, arg1);".  */
block.add_eval (ctxt.new_call (printf_func, arg0, arg1));

Type-coercion

gccjit::rvalue gccjit::context::new_cast(gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)

Given an rvalue of T, construct another rvalue of another type.

Currently only a limited set of conversions are possible:

  • int <-> float
  • int <-> bool
  • P* <-> Q*, for pointer types P and Q

Lvalues

class gccjit::lvalue

An lvalue is something that can of the left-hand side of an assignment: a storage area (such as a variable). It is a subclass of gccjit::rvalue, where the rvalue is computed by reading from the storage area.

It iss a thin wrapper around gcc_jit_lvalue * from the C API.

gccjit::rvalue gccjit::lvalue::get_address(gccjit::location loc)

Take the address of an lvalue; analogous to:

&(EXPR)

in C.

Parameter “loc” is optional.

Global variables

gccjit::lvalue gccjit::context::new_global(enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc)

Add a new global variable of the given type and name to the context.

This is a thin wrapper around gcc_jit_context_new_global() from the C API; the “kind” parameter has the same meaning as there.

Working with pointers, structs and unions

gccjit::lvalue gccjit::rvalue::dereference(gccjit::location loc)

Given an rvalue of pointer type T *, dereferencing the pointer, getting an lvalue of type T. Analogous to:

*(EXPR)

in C.

Parameter “loc” is optional.

If you don’t need to specify the location, this can also be expressed using an overloaded operator:

gccjit::lvalue gccjit::rvalue::operator* ();
gccjit::lvalue content = *ptr;

Field access is provided separately for both lvalues and rvalues:

gccjit::lvalue gccjit::lvalue::access_field(gccjit::field field, gccjit::location loc)

Given an lvalue of struct or union type, access the given field, getting an lvalue of the field’s type. Analogous to:

(EXPR).field = ...;

in C.

gccjit::rvalue gccjit::rvalue::access_field(gccjit::field field, gccjit::location loc)

Given an rvalue of struct or union type, access the given field as an rvalue. Analogous to:

(EXPR).field

in C.

gccjit::lvalue gccjit::rvalue::dereference_field(gccjit::field field, gccjit::location loc)

Given an rvalue of pointer type T * where T is of struct or union type, access the given field as an lvalue. Analogous to:

(EXPR)->field

in C, itself equivalent to (*EXPR).FIELD.

gccjit::lvalue gccjit::context::new_array_access(gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)

Given an rvalue of pointer type T *, get at the element T at the given index, using standard C array indexing rules i.e. each increment of index corresponds to sizeof(T) bytes. Analogous to:

PTR[INDEX]

in C (or, indeed, to PTR + INDEX).

Parameter “loc” is optional.

For array accesses where you don’t need to specify a gccjit::location, two overloaded operators are available:

gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)

gccjit::lvalue element = array[idx];

gccjit::lvalue gccjit::rvalue::operator[] (int index)

gccjit::lvalue element = array[0];