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