A gccjit::rvalue is an expression that can be computed. It is a subclass of gccjit::object, and is a thin wrapper around :c:type:`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).
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)
Given a numeric type (integer or floating point), get the rvalue for one. Essentially this is just a shortcut for:
ctxt.new_rvalue (numeric_type, 1)
Build a unary operation out of an input rvalue.
Parameter loc is optional.
This is a thin wrapper around the C API’s :c:func:`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:
Negate an arithmetic value; for example:
gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);
builds the equivalent of this C expression:
-pi
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
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 negpi = -pi;
gccjit::rvalue mask = ~a;
gccjit::rvalue guard = !cond;
Build a binary operation out of two constituent rvalues.
Parameter loc is optional.
This is a thin wrapper around the C API’s :c:func:`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:
The most concise way to spell them is with overloaded operators:
gccjit::rvalue sum = a + b;
gccjit::rvalue diff = a - b;
gccjit::rvalue prod = a * b;
gccjit::rvalue result = a / b;
gccjit::rvalue mod = a % b;
gccjit::rvalue x = a & b;
gccjit::rvalue x = a ^ b;
gccjit::rvalue x = a | b;
gccjit::rvalue cond = a && 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);
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 :c:func:`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:
The most concise way to spell them is with overloaded operators:
gccjit::rvalue cond = (a == ctxt.zero (t_int));
gccjit::rvalue cond = (i != j);
gccjit::rvalue cond = i < n;
gccjit::rvalue cond = i <= n;
gccjit::rvalue cond = (ch > limit);
gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
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));
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
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 :c:type:`gcc_jit_lvalue *` from the C API.
Take the address of an lvalue; analogous to:
&(EXPR)
in C.
Parameter “loc” is optional.
Add a new global variable of the given type and name to the context.
This is a thin wrapper around :c:func:`gcc_jit_context_new_global` from the C API; the “kind” parameter has the same meaning as there.
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 content = *ptr;
Field access is provided separately for both lvalues and rvalues:
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.
Given an rvalue of struct or union type, access the given field as an rvalue. Analogous to:
(EXPR).field
in C.
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.
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];