jit-recording.h revision 1.4
1/* Internals of libgccjit: classes for recording calls made to the JIT API.
2   Copyright (C) 2013-2018 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
33class result;
34class dump;
35class reproducer;
36
37/**********************************************************************
38 Recording.
39 **********************************************************************/
40
41namespace recording {
42
43playback::location *
44playback_location (replayer *r, location *loc);
45
46const char *
47playback_string (string *str);
48
49playback::block *
50playback_block (block *b);
51
52/* A recording of a call to gcc_jit_context_enable_dump.  */
53struct requested_dump
54{
55  const char *m_dumpname;
56  char **m_out_ptr;
57};
58
59/* A JIT-compilation context.  */
60class context : public log_user
61{
62public:
63  context (context *parent_ctxt);
64  ~context ();
65
66  builtins_manager *
67  get_builtins_manager ();
68
69  void record (memento *m);
70  void replay_into (replayer *r);
71  void disassociate_from_playback ();
72
73  string *
74  new_string (const char *text);
75
76  location *
77  new_location (const char *filename,
78		int line,
79		int column,
80		bool created_by_user);
81
82  type *
83  get_type (enum gcc_jit_types type);
84
85  type *
86  get_int_type (int num_bytes, int is_signed);
87
88  type *
89  new_array_type (location *loc,
90		  type *element_type,
91		  int num_elements);
92
93  field *
94  new_field (location *loc,
95	     type *type,
96	     const char *name);
97
98  struct_ *
99  new_struct_type (location *loc,
100		   const char *name);
101
102  union_ *
103  new_union_type (location *loc,
104		  const char *name);
105
106  function_type *
107  new_function_type (type *return_type,
108		     int num_params,
109		     type **param_types,
110		     int is_variadic);
111
112  type *
113  new_function_ptr_type (location *loc,
114			 type *return_type,
115			 int num_params,
116			 type **param_types,
117			 int is_variadic);
118
119  param *
120  new_param (location *loc,
121	     type *type,
122	     const char *name);
123
124  function *
125  new_function (location *loc,
126		enum gcc_jit_function_kind kind,
127		type *return_type,
128		const char *name,
129		int num_params,
130		param **params,
131		int is_variadic,
132		enum built_in_function builtin_id);
133
134  function *
135  get_builtin_function (const char *name);
136
137  lvalue *
138  new_global (location *loc,
139	      enum gcc_jit_global_kind kind,
140	      type *type,
141	      const char *name);
142
143  template <typename HOST_TYPE>
144  rvalue *
145  new_rvalue_from_const (type *type,
146			 HOST_TYPE value);
147
148  rvalue *
149  new_string_literal (const char *value);
150
151  rvalue *
152  new_rvalue_from_vector (location *loc,
153			  vector_type *type,
154			  rvalue **elements);
155
156  rvalue *
157  new_unary_op (location *loc,
158		enum gcc_jit_unary_op op,
159		type *result_type,
160		rvalue *a);
161
162  rvalue *
163  new_binary_op (location *loc,
164		 enum gcc_jit_binary_op op,
165		 type *result_type,
166		 rvalue *a, rvalue *b);
167
168  rvalue *
169  new_comparison (location *loc,
170		  enum gcc_jit_comparison op,
171		  rvalue *a, rvalue *b);
172
173  rvalue *
174  new_call (location *loc,
175	    function *func,
176	    int numargs, rvalue **args);
177
178  rvalue *
179  new_call_through_ptr (location *loc,
180			rvalue *fn_ptr,
181			int numargs, rvalue **args);
182
183  rvalue *
184  new_cast (location *loc,
185	    rvalue *expr,
186	    type *type_);
187
188  lvalue *
189  new_array_access (location *loc,
190		    rvalue *ptr,
191		    rvalue *index);
192
193  case_ *
194  new_case (rvalue *min_value,
195	    rvalue *max_value,
196	    block *block);
197
198  void
199  set_str_option (enum gcc_jit_str_option opt,
200		  const char *value);
201
202  void
203  set_int_option (enum gcc_jit_int_option opt,
204		  int value);
205
206  void
207  set_bool_option (enum gcc_jit_bool_option opt,
208		   int value);
209
210  void
211  set_inner_bool_option (enum inner_bool_option inner_opt,
212			 int value);
213
214  void
215  add_command_line_option (const char *optname);
216
217  void
218  append_command_line_options (vec <char *> *argvec);
219
220  void
221  enable_dump (const char *dumpname,
222	       char **out_ptr);
223
224  const char *
225  get_str_option (enum gcc_jit_str_option opt) const
226  {
227    return m_str_options[opt];
228  }
229
230  int
231  get_int_option (enum gcc_jit_int_option opt) const
232  {
233    return m_int_options[opt];
234  }
235
236  int
237  get_bool_option (enum gcc_jit_bool_option opt) const
238  {
239    return m_bool_options[opt];
240  }
241
242  int
243  get_inner_bool_option (enum inner_bool_option opt) const
244  {
245    return m_inner_bool_options[opt];
246  }
247
248  result *
249  compile ();
250
251  void
252  compile_to_file (enum gcc_jit_output_kind output_kind,
253		   const char *output_path);
254
255  void
256  add_error (location *loc, const char *fmt, ...)
257      GNU_PRINTF(3, 4);
258
259  void
260  add_error_va (location *loc, const char *fmt, va_list ap)
261      GNU_PRINTF(3, 0);
262
263  const char *
264  get_first_error () const;
265
266  const char *
267  get_last_error () const;
268
269  bool errors_occurred () const
270  {
271    if (m_parent_ctxt)
272      if (m_parent_ctxt->errors_occurred ())
273	return true;
274    return m_error_count;
275  }
276
277  type *get_opaque_FILE_type ();
278
279  void dump_to_file (const char *path, bool update_locations);
280
281  void dump_reproducer_to_file (const char *path);
282
283  void
284  get_all_requested_dumps (vec <recording::requested_dump> *out);
285
286  void set_timer (timer *t) { m_timer = t; }
287  timer *get_timer () const { return m_timer; }
288
289private:
290  void log_all_options () const;
291  void log_str_option (enum gcc_jit_str_option opt) const;
292  void log_int_option (enum gcc_jit_int_option opt) const;
293  void log_bool_option (enum gcc_jit_bool_option opt) const;
294  void log_inner_bool_option (enum inner_bool_option opt) const;
295
296  void validate ();
297
298private:
299  context *m_parent_ctxt;
300
301  /* The ultimate ancestor of the contexts within a family tree of
302     contexts.  This has itself as its own m_toplevel_ctxt.  */
303  context *m_toplevel_ctxt;
304
305  timer *m_timer;
306
307  int m_error_count;
308
309  char *m_first_error_str;
310  bool m_owns_first_error_str;
311
312  char *m_last_error_str;
313  bool m_owns_last_error_str;
314
315  char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
316  int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
317  bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
318  bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
319  auto_vec <char *> m_command_line_options;
320
321  /* Dumpfiles that were requested via gcc_jit_context_enable_dump.  */
322  auto_vec<requested_dump> m_requested_dumps;
323
324  /* Recorded API usage.  */
325  auto_vec<memento *> m_mementos;
326
327  /* Specific recordings, for use by dump_to_file.  */
328  auto_vec<compound_type *> m_compound_types;
329  auto_vec<global *> m_globals;
330  auto_vec<function *> m_functions;
331
332  type *m_basic_types[NUM_GCC_JIT_TYPES];
333  type *m_FILE_type;
334
335  builtins_manager *m_builtins_manager; // lazily created
336};
337
338
339/* An object with lifetime managed by the context i.e.
340   it lives until the context is released, at which
341   point it itself is cleaned up.  */
342
343class memento
344{
345public:
346  virtual ~memento () {}
347
348  /* Hook for replaying this.  */
349  virtual void replay_into (replayer *r) = 0;
350
351  void set_playback_obj (void *obj) { m_playback_obj = obj; }
352
353
354  /* Get the context that owns this object.
355
356     Implements the post-error-checking part of
357     gcc_jit_object_get_context.  */
358  context *get_context () { return m_ctxt; }
359
360  memento *
361  as_object () { return this; }
362
363  /* Debugging hook, for use in generating error messages etc.
364     Implements the post-error-checking part of
365     gcc_jit_object_get_debug_string.  */
366  const char *
367  get_debug_string ();
368
369  virtual void write_to_dump (dump &d);
370  virtual void write_reproducer (reproducer &r) = 0;
371  virtual location *dyn_cast_location () { return NULL; }
372
373protected:
374  memento (context *ctxt)
375  : m_ctxt (ctxt),
376    m_playback_obj (NULL),
377    m_debug_string (NULL)
378  {
379    gcc_assert (ctxt);
380  }
381
382  string *new_string (const char *text) { return m_ctxt->new_string (text); }
383
384private:
385  virtual string * make_debug_string () = 0;
386
387public:
388  context *m_ctxt;
389
390protected:
391  void *m_playback_obj;
392
393private:
394  string *m_debug_string;
395};
396
397/* or just use std::string? */
398class string : public memento
399{
400public:
401  string (context *ctxt, const char *text);
402  ~string ();
403
404  const char *c_str () { return m_buffer; }
405
406  static string * from_printf (context *ctxt, const char *fmt, ...)
407    GNU_PRINTF(2, 3);
408
409  void replay_into (replayer *) FINAL OVERRIDE {}
410
411private:
412  string * make_debug_string () FINAL OVERRIDE;
413  void write_reproducer (reproducer &r) FINAL OVERRIDE;
414
415private:
416  size_t m_len;
417  char *m_buffer;
418};
419
420class location : public memento
421{
422public:
423  location (context *ctxt, string *filename, int line, int column,
424	    bool created_by_user)
425  : memento (ctxt),
426    m_filename (filename),
427    m_line (line),
428    m_column (column),
429    m_created_by_user (created_by_user)
430 {}
431
432  void replay_into (replayer *r) FINAL OVERRIDE;
433
434  playback::location *
435  playback_location (replayer *r)
436  {
437    /* Normally during playback, we can walk forwards through the list of
438       recording objects, playing them back.  The ordering of recording
439       ensures that everything that a recording object refers to has
440       already been played back, so we can simply look up the relevant
441       m_playback_obj.
442
443       Locations are an exception, due to the "write_to_dump" method of
444       recording::statement.  This method can set a new location on a
445       statement after the statement is created, and thus the location
446       appears in the context's memento list *after* the statement that
447       refers to it.
448
449       In such circumstances, the statement is replayed *before* the location,
450       when the latter doesn't yet have a playback object.
451
452       Hence we need to ensure that locations have playback objects.  */
453    if (!m_playback_obj)
454      {
455	replay_into (r);
456      }
457    gcc_assert (m_playback_obj);
458    return static_cast <playback::location *> (m_playback_obj);
459  }
460
461  location *dyn_cast_location () FINAL OVERRIDE { return this; }
462  bool created_by_user () const { return m_created_by_user; }
463
464private:
465  string * make_debug_string () FINAL OVERRIDE;
466  void write_reproducer (reproducer &r) FINAL OVERRIDE;
467
468private:
469  string *m_filename;
470  int m_line;
471  int m_column;
472  bool m_created_by_user;
473};
474
475class type : public memento
476{
477public:
478  type *get_pointer ();
479  type *get_const ();
480  type *get_volatile ();
481  type *get_aligned (size_t alignment_in_bytes);
482  type *get_vector (size_t num_units);
483
484  /* Get the type obtained when dereferencing this type.
485
486     This will return NULL if it's not valid to dereference this type.
487     The caller is responsible for setting an error.  */
488  virtual type *dereference () = 0;
489
490  /* Dynamic casts.  */
491  virtual function_type *dyn_cast_function_type () { return NULL; }
492  virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
493  virtual struct_ *dyn_cast_struct () { return NULL; }
494  virtual vector_type *dyn_cast_vector_type () { return NULL; }
495
496  /* Is it typesafe to copy to this type from rtype?  */
497  virtual bool accepts_writes_from (type *rtype)
498  {
499    gcc_assert (rtype);
500    return this->unqualified ()->is_same_type_as (rtype->unqualified ());
501  }
502
503  virtual bool is_same_type_as (type *other)
504  {
505    return this == other;
506  }
507
508  /* Strip off "const" etc */
509  virtual type *unqualified ()
510  {
511    return this;
512  }
513
514  virtual bool is_int () const = 0;
515  virtual bool is_float () const = 0;
516  virtual bool is_bool () const = 0;
517  virtual type *is_pointer () = 0;
518  virtual type *is_array () = 0;
519  virtual bool is_void () const { return false; }
520  virtual bool has_known_size () const { return true; }
521
522  bool is_numeric () const
523  {
524    return is_int () || is_float () || is_bool ();
525  }
526
527  playback::type *
528  playback_type ()
529  {
530    return static_cast <playback::type *> (m_playback_obj);
531  }
532
533  virtual const char *access_as_type (reproducer &r);
534
535protected:
536  type (context *ctxt)
537    : memento (ctxt),
538    m_pointer_to_this_type (NULL)
539  {}
540
541private:
542  type *m_pointer_to_this_type;
543};
544
545/* Result of "gcc_jit_context_get_type".  */
546class memento_of_get_type : public type
547{
548public:
549  memento_of_get_type (context *ctxt,
550		       enum gcc_jit_types kind)
551  : type (ctxt),
552    m_kind (kind) {}
553
554  type *dereference () FINAL OVERRIDE;
555
556  bool accepts_writes_from (type *rtype) FINAL OVERRIDE
557  {
558    if (m_kind == GCC_JIT_TYPE_VOID_PTR)
559      if (rtype->is_pointer ())
560	{
561	  /* LHS (this) is type (void *), and the RHS is a pointer:
562	     accept it:  */
563	  return true;
564	}
565
566    return type::accepts_writes_from (rtype);
567  }
568
569  bool is_int () const FINAL OVERRIDE;
570  bool is_float () const FINAL OVERRIDE;
571  bool is_bool () const FINAL OVERRIDE;
572  type *is_pointer () FINAL OVERRIDE { return dereference (); }
573  type *is_array () FINAL OVERRIDE { return NULL; }
574  bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
575
576public:
577  void replay_into (replayer *r) FINAL OVERRIDE;
578
579private:
580  string * make_debug_string () FINAL OVERRIDE;
581  void write_reproducer (reproducer &r) FINAL OVERRIDE;
582
583private:
584  enum gcc_jit_types m_kind;
585};
586
587/* Result of "gcc_jit_type_get_pointer".  */
588class memento_of_get_pointer : public type
589{
590public:
591  memento_of_get_pointer (type *other_type)
592  : type (other_type->m_ctxt),
593    m_other_type (other_type) {}
594
595  type *dereference () FINAL OVERRIDE { return m_other_type; }
596
597  bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
598
599  void replay_into (replayer *r) FINAL OVERRIDE;
600
601  bool is_int () const FINAL OVERRIDE { return false; }
602  bool is_float () const FINAL OVERRIDE { return false; }
603  bool is_bool () const FINAL OVERRIDE { return false; }
604  type *is_pointer () FINAL OVERRIDE { return m_other_type; }
605  type *is_array () FINAL OVERRIDE { return NULL; }
606
607private:
608  string * make_debug_string () FINAL OVERRIDE;
609  void write_reproducer (reproducer &r) FINAL OVERRIDE;
610
611private:
612  type *m_other_type;
613};
614
615/* A decorated version of a type, for get_const, get_volatile,
616   get_aligned, and get_vector.  */
617
618class decorated_type : public type
619{
620public:
621  decorated_type (type *other_type)
622  : type (other_type->m_ctxt),
623    m_other_type (other_type) {}
624
625  type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
626
627  bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
628  bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
629  bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
630  type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
631  type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
632
633protected:
634  type *m_other_type;
635};
636
637/* Result of "gcc_jit_type_get_const".  */
638class memento_of_get_const : public decorated_type
639{
640public:
641  memento_of_get_const (type *other_type)
642  : decorated_type (other_type) {}
643
644  bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
645  {
646    /* Can't write to a "const".  */
647    return false;
648  }
649
650  /* Strip off the "const", giving the underlying type.  */
651  type *unqualified () FINAL OVERRIDE { return m_other_type; }
652
653  void replay_into (replayer *) FINAL OVERRIDE;
654
655private:
656  string * make_debug_string () FINAL OVERRIDE;
657  void write_reproducer (reproducer &r) FINAL OVERRIDE;
658};
659
660/* Result of "gcc_jit_type_get_volatile".  */
661class memento_of_get_volatile : public decorated_type
662{
663public:
664  memento_of_get_volatile (type *other_type)
665  : decorated_type (other_type) {}
666
667  /* Strip off the "volatile", giving the underlying type.  */
668  type *unqualified () FINAL OVERRIDE { return m_other_type; }
669
670  void replay_into (replayer *) FINAL OVERRIDE;
671
672private:
673  string * make_debug_string () FINAL OVERRIDE;
674  void write_reproducer (reproducer &r) FINAL OVERRIDE;
675};
676
677/* Result of "gcc_jit_type_get_aligned".  */
678class memento_of_get_aligned : public decorated_type
679{
680public:
681  memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
682  : decorated_type (other_type),
683    m_alignment_in_bytes (alignment_in_bytes) {}
684
685  /* Strip off the alignment, giving the underlying type.  */
686  type *unqualified () FINAL OVERRIDE { return m_other_type; }
687
688  void replay_into (replayer *) FINAL OVERRIDE;
689
690private:
691  string * make_debug_string () FINAL OVERRIDE;
692  void write_reproducer (reproducer &r) FINAL OVERRIDE;
693
694private:
695  size_t m_alignment_in_bytes;
696};
697
698/* Result of "gcc_jit_type_get_vector".  */
699class vector_type : public decorated_type
700{
701public:
702  vector_type (type *other_type, size_t num_units)
703  : decorated_type (other_type),
704    m_num_units (num_units) {}
705
706  size_t get_num_units () const { return m_num_units; }
707
708  vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
709
710  type *get_element_type () { return m_other_type; }
711
712  void replay_into (replayer *) FINAL OVERRIDE;
713
714private:
715  string * make_debug_string () FINAL OVERRIDE;
716  void write_reproducer (reproducer &r) FINAL OVERRIDE;
717
718private:
719  size_t m_num_units;
720};
721
722class array_type : public type
723{
724 public:
725  array_type (context *ctxt,
726	      location *loc,
727	      type *element_type,
728	      int num_elements)
729  : type (ctxt),
730    m_loc (loc),
731    m_element_type (element_type),
732    m_num_elements (num_elements)
733  {}
734
735  type *dereference () FINAL OVERRIDE;
736
737  bool is_int () const FINAL OVERRIDE { return false; }
738  bool is_float () const FINAL OVERRIDE { return false; }
739  bool is_bool () const FINAL OVERRIDE { return false; }
740  type *is_pointer () FINAL OVERRIDE { return NULL; }
741  type *is_array () FINAL OVERRIDE { return m_element_type; }
742
743  void replay_into (replayer *) FINAL OVERRIDE;
744
745 private:
746  string * make_debug_string () FINAL OVERRIDE;
747  void write_reproducer (reproducer &r) FINAL OVERRIDE;
748
749 private:
750  location *m_loc;
751  type *m_element_type;
752  int m_num_elements;
753};
754
755class function_type : public type
756{
757public:
758  function_type (context *ctxt,
759		 type *return_type,
760		 int num_params,
761		 type **param_types,
762		 int is_variadic);
763
764  type *dereference () FINAL OVERRIDE;
765  function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
766  function_type *as_a_function_type () FINAL OVERRIDE { return this; }
767
768  bool is_same_type_as (type *other) FINAL OVERRIDE;
769
770  bool is_int () const FINAL OVERRIDE { return false; }
771  bool is_float () const FINAL OVERRIDE { return false; }
772  bool is_bool () const FINAL OVERRIDE { return false; }
773  type *is_pointer () FINAL OVERRIDE { return NULL; }
774  type *is_array () FINAL OVERRIDE { return NULL; }
775
776  void replay_into (replayer *) FINAL OVERRIDE;
777
778  type * get_return_type () const { return m_return_type; }
779  const vec<type *> &get_param_types () const { return m_param_types; }
780  int is_variadic () const { return m_is_variadic; }
781
782  string * make_debug_string_with_ptr ();
783
784  void
785  write_deferred_reproducer (reproducer &r,
786			     memento *ptr_type);
787
788 private:
789  string * make_debug_string () FINAL OVERRIDE;
790  string * make_debug_string_with (const char *);
791  void write_reproducer (reproducer &r) FINAL OVERRIDE;
792
793private:
794  type *m_return_type;
795  auto_vec<type *> m_param_types;
796  int m_is_variadic;
797};
798
799class field : public memento
800{
801public:
802  field (context *ctxt,
803	 location *loc,
804	 type *type,
805	 string *name)
806  : memento (ctxt),
807    m_loc (loc),
808    m_type (type),
809    m_name (name),
810    m_container (NULL)
811  {}
812
813  type * get_type () const { return m_type; }
814
815  compound_type * get_container () const { return m_container; }
816  void set_container (compound_type *c) { m_container = c; }
817
818  void replay_into (replayer *) FINAL OVERRIDE;
819
820  void write_to_dump (dump &d) FINAL OVERRIDE;
821
822  playback::field *
823  playback_field () const
824  {
825    return static_cast <playback::field *> (m_playback_obj);
826  }
827
828private:
829  string * make_debug_string () FINAL OVERRIDE;
830  void write_reproducer (reproducer &r) FINAL OVERRIDE;
831
832private:
833  location *m_loc;
834  type *m_type;
835  string *m_name;
836  compound_type *m_container;
837};
838
839/* Base class for struct_ and union_ */
840class compound_type : public type
841{
842public:
843  compound_type (context *ctxt,
844		 location *loc,
845		 string *name);
846
847  string *get_name () const { return m_name; }
848  location *get_loc () const { return m_loc; }
849  fields * get_fields () { return m_fields; }
850
851  void
852  set_fields (location *loc,
853	      int num_fields,
854	      field **fields);
855
856  type *dereference () FINAL OVERRIDE;
857
858  bool is_int () const FINAL OVERRIDE { return false; }
859  bool is_float () const FINAL OVERRIDE { return false; }
860  bool is_bool () const FINAL OVERRIDE { return false; }
861  type *is_pointer () FINAL OVERRIDE { return NULL; }
862  type *is_array () FINAL OVERRIDE { return NULL; }
863
864  bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
865
866  playback::compound_type *
867  playback_compound_type ()
868  {
869    return static_cast <playback::compound_type *> (m_playback_obj);
870  }
871
872private:
873  location *m_loc;
874  string *m_name;
875  fields *m_fields;
876};
877
878class struct_ : public compound_type
879{
880public:
881  struct_ (context *ctxt,
882	   location *loc,
883	   string *name);
884
885  struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
886
887  type *
888  as_type () { return this; }
889
890  void replay_into (replayer *r) FINAL OVERRIDE;
891
892  const char *access_as_type (reproducer &r) FINAL OVERRIDE;
893
894private:
895  string * make_debug_string () FINAL OVERRIDE;
896  void write_reproducer (reproducer &r) FINAL OVERRIDE;
897};
898
899// memento of struct_::set_fields
900class fields : public memento
901{
902public:
903  fields (compound_type *struct_or_union,
904	  int num_fields,
905	  field **fields);
906
907  void replay_into (replayer *r) FINAL OVERRIDE;
908
909  void write_to_dump (dump &d) FINAL OVERRIDE;
910
911  int length () const { return m_fields.length (); }
912  field *get_field (int i) const { return m_fields[i]; }
913
914private:
915  string * make_debug_string () FINAL OVERRIDE;
916  void write_reproducer (reproducer &r) FINAL OVERRIDE;
917
918private:
919  compound_type *m_struct_or_union;
920  auto_vec<field *> m_fields;
921};
922
923class union_ : public compound_type
924{
925public:
926  union_ (context *ctxt,
927	  location *loc,
928	  string *name);
929
930  void replay_into (replayer *r) FINAL OVERRIDE;
931
932private:
933  string * make_debug_string () FINAL OVERRIDE;
934  void write_reproducer (reproducer &r) FINAL OVERRIDE;
935};
936
937/* An abstract base class for operations that visit all rvalues within an
938   expression tree.
939   Currently the only implementation is class rvalue_usage_validator within
940   jit-recording.c.  */
941
942class rvalue_visitor
943{
944 public:
945  virtual ~rvalue_visitor () {}
946  virtual void visit (rvalue *rvalue) = 0;
947};
948
949/* When generating debug strings for rvalues we mimic C, so we need to
950   mimic C's precedence levels when handling compound expressions.
951   These are in order from strongest precedence to weakest.  */
952enum precedence
953{
954  PRECEDENCE_PRIMARY,
955  PRECEDENCE_POSTFIX,
956  PRECEDENCE_UNARY,
957  PRECEDENCE_CAST,
958  PRECEDENCE_MULTIPLICATIVE,
959  PRECEDENCE_ADDITIVE,
960  PRECEDENCE_SHIFT,
961  PRECEDENCE_RELATIONAL,
962  PRECEDENCE_EQUALITY,
963  PRECEDENCE_BITWISE_AND,
964  PRECEDENCE_BITWISE_XOR,
965  PRECEDENCE_BITWISE_IOR,
966  PRECEDENCE_LOGICAL_AND,
967  PRECEDENCE_LOGICAL_OR
968};
969
970class rvalue : public memento
971{
972public:
973  rvalue (context *ctxt,
974	  location *loc,
975	  type *type_)
976  : memento (ctxt),
977    m_loc (loc),
978    m_type (type_),
979    m_scope (NULL),
980    m_parenthesized_string (NULL)
981  {
982    gcc_assert (type_);
983  }
984
985  location * get_loc () const { return m_loc; }
986
987  /* Get the recording::type of this rvalue.
988
989     Implements the post-error-checking part of
990     gcc_jit_rvalue_get_type.  */
991  type * get_type () const { return m_type; }
992
993  playback::rvalue *
994  playback_rvalue () const
995  {
996    return static_cast <playback::rvalue *> (m_playback_obj);
997  }
998  rvalue *
999  access_field (location *loc,
1000		field *field);
1001
1002  lvalue *
1003  dereference_field (location *loc,
1004		     field *field);
1005
1006  lvalue *
1007  dereference (location *loc);
1008
1009  void
1010  verify_valid_within_stmt (const char *api_funcname, statement *s);
1011
1012  virtual void visit_children (rvalue_visitor *v) = 0;
1013
1014  void set_scope (function *scope);
1015  function *get_scope () const { return m_scope; }
1016
1017  /* Dynamic casts.  */
1018  virtual param *dyn_cast_param () { return NULL; }
1019  virtual base_call *dyn_cast_base_call () { return NULL; }
1020
1021  virtual const char *access_as_rvalue (reproducer &r);
1022
1023  /* Get the debug string, wrapped in parentheses.  */
1024  const char *
1025  get_debug_string_parens (enum precedence outer_prec);
1026
1027  virtual bool is_constant () const { return false; }
1028  virtual bool get_wide_int (wide_int *) const { return false; }
1029
1030private:
1031  virtual enum precedence get_precedence () const = 0;
1032
1033protected:
1034  location *m_loc;
1035  type *m_type;
1036
1037 private:
1038  function *m_scope; /* NULL for globals, non-NULL for locals/params */
1039  string *m_parenthesized_string;
1040};
1041
1042class lvalue : public rvalue
1043{
1044public:
1045  lvalue (context *ctxt,
1046	  location *loc,
1047	  type *type_)
1048    : rvalue (ctxt, loc, type_)
1049    {}
1050
1051  playback::lvalue *
1052  playback_lvalue () const
1053  {
1054    return static_cast <playback::lvalue *> (m_playback_obj);
1055  }
1056
1057  lvalue *
1058  access_field (location *loc,
1059		field *field);
1060
1061  rvalue *
1062  get_address (location *loc);
1063
1064  rvalue *
1065  as_rvalue () { return this; }
1066
1067  const char *access_as_rvalue (reproducer &r) OVERRIDE;
1068  virtual const char *access_as_lvalue (reproducer &r);
1069};
1070
1071class param : public lvalue
1072{
1073public:
1074  param (context *ctxt,
1075	 location *loc,
1076	 type *type,
1077	 string *name)
1078    : lvalue (ctxt, loc, type),
1079    m_name (name) {}
1080
1081  lvalue *
1082  as_lvalue () { return this; }
1083
1084  void replay_into (replayer *r) FINAL OVERRIDE;
1085
1086  void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1087
1088  playback::param *
1089  playback_param () const
1090  {
1091    return static_cast <playback::param *> (m_playback_obj);
1092  }
1093
1094  param *dyn_cast_param () FINAL OVERRIDE { return this; }
1095
1096  const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1097  const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1098
1099private:
1100  string * make_debug_string () FINAL OVERRIDE { return m_name; }
1101  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1102  enum precedence get_precedence () const FINAL OVERRIDE
1103  {
1104    return PRECEDENCE_PRIMARY;
1105  }
1106
1107private:
1108  string *m_name;
1109};
1110
1111class function : public memento
1112{
1113public:
1114  function (context *ctxt,
1115	    location *loc,
1116	    enum gcc_jit_function_kind kind,
1117	    type *return_type,
1118	    string *name,
1119	    int num_params,
1120	    param **params,
1121	    int is_variadic,
1122	    enum built_in_function builtin_id);
1123
1124  void replay_into (replayer *r) FINAL OVERRIDE;
1125
1126  playback::function *
1127  playback_function () const
1128  {
1129    return static_cast <playback::function *> (m_playback_obj);
1130  }
1131
1132  enum gcc_jit_function_kind get_kind () const { return m_kind; }
1133
1134  lvalue *
1135  new_local (location *loc,
1136	     type *type,
1137	     const char *name);
1138
1139  block*
1140  new_block (const char *name);
1141
1142  location *get_loc () const { return m_loc; }
1143  type *get_return_type () const { return m_return_type; }
1144  string * get_name () const { return m_name; }
1145  const vec<param *> &get_params () const { return m_params; }
1146
1147  /* Get the given param by index.
1148     Implements the post-error-checking part of
1149     gcc_jit_function_get_param.  */
1150  param *get_param (int i) const { return m_params[i]; }
1151
1152  bool is_variadic () const { return m_is_variadic; }
1153
1154  void write_to_dump (dump &d) FINAL OVERRIDE;
1155
1156  void validate ();
1157
1158  void dump_to_dot (const char *path);
1159
1160  rvalue *get_address (location *loc);
1161
1162private:
1163  string * make_debug_string () FINAL OVERRIDE;
1164  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1165
1166private:
1167  location *m_loc;
1168  enum gcc_jit_function_kind m_kind;
1169  type *m_return_type;
1170  string *m_name;
1171  auto_vec<param *> m_params;
1172  int m_is_variadic;
1173  enum built_in_function m_builtin_id;
1174  auto_vec<local *> m_locals;
1175  auto_vec<block *> m_blocks;
1176  type *m_fn_ptr_type;
1177};
1178
1179class block : public memento
1180{
1181public:
1182  block (function *func, int index, string *name)
1183  : memento (func->m_ctxt),
1184    m_func (func),
1185    m_index (index),
1186    m_name (name),
1187    m_statements (),
1188    m_has_been_terminated (false),
1189    m_is_reachable (false)
1190  {
1191  }
1192
1193  /* Get the recording::function containing this block.
1194     Implements the post-error-checking part of
1195     gcc_jit_block_get_function.  */
1196  function *get_function () { return m_func; }
1197
1198  bool has_been_terminated () { return m_has_been_terminated; }
1199  bool is_reachable () { return m_is_reachable; }
1200
1201  statement *
1202  add_eval (location *loc,
1203	    rvalue *rvalue);
1204
1205  statement *
1206  add_assignment (location *loc,
1207		  lvalue *lvalue,
1208		  rvalue *rvalue);
1209
1210  statement *
1211  add_assignment_op (location *loc,
1212		     lvalue *lvalue,
1213		     enum gcc_jit_binary_op op,
1214		     rvalue *rvalue);
1215
1216  statement *
1217  add_comment (location *loc,
1218	       const char *text);
1219
1220  statement *
1221  end_with_conditional (location *loc,
1222			rvalue *boolval,
1223			block *on_true,
1224			block *on_false);
1225
1226  statement *
1227  end_with_jump (location *loc,
1228		 block *target);
1229
1230  statement *
1231  end_with_return (location *loc,
1232		   rvalue *rvalue);
1233
1234  statement *
1235  end_with_switch (location *loc,
1236		   rvalue *expr,
1237		   block *default_block,
1238		   int num_cases,
1239		   case_ **cases);
1240
1241  playback::block *
1242  playback_block () const
1243  {
1244    return static_cast <playback::block *> (m_playback_obj);
1245  }
1246
1247  void write_to_dump (dump &d) FINAL OVERRIDE;
1248
1249  bool validate ();
1250
1251  location *get_loc () const;
1252
1253  statement *get_first_statement () const;
1254  statement *get_last_statement () const;
1255
1256  vec <block *> get_successor_blocks () const;
1257
1258private:
1259  string * make_debug_string () FINAL OVERRIDE;
1260  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1261
1262  void replay_into (replayer *r) FINAL OVERRIDE;
1263
1264  void dump_to_dot (pretty_printer *pp);
1265  void dump_edges_to_dot (pretty_printer *pp);
1266
1267private:
1268  function *m_func;
1269  int m_index;
1270  string *m_name;
1271  auto_vec<statement *> m_statements;
1272  bool m_has_been_terminated;
1273  bool m_is_reachable;
1274
1275  friend class function;
1276};
1277
1278class global : public lvalue
1279{
1280public:
1281  global (context *ctxt,
1282	  location *loc,
1283	  enum gcc_jit_global_kind kind,
1284	  type *type,
1285	  string *name)
1286  : lvalue (ctxt, loc, type),
1287    m_kind (kind),
1288    m_name (name)
1289  {}
1290
1291  void replay_into (replayer *) FINAL OVERRIDE;
1292
1293  void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1294
1295  void write_to_dump (dump &d) FINAL OVERRIDE;
1296
1297private:
1298  string * make_debug_string () FINAL OVERRIDE { return m_name; }
1299  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1300  enum precedence get_precedence () const FINAL OVERRIDE
1301  {
1302    return PRECEDENCE_PRIMARY;
1303  }
1304
1305private:
1306  enum gcc_jit_global_kind m_kind;
1307  string *m_name;
1308};
1309
1310template <typename HOST_TYPE>
1311class memento_of_new_rvalue_from_const : public rvalue
1312{
1313public:
1314  memento_of_new_rvalue_from_const (context *ctxt,
1315				    location *loc,
1316				    type *type,
1317				    HOST_TYPE value)
1318  : rvalue (ctxt, loc, type),
1319    m_value (value) {}
1320
1321  void replay_into (replayer *r) FINAL OVERRIDE;
1322
1323  void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1324
1325  bool is_constant () const FINAL OVERRIDE { return true; }
1326
1327  bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1328
1329private:
1330  string * make_debug_string () FINAL OVERRIDE;
1331  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1332  enum precedence get_precedence () const FINAL OVERRIDE
1333  {
1334    return PRECEDENCE_PRIMARY;
1335  }
1336
1337private:
1338  HOST_TYPE m_value;
1339};
1340
1341class memento_of_new_string_literal : public rvalue
1342{
1343public:
1344  memento_of_new_string_literal (context *ctxt,
1345				 location *loc,
1346				 string *value)
1347  : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1348    m_value (value) {}
1349
1350  void replay_into (replayer *r) FINAL OVERRIDE;
1351
1352  void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1353
1354private:
1355  string * make_debug_string () FINAL OVERRIDE;
1356  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1357  enum precedence get_precedence () const FINAL OVERRIDE
1358  {
1359    return PRECEDENCE_PRIMARY;
1360  }
1361
1362private:
1363  string *m_value;
1364};
1365
1366class memento_of_new_rvalue_from_vector : public rvalue
1367{
1368public:
1369  memento_of_new_rvalue_from_vector (context *ctxt,
1370				     location *loc,
1371				     vector_type *type,
1372				     rvalue **elements);
1373
1374  void replay_into (replayer *r) FINAL OVERRIDE;
1375
1376  void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1377
1378private:
1379  string * make_debug_string () FINAL OVERRIDE;
1380  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1381  enum precedence get_precedence () const FINAL OVERRIDE
1382  {
1383    return PRECEDENCE_PRIMARY;
1384  }
1385
1386private:
1387  vector_type *m_vector_type;
1388  auto_vec<rvalue *> m_elements;
1389};
1390
1391class unary_op : public rvalue
1392{
1393public:
1394  unary_op (context *ctxt,
1395	    location *loc,
1396	    enum gcc_jit_unary_op op,
1397	    type *result_type,
1398	    rvalue *a)
1399  : rvalue (ctxt, loc, result_type),
1400    m_op (op),
1401    m_a (a)
1402  {}
1403
1404  void replay_into (replayer *r) FINAL OVERRIDE;
1405
1406  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1407
1408private:
1409  string * make_debug_string () FINAL OVERRIDE;
1410  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1411  enum precedence get_precedence () const FINAL OVERRIDE
1412  {
1413    return PRECEDENCE_UNARY;
1414  }
1415
1416private:
1417  enum gcc_jit_unary_op m_op;
1418  rvalue *m_a;
1419};
1420
1421class binary_op : public rvalue
1422{
1423public:
1424  binary_op (context *ctxt,
1425	     location *loc,
1426	     enum gcc_jit_binary_op op,
1427	     type *result_type,
1428	     rvalue *a, rvalue *b)
1429  : rvalue (ctxt, loc, result_type),
1430    m_op (op),
1431    m_a (a),
1432    m_b (b) {}
1433
1434  void replay_into (replayer *r) FINAL OVERRIDE;
1435
1436  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1437
1438private:
1439  string * make_debug_string () FINAL OVERRIDE;
1440  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1441  enum precedence get_precedence () const FINAL OVERRIDE;
1442
1443private:
1444  enum gcc_jit_binary_op m_op;
1445  rvalue *m_a;
1446  rvalue *m_b;
1447};
1448
1449class comparison : public rvalue
1450{
1451public:
1452  comparison (context *ctxt,
1453	      location *loc,
1454	      enum gcc_jit_comparison op,
1455	      rvalue *a, rvalue *b)
1456  : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1457    m_op (op),
1458    m_a (a),
1459    m_b (b)
1460  {}
1461
1462  void replay_into (replayer *r) FINAL OVERRIDE;
1463
1464  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1465
1466private:
1467  string * make_debug_string () FINAL OVERRIDE;
1468  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1469  enum precedence get_precedence () const FINAL OVERRIDE;
1470
1471private:
1472  enum gcc_jit_comparison m_op;
1473  rvalue *m_a;
1474  rvalue *m_b;
1475};
1476
1477class cast : public rvalue
1478{
1479public:
1480  cast (context *ctxt,
1481	location *loc,
1482	rvalue *a,
1483	type *type_)
1484  : rvalue (ctxt, loc, type_),
1485    m_rvalue (a)
1486  {}
1487
1488  void replay_into (replayer *r) FINAL OVERRIDE;
1489
1490  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1491
1492private:
1493  string * make_debug_string () FINAL OVERRIDE;
1494  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1495  enum precedence get_precedence () const FINAL OVERRIDE
1496  {
1497    return PRECEDENCE_CAST;
1498  }
1499
1500private:
1501  rvalue *m_rvalue;
1502};
1503
1504class base_call : public rvalue
1505{
1506 public:
1507  base_call (context *ctxt,
1508	     location *loc,
1509	     type *type_,
1510	     int numargs,
1511	     rvalue **args);
1512
1513  enum precedence get_precedence () const FINAL OVERRIDE
1514  {
1515    return PRECEDENCE_POSTFIX;
1516  }
1517
1518  base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1519
1520  void set_require_tail_call (bool require_tail_call)
1521  {
1522    m_require_tail_call = require_tail_call;
1523  }
1524
1525 protected:
1526  void write_reproducer_tail_call (reproducer &r, const char *id);
1527
1528 protected:
1529  auto_vec<rvalue *> m_args;
1530  bool m_require_tail_call;
1531};
1532
1533class call : public base_call
1534{
1535public:
1536  call (context *ctxt,
1537	location *loc,
1538	function *func,
1539	int numargs,
1540	rvalue **args);
1541
1542  void replay_into (replayer *r) FINAL OVERRIDE;
1543
1544  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1545
1546private:
1547  string * make_debug_string () FINAL OVERRIDE;
1548  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1549
1550private:
1551  function *m_func;
1552};
1553
1554class call_through_ptr : public base_call
1555{
1556public:
1557  call_through_ptr (context *ctxt,
1558		    location *loc,
1559		    rvalue *fn_ptr,
1560		    int numargs,
1561		    rvalue **args);
1562
1563  void replay_into (replayer *r) FINAL OVERRIDE;
1564
1565  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1566
1567private:
1568  string * make_debug_string () FINAL OVERRIDE;
1569  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1570
1571private:
1572  rvalue *m_fn_ptr;
1573};
1574
1575class array_access : public lvalue
1576{
1577public:
1578  array_access (context *ctxt,
1579		location *loc,
1580		rvalue *ptr,
1581		rvalue *index)
1582  : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1583    m_ptr (ptr),
1584    m_index (index)
1585  {}
1586
1587  void replay_into (replayer *r) FINAL OVERRIDE;
1588
1589  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1590
1591private:
1592  string * make_debug_string () FINAL OVERRIDE;
1593  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1594  enum precedence get_precedence () const FINAL OVERRIDE
1595  {
1596    return PRECEDENCE_POSTFIX;
1597  }
1598
1599private:
1600  rvalue *m_ptr;
1601  rvalue *m_index;
1602};
1603
1604class access_field_of_lvalue : public lvalue
1605{
1606public:
1607  access_field_of_lvalue (context *ctxt,
1608			  location *loc,
1609			  lvalue *val,
1610			  field *field)
1611  : lvalue (ctxt, loc, field->get_type ()),
1612    m_lvalue (val),
1613    m_field (field)
1614  {}
1615
1616  void replay_into (replayer *r) FINAL OVERRIDE;
1617
1618  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1619
1620private:
1621  string * make_debug_string () FINAL OVERRIDE;
1622  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1623  enum precedence get_precedence () const FINAL OVERRIDE
1624  {
1625    return PRECEDENCE_POSTFIX;
1626  }
1627
1628private:
1629  lvalue *m_lvalue;
1630  field *m_field;
1631};
1632
1633class access_field_rvalue : public rvalue
1634{
1635public:
1636  access_field_rvalue (context *ctxt,
1637		       location *loc,
1638		       rvalue *val,
1639		       field *field)
1640  : rvalue (ctxt, loc, field->get_type ()),
1641    m_rvalue (val),
1642    m_field (field)
1643  {}
1644
1645  void replay_into (replayer *r) FINAL OVERRIDE;
1646
1647  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1648
1649private:
1650  string * make_debug_string () FINAL OVERRIDE;
1651  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1652  enum precedence get_precedence () const FINAL OVERRIDE
1653  {
1654    return PRECEDENCE_POSTFIX;
1655  }
1656
1657private:
1658  rvalue *m_rvalue;
1659  field *m_field;
1660};
1661
1662class dereference_field_rvalue : public lvalue
1663{
1664public:
1665  dereference_field_rvalue (context *ctxt,
1666			    location *loc,
1667			    rvalue *val,
1668			    field *field)
1669  : lvalue (ctxt, loc, field->get_type ()),
1670    m_rvalue (val),
1671    m_field (field)
1672  {}
1673
1674  void replay_into (replayer *r) FINAL OVERRIDE;
1675
1676  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1677
1678private:
1679  string * make_debug_string () FINAL OVERRIDE;
1680  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1681  enum precedence get_precedence () const FINAL OVERRIDE
1682  {
1683    return PRECEDENCE_POSTFIX;
1684  }
1685
1686private:
1687  rvalue *m_rvalue;
1688  field *m_field;
1689};
1690
1691class dereference_rvalue : public lvalue
1692{
1693public:
1694  dereference_rvalue (context *ctxt,
1695		      location *loc,
1696		      rvalue *val)
1697  : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1698    m_rvalue (val) {}
1699
1700  void replay_into (replayer *r) FINAL OVERRIDE;
1701
1702  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1703
1704private:
1705  string * make_debug_string () FINAL OVERRIDE;
1706  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1707  enum precedence get_precedence () const FINAL OVERRIDE
1708  {
1709    return PRECEDENCE_UNARY;
1710  }
1711
1712private:
1713  rvalue *m_rvalue;
1714};
1715
1716class get_address_of_lvalue : public rvalue
1717{
1718public:
1719  get_address_of_lvalue (context *ctxt,
1720			 location *loc,
1721			 lvalue *val)
1722  : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1723    m_lvalue (val)
1724  {}
1725
1726  void replay_into (replayer *r) FINAL OVERRIDE;
1727
1728  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1729
1730private:
1731  string * make_debug_string () FINAL OVERRIDE;
1732  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1733  enum precedence get_precedence () const FINAL OVERRIDE
1734  {
1735    return PRECEDENCE_UNARY;
1736  }
1737
1738private:
1739  lvalue *m_lvalue;
1740};
1741
1742class function_pointer : public rvalue
1743{
1744public:
1745  function_pointer (context *ctxt,
1746		    location *loc,
1747		    function *fn,
1748		    type *type)
1749  : rvalue (ctxt, loc, type),
1750    m_fn (fn) {}
1751
1752  void replay_into (replayer *r) FINAL OVERRIDE;
1753
1754  void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1755
1756private:
1757  string * make_debug_string () FINAL OVERRIDE;
1758  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1759  enum precedence get_precedence () const FINAL OVERRIDE
1760  {
1761    return PRECEDENCE_UNARY;
1762  }
1763
1764private:
1765  function *m_fn;
1766};
1767
1768class local : public lvalue
1769{
1770public:
1771  local (function *func, location *loc, type *type_, string *name)
1772    : lvalue (func->m_ctxt, loc, type_),
1773    m_func (func),
1774    m_name (name)
1775  {
1776    set_scope (func);
1777  }
1778
1779  void replay_into (replayer *r) FINAL OVERRIDE;
1780
1781  void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1782
1783  void write_to_dump (dump &d) FINAL OVERRIDE;
1784
1785private:
1786  string * make_debug_string () FINAL OVERRIDE { return m_name; }
1787  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1788  enum precedence get_precedence () const FINAL OVERRIDE
1789  {
1790    return PRECEDENCE_PRIMARY;
1791  }
1792
1793private:
1794  function *m_func;
1795  string *m_name;
1796};
1797
1798class statement : public memento
1799{
1800public:
1801  virtual vec <block *> get_successor_blocks () const;
1802
1803  void write_to_dump (dump &d) FINAL OVERRIDE;
1804
1805  block *get_block () const { return m_block; }
1806  location *get_loc () const { return m_loc; }
1807
1808protected:
1809  statement (block *b, location *loc)
1810  : memento (b->m_ctxt),
1811    m_block (b),
1812    m_loc (loc) {}
1813
1814  playback::location *
1815  playback_location (replayer *r) const
1816  {
1817    return ::gcc::jit::recording::playback_location (r, m_loc);
1818  }
1819
1820private:
1821  block *m_block;
1822  location *m_loc;
1823};
1824
1825class eval : public statement
1826{
1827public:
1828  eval (block *b,
1829	location *loc,
1830	rvalue *rvalue)
1831  : statement (b, loc),
1832    m_rvalue (rvalue) {}
1833
1834  void replay_into (replayer *r) FINAL OVERRIDE;
1835
1836private:
1837  string * make_debug_string () FINAL OVERRIDE;
1838  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1839
1840private:
1841  rvalue *m_rvalue;
1842};
1843
1844class assignment : public statement
1845{
1846public:
1847  assignment (block *b,
1848	      location *loc,
1849	      lvalue *lvalue,
1850	      rvalue *rvalue)
1851  : statement (b, loc),
1852    m_lvalue (lvalue),
1853    m_rvalue (rvalue) {}
1854
1855  void replay_into (replayer *r) FINAL OVERRIDE;
1856
1857private:
1858  string * make_debug_string () FINAL OVERRIDE;
1859  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1860
1861private:
1862  lvalue *m_lvalue;
1863  rvalue *m_rvalue;
1864};
1865
1866class assignment_op : public statement
1867{
1868public:
1869  assignment_op (block *b,
1870		 location *loc,
1871		 lvalue *lvalue,
1872		 enum gcc_jit_binary_op op,
1873		 rvalue *rvalue)
1874  : statement (b, loc),
1875    m_lvalue (lvalue),
1876    m_op (op),
1877    m_rvalue (rvalue) {}
1878
1879  void replay_into (replayer *r) FINAL OVERRIDE;
1880
1881private:
1882  string * make_debug_string () FINAL OVERRIDE;
1883  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1884
1885private:
1886  lvalue *m_lvalue;
1887  enum gcc_jit_binary_op m_op;
1888  rvalue *m_rvalue;
1889};
1890
1891class comment : public statement
1892{
1893public:
1894  comment (block *b,
1895	   location *loc,
1896	   string *text)
1897  : statement (b, loc),
1898    m_text (text) {}
1899
1900  void replay_into (replayer *r) FINAL OVERRIDE;
1901
1902private:
1903  string * make_debug_string () FINAL OVERRIDE;
1904  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1905
1906private:
1907  string *m_text;
1908};
1909
1910class conditional : public statement
1911{
1912public:
1913  conditional (block *b,
1914	       location *loc,
1915	       rvalue *boolval,
1916	       block *on_true,
1917	       block *on_false)
1918  : statement (b, loc),
1919    m_boolval (boolval),
1920    m_on_true (on_true),
1921    m_on_false (on_false) {}
1922
1923  void replay_into (replayer *r) FINAL OVERRIDE;
1924
1925  vec <block *> get_successor_blocks () const FINAL OVERRIDE;
1926
1927private:
1928  string * make_debug_string () FINAL OVERRIDE;
1929  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1930
1931private:
1932  rvalue *m_boolval;
1933  block *m_on_true;
1934  block *m_on_false;
1935};
1936
1937class jump : public statement
1938{
1939public:
1940  jump (block *b,
1941	location *loc,
1942	block *target)
1943  : statement (b, loc),
1944    m_target (target) {}
1945
1946  void replay_into (replayer *r) FINAL OVERRIDE;
1947
1948  vec <block *> get_successor_blocks () const FINAL OVERRIDE;
1949
1950private:
1951  string * make_debug_string () FINAL OVERRIDE;
1952  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1953
1954private:
1955  block *m_target;
1956};
1957
1958class return_ : public statement
1959{
1960public:
1961  return_ (block *b,
1962	   location *loc,
1963	   rvalue *rvalue)
1964  : statement (b, loc),
1965    m_rvalue (rvalue) {}
1966
1967  void replay_into (replayer *r) FINAL OVERRIDE;
1968
1969  vec <block *> get_successor_blocks () const FINAL OVERRIDE;
1970
1971private:
1972  string * make_debug_string () FINAL OVERRIDE;
1973  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1974
1975private:
1976  rvalue *m_rvalue;
1977};
1978
1979class case_ : public memento
1980{
1981 public:
1982  case_ (context *ctxt,
1983	 rvalue *min_value,
1984	 rvalue *max_value,
1985	 block *dest_block)
1986  : memento (ctxt),
1987    m_min_value (min_value),
1988    m_max_value (max_value),
1989    m_dest_block (dest_block)
1990  {}
1991
1992  rvalue *get_min_value () const { return m_min_value; }
1993  rvalue *get_max_value () const { return m_max_value; }
1994  block *get_dest_block () const { return m_dest_block; }
1995
1996  void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
1997
1998  void write_reproducer (reproducer &r) FINAL OVERRIDE;
1999
2000private:
2001  string * make_debug_string () FINAL OVERRIDE;
2002
2003 private:
2004  rvalue *m_min_value;
2005  rvalue *m_max_value;
2006  block *m_dest_block;
2007};
2008
2009class switch_ : public statement
2010{
2011public:
2012  switch_ (block *b,
2013	   location *loc,
2014	   rvalue *expr,
2015	   block *default_block,
2016	   int num_cases,
2017	   case_ **cases);
2018
2019  void replay_into (replayer *r) FINAL OVERRIDE;
2020
2021  vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2022
2023private:
2024  string * make_debug_string () FINAL OVERRIDE;
2025  void write_reproducer (reproducer &r) FINAL OVERRIDE;
2026
2027private:
2028  rvalue *m_expr;
2029  block *m_default_block;
2030  auto_vec <case_ *> m_cases;
2031};
2032
2033} // namespace gcc::jit::recording
2034
2035/* Create a recording::memento_of_new_rvalue_from_const instance and add
2036   it to this context's list of mementos.
2037
2038   Implements the post-error-checking part of
2039   gcc_jit_context_new_rvalue_from_{int|long|double|ptr}.  */
2040
2041template <typename HOST_TYPE>
2042recording::rvalue *
2043recording::context::new_rvalue_from_const (recording::type *type,
2044					   HOST_TYPE value)
2045{
2046  recording::rvalue *result =
2047    new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2048  record (result);
2049  return result;
2050}
2051
2052} // namespace gcc::jit
2053
2054} // namespace gcc
2055
2056#endif /* JIT_RECORDING_H */
2057