expressions.rst revision 1.6
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