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