1.. Copyright (C) 2014-2020 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
108Vector expressions
109******************
110
111.. function:: gccjit::rvalue \
112	      gccjit::context::new_rvalue (gccjit::type vector_type, \
113	                                   std::vector<gccjit::rvalue> elements) const
114
115   Given a vector type, and a vector of scalar rvalue elements, generate a
116   vector rvalue.
117
118   The number of elements needs to match that of the vector type.
119
120Unary Operations
121****************
122
123.. function:: gccjit::rvalue  \
124              gccjit::context::new_unary_op (enum gcc_jit_unary_op, \
125                                             gccjit::type result_type, \
126                                             gccjit::rvalue rvalue, \
127                                             gccjit::location loc)
128
129   Build a unary operation out of an input rvalue.
130
131   Parameter ``loc`` is optional.
132
133   This is a thin wrapper around the C API's
134   :c:func:`gcc_jit_context_new_unary_op` and the available unary
135   operations are documented there.
136
137There are shorter ways to spell the various specific kinds of unary
138operation:
139
140.. function:: gccjit::rvalue \
141              gccjit::context::new_minus (gccjit::type result_type, \
142                                          gccjit::rvalue a, \
143                                          gccjit::location loc)
144
145   Negate an arithmetic value; for example:
146
147   .. code-block:: c++
148
149      gccjit::rvalue negpi = ctxt.new_minus (t_double, pi);
150
151   builds the equivalent of this C expression:
152
153   .. code-block:: c
154
155      -pi
156
157.. function:: gccjit::rvalue \
158              new_bitwise_negate (gccjit::type result_type, \
159                                  gccjit::rvalue a, \
160                                  gccjit::location loc)
161
162   Bitwise negation of an integer value (one's complement); for example:
163
164   .. code-block:: c++
165
166      gccjit::rvalue mask = ctxt.new_bitwise_negate (t_int, a);
167
168   builds the equivalent of this C expression:
169
170   .. code-block:: c
171
172      ~a
173
174.. function:: gccjit::rvalue \
175              new_logical_negate (gccjit::type result_type, \
176                                  gccjit::rvalue a, \
177                                  gccjit::location loc)
178
179   Logical negation of an arithmetic or pointer value; for example:
180
181   .. code-block:: c++
182
183      gccjit::rvalue guard = ctxt.new_logical_negate (t_bool, cond);
184
185   builds the equivalent of this C expression:
186
187   .. code-block:: c
188
189      !cond
190
191
192The most concise way to spell them is with overloaded operators:
193
194.. function:: gccjit::rvalue operator- (gccjit::rvalue a)
195
196   .. code-block:: c++
197
198     gccjit::rvalue negpi = -pi;
199
200
201.. function:: gccjit::rvalue operator~ (gccjit::rvalue a)
202
203   .. code-block:: c++
204
205      gccjit::rvalue mask = ~a;
206
207.. function:: gccjit::rvalue operator! (gccjit::rvalue a)
208
209   .. code-block:: c++
210
211      gccjit::rvalue guard = !cond;
212
213
214Binary Operations
215*****************
216
217.. function:: gccjit::rvalue\
218              gccjit::context::new_binary_op (enum gcc_jit_binary_op, \
219                                              gccjit::type result_type, \
220                                              gccjit::rvalue a, \
221                                              gccjit::rvalue b, \
222                                              gccjit::location loc)
223
224   Build a binary operation out of two constituent rvalues.
225
226   Parameter ``loc`` is optional.
227
228   This is a thin wrapper around the C API's
229   :c:func:`gcc_jit_context_new_binary_op` and the available binary
230   operations are documented there.
231
232There are shorter ways to spell the various specific kinds of binary
233operation:
234
235.. function:: gccjit::rvalue \
236              gccjit::context::new_plus (gccjit::type result_type, \
237                                         gccjit::rvalue a, gccjit::rvalue b, \
238                                         gccjit::location loc)
239
240.. function:: gccjit::rvalue \
241              gccjit::context::new_minus (gccjit::type result_type, \
242                                          gccjit::rvalue a, gccjit::rvalue b, \
243                                          gccjit::location loc)
244
245.. function:: gccjit::rvalue \
246              gccjit::context::new_mult (gccjit::type result_type, \
247                                         gccjit::rvalue a, gccjit::rvalue b, \
248                                         gccjit::location loc)
249
250.. function:: gccjit::rvalue \
251              gccjit::context::new_divide (gccjit::type result_type, \
252                                           gccjit::rvalue a, gccjit::rvalue b, \
253                                           gccjit::location loc)
254
255.. function:: gccjit::rvalue \
256              gccjit::context::new_modulo (gccjit::type result_type, \
257                                           gccjit::rvalue a, gccjit::rvalue b, \
258                                           gccjit::location loc)
259
260.. function:: gccjit::rvalue \
261              gccjit::context::new_bitwise_and (gccjit::type result_type, \
262                                                gccjit::rvalue a, gccjit::rvalue b, \
263                                                gccjit::location loc)
264
265.. function:: gccjit::rvalue \
266              gccjit::context::new_bitwise_xor (gccjit::type result_type, \
267                                                gccjit::rvalue a, gccjit::rvalue b, \
268                                                gccjit::location loc)
269
270.. function:: gccjit::rvalue \
271              gccjit::context::new_bitwise_or (gccjit::type result_type, \
272                                               gccjit::rvalue a, gccjit::rvalue b, \
273                                               gccjit::location loc)
274
275.. function:: gccjit::rvalue \
276              gccjit::context::new_logical_and (gccjit::type result_type, \
277                                                gccjit::rvalue a, gccjit::rvalue b, \
278                                                gccjit::location loc)
279
280.. function:: gccjit::rvalue \
281              gccjit::context::new_logical_or (gccjit::type result_type, \
282                                               gccjit::rvalue a, gccjit::rvalue b, \
283                                               gccjit::location loc)
284
285The most concise way to spell them is with overloaded operators:
286
287.. function:: gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b)
288
289   .. code-block:: c++
290
291      gccjit::rvalue sum = a + b;
292
293.. function:: gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b)
294
295   .. code-block:: c++
296
297      gccjit::rvalue diff = a - b;
298
299.. function:: gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b)
300
301   .. code-block:: c++
302
303      gccjit::rvalue prod = a * b;
304
305.. function:: gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b)
306
307   .. code-block:: c++
308
309      gccjit::rvalue result = a / b;
310
311.. function:: gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b)
312
313   .. code-block:: c++
314
315      gccjit::rvalue mod = a % b;
316
317.. function:: gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b)
318
319   .. code-block:: c++
320
321      gccjit::rvalue x = a & b;
322
323.. function:: gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b)
324
325   .. code-block:: c++
326
327      gccjit::rvalue x = a ^ b;
328
329.. function:: gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b)
330
331   .. code-block:: c++
332
333      gccjit::rvalue x = a | b;
334
335.. function:: gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b)
336
337   .. code-block:: c++
338
339      gccjit::rvalue cond = a && b;
340
341.. function:: gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b)
342
343   .. code-block:: c++
344
345      gccjit::rvalue cond = a || b;
346
347These can of course be combined, giving a terse way to build compound
348expressions:
349
350   .. code-block:: c++
351
352      gccjit::rvalue discriminant = (b * b) - (four * a * c);
353
354
355Comparisons
356***********
357
358.. function:: gccjit::rvalue \
359              gccjit::context::new_comparison (enum gcc_jit_comparison,\
360                                               gccjit::rvalue a, \
361                                               gccjit::rvalue b, \
362                                               gccjit::location loc)
363
364   Build a boolean rvalue out of the comparison of two other rvalues.
365
366   Parameter ``loc`` is optional.
367
368   This is a thin wrapper around the C API's
369   :c:func:`gcc_jit_context_new_comparison` and the available kinds
370   of comparison are documented there.
371
372There are shorter ways to spell the various specific kinds of binary
373operation:
374
375.. function:: gccjit::rvalue \
376              gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, \
377                                       gccjit::location loc)
378
379.. function:: gccjit::rvalue \
380              gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, \
381                                       gccjit::location loc)
382
383.. function:: gccjit::rvalue \
384              gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, \
385                                       gccjit::location loc)
386
387.. function:: gccjit::rvalue \
388              gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, \
389                                       gccjit::location loc)
390
391.. function:: gccjit::rvalue \
392              gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, \
393                                       gccjit::location loc)
394
395.. function:: gccjit::rvalue \
396              gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, \
397                                       gccjit::location loc)
398
399The most concise way to spell them is with overloaded operators:
400
401.. function:: gccjit::rvalue \
402              operator== (gccjit::rvalue a, gccjit::rvalue b)
403
404   .. code-block:: c++
405
406      gccjit::rvalue cond = (a == ctxt.zero (t_int));
407
408.. function:: gccjit::rvalue \
409              operator!= (gccjit::rvalue a, gccjit::rvalue b)
410
411   .. code-block:: c++
412
413      gccjit::rvalue cond = (i != j);
414
415.. function:: gccjit::rvalue \
416              operator< (gccjit::rvalue a, gccjit::rvalue b)
417
418   .. code-block:: c++
419
420      gccjit::rvalue cond = i < n;
421
422.. function:: gccjit::rvalue \
423              operator<= (gccjit::rvalue a, gccjit::rvalue b)
424
425   .. code-block:: c++
426
427      gccjit::rvalue cond = i <= n;
428
429.. function:: gccjit::rvalue \
430              operator> (gccjit::rvalue a, gccjit::rvalue b)
431
432   .. code-block:: c++
433
434      gccjit::rvalue cond = (ch > limit);
435
436.. function:: gccjit::rvalue \
437              operator>= (gccjit::rvalue a, gccjit::rvalue b)
438
439   .. code-block:: c++
440
441      gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
442
443.. TODO: beyond this point
444
445Function calls
446**************
447.. function:: gcc_jit_rvalue *\
448              gcc_jit_context_new_call (gcc_jit_context *ctxt,\
449                                        gcc_jit_location *loc,\
450                                        gcc_jit_function *func,\
451                                        int numargs , gcc_jit_rvalue **args)
452
453   Given a function and the given table of argument rvalues, construct a
454   call to the function, with the result as an rvalue.
455
456   .. note::
457
458      :func:`gccjit::context::new_call` merely builds a
459      :class:`gccjit::rvalue` i.e. an expression that can be evaluated,
460      perhaps as part of a more complicated expression.
461      The call *won't* happen unless you add a statement to a function
462      that evaluates the expression.
463
464      For example, if you want to call a function and discard the result
465      (or to call a function with ``void`` return type), use
466      :func:`gccjit::block::add_eval`:
467
468      .. code-block:: c++
469
470         /* Add "(void)printf (arg0, arg1);".  */
471         block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
472
473Function pointers
474*****************
475
476.. function:: gccjit::rvalue \
477	      gccjit::function::get_address (gccjit::location loc)
478
479   Get the address of a function as an rvalue, of function pointer
480   type.
481
482Type-coercion
483*************
484
485.. function:: gccjit::rvalue \
486              gccjit::context::new_cast (gccjit::rvalue rvalue,\
487                                         gccjit::type type, \
488                                         gccjit::location loc)
489
490   Given an rvalue of T, construct another rvalue of another type.
491
492   Currently only a limited set of conversions are possible:
493
494     * int <-> float
495     * int <-> bool
496     * P*  <-> Q*, for pointer types P and Q
497
498Lvalues
499-------
500
501.. class:: gccjit::lvalue
502
503An lvalue is something that can of the *left*-hand side of an assignment:
504a storage area (such as a variable).  It is a subclass of
505:class:`gccjit::rvalue`, where the rvalue is computed by reading from the
506storage area.
507
508It iss a thin wrapper around :c:type:`gcc_jit_lvalue *` from the C API.
509
510.. function:: gccjit::rvalue \
511              gccjit::lvalue::get_address (gccjit::location loc)
512
513   Take the address of an lvalue; analogous to:
514
515   .. code-block:: c
516
517     &(EXPR)
518
519   in C.
520
521   Parameter "loc" is optional.
522
523Global variables
524****************
525
526.. function:: gccjit::lvalue \
527              gccjit::context::new_global (enum gcc_jit_global_kind,\
528                                           gccjit::type type, \
529                                           const char *name, \
530                                           gccjit::location loc)
531
532   Add a new global variable of the given type and name to the context.
533
534   This is a thin wrapper around :c:func:`gcc_jit_context_new_global` from
535   the C API; the "kind" parameter has the same meaning as there.
536
537Working with pointers, structs and unions
538-----------------------------------------
539
540.. function:: gccjit::lvalue \
541              gccjit::rvalue::dereference (gccjit::location loc)
542
543   Given an rvalue of pointer type ``T *``, dereferencing the pointer,
544   getting an lvalue of type ``T``.  Analogous to:
545
546   .. code-block:: c++
547
548     *(EXPR)
549
550   in C.
551
552   Parameter "loc" is optional.
553
554If you don't need to specify the location, this can also be expressed using
555an overloaded operator:
556
557.. function:: gccjit::lvalue \
558              gccjit::rvalue::operator* ()
559
560   .. code-block:: c++
561
562      gccjit::lvalue content = *ptr;
563
564Field access is provided separately for both lvalues and rvalues:
565
566.. function:: gccjit::lvalue \
567              gccjit::lvalue::access_field (gccjit::field field, \
568                                            gccjit::location loc)
569
570   Given an lvalue of struct or union type, access the given field,
571   getting an lvalue of the field's type.  Analogous to:
572
573   .. code-block:: c++
574
575      (EXPR).field = ...;
576
577   in C.
578
579.. function:: gccjit::rvalue \
580              gccjit::rvalue::access_field (gccjit::field field, \
581                                            gccjit::location loc)
582
583   Given an rvalue of struct or union type, access the given field
584   as an rvalue.  Analogous to:
585
586   .. code-block:: c++
587
588      (EXPR).field
589
590   in C.
591
592.. function:: gccjit::lvalue \
593              gccjit::rvalue::dereference_field (gccjit::field field, \
594                                                 gccjit::location loc)
595
596   Given an rvalue of pointer type ``T *`` where T is of struct or union
597   type, access the given field as an lvalue.  Analogous to:
598
599   .. code-block:: c++
600
601      (EXPR)->field
602
603   in C, itself equivalent to ``(*EXPR).FIELD``.
604
605.. function:: gccjit::lvalue \
606              gccjit::context::new_array_access (gccjit::rvalue ptr, \
607                                                 gccjit::rvalue index, \
608                                                 gccjit::location loc)
609
610   Given an rvalue of pointer type ``T *``, get at the element `T` at
611   the given index, using standard C array indexing rules i.e. each
612   increment of ``index`` corresponds to ``sizeof(T)`` bytes.
613   Analogous to:
614
615   .. code-block:: c++
616
617      PTR[INDEX]
618
619   in C (or, indeed, to ``PTR + INDEX``).
620
621   Parameter "loc" is optional.
622
623For array accesses where you don't need to specify a :class:`gccjit::location`,
624two overloaded operators are available:
625
626    gccjit::lvalue gccjit::rvalue::operator[] (gccjit::rvalue index)
627
628    .. code-block:: c++
629
630       gccjit::lvalue element = array[idx];
631
632    gccjit::lvalue gccjit::rvalue::operator[] (int index)
633
634    .. code-block:: c++
635
636       gccjit::lvalue element = array[0];
637