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