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