1 /* A C++ API for libgccjit, purely as inline wrapper functions. 2 Copyright (C) 2014-2017 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GCC is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #ifndef LIBGCCJIT_PLUS_PLUS_H 21 #define LIBGCCJIT_PLUS_PLUS_H 22 23 #include "libgccjit.h" 24 25 #include <limits> 26 #include <ostream> 27 #include <vector> 28 29 /**************************************************************************** 30 C++ API 31 ****************************************************************************/ 32 33 namespace gccjit 34 { 35 /* Indentation indicates inheritance. */ 36 class context; 37 class error; 38 class object; 39 class location; 40 class field; 41 class type; 42 class struct_; 43 class function; 44 class block; 45 class rvalue; 46 class lvalue; 47 class param; 48 class case_; 49 class timer; 50 class auto_time; 51 52 /* Errors within the API become C++ exceptions of this class. */ 53 class error 54 { 55 }; 56 57 class object 58 { 59 public: 60 context get_context () const; 61 62 std::string get_debug_string () const; 63 64 protected: 65 object (); 66 object (gcc_jit_object *obj); 67 68 gcc_jit_object *get_inner_object () const; 69 70 private: 71 gcc_jit_object *m_inner_obj; 72 }; 73 74 inline std::ostream& operator << (std::ostream& stream, const object &obj); 75 76 /* Some client code will want to supply source code locations, others 77 won't. To avoid doubling the number of entrypoints, everything 78 accepting a location also has a default argument. To do this, the 79 other classes need to see that "location" has a default constructor, 80 hence we need to declare it first. */ 81 class location : public object 82 { 83 public: 84 location (); 85 location (gcc_jit_location *loc); 86 87 gcc_jit_location *get_inner_location () const; 88 }; 89 90 class context 91 { 92 public: 93 static context acquire (); 94 context (); 95 context (gcc_jit_context *ctxt); 96 97 gccjit::context new_child_context (); 98 99 gcc_jit_context *get_inner_context () { return m_inner_ctxt; } 100 101 void release (); 102 103 gcc_jit_result *compile (); 104 105 void compile_to_file (enum gcc_jit_output_kind output_kind, 106 const char *output_path); 107 108 void dump_to_file (const std::string &path, 109 bool update_locations); 110 111 void set_logfile (FILE *logfile, 112 int flags, 113 int verbosity); 114 115 void dump_reproducer_to_file (const char *path); 116 117 void set_str_option (enum gcc_jit_str_option opt, 118 const char *value); 119 120 void set_int_option (enum gcc_jit_int_option opt, 121 int value); 122 123 void set_bool_option (enum gcc_jit_bool_option opt, 124 int value); 125 126 void set_bool_allow_unreachable_blocks (int bool_value); 127 void set_bool_use_external_driver (int bool_value); 128 129 void add_command_line_option (const char *optname); 130 131 void set_timer (gccjit::timer t); 132 gccjit::timer get_timer () const; 133 134 location 135 new_location (const std::string &filename, 136 int line, 137 int column); 138 139 type get_type (enum gcc_jit_types kind); 140 type get_int_type (size_t num_bytes, int is_signed); 141 142 /* A way to map a specific int type, using the compiler to 143 get the details automatically e.g.: 144 gccjit::type type = get_int_type <my_int_type_t> (); */ 145 template <typename T> 146 type get_int_type (); 147 148 type new_array_type (type element_type, int num_elements, 149 location loc = location ()); 150 151 field new_field (type type_, const std::string &name, 152 location loc = location ()); 153 154 struct_ new_struct_type (const std::string &name, 155 std::vector<field> &fields, 156 location loc = location ()); 157 158 struct_ new_opaque_struct_type (const std::string &name, 159 location loc = location ()); 160 161 param new_param (type type_, 162 const std::string &name, 163 location loc = location ()); 164 165 function new_function (enum gcc_jit_function_kind kind, 166 type return_type, 167 const std::string &name, 168 std::vector<param> ¶ms, 169 int is_variadic, 170 location loc = location ()); 171 172 function get_builtin_function (const std::string &name); 173 174 lvalue new_global (enum gcc_jit_global_kind kind, 175 type type_, 176 const std::string &name, 177 location loc = location ()); 178 179 rvalue new_rvalue (type numeric_type, 180 int value) const; 181 rvalue new_rvalue (type numeric_type, 182 long value) const; 183 rvalue zero (type numeric_type) const; 184 rvalue one (type numeric_type) const; 185 rvalue new_rvalue (type numeric_type, 186 double value) const; 187 rvalue new_rvalue (type pointer_type, 188 void *value) const; 189 rvalue new_rvalue (const std::string &value) const; 190 191 /* Generic unary operations... */ 192 rvalue new_unary_op (enum gcc_jit_unary_op op, 193 type result_type, 194 rvalue a, 195 location loc = location ()); 196 197 /* ...and shorter ways to spell the various specific kinds of 198 unary op. */ 199 rvalue new_minus (type result_type, 200 rvalue a, 201 location loc = location ()); 202 rvalue new_bitwise_negate (type result_type, 203 rvalue a, 204 location loc = location ()); 205 rvalue new_logical_negate (type result_type, 206 rvalue a, 207 location loc = location ()); 208 209 /* Generic binary operations... */ 210 rvalue new_binary_op (enum gcc_jit_binary_op op, 211 type result_type, 212 rvalue a, rvalue b, 213 location loc = location ()); 214 215 /* ...and shorter ways to spell the various specific kinds of 216 binary op. */ 217 rvalue new_plus (type result_type, 218 rvalue a, rvalue b, 219 location loc = location ()); 220 rvalue new_minus (type result_type, 221 rvalue a, rvalue b, 222 location loc = location ()); 223 rvalue new_mult (type result_type, 224 rvalue a, rvalue b, 225 location loc = location ()); 226 rvalue new_divide (type result_type, 227 rvalue a, rvalue b, 228 location loc = location ()); 229 rvalue new_modulo (type result_type, 230 rvalue a, rvalue b, 231 location loc = location ()); 232 rvalue new_bitwise_and (type result_type, 233 rvalue a, rvalue b, 234 location loc = location ()); 235 rvalue new_bitwise_xor (type result_type, 236 rvalue a, rvalue b, 237 location loc = location ()); 238 rvalue new_bitwise_or (type result_type, 239 rvalue a, rvalue b, 240 location loc = location ()); 241 rvalue new_logical_and (type result_type, 242 rvalue a, rvalue b, 243 location loc = location ()); 244 rvalue new_logical_or (type result_type, 245 rvalue a, rvalue b, 246 location loc = location ()); 247 248 /* Generic comparisons... */ 249 rvalue new_comparison (enum gcc_jit_comparison op, 250 rvalue a, rvalue b, 251 location loc = location ()); 252 /* ...and shorter ways to spell the various specific kinds of 253 comparison. */ 254 rvalue new_eq (rvalue a, rvalue b, 255 location loc = location ()); 256 rvalue new_ne (rvalue a, rvalue b, 257 location loc = location ()); 258 rvalue new_lt (rvalue a, rvalue b, 259 location loc = location ()); 260 rvalue new_le (rvalue a, rvalue b, 261 location loc = location ()); 262 rvalue new_gt (rvalue a, rvalue b, 263 location loc = location ()); 264 rvalue new_ge (rvalue a, rvalue b, 265 location loc = location ()); 266 267 /* The most general way of creating a function call. */ 268 rvalue new_call (function func, 269 std::vector<rvalue> &args, 270 location loc = location ()); 271 272 /* In addition, we provide a series of overloaded "new_call" methods 273 for specific numbers of args (from 0 - 6), to avoid the need for 274 client code to manually build a vector. */ 275 rvalue new_call (function func, 276 location loc = location ()); 277 rvalue new_call (function func, 278 rvalue arg0, 279 location loc = location ()); 280 rvalue new_call (function func, 281 rvalue arg0, rvalue arg1, 282 location loc = location ()); 283 rvalue new_call (function func, 284 rvalue arg0, rvalue arg1, rvalue arg2, 285 location loc = location ()); 286 rvalue new_call (function func, 287 rvalue arg0, rvalue arg1, rvalue arg2, 288 rvalue arg3, 289 location loc = location ()); 290 rvalue new_call (function func, 291 rvalue arg0, rvalue arg1, rvalue arg2, 292 rvalue arg3, rvalue arg4, 293 location loc = location ()); 294 rvalue new_call (function func, 295 rvalue arg0, rvalue arg1, rvalue arg2, 296 rvalue arg3, rvalue arg4, rvalue arg5, 297 location loc = location ()); 298 299 rvalue new_cast (rvalue expr, 300 type type_, 301 location loc = location ()); 302 303 lvalue new_array_access (rvalue ptr, 304 rvalue index, 305 location loc = location ()); 306 307 case_ new_case (rvalue min_value, 308 rvalue max_value, 309 block dest_block); 310 311 private: 312 gcc_jit_context *m_inner_ctxt; 313 }; 314 315 class field : public object 316 { 317 public: 318 field (); 319 field (gcc_jit_field *inner); 320 321 gcc_jit_field *get_inner_field () const; 322 }; 323 324 class type : public object 325 { 326 public: 327 type (); 328 type (gcc_jit_type *inner); 329 330 gcc_jit_type *get_inner_type () const; 331 332 type get_pointer (); 333 type get_volatile (); 334 335 // Shortcuts for getting values of numeric types: 336 rvalue zero (); 337 rvalue one (); 338 }; 339 340 class struct_ : public type 341 { 342 public: 343 struct_ (); 344 struct_ (gcc_jit_struct *inner); 345 346 gcc_jit_struct *get_inner_struct () const; 347 }; 348 349 class function : public object 350 { 351 public: 352 function (); 353 function (gcc_jit_function *func); 354 355 gcc_jit_function *get_inner_function () const; 356 357 void dump_to_dot (const std::string &path); 358 359 param get_param (int index) const; 360 361 block new_block (); 362 block new_block (const std::string &name); 363 364 lvalue new_local (type type_, 365 const std::string &name, 366 location loc = location ()); 367 368 /* A series of overloaded operator () with various numbers of arguments 369 for a very terse way of creating a call to this function. The call 370 is created within the same context as the function itself, which may 371 not be what you want. */ 372 rvalue operator() (location loc = location ()); 373 rvalue operator() (rvalue arg0, 374 location loc = location ()); 375 rvalue operator() (rvalue arg0, rvalue arg1, 376 location loc = location ()); 377 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2, 378 location loc = location ()); 379 }; 380 381 class block : public object 382 { 383 public: 384 block (); 385 block (gcc_jit_block *inner); 386 387 gcc_jit_block *get_inner_block () const; 388 389 function get_function () const; 390 391 void add_eval (rvalue rvalue, 392 location loc = location ()); 393 394 void add_assignment (lvalue lvalue, 395 rvalue rvalue, 396 location loc = location ()); 397 398 void add_assignment_op (lvalue lvalue, 399 enum gcc_jit_binary_op op, 400 rvalue rvalue, 401 location loc = location ()); 402 403 /* A way to add a function call to the body of a function being 404 defined, with various numbers of args. */ 405 rvalue add_call (function other, 406 location loc = location ()); 407 rvalue add_call (function other, 408 rvalue arg0, 409 location loc = location ()); 410 rvalue add_call (function other, 411 rvalue arg0, rvalue arg1, 412 location loc = location ()); 413 rvalue add_call (function other, 414 rvalue arg0, rvalue arg1, rvalue arg2, 415 location loc = location ()); 416 rvalue add_call (function other, 417 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3, 418 location loc = location ()); 419 420 void add_comment (const std::string &text, 421 location loc = location ()); 422 423 void end_with_conditional (rvalue boolval, 424 block on_true, 425 block on_false, 426 location loc = location ()); 427 428 void end_with_jump (block target, 429 location loc = location ()); 430 431 void end_with_return (rvalue rvalue, 432 location loc = location ()); 433 void end_with_return (location loc = location ()); 434 435 void end_with_switch (rvalue expr, 436 block default_block, 437 std::vector <case_> cases, 438 location loc = location ()); 439 }; 440 441 class rvalue : public object 442 { 443 public: 444 rvalue (); 445 rvalue (gcc_jit_rvalue *inner); 446 gcc_jit_rvalue *get_inner_rvalue () const; 447 448 type get_type (); 449 450 rvalue access_field (field field, 451 location loc = location ()); 452 453 lvalue dereference_field (field field, 454 location loc = location ()); 455 456 lvalue dereference (location loc = location ()); 457 458 rvalue cast_to (type type_, 459 location loc = location ()); 460 461 /* Array access. */ 462 lvalue operator[] (rvalue index); 463 lvalue operator[] (int index); 464 }; 465 466 class lvalue : public rvalue 467 { 468 public: 469 lvalue (); 470 lvalue (gcc_jit_lvalue *inner); 471 472 gcc_jit_lvalue *get_inner_lvalue () const; 473 474 lvalue access_field (field field, 475 location loc = location ()); 476 477 rvalue get_address (location loc = location ()); 478 }; 479 480 class param : public lvalue 481 { 482 public: 483 param (); 484 param (gcc_jit_param *inner); 485 486 gcc_jit_param *get_inner_param () const; 487 }; 488 489 class case_ : public object 490 { 491 public: 492 case_ (); 493 case_ (gcc_jit_case *inner); 494 495 gcc_jit_case *get_inner_case () const; 496 }; 497 498 /* Overloaded operators, for those who want the most terse API 499 (at the possible risk of being a little too magical). 500 501 In each case, the first parameter is used to determine which context 502 owns the resulting expression, and, where appropriate, what the 503 latter's type is. */ 504 505 /* Unary operators. */ 506 rvalue operator- (rvalue a); // unary minus 507 rvalue operator~ (rvalue a); // unary bitwise negate 508 rvalue operator! (rvalue a); // unary logical negate 509 510 /* Binary operators. */ 511 rvalue operator+ (rvalue a, rvalue b); 512 rvalue operator- (rvalue a, rvalue b); 513 rvalue operator* (rvalue a, rvalue b); 514 rvalue operator/ (rvalue a, rvalue b); 515 rvalue operator% (rvalue a, rvalue b); 516 rvalue operator& (rvalue a, rvalue b); // bitwise and 517 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor 518 rvalue operator| (rvalue a, rvalue b); // bitwise_or 519 rvalue operator&& (rvalue a, rvalue b); // logical_and 520 rvalue operator|| (rvalue a, rvalue b); // logical_or 521 522 /* Comparisons. */ 523 rvalue operator== (rvalue a, rvalue b); 524 rvalue operator!= (rvalue a, rvalue b); 525 rvalue operator< (rvalue a, rvalue b); 526 rvalue operator<= (rvalue a, rvalue b); 527 rvalue operator> (rvalue a, rvalue b); 528 rvalue operator>= (rvalue a, rvalue b); 529 530 /* Dereferencing. */ 531 lvalue operator* (rvalue ptr); 532 533 class timer 534 { 535 public: 536 timer (); 537 timer (gcc_jit_timer *inner_timer); 538 539 void push (const char *item_name); 540 void pop (const char *item_name); 541 void print (FILE *f_out) const; 542 543 void release (); 544 545 gcc_jit_timer *get_inner_timer () const; 546 547 private: 548 gcc_jit_timer *m_inner_timer; 549 }; 550 551 class auto_time 552 { 553 public: 554 auto_time (timer t, const char *item_name); 555 auto_time (context ctxt, const char *item_name); 556 ~auto_time (); 557 558 private: 559 timer m_timer; 560 const char *m_item_name; 561 }; 562 } 563 564 /**************************************************************************** 565 Implementation of the API 566 ****************************************************************************/ 567 namespace gccjit { 568 569 // class context 570 inline context context::acquire () 571 { 572 return context (gcc_jit_context_acquire ()); 573 } 574 inline context::context () : m_inner_ctxt (NULL) {} 575 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner) 576 { 577 if (!inner) 578 throw error (); 579 } 580 581 inline gccjit::context 582 context::new_child_context () 583 { 584 return context (gcc_jit_context_new_child_context (m_inner_ctxt)); 585 } 586 587 inline void 588 context::release () 589 { 590 gcc_jit_context_release (m_inner_ctxt); 591 m_inner_ctxt = NULL; 592 } 593 594 inline gcc_jit_result * 595 context::compile () 596 { 597 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt); 598 if (!result) 599 throw error (); 600 return result; 601 } 602 603 inline void 604 context::compile_to_file (enum gcc_jit_output_kind output_kind, 605 const char *output_path) 606 { 607 gcc_jit_context_compile_to_file (m_inner_ctxt, 608 output_kind, 609 output_path); 610 } 611 612 inline void 613 context::dump_to_file (const std::string &path, 614 bool update_locations) 615 { 616 gcc_jit_context_dump_to_file (m_inner_ctxt, 617 path.c_str (), 618 update_locations); 619 } 620 621 inline void 622 context::set_logfile (FILE *logfile, 623 int flags, 624 int verbosity) 625 { 626 gcc_jit_context_set_logfile (m_inner_ctxt, 627 logfile, 628 flags, 629 verbosity); 630 } 631 632 inline void 633 context::dump_reproducer_to_file (const char *path) 634 { 635 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt, 636 path); 637 } 638 639 inline void 640 context::set_str_option (enum gcc_jit_str_option opt, 641 const char *value) 642 { 643 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value); 644 645 } 646 647 inline void 648 context::set_int_option (enum gcc_jit_int_option opt, 649 int value) 650 { 651 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value); 652 653 } 654 655 inline void 656 context::set_bool_option (enum gcc_jit_bool_option opt, 657 int value) 658 { 659 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value); 660 } 661 662 inline void 663 context::set_bool_allow_unreachable_blocks (int bool_value) 664 { 665 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt, 666 bool_value); 667 } 668 669 inline void 670 context::set_bool_use_external_driver (int bool_value) 671 { 672 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt, 673 bool_value); 674 } 675 676 inline void 677 context::add_command_line_option (const char *optname) 678 { 679 gcc_jit_context_add_command_line_option (m_inner_ctxt, optname); 680 } 681 682 inline void 683 context::set_timer (gccjit::timer t) 684 { 685 gcc_jit_context_set_timer (m_inner_ctxt, t.get_inner_timer ()); 686 } 687 688 inline gccjit::timer 689 context::get_timer () const 690 { 691 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt)); 692 } 693 694 695 inline location 696 context::new_location (const std::string &filename, 697 int line, 698 int column) 699 { 700 return location (gcc_jit_context_new_location (m_inner_ctxt, 701 filename.c_str (), 702 line, 703 column)); 704 } 705 706 inline type 707 context::get_type (enum gcc_jit_types kind) 708 { 709 return type (gcc_jit_context_get_type (m_inner_ctxt, kind)); 710 } 711 712 inline type 713 context::get_int_type (size_t num_bytes, int is_signed) 714 { 715 return type (gcc_jit_context_get_int_type (m_inner_ctxt, 716 num_bytes, 717 is_signed)); 718 } 719 720 template <typename T> 721 inline type 722 context::get_int_type () 723 { 724 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed); 725 } 726 727 inline type 728 context::new_array_type (type element_type, int num_elements, location loc) 729 { 730 return type (gcc_jit_context_new_array_type ( 731 m_inner_ctxt, 732 loc.get_inner_location (), 733 element_type.get_inner_type (), 734 num_elements)); 735 } 736 737 inline field 738 context::new_field (type type_, const std::string &name, location loc) 739 { 740 return field (gcc_jit_context_new_field (m_inner_ctxt, 741 loc.get_inner_location (), 742 type_.get_inner_type (), 743 name.c_str ())); 744 } 745 746 inline struct_ 747 context::new_struct_type (const std::string &name, 748 std::vector<field> &fields, 749 location loc) 750 { 751 /* Treat std::vector as an array, relying on it not being resized: */ 752 field *as_array_of_wrappers = &fields[0]; 753 754 /* Treat the array as being of the underlying pointers, relying on 755 the wrapper type being such a pointer internally. */ 756 gcc_jit_field **as_array_of_ptrs = 757 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers); 758 759 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt, 760 loc.get_inner_location (), 761 name.c_str (), 762 fields.size (), 763 as_array_of_ptrs)); 764 } 765 766 inline struct_ 767 context::new_opaque_struct_type (const std::string &name, 768 location loc) 769 { 770 return struct_ (gcc_jit_context_new_opaque_struct ( 771 m_inner_ctxt, 772 loc.get_inner_location (), 773 name.c_str ())); 774 } 775 776 inline param 777 context::new_param (type type_, 778 const std::string &name, 779 location loc) 780 { 781 return param (gcc_jit_context_new_param (m_inner_ctxt, 782 loc.get_inner_location (), 783 type_.get_inner_type (), 784 name.c_str ())); 785 } 786 787 inline function 788 context::new_function (enum gcc_jit_function_kind kind, 789 type return_type, 790 const std::string &name, 791 std::vector<param> ¶ms, 792 int is_variadic, 793 location loc) 794 { 795 /* Treat std::vector as an array, relying on it not being resized: */ 796 param *as_array_of_wrappers = ¶ms[0]; 797 798 /* Treat the array as being of the underlying pointers, relying on 799 the wrapper type being such a pointer internally. */ 800 gcc_jit_param **as_array_of_ptrs = 801 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers); 802 803 return function (gcc_jit_context_new_function (m_inner_ctxt, 804 loc.get_inner_location (), 805 kind, 806 return_type.get_inner_type (), 807 name.c_str (), 808 params.size (), 809 as_array_of_ptrs, 810 is_variadic)); 811 } 812 813 inline function 814 context::get_builtin_function (const std::string &name) 815 { 816 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt, 817 name.c_str ())); 818 } 819 820 inline lvalue 821 context::new_global (enum gcc_jit_global_kind kind, 822 type type_, 823 const std::string &name, 824 location loc) 825 { 826 return lvalue (gcc_jit_context_new_global (m_inner_ctxt, 827 loc.get_inner_location (), 828 kind, 829 type_.get_inner_type (), 830 name.c_str ())); 831 } 832 833 inline rvalue 834 context::new_rvalue (type numeric_type, 835 int value) const 836 { 837 return rvalue ( 838 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt, 839 numeric_type.get_inner_type (), 840 value)); 841 } 842 843 inline rvalue 844 context::new_rvalue (type numeric_type, 845 long value) const 846 { 847 return rvalue ( 848 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt, 849 numeric_type.get_inner_type (), 850 value)); 851 } 852 853 inline rvalue 854 context::zero (type numeric_type) const 855 { 856 return rvalue (gcc_jit_context_zero (m_inner_ctxt, 857 numeric_type.get_inner_type ())); 858 } 859 860 inline rvalue 861 context::one (type numeric_type) const 862 { 863 return rvalue (gcc_jit_context_one (m_inner_ctxt, 864 numeric_type.get_inner_type ())); 865 } 866 867 inline rvalue 868 context::new_rvalue (type numeric_type, 869 double value) const 870 { 871 return rvalue ( 872 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt, 873 numeric_type.get_inner_type (), 874 value)); 875 } 876 877 inline rvalue 878 context::new_rvalue (type pointer_type, 879 void *value) const 880 { 881 return rvalue ( 882 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt, 883 pointer_type.get_inner_type (), 884 value)); 885 } 886 887 inline rvalue 888 context::new_rvalue (const std::string &value) const 889 { 890 return rvalue ( 891 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ())); 892 } 893 894 inline rvalue 895 context::new_unary_op (enum gcc_jit_unary_op op, 896 type result_type, 897 rvalue a, 898 location loc) 899 { 900 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt, 901 loc.get_inner_location (), 902 op, 903 result_type.get_inner_type (), 904 a.get_inner_rvalue ())); 905 } 906 inline rvalue 907 context::new_minus (type result_type, 908 rvalue a, 909 location loc) 910 { 911 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS, 912 result_type, a, loc)); 913 } 914 inline rvalue 915 context::new_bitwise_negate (type result_type, 916 rvalue a, 917 location loc) 918 { 919 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE, 920 result_type, a, loc)); 921 } 922 inline rvalue 923 context::new_logical_negate (type result_type, 924 rvalue a, 925 location loc) 926 { 927 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE, 928 result_type, a, loc)); 929 } 930 931 inline rvalue 932 context::new_binary_op (enum gcc_jit_binary_op op, 933 type result_type, 934 rvalue a, rvalue b, 935 location loc) 936 { 937 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt, 938 loc.get_inner_location (), 939 op, 940 result_type.get_inner_type (), 941 a.get_inner_rvalue (), 942 b.get_inner_rvalue ())); 943 } 944 inline rvalue 945 context::new_plus (type result_type, 946 rvalue a, rvalue b, 947 location loc) 948 { 949 return new_binary_op (GCC_JIT_BINARY_OP_PLUS, 950 result_type, a, b, loc); 951 } 952 inline rvalue 953 context::new_minus (type result_type, 954 rvalue a, rvalue b, 955 location loc) 956 { 957 return new_binary_op (GCC_JIT_BINARY_OP_MINUS, 958 result_type, a, b, loc); 959 } 960 inline rvalue 961 context::new_mult (type result_type, 962 rvalue a, rvalue b, 963 location loc) 964 { 965 return new_binary_op (GCC_JIT_BINARY_OP_MULT, 966 result_type, a, b, loc); 967 } 968 inline rvalue 969 context::new_divide (type result_type, 970 rvalue a, rvalue b, 971 location loc) 972 { 973 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE, 974 result_type, a, b, loc); 975 } 976 inline rvalue 977 context::new_modulo (type result_type, 978 rvalue a, rvalue b, 979 location loc) 980 { 981 return new_binary_op (GCC_JIT_BINARY_OP_MODULO, 982 result_type, a, b, loc); 983 } 984 inline rvalue 985 context::new_bitwise_and (type result_type, 986 rvalue a, rvalue b, 987 location loc) 988 { 989 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND, 990 result_type, a, b, loc); 991 } 992 inline rvalue 993 context::new_bitwise_xor (type result_type, 994 rvalue a, rvalue b, 995 location loc) 996 { 997 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR, 998 result_type, a, b, loc); 999 } 1000 inline rvalue 1001 context::new_bitwise_or (type result_type, 1002 rvalue a, rvalue b, 1003 location loc) 1004 { 1005 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR, 1006 result_type, a, b, loc); 1007 } 1008 inline rvalue 1009 context::new_logical_and (type result_type, 1010 rvalue a, rvalue b, 1011 location loc) 1012 { 1013 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND, 1014 result_type, a, b, loc); 1015 } 1016 inline rvalue 1017 context::new_logical_or (type result_type, 1018 rvalue a, rvalue b, 1019 location loc) 1020 { 1021 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR, 1022 result_type, a, b, loc); 1023 } 1024 1025 inline rvalue 1026 context::new_comparison (enum gcc_jit_comparison op, 1027 rvalue a, rvalue b, 1028 location loc) 1029 { 1030 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt, 1031 loc.get_inner_location (), 1032 op, 1033 a.get_inner_rvalue (), 1034 b.get_inner_rvalue ())); 1035 } 1036 inline rvalue 1037 context::new_eq (rvalue a, rvalue b, 1038 location loc) 1039 { 1040 return new_comparison (GCC_JIT_COMPARISON_EQ, 1041 a, b, loc); 1042 } 1043 inline rvalue 1044 context::new_ne (rvalue a, rvalue b, 1045 location loc) 1046 { 1047 return new_comparison (GCC_JIT_COMPARISON_NE, 1048 a, b, loc); 1049 } 1050 inline rvalue 1051 context::new_lt (rvalue a, rvalue b, 1052 location loc) 1053 { 1054 return new_comparison (GCC_JIT_COMPARISON_LT, 1055 a, b, loc); 1056 } 1057 inline rvalue 1058 context::new_le (rvalue a, rvalue b, 1059 location loc) 1060 { 1061 return new_comparison (GCC_JIT_COMPARISON_LE, 1062 a, b, loc); 1063 } 1064 inline rvalue 1065 context::new_gt (rvalue a, rvalue b, 1066 location loc) 1067 { 1068 return new_comparison (GCC_JIT_COMPARISON_GT, 1069 a, b, loc); 1070 } 1071 inline rvalue 1072 context::new_ge (rvalue a, rvalue b, 1073 location loc) 1074 { 1075 return new_comparison (GCC_JIT_COMPARISON_GE, 1076 a, b, loc); 1077 } 1078 1079 inline rvalue 1080 context::new_call (function func, 1081 std::vector<rvalue> &args, 1082 location loc) 1083 { 1084 /* Treat std::vector as an array, relying on it not being resized: */ 1085 rvalue *as_array_of_wrappers = &args[0]; 1086 1087 /* Treat the array as being of the underlying pointers, relying on 1088 the wrapper type being such a pointer internally. */ 1089 gcc_jit_rvalue **as_array_of_ptrs = 1090 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers); 1091 return gcc_jit_context_new_call (m_inner_ctxt, 1092 loc.get_inner_location (), 1093 func.get_inner_function (), 1094 args.size (), 1095 as_array_of_ptrs); 1096 } 1097 inline rvalue 1098 context::new_call (function func, 1099 location loc) 1100 { 1101 std::vector<rvalue> args; 1102 return new_call (func, args, loc); 1103 } 1104 1105 inline rvalue 1106 context::new_call (function func, 1107 rvalue arg0, 1108 location loc) 1109 { 1110 std::vector<rvalue> args(1); 1111 args[0] = arg0; 1112 return new_call (func, args, loc); 1113 } 1114 inline rvalue 1115 context::new_call (function func, 1116 rvalue arg0, rvalue arg1, 1117 location loc) 1118 { 1119 std::vector<rvalue> args(2); 1120 args[0] = arg0; 1121 args[1] = arg1; 1122 return new_call (func, args, loc); 1123 } 1124 inline rvalue 1125 context::new_call (function func, 1126 rvalue arg0, rvalue arg1, rvalue arg2, 1127 location loc) 1128 { 1129 std::vector<rvalue> args(3); 1130 args[0] = arg0; 1131 args[1] = arg1; 1132 args[2] = arg2; 1133 return new_call (func, args, loc); 1134 } 1135 inline rvalue 1136 context::new_call (function func, 1137 rvalue arg0, rvalue arg1, rvalue arg2, 1138 rvalue arg3, 1139 location loc) 1140 { 1141 std::vector<rvalue> args(4); 1142 args[0] = arg0; 1143 args[1] = arg1; 1144 args[2] = arg2; 1145 args[3] = arg3; 1146 return new_call (func, args, loc); 1147 } 1148 inline rvalue 1149 context::new_call (function func, 1150 rvalue arg0, rvalue arg1, rvalue arg2, 1151 rvalue arg3, rvalue arg4, 1152 location loc) 1153 { 1154 std::vector<rvalue> args(5); 1155 args[0] = arg0; 1156 args[1] = arg1; 1157 args[2] = arg2; 1158 args[3] = arg3; 1159 args[4] = arg4; 1160 return new_call (func, args, loc); 1161 } 1162 inline rvalue 1163 context::new_call (function func, 1164 rvalue arg0, rvalue arg1, rvalue arg2, 1165 rvalue arg3, rvalue arg4, rvalue arg5, 1166 location loc) 1167 { 1168 std::vector<rvalue> args(6); 1169 args[0] = arg0; 1170 args[1] = arg1; 1171 args[2] = arg2; 1172 args[3] = arg3; 1173 args[4] = arg4; 1174 args[5] = arg5; 1175 return new_call (func, args, loc); 1176 } 1177 1178 inline rvalue 1179 context::new_cast (rvalue expr, 1180 type type_, 1181 location loc) 1182 { 1183 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt, 1184 loc.get_inner_location (), 1185 expr.get_inner_rvalue (), 1186 type_.get_inner_type ())); 1187 } 1188 1189 inline lvalue 1190 context::new_array_access (rvalue ptr, 1191 rvalue index, 1192 location loc) 1193 { 1194 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt, 1195 loc.get_inner_location (), 1196 ptr.get_inner_rvalue (), 1197 index.get_inner_rvalue ())); 1198 } 1199 1200 inline case_ 1201 context::new_case (rvalue min_value, 1202 rvalue max_value, 1203 block dest_block) 1204 { 1205 return case_ (gcc_jit_context_new_case (m_inner_ctxt, 1206 min_value.get_inner_rvalue (), 1207 max_value.get_inner_rvalue (), 1208 dest_block.get_inner_block ())); 1209 } 1210 1211 // class object 1212 inline context 1213 object::get_context () const 1214 { 1215 return context (gcc_jit_object_get_context (m_inner_obj)); 1216 } 1217 1218 inline std::string 1219 object::get_debug_string () const 1220 { 1221 return gcc_jit_object_get_debug_string (m_inner_obj); 1222 } 1223 1224 inline object::object () : m_inner_obj (NULL) {} 1225 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj) 1226 { 1227 if (!obj) 1228 throw error (); 1229 } 1230 1231 inline gcc_jit_object * 1232 object::get_inner_object () const 1233 { 1234 return m_inner_obj; 1235 } 1236 1237 inline std::ostream& 1238 operator << (std::ostream& stream, const object &obj) 1239 { 1240 return stream << obj.get_debug_string (); 1241 } 1242 1243 // class location 1244 inline location::location () : object () {} 1245 inline location::location (gcc_jit_location *loc) 1246 : object (gcc_jit_location_as_object (loc)) 1247 {} 1248 1249 inline gcc_jit_location * 1250 location::get_inner_location () const 1251 { 1252 /* Manual downcast: */ 1253 return reinterpret_cast<gcc_jit_location *> (get_inner_object ()); 1254 } 1255 1256 // class field 1257 inline field::field () : object () {} 1258 inline field::field (gcc_jit_field *inner) 1259 : object (gcc_jit_field_as_object (inner)) 1260 {} 1261 1262 inline gcc_jit_field * 1263 field::get_inner_field () const 1264 { 1265 /* Manual downcast: */ 1266 return reinterpret_cast<gcc_jit_field *> (get_inner_object ()); 1267 } 1268 1269 // class type 1270 inline type::type () : object () {} 1271 inline type::type (gcc_jit_type *inner) 1272 : object (gcc_jit_type_as_object (inner)) 1273 {} 1274 1275 inline gcc_jit_type * 1276 type::get_inner_type () const 1277 { 1278 /* Manual downcast: */ 1279 return reinterpret_cast<gcc_jit_type *> (get_inner_object ()); 1280 } 1281 1282 inline type 1283 type::get_pointer () 1284 { 1285 return type (gcc_jit_type_get_pointer (get_inner_type ())); 1286 } 1287 1288 inline type 1289 type::get_volatile () 1290 { 1291 return type (gcc_jit_type_get_volatile (get_inner_type ())); 1292 } 1293 1294 inline rvalue 1295 type::zero () 1296 { 1297 return get_context ().new_rvalue (*this, 0); 1298 } 1299 1300 inline rvalue 1301 type::one () 1302 { 1303 return get_context ().new_rvalue (*this, 1); 1304 } 1305 1306 // class struct_ 1307 inline struct_::struct_ () : type (NULL) {} 1308 inline struct_::struct_ (gcc_jit_struct *inner) : 1309 type (gcc_jit_struct_as_type (inner)) 1310 { 1311 } 1312 1313 inline gcc_jit_struct * 1314 struct_::get_inner_struct () const 1315 { 1316 /* Manual downcast: */ 1317 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ()); 1318 } 1319 1320 // class function 1321 inline function::function () : object () {} 1322 inline function::function (gcc_jit_function *inner) 1323 : object (gcc_jit_function_as_object (inner)) 1324 {} 1325 1326 inline gcc_jit_function * 1327 function::get_inner_function () const 1328 { 1329 /* Manual downcast: */ 1330 return reinterpret_cast<gcc_jit_function *> (get_inner_object ()); 1331 } 1332 1333 inline void 1334 function::dump_to_dot (const std::string &path) 1335 { 1336 gcc_jit_function_dump_to_dot (get_inner_function (), 1337 path.c_str ()); 1338 } 1339 1340 inline param 1341 function::get_param (int index) const 1342 { 1343 return param (gcc_jit_function_get_param (get_inner_function (), 1344 index)); 1345 } 1346 1347 inline block 1348 function::new_block () 1349 { 1350 return block (gcc_jit_function_new_block (get_inner_function (), 1351 NULL)); 1352 } 1353 1354 inline block 1355 function::new_block (const std::string &name) 1356 { 1357 return block (gcc_jit_function_new_block (get_inner_function (), 1358 name.c_str ())); 1359 } 1360 1361 inline lvalue 1362 function::new_local (type type_, 1363 const std::string &name, 1364 location loc) 1365 { 1366 return lvalue (gcc_jit_function_new_local (get_inner_function (), 1367 loc.get_inner_location (), 1368 type_.get_inner_type (), 1369 name.c_str ())); 1370 } 1371 1372 inline function 1373 block::get_function () const 1374 { 1375 return function (gcc_jit_block_get_function ( get_inner_block ())); 1376 } 1377 1378 inline void 1379 block::add_eval (rvalue rvalue, 1380 location loc) 1381 { 1382 gcc_jit_block_add_eval (get_inner_block (), 1383 loc.get_inner_location (), 1384 rvalue.get_inner_rvalue ()); 1385 } 1386 1387 inline void 1388 block::add_assignment (lvalue lvalue, 1389 rvalue rvalue, 1390 location loc) 1391 { 1392 gcc_jit_block_add_assignment (get_inner_block (), 1393 loc.get_inner_location (), 1394 lvalue.get_inner_lvalue (), 1395 rvalue.get_inner_rvalue ()); 1396 } 1397 1398 inline void 1399 block::add_assignment_op (lvalue lvalue, 1400 enum gcc_jit_binary_op op, 1401 rvalue rvalue, 1402 location loc) 1403 { 1404 gcc_jit_block_add_assignment_op (get_inner_block (), 1405 loc.get_inner_location (), 1406 lvalue.get_inner_lvalue (), 1407 op, 1408 rvalue.get_inner_rvalue ()); 1409 } 1410 1411 inline void 1412 block::add_comment (const std::string &text, 1413 location loc) 1414 { 1415 gcc_jit_block_add_comment (get_inner_block (), 1416 loc.get_inner_location (), 1417 text.c_str ()); 1418 } 1419 1420 inline void 1421 block::end_with_conditional (rvalue boolval, 1422 block on_true, 1423 block on_false, 1424 location loc) 1425 { 1426 gcc_jit_block_end_with_conditional (get_inner_block (), 1427 loc.get_inner_location (), 1428 boolval.get_inner_rvalue (), 1429 on_true.get_inner_block (), 1430 on_false.get_inner_block ()); 1431 } 1432 1433 inline void 1434 block::end_with_jump (block target, 1435 location loc) 1436 { 1437 gcc_jit_block_end_with_jump (get_inner_block (), 1438 loc.get_inner_location (), 1439 target.get_inner_block ()); 1440 } 1441 1442 inline void 1443 block::end_with_return (rvalue rvalue, 1444 location loc) 1445 { 1446 gcc_jit_block_end_with_return (get_inner_block (), 1447 loc.get_inner_location (), 1448 rvalue.get_inner_rvalue ()); 1449 } 1450 1451 inline void 1452 block::end_with_return (location loc) 1453 { 1454 gcc_jit_block_end_with_void_return (get_inner_block (), 1455 loc.get_inner_location ()); 1456 } 1457 1458 inline void 1459 block::end_with_switch (rvalue expr, 1460 block default_block, 1461 std::vector <case_> cases, 1462 location loc) 1463 { 1464 /* Treat std::vector as an array, relying on it not being resized: */ 1465 case_ *as_array_of_wrappers = &cases[0]; 1466 1467 /* Treat the array as being of the underlying pointers, relying on 1468 the wrapper type being such a pointer internally. */ 1469 gcc_jit_case **as_array_of_ptrs = 1470 reinterpret_cast<gcc_jit_case **> (as_array_of_wrappers); 1471 gcc_jit_block_end_with_switch (get_inner_block (), 1472 loc.get_inner_location (), 1473 expr.get_inner_rvalue (), 1474 default_block.get_inner_block (), 1475 cases.size (), 1476 as_array_of_ptrs); 1477 } 1478 1479 inline rvalue 1480 block::add_call (function other, 1481 location loc) 1482 { 1483 rvalue c = get_context ().new_call (other, loc); 1484 add_eval (c); 1485 return c; 1486 } 1487 inline rvalue 1488 block::add_call (function other, 1489 rvalue arg0, 1490 location loc) 1491 { 1492 rvalue c = get_context ().new_call (other, arg0, loc); 1493 add_eval (c); 1494 return c; 1495 } 1496 inline rvalue 1497 block::add_call (function other, 1498 rvalue arg0, rvalue arg1, 1499 location loc) 1500 { 1501 rvalue c = get_context ().new_call (other, arg0, arg1, loc); 1502 add_eval (c); 1503 return c; 1504 } 1505 inline rvalue 1506 block::add_call (function other, 1507 rvalue arg0, rvalue arg1, rvalue arg2, 1508 location loc) 1509 { 1510 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc); 1511 add_eval (c); 1512 return c; 1513 } 1514 1515 inline rvalue 1516 block::add_call (function other, 1517 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3, 1518 location loc) 1519 { 1520 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc); 1521 add_eval (c); 1522 return c; 1523 } 1524 1525 inline rvalue 1526 function::operator() (location loc) 1527 { 1528 return get_context ().new_call (*this, loc); 1529 } 1530 inline rvalue 1531 function::operator() (rvalue arg0, 1532 location loc) 1533 { 1534 return get_context ().new_call (*this, 1535 arg0, 1536 loc); 1537 } 1538 inline rvalue 1539 function::operator() (rvalue arg0, rvalue arg1, 1540 location loc) 1541 { 1542 return get_context ().new_call (*this, 1543 arg0, arg1, 1544 loc); 1545 } 1546 inline rvalue 1547 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2, 1548 location loc) 1549 { 1550 return get_context ().new_call (*this, 1551 arg0, arg1, arg2, 1552 loc); 1553 } 1554 1555 // class block 1556 inline block::block () : object () {} 1557 inline block::block (gcc_jit_block *inner) 1558 : object (gcc_jit_block_as_object (inner)) 1559 {} 1560 1561 inline gcc_jit_block * 1562 block::get_inner_block () const 1563 { 1564 /* Manual downcast: */ 1565 return reinterpret_cast<gcc_jit_block *> (get_inner_object ()); 1566 } 1567 1568 // class rvalue 1569 inline rvalue::rvalue () : object () {} 1570 inline rvalue::rvalue (gcc_jit_rvalue *inner) 1571 : object (gcc_jit_rvalue_as_object (inner)) 1572 {} 1573 1574 inline gcc_jit_rvalue * 1575 rvalue::get_inner_rvalue () const 1576 { 1577 /* Manual downcast: */ 1578 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ()); 1579 } 1580 1581 inline type 1582 rvalue::get_type () 1583 { 1584 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ())); 1585 } 1586 1587 inline rvalue 1588 rvalue::access_field (field field, 1589 location loc) 1590 { 1591 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (), 1592 loc.get_inner_location (), 1593 field.get_inner_field ())); 1594 } 1595 1596 inline lvalue 1597 rvalue::dereference_field (field field, 1598 location loc) 1599 { 1600 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (), 1601 loc.get_inner_location (), 1602 field.get_inner_field ())); 1603 } 1604 1605 inline lvalue 1606 rvalue::dereference (location loc) 1607 { 1608 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (), 1609 loc.get_inner_location ())); 1610 } 1611 1612 inline rvalue 1613 rvalue::cast_to (type type_, 1614 location loc) 1615 { 1616 return get_context ().new_cast (*this, type_, loc); 1617 } 1618 1619 inline lvalue 1620 rvalue::operator[] (rvalue index) 1621 { 1622 return get_context ().new_array_access (*this, index); 1623 } 1624 1625 inline lvalue 1626 rvalue::operator[] (int index) 1627 { 1628 context ctxt = get_context (); 1629 type int_t = ctxt.get_int_type <int> (); 1630 return ctxt.new_array_access (*this, 1631 ctxt.new_rvalue (int_t, 1632 index)); 1633 } 1634 1635 // class lvalue : public rvalue 1636 inline lvalue::lvalue () : rvalue () {} 1637 inline lvalue::lvalue (gcc_jit_lvalue *inner) 1638 : rvalue (gcc_jit_lvalue_as_rvalue (inner)) 1639 {} 1640 1641 inline gcc_jit_lvalue * 1642 lvalue::get_inner_lvalue () const 1643 { 1644 /* Manual downcast: */ 1645 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ()); 1646 } 1647 1648 inline lvalue 1649 lvalue::access_field (field field, location loc) 1650 { 1651 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (), 1652 loc.get_inner_location (), 1653 field.get_inner_field ())); 1654 } 1655 1656 inline rvalue 1657 lvalue::get_address (location loc) 1658 { 1659 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (), 1660 loc.get_inner_location ())); 1661 } 1662 1663 // class param : public lvalue 1664 inline param::param () : lvalue () {} 1665 inline param::param (gcc_jit_param *inner) 1666 : lvalue (gcc_jit_param_as_lvalue (inner)) 1667 {} 1668 1669 // class case_ : public object 1670 inline case_::case_ () : object () {} 1671 inline case_::case_ (gcc_jit_case *inner) 1672 : object (gcc_jit_case_as_object (inner)) 1673 { 1674 } 1675 1676 inline gcc_jit_case * 1677 case_::get_inner_case () const 1678 { 1679 /* Manual downcast: */ 1680 return reinterpret_cast<gcc_jit_case *> (get_inner_object ()); 1681 } 1682 1683 /* Overloaded operators. */ 1684 // Unary operators 1685 inline rvalue operator- (rvalue a) 1686 { 1687 return a.get_context ().new_minus (a.get_type (), a); 1688 } 1689 inline rvalue operator~ (rvalue a) 1690 { 1691 return a.get_context ().new_bitwise_negate (a.get_type (), a); 1692 } 1693 inline rvalue operator! (rvalue a) 1694 { 1695 return a.get_context ().new_logical_negate (a.get_type (), a); 1696 } 1697 1698 // Binary operators 1699 inline rvalue operator+ (rvalue a, rvalue b) 1700 { 1701 return a.get_context ().new_plus (a.get_type (), a, b); 1702 } 1703 inline rvalue operator- (rvalue a, rvalue b) 1704 { 1705 return a.get_context ().new_minus (a.get_type (), a, b); 1706 } 1707 inline rvalue operator* (rvalue a, rvalue b) 1708 { 1709 return a.get_context ().new_mult (a.get_type (), a, b); 1710 } 1711 inline rvalue operator/ (rvalue a, rvalue b) 1712 { 1713 return a.get_context ().new_divide (a.get_type (), a, b); 1714 } 1715 inline rvalue operator% (rvalue a, rvalue b) 1716 { 1717 return a.get_context ().new_modulo (a.get_type (), a, b); 1718 } 1719 inline rvalue operator& (rvalue a, rvalue b) 1720 { 1721 return a.get_context ().new_bitwise_and (a.get_type (), a, b); 1722 } 1723 inline rvalue operator^ (rvalue a, rvalue b) 1724 { 1725 return a.get_context ().new_bitwise_xor (a.get_type (), a, b); 1726 } 1727 inline rvalue operator| (rvalue a, rvalue b) 1728 { 1729 return a.get_context ().new_bitwise_or (a.get_type (), a, b); 1730 } 1731 inline rvalue operator&& (rvalue a, rvalue b) 1732 { 1733 return a.get_context ().new_logical_and (a.get_type (), a, b); 1734 } 1735 inline rvalue operator|| (rvalue a, rvalue b) 1736 { 1737 return a.get_context ().new_logical_or (a.get_type (), a, b); 1738 } 1739 1740 /* Comparisons. */ 1741 inline rvalue operator== (rvalue a, rvalue b) 1742 { 1743 return a.get_context ().new_eq (a, b); 1744 } 1745 inline rvalue operator!= (rvalue a, rvalue b) 1746 { 1747 return a.get_context ().new_ne (a, b); 1748 } 1749 inline rvalue operator< (rvalue a, rvalue b) 1750 { 1751 return a.get_context ().new_lt (a, b); 1752 } 1753 inline rvalue operator<= (rvalue a, rvalue b) 1754 { 1755 return a.get_context ().new_le (a, b); 1756 } 1757 inline rvalue operator> (rvalue a, rvalue b) 1758 { 1759 return a.get_context ().new_gt (a, b); 1760 } 1761 inline rvalue operator>= (rvalue a, rvalue b) 1762 { 1763 return a.get_context ().new_ge (a, b); 1764 } 1765 1766 /* Dereferencing. */ 1767 inline lvalue operator* (rvalue ptr) 1768 { 1769 return ptr.dereference (); 1770 } 1771 1772 // class timer 1773 inline 1774 timer::timer () 1775 { 1776 m_inner_timer = gcc_jit_timer_new (); 1777 } 1778 1779 inline 1780 timer::timer (gcc_jit_timer *inner_timer) 1781 { 1782 m_inner_timer = inner_timer; 1783 } 1784 1785 inline void 1786 timer::push (const char *item_name) 1787 { 1788 gcc_jit_timer_push (m_inner_timer, item_name); 1789 1790 } 1791 1792 inline void 1793 timer::pop (const char *item_name) 1794 { 1795 gcc_jit_timer_pop (m_inner_timer, item_name); 1796 } 1797 1798 inline void 1799 timer::print (FILE *f_out) const 1800 { 1801 gcc_jit_timer_print (m_inner_timer, f_out); 1802 } 1803 1804 inline gcc_jit_timer * 1805 timer::get_inner_timer () const 1806 { 1807 return m_inner_timer; 1808 } 1809 1810 inline void 1811 timer::release () 1812 { 1813 gcc_jit_timer_release (m_inner_timer); 1814 m_inner_timer = NULL; 1815 } 1816 1817 // class auto_time 1818 1819 inline 1820 auto_time::auto_time (timer t, const char *item_name) 1821 : m_timer (t), 1822 m_item_name (item_name) 1823 { 1824 t.push (item_name); 1825 } 1826 1827 inline 1828 auto_time::auto_time (context ctxt, const char *item_name) 1829 : m_timer (ctxt.get_timer ()), 1830 m_item_name (item_name) 1831 { 1832 m_timer.push (item_name); 1833 } 1834 1835 inline 1836 auto_time::~auto_time () 1837 { 1838 m_timer.pop (m_item_name); 1839 } 1840 1841 } // namespace gccjit 1842 1843 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */ 1844