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