1/* Internals of libgccjit: classes for recording calls made to the JIT API. 2 Copyright (C) 2013-2022 Free Software Foundation, Inc. 3 Contributed by David Malcolm <dmalcolm@redhat.com>. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21#ifndef JIT_RECORDING_H 22#define JIT_RECORDING_H 23 24#include "jit-common.h" 25#include "jit-logging.h" 26 27class timer; 28 29namespace gcc { 30 31namespace jit { 32 33extern const char * const unary_op_reproducer_strings[]; 34extern const char * const binary_op_reproducer_strings[]; 35 36class result; 37class dump; 38class reproducer; 39 40/********************************************************************** 41 Recording. 42 **********************************************************************/ 43 44namespace recording { 45 46playback::location * 47playback_location (replayer *r, location *loc); 48 49const char * 50playback_string (string *str); 51 52playback::block * 53playback_block (block *b); 54 55/* A recording of a call to gcc_jit_context_enable_dump. */ 56struct requested_dump 57{ 58 const char *m_dumpname; 59 char **m_out_ptr; 60}; 61 62/* A JIT-compilation context. */ 63class context : public log_user 64{ 65public: 66 context (context *parent_ctxt); 67 ~context (); 68 69 builtins_manager * 70 get_builtins_manager (); 71 72 void record (memento *m); 73 void replay_into (replayer *r); 74 void disassociate_from_playback (); 75 76 string * 77 new_string (const char *text, bool escaped = false); 78 79 location * 80 new_location (const char *filename, 81 int line, 82 int column, 83 bool created_by_user); 84 85 type * 86 get_type (enum gcc_jit_types type); 87 88 type * 89 get_int_type (int num_bytes, int is_signed); 90 91 type * 92 new_array_type (location *loc, 93 type *element_type, 94 int num_elements); 95 96 field * 97 new_field (location *loc, 98 type *type, 99 const char *name); 100 101 field * 102 new_bitfield (location *loc, 103 type *type, 104 int width, 105 const char *name); 106 107 struct_ * 108 new_struct_type (location *loc, 109 const char *name); 110 111 union_ * 112 new_union_type (location *loc, 113 const char *name); 114 115 function_type * 116 new_function_type (type *return_type, 117 int num_params, 118 type **param_types, 119 int is_variadic); 120 121 type * 122 new_function_ptr_type (location *loc, 123 type *return_type, 124 int num_params, 125 type **param_types, 126 int is_variadic); 127 128 param * 129 new_param (location *loc, 130 type *type, 131 const char *name); 132 133 function * 134 new_function (location *loc, 135 enum gcc_jit_function_kind kind, 136 type *return_type, 137 const char *name, 138 int num_params, 139 param **params, 140 int is_variadic, 141 enum built_in_function builtin_id); 142 143 function * 144 get_builtin_function (const char *name); 145 146 lvalue * 147 new_global (location *loc, 148 enum gcc_jit_global_kind kind, 149 type *type, 150 const char *name); 151 152 rvalue * 153 new_ctor (location *loc, 154 type *type, 155 size_t num_values, 156 field **fields, 157 rvalue **values); 158 159 void 160 new_global_init_rvalue (lvalue *variable, 161 rvalue *init); 162 163 template <typename HOST_TYPE> 164 rvalue * 165 new_rvalue_from_const (type *type, 166 HOST_TYPE value); 167 168 rvalue * 169 new_string_literal (const char *value); 170 171 rvalue * 172 new_rvalue_from_vector (location *loc, 173 vector_type *type, 174 rvalue **elements); 175 176 rvalue * 177 new_unary_op (location *loc, 178 enum gcc_jit_unary_op op, 179 type *result_type, 180 rvalue *a); 181 182 rvalue * 183 new_binary_op (location *loc, 184 enum gcc_jit_binary_op op, 185 type *result_type, 186 rvalue *a, rvalue *b); 187 188 rvalue * 189 new_comparison (location *loc, 190 enum gcc_jit_comparison op, 191 rvalue *a, rvalue *b); 192 193 rvalue * 194 new_call (location *loc, 195 function *func, 196 int numargs, rvalue **args); 197 198 rvalue * 199 new_call_through_ptr (location *loc, 200 rvalue *fn_ptr, 201 int numargs, rvalue **args); 202 203 rvalue * 204 new_cast (location *loc, 205 rvalue *expr, 206 type *type_); 207 208 rvalue * 209 new_bitcast (location *loc, 210 rvalue *expr, 211 type *type_); 212 213 lvalue * 214 new_array_access (location *loc, 215 rvalue *ptr, 216 rvalue *index); 217 218 case_ * 219 new_case (rvalue *min_value, 220 rvalue *max_value, 221 block *block); 222 223 void 224 set_str_option (enum gcc_jit_str_option opt, 225 const char *value); 226 227 void 228 set_int_option (enum gcc_jit_int_option opt, 229 int value); 230 231 void 232 set_bool_option (enum gcc_jit_bool_option opt, 233 int value); 234 235 void 236 set_inner_bool_option (enum inner_bool_option inner_opt, 237 int value); 238 239 void 240 add_command_line_option (const char *optname); 241 242 void 243 append_command_line_options (vec <char *> *argvec); 244 245 void 246 add_driver_option (const char *optname); 247 248 void 249 append_driver_options (auto_string_vec *argvec); 250 251 void 252 enable_dump (const char *dumpname, 253 char **out_ptr); 254 255 const char * 256 get_str_option (enum gcc_jit_str_option opt) const 257 { 258 return m_str_options[opt]; 259 } 260 261 int 262 get_int_option (enum gcc_jit_int_option opt) const 263 { 264 return m_int_options[opt]; 265 } 266 267 int 268 get_bool_option (enum gcc_jit_bool_option opt) const 269 { 270 return m_bool_options[opt]; 271 } 272 273 int 274 get_inner_bool_option (enum inner_bool_option opt) const 275 { 276 return m_inner_bool_options[opt]; 277 } 278 279 result * 280 compile (); 281 282 void 283 compile_to_file (enum gcc_jit_output_kind output_kind, 284 const char *output_path); 285 286 void 287 add_error (location *loc, const char *fmt, ...) 288 GNU_PRINTF(3, 4); 289 290 void 291 add_error_va (location *loc, const char *fmt, va_list ap) 292 GNU_PRINTF(3, 0); 293 294 const char * 295 get_first_error () const; 296 297 const char * 298 get_last_error () const; 299 300 bool errors_occurred () const 301 { 302 if (m_parent_ctxt) 303 if (m_parent_ctxt->errors_occurred ()) 304 return true; 305 return m_error_count; 306 } 307 308 type *get_opaque_FILE_type (); 309 310 void dump_to_file (const char *path, bool update_locations); 311 312 void dump_reproducer_to_file (const char *path); 313 314 void 315 get_all_requested_dumps (vec <recording::requested_dump> *out); 316 317 void set_timer (timer *t) { m_timer = t; } 318 timer *get_timer () const { return m_timer; } 319 320 void add_top_level_asm (location *loc, const char *asm_stmts); 321 322private: 323 void log_all_options () const; 324 void log_str_option (enum gcc_jit_str_option opt) const; 325 void log_int_option (enum gcc_jit_int_option opt) const; 326 void log_bool_option (enum gcc_jit_bool_option opt) const; 327 void log_inner_bool_option (enum inner_bool_option opt) const; 328 329 void validate (); 330 331private: 332 context *m_parent_ctxt; 333 334 /* The ultimate ancestor of the contexts within a family tree of 335 contexts. This has itself as its own m_toplevel_ctxt. */ 336 context *m_toplevel_ctxt; 337 338 timer *m_timer; 339 340 int m_error_count; 341 342 char *m_first_error_str; 343 bool m_owns_first_error_str; 344 345 char *m_last_error_str; 346 bool m_owns_last_error_str; 347 348 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS]; 349 int m_int_options[GCC_JIT_NUM_INT_OPTIONS]; 350 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS]; 351 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS]; 352 auto_vec <char *> m_command_line_options; 353 auto_vec <char *> m_driver_options; 354 355 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */ 356 auto_vec<requested_dump> m_requested_dumps; 357 358 /* Recorded API usage. */ 359 auto_vec<memento *> m_mementos; 360 361 /* Specific recordings, for use by dump_to_file. */ 362 auto_vec<compound_type *> m_compound_types; 363 auto_vec<global *> m_globals; 364 auto_vec<function *> m_functions; 365 auto_vec<top_level_asm *> m_top_level_asms; 366 367 type *m_basic_types[NUM_GCC_JIT_TYPES]; 368 type *m_FILE_type; 369 370 builtins_manager *m_builtins_manager; // lazily created 371}; 372 373 374/* An object with lifetime managed by the context i.e. 375 it lives until the context is released, at which 376 point it itself is cleaned up. */ 377 378class memento 379{ 380public: 381 virtual ~memento () {} 382 383 /* Hook for replaying this. */ 384 virtual void replay_into (replayer *r) = 0; 385 386 void set_playback_obj (void *obj) { m_playback_obj = obj; } 387 388 389 /* Get the context that owns this object. 390 391 Implements the post-error-checking part of 392 gcc_jit_object_get_context. */ 393 context *get_context () { return m_ctxt; } 394 395 memento * 396 as_object () { return this; } 397 398 /* Debugging hook, for use in generating error messages etc. 399 Implements the post-error-checking part of 400 gcc_jit_object_get_debug_string. */ 401 const char * 402 get_debug_string (); 403 404 virtual void write_to_dump (dump &d); 405 virtual void write_reproducer (reproducer &r) = 0; 406 virtual location *dyn_cast_location () { return NULL; } 407 408protected: 409 memento (context *ctxt) 410 : m_ctxt (ctxt), 411 m_playback_obj (NULL), 412 m_debug_string (NULL) 413 { 414 gcc_assert (ctxt); 415 } 416 417 string *new_string (const char *text) { return m_ctxt->new_string (text); } 418 419private: 420 virtual string * make_debug_string () = 0; 421 422public: 423 context *m_ctxt; 424 425protected: 426 void *m_playback_obj; 427 428private: 429 string *m_debug_string; 430}; 431 432/* or just use std::string? */ 433class string : public memento 434{ 435public: 436 string (context *ctxt, const char *text, bool escaped); 437 ~string (); 438 439 const char *c_str () { return m_buffer; } 440 441 static string * from_printf (context *ctxt, const char *fmt, ...) 442 GNU_PRINTF(2, 3); 443 444 void replay_into (replayer *) FINAL OVERRIDE {} 445 446private: 447 string * make_debug_string () FINAL OVERRIDE; 448 void write_reproducer (reproducer &r) FINAL OVERRIDE; 449 450private: 451 size_t m_len; 452 char *m_buffer; 453 454 /* Flag to track if this string is the result of string::make_debug_string, 455 to avoid infinite recursion when logging all mementos: don't re-escape 456 such strings. */ 457 bool m_escaped; 458}; 459 460class location : public memento 461{ 462public: 463 location (context *ctxt, string *filename, int line, int column, 464 bool created_by_user) 465 : memento (ctxt), 466 m_filename (filename), 467 m_line (line), 468 m_column (column), 469 m_created_by_user (created_by_user) 470 {} 471 472 void replay_into (replayer *r) FINAL OVERRIDE; 473 474 playback::location * 475 playback_location (replayer *r) 476 { 477 /* Normally during playback, we can walk forwards through the list of 478 recording objects, playing them back. The ordering of recording 479 ensures that everything that a recording object refers to has 480 already been played back, so we can simply look up the relevant 481 m_playback_obj. 482 483 Locations are an exception, due to the "write_to_dump" method of 484 recording::statement. This method can set a new location on a 485 statement after the statement is created, and thus the location 486 appears in the context's memento list *after* the statement that 487 refers to it. 488 489 In such circumstances, the statement is replayed *before* the location, 490 when the latter doesn't yet have a playback object. 491 492 Hence we need to ensure that locations have playback objects. */ 493 if (!m_playback_obj) 494 { 495 replay_into (r); 496 } 497 gcc_assert (m_playback_obj); 498 return static_cast <playback::location *> (m_playback_obj); 499 } 500 501 location *dyn_cast_location () FINAL OVERRIDE { return this; } 502 bool created_by_user () const { return m_created_by_user; } 503 504private: 505 string * make_debug_string () FINAL OVERRIDE; 506 void write_reproducer (reproducer &r) FINAL OVERRIDE; 507 508private: 509 string *m_filename; 510 int m_line; 511 int m_column; 512 bool m_created_by_user; 513}; 514 515class type : public memento 516{ 517public: 518 type *get_pointer (); 519 type *get_const (); 520 type *get_volatile (); 521 type *get_aligned (size_t alignment_in_bytes); 522 type *get_vector (size_t num_units); 523 524 /* Get the type obtained when dereferencing this type. 525 526 This will return NULL if it's not valid to dereference this type. 527 The caller is responsible for setting an error. */ 528 virtual type *dereference () = 0; 529 /* Get the type size in bytes. 530 531 This is implemented only for memento_of_get_type and 532 memento_of_get_pointer as it is used for initializing globals of 533 these types. */ 534 virtual size_t get_size () { gcc_unreachable (); } 535 536 /* Dynamic casts. */ 537 virtual function_type *dyn_cast_function_type () { return NULL; } 538 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; } 539 virtual struct_ *dyn_cast_struct () { return NULL; } 540 virtual vector_type *dyn_cast_vector_type () { return NULL; } 541 542 /* Is it typesafe to copy to this type from rtype? */ 543 virtual bool accepts_writes_from (type *rtype) 544 { 545 gcc_assert (rtype); 546 return this->unqualified ()->is_same_type_as (rtype->unqualified ()); 547 } 548 549 virtual bool is_same_type_as (type *other) 550 { 551 return this == other; 552 } 553 554 /* Strip off "const" etc */ 555 virtual type *unqualified () 556 { 557 return this; 558 } 559 560 virtual bool is_int () const = 0; 561 virtual bool is_float () const = 0; 562 virtual bool is_bool () const = 0; 563 virtual type *is_pointer () = 0; 564 virtual type *is_volatile () { return NULL; } 565 virtual type *is_const () { return NULL; } 566 virtual type *is_array () = 0; 567 virtual struct_ *is_struct () { return NULL; } 568 virtual bool is_union () const { return false; } 569 virtual bool is_void () const { return false; } 570 virtual vector_type *is_vector () { return NULL; } 571 virtual bool has_known_size () const { return true; } 572 virtual bool is_signed () const = 0; 573 574 bool is_numeric () const 575 { 576 return is_int () || is_float () || is_bool (); 577 } 578 579 playback::type * 580 playback_type () 581 { 582 return static_cast <playback::type *> (m_playback_obj); 583 } 584 585 virtual const char *access_as_type (reproducer &r); 586 587protected: 588 type (context *ctxt) 589 : memento (ctxt), 590 m_pointer_to_this_type (NULL) 591 {} 592 593private: 594 type *m_pointer_to_this_type; 595}; 596 597/* Result of "gcc_jit_context_get_type". */ 598class memento_of_get_type : public type 599{ 600public: 601 memento_of_get_type (context *ctxt, 602 enum gcc_jit_types kind) 603 : type (ctxt), 604 m_kind (kind) {} 605 606 type *dereference () FINAL OVERRIDE; 607 608 size_t get_size () FINAL OVERRIDE; 609 610 bool accepts_writes_from (type *rtype) FINAL OVERRIDE 611 { 612 if (m_kind == GCC_JIT_TYPE_VOID_PTR) 613 { 614 if (rtype->is_pointer ()) 615 { 616 /* LHS (this) is type (void *), and the RHS is a pointer: 617 accept it: */ 618 return true; 619 } 620 } else if (is_int () 621 && rtype->is_int () 622 && get_size () == rtype->get_size () 623 && is_signed () == rtype->is_signed ()) 624 { 625 /* LHS (this) is an integer of the same size and sign as rtype. */ 626 return true; 627 } 628 629 return type::accepts_writes_from (rtype); 630 } 631 632 bool is_int () const FINAL OVERRIDE; 633 bool is_float () const FINAL OVERRIDE; 634 bool is_bool () const FINAL OVERRIDE; 635 type *is_pointer () FINAL OVERRIDE { return dereference (); } 636 type *is_array () FINAL OVERRIDE { return NULL; } 637 bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; } 638 bool is_signed () const FINAL OVERRIDE; 639 640public: 641 void replay_into (replayer *r) FINAL OVERRIDE; 642 643private: 644 string * make_debug_string () FINAL OVERRIDE; 645 void write_reproducer (reproducer &r) FINAL OVERRIDE; 646 647private: 648 enum gcc_jit_types m_kind; 649}; 650 651/* Result of "gcc_jit_type_get_pointer". */ 652class memento_of_get_pointer : public type 653{ 654public: 655 memento_of_get_pointer (type *other_type) 656 : type (other_type->m_ctxt), 657 m_other_type (other_type) {} 658 659 type *dereference () FINAL OVERRIDE { return m_other_type; } 660 661 size_t get_size () FINAL OVERRIDE; 662 663 bool accepts_writes_from (type *rtype) FINAL OVERRIDE; 664 665 void replay_into (replayer *r) FINAL OVERRIDE; 666 667 bool is_int () const FINAL OVERRIDE { return false; } 668 bool is_float () const FINAL OVERRIDE { return false; } 669 bool is_bool () const FINAL OVERRIDE { return false; } 670 type *is_pointer () FINAL OVERRIDE { return m_other_type; } 671 type *is_array () FINAL OVERRIDE { return NULL; } 672 bool is_signed () const FINAL OVERRIDE { return false; } 673 674private: 675 string * make_debug_string () FINAL OVERRIDE; 676 void write_reproducer (reproducer &r) FINAL OVERRIDE; 677 678private: 679 type *m_other_type; 680}; 681 682/* A decorated version of a type, for get_const, get_volatile, 683 get_aligned, and get_vector. */ 684 685class decorated_type : public type 686{ 687public: 688 decorated_type (type *other_type) 689 : type (other_type->m_ctxt), 690 m_other_type (other_type) {} 691 692 type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); } 693 694 size_t get_size () FINAL OVERRIDE { return m_other_type->get_size (); }; 695 696 bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); } 697 bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); } 698 bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); } 699 type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); } 700 type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); } 701 struct_ *is_struct () FINAL OVERRIDE { return m_other_type->is_struct (); } 702 bool is_signed () const FINAL OVERRIDE { return m_other_type->is_signed (); } 703 704protected: 705 type *m_other_type; 706}; 707 708/* Result of "gcc_jit_type_get_const". */ 709class memento_of_get_const : public decorated_type 710{ 711public: 712 memento_of_get_const (type *other_type) 713 : decorated_type (other_type) {} 714 715 bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE 716 { 717 /* Can't write to a "const". */ 718 return false; 719 } 720 721 /* Strip off the "const", giving the underlying type. */ 722 type *unqualified () FINAL OVERRIDE { return m_other_type; } 723 724 virtual bool is_same_type_as (type *other) 725 { 726 if (!other->is_const ()) 727 return false; 728 return m_other_type->is_same_type_as (other->is_const ()); 729 } 730 731 virtual type *is_const () { return m_other_type; } 732 733 void replay_into (replayer *) FINAL OVERRIDE; 734 735private: 736 string * make_debug_string () FINAL OVERRIDE; 737 void write_reproducer (reproducer &r) FINAL OVERRIDE; 738}; 739 740/* Result of "gcc_jit_type_get_volatile". */ 741class memento_of_get_volatile : public decorated_type 742{ 743public: 744 memento_of_get_volatile (type *other_type) 745 : decorated_type (other_type) {} 746 747 virtual bool is_same_type_as (type *other) 748 { 749 if (!other->is_volatile ()) 750 return false; 751 return m_other_type->is_same_type_as (other->is_volatile ()); 752 } 753 754 /* Strip off the "volatile", giving the underlying type. */ 755 type *unqualified () FINAL OVERRIDE { return m_other_type; } 756 757 virtual type *is_volatile () { return m_other_type; } 758 759 void replay_into (replayer *) FINAL OVERRIDE; 760 761private: 762 string * make_debug_string () FINAL OVERRIDE; 763 void write_reproducer (reproducer &r) FINAL OVERRIDE; 764}; 765 766/* Result of "gcc_jit_type_get_aligned". */ 767class memento_of_get_aligned : public decorated_type 768{ 769public: 770 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes) 771 : decorated_type (other_type), 772 m_alignment_in_bytes (alignment_in_bytes) {} 773 774 /* Strip off the alignment, giving the underlying type. */ 775 type *unqualified () FINAL OVERRIDE { return m_other_type; } 776 777 void replay_into (replayer *) FINAL OVERRIDE; 778 779private: 780 string * make_debug_string () FINAL OVERRIDE; 781 void write_reproducer (reproducer &r) FINAL OVERRIDE; 782 783private: 784 size_t m_alignment_in_bytes; 785}; 786 787/* Result of "gcc_jit_type_get_vector". */ 788class vector_type : public decorated_type 789{ 790public: 791 vector_type (type *other_type, size_t num_units) 792 : decorated_type (other_type), 793 m_num_units (num_units) {} 794 795 size_t get_num_units () const { return m_num_units; } 796 797 vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; } 798 799 type *get_element_type () { return m_other_type; } 800 801 void replay_into (replayer *) FINAL OVERRIDE; 802 803 vector_type *is_vector () FINAL OVERRIDE { return this; } 804 805private: 806 string * make_debug_string () FINAL OVERRIDE; 807 void write_reproducer (reproducer &r) FINAL OVERRIDE; 808 809private: 810 size_t m_num_units; 811}; 812 813class array_type : public type 814{ 815 public: 816 array_type (context *ctxt, 817 location *loc, 818 type *element_type, 819 int num_elements) 820 : type (ctxt), 821 m_loc (loc), 822 m_element_type (element_type), 823 m_num_elements (num_elements) 824 {} 825 826 type *dereference () FINAL OVERRIDE; 827 828 bool is_int () const FINAL OVERRIDE { return false; } 829 bool is_float () const FINAL OVERRIDE { return false; } 830 bool is_bool () const FINAL OVERRIDE { return false; } 831 type *is_pointer () FINAL OVERRIDE { return NULL; } 832 type *is_array () FINAL OVERRIDE { return m_element_type; } 833 int num_elements () { return m_num_elements; } 834 bool is_signed () const FINAL OVERRIDE { return false; } 835 836 void replay_into (replayer *) FINAL OVERRIDE; 837 838 private: 839 string * make_debug_string () FINAL OVERRIDE; 840 void write_reproducer (reproducer &r) FINAL OVERRIDE; 841 842 private: 843 location *m_loc; 844 type *m_element_type; 845 int m_num_elements; 846}; 847 848class function_type : public type 849{ 850public: 851 function_type (context *ctxt, 852 type *return_type, 853 int num_params, 854 type **param_types, 855 int is_variadic); 856 857 type *dereference () FINAL OVERRIDE; 858 function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; } 859 function_type *as_a_function_type () FINAL OVERRIDE { return this; } 860 861 bool is_same_type_as (type *other) FINAL OVERRIDE; 862 863 bool is_int () const FINAL OVERRIDE { return false; } 864 bool is_float () const FINAL OVERRIDE { return false; } 865 bool is_bool () const FINAL OVERRIDE { return false; } 866 type *is_pointer () FINAL OVERRIDE { return NULL; } 867 type *is_array () FINAL OVERRIDE { return NULL; } 868 bool is_signed () const FINAL OVERRIDE { return false; } 869 870 void replay_into (replayer *) FINAL OVERRIDE; 871 872 type * get_return_type () const { return m_return_type; } 873 const vec<type *> &get_param_types () const { return m_param_types; } 874 int is_variadic () const { return m_is_variadic; } 875 876 string * make_debug_string_with_ptr (); 877 878 void 879 write_deferred_reproducer (reproducer &r, 880 memento *ptr_type); 881 882 private: 883 string * make_debug_string () FINAL OVERRIDE; 884 string * make_debug_string_with (const char *); 885 void write_reproducer (reproducer &r) FINAL OVERRIDE; 886 887private: 888 type *m_return_type; 889 auto_vec<type *> m_param_types; 890 int m_is_variadic; 891}; 892 893class field : public memento 894{ 895public: 896 field (context *ctxt, 897 location *loc, 898 type *type, 899 string *name) 900 : memento (ctxt), 901 m_loc (loc), 902 m_type (type), 903 m_name (name), 904 m_container (NULL) 905 {} 906 907 type * get_type () const { return m_type; } 908 909 compound_type * get_container () const { return m_container; } 910 void set_container (compound_type *c) { m_container = c; } 911 912 void replay_into (replayer *) OVERRIDE; 913 914 void write_to_dump (dump &d) OVERRIDE; 915 916 playback::field * 917 playback_field () const 918 { 919 return static_cast <playback::field *> (m_playback_obj); 920 } 921 922private: 923 string * make_debug_string () OVERRIDE; 924 void write_reproducer (reproducer &r) OVERRIDE; 925 926protected: 927 location *m_loc; 928 type *m_type; 929 string *m_name; 930 compound_type *m_container; 931}; 932 933 934class bitfield : public field 935{ 936public: 937 bitfield (context *ctxt, 938 location *loc, 939 type *type, 940 int width, 941 string *name) 942 : field (ctxt, loc, type, name), 943 m_width (width) 944 {} 945 946 void replay_into (replayer *) FINAL OVERRIDE; 947 948 void write_to_dump (dump &d) FINAL OVERRIDE; 949 950private: 951 string * make_debug_string () FINAL OVERRIDE; 952 void write_reproducer (reproducer &r) FINAL OVERRIDE; 953 954private: 955 int m_width; 956}; 957 958/* Base class for struct_ and union_ */ 959class compound_type : public type 960{ 961public: 962 compound_type (context *ctxt, 963 location *loc, 964 string *name); 965 966 string *get_name () const { return m_name; } 967 location *get_loc () const { return m_loc; } 968 fields * get_fields () { return m_fields; } 969 970 void 971 set_fields (location *loc, 972 int num_fields, 973 field **fields); 974 975 type *dereference () FINAL OVERRIDE; 976 977 bool is_int () const FINAL OVERRIDE { return false; } 978 bool is_float () const FINAL OVERRIDE { return false; } 979 bool is_bool () const FINAL OVERRIDE { return false; } 980 type *is_pointer () FINAL OVERRIDE { return NULL; } 981 type *is_array () FINAL OVERRIDE { return NULL; } 982 bool is_signed () const FINAL OVERRIDE { return false; } 983 984 bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; } 985 986 playback::compound_type * 987 playback_compound_type () 988 { 989 return static_cast <playback::compound_type *> (m_playback_obj); 990 } 991 992private: 993 location *m_loc; 994 string *m_name; 995 fields *m_fields; 996}; 997 998class struct_ : public compound_type 999{ 1000public: 1001 struct_ (context *ctxt, 1002 location *loc, 1003 string *name); 1004 1005 struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; } 1006 1007 type * 1008 as_type () { return this; } 1009 1010 void replay_into (replayer *r) FINAL OVERRIDE; 1011 1012 const char *access_as_type (reproducer &r) FINAL OVERRIDE; 1013 1014 struct_ *is_struct () FINAL OVERRIDE { return this; } 1015 1016private: 1017 string * make_debug_string () FINAL OVERRIDE; 1018 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1019}; 1020 1021// memento of struct_::set_fields 1022class fields : public memento 1023{ 1024public: 1025 fields (compound_type *struct_or_union, 1026 int num_fields, 1027 field **fields); 1028 1029 void replay_into (replayer *r) FINAL OVERRIDE; 1030 1031 void write_to_dump (dump &d) FINAL OVERRIDE; 1032 1033 int length () const { return m_fields.length (); } 1034 field *get_field (int i) const { return m_fields[i]; } 1035 1036private: 1037 string * make_debug_string () FINAL OVERRIDE; 1038 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1039 1040private: 1041 compound_type *m_struct_or_union; 1042 auto_vec<field *> m_fields; 1043}; 1044 1045class union_ : public compound_type 1046{ 1047public: 1048 union_ (context *ctxt, 1049 location *loc, 1050 string *name); 1051 1052 void replay_into (replayer *r) FINAL OVERRIDE; 1053 1054 virtual bool is_union () const FINAL OVERRIDE { return true; } 1055 1056private: 1057 string * make_debug_string () FINAL OVERRIDE; 1058 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1059}; 1060 1061/* An abstract base class for operations that visit all rvalues within an 1062 expression tree. 1063 Currently the only implementation is class rvalue_usage_validator within 1064 jit-recording.cc. */ 1065 1066class rvalue_visitor 1067{ 1068 public: 1069 virtual ~rvalue_visitor () {} 1070 virtual void visit (rvalue *rvalue) = 0; 1071}; 1072 1073/* When generating debug strings for rvalues we mimic C, so we need to 1074 mimic C's precedence levels when handling compound expressions. 1075 These are in order from strongest precedence to weakest. */ 1076enum precedence 1077{ 1078 PRECEDENCE_PRIMARY, 1079 PRECEDENCE_POSTFIX, 1080 PRECEDENCE_UNARY, 1081 PRECEDENCE_CAST, 1082 PRECEDENCE_MULTIPLICATIVE, 1083 PRECEDENCE_ADDITIVE, 1084 PRECEDENCE_SHIFT, 1085 PRECEDENCE_RELATIONAL, 1086 PRECEDENCE_EQUALITY, 1087 PRECEDENCE_BITWISE_AND, 1088 PRECEDENCE_BITWISE_XOR, 1089 PRECEDENCE_BITWISE_IOR, 1090 PRECEDENCE_LOGICAL_AND, 1091 PRECEDENCE_LOGICAL_OR 1092}; 1093 1094class rvalue : public memento 1095{ 1096public: 1097 rvalue (context *ctxt, 1098 location *loc, 1099 type *type_) 1100 : memento (ctxt), 1101 m_loc (loc), 1102 m_type (type_), 1103 m_scope (NULL), 1104 m_parenthesized_string (NULL) 1105 { 1106 gcc_assert (type_); 1107 } 1108 1109 location * get_loc () const { return m_loc; } 1110 1111 /* Get the recording::type of this rvalue. 1112 1113 Implements the post-error-checking part of 1114 gcc_jit_rvalue_get_type. */ 1115 type * get_type () const { return m_type; } 1116 1117 playback::rvalue * 1118 playback_rvalue () const 1119 { 1120 return static_cast <playback::rvalue *> (m_playback_obj); 1121 } 1122 rvalue * 1123 access_field (location *loc, 1124 field *field); 1125 1126 lvalue * 1127 dereference_field (location *loc, 1128 field *field); 1129 1130 lvalue * 1131 dereference (location *loc); 1132 1133 void 1134 verify_valid_within_stmt (const char *api_funcname, statement *s); 1135 1136 virtual void visit_children (rvalue_visitor *v) = 0; 1137 1138 void set_scope (function *scope); 1139 function *get_scope () const { return m_scope; } 1140 1141 /* Dynamic casts. */ 1142 virtual param *dyn_cast_param () { return NULL; } 1143 virtual base_call *dyn_cast_base_call () { return NULL; } 1144 1145 virtual const char *access_as_rvalue (reproducer &r); 1146 1147 /* Get the debug string, wrapped in parentheses. */ 1148 const char * 1149 get_debug_string_parens (enum precedence outer_prec); 1150 1151 virtual bool is_constant () const { return false; } 1152 virtual bool get_wide_int (wide_int *) const { return false; } 1153 1154private: 1155 virtual enum precedence get_precedence () const = 0; 1156 1157protected: 1158 location *m_loc; 1159 type *m_type; 1160 1161 private: 1162 function *m_scope; /* NULL for globals, non-NULL for locals/params */ 1163 string *m_parenthesized_string; 1164}; 1165 1166class lvalue : public rvalue 1167{ 1168public: 1169 lvalue (context *ctxt, 1170 location *loc, 1171 type *type_) 1172 : rvalue (ctxt, loc, type_), 1173 m_link_section (NULL), 1174 m_reg_name (NULL), 1175 m_tls_model (GCC_JIT_TLS_MODEL_NONE), 1176 m_alignment (0) 1177 {} 1178 1179 playback::lvalue * 1180 playback_lvalue () const 1181 { 1182 return static_cast <playback::lvalue *> (m_playback_obj); 1183 } 1184 1185 lvalue * 1186 access_field (location *loc, 1187 field *field); 1188 1189 rvalue * 1190 get_address (location *loc); 1191 1192 rvalue * 1193 as_rvalue () { return this; } 1194 1195 const char *access_as_rvalue (reproducer &r) OVERRIDE; 1196 virtual const char *access_as_lvalue (reproducer &r); 1197 virtual bool is_global () const { return false; } 1198 void set_tls_model (enum gcc_jit_tls_model model); 1199 void set_link_section (const char *name); 1200 void set_register_name (const char *reg_name); 1201 void set_alignment (unsigned bytes); 1202 unsigned get_alignment () const { return m_alignment; } 1203 1204protected: 1205 string *m_link_section; 1206 string *m_reg_name; 1207 enum gcc_jit_tls_model m_tls_model; 1208 unsigned m_alignment; 1209}; 1210 1211class param : public lvalue 1212{ 1213public: 1214 param (context *ctxt, 1215 location *loc, 1216 type *type, 1217 string *name) 1218 : lvalue (ctxt, loc, type), 1219 m_name (name) {} 1220 1221 lvalue * 1222 as_lvalue () { return this; } 1223 1224 void replay_into (replayer *r) FINAL OVERRIDE; 1225 1226 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1227 1228 playback::param * 1229 playback_param () const 1230 { 1231 return static_cast <playback::param *> (m_playback_obj); 1232 } 1233 1234 param *dyn_cast_param () FINAL OVERRIDE { return this; } 1235 1236 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE; 1237 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE; 1238 1239private: 1240 string * make_debug_string () FINAL OVERRIDE { return m_name; } 1241 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1242 enum precedence get_precedence () const FINAL OVERRIDE 1243 { 1244 return PRECEDENCE_PRIMARY; 1245 } 1246 1247private: 1248 string *m_name; 1249}; 1250 1251class function : public memento 1252{ 1253public: 1254 function (context *ctxt, 1255 location *loc, 1256 enum gcc_jit_function_kind kind, 1257 type *return_type, 1258 string *name, 1259 int num_params, 1260 param **params, 1261 int is_variadic, 1262 enum built_in_function builtin_id); 1263 1264 void replay_into (replayer *r) FINAL OVERRIDE; 1265 1266 playback::function * 1267 playback_function () const 1268 { 1269 return static_cast <playback::function *> (m_playback_obj); 1270 } 1271 1272 enum gcc_jit_function_kind get_kind () const { return m_kind; } 1273 1274 lvalue * 1275 new_local (location *loc, 1276 type *type, 1277 const char *name); 1278 1279 block* 1280 new_block (const char *name); 1281 1282 location *get_loc () const { return m_loc; } 1283 type *get_return_type () const { return m_return_type; } 1284 string * get_name () const { return m_name; } 1285 const vec<param *> &get_params () const { return m_params; } 1286 1287 /* Get the given param by index. 1288 Implements the post-error-checking part of 1289 gcc_jit_function_get_param. */ 1290 param *get_param (int i) const { return m_params[i]; } 1291 1292 bool is_variadic () const { return m_is_variadic; } 1293 1294 void write_to_dump (dump &d) FINAL OVERRIDE; 1295 1296 void validate (); 1297 1298 void dump_to_dot (const char *path); 1299 1300 rvalue *get_address (location *loc); 1301 1302private: 1303 string * make_debug_string () FINAL OVERRIDE; 1304 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1305 1306private: 1307 location *m_loc; 1308 enum gcc_jit_function_kind m_kind; 1309 type *m_return_type; 1310 string *m_name; 1311 auto_vec<param *> m_params; 1312 int m_is_variadic; 1313 enum built_in_function m_builtin_id; 1314 auto_vec<local *> m_locals; 1315 auto_vec<block *> m_blocks; 1316 type *m_fn_ptr_type; 1317}; 1318 1319class block : public memento 1320{ 1321public: 1322 block (function *func, int index, string *name) 1323 : memento (func->m_ctxt), 1324 m_func (func), 1325 m_index (index), 1326 m_name (name), 1327 m_statements (), 1328 m_has_been_terminated (false), 1329 m_is_reachable (false) 1330 { 1331 } 1332 1333 /* Get the recording::function containing this block. 1334 Implements the post-error-checking part of 1335 gcc_jit_block_get_function. */ 1336 function *get_function () { return m_func; } 1337 1338 bool has_been_terminated () { return m_has_been_terminated; } 1339 bool is_reachable () { return m_is_reachable; } 1340 1341 statement * 1342 add_eval (location *loc, 1343 rvalue *rvalue); 1344 1345 statement * 1346 add_assignment (location *loc, 1347 lvalue *lvalue, 1348 rvalue *rvalue); 1349 1350 statement * 1351 add_assignment_op (location *loc, 1352 lvalue *lvalue, 1353 enum gcc_jit_binary_op op, 1354 rvalue *rvalue); 1355 1356 statement * 1357 add_comment (location *loc, 1358 const char *text); 1359 1360 extended_asm * 1361 add_extended_asm (location *loc, 1362 const char *asm_template); 1363 1364 statement * 1365 end_with_conditional (location *loc, 1366 rvalue *boolval, 1367 block *on_true, 1368 block *on_false); 1369 1370 statement * 1371 end_with_jump (location *loc, 1372 block *target); 1373 1374 statement * 1375 end_with_return (location *loc, 1376 rvalue *rvalue); 1377 1378 statement * 1379 end_with_switch (location *loc, 1380 rvalue *expr, 1381 block *default_block, 1382 int num_cases, 1383 case_ **cases); 1384 1385 extended_asm * 1386 end_with_extended_asm_goto (location *loc, 1387 const char *asm_template, 1388 int num_goto_blocks, 1389 block **goto_blocks, 1390 block *fallthrough_block); 1391 1392 playback::block * 1393 playback_block () const 1394 { 1395 return static_cast <playback::block *> (m_playback_obj); 1396 } 1397 1398 void write_to_dump (dump &d) FINAL OVERRIDE; 1399 1400 bool validate (); 1401 1402 location *get_loc () const; 1403 1404 statement *get_first_statement () const; 1405 statement *get_last_statement () const; 1406 1407 vec <block *> get_successor_blocks () const; 1408 1409private: 1410 string * make_debug_string () FINAL OVERRIDE; 1411 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1412 1413 void replay_into (replayer *r) FINAL OVERRIDE; 1414 1415 void dump_to_dot (pretty_printer *pp); 1416 void dump_edges_to_dot (pretty_printer *pp); 1417 1418private: 1419 function *m_func; 1420 int m_index; 1421 string *m_name; 1422 auto_vec<statement *> m_statements; 1423 bool m_has_been_terminated; 1424 bool m_is_reachable; 1425 1426 friend class function; 1427}; 1428 1429class global : public lvalue 1430{ 1431public: 1432 global (context *ctxt, 1433 location *loc, 1434 enum gcc_jit_global_kind kind, 1435 type *type, 1436 string *name) 1437 : lvalue (ctxt, loc, type), 1438 m_kind (kind), 1439 m_name (name) 1440 { 1441 m_initializer = NULL; 1442 m_initializer_num_bytes = 0; 1443 } 1444 ~global () 1445 { 1446 free (m_initializer); 1447 } 1448 1449 void replay_into (replayer *) FINAL OVERRIDE; 1450 1451 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1452 1453 void write_to_dump (dump &d) FINAL OVERRIDE; 1454 1455 bool is_global () const FINAL OVERRIDE { return true; } 1456 1457 void 1458 set_initializer (const void *initializer, 1459 size_t num_bytes) 1460 { 1461 if (m_initializer) 1462 free (m_initializer); 1463 m_initializer = xmalloc (num_bytes); 1464 memcpy (m_initializer, initializer, num_bytes); 1465 m_initializer_num_bytes = num_bytes; 1466 } 1467 1468 void set_flags (int flag_fields) 1469 { 1470 m_flags = (enum global_var_flags)(m_flags | flag_fields); 1471 } 1472 /* Returns true if any of the flags in the argument is set. */ 1473 bool test_flags_anyof (int flag_fields) const 1474 { 1475 return m_flags & flag_fields; 1476 } 1477 1478 enum gcc_jit_global_kind get_kind () const 1479 { 1480 return m_kind; 1481 } 1482 1483 void set_rvalue_init (rvalue *val) { m_rvalue_init = val; } 1484 1485private: 1486 string * make_debug_string () FINAL OVERRIDE { return m_name; } 1487 template <typename T> 1488 void write_initializer_reproducer (const char *id, reproducer &r); 1489 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1490 enum precedence get_precedence () const FINAL OVERRIDE 1491 { 1492 return PRECEDENCE_PRIMARY; 1493 } 1494 1495private: 1496 enum gcc_jit_global_kind m_kind; 1497 enum global_var_flags m_flags = GLOBAL_VAR_FLAGS_NONE; 1498 string *m_name; 1499 void *m_initializer; 1500 rvalue *m_rvalue_init = nullptr; /* Only needed for write_dump. */ 1501 size_t m_initializer_num_bytes; 1502}; 1503 1504template <typename HOST_TYPE> 1505class memento_of_new_rvalue_from_const : public rvalue 1506{ 1507public: 1508 memento_of_new_rvalue_from_const (context *ctxt, 1509 location *loc, 1510 type *type, 1511 HOST_TYPE value) 1512 : rvalue (ctxt, loc, type), 1513 m_value (value) {} 1514 1515 void replay_into (replayer *r) FINAL OVERRIDE; 1516 1517 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1518 1519 bool is_constant () const FINAL OVERRIDE { return true; } 1520 1521 bool get_wide_int (wide_int *out) const FINAL OVERRIDE; 1522 1523private: 1524 string * make_debug_string () FINAL OVERRIDE; 1525 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1526 enum precedence get_precedence () const FINAL OVERRIDE 1527 { 1528 return PRECEDENCE_PRIMARY; 1529 } 1530 1531private: 1532 HOST_TYPE m_value; 1533}; 1534 1535class memento_of_new_string_literal : public rvalue 1536{ 1537public: 1538 memento_of_new_string_literal (context *ctxt, 1539 location *loc, 1540 string *value) 1541 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)), 1542 m_value (value) {} 1543 1544 void replay_into (replayer *r) FINAL OVERRIDE; 1545 1546 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 1547 1548private: 1549 string * make_debug_string () FINAL OVERRIDE; 1550 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1551 enum precedence get_precedence () const FINAL OVERRIDE 1552 { 1553 return PRECEDENCE_PRIMARY; 1554 } 1555 1556private: 1557 string *m_value; 1558}; 1559 1560class memento_of_new_rvalue_from_vector : public rvalue 1561{ 1562public: 1563 memento_of_new_rvalue_from_vector (context *ctxt, 1564 location *loc, 1565 vector_type *type, 1566 rvalue **elements); 1567 1568 void replay_into (replayer *r) FINAL OVERRIDE; 1569 1570 void visit_children (rvalue_visitor *) FINAL OVERRIDE; 1571 1572private: 1573 string * make_debug_string () FINAL OVERRIDE; 1574 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1575 enum precedence get_precedence () const FINAL OVERRIDE 1576 { 1577 return PRECEDENCE_PRIMARY; 1578 } 1579 1580private: 1581 vector_type *m_vector_type; 1582 auto_vec<rvalue *> m_elements; 1583}; 1584 1585class ctor : public rvalue 1586{ 1587public: 1588 ctor (context *ctxt, 1589 location *loc, 1590 type *type) 1591 : rvalue (ctxt, loc, type) 1592 { } 1593 1594 void replay_into (replayer *r) FINAL OVERRIDE; 1595 1596 void visit_children (rvalue_visitor *) FINAL OVERRIDE; 1597 1598private: 1599 string * make_debug_string () FINAL OVERRIDE; 1600 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1601 enum precedence get_precedence () const FINAL OVERRIDE 1602 { 1603 return PRECEDENCE_PRIMARY; 1604 } 1605 1606public: 1607 auto_vec<field *> m_fields; 1608 auto_vec<rvalue *> m_values; 1609}; 1610 1611class unary_op : public rvalue 1612{ 1613public: 1614 unary_op (context *ctxt, 1615 location *loc, 1616 enum gcc_jit_unary_op op, 1617 type *result_type, 1618 rvalue *a) 1619 : rvalue (ctxt, loc, result_type), 1620 m_op (op), 1621 m_a (a) 1622 {} 1623 1624 void replay_into (replayer *r) FINAL OVERRIDE; 1625 1626 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1627 1628private: 1629 string * make_debug_string () FINAL OVERRIDE; 1630 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1631 enum precedence get_precedence () const FINAL OVERRIDE 1632 { 1633 return PRECEDENCE_UNARY; 1634 } 1635 1636private: 1637 enum gcc_jit_unary_op m_op; 1638 rvalue *m_a; 1639}; 1640 1641class binary_op : public rvalue 1642{ 1643public: 1644 binary_op (context *ctxt, 1645 location *loc, 1646 enum gcc_jit_binary_op op, 1647 type *result_type, 1648 rvalue *a, rvalue *b) 1649 : rvalue (ctxt, loc, result_type), 1650 m_op (op), 1651 m_a (a), 1652 m_b (b) {} 1653 1654 void replay_into (replayer *r) FINAL OVERRIDE; 1655 1656 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1657 1658private: 1659 string * make_debug_string () FINAL OVERRIDE; 1660 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1661 enum precedence get_precedence () const FINAL OVERRIDE; 1662 1663private: 1664 enum gcc_jit_binary_op m_op; 1665 rvalue *m_a; 1666 rvalue *m_b; 1667}; 1668 1669class comparison : public rvalue 1670{ 1671public: 1672 comparison (context *ctxt, 1673 location *loc, 1674 enum gcc_jit_comparison op, 1675 rvalue *a, rvalue *b) 1676 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)), 1677 m_op (op), 1678 m_a (a), 1679 m_b (b) 1680 {} 1681 1682 void replay_into (replayer *r) FINAL OVERRIDE; 1683 1684 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1685 1686private: 1687 string * make_debug_string () FINAL OVERRIDE; 1688 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1689 enum precedence get_precedence () const FINAL OVERRIDE; 1690 1691private: 1692 enum gcc_jit_comparison m_op; 1693 rvalue *m_a; 1694 rvalue *m_b; 1695}; 1696 1697class cast : public rvalue 1698{ 1699public: 1700 cast (context *ctxt, 1701 location *loc, 1702 rvalue *a, 1703 type *type_) 1704 : rvalue (ctxt, loc, type_), 1705 m_rvalue (a) 1706 {} 1707 1708 void replay_into (replayer *r) FINAL OVERRIDE; 1709 1710 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1711 1712private: 1713 string * make_debug_string () FINAL OVERRIDE; 1714 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1715 enum precedence get_precedence () const FINAL OVERRIDE 1716 { 1717 return PRECEDENCE_CAST; 1718 } 1719 1720private: 1721 rvalue *m_rvalue; 1722}; 1723 1724class bitcast : public rvalue 1725{ 1726public: 1727 bitcast (context *ctxt, 1728 location *loc, 1729 rvalue *a, 1730 type *type_) 1731 : rvalue (ctxt, loc, type_), 1732 m_rvalue (a) 1733 {} 1734 1735 void replay_into (replayer *r) FINAL OVERRIDE; 1736 1737 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1738 1739private: 1740 string * make_debug_string () FINAL OVERRIDE; 1741 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1742 enum precedence get_precedence () const FINAL OVERRIDE 1743 { 1744 return PRECEDENCE_CAST; 1745 } 1746 1747private: 1748 rvalue *m_rvalue; 1749}; 1750 1751class base_call : public rvalue 1752{ 1753 public: 1754 base_call (context *ctxt, 1755 location *loc, 1756 type *type_, 1757 int numargs, 1758 rvalue **args); 1759 1760 enum precedence get_precedence () const FINAL OVERRIDE 1761 { 1762 return PRECEDENCE_POSTFIX; 1763 } 1764 1765 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; } 1766 1767 void set_require_tail_call (bool require_tail_call) 1768 { 1769 m_require_tail_call = require_tail_call; 1770 } 1771 1772 protected: 1773 void write_reproducer_tail_call (reproducer &r, const char *id); 1774 1775 protected: 1776 auto_vec<rvalue *> m_args; 1777 bool m_require_tail_call; 1778}; 1779 1780class call : public base_call 1781{ 1782public: 1783 call (context *ctxt, 1784 location *loc, 1785 function *func, 1786 int numargs, 1787 rvalue **args); 1788 1789 void replay_into (replayer *r) FINAL OVERRIDE; 1790 1791 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1792 1793private: 1794 string * make_debug_string () FINAL OVERRIDE; 1795 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1796 1797private: 1798 function *m_func; 1799}; 1800 1801class call_through_ptr : public base_call 1802{ 1803public: 1804 call_through_ptr (context *ctxt, 1805 location *loc, 1806 rvalue *fn_ptr, 1807 int numargs, 1808 rvalue **args); 1809 1810 void replay_into (replayer *r) FINAL OVERRIDE; 1811 1812 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1813 1814private: 1815 string * make_debug_string () FINAL OVERRIDE; 1816 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1817 1818private: 1819 rvalue *m_fn_ptr; 1820}; 1821 1822class array_access : public lvalue 1823{ 1824public: 1825 array_access (context *ctxt, 1826 location *loc, 1827 rvalue *ptr, 1828 rvalue *index) 1829 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()), 1830 m_ptr (ptr), 1831 m_index (index) 1832 {} 1833 1834 void replay_into (replayer *r) FINAL OVERRIDE; 1835 1836 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1837 1838private: 1839 string * make_debug_string () FINAL OVERRIDE; 1840 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1841 enum precedence get_precedence () const FINAL OVERRIDE 1842 { 1843 return PRECEDENCE_POSTFIX; 1844 } 1845 1846private: 1847 rvalue *m_ptr; 1848 rvalue *m_index; 1849}; 1850 1851class access_field_of_lvalue : public lvalue 1852{ 1853public: 1854 access_field_of_lvalue (context *ctxt, 1855 location *loc, 1856 lvalue *val, 1857 field *field) 1858 : lvalue (ctxt, loc, field->get_type ()), 1859 m_lvalue (val), 1860 m_field (field) 1861 {} 1862 1863 void replay_into (replayer *r) FINAL OVERRIDE; 1864 1865 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1866 1867private: 1868 string * make_debug_string () FINAL OVERRIDE; 1869 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1870 enum precedence get_precedence () const FINAL OVERRIDE 1871 { 1872 return PRECEDENCE_POSTFIX; 1873 } 1874 1875private: 1876 lvalue *m_lvalue; 1877 field *m_field; 1878}; 1879 1880class access_field_rvalue : public rvalue 1881{ 1882public: 1883 access_field_rvalue (context *ctxt, 1884 location *loc, 1885 rvalue *val, 1886 field *field) 1887 : rvalue (ctxt, loc, field->get_type ()), 1888 m_rvalue (val), 1889 m_field (field) 1890 {} 1891 1892 void replay_into (replayer *r) FINAL OVERRIDE; 1893 1894 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1895 1896private: 1897 string * make_debug_string () FINAL OVERRIDE; 1898 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1899 enum precedence get_precedence () const FINAL OVERRIDE 1900 { 1901 return PRECEDENCE_POSTFIX; 1902 } 1903 1904private: 1905 rvalue *m_rvalue; 1906 field *m_field; 1907}; 1908 1909class dereference_field_rvalue : public lvalue 1910{ 1911public: 1912 dereference_field_rvalue (context *ctxt, 1913 location *loc, 1914 rvalue *val, 1915 field *field) 1916 : lvalue (ctxt, loc, field->get_type ()), 1917 m_rvalue (val), 1918 m_field (field) 1919 {} 1920 1921 void replay_into (replayer *r) FINAL OVERRIDE; 1922 1923 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1924 1925private: 1926 string * make_debug_string () FINAL OVERRIDE; 1927 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1928 enum precedence get_precedence () const FINAL OVERRIDE 1929 { 1930 return PRECEDENCE_POSTFIX; 1931 } 1932 1933private: 1934 rvalue *m_rvalue; 1935 field *m_field; 1936}; 1937 1938class dereference_rvalue : public lvalue 1939{ 1940public: 1941 dereference_rvalue (context *ctxt, 1942 location *loc, 1943 rvalue *val) 1944 : lvalue (ctxt, loc, val->get_type ()->dereference ()), 1945 m_rvalue (val) {} 1946 1947 void replay_into (replayer *r) FINAL OVERRIDE; 1948 1949 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1950 1951private: 1952 string * make_debug_string () FINAL OVERRIDE; 1953 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1954 enum precedence get_precedence () const FINAL OVERRIDE 1955 { 1956 return PRECEDENCE_UNARY; 1957 } 1958 1959private: 1960 rvalue *m_rvalue; 1961}; 1962 1963class get_address_of_lvalue : public rvalue 1964{ 1965public: 1966 get_address_of_lvalue (context *ctxt, 1967 location *loc, 1968 lvalue *val) 1969 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()), 1970 m_lvalue (val) 1971 {} 1972 1973 void replay_into (replayer *r) FINAL OVERRIDE; 1974 1975 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 1976 1977private: 1978 string * make_debug_string () FINAL OVERRIDE; 1979 void write_reproducer (reproducer &r) FINAL OVERRIDE; 1980 enum precedence get_precedence () const FINAL OVERRIDE 1981 { 1982 return PRECEDENCE_UNARY; 1983 } 1984 1985private: 1986 lvalue *m_lvalue; 1987}; 1988 1989class function_pointer : public rvalue 1990{ 1991public: 1992 function_pointer (context *ctxt, 1993 location *loc, 1994 function *fn, 1995 type *type) 1996 : rvalue (ctxt, loc, type), 1997 m_fn (fn) {} 1998 1999 void replay_into (replayer *r) FINAL OVERRIDE; 2000 2001 void visit_children (rvalue_visitor *v) FINAL OVERRIDE; 2002 2003private: 2004 string * make_debug_string () FINAL OVERRIDE; 2005 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2006 enum precedence get_precedence () const FINAL OVERRIDE 2007 { 2008 return PRECEDENCE_UNARY; 2009 } 2010 2011private: 2012 function *m_fn; 2013}; 2014 2015class local : public lvalue 2016{ 2017public: 2018 local (function *func, location *loc, type *type_, string *name) 2019 : lvalue (func->m_ctxt, loc, type_), 2020 m_func (func), 2021 m_name (name) 2022 { 2023 set_scope (func); 2024 } 2025 2026 void replay_into (replayer *r) FINAL OVERRIDE; 2027 2028 void visit_children (rvalue_visitor *) FINAL OVERRIDE {} 2029 2030 void write_to_dump (dump &d) FINAL OVERRIDE; 2031 2032private: 2033 string * make_debug_string () FINAL OVERRIDE { return m_name; } 2034 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2035 enum precedence get_precedence () const FINAL OVERRIDE 2036 { 2037 return PRECEDENCE_PRIMARY; 2038 } 2039 2040private: 2041 function *m_func; 2042 string *m_name; 2043}; 2044 2045class statement : public memento 2046{ 2047public: 2048 virtual vec <block *> get_successor_blocks () const; 2049 2050 void write_to_dump (dump &d) FINAL OVERRIDE; 2051 2052 block *get_block () const { return m_block; } 2053 location *get_loc () const { return m_loc; } 2054 2055protected: 2056 statement (block *b, location *loc) 2057 : memento (b->m_ctxt), 2058 m_block (b), 2059 m_loc (loc) {} 2060 2061 playback::location * 2062 playback_location (replayer *r) const 2063 { 2064 return ::gcc::jit::recording::playback_location (r, m_loc); 2065 } 2066 2067private: 2068 block *m_block; 2069 location *m_loc; 2070}; 2071 2072class eval : public statement 2073{ 2074public: 2075 eval (block *b, 2076 location *loc, 2077 rvalue *rvalue) 2078 : statement (b, loc), 2079 m_rvalue (rvalue) {} 2080 2081 void replay_into (replayer *r) FINAL OVERRIDE; 2082 2083private: 2084 string * make_debug_string () FINAL OVERRIDE; 2085 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2086 2087private: 2088 rvalue *m_rvalue; 2089}; 2090 2091class assignment : public statement 2092{ 2093public: 2094 assignment (block *b, 2095 location *loc, 2096 lvalue *lvalue, 2097 rvalue *rvalue) 2098 : statement (b, loc), 2099 m_lvalue (lvalue), 2100 m_rvalue (rvalue) {} 2101 2102 void replay_into (replayer *r) FINAL OVERRIDE; 2103 2104private: 2105 string * make_debug_string () FINAL OVERRIDE; 2106 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2107 2108private: 2109 lvalue *m_lvalue; 2110 rvalue *m_rvalue; 2111}; 2112 2113class assignment_op : public statement 2114{ 2115public: 2116 assignment_op (block *b, 2117 location *loc, 2118 lvalue *lvalue, 2119 enum gcc_jit_binary_op op, 2120 rvalue *rvalue) 2121 : statement (b, loc), 2122 m_lvalue (lvalue), 2123 m_op (op), 2124 m_rvalue (rvalue) {} 2125 2126 void replay_into (replayer *r) FINAL OVERRIDE; 2127 2128private: 2129 string * make_debug_string () FINAL OVERRIDE; 2130 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2131 2132private: 2133 lvalue *m_lvalue; 2134 enum gcc_jit_binary_op m_op; 2135 rvalue *m_rvalue; 2136}; 2137 2138class comment : public statement 2139{ 2140public: 2141 comment (block *b, 2142 location *loc, 2143 string *text) 2144 : statement (b, loc), 2145 m_text (text) {} 2146 2147 void replay_into (replayer *r) FINAL OVERRIDE; 2148 2149private: 2150 string * make_debug_string () FINAL OVERRIDE; 2151 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2152 2153private: 2154 string *m_text; 2155}; 2156 2157class conditional : public statement 2158{ 2159public: 2160 conditional (block *b, 2161 location *loc, 2162 rvalue *boolval, 2163 block *on_true, 2164 block *on_false) 2165 : statement (b, loc), 2166 m_boolval (boolval), 2167 m_on_true (on_true), 2168 m_on_false (on_false) {} 2169 2170 void replay_into (replayer *r) FINAL OVERRIDE; 2171 2172 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2173 2174private: 2175 string * make_debug_string () FINAL OVERRIDE; 2176 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2177 2178private: 2179 rvalue *m_boolval; 2180 block *m_on_true; 2181 block *m_on_false; 2182}; 2183 2184class jump : public statement 2185{ 2186public: 2187 jump (block *b, 2188 location *loc, 2189 block *target) 2190 : statement (b, loc), 2191 m_target (target) {} 2192 2193 void replay_into (replayer *r) FINAL OVERRIDE; 2194 2195 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2196 2197private: 2198 string * make_debug_string () FINAL OVERRIDE; 2199 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2200 2201private: 2202 block *m_target; 2203}; 2204 2205class return_ : public statement 2206{ 2207public: 2208 return_ (block *b, 2209 location *loc, 2210 rvalue *rvalue) 2211 : statement (b, loc), 2212 m_rvalue (rvalue) {} 2213 2214 void replay_into (replayer *r) FINAL OVERRIDE; 2215 2216 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2217 2218private: 2219 string * make_debug_string () FINAL OVERRIDE; 2220 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2221 2222private: 2223 rvalue *m_rvalue; 2224}; 2225 2226class case_ : public memento 2227{ 2228 public: 2229 case_ (context *ctxt, 2230 rvalue *min_value, 2231 rvalue *max_value, 2232 block *dest_block) 2233 : memento (ctxt), 2234 m_min_value (min_value), 2235 m_max_value (max_value), 2236 m_dest_block (dest_block) 2237 {} 2238 2239 rvalue *get_min_value () const { return m_min_value; } 2240 rvalue *get_max_value () const { return m_max_value; } 2241 block *get_dest_block () const { return m_dest_block; } 2242 2243 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ } 2244 2245 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2246 2247private: 2248 string * make_debug_string () FINAL OVERRIDE; 2249 2250 private: 2251 rvalue *m_min_value; 2252 rvalue *m_max_value; 2253 block *m_dest_block; 2254}; 2255 2256class switch_ : public statement 2257{ 2258public: 2259 switch_ (block *b, 2260 location *loc, 2261 rvalue *expr, 2262 block *default_block, 2263 int num_cases, 2264 case_ **cases); 2265 2266 void replay_into (replayer *r) FINAL OVERRIDE; 2267 2268 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2269 2270private: 2271 string * make_debug_string () FINAL OVERRIDE; 2272 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2273 2274private: 2275 rvalue *m_expr; 2276 block *m_default_block; 2277 auto_vec <case_ *> m_cases; 2278}; 2279 2280class asm_operand : public memento 2281{ 2282public: 2283 asm_operand (extended_asm *ext_asm, 2284 string *asm_symbolic_name, 2285 string *constraint); 2286 2287 const char *get_symbolic_name () const 2288 { 2289 if (m_asm_symbolic_name) 2290 return m_asm_symbolic_name->c_str (); 2291 else 2292 return NULL; 2293 } 2294 2295 const char *get_constraint () const 2296 { 2297 return m_constraint->c_str (); 2298 } 2299 2300 virtual void print (pretty_printer *pp) const; 2301 2302private: 2303 string * make_debug_string () FINAL OVERRIDE; 2304 2305protected: 2306 extended_asm *m_ext_asm; 2307 string *m_asm_symbolic_name; 2308 string *m_constraint; 2309}; 2310 2311class output_asm_operand : public asm_operand 2312{ 2313public: 2314 output_asm_operand (extended_asm *ext_asm, 2315 string *asm_symbolic_name, 2316 string *constraint, 2317 lvalue *dest) 2318 : asm_operand (ext_asm, asm_symbolic_name, constraint), 2319 m_dest (dest) 2320 {} 2321 2322 lvalue *get_lvalue () const { return m_dest; } 2323 2324 void replay_into (replayer *) FINAL OVERRIDE {} 2325 2326 void print (pretty_printer *pp) const FINAL OVERRIDE; 2327 2328private: 2329 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2330 2331private: 2332 lvalue *m_dest; 2333}; 2334 2335class input_asm_operand : public asm_operand 2336{ 2337public: 2338 input_asm_operand (extended_asm *ext_asm, 2339 string *asm_symbolic_name, 2340 string *constraint, 2341 rvalue *src) 2342 : asm_operand (ext_asm, asm_symbolic_name, constraint), 2343 m_src (src) 2344 {} 2345 2346 rvalue *get_rvalue () const { return m_src; } 2347 2348 void replay_into (replayer *) FINAL OVERRIDE {} 2349 2350 void print (pretty_printer *pp) const FINAL OVERRIDE; 2351 2352private: 2353 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2354 2355private: 2356 rvalue *m_src; 2357}; 2358 2359/* Abstract base class for extended_asm statements. */ 2360 2361class extended_asm : public statement 2362{ 2363public: 2364 extended_asm (block *b, 2365 location *loc, 2366 string *asm_template) 2367 : statement (b, loc), 2368 m_asm_template (asm_template), 2369 m_is_volatile (false), 2370 m_is_inline (false) 2371 {} 2372 2373 void set_volatile_flag (bool flag) { m_is_volatile = flag; } 2374 void set_inline_flag (bool flag) { m_is_inline = flag; } 2375 2376 void add_output_operand (const char *asm_symbolic_name, 2377 const char *constraint, 2378 lvalue *dest); 2379 void add_input_operand (const char *asm_symbolic_name, 2380 const char *constraint, 2381 rvalue *src); 2382 void add_clobber (const char *victim); 2383 2384 void replay_into (replayer *r) OVERRIDE; 2385 2386 string *get_asm_template () const { return m_asm_template; } 2387 2388 virtual bool is_goto () const = 0; 2389 virtual void maybe_print_gotos (pretty_printer *) const = 0; 2390 2391protected: 2392 void write_flags (reproducer &r); 2393 void write_clobbers (reproducer &r); 2394 2395private: 2396 string * make_debug_string () FINAL OVERRIDE; 2397 virtual void maybe_populate_playback_blocks 2398 (auto_vec <playback::block *> *out) = 0; 2399 2400protected: 2401 string *m_asm_template; 2402 bool m_is_volatile; 2403 bool m_is_inline; 2404 auto_vec<output_asm_operand *> m_output_ops; 2405 auto_vec<input_asm_operand *> m_input_ops; 2406 auto_vec<string *> m_clobbers; 2407}; 2408 2409/* An extended_asm that's not a goto, as created by 2410 gcc_jit_block_add_extended_asm. */ 2411 2412class extended_asm_simple : public extended_asm 2413{ 2414public: 2415 extended_asm_simple (block *b, 2416 location *loc, 2417 string *asm_template) 2418 : extended_asm (b, loc, asm_template) 2419 {} 2420 2421 void write_reproducer (reproducer &r) OVERRIDE; 2422 bool is_goto () const FINAL OVERRIDE { return false; } 2423 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {} 2424 2425private: 2426 void maybe_populate_playback_blocks 2427 (auto_vec <playback::block *> *) FINAL OVERRIDE 2428 {} 2429}; 2430 2431/* An extended_asm that's a asm goto, as created by 2432 gcc_jit_block_end_with_extended_asm_goto. */ 2433 2434class extended_asm_goto : public extended_asm 2435{ 2436public: 2437 extended_asm_goto (block *b, 2438 location *loc, 2439 string *asm_template, 2440 int num_goto_blocks, 2441 block **goto_blocks, 2442 block *fallthrough_block); 2443 2444 void replay_into (replayer *r) FINAL OVERRIDE; 2445 void write_reproducer (reproducer &r) OVERRIDE; 2446 2447 vec <block *> get_successor_blocks () const FINAL OVERRIDE; 2448 2449 bool is_goto () const FINAL OVERRIDE { return true; } 2450 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE; 2451 2452private: 2453 void maybe_populate_playback_blocks 2454 (auto_vec <playback::block *> *out) FINAL OVERRIDE; 2455 2456private: 2457 auto_vec <block *> m_goto_blocks; 2458 block *m_fallthrough_block; 2459}; 2460 2461/* A group of top-level asm statements, as created by 2462 gcc_jit_context_add_top_level_asm. */ 2463 2464class top_level_asm : public memento 2465{ 2466public: 2467 top_level_asm (context *ctxt, location *loc, string *asm_stmts); 2468 2469 void write_to_dump (dump &d) FINAL OVERRIDE; 2470 2471private: 2472 void replay_into (replayer *r) FINAL OVERRIDE; 2473 string * make_debug_string () FINAL OVERRIDE; 2474 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2475 2476private: 2477 location *m_loc; 2478 string *m_asm_stmts; 2479}; 2480 2481class global_init_rvalue : public memento 2482{ 2483public: 2484 global_init_rvalue (context *ctxt, lvalue *variable, rvalue *init) : 2485 memento (ctxt), m_variable (variable), m_init (init) {}; 2486 2487 void write_to_dump (dump &d) FINAL OVERRIDE; 2488 2489private: 2490 void replay_into (replayer *r) FINAL OVERRIDE; 2491 string * make_debug_string () FINAL OVERRIDE; 2492 void write_reproducer (reproducer &r) FINAL OVERRIDE; 2493 2494private: 2495 lvalue *m_variable; 2496 rvalue *m_init; 2497}; 2498 2499} // namespace gcc::jit::recording 2500 2501/* Create a recording::memento_of_new_rvalue_from_const instance and add 2502 it to this context's list of mementos. 2503 2504 Implements the post-error-checking part of 2505 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */ 2506 2507template <typename HOST_TYPE> 2508recording::rvalue * 2509recording::context::new_rvalue_from_const (recording::type *type, 2510 HOST_TYPE value) 2511{ 2512 recording::rvalue *result = 2513 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value); 2514 record (result); 2515 return result; 2516} 2517 2518/* Don't call this directly. Call types_kinda_same. */ 2519bool 2520types_kinda_same_internal (recording::type *a, 2521 recording::type *b); 2522 2523/* Strip all qualifiers and count pointer depth, returning true 2524 if the types and pointer depth are the same, otherwise false. 2525 2526 For array and vector types the number of element also 2527 has to match, aswell as the element types themself. */ 2528static inline bool 2529types_kinda_same (recording::type *a, recording::type *b) 2530{ 2531 /* Handle trivial case here, to allow for inlining. */ 2532 return a == b || types_kinda_same_internal (a, b); 2533} 2534 2535} // namespace gcc::jit 2536 2537} // namespace gcc 2538 2539#endif /* JIT_RECORDING_H */ 2540