1/* Internals of libgccjit: classes for recording calls made to the JIT API.
2   Copyright (C) 2013-2022 Free Software Foundation, Inc.
3   Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3.  If not see
19<http://www.gnu.org/licenses/>.  */
20
21#include "config.h"
22#define INCLUDE_PTHREAD_H
23#include "system.h"
24#include "coretypes.h"
25#include "tm.h"
26#include "pretty-print.h"
27#include "toplev.h"
28
29
30#include "jit-builtins.h"
31#include "jit-recording.h"
32#include "jit-playback.h"
33
34namespace gcc {
35namespace jit {
36
37// class dump
38
39dump::dump (recording::context &ctxt,
40	    const char *filename,
41	    bool update_locations)
42: m_ctxt (ctxt),
43  m_filename (filename),
44  m_update_locations (update_locations),
45  m_line (0),
46  m_column (0)
47{
48  m_file = fopen (filename, "w");
49  if (!m_file)
50    ctxt.add_error (NULL,
51		    "error opening dump file %s for writing: %s",
52		    filename,
53		    xstrerror (errno));
54}
55
56dump::~dump ()
57{
58  if (m_file)
59    {
60      int err = fclose (m_file);
61      if (err)
62	m_ctxt.add_error (NULL,
63			  "error closing dump file %s: %s",
64			  m_filename,
65			  xstrerror (errno));
66    }
67}
68
69/* Write the given message to the dump, using printf-formatting
70   conventions, updating the line/column within the dump.
71
72   Emit an error on the context if a failure occurs.  */
73
74void
75dump::write (const char *fmt, ...)
76{
77  int len;
78  va_list ap;
79  char *buf;
80
81  /* If there was an error opening the file, we've already reported it.
82     Don't attempt further work.  */
83  if (!m_file)
84    return;
85
86  va_start (ap, fmt);
87  len = vasprintf (&buf, fmt, ap);
88  va_end (ap);
89
90  if (buf == NULL || len < 0)
91    {
92      m_ctxt.add_error (NULL, "malloc failure writing to dumpfile %s",
93			m_filename);
94      return;
95    }
96
97  if (fwrite (buf, strlen (buf), 1, m_file) != 1)
98    m_ctxt.add_error (NULL, "error writing to dump file %s",
99		      m_filename);
100
101  /* Flush after each line, to ease debugging crashes.  */
102  fflush (m_file);
103
104  /* Update line/column: */
105  for (const char *ptr = buf; *ptr; ptr++)
106    {
107      if ('\n' == *ptr)
108	{
109	  m_line++;
110	  m_column = 0;
111	}
112      else
113	m_column++;
114    }
115
116  free (buf);
117}
118
119/* Construct a gcc::jit::recording::location instance for the current
120   location within the dump.  */
121
122recording::location *
123dump::make_location () const
124{
125  return m_ctxt.new_location (m_filename, m_line, m_column,
126			      /* We need to flag such locations as *not*
127				 created by the user, so that
128				 reproducer::get_identifier can cope with
129				 them appearing *after* the memento that
130				 refers to them.  */
131			      false);
132}
133
134/* A collection of allocations, all of which can be released together, to
135   avoid needing to track and release them individually.  */
136
137class allocator
138{
139 public:
140  ~allocator ();
141
142  char *
143  xstrdup_printf (const char *, ...)
144    ATTRIBUTE_RETURNS_NONNULL
145    GNU_PRINTF(2, 3);
146
147  char *
148  xstrdup_printf_va (const char *, va_list ap)
149    ATTRIBUTE_RETURNS_NONNULL
150    GNU_PRINTF(2, 0);
151
152 private:
153  auto_vec <void *> m_buffers;
154};
155
156/* allocator's destructor.  Call "free" on all of the allocations.  */
157
158allocator::~allocator ()
159{
160  unsigned i;
161  void *buffer;
162  FOR_EACH_VEC_ELT (m_buffers, i, buffer)
163    free (buffer);
164}
165
166/* Formatted printing, allocating to a buffer (or exiting the process if
167   the allocation fails).
168
169   The buffer exists until the allocator is cleaned up, and is freed at
170   that point, so the caller doesn't need to track the result.  */
171
172char *
173allocator::xstrdup_printf (const char *fmt, ...)
174{
175  char *result;
176  va_list ap;
177  va_start (ap, fmt);
178  result = xstrdup_printf_va (fmt, ap);
179  va_end (ap);
180  return result;
181}
182
183/* Formatted printing, allocating to a buffer (or exiting the process if
184   the allocation fails).
185
186   The buffer exists until the allocator is cleaned up, and is freed at
187   that point, so the caller doesn't need to track the result.  */
188
189char *
190allocator::xstrdup_printf_va (const char *fmt, va_list ap)
191{
192  char *result = xvasprintf (fmt, ap);
193  m_buffers.safe_push (result);
194  return result;
195}
196
197/* gcc::jit::reproducer is a subclass of gcc::jit::dump, used for
198   implementing gcc_jit_context_dump_reproducer_to_file.  */
199
200class reproducer : public dump
201{
202 public:
203  reproducer (recording::context &ctxt,
204	      const char *filename);
205
206  void
207  write_params (const vec <recording::context *> &contexts);
208
209  void
210  write_args (const vec <recording::context *> &contexts);
211
212  const char *
213  make_identifier (recording::memento *m, const char *prefix);
214
215  const char *
216  make_tmp_identifier (const char *prefix, recording::memento *m);
217
218  const char *
219  get_identifier (recording::context *ctxt);
220
221  const char *
222  get_identifier (recording::memento *m);
223
224  const char *
225  get_identifier_as_rvalue (recording::rvalue *m);
226
227  const char *
228  get_identifier_as_lvalue (recording::lvalue *m);
229
230  const char *
231  get_identifier_as_type (recording::type *m);
232
233  char *
234  xstrdup_printf (const char *, ...)
235    ATTRIBUTE_RETURNS_NONNULL
236    GNU_PRINTF(2, 3);
237
238 private:
239  const char * ensure_identifier_is_unique (const char *candidate, void *ptr);
240
241 private:
242  hash_map<recording::memento *, const char *> m_map_memento_to_identifier;
243
244  struct hash_traits : public string_hash
245  {
246    static void remove (const char *) {}
247  };
248  hash_set<const char *, false, hash_traits> m_set_identifiers;
249  allocator m_allocator;
250};
251
252/* gcc::jit::reproducer's constructor.  */
253
254reproducer::reproducer (recording::context &ctxt,
255			const char *filename) :
256  dump (ctxt, filename, 0),
257  m_map_memento_to_identifier (),
258  m_set_identifiers (),
259  m_allocator ()
260{
261}
262
263/* Write out a list of contexts as a set of parameters within a
264   C function declaration.  */
265
266void
267reproducer::write_params (const vec <recording::context *> &contexts)
268{
269  unsigned i;
270  recording::context *ctxt;
271  FOR_EACH_VEC_ELT (contexts, i, ctxt)
272    {
273      write ("gcc_jit_context *%s",
274	     get_identifier (ctxt));
275      if (i < contexts.length () - 1)
276	write (",\n"
277	       "             ");
278    }
279}
280
281/* Write out a list of contexts as a set of arguments within a call
282   to a C function.  */
283
284void
285reproducer::write_args (const vec <recording::context *> &contexts)
286{
287  unsigned i;
288  recording::context *ctxt;
289  FOR_EACH_VEC_ELT (contexts, i, ctxt)
290    {
291      write ("%s",
292	     get_identifier (ctxt));
293      if (i < contexts.length () - 1)
294	write (",\n"
295	       "               ");
296    }
297}
298
299/* Ensure that STR is a valid C identifier by overwriting
300   any invalid chars in-place with underscores.
301
302   This doesn't special-case the first character.  */
303
304static void
305convert_to_identifier (char *str)
306{
307  for (char *p = str; *p; p++)
308    if (!ISALNUM (*p))
309      *p = '_';
310}
311
312/* Given CANDIDATE, a possible C identifier for use in a reproducer,
313   ensure that it is unique within the generated source file by
314   appending PTR to it if necessary.  Return the resulting string.
315
316   The reproducer will eventually clean up the buffer in its dtor.  */
317
318const char *
319reproducer::ensure_identifier_is_unique (const char *candidate, void *ptr)
320{
321  if (m_set_identifiers.contains (candidate))
322    candidate = m_allocator.xstrdup_printf ("%s_%p", candidate, ptr);
323  gcc_assert (!m_set_identifiers.contains (candidate));
324  m_set_identifiers.add (candidate);
325  return candidate;
326}
327
328/* Generate a C identifier for the given memento, associating the generated
329   buffer with the memento (for future calls to get_identifier et al).
330
331   The reproducer will eventually clean up the buffer in its dtor.  */
332const char *
333reproducer::make_identifier (recording::memento *m, const char *prefix)
334{
335  const char *result;
336  if (strlen (m->get_debug_string ()) < 100)
337    {
338      char *buf = m_allocator.xstrdup_printf ("%s_%s",
339					      prefix,
340					      m->get_debug_string ());
341      convert_to_identifier (buf);
342      result = buf;
343    }
344  else
345    result = m_allocator.xstrdup_printf ("%s_%p",
346					 prefix, (void *) m);
347  result = ensure_identifier_is_unique (result, m);
348  m_map_memento_to_identifier.put (m, result);
349  return result;
350}
351
352/* Generate a C identifier for a temporary variable.
353   The reproducer will eventually clean up the buffer in its dtor.  */
354
355const char *
356reproducer::make_tmp_identifier (const char *prefix, recording::memento *m)
357{
358  return m_allocator.xstrdup_printf ("%s_%s",
359				     prefix, get_identifier (m));
360}
361
362/* Generate a C identifier for the given context.
363   The reproducer will eventually clean up the buffer in its dtor.  */
364
365const char *
366reproducer::get_identifier (recording::context *ctxt)
367{
368  return m_allocator.xstrdup_printf ("ctxt_%p",
369				     (void *)ctxt);
370}
371
372/* Locate the C identifier for the given memento, which is assumed to
373   have already been created via make_identifier.  */
374
375const char *
376reproducer::get_identifier (recording::memento *m)
377{
378  if (!m)
379    return "NULL";
380
381  /* gcc_jit_context_dump_to_file (, , 1) generates and writes locations,
382     and hence these locations appear in the context's memento list
383     out-of-order: they appear in the context's memento list *after*
384     the memento that refers to them.  For this case, it's simplest to
385     pretend that they're NULL when writing out the code to recreate the
386     memento that uses them.  */
387  if (recording::location *loc = m->dyn_cast_location ())
388    if (!loc->created_by_user ())
389      return "NULL";
390
391  const char **slot = m_map_memento_to_identifier.get (m);
392  if (!slot)
393    {
394      get_context ().add_error (NULL,
395				"unable to find identifier for %p: %s",
396				(void *)m,
397				m->get_debug_string ());
398      gcc_unreachable ();
399    }
400  return *slot;
401}
402
403/* Locate the C identifier for the given rvalue, wrapping it within
404   a gcc_*_as_rvalue upcast if necessary.  */
405
406const char *
407reproducer::get_identifier_as_rvalue (recording::rvalue *m)
408{
409  return m->access_as_rvalue (*this);
410}
411
412/* Locate the C identifier for the given lvalue, wrapping it within
413   a gcc_*_as_lvalue upcast if necessary.  */
414
415const char *
416reproducer::get_identifier_as_lvalue (recording::lvalue *m)
417{
418  return m->access_as_lvalue (*this);
419}
420
421/* Locate the C identifier for the given type, wrapping it within
422   a gcc_*_as_type upcast if necessary.  */
423
424const char *
425reproducer::get_identifier_as_type (recording::type *m)
426{
427  return m->access_as_type (*this);
428}
429
430/* Formatted printing, allocating to a buffer (or exiting the process if
431   the allocation fails).
432
433   The buffer exists until the allocator is cleaned up, and is freed at
434   that point, so the caller doesn't need to track the result.
435
436   Note that we can't use ggc_printf since we're not within the compiler
437   proper (when within gcc_jit_context_dump_reproducer_to_file).  */
438
439char *
440reproducer::xstrdup_printf (const char *fmt, ...)
441{
442  char *result;
443  va_list ap;
444  va_start (ap, fmt);
445  result = m_allocator.xstrdup_printf_va (fmt, ap);
446  va_end (ap);
447  return result;
448}
449
450/* A helper class for implementing make_debug_string, for building
451   a temporary string from a vec of rvalues.  */
452
453class comma_separated_string
454{
455 public:
456  comma_separated_string (const auto_vec<recording::rvalue *> &rvalues,
457			  enum recording::precedence prec);
458  ~comma_separated_string ();
459
460  const char *as_char_ptr () const { return m_buf; }
461
462 private:
463  char *m_buf;
464};
465
466/* comma_separated_string's ctor
467   Build m_buf.  */
468
469comma_separated_string::comma_separated_string
470  (const auto_vec<recording::rvalue *> &rvalues,
471   enum recording::precedence prec)
472: m_buf (NULL)
473{
474  /* Calculate length of said buffer.  */
475  size_t sz = 1; /* nil terminator */
476  for (unsigned i = 0; i< rvalues.length (); i++)
477    {
478      sz += strlen (rvalues[i]->get_debug_string_parens (prec));
479      sz += 2; /* ", " separator */
480    }
481
482  /* Now allocate and populate the buffer.  */
483  m_buf = new char[sz];
484  size_t len = 0;
485
486  for (unsigned i = 0; i< rvalues.length (); i++)
487    {
488      strcpy (m_buf + len, rvalues[i]->get_debug_string_parens (prec));
489      len += strlen (rvalues[i]->get_debug_string_parens (prec));
490      if (i + 1 < rvalues.length ())
491	{
492	  strcpy (m_buf + len, ", ");
493	  len += 2;
494	}
495    }
496  m_buf[len] = '\0';
497}
498
499/* comma_separated_string's dtor.  */
500
501comma_separated_string::~comma_separated_string ()
502{
503  delete[] m_buf;
504}
505
506/**********************************************************************
507 Recording.
508 **********************************************************************/
509
510/* Get the playback::location for the given recording::location,
511   handling a NULL input with a NULL output.  */
512
513playback::location *
514recording::playback_location (replayer *r, recording::location *loc)
515{
516  if (loc)
517    return loc->playback_location (r);
518  else
519    return NULL;
520}
521
522/* Get a const char * for the given recording::string
523   handling a NULL input with a NULL output.  */
524
525const char *
526recording::playback_string (recording::string *str)
527{
528  if (str)
529    return str->c_str ();
530  else
531    return NULL;
532}
533
534/* Get the playback::block for the given recording::block,
535   handling a NULL input with a NULL output.  */
536
537playback::block *
538recording::playback_block (recording::block *b)
539{
540  if (b)
541    return b->playback_block ();
542  else
543    return NULL;
544}
545
546/* Methods of cc::jit::recording::context.  */
547
548/* The constructor for gcc::jit::recording::context, used by
549   gcc_jit_context_acquire and gcc_jit_context_new_child_context.  */
550
551recording::context::context (context *parent_ctxt)
552  : log_user (NULL),
553    m_parent_ctxt (parent_ctxt),
554    m_toplevel_ctxt (m_parent_ctxt ? m_parent_ctxt->m_toplevel_ctxt : this),
555    m_timer (NULL),
556    m_error_count (0),
557    m_first_error_str (NULL),
558    m_owns_first_error_str (false),
559    m_last_error_str (NULL),
560    m_owns_last_error_str (false),
561    m_mementos (),
562    m_compound_types (),
563    m_globals (),
564    m_functions (),
565    m_FILE_type (NULL),
566    m_builtins_manager(NULL)
567{
568  if (parent_ctxt)
569    {
570      /* Inherit options from parent.  */
571      for (unsigned i = 0;
572	   i < sizeof (m_str_options) / sizeof (m_str_options[0]);
573	   i++)
574	{
575	  const char *parent_opt = parent_ctxt->m_str_options[i];
576	  m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL;
577	}
578      memcpy (m_int_options,
579	      parent_ctxt->m_int_options,
580	      sizeof (m_int_options));
581      memcpy (m_bool_options,
582	      parent_ctxt->m_bool_options,
583	      sizeof (m_bool_options));
584      memcpy (m_inner_bool_options,
585	      parent_ctxt->m_inner_bool_options,
586	      sizeof (m_inner_bool_options));
587      set_logger (parent_ctxt->get_logger ());
588    }
589  else
590    {
591      memset (m_str_options, 0, sizeof (m_str_options));
592      memset (m_int_options, 0, sizeof (m_int_options));
593      memset (m_bool_options, 0, sizeof (m_bool_options));
594      memset (m_inner_bool_options, 0, sizeof (m_inner_bool_options));
595      m_inner_bool_options[INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR] = true;
596    }
597
598  memset (m_basic_types, 0, sizeof (m_basic_types));
599}
600
601/* The destructor for gcc::jit::recording::context, implicitly used by
602   gcc_jit_context_release.  */
603
604recording::context::~context ()
605{
606  JIT_LOG_SCOPE (get_logger ());
607  int i;
608  memento *m;
609  FOR_EACH_VEC_ELT (m_mementos, i, m)
610    {
611      delete m;
612    }
613
614  for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
615    free (m_str_options[i]);
616
617  char *optname;
618  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
619    free (optname);
620  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
621    free (optname);
622
623  if (m_builtins_manager)
624    delete m_builtins_manager;
625
626  if (m_owns_first_error_str)
627    free (m_first_error_str);
628
629  if (m_owns_last_error_str)
630    if (m_last_error_str != m_first_error_str)
631      free (m_last_error_str);
632}
633
634/* Add the given mememto to the list of those tracked by this
635   gcc::jit::recording::context, so that e.g. it can be deleted
636   when this context is released.  */
637
638void
639recording::context::record (memento *m)
640{
641  gcc_assert (m);
642
643  m_mementos.safe_push (m);
644}
645
646/* Replay this context (and any parents) into the given replayer.  */
647
648void
649recording::context::replay_into (replayer *r)
650{
651  JIT_LOG_SCOPE (get_logger ());
652  int i;
653  memento *m;
654
655  /* If we have a parent context, we must replay it.  This will
656     recursively walk backwards up the historical tree, then replay things
657     forwards "in historical order", starting with the ultimate parent
658     context, until we reach the "this" context.
659
660     Note that we fully replay the parent, then fully replay the child,
661     which means that inter-context references can only exist from child
662     to parent, not the other way around.
663
664     All of this replaying is suboptimal - it would be better to do the
665     work for the parent context *once*, rather than replaying the parent
666     every time we replay each child.  However, fixing this requires deep
667     surgery to lifetime-management: we'd need every context family tree
668     to have its own GC heap, and to initialize the GCC code to use that
669     heap (with a mutex on such a heap).  */
670  if (m_parent_ctxt)
671    m_parent_ctxt->replay_into (r);
672
673  if (r->errors_occurred ())
674    return;
675
676  /* Replay this context's saved operations into r.  */
677  FOR_EACH_VEC_ELT (m_mementos, i, m)
678    {
679      /* Disabled low-level debugging, here if we need it: print what
680	 we're replaying.
681	 Note that the calls to get_debug_string might lead to more
682	 mementos being created for the strings.
683	 This can also be used to exercise the debug_string
684	 machinery.  */
685      if (0)
686	printf ("context %p replaying (%p): %s\n",
687		(void *)this, (void *)m, m->get_debug_string ());
688
689      m->replay_into (r);
690
691      if (r->errors_occurred ())
692	return;
693    }
694}
695
696/* During a playback, we associate objects from the recording with
697   their counterparts during this playback.
698
699   For simplicity, we store this within the recording objects.
700
701   The following method cleans away these associations, to ensure that
702   we never have out-of-date associations lingering on subsequent
703   playbacks (the objects pointed to are GC-managed, but the
704   recording objects don't own refs to them).  */
705
706void
707recording::context::disassociate_from_playback ()
708{
709  JIT_LOG_SCOPE (get_logger ());
710  int i;
711  memento *m;
712
713  if (m_parent_ctxt)
714    m_parent_ctxt->disassociate_from_playback ();
715
716  FOR_EACH_VEC_ELT (m_mementos, i, m)
717    {
718      m->set_playback_obj (NULL);
719    }
720}
721
722/* Create a recording::string instance and add it to this context's list
723   of mementos.
724
725   This creates a fresh copy of the given 0-terminated buffer.  */
726
727recording::string *
728recording::context::new_string (const char *text, bool escaped)
729{
730  if (!text)
731    return NULL;
732
733  recording::string *result = new string (this, text, escaped);
734  record (result);
735  return result;
736}
737
738/* Create a recording::location instance and add it to this context's
739   list of mementos.
740
741   Implements the post-error-checking part of
742   gcc_jit_context_new_location.  */
743
744recording::location *
745recording::context::new_location (const char *filename,
746				  int line,
747				  int column,
748				  bool created_by_user)
749{
750  recording::location *result =
751    new recording::location (this,
752			     new_string (filename),
753			     line, column,
754			     created_by_user);
755  record (result);
756  return result;
757}
758
759/* If we haven't seen this enum value yet, create a recording::type
760   instance and add it to this context's list of mementos.
761
762   If we have seen it before, reuse our cached value, so that repeated
763   calls on the context give the same object.
764
765   If we have a parent context, the cache is within the ultimate
766   ancestor context.
767
768   Implements the post-error-checking part of
769   gcc_jit_context_get_type.  */
770
771recording::type *
772recording::context::get_type (enum gcc_jit_types kind)
773{
774  if (!m_basic_types[kind])
775    {
776      if (m_parent_ctxt)
777	m_basic_types[kind] = m_parent_ctxt->get_type (kind);
778      else
779	{
780	  recording::type *result = new memento_of_get_type (this, kind);
781	  record (result);
782	  m_basic_types[kind] = result;
783	}
784    }
785
786  return m_basic_types[kind];
787}
788
789/* Get a recording::type instance for the given size and signedness.
790   This is implemented in terms of recording::context::get_type
791   above.
792
793   Implements the post-error-checking part of
794   gcc_jit_context_get_int_type.  */
795
796recording::type *
797recording::context::get_int_type (int num_bytes, int is_signed)
798{
799  /* We can't use a switch here since some of the values are macros affected
800     by options; e.g. i386.h has
801       #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
802     Compare with tree.cc's make_or_reuse_type.  Note that the _SIZE macros
803     are in bits, rather than bytes.
804  */
805  const int num_bits = num_bytes * 8;
806  if (num_bits == INT_TYPE_SIZE)
807    return get_type (is_signed
808		     ? GCC_JIT_TYPE_INT
809		     : GCC_JIT_TYPE_UNSIGNED_INT);
810  if (num_bits == CHAR_TYPE_SIZE)
811    return get_type (is_signed
812		     ? GCC_JIT_TYPE_SIGNED_CHAR
813		     : GCC_JIT_TYPE_UNSIGNED_CHAR);
814  if (num_bits == SHORT_TYPE_SIZE)
815    return get_type (is_signed
816		     ? GCC_JIT_TYPE_SHORT
817		     : GCC_JIT_TYPE_UNSIGNED_SHORT);
818  if (num_bits == LONG_TYPE_SIZE)
819    return get_type (is_signed
820		     ? GCC_JIT_TYPE_LONG
821		     : GCC_JIT_TYPE_UNSIGNED_LONG);
822  if (num_bits == LONG_LONG_TYPE_SIZE)
823    return get_type (is_signed
824		     ? GCC_JIT_TYPE_LONG_LONG
825		     : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
826  if (num_bits == 128)
827    return get_type (is_signed
828		     ? GCC_JIT_TYPE_INT128_T
829		     : GCC_JIT_TYPE_UINT128_T);
830
831  /* Some other size, not corresponding to the C int types.  */
832  /* To be written: support arbitrary other sizes, sharing by
833     memoizing at the recording::context level?  */
834  gcc_unreachable ();
835}
836
837/* Create a recording::type instance and add it to this context's list
838   of mementos.
839
840   Implements the post-error-checking part of
841   gcc_jit_context_new_array_type.  */
842
843recording::type *
844recording::context::new_array_type (recording::location *loc,
845				    recording::type *element_type,
846				    int num_elements)
847{
848  if (struct_ *s = element_type->dyn_cast_struct ())
849    if (!s->get_fields ())
850      {
851	add_error (NULL,
852		   "cannot create an array of type %s"
853		   " until the fields have been set",
854		   s->get_name ()->c_str ());
855	return NULL;
856      }
857  recording::type *result =
858    new recording::array_type (this, loc, element_type, num_elements);
859  record (result);
860  return result;
861}
862
863/* Create a recording::field instance and add it to this context's list
864   of mementos.
865
866   Implements the post-error-checking part of
867   gcc_jit_context_new_field.  */
868
869recording::field *
870recording::context::new_field (recording::location *loc,
871			       recording::type *type,
872			       const char *name)
873{
874  recording::field *result =
875    new recording::field (this, loc, type, new_string (name));
876  record (result);
877  return result;
878}
879
880/* Create a recording::bitfield instance and add it to this context's list
881   of mementos.
882
883   Implements the post-error-checking part of
884   gcc_jit_context_new_bitfield.  */
885
886recording::field *
887recording::context::new_bitfield (recording::location *loc,
888				  recording::type *type,
889				  int width,
890				  const char *name)
891{
892  recording::field *result =
893    new recording::bitfield (this, loc, type, width, new_string (name));
894  record (result);
895  return result;
896}
897
898/* Create a recording::struct_ instance and add it to this context's
899   list of mementos and list of compound types.
900
901   Implements the post-error-checking part of
902   gcc_jit_context_new_struct_type.  */
903
904recording::struct_ *
905recording::context::new_struct_type (recording::location *loc,
906				     const char *name)
907{
908  recording::struct_ *result = new struct_ (this, loc, new_string (name));
909  record (result);
910  m_compound_types.safe_push (result);
911  return result;
912}
913
914/* Create a recording::union_ instance and add it to this context's
915   list of mementos and list of compound types.
916
917   Implements the first post-error-checking part of
918   gcc_jit_context_new_union_type.  */
919
920recording::union_ *
921recording::context::new_union_type (recording::location *loc,
922				    const char *name)
923{
924  recording::union_ *result = new union_ (this, loc, new_string (name));
925  record (result);
926  m_compound_types.safe_push (result);
927  return result;
928}
929
930/* Create a recording::function_type instance and add it to this context's
931   list of mementos.
932
933   Used by new_function_ptr_type and by builtins_manager::make_fn_type.  */
934
935recording::function_type *
936recording::context::new_function_type (recording::type *return_type,
937				       int num_params,
938				       recording::type **param_types,
939				       int is_variadic)
940{
941  recording::function_type *fn_type
942    = new function_type (this,
943			 return_type,
944			 num_params,
945			 param_types,
946			 is_variadic);
947  record (fn_type);
948  return fn_type;
949}
950
951/* Create a recording::type instance and add it to this context's list
952   of mementos.
953
954   Implements the post-error-checking part of
955   gcc_jit_context_new_function_ptr_type.  */
956
957recording::type *
958recording::context::new_function_ptr_type (recording::location *, /* unused loc */
959					   recording::type *return_type,
960					   int num_params,
961					   recording::type **param_types,
962					   int is_variadic)
963{
964  recording::function_type *fn_type
965    = new_function_type (return_type,
966			 num_params,
967			 param_types,
968			 is_variadic);
969
970  /* Return a pointer-type to the function type.  */
971  return fn_type->get_pointer ();
972}
973
974/* Create a recording::param instance and add it to this context's list
975   of mementos.
976
977   Implements the post-error-checking part of
978   gcc_jit_context_new_param.  */
979
980recording::param *
981recording::context::new_param (recording::location *loc,
982			       recording::type *type,
983			       const char *name)
984{
985  recording::param *result = new recording::param (this, loc, type, new_string (name));
986  record (result);
987  return result;
988}
989
990/* Create a recording::function instance and add it to this context's list
991   of mementos and list of functions.
992
993   Implements the post-error-checking part of
994   gcc_jit_context_new_function.  */
995
996recording::function *
997recording::context::new_function (recording::location *loc,
998				  enum gcc_jit_function_kind kind,
999				  recording::type *return_type,
1000				  const char *name,
1001				  int num_params,
1002				  recording::param **params,
1003				  int is_variadic,
1004				  enum built_in_function builtin_id)
1005{
1006  recording::function *result =
1007    new recording::function (this,
1008			     loc, kind, return_type,
1009			     new_string (name),
1010			     num_params, params, is_variadic,
1011			     builtin_id);
1012  record (result);
1013  m_functions.safe_push (result);
1014
1015  return result;
1016}
1017
1018/* Locate the builtins_manager (if any) for this family of contexts,
1019   creating it if it doesn't exist already.
1020
1021   All of the recording contexts in a family share one builtins_manager:
1022   if we have a child context, follow the parent links to get the
1023   ultimate ancestor context, and look for it/store it there.  */
1024
1025builtins_manager *
1026recording::context::get_builtins_manager ()
1027{
1028  if (m_parent_ctxt)
1029    return m_parent_ctxt->get_builtins_manager ();
1030
1031  if (!m_builtins_manager)
1032    m_builtins_manager = new builtins_manager (this);
1033
1034  return m_builtins_manager;
1035}
1036
1037/* Get a recording::function instance, which is lazily-created and added
1038   to the context's lists of mementos.
1039
1040   Implements the post-error-checking part of
1041   gcc_jit_context_get_builtin_function.  */
1042
1043recording::function *
1044recording::context::get_builtin_function (const char *name)
1045{
1046  builtins_manager *bm = get_builtins_manager ();
1047  return bm->get_builtin_function (name);
1048}
1049
1050/* Create a recording::global instance and add it to this context's list
1051   of mementos.
1052
1053   Implements the post-error-checking part of
1054   gcc_jit_context_new_global.  */
1055
1056recording::lvalue *
1057recording::context::new_global (recording::location *loc,
1058				enum gcc_jit_global_kind kind,
1059				recording::type *type,
1060				const char *name)
1061{
1062  recording::global *result =
1063    new recording::global (this, loc, kind, type, new_string (name));
1064  record (result);
1065  m_globals.safe_push (result);
1066
1067  return result;
1068}
1069
1070void
1071recording::context::new_global_init_rvalue (lvalue *variable,
1072					    rvalue *init)
1073{
1074  recording::global_init_rvalue *obj =
1075    new recording::global_init_rvalue (this, variable, init);
1076  record (obj);
1077
1078  global *gbl = (global *) variable;
1079  gbl->set_rvalue_init (init); /* Needed by the global for write dump.  */
1080}
1081
1082/* Create a recording::memento_of_new_string_literal instance and add it
1083   to this context's list of mementos.
1084
1085   Implements the post-error-checking part of
1086   gcc_jit_context_new_string_literal.  */
1087
1088recording::rvalue *
1089recording::context::new_string_literal (const char *value)
1090{
1091  recording::rvalue *result =
1092    new memento_of_new_string_literal (this, NULL, new_string (value));
1093  record (result);
1094  return result;
1095}
1096
1097/* Create a recording::memento_of_new_rvalue_from_vector instance and add it
1098   to this context's list of mementos.
1099
1100   Implements the post-error-checking part of
1101   gcc_jit_context_new_rvalue_from_vector.  */
1102
1103recording::rvalue *
1104recording::context::new_rvalue_from_vector (location *loc,
1105					    vector_type *type,
1106					    rvalue **elements)
1107{
1108  recording::rvalue *result
1109    = new memento_of_new_rvalue_from_vector (this, loc, type, elements);
1110  record (result);
1111  return result;
1112}
1113
1114recording::rvalue *
1115recording::context::new_ctor (recording::location *loc,
1116			      recording::type *type,
1117			      size_t num_values,
1118			      field **fields,
1119			      rvalue **values)
1120{
1121  recording::ctor *result = new ctor (this, loc, type);
1122
1123  /* Short cut for zero init.  */
1124  if (!num_values)
1125    {
1126      record (result);
1127      return result;
1128    }
1129
1130  bool is_struct_or_union = type->is_struct () || type->is_union ();
1131
1132  /* We need to copy fields and values into result's auto_vec:s.
1133     Both for structs and unions and only values for arrays.  */
1134  if (type->is_array () != NULL)
1135    {
1136      result->m_values.reserve (num_values, false);
1137
1138      for (size_t i = 0; i < num_values; i++)
1139	result->m_values.quick_push (values[i]);
1140    }
1141  else if (is_struct_or_union && fields)
1142    {
1143      /* ctor values are paired with user specified fields.  */
1144
1145      result->m_values.reserve (num_values, false);
1146      result->m_fields.reserve (num_values, false);
1147
1148      for (size_t i = 0; i < num_values; i++)
1149	{
1150	  result->m_values.quick_push (values[i]);
1151	  result->m_fields.quick_push (fields[i]);
1152	}
1153    }
1154  else if (is_struct_or_union && !fields)
1155    {
1156      /* ctor values are in definition order one by one,
1157	 so take the fields from the type object.  */
1158
1159      result->m_values.reserve (num_values, false);
1160      result->m_fields.reserve (num_values, false);
1161
1162      compound_type *ct = reinterpret_cast<compound_type *>(type);
1163      recording::fields *fields = ct->get_fields ();
1164
1165      /* The entry point checks that num_values is not greater than
1166	 the amount of fields in 'fields'.  */
1167      for (size_t i = 0; i < num_values; i++)
1168	{
1169	  result->m_values.quick_push (values[i]);
1170	  result->m_fields.quick_push (fields->get_field (i));
1171	}
1172    }
1173  else
1174    gcc_unreachable ();
1175
1176  record (result);
1177  return result;
1178}
1179
1180/* Create a recording::unary_op instance and add it to this context's
1181   list of mementos.
1182
1183   Implements the post-error-checking part of
1184   gcc_jit_context_new_unary_op.  */
1185
1186recording::rvalue *
1187recording::context::new_unary_op (recording::location *loc,
1188				  enum gcc_jit_unary_op op,
1189				  recording::type *result_type,
1190				  recording::rvalue *a)
1191{
1192  recording::rvalue *result =
1193    new unary_op (this, loc, op, result_type, a);
1194  record (result);
1195  return result;
1196}
1197
1198/* Create a recording::binary_op instance and add it to this context's
1199   list of mementos.
1200
1201   Implements the post-error-checking part of
1202   gcc_jit_context_new_binary_op.  */
1203
1204recording::rvalue *
1205recording::context::new_binary_op (recording::location *loc,
1206				   enum gcc_jit_binary_op op,
1207				   recording::type *result_type,
1208				   recording::rvalue *a,
1209				   recording::rvalue *b)
1210{
1211  recording::rvalue *result =
1212    new binary_op (this, loc, op, result_type, a, b);
1213  record (result);
1214  return result;
1215}
1216
1217/* Create a recording::comparison instance and add it to this context's
1218   list of mementos.
1219
1220   Implements the post-error-checking part of
1221   gcc_jit_context_new_comparison.  */
1222
1223recording::rvalue *
1224recording::context::new_comparison (recording::location *loc,
1225				    enum gcc_jit_comparison op,
1226				    recording::rvalue *a,
1227				    recording::rvalue *b)
1228{
1229  recording::rvalue *result = new comparison (this, loc, op, a, b);
1230  record (result);
1231  return result;
1232}
1233
1234/* Create a recording::cast instance and add it to this context's list
1235   of mementos.
1236
1237   Implements the post-error-checking part of
1238   gcc_jit_context_new_cast.  */
1239
1240recording::rvalue *
1241recording::context::new_cast (recording::location *loc,
1242			      recording::rvalue *expr,
1243			      recording::type *type_)
1244{
1245  recording::rvalue *result = new cast (this, loc, expr, type_);
1246  record (result);
1247  return result;
1248}
1249
1250/* Create a recording::bitcast instance and add it to this context's list
1251   of mementos.
1252
1253   Implements the post-error-checking part of
1254   gcc_jit_context_new_bitcast.  */
1255
1256recording::rvalue *
1257recording::context::new_bitcast (location *loc,
1258				 rvalue *expr,
1259				 type *type_)
1260{
1261  recording::rvalue *result = new bitcast (this, loc, expr, type_);
1262  record (result);
1263  return result;
1264}
1265
1266/* Create a recording::call instance and add it to this context's list
1267   of mementos.
1268
1269   Implements the post-error-checking part of
1270   gcc_jit_context_new_call.  */
1271
1272recording::rvalue *
1273recording::context::new_call (recording::location *loc,
1274			      function *func,
1275			      int numargs , recording::rvalue **args)
1276{
1277  recording::rvalue *result = new call (this, loc, func, numargs, args);
1278  record (result);
1279  return result;
1280}
1281
1282/* Create a recording::call_through_ptr instance and add it to this
1283   context's list of mementos.
1284
1285   Implements the post-error-checking part of
1286   gcc_jit_context_new_call_through_ptr.  */
1287
1288recording::rvalue *
1289recording::context::new_call_through_ptr (recording::location *loc,
1290					  recording::rvalue *fn_ptr,
1291					  int numargs,
1292					  recording::rvalue **args)
1293  {
1294  recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
1295  record (result);
1296  return result;
1297}
1298
1299/* Create a recording::array_access instance and add it to this context's list
1300   of mementos.
1301
1302   Implements the post-error-checking part of
1303   gcc_jit_context_new_array_access.  */
1304
1305recording::lvalue *
1306recording::context::new_array_access (recording::location *loc,
1307				      recording::rvalue *ptr,
1308				      recording::rvalue *index)
1309{
1310  recording::lvalue *result = new array_access (this, loc, ptr, index);
1311  record (result);
1312  return result;
1313}
1314
1315/* Create a recording::case_ instance and add it to this context's list
1316   of mementos.
1317
1318   Implements the post-error-checking part of
1319   gcc_jit_context_new_case.  */
1320
1321recording::case_ *
1322recording::context::new_case (recording::rvalue *min_value,
1323			      recording::rvalue *max_value,
1324			      recording::block *block)
1325{
1326  recording::case_ *result = new case_ (this, min_value, max_value, block);
1327  record (result);
1328  return result;
1329}
1330
1331/* Set the given string option for this context, or add an error if
1332   it's not recognized.
1333
1334   Implements the post-error-checking part of
1335   gcc_jit_context_set_str_option.  */
1336
1337void
1338recording::context::set_str_option (enum gcc_jit_str_option opt,
1339				    const char *value)
1340{
1341  if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
1342    {
1343      add_error (NULL,
1344		 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
1345      return;
1346    }
1347  free (m_str_options[opt]);
1348  m_str_options[opt] = value ? xstrdup (value) : NULL;
1349  log_str_option (opt);
1350}
1351
1352/* Set the given integer option for this context, or add an error if
1353   it's not recognized.
1354
1355   Implements the post-error-checking part of
1356   gcc_jit_context_set_int_option.  */
1357
1358void
1359recording::context::set_int_option (enum gcc_jit_int_option opt,
1360				    int value)
1361{
1362  if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
1363    {
1364      add_error (NULL,
1365		 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
1366      return;
1367    }
1368  m_int_options[opt] = value;
1369  log_int_option (opt);
1370}
1371
1372/* Set the given boolean option for this context, or add an error if
1373   it's not recognized.
1374
1375   Implements the post-error-checking part of
1376   gcc_jit_context_set_bool_option.  */
1377
1378void
1379recording::context::set_bool_option (enum gcc_jit_bool_option opt,
1380				     int value)
1381{
1382  if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
1383    {
1384      add_error (NULL,
1385		 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
1386      return;
1387    }
1388  m_bool_options[opt] = value ? true : false;
1389  log_bool_option (opt);
1390}
1391
1392void
1393recording::context::set_inner_bool_option (enum inner_bool_option inner_opt,
1394					   int value)
1395{
1396  gcc_assert (inner_opt >= 0 && inner_opt < NUM_INNER_BOOL_OPTIONS);
1397  m_inner_bool_options[inner_opt] = value ? true : false;
1398  log_inner_bool_option (inner_opt);
1399}
1400
1401
1402/* Add the given optname to this context's list of extra options.
1403
1404   Implements the post-error-checking part of
1405   gcc_jit_context_add_command_line_option.  */
1406
1407void
1408recording::context::add_command_line_option (const char *optname)
1409{
1410  m_command_line_options.safe_push (xstrdup (optname));
1411}
1412
1413/* Add any user-provided extra options, starting with any from
1414   parent contexts.
1415   Called by playback::context::make_fake_args.  */
1416
1417void
1418recording::context::append_command_line_options (vec <char *> *argvec)
1419{
1420  if (m_parent_ctxt)
1421    m_parent_ctxt->append_command_line_options (argvec);
1422
1423  int i;
1424  char *optname;
1425  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
1426    argvec->safe_push (xstrdup (optname));
1427}
1428
1429/* Add the given optname to this context's list of extra driver options.  */
1430
1431void
1432recording::context::add_driver_option (const char *optname)
1433{
1434  m_driver_options.safe_push (xstrdup (optname));
1435}
1436
1437/* Add any user-provided driver options, starting with any from
1438   parent contexts.
1439   Called by playback::context::invoke_driver.  */
1440
1441void
1442recording::context::append_driver_options (auto_string_vec *argvec)
1443{
1444  if (m_parent_ctxt)
1445    m_parent_ctxt->append_driver_options (argvec);
1446
1447  int i;
1448  char *optname;
1449
1450  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
1451    argvec->safe_push (xstrdup (optname));
1452}
1453
1454/* Add the given dumpname/out_ptr pair to this context's list of requested
1455   dumps.
1456
1457   Implements the post-error-checking part of
1458   gcc_jit_context_enable_dump.  */
1459
1460void
1461recording::context::enable_dump (const char *dumpname,
1462				 char **out_ptr)
1463{
1464  requested_dump d;
1465  gcc_assert (dumpname);
1466  gcc_assert (out_ptr);
1467
1468  d.m_dumpname = dumpname;
1469  d.m_out_ptr = out_ptr;
1470  *out_ptr = NULL;
1471  m_requested_dumps.safe_push (d);
1472}
1473
1474/* Validate this context, and if it passes, compile it to memory
1475   (within a mutex).
1476
1477   Implements the post-error-checking part of
1478   gcc_jit_context_compile.  */
1479
1480result *
1481recording::context::compile ()
1482{
1483  JIT_LOG_SCOPE (get_logger ());
1484
1485  log_all_options ();
1486
1487  validate ();
1488
1489  if (errors_occurred ())
1490    return NULL;
1491
1492  /* Set up a compile_to_memory playback context.  */
1493  ::gcc::jit::playback::compile_to_memory replayer (this);
1494
1495  /* Use it.  */
1496  replayer.compile ();
1497
1498  /* Get the jit::result (or NULL) from the
1499     compile_to_memory playback context.  */
1500  return replayer.get_result_obj ();
1501}
1502
1503/* Validate this context, and if it passes, compile it to a file
1504   (within a mutex).
1505
1506   Implements the post-error-checking part of
1507   gcc_jit_context_compile_to_file.  */
1508
1509void
1510recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
1511				     const char *output_path)
1512{
1513  JIT_LOG_SCOPE (get_logger ());
1514
1515  log_all_options ();
1516
1517  validate ();
1518
1519  if (errors_occurred ())
1520    return;
1521
1522  /* Set up a compile_to_file playback context.  */
1523  ::gcc::jit::playback::compile_to_file replayer (this,
1524						  output_kind,
1525						  output_path);
1526
1527  /* Use it.  */
1528  replayer.compile ();
1529}
1530
1531/* Format the given error using printf's conventions, print
1532   it to stderr, and add it to the context.  */
1533
1534void
1535recording::context::add_error (location *loc, const char *fmt, ...)
1536{
1537  va_list ap;
1538  va_start (ap, fmt);
1539  add_error_va (loc, fmt, ap);
1540  va_end (ap);
1541}
1542
1543/* Format the given error using printf's conventions, print
1544   it to stderr, and add it to the context.  */
1545
1546void
1547recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
1548{
1549  int len;
1550  char *malloced_msg;
1551  const char *errmsg;
1552  bool has_ownership;
1553
1554  JIT_LOG_SCOPE (get_logger ());
1555
1556  len = vasprintf (&malloced_msg, fmt, ap);
1557  if (malloced_msg == NULL || len < 0)
1558    {
1559      errmsg = "out of memory generating error message";
1560      has_ownership = false;
1561    }
1562  else
1563    {
1564      errmsg = malloced_msg;
1565      has_ownership = true;
1566    }
1567  if (get_logger ())
1568    get_logger ()->log ("error %i: %s", m_error_count, errmsg);
1569
1570  const char *ctxt_progname =
1571    get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
1572  if (!ctxt_progname)
1573    ctxt_progname = "libgccjit.so";
1574
1575  bool print_errors_to_stderr =
1576      get_inner_bool_option (INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR);
1577  if (print_errors_to_stderr)
1578  {
1579    if (loc)
1580      fprintf (stderr, "%s: %s: error: %s\n",
1581	       ctxt_progname,
1582	       loc->get_debug_string (),
1583	       errmsg);
1584    else
1585      fprintf (stderr, "%s: error: %s\n",
1586	       ctxt_progname,
1587	       errmsg);
1588  }
1589
1590  if (!m_error_count)
1591    {
1592      m_first_error_str = const_cast <char *> (errmsg);
1593      m_owns_first_error_str = has_ownership;
1594    }
1595
1596  if (m_owns_last_error_str)
1597    if (m_last_error_str != m_first_error_str)
1598      free (m_last_error_str);
1599  m_last_error_str = const_cast <char *> (errmsg);
1600  m_owns_last_error_str = has_ownership;
1601
1602  m_error_count++;
1603}
1604
1605/* Get the message for the first error that occurred on this context, or
1606   NULL if no errors have occurred on it.
1607
1608   Implements the post-error-checking part of
1609   gcc_jit_context_get_first_error.  */
1610
1611const char *
1612recording::context::get_first_error () const
1613{
1614  return m_first_error_str;
1615}
1616
1617/* Get the message for the last error that occurred on this context, or
1618   NULL if no errors have occurred on it.
1619
1620   Implements the post-error-checking part of
1621   gcc_jit_context_get_last_error.  */
1622
1623const char *
1624recording::context::get_last_error () const
1625{
1626  return m_last_error_str;
1627}
1628
1629/* Lazily generate and record a recording::type representing an opaque
1630   struct named "FILE".
1631
1632   For use if client code tries to dereference the result of
1633   get_type (GCC_JIT_TYPE_FILE_PTR).  */
1634
1635recording::type *
1636recording::context::get_opaque_FILE_type ()
1637{
1638  if (!m_FILE_type)
1639    m_FILE_type = new_struct_type (NULL, "FILE");
1640  return m_FILE_type;
1641}
1642
1643/* Dump a C-like representation of the given context to the given path.
1644   If UPDATE_LOCATIONS is true, update the locations within the
1645   context's mementos to point to the dumpfile.
1646
1647   Implements the post-error-checking part of
1648   gcc_jit_context_dump_to_file.  */
1649
1650void
1651recording::context::dump_to_file (const char *path, bool update_locations)
1652{
1653  int i;
1654  dump d (*this, path, update_locations);
1655
1656  /* Forward declaration of structs and unions.  */
1657  compound_type *st;
1658  FOR_EACH_VEC_ELT (m_compound_types, i, st)
1659    {
1660      d.write ("%s;\n\n", st->get_debug_string ());
1661    }
1662
1663  /* Content of structs, where set.  */
1664  FOR_EACH_VEC_ELT (m_compound_types, i, st)
1665    if (st->get_fields ())
1666      {
1667	st->get_fields ()->write_to_dump (d);
1668	d.write ("\n");
1669      }
1670
1671  /* Globals.  */
1672  global *g;
1673  FOR_EACH_VEC_ELT (m_globals, i, g)
1674    {
1675      g->write_to_dump (d);
1676    }
1677  if (!m_globals.is_empty ())
1678    d.write ("\n");
1679
1680  function *fn;
1681  FOR_EACH_VEC_ELT (m_functions, i, fn)
1682    {
1683      fn->write_to_dump (d);
1684    }
1685
1686  top_level_asm *tla;
1687  FOR_EACH_VEC_ELT (m_top_level_asms, i, tla)
1688    tla->write_to_dump (d);
1689}
1690
1691static const char * const
1692 str_option_reproducer_strings[GCC_JIT_NUM_STR_OPTIONS] = {
1693  "GCC_JIT_STR_OPTION_PROGNAME"
1694};
1695
1696static const char * const
1697 int_option_reproducer_strings[GCC_JIT_NUM_INT_OPTIONS] = {
1698  "GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL"
1699};
1700
1701static const char * const
1702 bool_option_reproducer_strings[GCC_JIT_NUM_BOOL_OPTIONS] = {
1703  "GCC_JIT_BOOL_OPTION_DEBUGINFO",
1704  "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE",
1705  "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE",
1706  "GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE",
1707  "GCC_JIT_BOOL_OPTION_DUMP_SUMMARY",
1708  "GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING",
1709  "GCC_JIT_BOOL_OPTION_SELFCHECK_GC",
1710  "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES"
1711};
1712
1713static const char * const
1714 inner_bool_option_reproducer_strings[NUM_INNER_BOOL_OPTIONS] = {
1715  "gcc_jit_context_set_bool_allow_unreachable_blocks",
1716  "gcc_jit_context_set_bool_use_external_driver",
1717  "gcc_jit_context_set_bool_print_errors_to_stderr",
1718};
1719
1720/* Write the current value of all options to the log file (if any).  */
1721
1722void
1723recording::context::log_all_options () const
1724{
1725  int opt_idx;
1726
1727  if (!get_logger ())
1728    return;
1729
1730  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_STR_OPTIONS; opt_idx++)
1731    log_str_option ((enum gcc_jit_str_option)opt_idx);
1732
1733  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_INT_OPTIONS; opt_idx++)
1734    log_int_option ((enum gcc_jit_int_option)opt_idx);
1735
1736  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++)
1737    log_bool_option ((enum gcc_jit_bool_option)opt_idx);
1738  for (opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
1739    log_inner_bool_option ((enum inner_bool_option)opt_idx);
1740}
1741
1742/* Write the current value of the given string option to the
1743   log file (if any).  */
1744
1745void
1746recording::context::log_str_option (enum gcc_jit_str_option opt) const
1747{
1748  gcc_assert (opt < GCC_JIT_NUM_STR_OPTIONS);
1749  if (get_logger ())
1750    {
1751      if (m_str_options[opt])
1752	log ("%s: \"%s\"",
1753	     str_option_reproducer_strings[opt],
1754	     m_str_options[opt]);
1755      else
1756	log ("%s: NULL",
1757	     str_option_reproducer_strings[opt]);
1758    }
1759}
1760
1761/* Write the current value of the given int option to the
1762   log file (if any).  */
1763
1764void
1765recording::context::log_int_option (enum gcc_jit_int_option opt) const
1766{
1767  gcc_assert (opt < GCC_JIT_NUM_INT_OPTIONS);
1768  if (get_logger ())
1769    log ("%s: %i",
1770	 int_option_reproducer_strings[opt],
1771	 m_int_options[opt]);
1772}
1773
1774/* Write the current value of the given bool option to the
1775   log file (if any).  */
1776
1777void
1778recording::context::log_bool_option (enum gcc_jit_bool_option opt) const
1779{
1780  gcc_assert (opt < GCC_JIT_NUM_BOOL_OPTIONS);
1781  if (get_logger ())
1782    log ("%s: %s",
1783	 bool_option_reproducer_strings[opt],
1784	 m_bool_options[opt] ? "true" : "false");
1785}
1786
1787/* Write the current value of the given "inner" bool option to the
1788   log file (if any).  */
1789
1790void
1791recording::context::log_inner_bool_option (enum inner_bool_option opt) const
1792{
1793  gcc_assert (opt < NUM_INNER_BOOL_OPTIONS);
1794  if (get_logger ())
1795    log ("%s: %s",
1796	 inner_bool_option_reproducer_strings[opt],
1797	 m_inner_bool_options[opt] ? "true" : "false");
1798}
1799
1800/* Write C source code to PATH that attempts to replay the API
1801   calls made to this context (and its parents), for use in
1802   minimizing test cases for libgccjit.
1803
1804   Implements the post-error-checking part of
1805   gcc_jit_context_dump_reproducer_to_file.  */
1806
1807void
1808recording::context::dump_reproducer_to_file (const char *path)
1809{
1810  JIT_LOG_SCOPE (get_logger ());
1811  reproducer r (*this, path);
1812
1813  /* Generate the "ancestry" of this context, as a list.  */
1814  auto_vec <context *> ascending_contexts;
1815  for (context *ctxt = this; ctxt; ctxt = ctxt->m_parent_ctxt)
1816    ascending_contexts.safe_push (ctxt);
1817
1818  /* Reverse the list, giving a list of contexts from
1819     top-most parent context down through to youngest child context.
1820     We will use this list as the parameters of the functions in
1821     our generated file.  */
1822  unsigned num_ctxts = ascending_contexts.length ();
1823  auto_vec <context *> contexts (num_ctxts);
1824  for (unsigned i = 0; i < num_ctxts; i++)
1825    contexts.safe_push (ascending_contexts[num_ctxts - (i + 1)]);
1826
1827  /* contexts[0] should be the top-level context.  */
1828  gcc_assert (contexts[0]);
1829  gcc_assert (contexts[0]->m_toplevel_ctxt == contexts[0]);
1830
1831  /* The final element in contexts should be "this".  */
1832  gcc_assert (contexts[contexts.length () - 1] == this);
1833  gcc_assert (contexts[contexts.length () - 1]->m_toplevel_ctxt
1834	      == contexts[0]);
1835
1836  r.write ("/* This code was autogenerated by"
1837	   " gcc_jit_context_dump_reproducer_to_file.\n\n");
1838  print_version (r.get_file (), "  ", false);
1839  r.write ("*/\n");
1840  r.write ("#include <libgccjit.h>\n\n");
1841  r.write ("#pragma GCC diagnostic ignored \"-Wunused-variable\"\n\n");
1842  r.write ("static void\nset_options (");
1843  r.write_params (contexts);
1844  r.write (");\n\n");
1845  r.write ("static void\ncreate_code (");
1846  r.write_params (contexts);
1847  r.write (");\n\n");
1848  r.write ("int\nmain (int argc, const char **argv)\n");
1849  r.write ("{\n");
1850  for (unsigned i = 0; i < num_ctxts; i++)
1851    r.write ("  gcc_jit_context *%s;\n",
1852	     r.get_identifier (contexts[i]));
1853  r.write ("  gcc_jit_result *result;\n"
1854	   "\n");
1855
1856  /* Create the contexts.
1857     The top-level context is acquired from a clean slate, the others as
1858     children of the prior context.  */
1859  r.write ("  %s = gcc_jit_context_acquire ();\n",
1860	   r.get_identifier (contexts[0]));
1861  for (unsigned i = 1; i < num_ctxts; i++)
1862    r.write ("  %s = gcc_jit_context_new_child_context (%s);\n",
1863	     r.get_identifier (contexts[i]),
1864	     r.get_identifier (contexts[i - 1]));
1865  r.write ("  set_options (");
1866  r.write_args (contexts);
1867  r.write (");\n");
1868  r.write ("  create_code (");
1869  r.write_args (contexts);
1870  r.write (");\n");
1871
1872  r.write ("  result = gcc_jit_context_compile (%s);\n",
1873	   r.get_identifier (this));
1874
1875  for (unsigned i = num_ctxts; i > 0; i--)
1876    r.write ("  gcc_jit_context_release (%s);\n",
1877	     r.get_identifier (contexts[i - 1]));
1878
1879  r.write ("  gcc_jit_result_release (result);\n"
1880	   "  return 0;\n"
1881	   "}\n\n");
1882
1883  /* Define (char *) variables for use in calls to
1884     gcc_jit_context_enable_dump.  */
1885  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
1886    {
1887      if (m_requested_dumps.length ())
1888	{
1889	  r.write ("/* Requested dumps for %s.  */\n",
1890		   r.get_identifier (contexts[ctxt_idx]));
1891	  for (unsigned i = 0; i < m_requested_dumps.length (); i++)
1892	    r.write ("static char *dump_%p;\n",
1893		     (void *)&m_requested_dumps[i]);
1894	  r.write ("\n");
1895	}
1896    }
1897
1898  /* Write out values of options.  */
1899  r.write ("static void\nset_options (");
1900  r.write_params (contexts);
1901  r.write (")\n{\n");
1902  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
1903    {
1904      if (ctxt_idx > 0)
1905	r.write ("\n");
1906
1907      r.write ("  /* Set options for %s.  */\n",
1908	       r.get_identifier (contexts[ctxt_idx]));
1909
1910      r.write ("  /* String options.  */\n");
1911      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_STR_OPTIONS; opt_idx++)
1912	{
1913	  r.write ("  gcc_jit_context_set_str_option (%s,\n"
1914		   "                                  %s,\n",
1915		   r.get_identifier (contexts[ctxt_idx]),
1916		   str_option_reproducer_strings[opt_idx]);
1917	  if (m_str_options[opt_idx])
1918	    r.write ("                                  \"%s\");\n",
1919		     m_str_options[opt_idx]);
1920	  else
1921	    r.write ("                                  NULL);\n");
1922	}
1923      r.write ("  /* Int options.  */\n");
1924      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_INT_OPTIONS; opt_idx++)
1925	r.write ("  gcc_jit_context_set_int_option (%s,\n"
1926		 "                                  %s,\n"
1927		 "                                  %i);\n",
1928		 r.get_identifier (contexts[ctxt_idx]),
1929		 int_option_reproducer_strings[opt_idx],
1930		 m_int_options[opt_idx]);
1931      r.write ("  /* Boolean options.  */\n");
1932      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++)
1933	r.write ("  gcc_jit_context_set_bool_option (%s,\n"
1934		 "                                  %s,\n"
1935		 "                                  %i);\n",
1936		 r.get_identifier (contexts[ctxt_idx]),
1937		 bool_option_reproducer_strings[opt_idx],
1938		 m_bool_options[opt_idx]);
1939      for (int opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
1940	r.write ("  %s (%s, %i);\n",
1941		 inner_bool_option_reproducer_strings[opt_idx],
1942		 r.get_identifier (contexts[ctxt_idx]),
1943		 m_inner_bool_options[opt_idx]);
1944
1945      if (!m_command_line_options.is_empty ())
1946	{
1947	  int i;
1948	  char *optname;
1949	  r.write ("  /* User-provided command-line options.  */\n");
1950	  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
1951	    r.write ("  gcc_jit_context_add_command_line_option (%s, \"%s\");\n",
1952		     r.get_identifier (contexts[ctxt_idx]),
1953		     optname);
1954	}
1955
1956      if (!m_driver_options.is_empty ())
1957	{
1958	  int i;
1959	  char *optname;
1960	  r.write ("  /* User-provided driver options.  */\n");
1961	  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
1962	    r.write ("  gcc_jit_context_add_driver_option (%s, \"%s\");\n",
1963		     r.get_identifier (contexts[ctxt_idx]),
1964		     optname);
1965	}
1966
1967      if (m_requested_dumps.length ())
1968	{
1969	  r.write ("  /* Requested dumps.  */\n");
1970	  /* Dumpfiles that were requested via gcc_jit_context_enable_dump.  */
1971	  for (unsigned i = 0; i < m_requested_dumps.length (); i++)
1972	    {
1973	      r.write ("  gcc_jit_context_enable_dump (%s,\n"
1974		       "                               \"%s\",\n"
1975		       "                               &dump_%p);\n",
1976		       r.get_identifier (contexts[ctxt_idx]),
1977		       m_requested_dumps[i].m_dumpname,
1978		       (void *)&m_requested_dumps[i]);
1979	    }
1980	}
1981    }
1982  r.write ("}\n\n");
1983
1984  r.write ("static void\ncreate_code (");
1985  r.write_params (contexts);
1986  r.write (")\n"
1987	   "{\n");
1988  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
1989    {
1990      memento *m;
1991      int i;
1992      if (ctxt_idx > 0)
1993	r.write ("\n\n");
1994
1995      r.write ("  /* Replay of API calls for %s.  */\n",
1996	       r.get_identifier (contexts[ctxt_idx]));
1997      FOR_EACH_VEC_ELT (contexts[ctxt_idx]->m_mementos, i, m)
1998	m->write_reproducer (r);
1999    }
2000  r.write ("}\n");
2001}
2002
2003/* Copy the requested dumps within this context and all ancestors into
2004   OUT. */
2005
2006void
2007recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
2008{
2009  if (m_parent_ctxt)
2010    m_parent_ctxt->get_all_requested_dumps (out);
2011
2012  out->reserve (m_requested_dumps.length ());
2013  out->splice (m_requested_dumps);
2014}
2015
2016/* Create a recording::top_level_asm instance and add it to this
2017   context's list of mementos and to m_top_level_asms.
2018
2019   Implements the post-error-checking part of
2020   gcc_jit_context_add_top_level_asm.  */
2021
2022void
2023recording::context::add_top_level_asm (recording::location *loc,
2024				       const char *asm_stmts)
2025{
2026  recording::top_level_asm *asm_obj
2027    = new recording::top_level_asm (this, loc, new_string (asm_stmts));
2028  record (asm_obj);
2029  m_top_level_asms.safe_push (asm_obj);
2030}
2031
2032/* This is a pre-compilation check for the context (and any parents).
2033
2034   Detect errors within the context, adding errors if any are found.  */
2035
2036void
2037recording::context::validate ()
2038{
2039  JIT_LOG_SCOPE (get_logger ());
2040
2041  if (m_parent_ctxt)
2042    m_parent_ctxt->validate ();
2043
2044  int i;
2045  function *fn;
2046  FOR_EACH_VEC_ELT (m_functions, i, fn)
2047    fn->validate ();
2048}
2049
2050/* The implementation of class gcc::jit::recording::memento.  */
2051
2052/* Get a (const char *) debug description of the given memento, by
2053   calling the pure-virtual make_debug_string hook, caching the
2054   result.
2055
2056   It is intended that this should only be called in debugging and
2057   error-handling paths, so this doesn't need to be particularly
2058   optimized.  */
2059
2060const char *
2061recording::memento::get_debug_string ()
2062{
2063  if (!m_debug_string)
2064    m_debug_string = make_debug_string ();
2065  return m_debug_string->c_str ();
2066}
2067
2068/* Default implementation of recording::memento::write_to_dump, writing
2069   an indented form of the memento's debug string to the dump.  */
2070
2071void
2072recording::memento::write_to_dump (dump &d)
2073{
2074  d.write("  %s\n", get_debug_string ());
2075}
2076
2077/* The implementation of class gcc::jit::recording::string.  */
2078
2079/* Constructor for gcc::jit::recording::string::string, allocating a
2080   copy of the given text using new char[].  */
2081
2082recording::string::string (context *ctxt, const char *text, bool escaped)
2083: memento (ctxt),
2084  m_escaped (escaped)
2085{
2086  m_len = strlen (text);
2087  m_buffer = new char[m_len + 1];
2088  strcpy (m_buffer, text);
2089}
2090
2091/* Destructor for gcc::jit::recording::string::string.  */
2092
2093recording::string::~string ()
2094{
2095  delete[] m_buffer;
2096}
2097
2098/* Function for making gcc::jit::recording::string instances on a
2099   context via printf-style formatting.
2100
2101   It is intended that this should only be called in debugging and
2102   error-handling paths, so this doesn't need to be particularly
2103   optimized, hence the double-copy of the string is acceptable.  */
2104
2105recording::string *
2106recording::string::from_printf (context *ctxt, const char *fmt, ...)
2107{
2108  int len;
2109  va_list ap;
2110  char *buf;
2111  recording::string *result;
2112
2113  va_start (ap, fmt);
2114  len = vasprintf (&buf, fmt, ap);
2115  va_end (ap);
2116
2117  if (buf == NULL || len < 0)
2118    {
2119      ctxt->add_error (NULL, "malloc failure");
2120      return NULL;
2121    }
2122
2123  result = ctxt->new_string (buf);
2124  free (buf);
2125  return result;
2126}
2127
2128/* Implementation of recording::memento::make_debug_string for strings,
2129   wrapping the given string in quotes and escaping as necessary.  */
2130
2131recording::string *
2132recording::string::make_debug_string ()
2133{
2134  /* Avoid infinite recursion into strings when logging all mementos:
2135     don't re-escape strings:  */
2136  if (m_escaped)
2137    return this;
2138
2139  /* Wrap in quotes and do escaping etc */
2140
2141  size_t sz = (1 /* opening quote */
2142	       + (m_len * 2) /* each char might get escaped */
2143	       + 1 /* closing quote */
2144	       + 1); /* nil termintator */
2145  char *tmp = new char[sz];
2146  size_t len = 0;
2147
2148#define APPEND(CH)  do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
2149  APPEND('"'); /* opening quote */
2150  for (size_t i = 0; i < m_len ; i++)
2151    {
2152      char ch = m_buffer[i];
2153      switch (ch)
2154	{
2155	default:
2156	  APPEND(ch);
2157	  break;
2158	case '\t':
2159	  APPEND('\\');
2160	  APPEND('t');
2161	  break;
2162	case '\n':
2163	  APPEND('\\');
2164	  APPEND('n');
2165	  break;
2166	case '\\':
2167	case '"':
2168	  APPEND('\\');
2169	  APPEND(ch);
2170	  break;
2171	}
2172    }
2173  APPEND('"'); /* closing quote */
2174#undef APPEND
2175  tmp[len] = '\0'; /* nil termintator */
2176
2177  string *result = m_ctxt->new_string (tmp, true);
2178
2179  delete[] tmp;
2180  return result;
2181}
2182
2183/* Implementation of recording::memento::write_reproducer for strings. */
2184
2185void
2186recording::string::write_reproducer (reproducer &)
2187{
2188  /* Empty.  */
2189}
2190
2191/* The implementation of class gcc::jit::recording::location.  */
2192
2193/* Implementation of recording::memento::replay_into for locations.
2194
2195   Create a new playback::location and store it into the
2196   recording::location's m_playback_obj field.  */
2197
2198void
2199recording::location::replay_into (replayer *r)
2200{
2201  m_playback_obj = r->new_location (this,
2202				    m_filename->c_str (),
2203				    m_line,
2204				    m_column);
2205}
2206
2207/* Implementation of recording::memento::make_debug_string for locations,
2208   turning them into the usual form:
2209     FILENAME:LINE:COLUMN
2210   like we do when emitting diagnostics.  */
2211
2212recording::string *
2213recording::location::make_debug_string ()
2214{
2215  return string::from_printf (m_ctxt,
2216			      "%s:%i:%i",
2217			      m_filename->c_str (), m_line, m_column);
2218}
2219
2220/* Implementation of recording::memento::write_reproducer for locations. */
2221
2222void
2223recording::location::write_reproducer (reproducer &r)
2224{
2225  const char *id = r.make_identifier (this, "loc");
2226  r.write ("  gcc_jit_location *%s =\n"
2227	   "    gcc_jit_context_new_location (%s, /* gcc_jit_context *ctxt */\n"
2228	   "    %s, /* const char *filename */\n"
2229	   "    %i, /* int line */\n"
2230	   "    %i);/* int column */\n",
2231	   id,
2232	   r.get_identifier (get_context ()),
2233	   m_filename->get_debug_string (),
2234	   m_line, m_column);
2235}
2236
2237/* The implementation of class gcc::jit::recording::type.  */
2238
2239/* Given a type T, get the type T*.
2240
2241   If this doesn't already exist, generate a new memento_of_get_pointer
2242   instance and add it to this type's context's list of mementos.
2243
2244   Otherwise, use the cached type.
2245
2246   Implements the post-error-checking part of
2247   gcc_jit_type_get_pointer.  */
2248
2249recording::type *
2250recording::type::get_pointer ()
2251{
2252  if (!m_pointer_to_this_type)
2253    {
2254      m_pointer_to_this_type = new memento_of_get_pointer (this);
2255      m_ctxt->record (m_pointer_to_this_type);
2256    }
2257  return m_pointer_to_this_type;
2258}
2259
2260/* Given a type T, get the type const T.
2261
2262   Implements the post-error-checking part of
2263   gcc_jit_type_get_const.  */
2264
2265recording::type *
2266recording::type::get_const ()
2267{
2268  recording::type *result = new memento_of_get_const (this);
2269  m_ctxt->record (result);
2270  return result;
2271}
2272
2273/* Given a type T, get the type volatile T.
2274
2275   Implements the post-error-checking part of
2276   gcc_jit_type_get_volatile.  */
2277
2278recording::type *
2279recording::type::get_volatile ()
2280{
2281  recording::type *result = new memento_of_get_volatile (this);
2282  m_ctxt->record (result);
2283  return result;
2284}
2285
2286/* Given a type, get an aligned version of the type.
2287
2288   Implements the post-error-checking part of
2289   gcc_jit_type_get_aligned.  */
2290
2291recording::type *
2292recording::type::get_aligned (size_t alignment_in_bytes)
2293{
2294  recording::type *result
2295    = new memento_of_get_aligned (this, alignment_in_bytes);
2296  m_ctxt->record (result);
2297  return result;
2298}
2299
2300/* Given a type, get a vector version of the type.
2301
2302   Implements the post-error-checking part of
2303   gcc_jit_type_get_vector.  */
2304
2305recording::type *
2306recording::type::get_vector (size_t num_units)
2307{
2308  recording::type *result
2309    = new vector_type (this, num_units);
2310  m_ctxt->record (result);
2311  return result;
2312}
2313
2314const char *
2315recording::type::access_as_type (reproducer &r)
2316{
2317  return r.get_identifier (this);
2318}
2319
2320/* Override of default implementation of
2321   recording::type::get_size.
2322
2323   Return the size in bytes.  This is in use for global
2324   initialization.  */
2325
2326size_t
2327recording::memento_of_get_type::get_size ()
2328{
2329  int size;
2330  switch (m_kind)
2331    {
2332    case GCC_JIT_TYPE_VOID:
2333      return 0;
2334    case GCC_JIT_TYPE_BOOL:
2335    case GCC_JIT_TYPE_CHAR:
2336    case GCC_JIT_TYPE_SIGNED_CHAR:
2337    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2338      return 1;
2339    case GCC_JIT_TYPE_SHORT:
2340    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2341      size = SHORT_TYPE_SIZE;
2342      break;
2343    case GCC_JIT_TYPE_INT:
2344    case GCC_JIT_TYPE_UNSIGNED_INT:
2345      size = INT_TYPE_SIZE;
2346      break;
2347    case GCC_JIT_TYPE_LONG:
2348    case GCC_JIT_TYPE_UNSIGNED_LONG:
2349      size = LONG_TYPE_SIZE;
2350      break;
2351    case GCC_JIT_TYPE_LONG_LONG:
2352    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2353      size = LONG_LONG_TYPE_SIZE;
2354      break;
2355    case GCC_JIT_TYPE_UINT8_T:
2356    case GCC_JIT_TYPE_INT8_T:
2357      size = 8;
2358      break;
2359    case GCC_JIT_TYPE_UINT16_T:
2360    case GCC_JIT_TYPE_INT16_T:
2361      size = 16;
2362      break;
2363    case GCC_JIT_TYPE_UINT32_T:
2364    case GCC_JIT_TYPE_INT32_T:
2365      size = 32;
2366      break;
2367    case GCC_JIT_TYPE_UINT64_T:
2368    case GCC_JIT_TYPE_INT64_T:
2369      size = 64;
2370      break;
2371    case GCC_JIT_TYPE_UINT128_T:
2372    case GCC_JIT_TYPE_INT128_T:
2373      size = 128;
2374      break;
2375    case GCC_JIT_TYPE_FLOAT:
2376      size = FLOAT_TYPE_SIZE;
2377      break;
2378    case GCC_JIT_TYPE_DOUBLE:
2379      size = DOUBLE_TYPE_SIZE;
2380      break;
2381    case GCC_JIT_TYPE_LONG_DOUBLE:
2382      size = LONG_DOUBLE_TYPE_SIZE;
2383      break;
2384    case GCC_JIT_TYPE_SIZE_T:
2385      size = MAX_BITS_PER_WORD;
2386      break;
2387    default:
2388      /* As this function is called by
2389	 'gcc_jit_global_set_initializer' and
2390	 'recording::global::write_reproducer' possible types are only
2391	 integrals and are covered by the previous cases.  */
2392      gcc_unreachable ();
2393    }
2394
2395  return size / BITS_PER_UNIT;
2396}
2397
2398/* Implementation of pure virtual hook recording::type::dereference for
2399   recording::memento_of_get_type.  */
2400
2401recording::type *
2402recording::memento_of_get_type::dereference ()
2403{
2404  switch (m_kind)
2405    {
2406    default: gcc_unreachable ();
2407
2408    case GCC_JIT_TYPE_VOID:
2409      return NULL;
2410
2411    case GCC_JIT_TYPE_VOID_PTR:
2412      return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
2413
2414    case GCC_JIT_TYPE_BOOL:
2415    case GCC_JIT_TYPE_CHAR:
2416    case GCC_JIT_TYPE_SIGNED_CHAR:
2417    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2418    case GCC_JIT_TYPE_SHORT:
2419    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2420    case GCC_JIT_TYPE_INT:
2421    case GCC_JIT_TYPE_UNSIGNED_INT:
2422    case GCC_JIT_TYPE_LONG:
2423    case GCC_JIT_TYPE_UNSIGNED_LONG:
2424    case GCC_JIT_TYPE_LONG_LONG:
2425    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2426    case GCC_JIT_TYPE_UINT8_T:
2427    case GCC_JIT_TYPE_UINT16_T:
2428    case GCC_JIT_TYPE_UINT32_T:
2429    case GCC_JIT_TYPE_UINT64_T:
2430    case GCC_JIT_TYPE_UINT128_T:
2431    case GCC_JIT_TYPE_INT8_T:
2432    case GCC_JIT_TYPE_INT16_T:
2433    case GCC_JIT_TYPE_INT32_T:
2434    case GCC_JIT_TYPE_INT64_T:
2435    case GCC_JIT_TYPE_INT128_T:
2436    case GCC_JIT_TYPE_FLOAT:
2437    case GCC_JIT_TYPE_DOUBLE:
2438    case GCC_JIT_TYPE_LONG_DOUBLE:
2439    case GCC_JIT_TYPE_COMPLEX_FLOAT:
2440    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
2441    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
2442      /* Not a pointer: */
2443      return NULL;
2444
2445    case GCC_JIT_TYPE_CONST_CHAR_PTR:
2446      return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
2447
2448    case GCC_JIT_TYPE_SIZE_T:
2449      /* Not a pointer: */
2450      return NULL;
2451
2452    case GCC_JIT_TYPE_FILE_PTR:
2453      /* Give the client code back an opaque "struct FILE".  */
2454      return m_ctxt->get_opaque_FILE_type ();
2455    }
2456}
2457
2458/* Implementation of pure virtual hook recording::type::is_int for
2459   recording::memento_of_get_type.  */
2460
2461bool
2462recording::memento_of_get_type::is_int () const
2463{
2464  switch (m_kind)
2465    {
2466    default: gcc_unreachable ();
2467
2468    case GCC_JIT_TYPE_VOID:
2469      return false;
2470
2471    case GCC_JIT_TYPE_VOID_PTR:
2472      return false;
2473
2474    case GCC_JIT_TYPE_BOOL:
2475      return false;
2476
2477    case GCC_JIT_TYPE_CHAR:
2478    case GCC_JIT_TYPE_SIGNED_CHAR:
2479    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2480    case GCC_JIT_TYPE_SHORT:
2481    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2482    case GCC_JIT_TYPE_INT:
2483    case GCC_JIT_TYPE_UNSIGNED_INT:
2484    case GCC_JIT_TYPE_LONG:
2485    case GCC_JIT_TYPE_UNSIGNED_LONG:
2486    case GCC_JIT_TYPE_LONG_LONG:
2487    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2488    case GCC_JIT_TYPE_UINT8_T:
2489    case GCC_JIT_TYPE_UINT16_T:
2490    case GCC_JIT_TYPE_UINT32_T:
2491    case GCC_JIT_TYPE_UINT64_T:
2492    case GCC_JIT_TYPE_UINT128_T:
2493    case GCC_JIT_TYPE_INT8_T:
2494    case GCC_JIT_TYPE_INT16_T:
2495    case GCC_JIT_TYPE_INT32_T:
2496    case GCC_JIT_TYPE_INT64_T:
2497    case GCC_JIT_TYPE_INT128_T:
2498      return true;
2499
2500    case GCC_JIT_TYPE_FLOAT:
2501    case GCC_JIT_TYPE_DOUBLE:
2502    case GCC_JIT_TYPE_LONG_DOUBLE:
2503      return false;
2504
2505    case GCC_JIT_TYPE_CONST_CHAR_PTR:
2506      return false;
2507
2508    case GCC_JIT_TYPE_SIZE_T:
2509      return true;
2510
2511    case GCC_JIT_TYPE_FILE_PTR:
2512      return false;
2513
2514    case GCC_JIT_TYPE_COMPLEX_FLOAT:
2515    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
2516    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
2517      return false;
2518    }
2519}
2520
2521/* Implementation of pure virtual hook recording::type::is_signed for
2522   recording::memento_of_get_type.  */
2523
2524bool
2525recording::memento_of_get_type::is_signed () const
2526{
2527  switch (m_kind)
2528    {
2529    default: gcc_unreachable ();
2530
2531    case GCC_JIT_TYPE_SIGNED_CHAR:
2532    case GCC_JIT_TYPE_CHAR:
2533    case GCC_JIT_TYPE_SHORT:
2534    case GCC_JIT_TYPE_INT:
2535    case GCC_JIT_TYPE_LONG:
2536    case GCC_JIT_TYPE_LONG_LONG:
2537    case GCC_JIT_TYPE_INT8_T:
2538    case GCC_JIT_TYPE_INT16_T:
2539    case GCC_JIT_TYPE_INT32_T:
2540    case GCC_JIT_TYPE_INT64_T:
2541    case GCC_JIT_TYPE_INT128_T:
2542      return true;
2543
2544    case GCC_JIT_TYPE_VOID:
2545    case GCC_JIT_TYPE_VOID_PTR:
2546    case GCC_JIT_TYPE_BOOL:
2547    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2548    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2549    case GCC_JIT_TYPE_UNSIGNED_INT:
2550    case GCC_JIT_TYPE_UNSIGNED_LONG:
2551    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2552    case GCC_JIT_TYPE_UINT8_T:
2553    case GCC_JIT_TYPE_UINT16_T:
2554    case GCC_JIT_TYPE_UINT32_T:
2555    case GCC_JIT_TYPE_UINT64_T:
2556    case GCC_JIT_TYPE_UINT128_T:
2557
2558    case GCC_JIT_TYPE_FLOAT:
2559    case GCC_JIT_TYPE_DOUBLE:
2560    case GCC_JIT_TYPE_LONG_DOUBLE:
2561
2562    case GCC_JIT_TYPE_CONST_CHAR_PTR:
2563
2564    case GCC_JIT_TYPE_SIZE_T:
2565
2566    case GCC_JIT_TYPE_FILE_PTR:
2567
2568    case GCC_JIT_TYPE_COMPLEX_FLOAT:
2569    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
2570    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
2571      return false;
2572    }
2573}
2574
2575/* Implementation of pure virtual hook recording::type::is_float for
2576   recording::memento_of_get_type.  */
2577
2578bool
2579recording::memento_of_get_type::is_float () const
2580{
2581  switch (m_kind)
2582    {
2583    default: gcc_unreachable ();
2584
2585    case GCC_JIT_TYPE_VOID:
2586      return false;
2587
2588    case GCC_JIT_TYPE_VOID_PTR:
2589      return false;
2590
2591    case GCC_JIT_TYPE_BOOL:
2592      return false;
2593
2594    case GCC_JIT_TYPE_CHAR:
2595    case GCC_JIT_TYPE_SIGNED_CHAR:
2596    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2597    case GCC_JIT_TYPE_SHORT:
2598    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2599    case GCC_JIT_TYPE_INT:
2600    case GCC_JIT_TYPE_UNSIGNED_INT:
2601    case GCC_JIT_TYPE_LONG:
2602    case GCC_JIT_TYPE_UNSIGNED_LONG:
2603    case GCC_JIT_TYPE_LONG_LONG:
2604    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2605    case GCC_JIT_TYPE_UINT8_T:
2606    case GCC_JIT_TYPE_UINT16_T:
2607    case GCC_JIT_TYPE_UINT32_T:
2608    case GCC_JIT_TYPE_UINT64_T:
2609    case GCC_JIT_TYPE_UINT128_T:
2610    case GCC_JIT_TYPE_INT8_T:
2611    case GCC_JIT_TYPE_INT16_T:
2612    case GCC_JIT_TYPE_INT32_T:
2613    case GCC_JIT_TYPE_INT64_T:
2614    case GCC_JIT_TYPE_INT128_T:
2615      return false;
2616
2617    case GCC_JIT_TYPE_FLOAT:
2618    case GCC_JIT_TYPE_DOUBLE:
2619    case GCC_JIT_TYPE_LONG_DOUBLE:
2620      return true;
2621
2622    case GCC_JIT_TYPE_CONST_CHAR_PTR:
2623      return false;
2624
2625    case GCC_JIT_TYPE_SIZE_T:
2626      return false;
2627
2628    case GCC_JIT_TYPE_FILE_PTR:
2629      return false;
2630
2631    case GCC_JIT_TYPE_COMPLEX_FLOAT:
2632    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
2633    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
2634      return true;
2635    }
2636}
2637
2638/* Implementation of pure virtual hook recording::type::is_bool for
2639   recording::memento_of_get_type.  */
2640
2641bool
2642recording::memento_of_get_type::is_bool () const
2643{
2644  switch (m_kind)
2645    {
2646    default: gcc_unreachable ();
2647
2648    case GCC_JIT_TYPE_VOID:
2649      return false;
2650
2651    case GCC_JIT_TYPE_VOID_PTR:
2652      return false;
2653
2654    case GCC_JIT_TYPE_BOOL:
2655      return true;
2656
2657    case GCC_JIT_TYPE_CHAR:
2658    case GCC_JIT_TYPE_SIGNED_CHAR:
2659    case GCC_JIT_TYPE_UNSIGNED_CHAR:
2660    case GCC_JIT_TYPE_SHORT:
2661    case GCC_JIT_TYPE_UNSIGNED_SHORT:
2662    case GCC_JIT_TYPE_INT:
2663    case GCC_JIT_TYPE_UNSIGNED_INT:
2664    case GCC_JIT_TYPE_LONG:
2665    case GCC_JIT_TYPE_UNSIGNED_LONG:
2666    case GCC_JIT_TYPE_LONG_LONG:
2667    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
2668    case GCC_JIT_TYPE_UINT8_T:
2669    case GCC_JIT_TYPE_UINT16_T:
2670    case GCC_JIT_TYPE_UINT32_T:
2671    case GCC_JIT_TYPE_UINT64_T:
2672    case GCC_JIT_TYPE_UINT128_T:
2673    case GCC_JIT_TYPE_INT8_T:
2674    case GCC_JIT_TYPE_INT16_T:
2675    case GCC_JIT_TYPE_INT32_T:
2676    case GCC_JIT_TYPE_INT64_T:
2677    case GCC_JIT_TYPE_INT128_T:
2678      return false;
2679
2680    case GCC_JIT_TYPE_FLOAT:
2681    case GCC_JIT_TYPE_DOUBLE:
2682    case GCC_JIT_TYPE_LONG_DOUBLE:
2683      return false;
2684
2685    case GCC_JIT_TYPE_CONST_CHAR_PTR:
2686      return false;
2687
2688    case GCC_JIT_TYPE_SIZE_T:
2689      return false;
2690
2691    case GCC_JIT_TYPE_FILE_PTR:
2692      return false;
2693
2694    case GCC_JIT_TYPE_COMPLEX_FLOAT:
2695    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
2696    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
2697      return false;
2698    }
2699}
2700
2701/* Implementation of pure virtual hook recording::memento::replay_into
2702   for recording::memento_of_get_type.  */
2703
2704void
2705recording::memento_of_get_type::replay_into (replayer *r)
2706{
2707  set_playback_obj (r->get_type (m_kind));
2708}
2709
2710/* The implementation of class gcc::jit::recording::memento_of_get_type.  */
2711
2712/* Descriptive strings for each of enum gcc_jit_types.  */
2713
2714static const char * const get_type_strings[] = {
2715  "void",    /* GCC_JIT_TYPE_VOID */
2716  "void *",  /* GCC_JIT_TYPE_VOID_PTR */
2717
2718  "bool",  /* GCC_JIT_TYPE_BOOL */
2719
2720  "char",           /* GCC_JIT_TYPE_CHAR */
2721  "signed char",    /* GCC_JIT_TYPE_SIGNED_CHAR */
2722  "unsigned char",  /* GCC_JIT_TYPE_UNSIGNED_CHAR */
2723
2724  "short",           /* GCC_JIT_TYPE_SHORT */
2725  "unsigned short",  /* GCC_JIT_TYPE_UNSIGNED_SHORT */
2726
2727  "int",           /* GCC_JIT_TYPE_INT */
2728  "unsigned int",  /* GCC_JIT_TYPE_UNSIGNED_INT */
2729
2730  "long",           /* GCC_JIT_TYPE_LONG  */
2731  "unsigned long",  /* GCC_JIT_TYPE_UNSIGNED_LONG, */
2732
2733  "long long",           /* GCC_JIT_TYPE_LONG_LONG */
2734  "unsigned long long",  /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
2735
2736  "float",        /* GCC_JIT_TYPE_FLOAT */
2737  "double",       /* GCC_JIT_TYPE_DOUBLE */
2738  "long double",  /* GCC_JIT_TYPE_LONG_DOUBLE */
2739
2740  "const char *",  /* GCC_JIT_TYPE_CONST_CHAR_PTR */
2741
2742  "size_t",  /* GCC_JIT_TYPE_SIZE_T */
2743
2744  "FILE *",  /* GCC_JIT_TYPE_FILE_PTR */
2745
2746  "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
2747  "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
2748  "complex long double",  /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
2749
2750  "__uint8_t",    /* GCC_JIT_TYPE_UINT8_T */
2751  "__uint16_t",   /* GCC_JIT_TYPE_UINT16_T */
2752  "__uint32_t",   /* GCC_JIT_TYPE_UINT32_T */
2753  "__uint64_t",   /* GCC_JIT_TYPE_UINT64_T */
2754  "__uint128_t",  /* GCC_JIT_TYPE_UINT128_T */
2755  "__int8_t",     /* GCC_JIT_TYPE_INT8_T */
2756  "__int16_t",    /* GCC_JIT_TYPE_INT16_T */
2757  "__int32_t",    /* GCC_JIT_TYPE_INT32_T */
2758  "__int64_t",    /* GCC_JIT_TYPE_INT64_T */
2759  "__int128_t",   /* GCC_JIT_TYPE_INT128_T */
2760
2761};
2762
2763/* Implementation of recording::memento::make_debug_string for
2764   results of get_type, using a simple table of type names.  */
2765
2766recording::string *
2767recording::memento_of_get_type::make_debug_string ()
2768{
2769  return m_ctxt->new_string (get_type_strings[m_kind]);
2770}
2771
2772static const char * const get_type_enum_strings[] = {
2773  "GCC_JIT_TYPE_VOID",
2774  "GCC_JIT_TYPE_VOID_PTR",
2775  "GCC_JIT_TYPE_BOOL",
2776  "GCC_JIT_TYPE_CHAR",
2777  "GCC_JIT_TYPE_SIGNED_CHAR",
2778  "GCC_JIT_TYPE_UNSIGNED_CHAR",
2779  "GCC_JIT_TYPE_SHORT",
2780  "GCC_JIT_TYPE_UNSIGNED_SHORT",
2781  "GCC_JIT_TYPE_INT",
2782  "GCC_JIT_TYPE_UNSIGNED_INT",
2783  "GCC_JIT_TYPE_LONG",
2784  "GCC_JIT_TYPE_UNSIGNED_LONG",
2785  "GCC_JIT_TYPE_LONG_LONG",
2786  "GCC_JIT_TYPE_UNSIGNED_LONG_LONG",
2787  "GCC_JIT_TYPE_FLOAT",
2788  "GCC_JIT_TYPE_DOUBLE",
2789  "GCC_JIT_TYPE_LONG_DOUBLE",
2790  "GCC_JIT_TYPE_CONST_CHAR_PTR",
2791  "GCC_JIT_TYPE_SIZE_T",
2792  "GCC_JIT_TYPE_FILE_PTR",
2793  "GCC_JIT_TYPE_COMPLEX_FLOAT",
2794  "GCC_JIT_TYPE_COMPLEX_DOUBLE",
2795  "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE",
2796  "GCC_JIT_TYPE_UINT8_T",
2797  "GCC_JIT_TYPE_UINT16_T",
2798  "GCC_JIT_TYPE_UINT32_T",
2799  "GCC_JIT_TYPE_UINT64_T",
2800  "GCC_JIT_TYPE_UINT128_T",
2801  "GCC_JIT_TYPE_INT8_T",
2802  "GCC_JIT_TYPE_INT16_T",
2803  "GCC_JIT_TYPE_INT32_T",
2804  "GCC_JIT_TYPE_INT64_T",
2805  "GCC_JIT_TYPE_INT128_T",
2806};
2807
2808void
2809recording::memento_of_get_type::write_reproducer (reproducer &r)
2810{
2811  const char *id = r.make_identifier (this, "type");
2812  r.write ("  gcc_jit_type *%s = gcc_jit_context_get_type (%s, %s);\n",
2813	   id,
2814	   r.get_identifier (get_context ()),
2815	   get_type_enum_strings[m_kind]);
2816}
2817
2818/* The implementation of class gcc::jit::recording::memento_of_get_pointer.  */
2819
2820/* Override of default implementation of
2821   recording::type::get_size for get_pointer.  */
2822
2823size_t
2824recording::memento_of_get_pointer::get_size ()
2825{
2826  return POINTER_SIZE / BITS_PER_UNIT;
2827}
2828
2829/* Override of default implementation of
2830   recording::type::accepts_writes_from for get_pointer.
2831
2832   Require a pointer type, and allowing writes to
2833   (const T *) from a (T*), but not the other way around.  */
2834
2835bool
2836recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
2837{
2838  /* Must be a pointer type: */
2839  type *rtype_points_to = rtype->is_pointer ();
2840  if (!rtype_points_to)
2841    return false;
2842
2843  /* It's OK to assign to a (const T *) from a (T *).  */
2844  if (m_other_type->unqualified ()->accepts_writes_from (rtype_points_to))
2845  {
2846    return true;
2847  }
2848
2849  /* It's OK to assign to a (volatile const T *) from a (volatile const T *). */
2850  return m_other_type->is_same_type_as (rtype_points_to);
2851}
2852
2853/* Implementation of pure virtual hook recording::memento::replay_into
2854   for recording::memento_of_get_pointer.  */
2855
2856void
2857recording::memento_of_get_pointer::replay_into (replayer *)
2858{
2859  set_playback_obj (m_other_type->playback_type ()->get_pointer ());
2860}
2861
2862/* Implementation of recording::memento::make_debug_string for
2863   results of get_pointer, adding " *" to the underlying type,
2864   with special-casing to handle function pointer types.  */
2865
2866recording::string *
2867recording::memento_of_get_pointer::make_debug_string ()
2868{
2869  /* Special-case function pointer types, to put the "*" in parens between
2870     the return type and the params (for one level of dereferencing, at
2871     least).  */
2872  if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
2873    return fn_type->make_debug_string_with_ptr ();
2874
2875  return string::from_printf (m_ctxt,
2876			      "%s *", m_other_type->get_debug_string ());
2877}
2878
2879/* Implementation of recording::memento::write_reproducer for get_pointer.  */
2880
2881void
2882recording::memento_of_get_pointer::write_reproducer (reproducer &r)
2883{
2884  /* We need to special-case function pointer types; see the notes in
2885     recording::function_type::write_deferred_reproducer.  */
2886  if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
2887    {
2888      fn_type->write_deferred_reproducer (r, this);
2889      return;
2890    }
2891
2892  const char *id = r.make_identifier (this, "type");
2893  r.write ("  gcc_jit_type *%s =\n"
2894	   "    gcc_jit_type_get_pointer (%s);\n",
2895	   id,
2896	   r.get_identifier_as_type (m_other_type));
2897}
2898
2899/* The implementation of class gcc::jit::recording::memento_of_get_const.  */
2900
2901/* Implementation of pure virtual hook recording::memento::replay_into
2902   for recording::memento_of_get_const.  */
2903
2904void
2905recording::memento_of_get_const::replay_into (replayer *)
2906{
2907  set_playback_obj (m_other_type->playback_type ()->get_const ());
2908}
2909
2910/* Implementation of recording::memento::make_debug_string for
2911   results of get_const, prepending "const ".  */
2912
2913recording::string *
2914recording::memento_of_get_const::make_debug_string ()
2915{
2916  return string::from_printf (m_ctxt,
2917			      "const %s", m_other_type->get_debug_string ());
2918}
2919
2920/* Implementation of recording::memento::write_reproducer for const types. */
2921
2922void
2923recording::memento_of_get_const::write_reproducer (reproducer &r)
2924{
2925  const char *id = r.make_identifier (this, "type");
2926  r.write ("  gcc_jit_type *%s =\n"
2927	   "    gcc_jit_type_get_const (%s);\n",
2928	   id,
2929	   r.get_identifier_as_type (m_other_type));
2930}
2931
2932/* The implementation of class gcc::jit::recording::memento_of_get_volatile.  */
2933
2934/* Implementation of pure virtual hook recording::memento::replay_into
2935   for recording::memento_of_get_volatile.  */
2936
2937void
2938recording::memento_of_get_volatile::replay_into (replayer *)
2939{
2940  set_playback_obj (m_other_type->playback_type ()->get_volatile ());
2941}
2942
2943/* Implementation of recording::memento::make_debug_string for
2944   results of get_volatile, prepending "volatile ".  */
2945
2946recording::string *
2947recording::memento_of_get_volatile::make_debug_string ()
2948{
2949  return string::from_printf (m_ctxt,
2950			      "volatile %s", m_other_type->get_debug_string ());
2951}
2952
2953/* Implementation of recording::memento::write_reproducer for volatile
2954   types. */
2955
2956void
2957recording::memento_of_get_volatile::write_reproducer (reproducer &r)
2958{
2959  const char *id = r.make_identifier (this, "type");
2960  r.write ("  gcc_jit_type *%s =\n"
2961	   "    gcc_jit_type_get_volatile (%s);\n",
2962	   id,
2963	   r.get_identifier_as_type (m_other_type));
2964}
2965
2966/* The implementation of class gcc::jit::recording::memento_of_get_aligned.  */
2967
2968/* Implementation of pure virtual hook recording::memento::replay_into
2969   for recording::memento_of_get_aligned.  */
2970
2971void
2972recording::memento_of_get_aligned::replay_into (replayer *)
2973{
2974  set_playback_obj
2975    (m_other_type->playback_type ()->get_aligned (m_alignment_in_bytes));
2976}
2977
2978/* Implementation of recording::memento::make_debug_string for
2979   results of get_aligned.  */
2980
2981recording::string *
2982recording::memento_of_get_aligned::make_debug_string ()
2983{
2984  return string::from_printf (m_ctxt,
2985			      "%s  __attribute__((aligned(%zi)))",
2986			      m_other_type->get_debug_string (),
2987			      m_alignment_in_bytes);
2988}
2989
2990/* Implementation of recording::memento::write_reproducer for aligned
2991   types. */
2992
2993void
2994recording::memento_of_get_aligned::write_reproducer (reproducer &r)
2995{
2996  const char *id = r.make_identifier (this, "type");
2997  r.write ("  gcc_jit_type *%s =\n"
2998	   "    gcc_jit_type_get_aligned (%s, %zi);\n",
2999	   id,
3000	   r.get_identifier_as_type (m_other_type),
3001	   m_alignment_in_bytes);
3002}
3003
3004/* The implementation of class gcc::jit::recording::vector_type.  */
3005
3006/* Implementation of pure virtual hook recording::memento::replay_into
3007   for recording::vector_type.  */
3008
3009void
3010recording::vector_type::replay_into (replayer *)
3011{
3012  set_playback_obj
3013    (m_other_type->playback_type ()->get_vector (m_num_units));
3014}
3015
3016/* Implementation of recording::memento::make_debug_string for
3017   results of get_vector.  */
3018
3019recording::string *
3020recording::vector_type::make_debug_string ()
3021{
3022  return string::from_printf
3023    (m_ctxt,
3024     "%s  __attribute__((vector_size(sizeof (%s) * %zi)))",
3025     m_other_type->get_debug_string (),
3026     m_other_type->get_debug_string (),
3027     m_num_units);
3028}
3029
3030/* Implementation of recording::memento::write_reproducer for vector types. */
3031
3032void
3033recording::vector_type::write_reproducer (reproducer &r)
3034{
3035  const char *id = r.make_identifier (this, "type");
3036  r.write ("  gcc_jit_type *%s =\n"
3037	   "    gcc_jit_type_get_vector (%s, %zi);\n",
3038	   id,
3039	   r.get_identifier_as_type (m_other_type),
3040	   m_num_units);
3041}
3042
3043/* The implementation of class gcc::jit::recording::array_type */
3044
3045/* Implementation of pure virtual hook recording::type::dereference for
3046   recording::array_type.  */
3047
3048recording::type *
3049recording::array_type::dereference ()
3050{
3051  return m_element_type;
3052}
3053
3054/* Implementation of pure virtual hook recording::memento::replay_into
3055   for recording::array_type.  */
3056
3057void
3058recording::array_type::replay_into (replayer *r)
3059{
3060  set_playback_obj (r->new_array_type (playback_location (r, m_loc),
3061				       m_element_type->playback_type (),
3062				       m_num_elements));
3063}
3064
3065/* Implementation of recording::memento::make_debug_string for
3066   results of new_array_type.  */
3067
3068recording::string *
3069recording::array_type::make_debug_string ()
3070{
3071  return string::from_printf (m_ctxt,
3072			      "%s[%d]",
3073			      m_element_type->get_debug_string (),
3074			      m_num_elements);
3075}
3076
3077/* Implementation of recording::memento::write_reproducer for array
3078   types. */
3079
3080void
3081recording::array_type::write_reproducer (reproducer &r)
3082{
3083  const char *id = r.make_identifier (this, "array_type");
3084  r.write ("  gcc_jit_type *%s =\n"
3085	   "    gcc_jit_context_new_array_type (%s,\n"
3086	   "                                    %s, /* gcc_jit_location *loc */\n"
3087	   "                                    %s, /* gcc_jit_type *element_type */\n"
3088	   "                                    %i); /* int num_elements */\n",
3089	   id,
3090	   r.get_identifier (get_context ()),
3091	   r.get_identifier (m_loc),
3092	   r.get_identifier_as_type (m_element_type),
3093	   m_num_elements);
3094}
3095
3096/* The implementation of class gcc::jit::recording::function_type */
3097
3098/* Constructor for gcc::jit::recording::function_type.  */
3099
3100recording::function_type::function_type (context *ctxt,
3101					 type *return_type,
3102					 int num_params,
3103					 type **param_types,
3104					 int is_variadic)
3105: type (ctxt),
3106  m_return_type (return_type),
3107  m_param_types (),
3108  m_is_variadic (is_variadic)
3109{
3110  for (int i = 0; i< num_params; i++)
3111    m_param_types.safe_push (param_types[i]);
3112}
3113
3114/* Implementation of pure virtual hook recording::type::dereference for
3115   recording::function_type.  */
3116
3117recording::type *
3118recording::function_type::dereference ()
3119{
3120  return NULL;
3121}
3122
3123/* Implementation of virtual hook recording::type::is_same_type_as for
3124   recording::function_type.
3125
3126   We override this to avoid requiring identity of function pointer types,
3127   so that if client code has obtained the same signature in
3128   different ways (e.g. via gcc_jit_context_new_function_ptr_type
3129   vs gcc_jit_function_get_address), the different function_type
3130   instances are treated as compatible.
3131
3132   We can't use type::accepts_writes_from for this as we need a stronger
3133   notion of "sameness": if we have a fn_ptr type that has args that are
3134   themselves fn_ptr types, then those args still need to match exactly.
3135
3136   Alternatively, we could consolidate attempts to create identical
3137   function_type instances so that pointer equality works, but that runs
3138   into issues about the lifetimes of the cache (w.r.t. nested contexts).  */
3139
3140bool
3141recording::function_type::is_same_type_as (type *other)
3142{
3143  gcc_assert (other);
3144
3145  function_type *other_fn_type = other->dyn_cast_function_type ();
3146  if (!other_fn_type)
3147    return false;
3148
3149  /* Everything must match.  */
3150
3151  if (!m_return_type->is_same_type_as (other_fn_type->m_return_type))
3152    return false;
3153
3154  if (m_param_types.length () != other_fn_type->m_param_types.length ())
3155    return false;
3156
3157  unsigned i;
3158  type *param_type;
3159  FOR_EACH_VEC_ELT (m_param_types, i, param_type)
3160    if (!param_type->is_same_type_as (other_fn_type->m_param_types[i]))
3161      return false;
3162
3163  if (m_is_variadic != other_fn_type->m_is_variadic)
3164    return false;
3165
3166  /* Passed all tests.  */
3167  return true;
3168}
3169
3170/* Implementation of pure virtual hook recording::memento::replay_into
3171   for recording::function_type.  */
3172
3173void
3174recording::function_type::replay_into (replayer *r)
3175{
3176  /* Convert m_param_types to a vec of playback type.  */
3177  auto_vec <playback::type *> param_types;
3178  int i;
3179  recording::type *type;
3180  param_types.create (m_param_types.length ());
3181  FOR_EACH_VEC_ELT (m_param_types, i, type)
3182    param_types.safe_push (type->playback_type ());
3183
3184  set_playback_obj (r->new_function_type (m_return_type->playback_type (),
3185					  &param_types,
3186					  m_is_variadic));
3187}
3188
3189/* Special-casing for make_debug_string for get_pointer results for
3190   handling (one level) of pointers to functions.  */
3191
3192recording::string *
3193recording::function_type::make_debug_string_with_ptr ()
3194{
3195  return make_debug_string_with ("(*) ");
3196}
3197
3198/* Implementation of recording::memento::make_debug_string for
3199   results of new_function_type.  */
3200
3201recording::string *
3202recording::function_type::make_debug_string ()
3203{
3204  return make_debug_string_with ("");
3205}
3206
3207/* Build a debug string representation of the form:
3208
3209     RESULT_TYPE INSERT (PARAM_TYPES)
3210
3211   for use when handling 0 and 1 level of indirection to this
3212   function type.  */
3213
3214recording::string *
3215recording::function_type::make_debug_string_with (const char *insert)
3216{
3217  /* First, build a buffer for the arguments.  */
3218  /* Calculate length of said buffer.  */
3219  size_t sz = 1; /* nil terminator */
3220  for (unsigned i = 0; i< m_param_types.length (); i++)
3221    {
3222      sz += strlen (m_param_types[i]->get_debug_string ());
3223      sz += 2; /* ", " separator */
3224    }
3225  if (m_is_variadic)
3226    sz += 5; /* ", ..." separator and ellipsis */
3227
3228  /* Now allocate and populate the buffer.  */
3229  char *argbuf = new char[sz];
3230  size_t len = 0;
3231
3232  for (unsigned i = 0; i< m_param_types.length (); i++)
3233    {
3234      strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
3235      len += strlen (m_param_types[i]->get_debug_string ());
3236      if (i + 1 < m_param_types.length ())
3237	{
3238	  strcpy (argbuf + len, ", ");
3239	  len += 2;
3240	}
3241    }
3242  if (m_is_variadic)
3243    {
3244      if (m_param_types.length ())
3245	{
3246	  strcpy (argbuf + len, ", ");
3247	  len += 2;
3248	}
3249      strcpy (argbuf + len, "...");
3250      len += 3;
3251    }
3252  argbuf[len] = '\0';
3253
3254  /* ...and use it to get the string for the call as a whole.  */
3255  string *result = string::from_printf (m_ctxt,
3256					"%s %s(%s)",
3257					m_return_type->get_debug_string (),
3258					insert,
3259					argbuf);
3260
3261  delete[] argbuf;
3262
3263  return result;
3264}
3265
3266/* Implementation of recording::memento::write_reproducer for function
3267   types.  */
3268
3269void
3270recording::function_type::write_reproducer (reproducer &)
3271{
3272  /* see notes below.  */
3273}
3274
3275/* There's a get_pointer within context::new_function_ptr_type:
3276   the type received by client code isn't the memento for the
3277   function_type, but instead the result of get_pointer on it.
3278
3279   Hence we can't directly write a reproducer that gives function_type.
3280   Instead we special-case things within get_pointer, detecting this
3281   case, calling the following function.  */
3282
3283void
3284recording::function_type::write_deferred_reproducer (reproducer &r,
3285						     memento *ptr_type)
3286{
3287  gcc_assert (ptr_type);
3288  r.make_identifier (this, "function_type");
3289  const char *ptr_id = r.make_identifier (ptr_type, "ptr_to");
3290  const char *param_types_id = r.make_tmp_identifier ("params_for", this);
3291  r.write ("  gcc_jit_type *%s[%i] = {\n",
3292	   param_types_id,
3293	   m_param_types.length ());
3294  int i;
3295  type *param_type;
3296  FOR_EACH_VEC_ELT (m_param_types, i, param_type)
3297    r.write ("    %s,\n", r.get_identifier_as_type (param_type));
3298  r.write ("  };\n");
3299  r.write ("  gcc_jit_type *%s =\n"
3300	   "    gcc_jit_context_new_function_ptr_type (%s, /* gcc_jit_context *ctxt */\n"
3301	   "                                           %s, /* gcc_jit_location *loc */\n"
3302	   "                                           %s, /* gcc_jit_type *return_type */\n"
3303	   "                                           %i, /* int num_params */\n"
3304	   "                                           %s, /* gcc_jit_type **param_types */\n"
3305	   "                                           %i); /* int is_variadic */\n",
3306	   ptr_id,
3307	   r.get_identifier (get_context ()),
3308	   "NULL", /* location is not stored */
3309	   r.get_identifier_as_type (m_return_type),
3310	   m_param_types.length (),
3311	   param_types_id,
3312	   m_is_variadic);
3313}
3314
3315/* The implementation of class gcc::jit::recording::field.  */
3316
3317/* Implementation of pure virtual hook recording::memento::replay_into
3318   for recording::field.  */
3319
3320void
3321recording::field::replay_into (replayer *r)
3322{
3323  set_playback_obj (r->new_field (playback_location (r, m_loc),
3324				  m_type->playback_type (),
3325				  playback_string (m_name)));
3326}
3327
3328/* Override the default implementation of
3329   recording::memento::write_to_dump.  Dump each field
3330   by dumping a line of the form:
3331      TYPE NAME;
3332   so that we can build up a struct/union field by field.  */
3333
3334void
3335recording::field::write_to_dump (dump &d)
3336{
3337  d.write ("  %s %s;\n",
3338	   m_type->get_debug_string (),
3339	   m_name->c_str ());
3340}
3341
3342/* Implementation of recording::memento::make_debug_string for
3343   results of new_field.  */
3344
3345recording::string *
3346recording::field::make_debug_string ()
3347{
3348  return m_name;
3349}
3350
3351/* Implementation of recording::memento::write_reproducer for fields.  */
3352
3353void
3354recording::field::write_reproducer (reproducer &r)
3355{
3356  const char *id = r.make_identifier (this, "field");
3357  r.write("  gcc_jit_field *%s =\n"
3358	  "    gcc_jit_context_new_field (%s,\n"
3359	  "                               %s, /* gcc_jit_location *loc */\n"
3360	  "                               %s, /* gcc_jit_type *type, */\n"
3361	  "                               %s); /* const char *name */\n",
3362	  id,
3363	  r.get_identifier (get_context ()),
3364	  r.get_identifier (m_loc),
3365	  r.get_identifier_as_type (m_type),
3366	  m_name->get_debug_string ());
3367}
3368
3369/* The implementation of class gcc::jit::recording::bitfield.  */
3370
3371/* Implementation of pure virtual hook recording::memento::replay_into
3372   for recording::bitfield.  */
3373
3374void
3375recording::bitfield::replay_into (replayer *r)
3376{
3377  set_playback_obj (r->new_bitfield (playback_location (r, m_loc),
3378				     m_type->playback_type (),
3379				     m_width,
3380				     playback_string (m_name)));
3381}
3382
3383/* Override the default implementation of
3384   recording::memento::write_to_dump.  Dump each bit field
3385   by dumping a line of the form:
3386      TYPE NAME:WIDTH;
3387   so that we can build up a struct/union field by field.  */
3388
3389void
3390recording::bitfield::write_to_dump (dump &d)
3391{
3392  d.write ("  %s %s:%d;\n",
3393	   m_type->get_debug_string (),
3394	   m_name->c_str (),
3395	   m_width);
3396}
3397
3398/* Implementation of recording::memento::make_debug_string for
3399   results of new_bitfield.  */
3400
3401recording::string *
3402recording::bitfield::make_debug_string ()
3403{
3404  return string::from_printf (m_ctxt,
3405			      "%s:%d",
3406			      m_name->c_str (), m_width);
3407}
3408
3409/* Implementation of recording::memento::write_reproducer for bitfields.  */
3410
3411void
3412recording::bitfield::write_reproducer (reproducer &r)
3413{
3414  const char *id = r.make_identifier (this, "bitfield");
3415  r.write ("  gcc_jit_field *%s =\n"
3416	   "    gcc_jit_context_new_bitfield (%s,\n"
3417	   "                               %s, /* gcc_jit_location *loc */\n"
3418	   "                               %s, /* gcc_jit_type *type, */\n"
3419	   "                               %d, /* int width, */\n"
3420	   "                               %s); /* const char *name */\n",
3421	   id,
3422	   r.get_identifier (get_context ()),
3423	   r.get_identifier (m_loc),
3424	   r.get_identifier_as_type (m_type),
3425	   m_width,
3426	   m_name->get_debug_string ());
3427}
3428
3429/* The implementation of class gcc::jit::recording::compound_type */
3430
3431/* The constructor for gcc::jit::recording::compound_type.  */
3432
3433recording::compound_type::compound_type (context *ctxt,
3434					 location *loc,
3435					 string *name)
3436: type (ctxt),
3437  m_loc (loc),
3438  m_name (name),
3439  m_fields (NULL)
3440{
3441}
3442
3443/* Set the fields of a compound type.
3444
3445   Implements the post-error-checking part of
3446   gcc_jit_struct_set_fields, and is also used by
3447   gcc_jit_context_new_union_type.  */
3448
3449void
3450recording::compound_type::set_fields (location *loc,
3451				      int num_fields,
3452				      field **field_array)
3453{
3454  m_loc = loc;
3455  gcc_assert (m_fields == NULL);
3456
3457  m_fields = new fields (this, num_fields, field_array);
3458  m_ctxt->record (m_fields);
3459}
3460
3461/* Implementation of pure virtual hook recording::type::dereference for
3462   recording::compound_type.  */
3463
3464recording::type *
3465recording::compound_type::dereference ()
3466{
3467  return NULL; /* not a pointer */
3468}
3469
3470/* The implementation of class gcc::jit::recording::struct_.  */
3471
3472/* The constructor for gcc::jit::recording::struct_.  */
3473
3474recording::struct_::struct_ (context *ctxt,
3475			     location *loc,
3476			     string *name)
3477: compound_type (ctxt, loc, name)
3478{
3479}
3480
3481/* Implementation of pure virtual hook recording::memento::replay_into
3482   for recording::struct_.  */
3483
3484void
3485recording::struct_::replay_into (replayer *r)
3486{
3487  set_playback_obj (
3488    r->new_compound_type (playback_location (r, get_loc ()),
3489			  get_name ()->c_str (),
3490			  true /* is_struct */));
3491}
3492
3493const char *
3494recording::struct_::access_as_type (reproducer &r)
3495{
3496  return r.xstrdup_printf ("gcc_jit_struct_as_type (%s)",
3497			   r.get_identifier (this));
3498}
3499
3500/* Implementation of recording::memento::make_debug_string for
3501   structs.  */
3502
3503recording::string *
3504recording::struct_::make_debug_string ()
3505{
3506  return string::from_printf (m_ctxt,
3507			      "struct %s", get_name ()->c_str ());
3508}
3509
3510void
3511recording::struct_::write_reproducer (reproducer &r)
3512{
3513  const char *id = r.make_identifier (this, "struct");
3514  r.write ("  gcc_jit_struct *%s =\n"
3515	   "    gcc_jit_context_new_opaque_struct (%s,\n"
3516	   "                                       %s, /* gcc_jit_location *loc */\n"
3517	   "                                       %s); /* const char *name */\n",
3518	   id,
3519	   r.get_identifier (get_context ()),
3520	   r.get_identifier (get_loc ()),
3521	   get_name ()->get_debug_string ());
3522}
3523
3524/* The implementation of class gcc::jit::recording::union_.  */
3525
3526/* The constructor for gcc::jit::recording::union_.  */
3527
3528recording::union_::union_ (context *ctxt,
3529			   location *loc,
3530			   string *name)
3531: compound_type (ctxt, loc, name)
3532{
3533}
3534
3535/* Implementation of pure virtual hook recording::memento::replay_into
3536   for recording::union_.  */
3537
3538void
3539recording::union_::replay_into (replayer *r)
3540{
3541  set_playback_obj (
3542    r->new_compound_type (playback_location (r, get_loc ()),
3543			  get_name ()->c_str (),
3544			  false /* is_struct */));
3545}
3546
3547/* Implementation of recording::memento::make_debug_string for
3548   unions.  */
3549
3550recording::string *
3551recording::union_::make_debug_string ()
3552{
3553  return string::from_printf (m_ctxt,
3554			      "union %s", get_name ()->c_str ());
3555}
3556
3557/* Implementation of recording::memento::write_reproducer for unions.  */
3558
3559void
3560recording::union_::write_reproducer (reproducer &r)
3561{
3562  const char *id = r.make_identifier (this, "union");
3563
3564  const char *fields_id = r.make_tmp_identifier ("fields_for", this);
3565  r.write ("  gcc_jit_field *%s[%i] = {\n",
3566	   fields_id,
3567	   get_fields ()->length ());
3568  for (int i = 0; i < get_fields ()->length (); i++)
3569    r.write ("    %s,\n", r.get_identifier (get_fields ()->get_field (i)));
3570  r.write ("  };\n");
3571
3572  r.write ("  gcc_jit_type *%s =\n"
3573	   "    gcc_jit_context_new_union_type (%s,\n"
3574	   "                                    %s, /* gcc_jit_location *loc */\n"
3575	   "                                    %s, /* const char *name */\n"
3576	   "                                    %i, /* int num_fields */\n"
3577	   "                                    %s); /* gcc_jit_field **fields */\n",
3578	   id,
3579	   r.get_identifier (get_context ()),
3580	   r.get_identifier (get_loc ()),
3581	   get_name ()->get_debug_string (),
3582	   get_fields ()->length (),
3583	   fields_id);
3584}
3585
3586/* The implementation of class gcc::jit::recording::fields.  */
3587
3588/* The constructor for gcc::jit::recording::fields.  */
3589
3590recording::fields::fields (compound_type *struct_or_union,
3591			   int num_fields,
3592			   field **fields)
3593: memento (struct_or_union->m_ctxt),
3594  m_struct_or_union (struct_or_union),
3595  m_fields ()
3596{
3597  for (int i = 0; i < num_fields; i++)
3598    {
3599      gcc_assert (fields[i]->get_container () == NULL);
3600      fields[i]->set_container (m_struct_or_union);
3601      m_fields.safe_push (fields[i]);
3602    }
3603}
3604
3605/* Implementation of pure virtual hook recording::memento::replay_into
3606   for recording::fields.  */
3607
3608void
3609recording::fields::replay_into (replayer *)
3610{
3611  auto_vec<playback::field *> playback_fields;
3612  playback_fields.create (m_fields.length ());
3613  for (unsigned i = 0; i < m_fields.length (); i++)
3614    playback_fields.safe_push (m_fields[i]->playback_field ());
3615  m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
3616}
3617
3618/* Override the default implementation of
3619   recording::memento::write_to_dump by writing a union/struct
3620   declaration of this form:
3621
3622      struct/union NAME {
3623	TYPE_1 NAME_1;
3624	TYPE_2 NAME_2;
3625	....
3626	TYPE_N NAME_N;
3627      };
3628
3629    to the dump.  */
3630
3631void
3632recording::fields::write_to_dump (dump &d)
3633{
3634  int i;
3635  field *f;
3636
3637  d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
3638  FOR_EACH_VEC_ELT (m_fields, i, f)
3639    f->write_to_dump (d);
3640  d.write ("};\n");
3641}
3642
3643/* Implementation of recording::memento::write_reproducer for the fields
3644   subclass.  */
3645
3646void
3647recording::fields::write_reproducer (reproducer &r)
3648{
3649  if (m_struct_or_union)
3650    if (m_struct_or_union->dyn_cast_struct () == NULL)
3651      /* We have a union; the fields have already been written by
3652	 union::write_reproducer.  */
3653      return;
3654
3655  const char *fields_id = r.make_identifier (this, "fields");
3656  r.write ("  gcc_jit_field *%s[%i] = {\n",
3657	   fields_id,
3658	   m_fields.length ());
3659  int i;
3660  field *field;
3661  FOR_EACH_VEC_ELT (m_fields, i, field)
3662    r.write ("    %s,\n", r.get_identifier (field));
3663  r.write ("  };\n");
3664
3665  r.write ("  gcc_jit_struct_set_fields (%s, /* gcc_jit_struct *struct_type */\n"
3666	   "                             %s, /* gcc_jit_location *loc */\n"
3667	   "                             %i, /* int num_fields */\n"
3668	   "                             %s); /* gcc_jit_field **fields */\n",
3669	   r.get_identifier (m_struct_or_union),
3670	   r.get_identifier ((memento *)NULL),
3671	   m_fields.length (),
3672	   fields_id);
3673}
3674
3675/* Implementation of recording::memento::make_debug_string for
3676   field tables.  */
3677
3678recording::string *
3679recording::fields::make_debug_string ()
3680{
3681  return string::from_printf (m_ctxt,
3682			      "fields");
3683}
3684
3685/* The implementation of class gcc::jit::recording::rvalue.  */
3686
3687/* Create a recording::access_field_rvalue instance and add it to
3688   the rvalue's context's list of mementos.
3689
3690   Implements the post-error-checking part of
3691   gcc_jit_rvalue_access_field.  */
3692
3693recording::rvalue *
3694recording::rvalue::access_field (recording::location *loc,
3695				 field *field)
3696{
3697  recording::rvalue *result =
3698    new access_field_rvalue (m_ctxt, loc, this, field);
3699  m_ctxt->record (result);
3700  return result;
3701}
3702
3703/* Create a recording::dereference_field_rvalue instance and add it to
3704   the rvalue's context's list of mementos.
3705
3706   Implements the post-error-checking part of
3707   gcc_jit_rvalue_dereference_field.  */
3708
3709recording::lvalue *
3710recording::rvalue::dereference_field (recording::location *loc,
3711				      field *field)
3712{
3713  recording::lvalue *result =
3714    new dereference_field_rvalue (m_ctxt, loc, this, field);
3715  m_ctxt->record (result);
3716  return result;
3717}
3718
3719/* Create a recording::dereference_rvalue instance and add it to the
3720   rvalue's context's list of mementos.
3721
3722   Implements the post-error-checking part of
3723   gcc_jit_rvalue_dereference.  */
3724
3725recording::lvalue *
3726recording::rvalue::dereference (recording::location *loc)
3727{
3728  recording::lvalue *result =
3729    new dereference_rvalue (m_ctxt, loc, this);
3730  m_ctxt->record (result);
3731  return result;
3732}
3733
3734/* An rvalue visitor, for validating that every rvalue within an expression
3735   trees within "STMT" has the correct scope (e.g. no access to locals
3736   of a different function).  */
3737
3738class rvalue_usage_validator : public recording::rvalue_visitor
3739{
3740 public:
3741  rvalue_usage_validator (const char *api_funcname,
3742			  recording::context *ctxt,
3743			  recording::statement *stmt);
3744
3745  void
3746  visit (recording::rvalue *rvalue) FINAL OVERRIDE;
3747
3748 private:
3749  const char *m_api_funcname;
3750  recording::context *m_ctxt;
3751  recording::statement *m_stmt;
3752};
3753
3754/* The trivial constructor for rvalue_usage_validator.  */
3755
3756rvalue_usage_validator::rvalue_usage_validator (const char *api_funcname,
3757						recording::context *ctxt,
3758						recording::statement *stmt)
3759  : m_api_funcname (api_funcname),
3760    m_ctxt (ctxt),
3761    m_stmt (stmt)
3762{
3763}
3764
3765/* Verify that the given rvalue is in the correct scope.  */
3766
3767void
3768rvalue_usage_validator::visit (recording::rvalue *rvalue)
3769{
3770  gcc_assert (m_stmt->get_block ());
3771  recording::function *stmt_scope = m_stmt->get_block ()->get_function ();
3772
3773  /* Most rvalues don't have a scope (only locals and params).  */
3774  if (rvalue->get_scope ())
3775    {
3776      if (rvalue->get_scope () != stmt_scope)
3777	m_ctxt->add_error
3778	  (rvalue->get_loc (),
3779	   "%s:"
3780	   " rvalue %s (type: %s)"
3781	   " has scope limited to function %s"
3782	   " but was used within function %s"
3783	   " (in statement: %s)",
3784	   m_api_funcname,
3785	   rvalue->get_debug_string (),
3786	   rvalue->get_type ()->get_debug_string (),
3787	   rvalue->get_scope ()->get_debug_string (),
3788	   stmt_scope->get_debug_string (),
3789	   m_stmt->get_debug_string ());
3790    }
3791  else
3792    {
3793      if (rvalue->dyn_cast_param ())
3794	m_ctxt->add_error
3795	  (rvalue->get_loc (),
3796	   "%s:"
3797	   " param %s (type: %s)"
3798	   " was used within function %s"
3799	   " (in statement: %s)"
3800	   " but is not associated with any function",
3801	   m_api_funcname,
3802	   rvalue->get_debug_string (),
3803	   rvalue->get_type ()->get_debug_string (),
3804	   stmt_scope->get_debug_string (),
3805	   m_stmt->get_debug_string ());
3806    }
3807}
3808
3809/* Verify that it's valid to use this rvalue (and all expressions
3810   in the tree below it) within the given statement.
3811
3812   For example, we must reject attempts to use a local from one
3813   function within a different function here, or we'll get
3814   an ICE deep inside toplev::main.  */
3815
3816void
3817recording::rvalue::verify_valid_within_stmt (const char *api_funcname, statement *s)
3818{
3819  rvalue_usage_validator v (api_funcname,
3820			    s->get_context (),
3821			    s);
3822
3823  /* Verify that it's OK to use this rvalue within s.  */
3824  v.visit (this);
3825
3826  /* Traverse the expression tree below "this", verifying all rvalues
3827     within it.  */
3828  visit_children (&v);
3829}
3830
3831/* Set the scope of this rvalue to be the given function.  This can only
3832   be done once on a given rvalue.  */
3833
3834void
3835recording::rvalue::set_scope (function *scope)
3836{
3837  gcc_assert (scope);
3838  gcc_assert (m_scope == NULL);
3839  m_scope = scope;
3840}
3841
3842
3843/* Implementation of recording::rvalue::access_as_rvalue for rvalues
3844   themselves.
3845   Instances of rvalue don't need an upcast call.  */
3846
3847const char *
3848recording::rvalue::access_as_rvalue (reproducer &r)
3849{
3850  return r.get_identifier (this);
3851}
3852
3853/* Return a debug string for the given rvalue, wrapping it in parentheses
3854   if needed to mimic C's precedence rules, i.e. if OUTER_PREC is of
3855   stronger precedence that this rvalue's precedence.
3856
3857   For example, given:
3858
3859           MULT
3860          /    \
3861       PLUS     MINUS
3862      /    \   /     \
3863     A      B C       D
3864
3865   we want to emit:
3866
3867     (A + B) * (C - D)
3868
3869   since MULT has strong precedence than PLUS and MINUS, whereas for:
3870
3871           PLUS
3872          /    \
3873       MULT     DIVIDE
3874      /    \   /      \
3875     A      B C        D
3876
3877   we can simply emit:
3878
3879     A * B + C / D
3880
3881   since PLUS has weaker precedence than MULT and DIVIDE.  */
3882
3883const char *
3884recording::rvalue::get_debug_string_parens (enum precedence outer_prec)
3885{
3886  enum precedence this_prec = get_precedence ();
3887
3888  /* If this_prec has stronger precedence than outer_prec, we don't
3889     need to wrap this in parens within the outer debug string.
3890     Stronger precedences occur earlier than weaker within the enum,
3891     so this is a less than test.  Equal precedences don't need
3892     parentheses.  */
3893  if (this_prec <= outer_prec)
3894    return get_debug_string();
3895
3896  /* Otherwise, we need parentheses.  */
3897
3898  /* Lazily-build and cache m_parenthesized_string.  */
3899  if (!m_parenthesized_string)
3900    {
3901      const char *debug_string = get_debug_string ();
3902      m_parenthesized_string = string::from_printf (get_context (),
3903						    "(%s)",
3904						    debug_string);
3905    }
3906  gcc_assert (m_parenthesized_string);
3907  return m_parenthesized_string->c_str ();
3908}
3909
3910
3911/* The implementation of class gcc::jit::recording::lvalue.  */
3912
3913/* Create a recording::new_access_field_of_lvalue instance and add it to
3914   the lvalue's context's list of mementos.
3915
3916   Implements the post-error-checking part of
3917   gcc_jit_lvalue_access_field.  */
3918
3919recording::lvalue *
3920recording::lvalue::access_field (recording::location *loc,
3921				 field *field)
3922{
3923  recording::lvalue *result =
3924    new access_field_of_lvalue (m_ctxt, loc, this, field);
3925  m_ctxt->record (result);
3926  return result;
3927}
3928
3929/* Implementation of recording::rvalue::access_as_rvalue for lvalues.
3930   Instances of lvalue need to be wrapped in a gcc_jit_lvalue_as_rvalue
3931   upcast call.  */
3932
3933const char *
3934recording::lvalue::access_as_rvalue (reproducer &r)
3935{
3936  return r.xstrdup_printf ("gcc_jit_lvalue_as_rvalue (%s)",
3937			   r.get_identifier (this));
3938}
3939
3940/* Implementation of recording::lvalue::access_as_lvalue for lvalues.
3941   Instances of lvalue don't need to be upcast.  */
3942
3943const char *
3944recording::lvalue::access_as_lvalue (reproducer &r)
3945{
3946  return r.get_identifier (this);
3947}
3948
3949/* Create a recording::get_address_of_lvalue instance and add it to
3950   the lvalue's context's list of mementos.
3951
3952   Implements the post-error-checking part of
3953   gcc_jit_lvalue_get_address.  */
3954
3955recording::rvalue *
3956recording::lvalue::get_address (recording::location *loc)
3957{
3958  recording::rvalue *result =
3959    new get_address_of_lvalue (m_ctxt, loc, this);
3960  m_ctxt->record (result);
3961  return result;
3962}
3963
3964void
3965recording::lvalue::set_tls_model (enum gcc_jit_tls_model model)
3966{
3967    m_tls_model = model;
3968}
3969
3970void recording::lvalue::set_link_section (const char *name)
3971{
3972  m_link_section = new_string (name);
3973}
3974
3975void recording::lvalue::set_register_name (const char *reg_name)
3976{
3977  m_reg_name = new_string (reg_name);
3978}
3979
3980void recording::lvalue::set_alignment (unsigned bytes)
3981{
3982  m_alignment = bytes;
3983}
3984
3985/* The implementation of class gcc::jit::recording::param.  */
3986
3987/* Implementation of pure virtual hook recording::memento::replay_into
3988   for recording::param.  */
3989
3990void
3991recording::param::replay_into (replayer *r)
3992{
3993  set_playback_obj (r->new_param (playback_location (r, m_loc),
3994				  m_type->playback_type (),
3995				  m_name->c_str ()));
3996}
3997
3998/* Implementation of recording::rvalue::access_as_rvalue for params.
3999   Instances of param need to be wrapped in a gcc_jit_param_as_rvalue
4000   upcast call.  */
4001
4002const char *
4003recording::param::access_as_rvalue (reproducer &r)
4004{
4005  return r.xstrdup_printf ("gcc_jit_param_as_rvalue (%s)",
4006			   r.get_identifier (this));
4007}
4008
4009/* Implementation of recording::lvalue::access_as_lvalue for params.
4010   Instances of param need to be wrapped in a gcc_jit_param_as_lvalue
4011   upcast call.  */
4012
4013const char *
4014recording::param::access_as_lvalue (reproducer &r)
4015{
4016  return r.xstrdup_printf ("gcc_jit_param_as_lvalue (%s)",
4017			   r.get_identifier (this));
4018}
4019
4020/* Implementation of recording::memento::write_reproducer for params. */
4021
4022void
4023recording::param::write_reproducer (reproducer &r)
4024{
4025  const char *id = r.make_identifier (this, "param");
4026  r.write ("  gcc_jit_param *%s =\n"
4027	   "    gcc_jit_context_new_param (%s,\n"
4028	   "                               %s, /* gcc_jit_location *loc */\n"
4029	   "                               %s, /*gcc_jit_type *type */\n"
4030	   "                               %s); /* const char *name */\n",
4031	   id,
4032    r.get_identifier (get_context ()),
4033	   r.get_identifier (m_loc),
4034	   r.get_identifier_as_type (m_type),
4035	   m_name->get_debug_string ());
4036}
4037
4038/* The implementation of class gcc::jit::recording::function.  */
4039
4040/* gcc::jit::recording::function's constructor.  */
4041
4042recording::function::function (context *ctxt,
4043			       recording::location *loc,
4044			       enum gcc_jit_function_kind kind,
4045			       type *return_type,
4046			       recording::string *name,
4047			       int num_params,
4048			       recording::param **params,
4049			       int is_variadic,
4050			       enum built_in_function builtin_id)
4051: memento (ctxt),
4052  m_loc (loc),
4053  m_kind (kind),
4054  m_return_type (return_type),
4055  m_name (name),
4056  m_params (),
4057  m_is_variadic (is_variadic),
4058  m_builtin_id (builtin_id),
4059  m_locals (),
4060  m_blocks (),
4061  m_fn_ptr_type (NULL)
4062{
4063  for (int i = 0; i< num_params; i++)
4064    {
4065      param *param = params[i];
4066      gcc_assert (param);
4067
4068      /* Associate each param with this function.
4069
4070	 Verify that the param doesn't already have a function.  */
4071      if (param->get_scope ())
4072	{
4073	  /* We've already rejected attempts to reuse a param between
4074	     different functions (within gcc_jit_context_new_function), so
4075	     if the param *does* already have a function, it must be being
4076	     reused within the params array for this function.  We must
4077	     produce an error for this reuse (blocking the compile), since
4078	     otherwise we'd have an ICE later on.  */
4079	  gcc_assert (this == param->get_scope ());
4080	  ctxt->add_error
4081	    (loc,
4082	     "gcc_jit_context_new_function:"
4083	     " parameter %s (type: %s)"
4084	     " is used more than once when creating function %s",
4085	     param->get_debug_string (),
4086	     param->get_type ()->get_debug_string (),
4087	     name->c_str ());
4088	}
4089      else
4090	{
4091	  /* The normal, non-error case: associate this function with the
4092	     param.  */
4093	  param->set_scope (this);
4094	}
4095
4096      m_params.safe_push (param);
4097    }
4098}
4099
4100/* Implementation of pure virtual hook recording::memento::replay_into
4101   for recording::function.  */
4102
4103void
4104recording::function::replay_into (replayer *r)
4105{
4106  /* Convert m_params to a vec of playback param.  */
4107  auto_vec <playback::param *> params;
4108  int i;
4109  recording::param *param;
4110  params.create (m_params.length ());
4111  FOR_EACH_VEC_ELT (m_params, i, param)
4112    params.safe_push (param->playback_param ());
4113
4114  set_playback_obj (r->new_function (playback_location (r, m_loc),
4115				     m_kind,
4116				     m_return_type->playback_type (),
4117				     m_name->c_str (),
4118				     &params,
4119				     m_is_variadic,
4120				     m_builtin_id));
4121}
4122
4123/* Create a recording::local instance and add it to
4124   the functions's context's list of mementos, and to the function's
4125   list of locals.
4126
4127   Implements the post-error-checking part of
4128   gcc_jit_function_new_local.  */
4129
4130recording::lvalue *
4131recording::function::new_local (recording::location *loc,
4132				type *type,
4133				const char *name)
4134{
4135  local *result = new local (this, loc, type, new_string (name));
4136  m_ctxt->record (result);
4137  m_locals.safe_push (result);
4138  return result;
4139}
4140
4141/* Create a recording::block instance and add it to
4142   the functions's context's list of mementos, and to the function's
4143   list of blocks.
4144
4145   Implements the post-error-checking part of
4146   gcc_jit_function_new_block.  */
4147
4148recording::block*
4149recording::function::new_block (const char *name)
4150{
4151  gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
4152
4153  recording::block *result =
4154    new recording::block (this, m_blocks.length (), new_string (name));
4155  m_ctxt->record (result);
4156  m_blocks.safe_push (result);
4157  return result;
4158}
4159
4160/* Override the default implementation of
4161   recording::memento::write_to_dump by dumping a C-like
4162   representation of the function; either like a prototype
4163   for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
4164   all other kinds of function.  */
4165
4166void
4167recording::function::write_to_dump (dump &d)
4168{
4169  switch (m_kind)
4170    {
4171    default: gcc_unreachable ();
4172    case GCC_JIT_FUNCTION_EXPORTED:
4173    case GCC_JIT_FUNCTION_IMPORTED:
4174      d.write ("extern ");
4175      break;
4176    case GCC_JIT_FUNCTION_INTERNAL:
4177      d.write ("static ");
4178      break;
4179    case GCC_JIT_FUNCTION_ALWAYS_INLINE:
4180      d.write ("static inline ");
4181      break;
4182     }
4183  d.write ("%s\n", m_return_type->get_debug_string ());
4184
4185  if (d.update_locations ())
4186    m_loc = d.make_location ();
4187
4188  d.write ("%s (", get_debug_string ());
4189
4190  int i;
4191  recording::param *param;
4192  FOR_EACH_VEC_ELT (m_params, i, param)
4193    {
4194      if (i > 0)
4195	d.write (", ");
4196      d.write ("%s %s",
4197	       param->get_type ()->get_debug_string (),
4198	       param->get_debug_string ());
4199    }
4200  d.write (")");
4201  if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
4202    {
4203      d.write ("; /* (imported) */\n\n");
4204    }
4205  else
4206    {
4207      int i;
4208      local *var = NULL;
4209      block *b;
4210      d.write ("\n{\n");
4211
4212      /* Write locals: */
4213      FOR_EACH_VEC_ELT (m_locals, i, var)
4214	var->write_to_dump (d);
4215      if (m_locals.length ())
4216	d.write ("\n");
4217
4218      /* Write each block: */
4219      FOR_EACH_VEC_ELT (m_blocks, i, b)
4220	{
4221	  if (i > 0)
4222	    d.write ("\n");
4223	  b->write_to_dump (d);
4224	}
4225
4226      d.write ("}\n\n");
4227    }
4228}
4229
4230/* Pre-compilation validation of a function, for those things we can't
4231   check until the context is (supposedly) fully-populated.  */
4232
4233void
4234recording::function::validate ()
4235{
4236  /* Complain about empty functions with non-void return type.  */
4237  if (m_kind != GCC_JIT_FUNCTION_IMPORTED
4238      && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
4239    if (m_blocks.length () == 0)
4240      m_ctxt->add_error (m_loc,
4241			 "function %s returns non-void (type: %s)"
4242			 " but has no blocks",
4243			 get_debug_string (),
4244			 m_return_type->get_debug_string ());
4245
4246  /* Check that all blocks are terminated.  */
4247  int num_invalid_blocks = 0;
4248  {
4249    int i;
4250    block *b;
4251
4252    FOR_EACH_VEC_ELT (m_blocks, i, b)
4253      if (!b->validate ())
4254	num_invalid_blocks++;
4255  }
4256
4257  /* Check that all blocks are reachable.  */
4258  if (!m_ctxt->get_inner_bool_option
4259        (INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS)
4260      && m_blocks.length () > 0 && num_invalid_blocks == 0)
4261    {
4262      /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
4263	 flag, starting at the initial block.  */
4264      auto_vec<block *> worklist (m_blocks.length ());
4265      worklist.safe_push (m_blocks[0]);
4266      while (worklist.length () > 0)
4267	{
4268	  block *b = worklist.pop ();
4269	  b->m_is_reachable = true;
4270
4271	  /* Add successor blocks that aren't yet marked to the worklist.  */
4272	  /* We checked that each block has a terminating statement above .  */
4273	  vec <block *> successors = b->get_successor_blocks ();
4274	  int i;
4275	  block *succ;
4276	  FOR_EACH_VEC_ELT (successors, i, succ)
4277	    if (!succ->m_is_reachable)
4278	      worklist.safe_push (succ);
4279	  successors.release ();
4280	}
4281
4282      /* Now complain about any blocks that haven't been marked.  */
4283      {
4284	int i;
4285	block *b;
4286	FOR_EACH_VEC_ELT (m_blocks, i, b)
4287	  if (!b->m_is_reachable)
4288	    m_ctxt->add_error (b->get_loc (),
4289			       "unreachable block: %s",
4290			       b->get_debug_string ());
4291      }
4292    }
4293}
4294
4295/* Implements the post-error-checking part of
4296   gcc_jit_function_dump_to_dot.  */
4297
4298void
4299recording::function::dump_to_dot (const char *path)
4300{
4301  FILE *fp  = fopen (path, "w");
4302  if (!fp)
4303    return;
4304
4305  pretty_printer the_pp;
4306  the_pp.buffer->stream = fp;
4307
4308  pretty_printer *pp = &the_pp;
4309
4310  pp_printf (pp, "digraph %s", get_debug_string ());
4311  pp_string (pp, " {\n");
4312
4313  /* Blocks: */
4314  {
4315    int i;
4316    block *b;
4317    FOR_EACH_VEC_ELT (m_blocks, i, b)
4318      b->dump_to_dot (pp);
4319  }
4320
4321  /* Edges: */
4322  {
4323    int i;
4324    block *b;
4325    FOR_EACH_VEC_ELT (m_blocks, i, b)
4326      b->dump_edges_to_dot (pp);
4327  }
4328
4329  pp_string (pp, "}\n");
4330  pp_flush (pp);
4331  fclose (fp);
4332}
4333
4334/* Implements the post-error-checking part of
4335   gcc_jit_function_get_address.  */
4336
4337recording::rvalue *
4338recording::function::get_address (recording::location *loc)
4339{
4340  /* Lazily create and cache the function pointer type.  */
4341  if (!m_fn_ptr_type)
4342    {
4343      /* Make a recording::function_type for this function.  */
4344      auto_vec <recording::type *> param_types (m_params.length ());
4345      unsigned i;
4346      recording::param *param;
4347      FOR_EACH_VEC_ELT (m_params, i, param)
4348	param_types.safe_push (param->get_type ());
4349      recording::function_type *fn_type
4350	= m_ctxt->new_function_type (m_return_type,
4351				     m_params.length (),
4352				     param_types.address (),
4353				     m_is_variadic);
4354      m_fn_ptr_type = fn_type->get_pointer ();
4355    }
4356  gcc_assert (m_fn_ptr_type);
4357
4358  rvalue *result = new function_pointer (get_context (), loc, this, m_fn_ptr_type);
4359  m_ctxt->record (result);
4360  return result;
4361}
4362
4363/* Implementation of recording::memento::make_debug_string for
4364   functions.  */
4365
4366recording::string *
4367recording::function::make_debug_string ()
4368{
4369  return m_name;
4370}
4371
4372/* A table of enum gcc_jit_function_kind values expressed in string
4373   form.  */
4374
4375static const char * const names_of_function_kinds[] = {
4376  "GCC_JIT_FUNCTION_EXPORTED",
4377  "GCC_JIT_FUNCTION_INTERNAL",
4378  "GCC_JIT_FUNCTION_IMPORTED",
4379  "GCC_JIT_FUNCTION_ALWAYS_INLINE"
4380};
4381
4382/* Implementation of recording::memento::write_reproducer for functions. */
4383
4384void
4385recording::function::write_reproducer (reproducer &r)
4386{
4387  const char *id = r.make_identifier (this, "func");
4388
4389  if (m_builtin_id)
4390    {
4391      r.write ("  gcc_jit_function *%s =\n"
4392	       "    gcc_jit_context_get_builtin_function (%s,\n"
4393	       "                                          %s);\n",
4394	       id,
4395	       r.get_identifier (get_context ()),
4396	       m_name->get_debug_string ());
4397      return;
4398    }
4399  const char *params_id = r.make_tmp_identifier ("params_for", this);
4400  r.write ("  gcc_jit_param *%s[%i] = {\n",
4401	   params_id,
4402	   m_params.length ());
4403  int i;
4404  param *param;
4405  FOR_EACH_VEC_ELT (m_params, i, param)
4406    r.write ("    %s,\n", r.get_identifier (param));
4407  r.write ("  };\n");
4408  r.write ("  gcc_jit_function *%s =\n"
4409	   "    gcc_jit_context_new_function (%s, /* gcc_jit_context *ctxt */\n"
4410	   "                                  %s, /* gcc_jit_location *loc */\n"
4411	   "                                  %s, /* enum gcc_jit_function_kind kind */\n"
4412	   "                                  %s, /* gcc_jit_type *return_type */\n"
4413	   "                                  %s, /* const char *name */\n"
4414	   "                                  %i, /* int num_params */\n"
4415	   "                                  %s, /* gcc_jit_param **params */\n"
4416	   "                                  %i); /* int is_variadic */\n",
4417	   id,
4418	   r.get_identifier (get_context ()),
4419	   r.get_identifier (m_loc),
4420	   names_of_function_kinds[m_kind],
4421	   r.get_identifier_as_type (m_return_type),
4422	   m_name->get_debug_string (),
4423	   m_params.length (),
4424	   params_id,
4425	   m_is_variadic);
4426}
4427
4428
4429/* The implementation of class gcc::jit::recording::block.  */
4430
4431/* Create a recording::eval instance and add it to
4432   the block's context's list of mementos, and to the block's
4433   list of statements.
4434
4435   Implements the heart of gcc_jit_block_add_eval.  */
4436
4437recording::statement *
4438recording::block::add_eval (recording::location *loc,
4439			    recording::rvalue *rvalue)
4440{
4441  statement *result = new eval (this, loc, rvalue);
4442  m_ctxt->record (result);
4443  m_statements.safe_push (result);
4444  return result;
4445}
4446
4447/* Create a recording::assignment instance and add it to
4448   the block's context's list of mementos, and to the block's
4449   list of statements.
4450
4451   Implements the heart of gcc_jit_block_add_assignment.  */
4452
4453recording::statement *
4454recording::block::add_assignment (recording::location *loc,
4455				  recording::lvalue *lvalue,
4456				  recording::rvalue *rvalue)
4457{
4458  statement *result = new assignment (this, loc, lvalue, rvalue);
4459  m_ctxt->record (result);
4460  m_statements.safe_push (result);
4461  return result;
4462}
4463
4464/* Create a recording::assignment_op instance and add it to
4465   the block's context's list of mementos, and to the block's
4466   list of statements.
4467
4468   Implements the heart of gcc_jit_block_add_assignment_op.  */
4469
4470recording::statement *
4471recording::block::add_assignment_op (recording::location *loc,
4472				     recording::lvalue *lvalue,
4473				     enum gcc_jit_binary_op op,
4474				     recording::rvalue *rvalue)
4475{
4476  statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
4477  m_ctxt->record (result);
4478  m_statements.safe_push (result);
4479  return result;
4480}
4481
4482/* Create a recording::comment instance and add it to
4483   the block's context's list of mementos, and to the block's
4484   list of statements.
4485
4486   Implements the heart of gcc_jit_block_add_comment.  */
4487
4488recording::statement *
4489recording::block::add_comment (recording::location *loc,
4490			       const char *text)
4491{
4492  statement *result = new comment (this, loc, new_string (text));
4493  m_ctxt->record (result);
4494  m_statements.safe_push (result);
4495  return result;
4496}
4497
4498/* Create a recording::extended_asm_simple instance and add it to
4499   the block's context's list of mementos, and to the block's
4500   list of statements.
4501
4502   Implements the heart of gcc_jit_block_add_extended_asm.  */
4503
4504recording::extended_asm *
4505recording::block::add_extended_asm (location *loc,
4506				    const char *asm_template)
4507{
4508  extended_asm *result
4509    = new extended_asm_simple (this, loc, new_string (asm_template));
4510  m_ctxt->record (result);
4511  m_statements.safe_push (result);
4512  return result;
4513}
4514
4515/* Create a recording::end_with_conditional instance and add it to
4516   the block's context's list of mementos, and to the block's
4517   list of statements.
4518
4519   Implements the heart of gcc_jit_block_end_with_conditional.  */
4520
4521recording::statement *
4522recording::block::end_with_conditional (recording::location *loc,
4523					recording::rvalue *boolval,
4524					recording::block *on_true,
4525					recording::block *on_false)
4526{
4527  statement *result = new conditional (this, loc, boolval, on_true, on_false);
4528  m_ctxt->record (result);
4529  m_statements.safe_push (result);
4530  m_has_been_terminated = true;
4531  return result;
4532}
4533
4534/* Create a recording::end_with_jump instance and add it to
4535   the block's context's list of mementos, and to the block's
4536   list of statements.
4537
4538   Implements the heart of gcc_jit_block_end_with_jump.  */
4539
4540recording::statement *
4541recording::block::end_with_jump (recording::location *loc,
4542				 recording::block *target)
4543{
4544  statement *result = new jump (this, loc, target);
4545  m_ctxt->record (result);
4546  m_statements.safe_push (result);
4547  m_has_been_terminated = true;
4548  return result;
4549}
4550
4551/* Create a recording::end_with_return instance and add it to
4552   the block's context's list of mementos, and to the block's
4553   list of statements.
4554
4555   Implements the post-error-checking parts of
4556   gcc_jit_block_end_with_return and
4557   gcc_jit_block_end_with_void_return.  */
4558
4559recording::statement *
4560recording::block::end_with_return (recording::location *loc,
4561				   recording::rvalue *rvalue)
4562{
4563  /* This is used by both gcc_jit_function_add_return and
4564     gcc_jit_function_add_void_return; rvalue will be non-NULL for
4565     the former and NULL for the latter.  */
4566  statement *result = new return_ (this, loc, rvalue);
4567  m_ctxt->record (result);
4568  m_statements.safe_push (result);
4569  m_has_been_terminated = true;
4570  return result;
4571}
4572
4573/* Create a recording::switch_ instance and add it to
4574   the block's context's list of mementos, and to the block's
4575   list of statements.
4576
4577   Implements the heart of gcc_jit_block_end_with_switch.  */
4578
4579recording::statement *
4580recording::block::end_with_switch (recording::location *loc,
4581				   recording::rvalue *expr,
4582				   recording::block *default_block,
4583				   int num_cases,
4584				   recording::case_ **cases)
4585{
4586  statement *result = new switch_ (this, loc,
4587				   expr,
4588				   default_block,
4589				   num_cases,
4590				   cases);
4591  m_ctxt->record (result);
4592  m_statements.safe_push (result);
4593  m_has_been_terminated = true;
4594  return result;
4595}
4596
4597/* Create a recording::extended_asm_goto instance and add it to
4598   the block's context's list of mementos, and to the block's
4599   list of statements.
4600
4601   Implements the heart of gcc_jit_block_end_with_extended_asm_goto.  */
4602
4603
4604recording::extended_asm *
4605recording::block::end_with_extended_asm_goto (location *loc,
4606					      const char *asm_template,
4607					      int num_goto_blocks,
4608					      block **goto_blocks,
4609					      block *fallthrough_block)
4610{
4611  extended_asm *result
4612    = new extended_asm_goto (this, loc, new_string (asm_template),
4613			     num_goto_blocks, goto_blocks,
4614			     fallthrough_block);
4615  m_ctxt->record (result);
4616  m_statements.safe_push (result);
4617  m_has_been_terminated = true;
4618  return result;
4619}
4620
4621/* Override the default implementation of
4622   recording::memento::write_to_dump for blocks by writing
4623   an unindented block name as a label, followed by the indented
4624   statements:
4625
4626    BLOCK_NAME:
4627      STATEMENT_1;
4628      STATEMENT_2;
4629      ...
4630      STATEMENT_N;  */
4631
4632void
4633recording::block::write_to_dump (dump &d)
4634{
4635  d.write ("%s:\n", get_debug_string ());
4636
4637  int i;
4638  statement *s;
4639  FOR_EACH_VEC_ELT (m_statements, i, s)
4640    s->write_to_dump (d);
4641}
4642
4643/* Validate a block by ensuring that it has been terminated.  */
4644
4645bool
4646recording::block::validate ()
4647{
4648  /* Check for termination.  */
4649  if (!has_been_terminated ())
4650    {
4651      statement *stmt = get_last_statement ();
4652      location *loc = stmt ? stmt->get_loc () : NULL;
4653      m_func->get_context ()->add_error (loc,
4654					 "unterminated block in %s: %s",
4655					 m_func->get_debug_string (),
4656					 get_debug_string ());
4657      return false;
4658    }
4659
4660  return true;
4661}
4662
4663/* Get the source-location of a block by using that of the first
4664   statement within it, if any.  */
4665
4666recording::location *
4667recording::block::get_loc () const
4668{
4669  recording::statement *stmt = get_first_statement ();
4670  if (stmt)
4671    return stmt->get_loc ();
4672  else
4673    return NULL;
4674}
4675
4676/* Get the first statement within a block, if any.  */
4677
4678recording::statement *
4679recording::block::get_first_statement () const
4680{
4681  if (m_statements.length ())
4682    return m_statements[0];
4683  else
4684    return NULL;
4685}
4686
4687/* Get the last statement within a block, if any.  */
4688
4689recording::statement *
4690recording::block::get_last_statement () const
4691{
4692  if (m_statements.length ())
4693    return m_statements[m_statements.length () - 1];
4694  else
4695    return NULL;
4696}
4697
4698/* Assuming that this block has been terminated, get the successor blocks
4699   as a vector.  Ownership of the vector transfers to the caller, which
4700   must call its release () method.
4701
4702   Used when validating functions, and when dumping dot representations
4703   of them.  */
4704
4705vec <recording::block *>
4706recording::block::get_successor_blocks () const
4707{
4708  gcc_assert (m_has_been_terminated);
4709  statement *last_statement = get_last_statement ();
4710  gcc_assert (last_statement);
4711  return last_statement->get_successor_blocks ();
4712}
4713
4714/* Implementation of pure virtual hook recording::memento::replay_into
4715   for recording::block.  */
4716
4717void
4718recording::block::replay_into (replayer *)
4719{
4720  set_playback_obj (m_func->playback_function ()
4721		      ->new_block (playback_string (m_name)));
4722}
4723
4724/* Implementation of recording::memento::make_debug_string for
4725   blocks.  */
4726
4727recording::string *
4728recording::block::make_debug_string ()
4729{
4730  if (m_name)
4731    return m_name;
4732  else
4733    return string::from_printf (m_ctxt,
4734				"<UNNAMED BLOCK %p>",
4735				(void *)this);
4736}
4737
4738/* Implementation of recording::memento::write_reproducer for blocks. */
4739
4740void
4741recording::block::write_reproducer (reproducer &r)
4742{
4743  const char *id = r.make_identifier (this, "block");
4744  r.write ("  gcc_jit_block *%s =\n"
4745	   "    gcc_jit_function_new_block (%s, %s);\n",
4746	   id,
4747	   r.get_identifier (m_func),
4748	   m_name ? m_name->get_debug_string () : "NULL");
4749}
4750
4751/* Disable warnings about missing quoting in GCC diagnostics for
4752   the pp_printf calls.  Their format strings deliberately don't
4753   follow GCC diagnostic conventions.  */
4754#if __GNUC__ >= 10
4755#  pragma GCC diagnostic push
4756#  pragma GCC diagnostic ignored "-Wformat-diag"
4757#endif
4758
4759/* Dump a block in graphviz form into PP, capturing the block name (if
4760   any) and the statements.  */
4761
4762void
4763recording::block::dump_to_dot (pretty_printer *pp)
4764{
4765  pp_printf (pp,
4766	     ("\tblock_%d "
4767	      "[shape=record,style=filled,fillcolor=white,label=\"{"),
4768	     m_index);
4769  pp_write_text_to_stream (pp);
4770  if (m_name)
4771    {
4772      pp_string (pp, m_name->c_str ());
4773      pp_string (pp, ":");
4774      pp_newline (pp);
4775      pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
4776    }
4777
4778  int i;
4779  statement *s;
4780  FOR_EACH_VEC_ELT (m_statements, i, s)
4781    {
4782      pp_string (pp, s->get_debug_string ());
4783      pp_newline (pp);
4784      pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
4785    }
4786
4787  pp_string (pp,
4788	     "}\"];\n\n");
4789  pp_flush (pp);
4790}
4791
4792/* Dump the out-edges of the block in graphviz form into PP.  */
4793
4794void
4795recording::block::dump_edges_to_dot (pretty_printer *pp)
4796{
4797  vec <block *> successors = get_successor_blocks ();
4798  int i;
4799  block *succ;
4800  FOR_EACH_VEC_ELT (successors, i, succ)
4801    pp_printf (pp,
4802	       "\tblock_%d:s -> block_%d:n;\n",
4803	       m_index, succ->m_index);
4804  successors.release ();
4805}
4806
4807#if __GNUC__ >= 10
4808#  pragma GCC diagnostic pop
4809#endif
4810
4811namespace recording {
4812static const enum tls_model tls_models[] = {
4813  TLS_MODEL_NONE, /* GCC_JIT_TLS_MODEL_NONE */
4814  TLS_MODEL_GLOBAL_DYNAMIC, /* GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC */
4815  TLS_MODEL_LOCAL_DYNAMIC, /* GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC */
4816  TLS_MODEL_INITIAL_EXEC, /* GCC_JIT_TLS_MODEL_INITIAL_EXEC */
4817  TLS_MODEL_LOCAL_EXEC, /* GCC_JIT_TLS_MODEL_LOCAL_EXEC */
4818};
4819} /* namespace recording */
4820
4821/* The implementation of class gcc::jit::recording::global.  */
4822
4823/* Implementation of pure virtual hook recording::memento::replay_into
4824   for recording::global.  */
4825
4826void
4827recording::global::replay_into (replayer *r)
4828{
4829  playback::lvalue *global = m_initializer
4830  ? r->new_global_initialized (playback_location (r, m_loc),
4831				 m_kind,
4832				 m_type->playback_type (),
4833				 m_type->dereference ()->get_size (),
4834				 m_initializer_num_bytes
4835				 / m_type->dereference ()->get_size (),
4836				 m_initializer,
4837				 playback_string (m_name),
4838				 m_flags)
4839    : r->new_global (playback_location (r, m_loc),
4840		     m_kind,
4841		     m_type->playback_type (),
4842		     playback_string (m_name),
4843		     m_flags);
4844
4845  if (m_tls_model != GCC_JIT_TLS_MODEL_NONE)
4846    global->set_tls_model (recording::tls_models[m_tls_model]);
4847
4848  if (m_link_section != NULL)
4849    global->set_link_section (m_link_section->c_str ());
4850
4851  if (m_reg_name != NULL)
4852    global->set_register_name (m_reg_name->c_str ());
4853
4854  if (m_alignment != 0)
4855    global->set_alignment (m_alignment);
4856
4857  set_playback_obj (global);
4858}
4859
4860/* Override the default implementation of
4861   recording::memento::write_to_dump for globals.
4862   This will be of the form:
4863
4864   GCC_JIT_GLOBAL_EXPORTED:
4865      "TYPE NAME;"
4866      e.g. "int foo;"
4867
4868   GCC_JIT_GLOBAL_INTERNAL:
4869      "static TYPE NAME;"
4870      e.g. "static int foo;"
4871
4872   GCC_JIT_GLOBAL_IMPORTED:
4873      "extern TYPE NAME;"
4874      e.g. "extern int foo;"
4875
4876   These are written to the top of the dump by
4877   recording::context::dump_to_file.  */
4878
4879void
4880recording::global::write_to_dump (dump &d)
4881{
4882  if (d.update_locations ())
4883    m_loc = d.make_location ();
4884
4885  switch (m_kind)
4886    {
4887    default:
4888      gcc_unreachable ();
4889
4890    case GCC_JIT_GLOBAL_EXPORTED:
4891      break;
4892
4893    case GCC_JIT_GLOBAL_INTERNAL:
4894      d.write ("static ");
4895      break;
4896
4897    case GCC_JIT_GLOBAL_IMPORTED:
4898      d.write ("extern ");
4899      break;
4900    }
4901
4902  d.write ("%s %s",
4903	   m_type->get_debug_string (),
4904	   get_debug_string ());
4905
4906  if (!m_initializer && !m_rvalue_init)
4907    {
4908      d.write (";\n");
4909    }
4910  else if (m_initializer)
4911    {
4912      d.write ("=\n  { ");
4913      const unsigned char *p = (const unsigned char *)m_initializer;
4914      for (size_t i = 0; i < m_initializer_num_bytes; i++)
4915	{
4916	  d.write ("0x%x, ", p[i]);
4917	  if (i && !(i % 64))
4918	    d.write ("\n    ");
4919	}
4920      d.write ("};\n");
4921    }
4922  else if (m_rvalue_init)
4923    {
4924      d.write (" = ");
4925      d.write (m_rvalue_init->get_debug_string ());
4926      d.write (";\n");
4927    }
4928
4929  return;
4930}
4931
4932/* A table of enum gcc_jit_global_kind values expressed in string
4933   form.  */
4934
4935static const char * const global_kind_reproducer_strings[] = {
4936  "GCC_JIT_GLOBAL_EXPORTED",
4937  "GCC_JIT_GLOBAL_INTERNAL",
4938  "GCC_JIT_GLOBAL_IMPORTED"
4939};
4940
4941template <typename T>
4942void
4943recording::global::write_initializer_reproducer (const char *id, reproducer &r)
4944{
4945  const char *init_id = r.make_tmp_identifier ("init_for", this);
4946  r.write ("  %s %s[] =\n    {",
4947	   m_type->dereference ()->get_debug_string (),
4948	   init_id);
4949
4950  const T *p = (const T *)m_initializer;
4951  for (size_t i = 0; i < m_initializer_num_bytes / sizeof (T); i++)
4952    {
4953      r.write ("%" PRIu64 ", ", (uint64_t)p[i]);
4954      if (i && !(i % 64))
4955	r.write ("\n    ");
4956    }
4957  r.write ("};\n");
4958  r.write ("  gcc_jit_global_set_initializer (%s, %s, sizeof (%s));\n",
4959	   id, init_id, init_id);
4960}
4961
4962/* Implementation of recording::memento::write_reproducer for globals. */
4963
4964static const char * const tls_model_enum_strings[] = {
4965  "GCC_JIT_TLS_MODEL_NONE",
4966  "GCC_JIT_TLS_MODEL_GLOBAL_DYNAMIC",
4967  "GCC_JIT_TLS_MODEL_LOCAL_DYNAMIC",
4968  "GCC_JIT_TLS_MODEL_INITIAL_EXEC",
4969  "GCC_JIT_TLS_MODEL_LOCAL_EXEC",
4970};
4971
4972void
4973recording::global::write_reproducer (reproducer &r)
4974{
4975  const char *id = r.make_identifier (this, "block");
4976  r.write ("  gcc_jit_lvalue *%s =\n"
4977    "    gcc_jit_context_new_global (%s, /* gcc_jit_context *ctxt */\n"
4978    "                                %s, /* gcc_jit_location *loc */\n"
4979    "                                %s, /* enum gcc_jit_global_kind kind */\n"
4980    "                                %s, /* gcc_jit_type *type */\n"
4981    "                                %s); /* const char *name */\n",
4982    id,
4983    r.get_identifier (get_context ()),
4984    r.get_identifier (m_loc),
4985    global_kind_reproducer_strings[m_kind],
4986    r.get_identifier_as_type (get_type ()),
4987    m_name->get_debug_string ());
4988
4989  if (m_tls_model != GCC_JIT_TLS_MODEL_NONE)
4990    r.write ("  gcc_jit_lvalue_set_tls_model (%s, /* gcc_jit_lvalue *lvalue */\n"
4991	     "                                %s); /* enum gcc_jit_tls_model model */\n",
4992	     id,
4993	     tls_model_enum_strings[m_tls_model]);
4994
4995  if (m_link_section != NULL)
4996    r.write ("  gcc_jit_lvalue_set_link_section (%s, /* gcc_jit_lvalue *lvalue */\n"
4997	"                                  \"%s\"); /* */\n",
4998     id,
4999     m_link_section->c_str ());
5000
5001  if (m_initializer)
5002    switch (m_type->dereference ()->get_size ())
5003      {
5004      case 1:
5005	write_initializer_reproducer<uint8_t> (id, r);
5006	break;
5007      case 2:
5008	write_initializer_reproducer<uint16_t> (id, r);
5009	break;
5010      case 4:
5011	write_initializer_reproducer<uint32_t> (id, r);
5012	break;
5013      case 8:
5014	write_initializer_reproducer<uint64_t> (id, r);
5015	break;
5016      default:
5017	/* This function is serving on sizes returned by 'get_size',
5018	   these are all covered by the previous cases.  */
5019	gcc_unreachable ();
5020      }
5021}
5022
5023/* The implementation of the various const-handling classes:
5024   gcc::jit::recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */
5025
5026/* Explicit specialization of the various mementos we're interested in.  */
5027template class recording::memento_of_new_rvalue_from_const <int>;
5028template class recording::memento_of_new_rvalue_from_const <long>;
5029template class recording::memento_of_new_rvalue_from_const <double>;
5030template class recording::memento_of_new_rvalue_from_const <void *>;
5031
5032/* Implementation of the pure virtual hook recording::memento::replay_into
5033   for recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */
5034
5035template <typename HOST_TYPE>
5036void
5037recording::
5038memento_of_new_rvalue_from_const <HOST_TYPE>::replay_into (replayer *r)
5039{
5040    set_playback_obj
5041      (r->new_rvalue_from_const <HOST_TYPE> (m_type->playback_type (),
5042					     m_value));
5043}
5044
5045/* The make_debug_string and write_reproducer methods vary between the
5046   various
5047     memento_of_new_rvalue_from_const <HOST_TYPE>
5048   classes, so we explicitly write specializations of them.
5049
5050   I (dmalcolm) find the code to be clearer if the "recording" vs "playback"
5051   namespaces are written out explicitly, which is why most of this file
5052   doesn't abbreviate things by entering the "recording" namespace.
5053
5054   However, these specializations are required to be in the same namespace
5055   as the template, hence we now have to enter the gcc::jit::recording
5056   namespace.  */
5057
5058namespace recording
5059{
5060
5061/* The make_debug_string specialization for <int>, which renders it as
5062     (TARGET_TYPE)LITERAL
5063   e.g.
5064     "(int)42".  */
5065
5066template <>
5067string *
5068memento_of_new_rvalue_from_const <int>::make_debug_string ()
5069{
5070  return string::from_printf (m_ctxt,
5071			      "(%s)%i",
5072			      m_type->get_debug_string (),
5073			      m_value);
5074}
5075
5076/* The get_wide_int specialization for <int>.  */
5077
5078template <>
5079bool
5080memento_of_new_rvalue_from_const <int>::get_wide_int (wide_int *out) const
5081{
5082  *out = wi::shwi (m_value, sizeof (m_value) * 8);
5083  return true;
5084}
5085
5086/* The write_reproducer specialization for <int>.  */
5087
5088template <>
5089void
5090memento_of_new_rvalue_from_const <int>::write_reproducer (reproducer &r)
5091{
5092  const char *id = r.make_identifier (this, "rvalue");
5093  r.write ("  gcc_jit_rvalue *%s =\n"
5094    "    gcc_jit_context_new_rvalue_from_int (%s, /* gcc_jit_context *ctxt */\n"
5095    "                                         %s, /* gcc_jit_type *numeric_type */\n"
5096    "                                         %i); /* int value */\n",
5097    id,
5098    r.get_identifier (get_context ()),
5099    r.get_identifier_as_type (m_type),
5100    m_value);
5101}
5102
5103/* The make_debug_string specialization for <long>, rendering it as
5104     (TARGET_TYPE)LITERAL
5105   e.g.
5106     "(long)42".  */
5107
5108template <>
5109string *
5110memento_of_new_rvalue_from_const <long>::make_debug_string ()
5111{
5112  return string::from_printf (m_ctxt,
5113			      "(%s)%li",
5114			      m_type->get_debug_string (),
5115			      m_value);
5116}
5117
5118/* The get_wide_int specialization for <long>.  */
5119
5120template <>
5121bool
5122memento_of_new_rvalue_from_const <long>::get_wide_int (wide_int *out) const
5123{
5124  *out = wi::shwi (m_value, sizeof (m_value) * 8);
5125  return true;
5126}
5127
5128/* The write_reproducer specialization for <long>.  */
5129
5130template <>
5131void
5132recording::memento_of_new_rvalue_from_const <long>::write_reproducer (reproducer &r)
5133{
5134  const char *id = r.make_identifier (this, "rvalue");
5135
5136  /* We have to special-case LONG_MIN, since e.g.
5137       -9223372036854775808L
5138     is parsed as
5139       -(9223372036854775808L)
5140     and hence we'd get:
5141	error: integer constant is so large that it is unsigned [-Werror]
5142	Workaround this by writing (LONG_MIN + 1) - 1.  */
5143  if (m_value == LONG_MIN)
5144    {
5145      r.write ("  gcc_jit_rvalue *%s =\n"
5146	       "    gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
5147	       "                                          %s, /* gcc_jit_type *numeric_type */\n"
5148	       "                                          %ldL - 1); /* long value */\n",
5149	       id,
5150	       r.get_identifier (get_context ()),
5151	       r.get_identifier_as_type (m_type),
5152	       m_value + 1);
5153      return;
5154    }
5155
5156  r.write ("  gcc_jit_rvalue *%s =\n"
5157	   "    gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
5158	   "                                          %s, /* gcc_jit_type *numeric_type */\n"
5159	   "                                          %ldL); /* long value */\n",
5160	   id,
5161	   r.get_identifier (get_context ()),
5162	   r.get_identifier_as_type (m_type),
5163	   m_value);
5164	   }
5165
5166/* The make_debug_string specialization for <double>, rendering it as
5167     (TARGET_TYPE)LITERAL
5168   e.g.
5169     "(float)42.0".  */
5170
5171template <>
5172string *
5173memento_of_new_rvalue_from_const <double>::make_debug_string ()
5174{
5175  return string::from_printf (m_ctxt,
5176			      "(%s)%f",
5177			      m_type->get_debug_string (),
5178			      m_value);
5179}
5180
5181/* The get_wide_int specialization for <double>.  */
5182
5183template <>
5184bool
5185memento_of_new_rvalue_from_const <double>::get_wide_int (wide_int *) const
5186{
5187  return false;
5188}
5189
5190/* The write_reproducer specialization for <double>.  */
5191
5192template <>
5193void
5194recording::memento_of_new_rvalue_from_const <double>::write_reproducer (reproducer &r)
5195{
5196  const char *id = r.make_identifier (this, "rvalue");
5197  r.write ("  gcc_jit_rvalue *%s =\n"
5198    "    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
5199    "                                            %s, /* gcc_jit_type *numeric_type */\n"
5200    "                                            %f); /* double value */\n",
5201    id,
5202    r.get_identifier (get_context ()),
5203    r.get_identifier_as_type (m_type),
5204    m_value);
5205}
5206
5207/* The make_debug_string specialization for <void *>, rendering it as
5208     (TARGET_TYPE)HEX
5209   e.g.
5210     "(int *)0xdeadbeef"
5211
5212   Zero is rendered as NULL e.g.
5213     "(int *)NULL".  */
5214
5215template <>
5216string *
5217memento_of_new_rvalue_from_const <void *>::make_debug_string ()
5218{
5219  if (m_value != NULL)
5220    return string::from_printf (m_ctxt,
5221				"(%s)%p",
5222				m_type->get_debug_string (), m_value);
5223  else
5224    return string::from_printf (m_ctxt,
5225				"(%s)NULL",
5226				m_type->get_debug_string ());
5227}
5228
5229/* The get_wide_int specialization for <void *>.  */
5230
5231template <>
5232bool
5233memento_of_new_rvalue_from_const <void *>::get_wide_int (wide_int *) const
5234{
5235  return false;
5236}
5237
5238/* Implementation of recording::memento::write_reproducer for <void *>
5239   values. */
5240
5241template <>
5242void
5243memento_of_new_rvalue_from_const <void *>::write_reproducer (reproducer &r)
5244{
5245  const char *id = r.make_identifier (this, "rvalue");
5246  if (m_value)
5247    r.write ("  gcc_jit_rvalue *%s =\n"
5248	     "    gcc_jit_context_new_rvalue_from_ptr (%s, /* gcc_jit_context *ctxt */\n"
5249	     "                                         %s, /* gcc_jit_type *pointer_type */\n"
5250	     "                                         (void *)%p); /* void *value */\n",
5251	     id,
5252	     r.get_identifier (get_context ()),
5253	     r.get_identifier_as_type (m_type),
5254	     m_value);
5255  else
5256    r.write ("  gcc_jit_rvalue *%s =\n"
5257	     "    gcc_jit_context_null (%s, /* gcc_jit_context *ctxt */\n"
5258	     "                          %s); /* gcc_jit_type *pointer_type */\n",
5259	     id,
5260	     r.get_identifier (get_context ()),
5261	     r.get_identifier_as_type (m_type));
5262}
5263
5264/* We're done specializing make_debug_string and write_reproducer, so we
5265   can exit the gcc::jit::recording namespace.  */
5266
5267} // namespace recording
5268
5269/* The implementation of class gcc::jit::recording::memento_of_new_string_literal.  */
5270
5271/* Implementation of pure virtual hook recording::memento::replay_into
5272   for recording::memento_of_new_string_literal.  */
5273
5274void
5275recording::memento_of_new_string_literal::replay_into (replayer *r)
5276{
5277  set_playback_obj (r->new_string_literal (m_value->c_str ()));
5278}
5279
5280/* Implementation of recording::memento::make_debug_string for
5281   string literals.  */
5282
5283recording::string *
5284recording::memento_of_new_string_literal::make_debug_string ()
5285{
5286  return string::from_printf (m_ctxt,
5287			      "%s",
5288			      m_value->get_debug_string ());
5289}
5290
5291/* Implementation of recording::memento::write_reproducer for string literal
5292   values. */
5293
5294void
5295recording::memento_of_new_string_literal::write_reproducer (reproducer &r)
5296{
5297  const char *id = r.make_identifier (this, "rvalue");
5298  r.write ("  gcc_jit_rvalue *%s =\n"
5299    "    gcc_jit_context_new_string_literal (%s, /* gcc_jit_context *ctxt */\n"
5300    "                                        %s); /* const char *value */\n",
5301    id,
5302    r.get_identifier (get_context ()),
5303    m_value->get_debug_string ());
5304}
5305
5306/* The implementation of class
5307   gcc::jit::recording::memento_of_new_rvalue_from_vector.  */
5308
5309/* The constructor for
5310   gcc::jit::recording::memento_of_new_rvalue_from_vector.  */
5311
5312recording::memento_of_new_rvalue_from_vector::
5313memento_of_new_rvalue_from_vector (context *ctxt,
5314				   location *loc,
5315				   vector_type *type,
5316				   rvalue **elements)
5317: rvalue (ctxt, loc, type),
5318  m_vector_type (type),
5319  m_elements ()
5320{
5321  for (unsigned i = 0; i < type->get_num_units (); i++)
5322    m_elements.safe_push (elements[i]);
5323}
5324
5325/* Implementation of pure virtual hook recording::memento::replay_into
5326   for recording::memento_of_new_rvalue_from_vector.  */
5327
5328void
5329recording::memento_of_new_rvalue_from_vector::replay_into (replayer *r)
5330{
5331  auto_vec<playback::rvalue *> playback_elements;
5332  playback_elements.create (m_elements.length ());
5333  for (unsigned i = 0; i< m_elements.length (); i++)
5334    playback_elements.safe_push (m_elements[i]->playback_rvalue ());
5335
5336  set_playback_obj (r->new_rvalue_from_vector (playback_location (r, m_loc),
5337					       m_type->playback_type (),
5338					       playback_elements));
5339}
5340
5341/* Implementation of pure virtual hook recording::rvalue::visit_children
5342   for recording::memento_of_new_rvalue_from_vector.  */
5343
5344void
5345recording::memento_of_new_rvalue_from_vector::visit_children (rvalue_visitor *v)
5346{
5347  for (unsigned i = 0; i< m_elements.length (); i++)
5348    v->visit (m_elements[i]);
5349}
5350
5351/* Implementation of recording::memento::make_debug_string for
5352   vectors.  */
5353
5354recording::string *
5355recording::memento_of_new_rvalue_from_vector::make_debug_string ()
5356{
5357  comma_separated_string elements (m_elements, get_precedence ());
5358
5359  /* Now build a string.  */
5360  string *result = string::from_printf (m_ctxt,
5361					"{%s}",
5362					elements.as_char_ptr ());
5363
5364 return result;
5365
5366}
5367
5368/* Implementation of recording::memento::write_reproducer for
5369   vectors.  */
5370
5371void
5372recording::memento_of_new_rvalue_from_vector::write_reproducer (reproducer &r)
5373{
5374  const char *id = r.make_identifier (this, "vector");
5375  const char *elements_id = r.make_tmp_identifier ("elements_for_", this);
5376  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
5377	   elements_id,
5378	   m_elements.length ());
5379  for (unsigned i = 0; i< m_elements.length (); i++)
5380    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_elements[i]));
5381  r.write ("  };\n");
5382  r.write ("  gcc_jit_rvalue *%s =\n"
5383	   "    gcc_jit_context_new_rvalue_from_vector (%s, /* gcc_jit_context *ctxt */\n"
5384	   "                                            %s, /* gcc_jit_location *loc */\n"
5385	   "                                            %s, /* gcc_jit_type *vec_type */\n"
5386	   "                                            %i, /* size_t num_elements  */ \n"
5387	   "                                            %s); /* gcc_jit_rvalue **elements*/\n",
5388	   id,
5389	   r.get_identifier (get_context ()),
5390	   r.get_identifier (m_loc),
5391	   r.get_identifier (m_vector_type),
5392	   m_elements.length (),
5393	   elements_id);
5394}
5395
5396void
5397recording::ctor::visit_children (rvalue_visitor *v)
5398{
5399  for (unsigned int i = 0; i < m_values.length (); i++)
5400    v->visit (m_values[i]);
5401}
5402
5403recording::string *
5404recording::ctor::make_debug_string ()
5405{
5406  //Make a compound literal-ish
5407  pretty_printer pp;
5408
5409  pp_string (&pp, "(");
5410  pp_string (&pp, m_type->get_debug_string ());
5411  pp_string (&pp, ") {");
5412
5413  size_t field_n = m_fields.length ();
5414  size_t values_n = m_values.length ();
5415
5416  if (!field_n && !values_n)
5417    ;
5418  else if (!field_n && values_n)
5419    {
5420      for (size_t i = 0; i < values_n; i++)
5421	{
5422	  if (m_values[i])
5423	    pp_string (&pp, m_values[i]->get_debug_string ());
5424	  else
5425	    pp_string (&pp, "0");
5426	  if (i + 1 != values_n)
5427	    pp_string (&pp, ", ");
5428	}
5429    }
5430  else if (field_n && values_n)
5431    {
5432      for (size_t i = 0; i < values_n; i++)
5433	{
5434	  pp_string (&pp, ".");
5435	  pp_string (&pp, m_fields[i]->get_debug_string ());
5436	  pp_string (&pp, "=");
5437	  if (m_values[i])
5438	    pp_string (&pp, m_values[i]->get_debug_string ());
5439	  else
5440	    pp_string (&pp, "0");
5441	  if (i + 1 != values_n)
5442	    pp_string (&pp, ", ");
5443	}
5444    }
5445  /* m_fields are never populated with m_values empty.  */
5446
5447  pp_string (&pp, "}");
5448
5449  return new_string (pp_formatted_text (&pp));
5450}
5451
5452void
5453recording::ctor::write_reproducer (reproducer &r)
5454{
5455  const char *id = r.make_identifier (this, "rvalue");
5456  type *type = get_type ();
5457
5458  r.write ("  gcc_jit_rvalue *%s;\n", id);
5459  r.write ("  {\n"); /* Open scope for locals.  */
5460
5461  if (type->is_union ())
5462    {
5463      if (m_values.length () == 0)
5464	r.write ("    gcc_jit_rvalue *value = NULL;\n");
5465      else
5466	r.write ("    gcc_jit_rvalue *value = %s;\n",
5467		 r.get_identifier (m_values[0]));
5468
5469      if (m_fields.length () == 0)
5470	r.write ("    gcc_jit_field *field = NULL;\n");
5471      else
5472	r.write ("    gcc_jit_field *field = %s;\n",
5473		 r.get_identifier (m_fields[0]));
5474    }
5475  else
5476    {
5477      /* Write the array of values.  */
5478      if (m_values.length () == 0)
5479	r.write ("    gcc_jit_rvalue **values = NULL;\n");
5480      else
5481	{
5482	  r.write ("    gcc_jit_rvalue *values[] = {\n");
5483	  for (size_t i = 0; i < m_values.length (); i++)
5484	    r.write ("        %s,\n", r.get_identifier (m_values[i]));
5485	  r.write ("      };\n");
5486	}
5487      /* Write the array of fields.  */
5488      if (m_fields.length () == 0)
5489	r.write ("    gcc_jit_field **fields = NULL;\n");
5490      else
5491	{
5492	  r.write ("    gcc_jit_field *fields[] = {\n");
5493	  for (size_t i = 0; i < m_fields.length (); i++)
5494	    r.write ("        %s,\n", r.get_identifier (m_fields[i]));
5495	  r.write ("      };\n");
5496	}
5497    }
5498  if (type->is_array ())
5499    r.write (
5500"    %s =\n"
5501"      gcc_jit_context_new_array_constructor (%s,\n"
5502"                                             %s, /* gcc_jit_location *loc */\n"
5503"                                             %s, /* gcc_jit_type *type */\n"
5504"                                             %i, /* int num_values */\n"
5505"                                             values);\n",
5506	   id,
5507	   r.get_identifier (get_context ()),
5508	   r.get_identifier (m_loc),
5509	   r.get_identifier_as_type (get_type ()),
5510	   m_values.length ());
5511  else if (type->is_struct ())
5512    r.write (
5513"    %s =\n"
5514"      gcc_jit_context_new_struct_constructor (%s,\n"
5515"                                              %s, /* loc */\n"
5516"                                              %s, /* gcc_jit_type *type */\n"
5517"                                              %i, /* int num_values */\n"
5518"                                              fields,\n"
5519"                                              values);\n",
5520	   id,
5521	   r.get_identifier (get_context ()),
5522	   r.get_identifier (m_loc),
5523	   r.get_identifier_as_type (get_type ()),
5524	   m_values.length ());
5525  else if (type->is_union ())
5526    r.write (
5527"    %s =\n"
5528"      gcc_jit_context_new_union_constructor (%s,\n"
5529"                                             %s, /* loc */\n"
5530"                                             %s, /* gcc_jit_type *type */\n"
5531"                                             field,\n"
5532"                                             value);\n",
5533	   id,
5534	   r.get_identifier (get_context ()),
5535	   r.get_identifier (m_loc),
5536	   r.get_identifier_as_type (get_type ()));
5537  else
5538    gcc_unreachable ();
5539
5540  r.write ("  }\n"); /* Close scope for locals.  */
5541}
5542
5543void
5544recording::ctor::replay_into (replayer *r)
5545{
5546  auto_vec<playback::rvalue *> playback_values;
5547  auto_vec<playback::field *> playback_fields;
5548
5549  int n = m_values.length ();
5550
5551  type *type = get_type ();
5552
5553  /* Handle arrays, and return.  */
5554  if (type->is_array ())
5555    {
5556      playback_values.reserve (n, false);
5557
5558      for (int i = 0; i < n; i++)
5559	{
5560	  /* null m_values element indicates zero ctor.  */
5561	  playback_values.quick_push (m_values[i] ?
5562				      m_values[i]->playback_rvalue () :
5563				      NULL);
5564	}
5565      set_playback_obj (r->new_ctor (playback_location (r, m_loc),
5566				     get_type ()->playback_type (),
5567				     NULL,
5568				     &playback_values));
5569      return;
5570    }
5571  /* ... else handle unions and structs.  */
5572
5573  playback_values.reserve (n, false);
5574  playback_fields.reserve (n, false);
5575
5576  for (int i = 0; i < n; i++)
5577    {
5578      /* null m_values element indicates zero ctor.  */
5579      playback_values.quick_push (m_values[i] ?
5580				    m_values[i]->playback_rvalue () :
5581				    NULL);
5582      playback_fields.quick_push (m_fields[i]->playback_field ());
5583    }
5584
5585  set_playback_obj (r->new_ctor (playback_location (r, m_loc),
5586				 get_type ()->playback_type (),
5587				 &playback_fields,
5588				 &playback_values));
5589}
5590
5591/* The implementation of class gcc::jit::recording::unary_op.  */
5592
5593/* Implementation of pure virtual hook recording::memento::replay_into
5594   for recording::unary_op.  */
5595
5596void
5597recording::unary_op::replay_into (replayer *r)
5598{
5599  set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
5600				     m_op,
5601				     get_type ()->playback_type (),
5602				     m_a->playback_rvalue ()));
5603}
5604
5605/* Implementation of pure virtual hook recording::rvalue::visit_children
5606   for recording::unary_op.  */
5607void
5608recording::unary_op::visit_children (rvalue_visitor *v)
5609{
5610  v->visit (m_a);
5611}
5612
5613/* Implementation of recording::memento::make_debug_string for
5614   unary ops.  */
5615
5616static const char * const unary_op_strings[] = {
5617  "-", /* GCC_JIT_UNARY_OP_MINUS */
5618  "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
5619  "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
5620  "abs ", /* GCC_JIT_UNARY_OP_ABS */
5621};
5622
5623recording::string *
5624recording::unary_op::make_debug_string ()
5625{
5626  return string::from_printf (m_ctxt,
5627			      "%s(%s)",
5628			      unary_op_strings[m_op],
5629			      m_a->get_debug_string ());
5630}
5631
5632const char * const unary_op_reproducer_strings[] = {
5633  "GCC_JIT_UNARY_OP_MINUS",
5634  "GCC_JIT_UNARY_OP_BITWISE_NEGATE",
5635  "GCC_JIT_UNARY_OP_LOGICAL_NEGATE",
5636  "GCC_JIT_UNARY_OP_ABS"
5637};
5638
5639/* Implementation of recording::memento::write_reproducer for unary ops.  */
5640
5641void
5642recording::unary_op::write_reproducer (reproducer &r)
5643{
5644  const char *id = r.make_identifier (this, "rvalue");
5645  r.write ("  gcc_jit_rvalue *%s =\n"
5646	   "    gcc_jit_context_new_unary_op (%s,\n"
5647	   "                                  %s, /* gcc_jit_location *loc */\n"
5648	   "                                  %s, /* enum gcc_jit_unary_op op */\n"
5649	   "                                  %s, /* gcc_jit_type *result_type */\n"
5650	   "                                  %s); /* gcc_jit_rvalue *a */\n",
5651	   id,
5652	   r.get_identifier (get_context ()),
5653	   r.get_identifier (m_loc),
5654	   unary_op_reproducer_strings[m_op],
5655	   r.get_identifier_as_type (get_type ()),
5656	   r.get_identifier_as_rvalue (m_a));
5657}
5658
5659/* The implementation of class gcc::jit::recording::binary_op.  */
5660
5661/* Implementation of pure virtual hook recording::memento::replay_into
5662   for recording::binary_op.  */
5663
5664void
5665recording::binary_op::replay_into (replayer *r)
5666{
5667  set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
5668				      m_op,
5669				      get_type ()->playback_type (),
5670				      m_a->playback_rvalue (),
5671				      m_b->playback_rvalue ()));
5672}
5673
5674/* Implementation of pure virtual hook recording::rvalue::visit_children
5675   for recording::binary_op.  */
5676void
5677recording::binary_op::visit_children (rvalue_visitor *v)
5678{
5679  v->visit (m_a);
5680  v->visit (m_b);
5681}
5682
5683/* Implementation of recording::memento::make_debug_string for
5684   binary ops.  */
5685
5686static const char * const binary_op_strings[] = {
5687  "+", /* GCC_JIT_BINARY_OP_PLUS */
5688  "-", /* GCC_JIT_BINARY_OP_MINUS */
5689  "*", /* GCC_JIT_BINARY_OP_MULT */
5690  "/", /* GCC_JIT_BINARY_OP_DIVIDE */
5691  "%", /* GCC_JIT_BINARY_OP_MODULO */
5692  "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
5693  "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
5694  "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
5695  "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
5696  "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
5697  "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
5698  ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
5699};
5700
5701recording::string *
5702recording::binary_op::make_debug_string ()
5703{
5704  enum precedence prec = get_precedence ();
5705  return string::from_printf (m_ctxt,
5706			      "%s %s %s",
5707			      m_a->get_debug_string_parens (prec),
5708			      binary_op_strings[m_op],
5709			      m_b->get_debug_string_parens (prec));
5710}
5711
5712const char * const binary_op_reproducer_strings[] = {
5713  "GCC_JIT_BINARY_OP_PLUS",
5714  "GCC_JIT_BINARY_OP_MINUS",
5715  "GCC_JIT_BINARY_OP_MULT",
5716  "GCC_JIT_BINARY_OP_DIVIDE",
5717  "GCC_JIT_BINARY_OP_MODULO",
5718  "GCC_JIT_BINARY_OP_BITWISE_AND",
5719  "GCC_JIT_BINARY_OP_BITWISE_XOR",
5720  "GCC_JIT_BINARY_OP_BITWISE_OR",
5721  "GCC_JIT_BINARY_OP_LOGICAL_AND",
5722  "GCC_JIT_BINARY_OP_LOGICAL_OR",
5723  "GCC_JIT_BINARY_OP_LSHIFT",
5724  "GCC_JIT_BINARY_OP_RSHIFT"
5725};
5726
5727/* Implementation of recording::memento::write_reproducer for binary ops.  */
5728
5729void
5730recording::binary_op::write_reproducer (reproducer &r)
5731{
5732  const char *id = r.make_identifier (this, "rvalue");
5733  r.write ("  gcc_jit_rvalue *%s =\n"
5734	   "    gcc_jit_context_new_binary_op (%s,\n"
5735	   "                                   %s, /* gcc_jit_location *loc */\n"
5736	   "                                   %s, /* enum gcc_jit_binary_op op */\n"
5737	   "                                   %s, /* gcc_jit_type *result_type */\n"
5738	   "                                   %s, /* gcc_jit_rvalue *a */\n"
5739	   "                                   %s); /* gcc_jit_rvalue *b */\n",
5740	   id,
5741	   r.get_identifier (get_context ()),
5742	   r.get_identifier (m_loc),
5743	   binary_op_reproducer_strings[m_op],
5744	   r.get_identifier_as_type (get_type ()),
5745	   r.get_identifier_as_rvalue (m_a),
5746	   r.get_identifier_as_rvalue (m_b));
5747}
5748
5749namespace recording {
5750static const enum precedence binary_op_precedence[] = {
5751  PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_PLUS */
5752  PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_MINUS */
5753
5754  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MULT */
5755  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_DIVIDE */
5756  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MODULO */
5757
5758  PRECEDENCE_BITWISE_AND, /* GCC_JIT_BINARY_OP_BITWISE_AND */
5759  PRECEDENCE_BITWISE_XOR, /* GCC_JIT_BINARY_OP_BITWISE_XOR */
5760  PRECEDENCE_BITWISE_IOR, /* GCC_JIT_BINARY_OP_BITWISE_OR */
5761  PRECEDENCE_LOGICAL_AND, /* GCC_JIT_BINARY_OP_LOGICAL_AND */
5762  PRECEDENCE_LOGICAL_OR, /* GCC_JIT_BINARY_OP_LOGICAL_OR */
5763  PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_LSHIFT */
5764  PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_RSHIFT */
5765};
5766} /* namespace recording */
5767
5768enum recording::precedence
5769recording::binary_op::get_precedence () const
5770{
5771  return binary_op_precedence[m_op];
5772}
5773
5774/* The implementation of class gcc::jit::recording::comparison.  */
5775
5776/* Implementation of recording::memento::make_debug_string for
5777   comparisons.  */
5778
5779static const char * const comparison_strings[] =
5780{
5781  "==", /* GCC_JIT_COMPARISON_EQ */
5782  "!=", /* GCC_JIT_COMPARISON_NE */
5783  "<",  /* GCC_JIT_COMPARISON_LT */
5784  "<=", /* GCC_JIT_COMPARISON_LE */
5785  ">",  /* GCC_JIT_COMPARISON_GT */
5786  ">=", /* GCC_JIT_COMPARISON_GE */
5787};
5788
5789recording::string *
5790recording::comparison::make_debug_string ()
5791{
5792  enum precedence prec = get_precedence ();
5793  return string::from_printf (m_ctxt,
5794			      "%s %s %s",
5795			      m_a->get_debug_string_parens (prec),
5796			      comparison_strings[m_op],
5797			      m_b->get_debug_string_parens (prec));
5798}
5799
5800/* A table of enum gcc_jit_comparison values expressed in string
5801   form.  */
5802
5803static const char * const comparison_reproducer_strings[] =
5804{
5805  "GCC_JIT_COMPARISON_EQ",
5806  "GCC_JIT_COMPARISON_NE",
5807  "GCC_JIT_COMPARISON_LT",
5808  "GCC_JIT_COMPARISON_LE",
5809  "GCC_JIT_COMPARISON_GT",
5810  "GCC_JIT_COMPARISON_GE"
5811};
5812
5813/* Implementation of recording::memento::write_reproducer for comparisons.  */
5814
5815void
5816recording::comparison::write_reproducer (reproducer &r)
5817{
5818  const char *id = r.make_identifier (this, "rvalue");
5819  r.write ("  gcc_jit_rvalue *%s =\n"
5820	   "    gcc_jit_context_new_comparison (%s,\n"
5821	   "                                    %s, /* gcc_jit_location *loc */\n"
5822	   "                                    %s, /* enum gcc_jit_comparison op */\n"
5823	   "                                    %s, /* gcc_jit_rvalue *a */\n"
5824	   "                                    %s); /* gcc_jit_rvalue *b */\n",
5825	   id,
5826	   r.get_identifier (get_context ()),
5827	   r.get_identifier (m_loc),
5828	   comparison_reproducer_strings[m_op],
5829	   r.get_identifier_as_rvalue (m_a),
5830	   r.get_identifier_as_rvalue (m_b));
5831}
5832
5833/* Implementation of pure virtual hook recording::memento::replay_into
5834   for recording::comparison.  */
5835
5836void
5837recording::comparison::replay_into (replayer *r)
5838{
5839  set_playback_obj (r->new_comparison (playback_location (r, m_loc),
5840				       m_op,
5841				       m_a->playback_rvalue (),
5842				       m_b->playback_rvalue ()));
5843}
5844
5845/* Implementation of pure virtual hook recording::rvalue::visit_children
5846   for recording::comparison.  */
5847
5848void
5849recording::comparison::visit_children (rvalue_visitor *v)
5850{
5851  v->visit (m_a);
5852  v->visit (m_b);
5853}
5854
5855namespace recording {
5856static const enum precedence comparison_precedence[] =
5857{
5858  PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_EQ */
5859  PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_NE */
5860
5861  PRECEDENCE_RELATIONAL,  /* GCC_JIT_COMPARISON_LT */
5862  PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_LE */
5863  PRECEDENCE_RELATIONAL,  /* GCC_JIT_COMPARISON_GT */
5864  PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_GE */
5865};
5866} /* namespace recording */
5867
5868enum recording::precedence
5869recording::comparison::get_precedence () const
5870{
5871  return comparison_precedence[m_op];
5872}
5873
5874/* Implementation of pure virtual hook recording::memento::replay_into
5875   for recording::cast.  */
5876
5877void
5878recording::cast::replay_into (replayer *r)
5879{
5880  set_playback_obj (r->new_cast (playback_location (r, m_loc),
5881				 m_rvalue->playback_rvalue (),
5882				 get_type ()->playback_type ()));
5883}
5884
5885/* Implementation of pure virtual hook recording::rvalue::visit_children
5886   for recording::cast.  */
5887void
5888recording::cast::visit_children (rvalue_visitor *v)
5889{
5890  v->visit (m_rvalue);
5891}
5892
5893/* Implementation of recording::memento::make_debug_string for
5894   casts.  */
5895
5896recording::string *
5897recording::cast::make_debug_string ()
5898{
5899  enum precedence prec = get_precedence ();
5900  return string::from_printf (m_ctxt,
5901			      "(%s)%s",
5902			      get_type ()->get_debug_string (),
5903			      m_rvalue->get_debug_string_parens (prec));
5904}
5905
5906/* Implementation of recording::memento::write_reproducer for casts.  */
5907
5908void
5909recording::cast::write_reproducer (reproducer &r)
5910{
5911  const char *id = r.make_identifier (this, "rvalue");
5912  r.write ("  gcc_jit_rvalue *%s =\n"
5913	   "    gcc_jit_context_new_cast (%s,\n"
5914	   "                              %s, /* gcc_jit_location *loc */\n"
5915	   "                              %s, /* gcc_jit_rvalue *rvalue */\n"
5916	   "                              %s); /* gcc_jit_type *type */\n",
5917	   id,
5918	   r.get_identifier (get_context ()),
5919	   r.get_identifier (m_loc),
5920	   r.get_identifier_as_rvalue (m_rvalue),
5921	   r.get_identifier_as_type (get_type ()));
5922}
5923
5924/* Implementation of pure virtual hook recording::memento::replay_into
5925   for recording::bitcast.  */
5926
5927void
5928recording::bitcast::replay_into (replayer *r)
5929{
5930  set_playback_obj (r->new_bitcast (playback_location (r, m_loc),
5931				    m_rvalue->playback_rvalue (),
5932				    get_type ()->playback_type ()));
5933}
5934
5935/* Implementation of pure virtual hook recording::rvalue::visit_children
5936   for recording::bitcast.  */
5937void
5938recording::bitcast::visit_children (rvalue_visitor *v)
5939{
5940  v->visit (m_rvalue);
5941}
5942
5943/* Implementation of recording::memento::make_debug_string for
5944   casts.  */
5945
5946recording::string *
5947recording::bitcast::make_debug_string ()
5948{
5949  enum precedence prec = get_precedence ();
5950  return string::from_printf (m_ctxt,
5951			      "bitcast(%s, %s)",
5952			      m_rvalue->get_debug_string_parens (prec),
5953			      get_type ()->get_debug_string ());
5954}
5955
5956/* Implementation of recording::memento::write_reproducer for casts.  */
5957
5958void
5959recording::bitcast::write_reproducer (reproducer &r)
5960{
5961  const char *id = r.make_identifier (this, "rvalue");
5962  r.write ("  gcc_jit_rvalue *%s =\n"
5963	   "    gcc_jit_context_new_bitcast (%s,\n"
5964	   "                                 %s, /* gcc_jit_location *loc */\n"
5965	   "                                 %s, /* gcc_jit_rvalue *rvalue */\n"
5966	   "                                 %s); /* gcc_jit_type *type */\n",
5967	   id,
5968	   r.get_identifier (get_context ()),
5969	   r.get_identifier (m_loc),
5970	   r.get_identifier_as_rvalue (m_rvalue),
5971	   r.get_identifier_as_type (get_type ()));
5972}
5973
5974/* The implementation of class gcc::jit::recording::base_call.  */
5975
5976/* The constructor for gcc::jit::recording::base_call.  */
5977
5978recording::base_call::base_call (context *ctxt,
5979				 location *loc,
5980				 type *type_,
5981				 int numargs,
5982				 rvalue **args)
5983: rvalue (ctxt, loc, type_),
5984  m_args (),
5985  m_require_tail_call (0)
5986{
5987  for (int i = 0; i< numargs; i++)
5988    m_args.safe_push (args[i]);
5989}
5990
5991/* Subroutine for use by call and call_though_ptr's write_reproducer
5992   methods.  */
5993
5994void
5995recording::base_call::write_reproducer_tail_call (reproducer &r,
5996						  const char *id)
5997{
5998  if (m_require_tail_call)
5999    {
6000      r.write ("  gcc_jit_rvalue_set_bool_require_tail_call (%s,  /* gcc_jit_rvalue *call*/\n"
6001	       "                                             %i); /* int require_tail_call*/\n",
6002	       id,
6003	       1);
6004    }
6005}
6006
6007/* The implementation of class gcc::jit::recording::call.  */
6008
6009/* The constructor for gcc::jit::recording::call.  */
6010
6011recording::call::call (recording::context *ctxt,
6012		       recording::location *loc,
6013		       recording::function *func,
6014		       int numargs,
6015		       rvalue **args)
6016: base_call (ctxt, loc, func->get_return_type (), numargs, args),
6017  m_func (func)
6018{
6019}
6020
6021/* Implementation of pure virtual hook recording::memento::replay_into
6022   for recording::call.  */
6023
6024void
6025recording::call::replay_into (replayer *r)
6026{
6027  auto_vec<playback::rvalue *> playback_args;
6028  playback_args.create (m_args.length ());
6029  for (unsigned i = 0; i< m_args.length (); i++)
6030    playback_args.safe_push (m_args[i]->playback_rvalue ());
6031
6032  set_playback_obj (r->new_call (playback_location (r, m_loc),
6033				 m_func->playback_function (),
6034				 &playback_args,
6035				 m_require_tail_call));
6036}
6037
6038/* Implementation of pure virtual hook recording::rvalue::visit_children
6039   for recording::call.  */
6040
6041void
6042recording::call::visit_children (rvalue_visitor *v)
6043{
6044  for (unsigned i = 0; i< m_args.length (); i++)
6045    v->visit (m_args[i]);
6046}
6047
6048/* Implementation of recording::memento::make_debug_string for
6049   function calls.  */
6050
6051recording::string *
6052recording::call::make_debug_string ()
6053{
6054  /* First, build a buffer for the arguments.  */
6055  comma_separated_string args (m_args, get_precedence ());
6056
6057  /* ...and use it to get the string for the call as a whole.  */
6058  string *result = string::from_printf (m_ctxt,
6059					"%s (%s)",
6060					m_func->get_debug_string (),
6061					args.as_char_ptr ());
6062
6063  return result;
6064}
6065
6066void
6067recording::call::write_reproducer (reproducer &r)
6068{
6069  const char *id = r.make_identifier (this, "call");
6070  const char *args_id = r.make_tmp_identifier ("args_for_", this);
6071  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
6072	   args_id,
6073	   m_args.length ());
6074  for (unsigned i = 0; i< m_args.length (); i++)
6075    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_args[i]));
6076  r.write ("  };\n");
6077  r.write ("  gcc_jit_rvalue *%s =\n"
6078	   "    gcc_jit_context_new_call (%s, /* gcc_jit_context *ctxt */\n"
6079	   "                              %s, /* gcc_jit_location *loc */\n"
6080	   "                              %s, /* gcc_jit_function *func */\n"
6081	   "                              %i, /* int numargs  */ \n"
6082	   "                              %s); /* gcc_jit_rvalue **args*/\n",
6083	   id,
6084	   r.get_identifier (get_context ()),
6085	   r.get_identifier (m_loc),
6086	   r.get_identifier (m_func),
6087	   m_args.length (),
6088	   args_id);
6089  write_reproducer_tail_call (r, id);
6090}
6091
6092/* The implementation of class gcc::jit::recording::call_through_ptr.  */
6093
6094/* The constructor for recording::call_through_ptr. */
6095
6096recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
6097					       recording::location *loc,
6098					       recording::rvalue *fn_ptr,
6099					       int numargs,
6100					       rvalue **args)
6101: base_call (ctxt, loc,
6102	     fn_ptr->get_type ()->dereference ()
6103	       ->as_a_function_type ()->get_return_type (),
6104	     numargs, args),
6105  m_fn_ptr (fn_ptr)
6106{
6107}
6108
6109/* Implementation of pure virtual hook recording::memento::replay_into
6110   for recording::call_through_ptr.  */
6111
6112void
6113recording::call_through_ptr::replay_into (replayer *r)
6114{
6115  auto_vec<playback::rvalue *> playback_args;
6116  playback_args.create (m_args.length ());
6117  for (unsigned i = 0; i< m_args.length (); i++)
6118    playback_args.safe_push (m_args[i]->playback_rvalue ());
6119
6120  set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
6121					     m_fn_ptr->playback_rvalue (),
6122					     &playback_args,
6123					     m_require_tail_call));
6124}
6125
6126/* Implementation of pure virtual hook recording::rvalue::visit_children
6127   for recording::call_through_ptr.  */
6128
6129void
6130recording::call_through_ptr::visit_children (rvalue_visitor *v)
6131{
6132  v->visit (m_fn_ptr);
6133  for (unsigned i = 0; i< m_args.length (); i++)
6134    v->visit (m_args[i]);
6135}
6136
6137/* Implementation of recording::memento::make_debug_string for
6138   calls through function ptrs.  */
6139
6140recording::string *
6141recording::call_through_ptr::make_debug_string ()
6142{
6143  enum precedence prec = get_precedence ();
6144  /* First, build a buffer for the arguments.  */
6145  /* Calculate length of said buffer.  */
6146  size_t sz = 1; /* nil terminator */
6147  for (unsigned i = 0; i< m_args.length (); i++)
6148    {
6149      sz += strlen (m_args[i]->get_debug_string_parens (prec));
6150      sz += 2; /* ", " separator */
6151    }
6152
6153  /* Now allocate and populate the buffer.  */
6154  char *argbuf = new char[sz];
6155  size_t len = 0;
6156
6157  for (unsigned i = 0; i< m_args.length (); i++)
6158    {
6159      strcpy (argbuf + len, m_args[i]->get_debug_string_parens (prec));
6160      len += strlen (m_args[i]->get_debug_string_parens (prec));
6161      if (i + 1 < m_args.length ())
6162	{
6163	  strcpy (argbuf + len, ", ");
6164	  len += 2;
6165	}
6166    }
6167  argbuf[len] = '\0';
6168
6169  /* ...and use it to get the string for the call as a whole.  */
6170  string *result = string::from_printf (m_ctxt,
6171					"%s (%s)",
6172					m_fn_ptr->get_debug_string_parens (prec),
6173					argbuf);
6174
6175  delete[] argbuf;
6176
6177  return result;
6178}
6179
6180/* Implementation of recording::memento::write_reproducer for
6181   call_through_ptr.  */
6182
6183void
6184recording::call_through_ptr::write_reproducer (reproducer &r)
6185{
6186  const char *id = r.make_identifier (this, "call");
6187  const char *args_id = r.make_tmp_identifier ("args_for_", this);
6188  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
6189	     args_id,
6190	     m_args.length ());
6191  for (unsigned i = 0; i< m_args.length (); i++)
6192    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_args[i]));
6193  r.write ("  };\n");
6194  r.write ("  gcc_jit_rvalue *%s =\n"
6195	   "    gcc_jit_context_new_call_through_ptr (%s, /* gcc_jit_context *ctxt */\n"
6196	   "                              %s, /* gcc_jit_location *loc */\n"
6197	   "                              %s, /* gcc_jit_rvalue *fn_ptr */\n"
6198	   "                              %i, /* int numargs  */ \n"
6199	   "                              %s); /* gcc_jit_rvalue **args*/\n",
6200	   id,
6201	   r.get_identifier (get_context ()),
6202	   r.get_identifier (m_loc),
6203	   r.get_identifier_as_rvalue (m_fn_ptr),
6204	   m_args.length (),
6205	   args_id);
6206  write_reproducer_tail_call (r, id);
6207}
6208
6209/* The implementation of class gcc::jit::recording::array_access.  */
6210
6211/* Implementation of pure virtual hook recording::memento::replay_into
6212   for recording::array_access.  */
6213
6214void
6215recording::array_access::replay_into (replayer *r)
6216{
6217  set_playback_obj (
6218    r->new_array_access (playback_location (r, m_loc),
6219			 m_ptr->playback_rvalue (),
6220			 m_index->playback_rvalue ()));
6221}
6222
6223/* Implementation of pure virtual hook recording::rvalue::visit_children
6224   for recording::array_access.  */
6225
6226void
6227recording::array_access::visit_children (rvalue_visitor *v)
6228{
6229  v->visit (m_ptr);
6230  v->visit (m_index);
6231}
6232
6233/* Implementation of recording::memento::make_debug_string for
6234   array accesses.  */
6235
6236recording::string *
6237recording::array_access::make_debug_string ()
6238{
6239  enum precedence prec = get_precedence ();
6240  return string::from_printf (m_ctxt,
6241			      "%s[%s]",
6242			      m_ptr->get_debug_string_parens (prec),
6243			      m_index->get_debug_string_parens (prec));
6244}
6245
6246/* Implementation of recording::memento::write_reproducer for
6247   array_access.  */
6248
6249void
6250recording::array_access::write_reproducer (reproducer &r)
6251{
6252  const char *id = r.make_identifier (this, "lvalue");
6253  r.write ("  gcc_jit_lvalue *%s = \n"
6254	   "    gcc_jit_context_new_array_access (%s, /* gcc_jit_context *ctxt */\n"
6255	   "                                      %s, /*gcc_jit_location *loc */\n"
6256	   "                                      %s, /* gcc_jit_rvalue *ptr */\n"
6257	   "                                      %s); /* gcc_jit_rvalue *index */\n",
6258	   id,
6259	   r.get_identifier (get_context ()),
6260	   r.get_identifier (m_loc),
6261	   r.get_identifier_as_rvalue (m_ptr),
6262	   r.get_identifier_as_rvalue (m_index));
6263}
6264
6265/* The implementation of class gcc::jit::recording::access_field_of_lvalue.  */
6266
6267/* Implementation of pure virtual hook recording::memento::replay_into
6268   for recording::access_field_of_lvalue.  */
6269
6270void
6271recording::access_field_of_lvalue::replay_into (replayer *r)
6272{
6273  set_playback_obj (
6274    m_lvalue->playback_lvalue ()
6275      ->access_field (playback_location (r, m_loc),
6276		      m_field->playback_field ()));
6277
6278}
6279
6280/* Implementation of pure virtual hook recording::rvalue::visit_children
6281   for recording::access_field_of_lvalue.  */
6282
6283void
6284recording::access_field_of_lvalue::visit_children (rvalue_visitor *v)
6285{
6286  v->visit (m_lvalue);
6287}
6288
6289/* Implementation of recording::memento::make_debug_string for
6290   accessing a field of an lvalue.  */
6291
6292recording::string *
6293recording::access_field_of_lvalue::make_debug_string ()
6294{
6295  enum precedence prec = get_precedence ();
6296  return string::from_printf (m_ctxt,
6297			      "%s.%s",
6298			      m_lvalue->get_debug_string_parens (prec),
6299			      m_field->get_debug_string ());
6300}
6301
6302/* Implementation of recording::memento::write_reproducer for
6303   access_field_of_lvalue.  */
6304
6305void
6306recording::access_field_of_lvalue::write_reproducer (reproducer &r)
6307{
6308  const char *id = r.make_identifier (this, "lvalue");
6309  r.write ("  gcc_jit_lvalue *%s = \n"
6310	   "    gcc_jit_lvalue_access_field (%s, /*gcc_jit_lvalue *struct_or_union */\n"
6311	   "                                 %s, /*gcc_jit_location *loc */\n"
6312	   "                                 %s);\n",
6313	   id,
6314	   r.get_identifier_as_lvalue (m_lvalue),
6315	   r.get_identifier (m_loc),
6316	   r.get_identifier (m_field));
6317}
6318
6319/* The implementation of class gcc::jit::recording::access_field_rvalue.  */
6320
6321/* Implementation of pure virtual hook recording::memento::replay_into
6322   for recording::access_field_rvalue.  */
6323
6324void
6325recording::access_field_rvalue::replay_into (replayer *r)
6326{
6327  set_playback_obj (
6328    m_rvalue->playback_rvalue ()
6329      ->access_field (playback_location (r, m_loc),
6330		      m_field->playback_field ()));
6331}
6332
6333/* Implementation of pure virtual hook recording::rvalue::visit_children
6334   for recording::access_field_rvalue.  */
6335
6336void
6337recording::access_field_rvalue::visit_children (rvalue_visitor *v)
6338{
6339  v->visit (m_rvalue);
6340}
6341
6342/* Implementation of recording::memento::make_debug_string for
6343   accessing a field of an rvalue.  */
6344
6345recording::string *
6346recording::access_field_rvalue::make_debug_string ()
6347{
6348  enum precedence prec = get_precedence ();
6349  return string::from_printf (m_ctxt,
6350			      "%s.%s",
6351			      m_rvalue->get_debug_string_parens (prec),
6352			      m_field->get_debug_string ());
6353}
6354
6355/* Implementation of recording::memento::write_reproducer for
6356   access_field_rvalue.  */
6357
6358void
6359recording::access_field_rvalue::write_reproducer (reproducer &r)
6360{
6361  const char *id = r.make_identifier (this, "rvalue");
6362  r.write ("  gcc_jit_rvalue *%s = \n"
6363	   "    gcc_jit_rvalue_access_field (%s, /*gcc_jit_rvalue *struct_or_union */\n"
6364	   "                                 %s, /*gcc_jit_location *loc */\n"
6365	   "                                 %s);\n",
6366	   id,
6367	   r.get_identifier_as_rvalue (m_rvalue),
6368	   r.get_identifier (m_loc),
6369	   r.get_identifier (m_field));
6370}
6371
6372/* The implementation of class
6373   gcc::jit::recording::dereference_field_rvalue.  */
6374
6375/* Implementation of pure virtual hook recording::memento::replay_into
6376   for recording::dereference_field_rvalue.  */
6377
6378void
6379recording::dereference_field_rvalue::replay_into (replayer *r)
6380{
6381  set_playback_obj (
6382    m_rvalue->playback_rvalue ()->
6383      dereference_field (playback_location (r, m_loc),
6384			 m_field->playback_field ()));
6385}
6386
6387/* Implementation of pure virtual hook recording::rvalue::visit_children
6388   for recording::dereference_field_rvalue.  */
6389
6390void
6391recording::dereference_field_rvalue::visit_children (rvalue_visitor *v)
6392{
6393  v->visit (m_rvalue);
6394}
6395
6396/* Implementation of recording::memento::make_debug_string for
6397   dereferencing a field of an rvalue.  */
6398
6399recording::string *
6400recording::dereference_field_rvalue::make_debug_string ()
6401{
6402  enum precedence prec = get_precedence ();
6403  return string::from_printf (m_ctxt,
6404			      "%s->%s",
6405			      m_rvalue->get_debug_string_parens (prec),
6406			      m_field->get_debug_string ());
6407}
6408
6409/* Implementation of recording::memento::write_reproducer for
6410   dereference_field_rvalue.  */
6411
6412void
6413recording::dereference_field_rvalue::write_reproducer (reproducer &r)
6414{
6415  const char *id = r.make_identifier (this, "lvalue");
6416  r.write ("  gcc_jit_lvalue *%s=\n"
6417	   "    gcc_jit_rvalue_dereference_field (%s, /* gcc_jit_rvalue *ptr */\n"
6418	   "                                      %s, /* gcc_jit_location *loc */\n"
6419	   "                                      %s); /* gcc_jit_field *field */\n",
6420	   id,
6421	   r.get_identifier_as_rvalue (m_rvalue),
6422	   r.get_identifier (m_loc),
6423	   r.get_identifier (m_field));
6424}
6425
6426/* The implementation of class gcc::jit::recording::dereference_rvalue.  */
6427
6428/* Implementation of pure virtual hook recording::memento::replay_into
6429   for recording::dereference_rvalue.  */
6430
6431void
6432recording::dereference_rvalue::replay_into (replayer *r)
6433{
6434  set_playback_obj (
6435    m_rvalue->playback_rvalue ()->
6436      dereference (playback_location (r, m_loc)));
6437}
6438
6439/* Implementation of pure virtual hook recording::rvalue::visit_children
6440   for recording::dereference_rvalue.  */
6441
6442void
6443recording::dereference_rvalue::visit_children (rvalue_visitor *v)
6444{
6445  v->visit (m_rvalue);
6446}
6447
6448/* Implementation of recording::memento::make_debug_string for
6449   dereferencing an rvalue.  */
6450
6451recording::string *
6452recording::dereference_rvalue::make_debug_string ()
6453{
6454  enum precedence prec = get_precedence ();
6455  return string::from_printf (m_ctxt,
6456			      "*%s",
6457			      m_rvalue->get_debug_string_parens (prec));
6458}
6459
6460/* Implementation of recording::memento::write_reproducer for
6461   dereference_rvalue.  */
6462
6463void
6464recording::dereference_rvalue::write_reproducer (reproducer &r)
6465{
6466  const char *id = r.make_identifier (this, "dereference");
6467  r.write ("  gcc_jit_lvalue *%s =\n"
6468	   "    gcc_jit_rvalue_dereference (%s, /* gcc_jit_rvalue *rvalue */\n"
6469	   "                                %s); /* gcc_jit_location *loc */\n",
6470	   id,
6471	   r.get_identifier_as_rvalue (m_rvalue),
6472	   r.get_identifier (m_loc));
6473}
6474
6475/* The implementation of class gcc::jit::recording::get_address_of_lvalue.  */
6476
6477/* Implementation of pure virtual hook recording::memento::replay_into
6478   for recording::get_address_of_lvalue.  */
6479
6480void
6481recording::get_address_of_lvalue::replay_into (replayer *r)
6482{
6483  set_playback_obj (
6484    m_lvalue->playback_lvalue ()->
6485      get_address (playback_location (r, m_loc)));
6486}
6487
6488/* Implementation of pure virtual hook recording::rvalue::visit_children
6489   for recording::get_address_of_lvalue.  */
6490
6491void
6492recording::get_address_of_lvalue::visit_children (rvalue_visitor *v)
6493{
6494  v->visit (m_lvalue);
6495}
6496
6497/* Implementation of recording::memento::make_debug_string for
6498   getting the address of an lvalue.  */
6499
6500recording::string *
6501recording::get_address_of_lvalue::make_debug_string ()
6502{
6503  enum precedence prec = get_precedence ();
6504  return string::from_printf (m_ctxt,
6505			      "&%s",
6506			      m_lvalue->get_debug_string_parens (prec));
6507}
6508
6509/* Implementation of recording::memento::write_reproducer for
6510   get_address_of_lvalue.  */
6511
6512void
6513recording::get_address_of_lvalue::write_reproducer (reproducer &r)
6514{
6515  const char *id = r.make_identifier (this, "address_of");
6516  r.write ("  gcc_jit_rvalue *%s =\n"
6517	   "    gcc_jit_lvalue_get_address (%s, /* gcc_jit_lvalue *lvalue */\n"
6518	   "                                %s); /* gcc_jit_location *loc */\n",
6519	   id,
6520	   r.get_identifier_as_lvalue (m_lvalue),
6521	   r.get_identifier (m_loc));
6522}
6523
6524/* The implementation of class gcc::jit::recording::function_pointer.  */
6525
6526/* Implementation of pure virtual hook recording::memento::replay_into
6527   for recording::function_pointer.  */
6528
6529void
6530recording::function_pointer::replay_into (replayer *r)
6531{
6532  set_playback_obj (
6533    m_fn->playback_function ()->
6534      get_address (playback_location (r, m_loc)));
6535}
6536
6537void
6538recording::function_pointer::visit_children (rvalue_visitor *)
6539{
6540  /* Empty.  */
6541}
6542
6543/* Implementation of recording::memento::make_debug_string for
6544   getting the address of an lvalue.  */
6545
6546recording::string *
6547recording::function_pointer::make_debug_string ()
6548{
6549  return string::from_printf (m_ctxt,
6550			      "%s",
6551			      m_fn->get_debug_string ());
6552}
6553
6554/* Implementation of recording::memento::write_reproducer for
6555   function_pointer.  */
6556
6557void
6558recording::function_pointer::write_reproducer (reproducer &r)
6559{
6560  const char *id = r.make_identifier (this, "address_of");
6561  r.write ("  gcc_jit_rvalue *%s =\n"
6562	   "    gcc_jit_function_get_address (%s, /* gcc_jit_function *fn */\n"
6563	   "                                  %s); /* gcc_jit_location *loc */\n",
6564	   id,
6565	   r.get_identifier (m_fn),
6566	   r.get_identifier (m_loc));
6567}
6568
6569/* The implementation of class gcc::jit::recording::local.  */
6570
6571/* Implementation of pure virtual hook recording::memento::replay_into
6572   for recording::local.  */
6573
6574void
6575recording::local::replay_into (replayer *r)
6576{
6577  playback::lvalue *obj = m_func->playback_function ()
6578      ->new_local (playback_location (r, m_loc),
6579		   m_type->playback_type (),
6580		   playback_string (m_name));
6581
6582  if (m_reg_name != NULL)
6583    obj->set_register_name (m_reg_name->c_str ());
6584
6585  if (m_alignment != 0)
6586    obj->set_alignment (m_alignment);
6587
6588  set_playback_obj (obj);
6589}
6590
6591/* Override the default implementation of
6592   recording::memento::write_to_dump for locals by writing
6593      TYPE NAME;
6594   for use at the top of the function body as if it were a
6595   declaration.  */
6596
6597void
6598recording::local::write_to_dump (dump &d)
6599{
6600  if (d.update_locations ())
6601    m_loc = d.make_location ();
6602  d.write("  %s %s;\n",
6603	  m_type->get_debug_string (),
6604	  get_debug_string ());
6605}
6606
6607void
6608recording::local::write_reproducer (reproducer &r)
6609{
6610  const char *id = r.make_identifier (this, "local");
6611  r.write ("  gcc_jit_lvalue *%s =\n"
6612	   "    gcc_jit_function_new_local (%s, /* gcc_jit_function *func */\n"
6613	   "                                %s, /* gcc_jit_location *loc */\n"
6614	   "                                %s, /* gcc_jit_type *type */\n"
6615	   "                                %s); /* const char *name */\n",
6616	   id,
6617	   r.get_identifier (m_func),
6618	   r.get_identifier (m_loc),
6619	   r.get_identifier_as_type (m_type),
6620	   m_name->get_debug_string ());
6621}
6622
6623/* The implementation of class gcc::jit::recording::statement.  */
6624
6625/* We poison the default implementation of
6626   gcc::jit::recording::statement::get_successor_blocks
6627   since this vfunc must only ever be called on terminator
6628   statements.  */
6629
6630vec <recording::block *>
6631recording::statement::get_successor_blocks () const
6632{
6633  /* The base class implementation is for non-terminating statements,
6634     and thus should never be called.  */
6635  gcc_unreachable ();
6636  vec <block *> result;
6637  result.create (0);
6638  return result;
6639}
6640
6641/* Extend the default implementation of
6642   recording::memento::write_to_dump for statements by (if requested)
6643   updating the location of the statement to the current location in
6644   the dumpfile.  */
6645
6646void
6647recording::statement::write_to_dump (dump &d)
6648{
6649  memento::write_to_dump (d);
6650  if (d.update_locations ())
6651    m_loc = d.make_location ();
6652}
6653
6654/* The implementation of class gcc::jit::recording::eval.  */
6655
6656/* Implementation of pure virtual hook recording::memento::replay_into
6657   for recording::eval.  */
6658
6659void
6660recording::eval::replay_into (replayer *r)
6661{
6662  playback_block (get_block ())
6663    ->add_eval (playback_location (r),
6664		m_rvalue->playback_rvalue ());
6665}
6666
6667/* Implementation of recording::memento::make_debug_string for
6668   an eval statement.  */
6669
6670recording::string *
6671recording::eval::make_debug_string ()
6672{
6673  return string::from_printf (m_ctxt,
6674			      "(void)%s;",
6675			      m_rvalue->get_debug_string ());
6676}
6677
6678/* Implementation of recording::memento::write_reproducer for
6679   eval statements.  */
6680
6681void
6682recording::eval::write_reproducer (reproducer &r)
6683{
6684  r.write ("  gcc_jit_block_add_eval (%s, /*gcc_jit_block *block */\n"
6685	   "                          %s, /* gcc_jit_location *loc */\n"
6686	   "                          %s); /* gcc_jit_rvalue *rvalue */\n",
6687	   r.get_identifier (get_block ()),
6688	   r.get_identifier (get_loc ()),
6689	   r.get_identifier_as_rvalue (m_rvalue));
6690}
6691
6692/* The implementation of class gcc::jit::recording::assignment.  */
6693
6694/* Implementation of pure virtual hook recording::memento::replay_into
6695   for recording::assignment.  */
6696
6697void
6698recording::assignment::replay_into (replayer *r)
6699{
6700  playback_block (get_block ())
6701    ->add_assignment (playback_location (r),
6702		      m_lvalue->playback_lvalue (),
6703		      m_rvalue->playback_rvalue ());
6704}
6705
6706/* Implementation of recording::memento::make_debug_string for
6707   an assignment statement.  */
6708
6709recording::string *
6710recording::assignment::make_debug_string ()
6711{
6712  return string::from_printf (m_ctxt,
6713			      "%s = %s;",
6714			      m_lvalue->get_debug_string (),
6715			      m_rvalue->get_debug_string ());
6716}
6717
6718/* Implementation of recording::memento::write_reproducer for
6719   assignment statements.  */
6720
6721void
6722recording::assignment::write_reproducer (reproducer &r)
6723{
6724  r.write ("  gcc_jit_block_add_assignment (%s, /*gcc_jit_block *block */\n"
6725	   "                                %s, /* gcc_jit_location *loc */\n"
6726	   "                                %s, /* gcc_jit_lvalue *lvalue */\n"
6727	   "                                %s); /* gcc_jit_rvalue *rvalue */\n",
6728	   r.get_identifier (get_block ()),
6729	   r.get_identifier (get_loc ()),
6730	   r.get_identifier_as_lvalue (m_lvalue),
6731	   r.get_identifier_as_rvalue (m_rvalue));
6732}
6733
6734/* The implementation of class gcc::jit::recording::assignment_op.  */
6735
6736/* Implementation of pure virtual hook recording::memento::replay_into
6737   for recording::assignment_op.  */
6738
6739void
6740recording::assignment_op::replay_into (replayer *r)
6741{
6742  playback::type *result_type =
6743    m_lvalue->playback_lvalue ()->get_type ();
6744
6745  playback::rvalue *binary_op =
6746    r->new_binary_op (playback_location (r),
6747		      m_op,
6748		      result_type,
6749		      m_lvalue->playback_rvalue (),
6750		      m_rvalue->playback_rvalue ());
6751
6752  playback_block (get_block ())
6753    ->add_assignment (playback_location (r),
6754		      m_lvalue->playback_lvalue (),
6755		      binary_op);
6756}
6757
6758/* Implementation of recording::memento::make_debug_string for
6759   an assignment_op statement.  */
6760
6761recording::string *
6762recording::assignment_op::make_debug_string ()
6763{
6764  return string::from_printf (m_ctxt,
6765			      "%s %s= %s;",
6766			      m_lvalue->get_debug_string (),
6767			      binary_op_strings[m_op],
6768			      m_rvalue->get_debug_string ());
6769}
6770
6771/* Implementation of recording::memento::write_reproducer for
6772   assignment_op statements.  */
6773
6774void
6775recording::assignment_op::write_reproducer (reproducer &r)
6776{
6777  r.write ("  gcc_jit_block_add_assignment_op (%s, /*gcc_jit_block *block */\n"
6778	   "                                   %s, /* gcc_jit_location *loc */\n"
6779	   "                                   %s, /* gcc_jit_lvalue *lvalue */\n"
6780	   "                                   %s, /* enum gcc_jit_binary_op op */\n"
6781	   "                                   %s); /* gcc_jit_rvalue *rvalue */\n",
6782	   r.get_identifier (get_block ()),
6783	   r.get_identifier (get_loc ()),
6784	   r.get_identifier_as_lvalue (m_lvalue),
6785	   binary_op_reproducer_strings[m_op],
6786	   r.get_identifier_as_rvalue (m_rvalue));
6787}
6788
6789/* The implementation of class gcc::jit::recording::comment.  */
6790
6791/* Implementation of pure virtual hook recording::memento::replay_into
6792   for recording::comment.  */
6793
6794void
6795recording::comment::replay_into (replayer *r)
6796{
6797  playback_block (get_block ())
6798    ->add_comment (playback_location (r),
6799		   m_text->c_str ());
6800}
6801
6802/* Implementation of recording::memento::make_debug_string for
6803   a comment "statement".  */
6804
6805recording::string *
6806recording::comment::make_debug_string ()
6807{
6808  return string::from_printf (m_ctxt,
6809			      "/* %s */",
6810			      m_text->c_str ());
6811}
6812
6813/* Implementation of recording::memento::write_reproducer for
6814   comments.  */
6815
6816void
6817recording::comment::write_reproducer (reproducer &r)
6818{
6819  r.write ("  gcc_jit_block_add_comment (%s, /*gcc_jit_block *block */\n"
6820	   "                             %s, /* gcc_jit_location *loc */\n"
6821	   "                             %s); /* const char *text */\n",
6822	   r.get_identifier (get_block ()),
6823	   r.get_identifier (get_loc ()),
6824	   m_text->get_debug_string ());
6825}
6826
6827/* The implementation of class gcc::jit::recording::conditional.  */
6828
6829/* Implementation of pure virtual hook recording::memento::replay_into
6830   for recording::conditional.  */
6831
6832void
6833recording::conditional::replay_into (replayer *r)
6834{
6835  playback_block (get_block ())
6836    ->add_conditional (playback_location (r),
6837		       m_boolval->playback_rvalue (),
6838		       playback_block (m_on_true),
6839		       playback_block (m_on_false));
6840}
6841
6842/* Override the poisoned default implementation of
6843   gcc::jit::recording::statement::get_successor_blocks
6844
6845   A conditional jump has 2 successor blocks.  */
6846
6847vec <recording::block *>
6848recording::conditional::get_successor_blocks () const
6849{
6850  vec <block *> result;
6851  result.create (2);
6852  result.quick_push (m_on_true);
6853  result.quick_push (m_on_false);
6854  return result;
6855}
6856
6857/* Implementation of recording::memento::make_debug_string for
6858   a conditional jump statement.  */
6859
6860recording::string *
6861recording::conditional::make_debug_string ()
6862{
6863  if (m_on_false)
6864    return string::from_printf (m_ctxt,
6865				"if (%s) goto %s; else goto %s;",
6866				m_boolval->get_debug_string (),
6867				m_on_true->get_debug_string (),
6868				m_on_false->get_debug_string ());
6869  else
6870    return string::from_printf (m_ctxt,
6871				"if (%s) goto %s;",
6872				m_boolval->get_debug_string (),
6873				m_on_true->get_debug_string ());
6874}
6875
6876/* Implementation of recording::memento::write_reproducer for
6877   conditional statements.  */
6878
6879void
6880recording::conditional::write_reproducer (reproducer &r)
6881{
6882  r.write ("  gcc_jit_block_end_with_conditional (%s, /*gcc_jit_block *block */\n"
6883	   "                                      %s, /* gcc_jit_location *loc */\n"
6884	   "                                      %s, /* gcc_jit_rvalue *boolval */\n"
6885	   "                                      %s, /* gcc_jit_block *on_true */\n"
6886	   "                                      %s); /* gcc_jit_block *on_false */\n",
6887	   r.get_identifier (get_block ()),
6888	   r.get_identifier (get_loc ()),
6889	   r.get_identifier_as_rvalue (m_boolval),
6890	   r.get_identifier (m_on_true),
6891	   r.get_identifier (m_on_false));
6892}
6893
6894/* The implementation of class gcc::jit::recording::jump.  */
6895
6896/* Implementation of pure virtual hook recording::memento::replay_into
6897   for recording::jump.  */
6898
6899void
6900recording::jump::replay_into (replayer *r)
6901{
6902  playback_block (get_block ())
6903    ->add_jump (playback_location (r),
6904		m_target->playback_block ());
6905}
6906
6907/* Override the poisoned default implementation of
6908   gcc::jit::recording::statement::get_successor_blocks
6909
6910   An unconditional jump has 1 successor block.  */
6911
6912vec <recording::block *>
6913recording::jump::get_successor_blocks () const
6914{
6915  vec <block *> result;
6916  result.create (1);
6917  result.quick_push (m_target);
6918  return result;
6919}
6920
6921/* Implementation of recording::memento::make_debug_string for
6922   a unconditional jump statement.  */
6923
6924recording::string *
6925recording::jump::make_debug_string ()
6926{
6927  return string::from_printf (m_ctxt,
6928			      "goto %s;",
6929			      m_target->get_debug_string ());
6930}
6931
6932/* Implementation of recording::memento::write_reproducer for
6933   jump statements.  */
6934
6935void
6936recording::jump::write_reproducer (reproducer &r)
6937{
6938  r.write ("  gcc_jit_block_end_with_jump (%s, /*gcc_jit_block *block */\n"
6939	   "                               %s, /* gcc_jit_location *loc */\n"
6940	   "                               %s); /* gcc_jit_block *target */\n",
6941	   r.get_identifier (get_block ()),
6942	   r.get_identifier (get_loc ()),
6943	   r.get_identifier (m_target));
6944}
6945
6946/* The implementation of class gcc::jit::recording::return_.  */
6947
6948/* Implementation of pure virtual hook recording::memento::replay_into
6949   for recording::return_.  */
6950
6951void
6952recording::return_::replay_into (replayer *r)
6953{
6954  playback_block (get_block ())
6955    ->add_return (playback_location (r),
6956		  m_rvalue ? m_rvalue->playback_rvalue () : NULL);
6957}
6958
6959/* Override the poisoned default implementation of
6960   gcc::jit::recording::statement::get_successor_blocks
6961
6962   A return statement has no successor block.  */
6963
6964vec <recording::block *>
6965recording::return_::get_successor_blocks () const
6966{
6967  vec <block *> result;
6968  result.create (0);
6969  return result;
6970}
6971
6972/* Implementation of recording::memento::make_debug_string for
6973   a return statement (covers both those with and without rvalues).  */
6974
6975recording::string *
6976recording::return_::make_debug_string ()
6977{
6978  if (m_rvalue)
6979    return string::from_printf (m_ctxt,
6980				"return %s;",
6981				m_rvalue->get_debug_string ());
6982  else
6983    return string::from_printf (m_ctxt,
6984				"return;");
6985}
6986
6987/* Implementation of recording::memento::write_reproducer for
6988   return statements.  */
6989
6990void
6991recording::return_::write_reproducer (reproducer &r)
6992{
6993  if (m_rvalue)
6994    r.write ("  gcc_jit_block_end_with_return (%s, /*gcc_jit_block *block */\n"
6995	     "                                 %s, /* gcc_jit_location *loc */\n"
6996	     "                                 %s); /* gcc_jit_rvalue *rvalue */\n",
6997	     r.get_identifier (get_block ()),
6998	     r.get_identifier (get_loc ()),
6999	     r.get_identifier_as_rvalue (m_rvalue));
7000  else
7001    r.write ("  gcc_jit_block_end_with_void_return (%s, /*gcc_jit_block *block */\n"
7002	     "                                      %s); /* gcc_jit_location *loc */\n",
7003	     r.get_identifier (get_block ()),
7004	     r.get_identifier (get_loc ()));
7005}
7006
7007/* The implementation of class gcc::jit::recording::case_.  */
7008
7009void
7010recording::case_::write_reproducer (reproducer &r)
7011{
7012  const char *id = r.make_identifier (this, "case");
7013  const char *fmt =
7014    "  gcc_jit_case *%s = \n"
7015    "    gcc_jit_context_new_case (%s, /*gcc_jit_context *ctxt */\n"
7016    "                              %s, /* gcc_jit_rvalue *min_value */\n"
7017    "                              %s, /* gcc_jit_rvalue *max_value */\n"
7018    "                              %s); /* gcc_jit_block *dest_block */\n";
7019  r.write (fmt,
7020	   id,
7021	   r.get_identifier (get_context ()),
7022	   r.get_identifier_as_rvalue (m_min_value),
7023	   r.get_identifier_as_rvalue (m_max_value),
7024	   r.get_identifier (m_dest_block));
7025}
7026
7027recording::string *
7028recording::case_::make_debug_string ()
7029{
7030  return string::from_printf (get_context (),
7031			      "case %s ... %s: goto %s;",
7032			      m_min_value->get_debug_string (),
7033			      m_max_value->get_debug_string (),
7034			      m_dest_block->get_debug_string ());
7035}
7036
7037/* The implementation of class gcc::jit::recording::switch_.  */
7038
7039/* gcc::jit::recording::switch_'s constructor.  */
7040
7041recording::switch_::switch_ (block *b,
7042			     location *loc,
7043			     rvalue *expr,
7044			     block *default_block,
7045			     int num_cases,
7046			     case_ **cases)
7047: statement (b, loc),
7048  m_expr (expr),
7049  m_default_block (default_block)
7050{
7051  m_cases.reserve_exact (num_cases);
7052  for (int i = 0; i< num_cases; i++)
7053    m_cases.quick_push (cases[i]);
7054}
7055
7056/* Implementation of pure virtual hook recording::memento::replay_into
7057   for recording::switch_.  */
7058
7059void
7060recording::switch_::replay_into (replayer *r)
7061{
7062  auto_vec <playback::case_> pcases;
7063  int i;
7064  recording::case_ *rcase;
7065  pcases.reserve_exact (m_cases.length ());
7066  FOR_EACH_VEC_ELT (m_cases, i, rcase)
7067    {
7068      playback::case_ pcase (rcase->get_min_value ()->playback_rvalue (),
7069			     rcase->get_max_value ()->playback_rvalue (),
7070			     rcase->get_dest_block ()->playback_block ());
7071      pcases.safe_push (pcase);
7072    }
7073  playback_block (get_block ())
7074    ->add_switch (playback_location (r),
7075		  m_expr->playback_rvalue (),
7076		  m_default_block->playback_block (),
7077		  &pcases);
7078}
7079
7080/* Override the poisoned default implementation of
7081   gcc::jit::recording::statement::get_successor_blocks
7082
7083   A switch statement has (NUM_CASES + 1) successor blocks.  */
7084
7085vec <recording::block *>
7086recording::switch_::get_successor_blocks () const
7087{
7088  vec <block *> result;
7089  result.create (m_cases.length () + 1);
7090  result.quick_push (m_default_block);
7091  int i;
7092  case_ *c;
7093  FOR_EACH_VEC_ELT (m_cases, i, c)
7094    result.quick_push (c->get_dest_block ());
7095  return result;
7096}
7097
7098/* Implementation of recording::memento::make_debug_string for
7099   a switch statement.  */
7100
7101recording::string *
7102recording::switch_::make_debug_string ()
7103{
7104  auto_vec <char> cases_str;
7105  int i;
7106  case_ *c;
7107  FOR_EACH_VEC_ELT (m_cases, i, c)
7108    {
7109      size_t len = strlen (c->get_debug_string ());
7110      unsigned idx = cases_str.length ();
7111      cases_str.safe_grow (idx + 1 + len, true);
7112      cases_str[idx] = ' ';
7113      memcpy (&(cases_str[idx + 1]),
7114	      c->get_debug_string (),
7115	      len);
7116    }
7117  cases_str.safe_push ('\0');
7118
7119  return string::from_printf (m_ctxt,
7120			      "switch (%s) {default: goto %s;%s}",
7121			      m_expr->get_debug_string (),
7122			      m_default_block->get_debug_string (),
7123			      &cases_str[0]);
7124}
7125
7126/* Implementation of recording::memento::write_reproducer for
7127   switch statements.  */
7128
7129void
7130recording::switch_::write_reproducer (reproducer &r)
7131{
7132  r.make_identifier (this, "switch");
7133  int i;
7134  case_ *c;
7135  const char *cases_id =
7136    r.make_tmp_identifier ("cases_for", this);
7137  r.write ("  gcc_jit_case *%s[%i] = {\n",
7138	   cases_id,
7139	   m_cases.length ());
7140  FOR_EACH_VEC_ELT (m_cases, i, c)
7141    r.write ("    %s,\n", r.get_identifier (c));
7142  r.write ("  };\n");
7143  const char *fmt =
7144    "  gcc_jit_block_end_with_switch (%s, /*gcc_jit_block *block */\n"
7145    "                                 %s, /* gcc_jit_location *loc */\n"
7146    "                                 %s, /* gcc_jit_rvalue *expr */\n"
7147    "                                 %s, /* gcc_jit_block *default_block */\n"
7148    "                                 %i, /* int num_cases */\n"
7149    "                                 %s); /* gcc_jit_case **cases */\n";
7150    r.write (fmt,
7151	     r.get_identifier (get_block ()),
7152	     r.get_identifier (get_loc ()),
7153	     r.get_identifier_as_rvalue (m_expr),
7154	     r.get_identifier (m_default_block),
7155	     m_cases.length (),
7156	     cases_id);
7157}
7158
7159/* class asm_operand : public memento.  */
7160
7161recording::asm_operand::asm_operand (extended_asm *ext_asm,
7162				     string *asm_symbolic_name,
7163				     string *constraint)
7164: memento (ext_asm->get_context ()),
7165  m_ext_asm (ext_asm),
7166  m_asm_symbolic_name (asm_symbolic_name),
7167  m_constraint (constraint)
7168{
7169}
7170
7171void
7172recording::asm_operand::print (pretty_printer *pp) const
7173{
7174  if (m_asm_symbolic_name)
7175    {
7176      pp_character (pp, '[');
7177      pp_string (pp, m_asm_symbolic_name->c_str ());
7178      pp_character (pp, ']');
7179      pp_space (pp);
7180    }
7181  pp_string (pp, m_constraint->get_debug_string ());
7182  /* Subclass will add lvalue/rvalue.  */
7183}
7184
7185recording::string *
7186recording::asm_operand::make_debug_string ()
7187{
7188  pretty_printer pp;
7189  print (&pp);
7190  return m_ctxt->new_string (pp_formatted_text (&pp), false);
7191}
7192
7193/* class output_asm_operand : public asm_operand.  */
7194
7195void
7196recording::output_asm_operand::write_reproducer (reproducer &r)
7197{
7198  const char *fmt =
7199    "  gcc_jit_extended_asm_add_output_operand (%s, /* gcc_jit_extended_asm *ext_asm */\n"
7200    "                                           %s, /* const char *asm_symbolic_name */\n"
7201    "                                           %s, /* const char *constraint */\n"
7202    "                                           %s); /* gcc_jit_lvalue *dest */\n";
7203  r.write (fmt,
7204	   r.get_identifier (m_ext_asm),
7205	   (m_asm_symbolic_name
7206	    ? m_asm_symbolic_name->get_debug_string () : "NULL"),
7207	   m_constraint->get_debug_string (),
7208	   r.get_identifier (m_dest));
7209}
7210
7211void
7212recording::output_asm_operand::print (pretty_printer *pp) const
7213{
7214  asm_operand::print (pp);
7215  pp_string (pp, " (");
7216  pp_string (pp, m_dest->get_debug_string ());
7217  pp_string (pp, ")");
7218}
7219
7220/* class input_asm_operand : public asm_operand.  */
7221
7222void
7223recording::input_asm_operand::write_reproducer (reproducer &r)
7224{
7225  const char *fmt =
7226    "  gcc_jit_extended_asm_add_input_operand (%s, /* gcc_jit_extended_asm *ext_asm */\n"
7227    "                                          %s, /* const char *asm_symbolic_name */\n"
7228    "                                          %s, /* const char *constraint */\n"
7229    "                                          %s); /* gcc_jit_rvalue *src */\n";
7230  r.write (fmt,
7231	   r.get_identifier (m_ext_asm),
7232	   (m_asm_symbolic_name
7233	    ? m_asm_symbolic_name->get_debug_string () : "NULL"),
7234	   m_constraint->get_debug_string (),
7235	   r.get_identifier_as_rvalue (m_src));
7236}
7237
7238void
7239recording::input_asm_operand::print (pretty_printer *pp) const
7240{
7241  asm_operand::print (pp);
7242  pp_string (pp, " (");
7243  pp_string (pp, m_src->get_debug_string ());
7244  pp_string (pp, ")");
7245}
7246
7247/* The implementation of class gcc::jit::recording::extended_asm.  */
7248
7249void
7250recording::extended_asm::add_output_operand (const char *asm_symbolic_name,
7251					     const char *constraint,
7252					     lvalue *dest)
7253{
7254  output_asm_operand *op
7255    = new output_asm_operand (this,
7256			      new_string (asm_symbolic_name),
7257			      new_string (constraint),
7258			      dest);
7259  m_ctxt->record (op);
7260  m_output_ops.safe_push (op);
7261}
7262
7263void
7264recording::extended_asm::add_input_operand (const char *asm_symbolic_name,
7265					    const char *constraint,
7266					    rvalue *src)
7267{
7268  input_asm_operand *op
7269    = new input_asm_operand (this,
7270			     new_string (asm_symbolic_name),
7271			     new_string (constraint),
7272			     src);
7273  m_ctxt->record (op);
7274  m_input_ops.safe_push (op);
7275}
7276
7277void
7278recording::extended_asm::add_clobber (const char *victim)
7279{
7280  m_clobbers.safe_push (new_string (victim));
7281}
7282
7283/* Implementation of recording::memento::replay_into
7284   for recording::extended_asm.  */
7285
7286void
7287recording::extended_asm::replay_into (replayer *r)
7288{
7289  auto_vec<playback::asm_operand> playback_output_ops;
7290  auto_vec<playback::asm_operand> playback_input_ops;
7291  auto_vec<const char *> playback_clobbers;
7292  auto_vec<playback::block *> playback_goto_blocks;
7293
7294  /* Populate outputs.  */
7295  {
7296    output_asm_operand *rec_asm_op;
7297    unsigned i;
7298    FOR_EACH_VEC_ELT (m_output_ops, i, rec_asm_op)
7299      {
7300	playback::asm_operand playback_asm_op
7301	  (rec_asm_op->get_symbolic_name (),
7302	   rec_asm_op->get_constraint (),
7303	   rec_asm_op->get_lvalue ()->playback_lvalue ()->as_tree ());
7304	playback_output_ops.safe_push (playback_asm_op);
7305      }
7306  }
7307
7308  /* Populate inputs.  */
7309  {
7310    input_asm_operand *rec_asm_op;
7311    unsigned i;
7312    FOR_EACH_VEC_ELT (m_input_ops, i, rec_asm_op)
7313      {
7314	playback::asm_operand playback_asm_op
7315	  (rec_asm_op->get_symbolic_name (),
7316	   rec_asm_op->get_constraint (),
7317	   rec_asm_op->get_rvalue ()->playback_rvalue ()->as_tree ());
7318	playback_input_ops.safe_push (playback_asm_op);
7319      }
7320  }
7321
7322  /* Populate clobbers.  */
7323  {
7324    string *rec_clobber;
7325    unsigned i;
7326    FOR_EACH_VEC_ELT (m_clobbers, i, rec_clobber)
7327      playback_clobbers.safe_push (rec_clobber->c_str ());
7328  }
7329
7330  /* Populate playback blocks if an "asm goto".  */
7331  maybe_populate_playback_blocks (&playback_goto_blocks);
7332
7333  playback_block (get_block ())
7334    ->add_extended_asm (playback_location (r),
7335			m_asm_template->c_str (),
7336			m_is_volatile, m_is_inline,
7337			&playback_output_ops,
7338			&playback_input_ops,
7339			&playback_clobbers,
7340			&playback_goto_blocks);
7341}
7342
7343/* Implementation of recording::memento::make_debug_string for
7344   an extended_asm "statement".  */
7345
7346recording::string *
7347recording::extended_asm::make_debug_string ()
7348{
7349  pretty_printer pp;
7350  pp_string (&pp, "asm ");
7351  if (m_is_volatile)
7352    pp_string (&pp, "volatile ");
7353  if (m_is_inline)
7354    pp_string (&pp, "inline ");
7355  if (is_goto ())
7356    pp_string (&pp, "goto ");
7357  pp_character (&pp, '(');
7358  pp_string (&pp, m_asm_template->get_debug_string ());
7359  pp_string (&pp, " : ");
7360  unsigned i;
7361  {
7362    output_asm_operand *asm_op;
7363    FOR_EACH_VEC_ELT (m_output_ops, i, asm_op)
7364      {
7365	if (i > 0)
7366	  pp_string (&pp, ", ");
7367	asm_op->print (&pp);
7368      }
7369  }
7370  pp_string (&pp, " : ");
7371  {
7372    input_asm_operand *asm_op;
7373    FOR_EACH_VEC_ELT (m_input_ops, i, asm_op)
7374      {
7375	if (i > 0)
7376	  pp_string (&pp, ", ");
7377	asm_op->print (&pp);
7378      }
7379  }
7380  pp_string (&pp, " : ");
7381  string *rec_clobber;
7382  FOR_EACH_VEC_ELT (m_clobbers, i, rec_clobber)
7383      {
7384	if (i > 0)
7385	  pp_string (&pp, ", ");
7386	pp_string (&pp, rec_clobber->get_debug_string ());
7387      }
7388  maybe_print_gotos (&pp);
7389  pp_character (&pp, ')');
7390  return new_string (pp_formatted_text (&pp));
7391}
7392
7393void
7394recording::extended_asm::write_flags (reproducer &r)
7395{
7396  if (m_is_volatile)
7397    r.write ("  gcc_jit_extended_asm_set_volatile_flag (%s, 1);\n",
7398	     r.get_identifier (this));
7399  if (m_is_inline)
7400    r.write ("  gcc_jit_extended_asm_set_inline_flag (%s, 1);\n",
7401	     r.get_identifier (this));
7402}
7403
7404void
7405recording::extended_asm::write_clobbers (reproducer &r)
7406{
7407  string *clobber;
7408  unsigned i;
7409  FOR_EACH_VEC_ELT (m_clobbers, i, clobber)
7410    r.write ("  gcc_jit_extended_asm_add_clobber (%s, %s);\n",
7411	     r.get_identifier (this),
7412	     clobber->get_debug_string ());
7413}
7414
7415/* Implementation of recording::memento::write_reproducer for
7416   extended_asm_simple.  */
7417
7418void
7419recording::extended_asm_simple::write_reproducer (reproducer &r)
7420{
7421  const char *id = r.make_identifier (this, "extended_asm");
7422  r.write ("  gcc_jit_extended_asm *%s =\n"
7423	   "    gcc_jit_block_add_extended_asm (%s, /*gcc_jit_block *block */\n"
7424	   "                                    %s, /* gcc_jit_location *loc */\n"
7425	   "                                    %s); /* const char *asm_template */\n",
7426	   id,
7427	   r.get_identifier (get_block ()),
7428	   r.get_identifier (get_loc ()),
7429	   m_asm_template->get_debug_string ());
7430  write_flags (r);
7431  write_clobbers (r);
7432}
7433
7434void
7435recording::extended_asm::
7436maybe_populate_playback_blocks (auto_vec <playback::block *> *)
7437{
7438  /* Do nothing; not an "asm goto".  */
7439}
7440
7441/* The implementation of class gcc::jit::recording::extended_asm_goto.  */
7442
7443/* recording::extended_asm_goto's ctor.  */
7444
7445recording::extended_asm_goto::extended_asm_goto (block *b,
7446						 location *loc,
7447						 string *asm_template,
7448						 int num_goto_blocks,
7449						 block **goto_blocks,
7450						 block *fallthrough_block)
7451: extended_asm (b, loc, asm_template),
7452  m_goto_blocks (num_goto_blocks),
7453  m_fallthrough_block (fallthrough_block)
7454{
7455  for (int i = 0; i < num_goto_blocks; i++)
7456    m_goto_blocks.quick_push (goto_blocks[i]);
7457}
7458
7459/* Implementation of recording::memento::replay_into
7460   for recording::extended_asm_goto.  */
7461
7462void
7463recording::extended_asm_goto::replay_into (replayer *r)
7464{
7465  /* Chain up to base class impl.  */
7466  recording::extended_asm::replay_into (r);
7467
7468  /* ...and potentially add a goto for the fallthrough.  */
7469  if (m_fallthrough_block)
7470    playback_block (get_block ())
7471      ->add_jump (playback_location (r),
7472		  m_fallthrough_block->playback_block ());
7473}
7474
7475/* Implementation of recording::memento::write_reproducer for
7476   extended_asm_goto.  */
7477
7478void
7479recording::extended_asm_goto::write_reproducer (reproducer &r)
7480{
7481  const char *id = r.make_identifier (this, "extended_asm");
7482  const char *blocks_id = r.make_tmp_identifier ("blocks_for", this);
7483  r.write ("  gcc_jit_block *%s[%i] = {\n",
7484	   blocks_id,
7485	   m_goto_blocks.length ());
7486  int i;
7487  block *b;
7488  FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
7489    r.write ("    %s,\n", r.get_identifier (b));
7490  r.write ("  };\n");
7491  r.write ("  gcc_jit_extended_asm *%s =\n"
7492	   "    gcc_jit_block_end_with_extended_asm_goto (%s, /*gcc_jit_block *block */\n"
7493	   "                                              %s, /* gcc_jit_location *loc */\n"
7494	   "                                              %s, /* const char *asm_template */\n"
7495	   "                                              %i, /* int num_goto_blocks */\n"
7496	   "                                              %s, /* gcc_jit_block **goto_blocks */\n"
7497	   "                                              %s); /* gcc_jit_block *fallthrough_block */\n",
7498	   id,
7499	   r.get_identifier (get_block ()),
7500	   r.get_identifier (get_loc ()),
7501	   m_asm_template->get_debug_string (),
7502	   m_goto_blocks.length (),
7503	   blocks_id,
7504	   (m_fallthrough_block
7505	    ? r.get_identifier (m_fallthrough_block)
7506	    : "NULL"));
7507  write_flags (r);
7508  write_clobbers (r);
7509}
7510
7511/* Override the poisoned default implementation of
7512   gcc::jit::recording::statement::get_successor_blocks
7513
7514   An extended_asm_goto can jump to the m_goto_blocks, and to
7515   the (optional) m_fallthrough_block.  */
7516
7517vec <recording::block *>
7518recording::extended_asm_goto::get_successor_blocks () const
7519{
7520  vec <block *> result;
7521  result.create (m_goto_blocks.length () + 1);
7522  if (m_fallthrough_block)
7523    result.quick_push (m_fallthrough_block);
7524  result.splice (m_goto_blocks);
7525  return result;
7526}
7527
7528/* Vfunc for use by recording::extended_asm::make_debug_string.  */
7529
7530void
7531recording::extended_asm_goto::maybe_print_gotos (pretty_printer *pp) const
7532{
7533  pp_string (pp, " : ");
7534  unsigned i;
7535  block *b;
7536  FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
7537    {
7538      if (i > 0)
7539	pp_string (pp, ", ");
7540      pp_string (pp, b->get_debug_string ());
7541    }
7542  /* Non-C syntax here.  */
7543  if (m_fallthrough_block)
7544    pp_printf (pp, " [fallthrough: %s]",
7545	       m_fallthrough_block->get_debug_string ());
7546}
7547
7548/* Vfunc for use by recording::extended_asm::replay_into.  */
7549
7550void
7551recording::extended_asm_goto::
7552maybe_populate_playback_blocks (auto_vec <playback::block *> *out)
7553{
7554  unsigned i;
7555  block *b;
7556  FOR_EACH_VEC_ELT (m_goto_blocks, i, b)
7557    out->safe_push (b->playback_block ());
7558}
7559
7560/* class top_level_asm : public memento.  */
7561
7562recording::top_level_asm::top_level_asm (context *ctxt,
7563					 location *loc,
7564					 string *asm_stmts)
7565: memento (ctxt),
7566  m_loc (loc),
7567  m_asm_stmts (asm_stmts)
7568{
7569}
7570
7571/* Implementation of recording::memento::replay_into for top-level asm.  */
7572
7573void
7574recording::top_level_asm::replay_into (replayer *r)
7575{
7576  r->add_top_level_asm (m_asm_stmts->c_str ());
7577}
7578
7579/* Implementation of recording::memento::make_debug_string for
7580   top-level asm.  */
7581
7582recording::string *
7583recording::top_level_asm::make_debug_string ()
7584{
7585  return string::from_printf (m_ctxt, "asm (%s)",
7586			      m_asm_stmts->get_debug_string ());
7587}
7588
7589/* Override the default implementation of
7590   recording::memento::write_to_dump.
7591   Don't indent the string.  */
7592
7593void
7594recording::top_level_asm::write_to_dump (dump &d)
7595{
7596  d.write ("%s;\n", get_debug_string ());
7597}
7598
7599/* Implementation of recording::memento::write_reproducer for top-level asm. */
7600
7601void
7602recording::top_level_asm::write_reproducer (reproducer &r)
7603{
7604  r.write ("  gcc_jit_context_add_top_level_asm (%s, /* gcc_jit_context *ctxt */\n"
7605	   "                                     %s, /* gcc_jit_location *loc */\n"
7606	   "                                     %s); /* const char *asm_stmts */\n",
7607	   r.get_identifier (get_context ()),
7608	   r.get_identifier (m_loc),
7609	   m_asm_stmts->get_debug_string ());
7610}
7611
7612void
7613recording::global_init_rvalue::replay_into (replayer *r)
7614{
7615  r->global_set_init_rvalue (m_variable->playback_lvalue (),
7616			     m_init->playback_rvalue ());
7617}
7618
7619void
7620recording::global_init_rvalue::write_reproducer (reproducer &r)
7621{
7622  r.write (
7623    "  gcc_jit_global_set_initializer_rvalue (%s, /* lvalue *global */\n"
7624    "                                         %s);/* rvalue *init */\n",
7625    r.get_identifier (m_variable),
7626    r.get_identifier_as_rvalue (m_init));
7627}
7628
7629void
7630recording::global_init_rvalue::write_to_dump (dump &d)
7631{
7632  d.write ("%s;\n", get_debug_string ());
7633}
7634
7635recording::string *
7636recording::global_init_rvalue::make_debug_string ()
7637{
7638    return string::from_printf (m_ctxt, "%s = %s",
7639      m_variable->get_debug_string (),
7640      m_init->get_debug_string ());
7641}
7642
7643enum strip_flags {
7644  STRIP_FLAG_NONE,
7645  STRIP_FLAG_ARR,
7646  STRIP_FLAG_VEC
7647};
7648
7649/* Strips type down to array, vector or base type (whichever comes first)
7650
7651   Also saves 'ptr_depth' and sets 'flags' for array or vector types.  */
7652static
7653recording::type *
7654strip_and_count (recording::type *type_to_strip,
7655		 int &ptr_depth,
7656		 strip_flags &flags)
7657{
7658  recording::type *t = type_to_strip;
7659
7660  while (true)
7661    {
7662      if (!t)
7663	gcc_unreachable (); /* Should only happen on corrupt input.  */
7664
7665      recording::type *pointed_to_type = t->is_pointer ();
7666      if (pointed_to_type != NULL)
7667	{
7668	  ptr_depth++;
7669	  t = pointed_to_type;
7670	  continue;
7671	}
7672
7673      recording::type *array_el = t->is_array ();
7674      if (array_el != NULL)
7675	{
7676	  flags = STRIP_FLAG_ARR;
7677	  break;
7678	}
7679
7680      recording::type *vec = t->dyn_cast_vector_type ();
7681      if (vec != NULL)
7682	{
7683	  flags = STRIP_FLAG_VEC;
7684	  break;
7685	}
7686
7687      /* unqualified () returns 'this' on base types.  */
7688      recording::type *next = t->unqualified ();
7689      if (next == t)
7690	{
7691	  break;
7692	}
7693      t = next;
7694    }
7695
7696  return t;
7697}
7698
7699/* Strip qualifiers and count pointer depth, returning true
7700   if the types' base type and pointer depth are
7701   the same, otherwise false.
7702
7703   For array and vector types the number of element also
7704   has to match.
7705
7706   Do not call this directly.  Call 'types_kinda_same'.  */
7707bool
7708types_kinda_same_internal (recording::type *a, recording::type *b)
7709{
7710  int ptr_depth_a = 0;
7711  int ptr_depth_b = 0;
7712  recording::type *base_a;
7713  recording::type *base_b;
7714
7715  strip_flags flags_a = STRIP_FLAG_NONE;
7716  strip_flags flags_b = STRIP_FLAG_NONE;
7717
7718  base_a = strip_and_count (a, ptr_depth_a, flags_a);
7719  base_b = strip_and_count (b, ptr_depth_b, flags_b);
7720
7721  if (ptr_depth_a != ptr_depth_b)
7722    return false;
7723
7724  if (base_a == base_b)
7725    return true;
7726
7727  if (flags_a != flags_b)
7728    return false;
7729
7730  /* If the "base type" is an array or vector we might need to
7731     check deeper.  */
7732  if (flags_a == STRIP_FLAG_ARR)
7733    {
7734      recording::array_type *arr_a =
7735	static_cast<recording::array_type*> (base_a);
7736      recording::array_type *arr_b =
7737	static_cast<recording::array_type*> (base_b);
7738
7739      if (arr_a->num_elements () != arr_b->num_elements ())
7740	return false;
7741
7742      /* is_array returns element type.  */
7743      recording::type *el_a = arr_a->is_array ();
7744      recording::type *el_b = arr_b->is_array ();
7745
7746      if (el_a == el_b)
7747	return true;
7748
7749      return types_kinda_same_internal (el_a, el_b);
7750    }
7751  if (flags_a == STRIP_FLAG_VEC)
7752    {
7753      recording::vector_type *arr_a =
7754	static_cast<recording::vector_type*> (base_a);
7755      recording::vector_type *arr_b =
7756	static_cast<recording::vector_type*> (base_b);
7757
7758      if (arr_a->get_num_units () != arr_b->get_num_units ())
7759	return false;
7760
7761      recording::type *el_a = arr_a->get_element_type ();
7762      recording::type *el_b = arr_b->get_element_type ();
7763
7764      if (el_a == el_b)
7765	return true;
7766
7767      return types_kinda_same_internal (el_a, el_b);
7768    }
7769
7770  return false;
7771}
7772
7773} // namespace gcc::jit
7774
7775} // namespace gcc
7776