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