expressions.rst revision 1.3
1.. Copyright (C) 2014-2017 Free Software Foundation, Inc.
2   Originally contributed by David Malcolm <dmalcolm@redhat.com>
3
4   This is free software: you can redistribute it and/or modify it
5   under the terms of the GNU General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see
16   <http://www.gnu.org/licenses/>.
17
18.. default-domain:: cpp
19
20Expressions
21===========
22
23Rvalues
24-------
25.. class:: gccjit::rvalue
26
27A :class:`gccjit::rvalue` is an expression that can be computed.  It is a
28subclass of :class:`gccjit::object`, and is a thin wrapper around
29:c:type:`gcc_jit_rvalue *` from the C API.
30
31It can be simple, e.g.:
32
33  * an integer value e.g. `0` or `42`
34  * a string literal e.g. `"Hello world"`
35  * a variable e.g. `i`.  These are also lvalues (see below).
36
37or compound e.g.:
38
39  * a unary expression e.g. `!cond`
40  * a binary expression e.g. `(a + b)`
41  * a function call e.g. `get_distance (&player_ship, &target)`
42  * etc.
43
44Every rvalue has an associated type, and the API will check to ensure
45that types match up correctly (otherwise the context will emit an error).
46
47.. function:: gccjit::type gccjit::rvalue::get_type ()
48
49  Get the type of this rvalue.
50
51
52Simple expressions
53******************
54
55.. function:: gccjit::rvalue \
56              gccjit::context::new_rvalue (gccjit::type numeric_type, \
57                                           int value) const
58
59   Given a numeric type (integer or floating point), build an rvalue for
60   the given constant :c:type:`int` value.
61
62.. function:: gccjit::rvalue \
63              gccjit::context::new_rvalue (gccjit::type numeric_type, \
64                                           long value) const
65
66   Given a numeric type (integer or floating point), build an rvalue for
67   the given constant :c:type:`long` value.
68
69.. function::  gccjit::rvalue \
70               gccjit::context::zero (gccjit::type numeric_type) const
71
72   Given a numeric type (integer or floating point), get the rvalue for
73   zero.  Essentially this is just a shortcut for:
74
75   .. code-block:: c++
76
77      ctxt.new_rvalue (numeric_type, 0)
78
79.. function::  gccjit::rvalue \
80               gccjit::context::one (gccjit::type numeric_type) const
81
82   Given a numeric type (integer or floating point), get the rvalue for
83   one.  Essentially this is just a shortcut for:
84
85   .. code-block:: c++
86
87      ctxt.new_rvalue (numeric_type, 1)
88
89.. function::  gccjit::rvalue \
90               gccjit::context::new_rvalue (gccjit::type numeric_type, \
91                                            double value) const
92
93   Given a numeric type (integer or floating point), build an rvalue for
94   the given constant :c:type:`double` value.
95
96.. function:: gccjit::rvalue \
97              gccjit::context::new_rvalue (gccjit::type pointer_type, \
98                                           void *value) const
99
100   Given a pointer type, build an rvalue for the given address.
101
102.. function:: gccjit::rvalue \
103              gccjit::context::new_rvalue (const std::string &value) const
104
105   Generate an rvalue of type :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` for
106   the given string.  This is akin to a string literal.
107
108
109Unary Operations
110****************
111
112.. function:: gccjit::rvalue  \
113              gccjit::context::new_unary_op (enum gcc_jit_unary_op, \
114                                             gccjit::type result_type, \
115                                             gccjit::rvalue rvalue, \
116                                             gccjit::location loc)
117
118   Build a unary operation out of an input rvalue.
119
120   Parameter ``loc`` is optional.
121
122   This is a thin wrapper around the C API's
123   :c:func:`gcc_jit_context_new_unary_op` and the available unary
124   operations are documented there.
125
126There are shorter ways to spell the various specific kinds of unary
127operation:
128
129.. function:: gccjit::rvalue \
130              gccjit::context::new_minus (gccjit::type result_type, \
131                                          gccjit::rvalue a, \
132                                          gccjit::location loc)
133
134   Negate an arithmetic value; for example:
135
136   .. code-block:: c++
137
138      gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);
139
140   builds the equivalent of this C expression:
141
142   .. code-block:: c
143
144      -pi
145
146.. function:: gccjit::rvalue \
147              new_bitwise_negate (gccjit::type result_type, \
148                                  gccjit::rvalue a, \
149                                  gccjit::location loc)
150
151   Bitwise negation of an integer value (one's complement); for example:
152
153   .. code-block:: c++
154
155      gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);
156
157   builds the equivalent of this C expression:
158
159   .. code-block:: c
160
161      ~a
162
163.. function:: gccjit::rvalue \
164              new_logical_negate (gccjit::type result_type, \
165                                  gccjit::rvalue a, \
166                                  gccjit::location loc)
167
168   Logical negation of an arithmetic or pointer value; for example:
169
170   .. code-block:: c++
171
172      gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);
173
174   builds the equivalent of this C expression:
175
176   .. code-block:: c
177
178      !cond
179
180
181The most concise way to spell them is with overloaded operators:
182
183.. function:: gccjit::rvalue operator- (gccjit::rvalue a)
184
185   .. code-block:: c++
186
187     gccjit::rvalue negpi = -pi;
188
189
190.. function:: gccjit::rvalue operator~ (gccjit::rvalue a)
191
192   .. code-block:: c++
193
194      gccjit::rvalue mask = ~a;
195
196.. function:: gccjit::rvalue operator! (gccjit::rvalue a)
197
198   .. code-block:: c++
199
200      gccjit::rvalue guard = !cond;
201
202
203Binary Operations
204*****************
205
206.. function:: gccjit::rvalue\
207              gccjit::context::new_binary_op (enum gcc_jit_binary_op, \
208                                              gccjit::type result_type, \
209                                              gccjit::rvalue a, \
210                                              gccjit::rvalue b, \
211                                              gccjit::location loc)
212
213   Build a binary operation out of two constituent rvalues.
214
215   Parameter ``loc`` is optional.
216
217   This is a thin wrapper around the C API's
218   :c:func:`gcc_jit_context_new_binary_op` and the available binary
219   operations are documented there.
220
221There are shorter ways to spell the various specific kinds of binary
222operation:
223
224.. function:: gccjit::rvalue \
225              gccjit::context::new_plus (gccjit::type result_type, \
226                                         gccjit::rvalue a, gccjit::rvalue b, \
227                                         gccjit::location loc)
228
229.. function:: gccjit::rvalue \
230              gccjit::context::new_minus (gccjit::type result_type, \
231                                          gccjit::rvalue a, gccjit::rvalue b, \
232                                          gccjit::location loc)
233
234.. function:: gccjit::rvalue \
235              gccjit::context::new_mult (gccjit::type result_type, \
236                                         gccjit::rvalue a, gccjit::rvalue b, \
237                                         gccjit::location loc)
238
239.. function:: gccjit::rvalue \
240              gccjit::context::new_divide (gccjit::type result_type, \
241                                           gccjit::rvalue a, gccjit::rvalue b, \
242                                           gccjit::location loc)
243
244.. function:: gccjit::rvalue \
245              gccjit::context::new_modulo (gccjit::type result_type, \
246                                           gccjit::rvalue a, gccjit::rvalue b, \
247                                           gccjit::location loc)
248
249.. function:: gccjit::rvalue \
250              gccjit::context::new_bitwise_and (gccjit::type result_type, \
251                                                gccjit::rvalue a, gccjit::rvalue b, \
252                                                gccjit::location loc)
253
254.. function:: gccjit::rvalue \
255              gccjit::context::new_bitwise_xor (gccjit::type result_type, \
256                                                gccjit::rvalue a, gccjit::rvalue b, \
257                                                gccjit::location loc)
258
259.. function:: gccjit::rvalue \
260              gccjit::context::new_bitwise_or (gccjit::type result_type, \
261                                               gccjit::rvalue a, gccjit::rvalue b, \
262                                               gccjit::location loc)
263
264.. function:: gccjit::rvalue \
265              gccjit::context::new_logical_and (gccjit::type result_type, \
266                                                gccjit::rvalue a, gccjit::rvalue b, \
267                                                gccjit::location loc)
268
269.. function:: gccjit::rvalue \
270              gccjit::context::new_logical_or (gccjit::type result_type, \
271                                               gccjit::rvalue a, gccjit::rvalue b, \
272                                               gccjit::location loc)
273
274The most concise way to spell them is with overloaded operators:
275
276.. function:: gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b)
277
278   .. code-block:: c++
279
280      gccjit::rvalue sum = a + b;
281
282.. function:: gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b)
283
284   .. code-block:: c++
285
286      gccjit::rvalue diff = a - b;
287
288.. function:: gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b)
289
290   .. code-block:: c++
291
292      gccjit::rvalue prod = a * b;
293
294.. function:: gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b)
295
296   .. code-block:: c++
297
298      gccjit::rvalue result = a / b;
299
300.. function:: gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b)
301
302   .. code-block:: c++
303
304      gccjit::rvalue mod = a % b;
305
306.. function:: gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b)
307
308   .. code-block:: c++
309
310      gccjit::rvalue x = a & b;
311
312.. function:: gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b)
313
314   .. code-block:: c++
315
316      gccjit::rvalue x = a ^ b;
317
318.. function:: gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b)
319
320   .. code-block:: c++
321
322      gccjit::rvalue x = a | b;
323
324.. function:: gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b)
325
326   .. code-block:: c++
327
328      gccjit::rvalue cond = a && b;
329
330.. function:: gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b)
331
332   .. code-block:: c++
333
334      gccjit::rvalue cond = a || b;
335
336These can of course be combined, giving a terse way to build compound
337expressions:
338
339   .. code-block:: c++
340
341      gccjit::rvalue discriminant = (b * b) - (four * a * c);
342
343
344Comparisons
345***********
346
347.. function:: gccjit::rvalue \
348              gccjit::context::new_comparison (enum gcc_jit_comparison,\
349                                               gccjit::rvalue a, \
350                                               gccjit::rvalue b, \
351                                               gccjit::location loc)
352
353   Build a boolean rvalue out of the comparison of two other rvalues.
354
355   Parameter ``loc`` is optional.
356
357   This is a thin wrapper around the C API's
358   :c:func:`gcc_jit_context_new_comparison` and the available kinds
359   of comparison are documented there.
360
361There are shorter ways to spell the various specific kinds of binary
362operation:
363
364.. function:: gccjit::rvalue \
365              gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, \
366                                       gccjit::location loc)
367
368.. function:: gccjit::rvalue \
369              gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, \
370                                       gccjit::location loc)
371
372.. function:: gccjit::rvalue \
373              gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, \
374                                       gccjit::location loc)
375
376.. function:: gccjit::rvalue \
377              gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, \
378                                       gccjit::location loc)
379
380.. function:: gccjit::rvalue \
381              gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, \
382                                       gccjit::location loc)
383
384.. function:: gccjit::rvalue \
385              gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, \
386                                       gccjit::location loc)
387
388The most concise way to spell them is with overloaded operators:
389
390.. function:: gccjit::rvalue \
391              operator== (gccjit::rvalue a, gccjit::rvalue b)
392
393   .. code-block:: c++
394
395      gccjit::rvalue cond = (a == ctxt.zero (t_int));
396
397.. function:: gccjit::rvalue \
398              operator!= (gccjit::rvalue a, gccjit::rvalue b)
399
400   .. code-block:: c++
401
402      gccjit::rvalue cond = (i != j);
403
404.. function:: gccjit::rvalue \
405              operator< (gccjit::rvalue a, gccjit::rvalue b)
406
407   .. code-block:: c++
408
409      gccjit::rvalue cond = i < n;
410
411.. function:: gccjit::rvalue \
412              operator<= (gccjit::rvalue a, gccjit::rvalue b)
413
414   .. code-block:: c++
415
416      gccjit::rvalue cond = i <= n;
417
418.. function:: gccjit::rvalue \
419              operator> (gccjit::rvalue a, gccjit::rvalue b)
420
421   .. code-block:: c++
422
423      gccjit::rvalue cond = (ch > limit);
424
425.. function:: gccjit::rvalue \
426              operator>= (gccjit::rvalue a, gccjit::rvalue b)
427
428   .. code-block:: c++
429
430      gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
431
432.. TODO: beyond this point
433
434Function calls
435**************
436.. function:: gcc_jit_rvalue *\
437              gcc_jit_context_new_call (gcc_jit_context *ctxt,\
438                                        gcc_jit_location *loc,\
439                                        gcc_jit_function *func,\
440                                        int numargs , gcc_jit_rvalue **args)
441
442   Given a function and the given table of argument rvalues, construct a
443   call to the function, with the result as an rvalue.
444
445   .. note::
446
447      :func:`gccjit::context::new_call` merely builds a
448      :class:`gccjit::rvalue` i.e. an expression that can be evaluated,
449      perhaps as part of a more complicated expression.
450      The call *won't* happen unless you add a statement to a function
451      that evaluates the expression.
452
453      For example, if you want to call a function and discard the result
454      (or to call a function with ``void`` return type), use
455      :func:`gccjit::block::add_eval`:
456
457      .. code-block:: c++
458
459         /* Add "(void)printf (arg0, arg1);".  */
460         block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
461
462Type-coercion
463*************
464
465.. function:: gccjit::rvalue \
466              gccjit::context::new_cast (gccjit::rvalue rvalue,\
467                                         gccjit::type type, \
468                                         gccjit::location loc)
469
470   Given an rvalue of T, construct another rvalue of another type.
471
472   Currently only a limited set of conversions are possible:
473
474     * int <-> float
475     * int <-> bool
476     * P*  <-> Q*, for pointer types P and Q
477
478Lvalues
479-------
480
481.. class:: gccjit::lvalue
482
483An lvalue is something that can of the *left*-hand side of an assignment:
484a storage area (such as a variable).  It is a subclass of
485:class:`gccjit::rvalue`, where the rvalue is computed by reading from the
486storage area.
487
488It iss a thin wrapper around :c:type:`gcc_jit_lvalue *` from the C API.
489
490.. function:: gccjit::rvalue \
491              gccjit::lvalue::get_address (gccjit::location loc)
492
493   Take the address of an lvalue; analogous to:
494
495   .. code-block:: c
496
497     &(EXPR)
498
499   in C.
500
501   Parameter "loc" is optional.
502
503Global variables
504****************
505
506.. function:: gccjit::lvalue \
507              gccjit::context::new_global (enum gcc_jit_global_kind,\
508                                           gccjit::type type, \
509                                           const char *name, \
510                                           gccjit::location loc)
511
512   Add a new global variable of the given type and name to the context.
513
514   This is a thin wrapper around :c:func:`gcc_jit_context_new_global` from
515   the C API; the "kind" parameter has the same meaning as there.
516
517Working with pointers, structs and unions
518-----------------------------------------
519
520.. function:: gccjit::lvalue \
521              gccjit::rvalue::dereference (gccjit::location loc)
522
523   Given an rvalue of pointer type ``T *``, dereferencing the pointer,
524   getting an lvalue of type ``T``.  Analogous to:
525
526   .. code-block:: c++
527
528     *(EXPR)
529
530   in C.
531
532   Parameter "loc" is optional.
533
534If you don't need to specify the location, this can also be expressed using
535an overloaded operator:
536
537.. function:: gccjit::lvalue \
538              gccjit::rvalue::operator* ()
539
540   .. code-block:: c++
541
542      gccjit::lvalue content = *ptr;
543
544Field access is provided separately for both lvalues and rvalues:
545
546.. function:: gccjit::lvalue \
547              gccjit::lvalue::access_field (gccjit::field field, \
548                                            gccjit::location loc)
549
550   Given an lvalue of struct or union type, access the given field,
551   getting an lvalue of the field's type.  Analogous to:
552
553   .. code-block:: c++
554
555      (EXPR).field = ...;
556
557   in C.
558
559.. function:: gccjit::rvalue \
560              gccjit::rvalue::access_field (gccjit::field field, \
561                                            gccjit::location loc)
562
563   Given an rvalue of struct or union type, access the given field
564   as an rvalue.  Analogous to:
565
566   .. code-block:: c++
567
568      (EXPR).field
569
570   in C.
571
572.. function:: gccjit::lvalue \
573              gccjit::rvalue::dereference_field (gccjit::field field, \
574                                                 gccjit::location loc)
575
576   Given an rvalue of pointer type ``T *`` where T is of struct or union
577   type, access the given field as an lvalue.  Analogous to:
578
579   .. code-block:: c++
580
581      (EXPR)->field
582
583   in C, itself equivalent to ``(*EXPR).FIELD``.
584
585.. function:: gccjit::lvalue \
586              gccjit::context::new_array_access (gccjit::rvalue ptr, \
587                                                 gccjit::rvalue index, \
588                                                 gccjit::location loc)
589
590   Given an rvalue of pointer type ``T *``, get at the element `T` at
591   the given index, using standard C array indexing rules i.e. each
592   increment of ``index`` corresponds to ``sizeof(T)`` bytes.
593   Analogous to:
594
595   .. code-block:: c++
596
597      PTR[INDEX]
598
599   in C (or, indeed, to ``PTR + INDEX``).
600
601   Parameter "loc" is optional.
602
603For array accesses where you don't need to specify a :class:`gccjit::location`,
604two overloaded operators are available:
605
606    gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)
607
608    .. code-block:: c++
609
610       gccjit::lvalue element = array[idx];
611
612    gccjit::lvalue gccjit::rvalue::operator[] (int index)
613
614    .. code-block:: c++
615
616       gccjit::lvalue element = array[0];
617