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