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_void()549   virtual bool is_void () const { return false; }
has_known_size()550   virtual bool has_known_size () const { return true; }
551 
is_numeric()552   bool is_numeric () const
553   {
554     return is_int () || is_float () || is_bool ();
555   }
556 
557   playback::type *
playback_type()558   playback_type ()
559   {
560     return static_cast <playback::type *> (m_playback_obj);
561   }
562 
563   virtual const char *access_as_type (reproducer &r);
564 
565 protected:
type(context * ctxt)566   type (context *ctxt)
567     : memento (ctxt),
568     m_pointer_to_this_type (NULL)
569   {}
570 
571 private:
572   type *m_pointer_to_this_type;
573 };
574 
575 /* Result of "gcc_jit_context_get_type".  */
576 class memento_of_get_type : public type
577 {
578 public:
memento_of_get_type(context * ctxt,enum gcc_jit_types kind)579   memento_of_get_type (context *ctxt,
580 		       enum gcc_jit_types kind)
581   : type (ctxt),
582     m_kind (kind) {}
583 
584   type *dereference () FINAL OVERRIDE;
585 
586   size_t get_size () FINAL OVERRIDE;
587 
accepts_writes_from(type * rtype)588   bool accepts_writes_from (type *rtype) FINAL OVERRIDE
589   {
590     if (m_kind == GCC_JIT_TYPE_VOID_PTR)
591       if (rtype->is_pointer ())
592 	{
593 	  /* LHS (this) is type (void *), and the RHS is a pointer:
594 	     accept it:  */
595 	  return true;
596 	}
597 
598     return type::accepts_writes_from (rtype);
599   }
600 
601   bool is_int () const FINAL OVERRIDE;
602   bool is_float () const FINAL OVERRIDE;
603   bool is_bool () const FINAL OVERRIDE;
is_pointer()604   type *is_pointer () FINAL OVERRIDE { return dereference (); }
is_array()605   type *is_array () FINAL OVERRIDE { return NULL; }
is_void()606   bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
607 
608 public:
609   void replay_into (replayer *r) FINAL OVERRIDE;
610 
611 private:
612   string * make_debug_string () FINAL OVERRIDE;
613   void write_reproducer (reproducer &r) FINAL OVERRIDE;
614 
615 private:
616   enum gcc_jit_types m_kind;
617 };
618 
619 /* Result of "gcc_jit_type_get_pointer".  */
620 class memento_of_get_pointer : public type
621 {
622 public:
memento_of_get_pointer(type * other_type)623   memento_of_get_pointer (type *other_type)
624   : type (other_type->m_ctxt),
625     m_other_type (other_type) {}
626 
dereference()627   type *dereference () FINAL OVERRIDE { return m_other_type; }
628 
629   size_t get_size () FINAL OVERRIDE;
630 
631   bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
632 
633   void replay_into (replayer *r) FINAL OVERRIDE;
634 
is_int()635   bool is_int () const FINAL OVERRIDE { return false; }
is_float()636   bool is_float () const FINAL OVERRIDE { return false; }
is_bool()637   bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()638   type *is_pointer () FINAL OVERRIDE { return m_other_type; }
is_array()639   type *is_array () FINAL OVERRIDE { return NULL; }
640 
641 private:
642   string * make_debug_string () FINAL OVERRIDE;
643   void write_reproducer (reproducer &r) FINAL OVERRIDE;
644 
645 private:
646   type *m_other_type;
647 };
648 
649 /* A decorated version of a type, for get_const, get_volatile,
650    get_aligned, and get_vector.  */
651 
652 class decorated_type : public type
653 {
654 public:
decorated_type(type * other_type)655   decorated_type (type *other_type)
656   : type (other_type->m_ctxt),
657     m_other_type (other_type) {}
658 
dereference()659   type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
660 
is_int()661   bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
is_float()662   bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
is_bool()663   bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
is_pointer()664   type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
is_array()665   type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
666 
667 protected:
668   type *m_other_type;
669 };
670 
671 /* Result of "gcc_jit_type_get_const".  */
672 class memento_of_get_const : public decorated_type
673 {
674 public:
memento_of_get_const(type * other_type)675   memento_of_get_const (type *other_type)
676   : decorated_type (other_type) {}
677 
accepts_writes_from(type *)678   bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
679   {
680     /* Can't write to a "const".  */
681     return false;
682   }
683 
684   /* Strip off the "const", giving the underlying type.  */
unqualified()685   type *unqualified () FINAL OVERRIDE { return m_other_type; }
686 
687   void replay_into (replayer *) FINAL OVERRIDE;
688 
689 private:
690   string * make_debug_string () FINAL OVERRIDE;
691   void write_reproducer (reproducer &r) FINAL OVERRIDE;
692 };
693 
694 /* Result of "gcc_jit_type_get_volatile".  */
695 class memento_of_get_volatile : public decorated_type
696 {
697 public:
memento_of_get_volatile(type * other_type)698   memento_of_get_volatile (type *other_type)
699   : decorated_type (other_type) {}
700 
701   /* Strip off the "volatile", giving the underlying type.  */
unqualified()702   type *unqualified () FINAL OVERRIDE { return m_other_type; }
703 
704   void replay_into (replayer *) FINAL OVERRIDE;
705 
706 private:
707   string * make_debug_string () FINAL OVERRIDE;
708   void write_reproducer (reproducer &r) FINAL OVERRIDE;
709 };
710 
711 /* Result of "gcc_jit_type_get_aligned".  */
712 class memento_of_get_aligned : public decorated_type
713 {
714 public:
memento_of_get_aligned(type * other_type,size_t alignment_in_bytes)715   memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
716   : decorated_type (other_type),
717     m_alignment_in_bytes (alignment_in_bytes) {}
718 
719   /* Strip off the alignment, giving the underlying type.  */
unqualified()720   type *unqualified () FINAL OVERRIDE { return m_other_type; }
721 
722   void replay_into (replayer *) FINAL OVERRIDE;
723 
724 private:
725   string * make_debug_string () FINAL OVERRIDE;
726   void write_reproducer (reproducer &r) FINAL OVERRIDE;
727 
728 private:
729   size_t m_alignment_in_bytes;
730 };
731 
732 /* Result of "gcc_jit_type_get_vector".  */
733 class vector_type : public decorated_type
734 {
735 public:
vector_type(type * other_type,size_t num_units)736   vector_type (type *other_type, size_t num_units)
737   : decorated_type (other_type),
738     m_num_units (num_units) {}
739 
get_num_units()740   size_t get_num_units () const { return m_num_units; }
741 
dyn_cast_vector_type()742   vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
743 
get_element_type()744   type *get_element_type () { return m_other_type; }
745 
746   void replay_into (replayer *) FINAL OVERRIDE;
747 
748 private:
749   string * make_debug_string () FINAL OVERRIDE;
750   void write_reproducer (reproducer &r) FINAL OVERRIDE;
751 
752 private:
753   size_t m_num_units;
754 };
755 
756 class array_type : public type
757 {
758  public:
array_type(context * ctxt,location * loc,type * element_type,int num_elements)759   array_type (context *ctxt,
760 	      location *loc,
761 	      type *element_type,
762 	      int num_elements)
763   : type (ctxt),
764     m_loc (loc),
765     m_element_type (element_type),
766     m_num_elements (num_elements)
767   {}
768 
769   type *dereference () FINAL OVERRIDE;
770 
is_int()771   bool is_int () const FINAL OVERRIDE { return false; }
is_float()772   bool is_float () const FINAL OVERRIDE { return false; }
is_bool()773   bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()774   type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()775   type *is_array () FINAL OVERRIDE { return m_element_type; }
num_elements()776   int num_elements () { return m_num_elements; }
777 
778   void replay_into (replayer *) FINAL OVERRIDE;
779 
780  private:
781   string * make_debug_string () FINAL OVERRIDE;
782   void write_reproducer (reproducer &r) FINAL OVERRIDE;
783 
784  private:
785   location *m_loc;
786   type *m_element_type;
787   int m_num_elements;
788 };
789 
790 class function_type : public type
791 {
792 public:
793   function_type (context *ctxt,
794 		 type *return_type,
795 		 int num_params,
796 		 type **param_types,
797 		 int is_variadic);
798 
799   type *dereference () FINAL OVERRIDE;
dyn_cast_function_type()800   function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
as_a_function_type()801   function_type *as_a_function_type () FINAL OVERRIDE { return this; }
802 
803   bool is_same_type_as (type *other) FINAL OVERRIDE;
804 
is_int()805   bool is_int () const FINAL OVERRIDE { return false; }
is_float()806   bool is_float () const FINAL OVERRIDE { return false; }
is_bool()807   bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()808   type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()809   type *is_array () FINAL OVERRIDE { return NULL; }
810 
811   void replay_into (replayer *) FINAL OVERRIDE;
812 
get_return_type()813   type * get_return_type () const { return m_return_type; }
get_param_types()814   const vec<type *> &get_param_types () const { return m_param_types; }
is_variadic()815   int is_variadic () const { return m_is_variadic; }
816 
817   string * make_debug_string_with_ptr ();
818 
819   void
820   write_deferred_reproducer (reproducer &r,
821 			     memento *ptr_type);
822 
823  private:
824   string * make_debug_string () FINAL OVERRIDE;
825   string * make_debug_string_with (const char *);
826   void write_reproducer (reproducer &r) FINAL OVERRIDE;
827 
828 private:
829   type *m_return_type;
830   auto_vec<type *> m_param_types;
831   int m_is_variadic;
832 };
833 
834 class field : public memento
835 {
836 public:
field(context * ctxt,location * loc,type * type,string * name)837   field (context *ctxt,
838 	 location *loc,
839 	 type *type,
840 	 string *name)
841   : memento (ctxt),
842     m_loc (loc),
843     m_type (type),
844     m_name (name),
845     m_container (NULL)
846   {}
847 
get_type()848   type * get_type () const { return m_type; }
849 
get_container()850   compound_type * get_container () const { return m_container; }
set_container(compound_type * c)851   void set_container (compound_type *c) { m_container = c; }
852 
853   void replay_into (replayer *) OVERRIDE;
854 
855   void write_to_dump (dump &d) OVERRIDE;
856 
857   playback::field *
playback_field()858   playback_field () const
859   {
860     return static_cast <playback::field *> (m_playback_obj);
861   }
862 
863 private:
864   string * make_debug_string () OVERRIDE;
865   void write_reproducer (reproducer &r) OVERRIDE;
866 
867 protected:
868   location *m_loc;
869   type *m_type;
870   string *m_name;
871   compound_type *m_container;
872 };
873 
874 
875 class bitfield : public field
876 {
877 public:
bitfield(context * ctxt,location * loc,type * type,int width,string * name)878   bitfield (context *ctxt,
879 	    location *loc,
880 	    type *type,
881 	    int width,
882 	    string *name)
883     : field (ctxt, loc, type, name),
884       m_width (width)
885   {}
886 
887   void replay_into (replayer *) FINAL OVERRIDE;
888 
889   void write_to_dump (dump &d) FINAL OVERRIDE;
890 
891 private:
892   string * make_debug_string () FINAL OVERRIDE;
893   void write_reproducer (reproducer &r) FINAL OVERRIDE;
894 
895 private:
896   int m_width;
897 };
898 
899 /* Base class for struct_ and union_ */
900 class compound_type : public type
901 {
902 public:
903   compound_type (context *ctxt,
904 		 location *loc,
905 		 string *name);
906 
get_name()907   string *get_name () const { return m_name; }
get_loc()908   location *get_loc () const { return m_loc; }
get_fields()909   fields * get_fields () { return m_fields; }
910 
911   void
912   set_fields (location *loc,
913 	      int num_fields,
914 	      field **fields);
915 
916   type *dereference () FINAL OVERRIDE;
917 
is_int()918   bool is_int () const FINAL OVERRIDE { return false; }
is_float()919   bool is_float () const FINAL OVERRIDE { return false; }
is_bool()920   bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()921   type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()922   type *is_array () FINAL OVERRIDE { return NULL; }
923 
has_known_size()924   bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
925 
926   playback::compound_type *
playback_compound_type()927   playback_compound_type ()
928   {
929     return static_cast <playback::compound_type *> (m_playback_obj);
930   }
931 
932 private:
933   location *m_loc;
934   string *m_name;
935   fields *m_fields;
936 };
937 
938 class struct_ : public compound_type
939 {
940 public:
941   struct_ (context *ctxt,
942 	   location *loc,
943 	   string *name);
944 
dyn_cast_struct()945   struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
946 
947   type *
as_type()948   as_type () { return this; }
949 
950   void replay_into (replayer *r) FINAL OVERRIDE;
951 
952   const char *access_as_type (reproducer &r) FINAL OVERRIDE;
953 
954 private:
955   string * make_debug_string () FINAL OVERRIDE;
956   void write_reproducer (reproducer &r) FINAL OVERRIDE;
957 };
958 
959 // memento of struct_::set_fields
960 class fields : public memento
961 {
962 public:
963   fields (compound_type *struct_or_union,
964 	  int num_fields,
965 	  field **fields);
966 
967   void replay_into (replayer *r) FINAL OVERRIDE;
968 
969   void write_to_dump (dump &d) FINAL OVERRIDE;
970 
length()971   int length () const { return m_fields.length (); }
get_field(int i)972   field *get_field (int i) const { return m_fields[i]; }
973 
974 private:
975   string * make_debug_string () FINAL OVERRIDE;
976   void write_reproducer (reproducer &r) FINAL OVERRIDE;
977 
978 private:
979   compound_type *m_struct_or_union;
980   auto_vec<field *> m_fields;
981 };
982 
983 class union_ : public compound_type
984 {
985 public:
986   union_ (context *ctxt,
987 	  location *loc,
988 	  string *name);
989 
990   void replay_into (replayer *r) FINAL OVERRIDE;
991 
992 private:
993   string * make_debug_string () FINAL OVERRIDE;
994   void write_reproducer (reproducer &r) FINAL OVERRIDE;
995 };
996 
997 /* An abstract base class for operations that visit all rvalues within an
998    expression tree.
999    Currently the only implementation is class rvalue_usage_validator within
1000    jit-recording.c.  */
1001 
1002 class rvalue_visitor
1003 {
1004  public:
~rvalue_visitor()1005   virtual ~rvalue_visitor () {}
1006   virtual void visit (rvalue *rvalue) = 0;
1007 };
1008 
1009 /* When generating debug strings for rvalues we mimic C, so we need to
1010    mimic C's precedence levels when handling compound expressions.
1011    These are in order from strongest precedence to weakest.  */
1012 enum precedence
1013 {
1014   PRECEDENCE_PRIMARY,
1015   PRECEDENCE_POSTFIX,
1016   PRECEDENCE_UNARY,
1017   PRECEDENCE_CAST,
1018   PRECEDENCE_MULTIPLICATIVE,
1019   PRECEDENCE_ADDITIVE,
1020   PRECEDENCE_SHIFT,
1021   PRECEDENCE_RELATIONAL,
1022   PRECEDENCE_EQUALITY,
1023   PRECEDENCE_BITWISE_AND,
1024   PRECEDENCE_BITWISE_XOR,
1025   PRECEDENCE_BITWISE_IOR,
1026   PRECEDENCE_LOGICAL_AND,
1027   PRECEDENCE_LOGICAL_OR
1028 };
1029 
1030 class rvalue : public memento
1031 {
1032 public:
rvalue(context * ctxt,location * loc,type * type_)1033   rvalue (context *ctxt,
1034 	  location *loc,
1035 	  type *type_)
1036   : memento (ctxt),
1037     m_loc (loc),
1038     m_type (type_),
1039     m_scope (NULL),
1040     m_parenthesized_string (NULL)
1041   {
1042     gcc_assert (type_);
1043   }
1044 
get_loc()1045   location * get_loc () const { return m_loc; }
1046 
1047   /* Get the recording::type of this rvalue.
1048 
1049      Implements the post-error-checking part of
1050      gcc_jit_rvalue_get_type.  */
get_type()1051   type * get_type () const { return m_type; }
1052 
1053   playback::rvalue *
playback_rvalue()1054   playback_rvalue () const
1055   {
1056     return static_cast <playback::rvalue *> (m_playback_obj);
1057   }
1058   rvalue *
1059   access_field (location *loc,
1060 		field *field);
1061 
1062   lvalue *
1063   dereference_field (location *loc,
1064 		     field *field);
1065 
1066   lvalue *
1067   dereference (location *loc);
1068 
1069   void
1070   verify_valid_within_stmt (const char *api_funcname, statement *s);
1071 
1072   virtual void visit_children (rvalue_visitor *v) = 0;
1073 
1074   void set_scope (function *scope);
get_scope()1075   function *get_scope () const { return m_scope; }
1076 
1077   /* Dynamic casts.  */
dyn_cast_param()1078   virtual param *dyn_cast_param () { return NULL; }
dyn_cast_base_call()1079   virtual base_call *dyn_cast_base_call () { return NULL; }
1080 
1081   virtual const char *access_as_rvalue (reproducer &r);
1082 
1083   /* Get the debug string, wrapped in parentheses.  */
1084   const char *
1085   get_debug_string_parens (enum precedence outer_prec);
1086 
is_constant()1087   virtual bool is_constant () const { return false; }
get_wide_int(wide_int *)1088   virtual bool get_wide_int (wide_int *) const { return false; }
1089 
1090 private:
1091   virtual enum precedence get_precedence () const = 0;
1092 
1093 protected:
1094   location *m_loc;
1095   type *m_type;
1096 
1097  private:
1098   function *m_scope; /* NULL for globals, non-NULL for locals/params */
1099   string *m_parenthesized_string;
1100 };
1101 
1102 class lvalue : public rvalue
1103 {
1104 public:
lvalue(context * ctxt,location * loc,type * type_)1105   lvalue (context *ctxt,
1106 	  location *loc,
1107 	  type *type_)
1108     : rvalue (ctxt, loc, type_)
1109     {}
1110 
1111   playback::lvalue *
playback_lvalue()1112   playback_lvalue () const
1113   {
1114     return static_cast <playback::lvalue *> (m_playback_obj);
1115   }
1116 
1117   lvalue *
1118   access_field (location *loc,
1119 		field *field);
1120 
1121   rvalue *
1122   get_address (location *loc);
1123 
1124   rvalue *
as_rvalue()1125   as_rvalue () { return this; }
1126 
1127   const char *access_as_rvalue (reproducer &r) OVERRIDE;
1128   virtual const char *access_as_lvalue (reproducer &r);
is_global()1129   virtual bool is_global () const { return false; }
1130 };
1131 
1132 class param : public lvalue
1133 {
1134 public:
param(context * ctxt,location * loc,type * type,string * name)1135   param (context *ctxt,
1136 	 location *loc,
1137 	 type *type,
1138 	 string *name)
1139     : lvalue (ctxt, loc, type),
1140     m_name (name) {}
1141 
1142   lvalue *
as_lvalue()1143   as_lvalue () { return this; }
1144 
1145   void replay_into (replayer *r) FINAL OVERRIDE;
1146 
visit_children(rvalue_visitor *)1147   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1148 
1149   playback::param *
playback_param()1150   playback_param () const
1151   {
1152     return static_cast <playback::param *> (m_playback_obj);
1153   }
1154 
dyn_cast_param()1155   param *dyn_cast_param () FINAL OVERRIDE { return this; }
1156 
1157   const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1158   const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1159 
1160 private:
make_debug_string()1161   string * make_debug_string () FINAL OVERRIDE { return m_name; }
1162   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1163   enum precedence get_precedence () const FINAL OVERRIDE
1164   {
1165     return PRECEDENCE_PRIMARY;
1166   }
1167 
1168 private:
1169   string *m_name;
1170 };
1171 
1172 class function : public memento
1173 {
1174 public:
1175   function (context *ctxt,
1176 	    location *loc,
1177 	    enum gcc_jit_function_kind kind,
1178 	    type *return_type,
1179 	    string *name,
1180 	    int num_params,
1181 	    param **params,
1182 	    int is_variadic,
1183 	    enum built_in_function builtin_id);
1184 
1185   void replay_into (replayer *r) FINAL OVERRIDE;
1186 
1187   playback::function *
playback_function()1188   playback_function () const
1189   {
1190     return static_cast <playback::function *> (m_playback_obj);
1191   }
1192 
get_kind()1193   enum gcc_jit_function_kind get_kind () const { return m_kind; }
1194 
1195   lvalue *
1196   new_local (location *loc,
1197 	     type *type,
1198 	     const char *name);
1199 
1200   block*
1201   new_block (const char *name);
1202 
get_loc()1203   location *get_loc () const { return m_loc; }
get_return_type()1204   type *get_return_type () const { return m_return_type; }
get_name()1205   string * get_name () const { return m_name; }
get_params()1206   const vec<param *> &get_params () const { return m_params; }
1207 
1208   /* Get the given param by index.
1209      Implements the post-error-checking part of
1210      gcc_jit_function_get_param.  */
get_param(int i)1211   param *get_param (int i) const { return m_params[i]; }
1212 
is_variadic()1213   bool is_variadic () const { return m_is_variadic; }
1214 
1215   void write_to_dump (dump &d) FINAL OVERRIDE;
1216 
1217   void validate ();
1218 
1219   void dump_to_dot (const char *path);
1220 
1221   rvalue *get_address (location *loc);
1222 
1223 private:
1224   string * make_debug_string () FINAL OVERRIDE;
1225   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1226 
1227 private:
1228   location *m_loc;
1229   enum gcc_jit_function_kind m_kind;
1230   type *m_return_type;
1231   string *m_name;
1232   auto_vec<param *> m_params;
1233   int m_is_variadic;
1234   enum built_in_function m_builtin_id;
1235   auto_vec<local *> m_locals;
1236   auto_vec<block *> m_blocks;
1237   type *m_fn_ptr_type;
1238 };
1239 
1240 class block : public memento
1241 {
1242 public:
block(function * func,int index,string * name)1243   block (function *func, int index, string *name)
1244   : memento (func->m_ctxt),
1245     m_func (func),
1246     m_index (index),
1247     m_name (name),
1248     m_statements (),
1249     m_has_been_terminated (false),
1250     m_is_reachable (false)
1251   {
1252   }
1253 
1254   /* Get the recording::function containing this block.
1255      Implements the post-error-checking part of
1256      gcc_jit_block_get_function.  */
get_function()1257   function *get_function () { return m_func; }
1258 
has_been_terminated()1259   bool has_been_terminated () { return m_has_been_terminated; }
is_reachable()1260   bool is_reachable () { return m_is_reachable; }
1261 
1262   statement *
1263   add_eval (location *loc,
1264 	    rvalue *rvalue);
1265 
1266   statement *
1267   add_assignment (location *loc,
1268 		  lvalue *lvalue,
1269 		  rvalue *rvalue);
1270 
1271   statement *
1272   add_assignment_op (location *loc,
1273 		     lvalue *lvalue,
1274 		     enum gcc_jit_binary_op op,
1275 		     rvalue *rvalue);
1276 
1277   statement *
1278   add_comment (location *loc,
1279 	       const char *text);
1280 
1281   extended_asm *
1282   add_extended_asm (location *loc,
1283 		    const char *asm_template);
1284 
1285   statement *
1286   end_with_conditional (location *loc,
1287 			rvalue *boolval,
1288 			block *on_true,
1289 			block *on_false);
1290 
1291   statement *
1292   end_with_jump (location *loc,
1293 		 block *target);
1294 
1295   statement *
1296   end_with_return (location *loc,
1297 		   rvalue *rvalue);
1298 
1299   statement *
1300   end_with_switch (location *loc,
1301 		   rvalue *expr,
1302 		   block *default_block,
1303 		   int num_cases,
1304 		   case_ **cases);
1305 
1306   extended_asm *
1307   end_with_extended_asm_goto (location *loc,
1308 			      const char *asm_template,
1309 			      int num_goto_blocks,
1310 			      block **goto_blocks,
1311 			      block *fallthrough_block);
1312 
1313   playback::block *
playback_block()1314   playback_block () const
1315   {
1316     return static_cast <playback::block *> (m_playback_obj);
1317   }
1318 
1319   void write_to_dump (dump &d) FINAL OVERRIDE;
1320 
1321   bool validate ();
1322 
1323   location *get_loc () const;
1324 
1325   statement *get_first_statement () const;
1326   statement *get_last_statement () const;
1327 
1328   vec <block *> get_successor_blocks () const;
1329 
1330 private:
1331   string * make_debug_string () FINAL OVERRIDE;
1332   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1333 
1334   void replay_into (replayer *r) FINAL OVERRIDE;
1335 
1336   void dump_to_dot (pretty_printer *pp);
1337   void dump_edges_to_dot (pretty_printer *pp);
1338 
1339 private:
1340   function *m_func;
1341   int m_index;
1342   string *m_name;
1343   auto_vec<statement *> m_statements;
1344   bool m_has_been_terminated;
1345   bool m_is_reachable;
1346 
1347   friend class function;
1348 };
1349 
1350 class global : public lvalue
1351 {
1352 public:
global(context * ctxt,location * loc,enum gcc_jit_global_kind kind,type * type,string * name)1353   global (context *ctxt,
1354 	  location *loc,
1355 	  enum gcc_jit_global_kind kind,
1356 	  type *type,
1357 	  string *name)
1358   : lvalue (ctxt, loc, type),
1359     m_kind (kind),
1360     m_name (name)
1361   {
1362     m_initializer = NULL;
1363     m_initializer_num_bytes = 0;
1364   }
~global()1365   ~global ()
1366   {
1367     free (m_initializer);
1368   }
1369 
1370   void replay_into (replayer *) FINAL OVERRIDE;
1371 
visit_children(rvalue_visitor *)1372   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1373 
1374   void write_to_dump (dump &d) FINAL OVERRIDE;
1375 
is_global()1376   bool is_global () const FINAL OVERRIDE { return true; }
1377 
1378   void
set_initializer(const void * initializer,size_t num_bytes)1379   set_initializer (const void *initializer,
1380                    size_t num_bytes)
1381   {
1382     if (m_initializer)
1383       free (m_initializer);
1384     m_initializer = xmalloc (num_bytes);
1385     memcpy (m_initializer, initializer, num_bytes);
1386     m_initializer_num_bytes = num_bytes;
1387   }
1388 
1389 private:
make_debug_string()1390   string * make_debug_string () FINAL OVERRIDE { return m_name; }
1391   template <typename T>
1392   void write_initializer_reproducer (const char *id, reproducer &r);
1393   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1394   enum precedence get_precedence () const FINAL OVERRIDE
1395   {
1396     return PRECEDENCE_PRIMARY;
1397   }
1398 
1399 private:
1400   enum gcc_jit_global_kind m_kind;
1401   string *m_name;
1402   void *m_initializer;
1403   size_t m_initializer_num_bytes;
1404 };
1405 
1406 template <typename HOST_TYPE>
1407 class memento_of_new_rvalue_from_const : public rvalue
1408 {
1409 public:
memento_of_new_rvalue_from_const(context * ctxt,location * loc,type * type,HOST_TYPE value)1410   memento_of_new_rvalue_from_const (context *ctxt,
1411 				    location *loc,
1412 				    type *type,
1413 				    HOST_TYPE value)
1414   : rvalue (ctxt, loc, type),
1415     m_value (value) {}
1416 
1417   void replay_into (replayer *r) FINAL OVERRIDE;
1418 
visit_children(rvalue_visitor *)1419   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1420 
is_constant()1421   bool is_constant () const FINAL OVERRIDE { return true; }
1422 
1423   bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1424 
1425 private:
1426   string * make_debug_string () FINAL OVERRIDE;
1427   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1428   enum precedence get_precedence () const FINAL OVERRIDE
1429   {
1430     return PRECEDENCE_PRIMARY;
1431   }
1432 
1433 private:
1434   HOST_TYPE m_value;
1435 };
1436 
1437 class memento_of_new_string_literal : public rvalue
1438 {
1439 public:
memento_of_new_string_literal(context * ctxt,location * loc,string * value)1440   memento_of_new_string_literal (context *ctxt,
1441 				 location *loc,
1442 				 string *value)
1443   : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1444     m_value (value) {}
1445 
1446   void replay_into (replayer *r) FINAL OVERRIDE;
1447 
visit_children(rvalue_visitor *)1448   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1449 
1450 private:
1451   string * make_debug_string () FINAL OVERRIDE;
1452   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1453   enum precedence get_precedence () const FINAL OVERRIDE
1454   {
1455     return PRECEDENCE_PRIMARY;
1456   }
1457 
1458 private:
1459   string *m_value;
1460 };
1461 
1462 class memento_of_new_rvalue_from_vector : public rvalue
1463 {
1464 public:
1465   memento_of_new_rvalue_from_vector (context *ctxt,
1466 				     location *loc,
1467 				     vector_type *type,
1468 				     rvalue **elements);
1469 
1470   void replay_into (replayer *r) FINAL OVERRIDE;
1471 
1472   void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1473 
1474 private:
1475   string * make_debug_string () FINAL OVERRIDE;
1476   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1477   enum precedence get_precedence () const FINAL OVERRIDE
1478   {
1479     return PRECEDENCE_PRIMARY;
1480   }
1481 
1482 private:
1483   vector_type *m_vector_type;
1484   auto_vec<rvalue *> m_elements;
1485 };
1486 
1487 class unary_op : public rvalue
1488 {
1489 public:
unary_op(context * ctxt,location * loc,enum gcc_jit_unary_op op,type * result_type,rvalue * a)1490   unary_op (context *ctxt,
1491 	    location *loc,
1492 	    enum gcc_jit_unary_op op,
1493 	    type *result_type,
1494 	    rvalue *a)
1495   : rvalue (ctxt, loc, result_type),
1496     m_op (op),
1497     m_a (a)
1498   {}
1499 
1500   void replay_into (replayer *r) FINAL OVERRIDE;
1501 
1502   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1503 
1504 private:
1505   string * make_debug_string () FINAL OVERRIDE;
1506   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1507   enum precedence get_precedence () const FINAL OVERRIDE
1508   {
1509     return PRECEDENCE_UNARY;
1510   }
1511 
1512 private:
1513   enum gcc_jit_unary_op m_op;
1514   rvalue *m_a;
1515 };
1516 
1517 class binary_op : public rvalue
1518 {
1519 public:
binary_op(context * ctxt,location * loc,enum gcc_jit_binary_op op,type * result_type,rvalue * a,rvalue * b)1520   binary_op (context *ctxt,
1521 	     location *loc,
1522 	     enum gcc_jit_binary_op op,
1523 	     type *result_type,
1524 	     rvalue *a, rvalue *b)
1525   : rvalue (ctxt, loc, result_type),
1526     m_op (op),
1527     m_a (a),
1528     m_b (b) {}
1529 
1530   void replay_into (replayer *r) FINAL OVERRIDE;
1531 
1532   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1533 
1534 private:
1535   string * make_debug_string () FINAL OVERRIDE;
1536   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1537   enum precedence get_precedence () const FINAL OVERRIDE;
1538 
1539 private:
1540   enum gcc_jit_binary_op m_op;
1541   rvalue *m_a;
1542   rvalue *m_b;
1543 };
1544 
1545 class comparison : public rvalue
1546 {
1547 public:
comparison(context * ctxt,location * loc,enum gcc_jit_comparison op,rvalue * a,rvalue * b)1548   comparison (context *ctxt,
1549 	      location *loc,
1550 	      enum gcc_jit_comparison op,
1551 	      rvalue *a, rvalue *b)
1552   : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1553     m_op (op),
1554     m_a (a),
1555     m_b (b)
1556   {}
1557 
1558   void replay_into (replayer *r) FINAL OVERRIDE;
1559 
1560   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1561 
1562 private:
1563   string * make_debug_string () FINAL OVERRIDE;
1564   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1565   enum precedence get_precedence () const FINAL OVERRIDE;
1566 
1567 private:
1568   enum gcc_jit_comparison m_op;
1569   rvalue *m_a;
1570   rvalue *m_b;
1571 };
1572 
1573 class cast : public rvalue
1574 {
1575 public:
cast(context * ctxt,location * loc,rvalue * a,type * type_)1576   cast (context *ctxt,
1577 	location *loc,
1578 	rvalue *a,
1579 	type *type_)
1580   : rvalue (ctxt, loc, type_),
1581     m_rvalue (a)
1582   {}
1583 
1584   void replay_into (replayer *r) FINAL OVERRIDE;
1585 
1586   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1587 
1588 private:
1589   string * make_debug_string () FINAL OVERRIDE;
1590   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1591   enum precedence get_precedence () const FINAL OVERRIDE
1592   {
1593     return PRECEDENCE_CAST;
1594   }
1595 
1596 private:
1597   rvalue *m_rvalue;
1598 };
1599 
1600 class base_call : public rvalue
1601 {
1602  public:
1603   base_call (context *ctxt,
1604 	     location *loc,
1605 	     type *type_,
1606 	     int numargs,
1607 	     rvalue **args);
1608 
get_precedence()1609   enum precedence get_precedence () const FINAL OVERRIDE
1610   {
1611     return PRECEDENCE_POSTFIX;
1612   }
1613 
dyn_cast_base_call()1614   base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1615 
set_require_tail_call(bool require_tail_call)1616   void set_require_tail_call (bool require_tail_call)
1617   {
1618     m_require_tail_call = require_tail_call;
1619   }
1620 
1621  protected:
1622   void write_reproducer_tail_call (reproducer &r, const char *id);
1623 
1624  protected:
1625   auto_vec<rvalue *> m_args;
1626   bool m_require_tail_call;
1627 };
1628 
1629 class call : public base_call
1630 {
1631 public:
1632   call (context *ctxt,
1633 	location *loc,
1634 	function *func,
1635 	int numargs,
1636 	rvalue **args);
1637 
1638   void replay_into (replayer *r) FINAL OVERRIDE;
1639 
1640   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1641 
1642 private:
1643   string * make_debug_string () FINAL OVERRIDE;
1644   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1645 
1646 private:
1647   function *m_func;
1648 };
1649 
1650 class call_through_ptr : public base_call
1651 {
1652 public:
1653   call_through_ptr (context *ctxt,
1654 		    location *loc,
1655 		    rvalue *fn_ptr,
1656 		    int numargs,
1657 		    rvalue **args);
1658 
1659   void replay_into (replayer *r) FINAL OVERRIDE;
1660 
1661   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1662 
1663 private:
1664   string * make_debug_string () FINAL OVERRIDE;
1665   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1666 
1667 private:
1668   rvalue *m_fn_ptr;
1669 };
1670 
1671 class array_access : public lvalue
1672 {
1673 public:
array_access(context * ctxt,location * loc,rvalue * ptr,rvalue * index)1674   array_access (context *ctxt,
1675 		location *loc,
1676 		rvalue *ptr,
1677 		rvalue *index)
1678   : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1679     m_ptr (ptr),
1680     m_index (index)
1681   {}
1682 
1683   void replay_into (replayer *r) FINAL OVERRIDE;
1684 
1685   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1686 
1687 private:
1688   string * make_debug_string () FINAL OVERRIDE;
1689   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1690   enum precedence get_precedence () const FINAL OVERRIDE
1691   {
1692     return PRECEDENCE_POSTFIX;
1693   }
1694 
1695 private:
1696   rvalue *m_ptr;
1697   rvalue *m_index;
1698 };
1699 
1700 class access_field_of_lvalue : public lvalue
1701 {
1702 public:
access_field_of_lvalue(context * ctxt,location * loc,lvalue * val,field * field)1703   access_field_of_lvalue (context *ctxt,
1704 			  location *loc,
1705 			  lvalue *val,
1706 			  field *field)
1707   : lvalue (ctxt, loc, field->get_type ()),
1708     m_lvalue (val),
1709     m_field (field)
1710   {}
1711 
1712   void replay_into (replayer *r) FINAL OVERRIDE;
1713 
1714   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1715 
1716 private:
1717   string * make_debug_string () FINAL OVERRIDE;
1718   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1719   enum precedence get_precedence () const FINAL OVERRIDE
1720   {
1721     return PRECEDENCE_POSTFIX;
1722   }
1723 
1724 private:
1725   lvalue *m_lvalue;
1726   field *m_field;
1727 };
1728 
1729 class access_field_rvalue : public rvalue
1730 {
1731 public:
access_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1732   access_field_rvalue (context *ctxt,
1733 		       location *loc,
1734 		       rvalue *val,
1735 		       field *field)
1736   : rvalue (ctxt, loc, field->get_type ()),
1737     m_rvalue (val),
1738     m_field (field)
1739   {}
1740 
1741   void replay_into (replayer *r) FINAL OVERRIDE;
1742 
1743   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1744 
1745 private:
1746   string * make_debug_string () FINAL OVERRIDE;
1747   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1748   enum precedence get_precedence () const FINAL OVERRIDE
1749   {
1750     return PRECEDENCE_POSTFIX;
1751   }
1752 
1753 private:
1754   rvalue *m_rvalue;
1755   field *m_field;
1756 };
1757 
1758 class dereference_field_rvalue : public lvalue
1759 {
1760 public:
dereference_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1761   dereference_field_rvalue (context *ctxt,
1762 			    location *loc,
1763 			    rvalue *val,
1764 			    field *field)
1765   : lvalue (ctxt, loc, field->get_type ()),
1766     m_rvalue (val),
1767     m_field (field)
1768   {}
1769 
1770   void replay_into (replayer *r) FINAL OVERRIDE;
1771 
1772   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1773 
1774 private:
1775   string * make_debug_string () FINAL OVERRIDE;
1776   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1777   enum precedence get_precedence () const FINAL OVERRIDE
1778   {
1779     return PRECEDENCE_POSTFIX;
1780   }
1781 
1782 private:
1783   rvalue *m_rvalue;
1784   field *m_field;
1785 };
1786 
1787 class dereference_rvalue : public lvalue
1788 {
1789 public:
dereference_rvalue(context * ctxt,location * loc,rvalue * val)1790   dereference_rvalue (context *ctxt,
1791 		      location *loc,
1792 		      rvalue *val)
1793   : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1794     m_rvalue (val) {}
1795 
1796   void replay_into (replayer *r) FINAL OVERRIDE;
1797 
1798   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1799 
1800 private:
1801   string * make_debug_string () FINAL OVERRIDE;
1802   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1803   enum precedence get_precedence () const FINAL OVERRIDE
1804   {
1805     return PRECEDENCE_UNARY;
1806   }
1807 
1808 private:
1809   rvalue *m_rvalue;
1810 };
1811 
1812 class get_address_of_lvalue : public rvalue
1813 {
1814 public:
get_address_of_lvalue(context * ctxt,location * loc,lvalue * val)1815   get_address_of_lvalue (context *ctxt,
1816 			 location *loc,
1817 			 lvalue *val)
1818   : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1819     m_lvalue (val)
1820   {}
1821 
1822   void replay_into (replayer *r) FINAL OVERRIDE;
1823 
1824   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1825 
1826 private:
1827   string * make_debug_string () FINAL OVERRIDE;
1828   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1829   enum precedence get_precedence () const FINAL OVERRIDE
1830   {
1831     return PRECEDENCE_UNARY;
1832   }
1833 
1834 private:
1835   lvalue *m_lvalue;
1836 };
1837 
1838 class function_pointer : public rvalue
1839 {
1840 public:
function_pointer(context * ctxt,location * loc,function * fn,type * type)1841   function_pointer (context *ctxt,
1842 		    location *loc,
1843 		    function *fn,
1844 		    type *type)
1845   : rvalue (ctxt, loc, type),
1846     m_fn (fn) {}
1847 
1848   void replay_into (replayer *r) FINAL OVERRIDE;
1849 
1850   void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1851 
1852 private:
1853   string * make_debug_string () FINAL OVERRIDE;
1854   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1855   enum precedence get_precedence () const FINAL OVERRIDE
1856   {
1857     return PRECEDENCE_UNARY;
1858   }
1859 
1860 private:
1861   function *m_fn;
1862 };
1863 
1864 class local : public lvalue
1865 {
1866 public:
local(function * func,location * loc,type * type_,string * name)1867   local (function *func, location *loc, type *type_, string *name)
1868     : lvalue (func->m_ctxt, loc, type_),
1869     m_func (func),
1870     m_name (name)
1871   {
1872     set_scope (func);
1873   }
1874 
1875   void replay_into (replayer *r) FINAL OVERRIDE;
1876 
visit_children(rvalue_visitor *)1877   void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1878 
1879   void write_to_dump (dump &d) FINAL OVERRIDE;
1880 
1881 private:
make_debug_string()1882   string * make_debug_string () FINAL OVERRIDE { return m_name; }
1883   void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1884   enum precedence get_precedence () const FINAL OVERRIDE
1885   {
1886     return PRECEDENCE_PRIMARY;
1887   }
1888 
1889 private:
1890   function *m_func;
1891   string *m_name;
1892 };
1893 
1894 class statement : public memento
1895 {
1896 public:
1897   virtual vec <block *> get_successor_blocks () const;
1898 
1899   void write_to_dump (dump &d) FINAL OVERRIDE;
1900 
get_block()1901   block *get_block () const { return m_block; }
get_loc()1902   location *get_loc () const { return m_loc; }
1903 
1904 protected:
statement(block * b,location * loc)1905   statement (block *b, location *loc)
1906   : memento (b->m_ctxt),
1907     m_block (b),
1908     m_loc (loc) {}
1909 
1910   playback::location *
playback_location(replayer * r)1911   playback_location (replayer *r) const
1912   {
1913     return ::gcc::jit::recording::playback_location (r, m_loc);
1914   }
1915 
1916 private:
1917   block *m_block;
1918   location *m_loc;
1919 };
1920 
1921 class eval : public statement
1922 {
1923 public:
eval(block * b,location * loc,rvalue * rvalue)1924   eval (block *b,
1925 	location *loc,
1926 	rvalue *rvalue)
1927   : statement (b, loc),
1928     m_rvalue (rvalue) {}
1929 
1930   void replay_into (replayer *r) FINAL OVERRIDE;
1931 
1932 private:
1933   string * make_debug_string () FINAL OVERRIDE;
1934   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1935 
1936 private:
1937   rvalue *m_rvalue;
1938 };
1939 
1940 class assignment : public statement
1941 {
1942 public:
assignment(block * b,location * loc,lvalue * lvalue,rvalue * rvalue)1943   assignment (block *b,
1944 	      location *loc,
1945 	      lvalue *lvalue,
1946 	      rvalue *rvalue)
1947   : statement (b, loc),
1948     m_lvalue (lvalue),
1949     m_rvalue (rvalue) {}
1950 
1951   void replay_into (replayer *r) FINAL OVERRIDE;
1952 
1953 private:
1954   string * make_debug_string () FINAL OVERRIDE;
1955   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1956 
1957 private:
1958   lvalue *m_lvalue;
1959   rvalue *m_rvalue;
1960 };
1961 
1962 class assignment_op : public statement
1963 {
1964 public:
assignment_op(block * b,location * loc,lvalue * lvalue,enum gcc_jit_binary_op op,rvalue * rvalue)1965   assignment_op (block *b,
1966 		 location *loc,
1967 		 lvalue *lvalue,
1968 		 enum gcc_jit_binary_op op,
1969 		 rvalue *rvalue)
1970   : statement (b, loc),
1971     m_lvalue (lvalue),
1972     m_op (op),
1973     m_rvalue (rvalue) {}
1974 
1975   void replay_into (replayer *r) FINAL OVERRIDE;
1976 
1977 private:
1978   string * make_debug_string () FINAL OVERRIDE;
1979   void write_reproducer (reproducer &r) FINAL OVERRIDE;
1980 
1981 private:
1982   lvalue *m_lvalue;
1983   enum gcc_jit_binary_op m_op;
1984   rvalue *m_rvalue;
1985 };
1986 
1987 class comment : public statement
1988 {
1989 public:
comment(block * b,location * loc,string * text)1990   comment (block *b,
1991 	   location *loc,
1992 	   string *text)
1993   : statement (b, loc),
1994     m_text (text) {}
1995 
1996   void replay_into (replayer *r) FINAL OVERRIDE;
1997 
1998 private:
1999   string * make_debug_string () FINAL OVERRIDE;
2000   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2001 
2002 private:
2003   string *m_text;
2004 };
2005 
2006 class conditional : public statement
2007 {
2008 public:
conditional(block * b,location * loc,rvalue * boolval,block * on_true,block * on_false)2009   conditional (block *b,
2010 	       location *loc,
2011 	       rvalue *boolval,
2012 	       block *on_true,
2013 	       block *on_false)
2014   : statement (b, loc),
2015     m_boolval (boolval),
2016     m_on_true (on_true),
2017     m_on_false (on_false) {}
2018 
2019   void replay_into (replayer *r) FINAL OVERRIDE;
2020 
2021   vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2022 
2023 private:
2024   string * make_debug_string () FINAL OVERRIDE;
2025   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2026 
2027 private:
2028   rvalue *m_boolval;
2029   block *m_on_true;
2030   block *m_on_false;
2031 };
2032 
2033 class jump : public statement
2034 {
2035 public:
jump(block * b,location * loc,block * target)2036   jump (block *b,
2037 	location *loc,
2038 	block *target)
2039   : statement (b, loc),
2040     m_target (target) {}
2041 
2042   void replay_into (replayer *r) FINAL OVERRIDE;
2043 
2044   vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2045 
2046 private:
2047   string * make_debug_string () FINAL OVERRIDE;
2048   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2049 
2050 private:
2051   block *m_target;
2052 };
2053 
2054 class return_ : public statement
2055 {
2056 public:
return_(block * b,location * loc,rvalue * rvalue)2057   return_ (block *b,
2058 	   location *loc,
2059 	   rvalue *rvalue)
2060   : statement (b, loc),
2061     m_rvalue (rvalue) {}
2062 
2063   void replay_into (replayer *r) FINAL OVERRIDE;
2064 
2065   vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2066 
2067 private:
2068   string * make_debug_string () FINAL OVERRIDE;
2069   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2070 
2071 private:
2072   rvalue *m_rvalue;
2073 };
2074 
2075 class case_ : public memento
2076 {
2077  public:
case_(context * ctxt,rvalue * min_value,rvalue * max_value,block * dest_block)2078   case_ (context *ctxt,
2079 	 rvalue *min_value,
2080 	 rvalue *max_value,
2081 	 block *dest_block)
2082   : memento (ctxt),
2083     m_min_value (min_value),
2084     m_max_value (max_value),
2085     m_dest_block (dest_block)
2086   {}
2087 
get_min_value()2088   rvalue *get_min_value () const { return m_min_value; }
get_max_value()2089   rvalue *get_max_value () const { return m_max_value; }
get_dest_block()2090   block *get_dest_block () const { return m_dest_block; }
2091 
replay_into(replayer *)2092   void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
2093 
2094   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2095 
2096 private:
2097   string * make_debug_string () FINAL OVERRIDE;
2098 
2099  private:
2100   rvalue *m_min_value;
2101   rvalue *m_max_value;
2102   block *m_dest_block;
2103 };
2104 
2105 class switch_ : public statement
2106 {
2107 public:
2108   switch_ (block *b,
2109 	   location *loc,
2110 	   rvalue *expr,
2111 	   block *default_block,
2112 	   int num_cases,
2113 	   case_ **cases);
2114 
2115   void replay_into (replayer *r) FINAL OVERRIDE;
2116 
2117   vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2118 
2119 private:
2120   string * make_debug_string () FINAL OVERRIDE;
2121   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2122 
2123 private:
2124   rvalue *m_expr;
2125   block *m_default_block;
2126   auto_vec <case_ *> m_cases;
2127 };
2128 
2129 class asm_operand : public memento
2130 {
2131 public:
2132   asm_operand (extended_asm *ext_asm,
2133 	       string *asm_symbolic_name,
2134 	       string *constraint);
2135 
get_symbolic_name()2136   const char *get_symbolic_name () const
2137   {
2138     if (m_asm_symbolic_name)
2139       return m_asm_symbolic_name->c_str ();
2140     else
2141       return NULL;
2142   }
2143 
get_constraint()2144   const char *get_constraint () const
2145   {
2146     return m_constraint->c_str ();
2147   }
2148 
2149   virtual void print (pretty_printer *pp) const;
2150 
2151 private:
2152   string * make_debug_string () FINAL OVERRIDE;
2153 
2154 protected:
2155   extended_asm *m_ext_asm;
2156   string *m_asm_symbolic_name;
2157   string *m_constraint;
2158 };
2159 
2160 class output_asm_operand : public asm_operand
2161 {
2162 public:
output_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,lvalue * dest)2163   output_asm_operand (extended_asm *ext_asm,
2164 		      string *asm_symbolic_name,
2165 		      string *constraint,
2166 		      lvalue *dest)
2167   : asm_operand (ext_asm, asm_symbolic_name, constraint),
2168     m_dest (dest)
2169   {}
2170 
get_lvalue()2171   lvalue *get_lvalue () const { return m_dest; }
2172 
replay_into(replayer *)2173   void replay_into (replayer *) FINAL OVERRIDE {}
2174 
2175   void print (pretty_printer *pp) const FINAL OVERRIDE;
2176 
2177 private:
2178   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2179 
2180 private:
2181   lvalue *m_dest;
2182 };
2183 
2184 class input_asm_operand : public asm_operand
2185 {
2186 public:
input_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,rvalue * src)2187   input_asm_operand (extended_asm *ext_asm,
2188 		     string *asm_symbolic_name,
2189 		     string *constraint,
2190 		     rvalue *src)
2191   : asm_operand (ext_asm, asm_symbolic_name, constraint),
2192     m_src (src)
2193   {}
2194 
get_rvalue()2195   rvalue *get_rvalue () const { return m_src; }
2196 
replay_into(replayer *)2197   void replay_into (replayer *) FINAL OVERRIDE {}
2198 
2199   void print (pretty_printer *pp) const FINAL OVERRIDE;
2200 
2201 private:
2202   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2203 
2204 private:
2205   rvalue *m_src;
2206 };
2207 
2208 /* Abstract base class for extended_asm statements.  */
2209 
2210 class extended_asm : public statement
2211 {
2212 public:
extended_asm(block * b,location * loc,string * asm_template)2213   extended_asm (block *b,
2214 		location *loc,
2215 		string *asm_template)
2216   : statement (b, loc),
2217     m_asm_template (asm_template),
2218     m_is_volatile (false),
2219     m_is_inline (false)
2220   {}
2221 
set_volatile_flag(bool flag)2222   void set_volatile_flag (bool flag) { m_is_volatile = flag; }
set_inline_flag(bool flag)2223   void set_inline_flag (bool flag) { m_is_inline = flag; }
2224 
2225   void add_output_operand (const char *asm_symbolic_name,
2226 			   const char *constraint,
2227 			   lvalue *dest);
2228   void add_input_operand (const char *asm_symbolic_name,
2229 			  const char *constraint,
2230 			  rvalue *src);
2231   void add_clobber (const char *victim);
2232 
2233   void replay_into (replayer *r) OVERRIDE;
2234 
get_asm_template()2235   string *get_asm_template () const { return m_asm_template; }
2236 
2237   virtual bool is_goto () const = 0;
2238   virtual void maybe_print_gotos (pretty_printer *) const = 0;
2239 
2240 protected:
2241   void write_flags (reproducer &r);
2242   void write_clobbers (reproducer &r);
2243 
2244 private:
2245   string * make_debug_string () FINAL OVERRIDE;
2246   virtual void maybe_populate_playback_blocks
2247     (auto_vec <playback::block *> *out) = 0;
2248 
2249 protected:
2250   string *m_asm_template;
2251   bool m_is_volatile;
2252   bool m_is_inline;
2253   auto_vec<output_asm_operand *> m_output_ops;
2254   auto_vec<input_asm_operand *> m_input_ops;
2255   auto_vec<string *> m_clobbers;
2256 };
2257 
2258 /* An extended_asm that's not a goto, as created by
2259    gcc_jit_block_add_extended_asm. */
2260 
2261 class extended_asm_simple : public extended_asm
2262 {
2263 public:
extended_asm_simple(block * b,location * loc,string * asm_template)2264   extended_asm_simple (block *b,
2265 		       location *loc,
2266 		       string *asm_template)
2267   : extended_asm (b, loc, asm_template)
2268   {}
2269 
2270   void write_reproducer (reproducer &r) OVERRIDE;
is_goto()2271   bool is_goto () const FINAL OVERRIDE { return false; }
maybe_print_gotos(pretty_printer *)2272   void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
2273 
2274 private:
maybe_populate_playback_blocks(auto_vec<playback::block * > *)2275   void maybe_populate_playback_blocks
2276     (auto_vec <playback::block *> *) FINAL OVERRIDE
2277   {}
2278 };
2279 
2280 /* An extended_asm that's a asm goto, as created by
2281    gcc_jit_block_end_with_extended_asm_goto.  */
2282 
2283 class extended_asm_goto : public extended_asm
2284 {
2285 public:
2286   extended_asm_goto (block *b,
2287 		     location *loc,
2288 		     string *asm_template,
2289 		     int num_goto_blocks,
2290 		     block **goto_blocks,
2291 		     block *fallthrough_block);
2292 
2293   void replay_into (replayer *r) FINAL OVERRIDE;
2294   void write_reproducer (reproducer &r) OVERRIDE;
2295 
2296   vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2297 
is_goto()2298   bool is_goto () const FINAL OVERRIDE { return true; }
2299   void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
2300 
2301 private:
2302   void maybe_populate_playback_blocks
2303     (auto_vec <playback::block *> *out) FINAL OVERRIDE;
2304 
2305 private:
2306   auto_vec <block *> m_goto_blocks;
2307   block *m_fallthrough_block;
2308 };
2309 
2310 /* A group of top-level asm statements, as created by
2311    gcc_jit_context_add_top_level_asm.  */
2312 
2313 class top_level_asm : public memento
2314 {
2315 public:
2316   top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2317 
2318   void write_to_dump (dump &d) FINAL OVERRIDE;
2319 
2320 private:
2321   void replay_into (replayer *r) FINAL OVERRIDE;
2322   string * make_debug_string () FINAL OVERRIDE;
2323   void write_reproducer (reproducer &r) FINAL OVERRIDE;
2324 
2325 private:
2326   location *m_loc;
2327   string *m_asm_stmts;
2328 };
2329 
2330 } // namespace gcc::jit::recording
2331 
2332 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2333    it to this context's list of mementos.
2334 
2335    Implements the post-error-checking part of
2336    gcc_jit_context_new_rvalue_from_{int|long|double|ptr}.  */
2337 
2338 template <typename HOST_TYPE>
2339 recording::rvalue *
new_rvalue_from_const(recording::type * type,HOST_TYPE value)2340 recording::context::new_rvalue_from_const (recording::type *type,
2341 					   HOST_TYPE value)
2342 {
2343   recording::rvalue *result =
2344     new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2345   record (result);
2346   return result;
2347 }
2348 
2349 } // namespace gcc::jit
2350 
2351 } // namespace gcc
2352 
2353 #endif /* JIT_RECORDING_H */
2354