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