/* Internals of libgccjit: classes for recording calls made to the JIT API.
   Copyright (C) 2013-2019 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "pretty-print.h"
#include "toplev.h"

#include <pthread.h>

#include "jit-builtins.h"
#include "jit-recording.h"
#include "jit-playback.h"

namespace gcc {
namespace jit {

// class dump

dump::dump (recording::context &ctxt,
	    const char *filename,
	    bool update_locations)
: m_ctxt (ctxt),
  m_filename (filename),
  m_update_locations (update_locations),
  m_line (0),
  m_column (0)
{
  m_file = fopen (filename, "w");
  if (!m_file)
    ctxt.add_error (NULL,
		    "error opening dump file %s for writing: %s",
		    filename,
		    xstrerror (errno));
}

dump::~dump ()
{
  if (m_file)
    {
      int err = fclose (m_file);
      if (err)
	m_ctxt.add_error (NULL,
			  "error closing dump file %s: %s",
			  m_filename,
			  xstrerror (errno));
    }
}

/* Write the given message to the dump, using printf-formatting
   conventions, updating the line/column within the dump.

   Emit an error on the context if a failure occurs.  */

void
dump::write (const char *fmt, ...)
{
  int len;
  va_list ap;
  char *buf;

  /* If there was an error opening the file, we've already reported it.
     Don't attempt further work.  */
  if (!m_file)
    return;

  va_start (ap, fmt);
  len = vasprintf (&buf, fmt, ap);
  va_end (ap);

  if (buf == NULL || len < 0)
    {
      m_ctxt.add_error (NULL, "malloc failure writing to dumpfile %s",
			m_filename);
      return;
    }

  if (fwrite (buf, strlen (buf), 1, m_file) != 1)
    m_ctxt.add_error (NULL, "error writing to dump file %s",
		      m_filename);

  /* Flush after each line, to ease debugging crashes.  */
  fflush (m_file);

  /* Update line/column: */
  for (const char *ptr = buf; *ptr; ptr++)
    {
      if ('\n' == *ptr)
	{
	  m_line++;
	  m_column = 0;
	}
      else
	m_column++;
    }

  free (buf);
}

/* Construct a gcc::jit::recording::location instance for the current
   location within the dump.  */

recording::location *
dump::make_location () const
{
  return m_ctxt.new_location (m_filename, m_line, m_column,
			      /* We need to flag such locations as *not*
				 created by the user, so that
				 reproducer::get_identifier can cope with
				 them appearing *after* the memento that
				 refers to them.  */
			      false);
}

/* A collection of allocations, all of which can be released together, to
   avoid needing to track and release them individually.  */

class allocator
{
 public:
  ~allocator ();

  char *
  xstrdup_printf (const char *, ...)
    ATTRIBUTE_RETURNS_NONNULL
    GNU_PRINTF(2, 3);

  char *
  xstrdup_printf_va (const char *, va_list ap)
    ATTRIBUTE_RETURNS_NONNULL
    GNU_PRINTF(2, 0);

 private:
  auto_vec <void *> m_buffers;
};

/* allocator's destructor.  Call "free" on all of the allocations.  */

allocator::~allocator ()
{
  unsigned i;
  void *buffer;
  FOR_EACH_VEC_ELT (m_buffers, i, buffer)
    free (buffer);
}

/* Formatted printing, allocating to a buffer (or exiting the process if
   the allocation fails).

   The buffer exists until the allocator is cleaned up, and is freed at
   that point, so the caller doesn't need to track the result.  */

char *
allocator::xstrdup_printf (const char *fmt, ...)
{
  char *result;
  va_list ap;
  va_start (ap, fmt);
  result = xstrdup_printf_va (fmt, ap);
  va_end (ap);
  return result;
}

/* Formatted printing, allocating to a buffer (or exiting the process if
   the allocation fails).

   The buffer exists until the allocator is cleaned up, and is freed at
   that point, so the caller doesn't need to track the result.  */

char *
allocator::xstrdup_printf_va (const char *fmt, va_list ap)
{
  char *result = xvasprintf (fmt, ap);
  m_buffers.safe_push (result);
  return result;
}

/* gcc::jit::reproducer is a subclass of gcc::jit::dump, used for
   implementing gcc_jit_context_dump_reproducer_to_file.  */

class reproducer : public dump
{
 public:
  reproducer (recording::context &ctxt,
	      const char *filename);

  void
  write_params (const vec <recording::context *> &contexts);

  void
  write_args (const vec <recording::context *> &contexts);

  const char *
  make_identifier (recording::memento *m, const char *prefix);

  const char *
  make_tmp_identifier (const char *prefix, recording::memento *m);

  const char *
  get_identifier (recording::context *ctxt);

  const char *
  get_identifier (recording::memento *m);

  const char *
  get_identifier_as_rvalue (recording::rvalue *m);

  const char *
  get_identifier_as_lvalue (recording::lvalue *m);

  const char *
  get_identifier_as_type (recording::type *m);

  char *
  xstrdup_printf (const char *, ...)
    ATTRIBUTE_RETURNS_NONNULL
    GNU_PRINTF(2, 3);

 private:
  const char * ensure_identifier_is_unique (const char *candidate, void *ptr);

 private:
  hash_map<recording::memento *, const char *> m_map_memento_to_identifier;

  struct hash_traits : public string_hash
  {
    static void remove (const char *) {}
  };
  hash_set<const char *, false, hash_traits> m_set_identifiers;
  allocator m_allocator;
};

/* gcc::jit::reproducer's constructor.  */

reproducer::reproducer (recording::context &ctxt,
			const char *filename) :
  dump (ctxt, filename, 0),
  m_map_memento_to_identifier (),
  m_set_identifiers (),
  m_allocator ()
{
}

/* Write out a list of contexts as a set of parameters within a
   C function declaration.  */

void
reproducer::write_params (const vec <recording::context *> &contexts)
{
  unsigned i;
  recording::context *ctxt;
  FOR_EACH_VEC_ELT (contexts, i, ctxt)
    {
      write ("gcc_jit_context *%s",
	     get_identifier (ctxt));
      if (i < contexts.length () - 1)
	write (",\n"
	       "             ");
    }
}

/* Write out a list of contexts as a set of arguments within a call
   to a C function.  */

void
reproducer::write_args (const vec <recording::context *> &contexts)
{
  unsigned i;
  recording::context *ctxt;
  FOR_EACH_VEC_ELT (contexts, i, ctxt)
    {
      write ("%s",
	     get_identifier (ctxt));
      if (i < contexts.length () - 1)
	write (",\n"
	       "               ");
    }
}

/* Ensure that STR is a valid C identifier by overwriting
   any invalid chars in-place with underscores.

   This doesn't special-case the first character.  */

static void
convert_to_identifier (char *str)
{
  for (char *p = str; *p; p++)
    if (!ISALNUM (*p))
      *p = '_';
}

/* Given CANDIDATE, a possible C identifier for use in a reproducer,
   ensure that it is unique within the generated source file by
   appending PTR to it if necessary.  Return the resulting string.

   The reproducer will eventually clean up the buffer in its dtor.  */

const char *
reproducer::ensure_identifier_is_unique (const char *candidate, void *ptr)
{
  if (m_set_identifiers.contains (candidate))
    candidate = m_allocator.xstrdup_printf ("%s_%p", candidate, ptr);
  gcc_assert (!m_set_identifiers.contains (candidate));
  m_set_identifiers.add (candidate);
  return candidate;
}

/* Generate a C identifier for the given memento, associating the generated
   buffer with the memento (for future calls to get_identifier et al).

   The reproducer will eventually clean up the buffer in its dtor.  */
const char *
reproducer::make_identifier (recording::memento *m, const char *prefix)
{
  const char *result;
  if (strlen (m->get_debug_string ()) < 100)
    {
      char *buf = m_allocator.xstrdup_printf ("%s_%s",
					      prefix,
					      m->get_debug_string ());
      convert_to_identifier (buf);
      result = buf;
    }
  else
    result = m_allocator.xstrdup_printf ("%s_%p",
					 prefix, (void *) m);
  result = ensure_identifier_is_unique (result, m);
  m_map_memento_to_identifier.put (m, result);
  return result;
}

/* Generate a C identifier for a temporary variable.
   The reproducer will eventually clean up the buffer in its dtor.  */

const char *
reproducer::make_tmp_identifier (const char *prefix, recording::memento *m)
{
  return m_allocator.xstrdup_printf ("%s_%s",
				     prefix, get_identifier (m));
}

/* Generate a C identifier for the given context.
   The reproducer will eventually clean up the buffer in its dtor.  */

const char *
reproducer::get_identifier (recording::context *ctxt)
{
  return m_allocator.xstrdup_printf ("ctxt_%p",
				     (void *)ctxt);
}

/* Locate the C identifier for the given memento, which is assumed to
   have already been created via make_identifier.  */

const char *
reproducer::get_identifier (recording::memento *m)
{
  if (!m)
    return "NULL";

  /* gcc_jit_context_dump_to_file (, , 1) generates and writes locations,
     and hence these locations appear in the context's memento list
     out-of-order: they appear in the context's memento list *after*
     the memento that refers to them.  For this case, it's simplest to
     pretend that they're NULL when writing out the code to recreate the
     memento that uses them.  */
  if (recording::location *loc = m->dyn_cast_location ())
    if (!loc->created_by_user ())
      return "NULL";

  const char **slot = m_map_memento_to_identifier.get (m);
  if (!slot)
    {
      get_context ().add_error (NULL,
				"unable to find identifier for %p: %s",
				(void *)m,
				m->get_debug_string ());
      gcc_unreachable ();
    }
  return *slot;
}

/* Locate the C identifier for the given rvalue, wrapping it within
   a gcc_*_as_rvalue upcast if necessary.  */

const char *
reproducer::get_identifier_as_rvalue (recording::rvalue *m)
{
  return m->access_as_rvalue (*this);
}

/* Locate the C identifier for the given lvalue, wrapping it within
   a gcc_*_as_lvalue upcast if necessary.  */

const char *
reproducer::get_identifier_as_lvalue (recording::lvalue *m)
{
  return m->access_as_lvalue (*this);
}

/* Locate the C identifier for the given type, wrapping it within
   a gcc_*_as_type upcast if necessary.  */

const char *
reproducer::get_identifier_as_type (recording::type *m)
{
  return m->access_as_type (*this);
}

/* Formatted printing, allocating to a buffer (or exiting the process if
   the allocation fails).

   The buffer exists until the allocator is cleaned up, and is freed at
   that point, so the caller doesn't need to track the result.

   Note that we can't use ggc_printf since we're not within the compiler
   proper (when within gcc_jit_context_dump_reproducer_to_file).  */

char *
reproducer::xstrdup_printf (const char *fmt, ...)
{
  char *result;
  va_list ap;
  va_start (ap, fmt);
  result = m_allocator.xstrdup_printf_va (fmt, ap);
  va_end (ap);
  return result;
}

/* A helper class for implementing make_debug_string, for building
   a temporary string from a vec of rvalues.  */

class comma_separated_string
{
 public:
  comma_separated_string (const auto_vec<recording::rvalue *> &rvalues,
			  enum recording::precedence prec);
  ~comma_separated_string ();

  const char *as_char_ptr () const { return m_buf; }

 private:
  char *m_buf;
};

/* comma_separated_string's ctor
   Build m_buf.  */

comma_separated_string::comma_separated_string
  (const auto_vec<recording::rvalue *> &rvalues,
   enum recording::precedence prec)
: m_buf (NULL)
{
  /* Calculate length of said buffer.  */
  size_t sz = 1; /* nil terminator */
  for (unsigned i = 0; i< rvalues.length (); i++)
    {
      sz += strlen (rvalues[i]->get_debug_string_parens (prec));
      sz += 2; /* ", " separator */
    }

  /* Now allocate and populate the buffer.  */
  m_buf = new char[sz];
  size_t len = 0;

  for (unsigned i = 0; i< rvalues.length (); i++)
    {
      strcpy (m_buf + len, rvalues[i]->get_debug_string_parens (prec));
      len += strlen (rvalues[i]->get_debug_string_parens (prec));
      if (i + 1 < rvalues.length ())
	{
	  strcpy (m_buf + len, ", ");
	  len += 2;
	}
    }
  m_buf[len] = '\0';
}

/* comma_separated_string's dtor.  */

comma_separated_string::~comma_separated_string ()
{
  delete[] m_buf;
}

/**********************************************************************
 Recording.
 **********************************************************************/

/* Get the playback::location for the given recording::location,
   handling a NULL input with a NULL output.  */

playback::location *
recording::playback_location (replayer *r, recording::location *loc)
{
  if (loc)
    return loc->playback_location (r);
  else
    return NULL;
}

/* Get a const char * for the given recording::string
   handling a NULL input with a NULL output.  */

const char *
recording::playback_string (recording::string *str)
{
  if (str)
    return str->c_str ();
  else
    return NULL;
}

/* Get the playback::block for the given recording::block,
   handling a NULL input with a NULL output.  */

playback::block *
recording::playback_block (recording::block *b)
{
  if (b)
    return b->playback_block ();
  else
    return NULL;
}

/* Methods of cc::jit::recording::context.  */

/* The constructor for gcc::jit::recording::context, used by
   gcc_jit_context_acquire and gcc_jit_context_new_child_context.  */

recording::context::context (context *parent_ctxt)
  : log_user (NULL),
    m_parent_ctxt (parent_ctxt),
    m_toplevel_ctxt (m_parent_ctxt ? m_parent_ctxt->m_toplevel_ctxt : this),
    m_timer (NULL),
    m_error_count (0),
    m_first_error_str (NULL),
    m_owns_first_error_str (false),
    m_last_error_str (NULL),
    m_owns_last_error_str (false),
    m_mementos (),
    m_compound_types (),
    m_globals (),
    m_functions (),
    m_FILE_type (NULL),
    m_builtins_manager(NULL)
{
  if (parent_ctxt)
    {
      /* Inherit options from parent.  */
      for (unsigned i = 0;
	   i < sizeof (m_str_options) / sizeof (m_str_options[0]);
	   i++)
	{
	  const char *parent_opt = parent_ctxt->m_str_options[i];
	  m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL;
	}
      memcpy (m_int_options,
	      parent_ctxt->m_int_options,
	      sizeof (m_int_options));
      memcpy (m_bool_options,
	      parent_ctxt->m_bool_options,
	      sizeof (m_bool_options));
      memcpy (m_inner_bool_options,
	      parent_ctxt->m_inner_bool_options,
	      sizeof (m_inner_bool_options));
      set_logger (parent_ctxt->get_logger ());
    }
  else
    {
      memset (m_str_options, 0, sizeof (m_str_options));
      memset (m_int_options, 0, sizeof (m_int_options));
      memset (m_bool_options, 0, sizeof (m_bool_options));
      memset (m_inner_bool_options, 0, sizeof (m_inner_bool_options));
    }

  memset (m_basic_types, 0, sizeof (m_basic_types));
}

/* The destructor for gcc::jit::recording::context, implicitly used by
   gcc_jit_context_release.  */

recording::context::~context ()
{
  JIT_LOG_SCOPE (get_logger ());
  int i;
  memento *m;
  FOR_EACH_VEC_ELT (m_mementos, i, m)
    {
      delete m;
    }

  for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
    free (m_str_options[i]);

  char *optname;
  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
    free (optname);
  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
    free (optname);

  if (m_builtins_manager)
    delete m_builtins_manager;

  if (m_owns_first_error_str)
    free (m_first_error_str);

  if (m_owns_last_error_str)
    if (m_last_error_str != m_first_error_str)
      free (m_last_error_str);
}

/* Add the given mememto to the list of those tracked by this
   gcc::jit::recording::context, so that e.g. it can be deleted
   when this context is released.  */

void
recording::context::record (memento *m)
{
  gcc_assert (m);

  m_mementos.safe_push (m);
}

/* Replay this context (and any parents) into the given replayer.  */

void
recording::context::replay_into (replayer *r)
{
  JIT_LOG_SCOPE (get_logger ());
  int i;
  memento *m;

  /* If we have a parent context, we must replay it.  This will
     recursively walk backwards up the historical tree, then replay things
     forwards "in historical order", starting with the ultimate parent
     context, until we reach the "this" context.

     Note that we fully replay the parent, then fully replay the child,
     which means that inter-context references can only exist from child
     to parent, not the other way around.

     All of this replaying is suboptimal - it would be better to do the
     work for the parent context *once*, rather than replaying the parent
     every time we replay each child.  However, fixing this requires deep
     surgery to lifetime-management: we'd need every context family tree
     to have its own GC heap, and to initialize the GCC code to use that
     heap (with a mutex on such a heap).  */
  if (m_parent_ctxt)
    m_parent_ctxt->replay_into (r);

  if (r->errors_occurred ())
    return;

  /* Replay this context's saved operations into r.  */
  FOR_EACH_VEC_ELT (m_mementos, i, m)
    {
      /* Disabled low-level debugging, here if we need it: print what
	 we're replaying.
	 Note that the calls to get_debug_string might lead to more
	 mementos being created for the strings.
	 This can also be used to exercise the debug_string
	 machinery.  */
      if (0)
	printf ("context %p replaying (%p): %s\n",
		(void *)this, (void *)m, m->get_debug_string ());

      m->replay_into (r);

      if (r->errors_occurred ())
	return;
    }
}

/* During a playback, we associate objects from the recording with
   their counterparts during this playback.

   For simplicity, we store this within the recording objects.

   The following method cleans away these associations, to ensure that
   we never have out-of-date associations lingering on subsequent
   playbacks (the objects pointed to are GC-managed, but the
   recording objects don't own refs to them).  */

void
recording::context::disassociate_from_playback ()
{
  JIT_LOG_SCOPE (get_logger ());
  int i;
  memento *m;

  if (m_parent_ctxt)
    m_parent_ctxt->disassociate_from_playback ();

  FOR_EACH_VEC_ELT (m_mementos, i, m)
    {
      m->set_playback_obj (NULL);
    }
}

/* Create a recording::string instance and add it to this context's list
   of mementos.

   This creates a fresh copy of the given 0-terminated buffer.  */

recording::string *
recording::context::new_string (const char *text)
{
  if (!text)
    return NULL;

  recording::string *result = new string (this, text);
  record (result);
  return result;
}

/* Create a recording::location instance and add it to this context's
   list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_location.  */

recording::location *
recording::context::new_location (const char *filename,
				  int line,
				  int column,
				  bool created_by_user)
{
  recording::location *result =
    new recording::location (this,
			     new_string (filename),
			     line, column,
			     created_by_user);
  record (result);
  return result;
}

/* If we haven't seen this enum value yet, create a recording::type
   instance and add it to this context's list of mementos.

   If we have seen it before, reuse our cached value, so that repeated
   calls on the context give the same object.

   If we have a parent context, the cache is within the ultimate
   ancestor context.

   Implements the post-error-checking part of
   gcc_jit_context_get_type.  */

recording::type *
recording::context::get_type (enum gcc_jit_types kind)
{
  if (!m_basic_types[kind])
    {
      if (m_parent_ctxt)
	m_basic_types[kind] = m_parent_ctxt->get_type (kind);
      else
	{
	  recording::type *result = new memento_of_get_type (this, kind);
	  record (result);
	  m_basic_types[kind] = result;
	}
    }

  return m_basic_types[kind];
}

/* Get a recording::type instance for the given size and signedness.
   This is implemented in terms of recording::context::get_type
   above.

   Implements the post-error-checking part of
   gcc_jit_context_get_int_type.  */

recording::type *
recording::context::get_int_type (int num_bytes, int is_signed)
{
  /* We can't use a switch here since some of the values are macros affected
     by options; e.g. i386.h has
       #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
     Compare with tree.c's make_or_reuse_type.  Note that the _SIZE macros
     are in bits, rather than bytes.
  */
  const int num_bits = num_bytes * 8;
  if (num_bits == INT_TYPE_SIZE)
    return get_type (is_signed
		     ? GCC_JIT_TYPE_INT
		     : GCC_JIT_TYPE_UNSIGNED_INT);
  if (num_bits == CHAR_TYPE_SIZE)
    return get_type (is_signed
		     ? GCC_JIT_TYPE_SIGNED_CHAR
		     : GCC_JIT_TYPE_UNSIGNED_CHAR);
  if (num_bits == SHORT_TYPE_SIZE)
    return get_type (is_signed
		     ? GCC_JIT_TYPE_SHORT
		     : GCC_JIT_TYPE_UNSIGNED_SHORT);
  if (num_bits == LONG_TYPE_SIZE)
    return get_type (is_signed
		     ? GCC_JIT_TYPE_LONG
		     : GCC_JIT_TYPE_UNSIGNED_LONG);
  if (num_bits == LONG_LONG_TYPE_SIZE)
    return get_type (is_signed
		     ? GCC_JIT_TYPE_LONG_LONG
		     : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);

  /* Some other size, not corresponding to the C int types.  */
  /* To be written: support arbitrary other sizes, sharing by
     memoizing at the recording::context level?  */
  gcc_unreachable ();
}

/* Create a recording::type instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_array_type.  */

recording::type *
recording::context::new_array_type (recording::location *loc,
				    recording::type *element_type,
				    int num_elements)
{
  if (struct_ *s = element_type->dyn_cast_struct ())
    if (!s->get_fields ())
      {
	add_error (NULL,
		   "cannot create an array of type %s"
		   " until the fields have been set",
		   s->get_name ()->c_str ());
	return NULL;
      }
  recording::type *result =
    new recording::array_type (this, loc, element_type, num_elements);
  record (result);
  return result;
}

/* Create a recording::field instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_field.  */

recording::field *
recording::context::new_field (recording::location *loc,
			       recording::type *type,
			       const char *name)
{
  recording::field *result =
    new recording::field (this, loc, type, new_string (name));
  record (result);
  return result;
}

/* Create a recording::struct_ instance and add it to this context's
   list of mementos and list of compound types.

   Implements the post-error-checking part of
   gcc_jit_context_new_struct_type.  */

recording::struct_ *
recording::context::new_struct_type (recording::location *loc,
				     const char *name)
{
  recording::struct_ *result = new struct_ (this, loc, new_string (name));
  record (result);
  m_compound_types.safe_push (result);
  return result;
}

/* Create a recording::union_ instance and add it to this context's
   list of mementos and list of compound types.

   Implements the first post-error-checking part of
   gcc_jit_context_new_union_type.  */

recording::union_ *
recording::context::new_union_type (recording::location *loc,
				    const char *name)
{
  recording::union_ *result = new union_ (this, loc, new_string (name));
  record (result);
  m_compound_types.safe_push (result);
  return result;
}

/* Create a recording::function_type instance and add it to this context's
   list of mementos.

   Used by new_function_ptr_type and by builtins_manager::make_fn_type.  */

recording::function_type *
recording::context::new_function_type (recording::type *return_type,
				       int num_params,
				       recording::type **param_types,
				       int is_variadic)
{
  recording::function_type *fn_type
    = new function_type (this,
			 return_type,
			 num_params,
			 param_types,
			 is_variadic);
  record (fn_type);
  return fn_type;
}

/* Create a recording::type instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_function_ptr_type.  */

recording::type *
recording::context::new_function_ptr_type (recording::location *, /* unused loc */
					   recording::type *return_type,
					   int num_params,
					   recording::type **param_types,
					   int is_variadic)
{
  recording::function_type *fn_type
    = new_function_type (return_type,
			 num_params,
			 param_types,
			 is_variadic);

  /* Return a pointer-type to the function type.  */
  return fn_type->get_pointer ();
}

/* Create a recording::param instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_param.  */

recording::param *
recording::context::new_param (recording::location *loc,
			       recording::type *type,
			       const char *name)
{
  recording::param *result = new recording::param (this, loc, type, new_string (name));
  record (result);
  return result;
}

/* Create a recording::function instance and add it to this context's list
   of mementos and list of functions.

   Implements the post-error-checking part of
   gcc_jit_context_new_function.  */

recording::function *
recording::context::new_function (recording::location *loc,
				  enum gcc_jit_function_kind kind,
				  recording::type *return_type,
				  const char *name,
				  int num_params,
				  recording::param **params,
				  int is_variadic,
				  enum built_in_function builtin_id)
{
  recording::function *result =
    new recording::function (this,
			     loc, kind, return_type,
			     new_string (name),
			     num_params, params, is_variadic,
			     builtin_id);
  record (result);
  m_functions.safe_push (result);

  return result;
}

/* Locate the builtins_manager (if any) for this family of contexts,
   creating it if it doesn't exist already.

   All of the recording contexts in a family share one builtins_manager:
   if we have a child context, follow the parent links to get the
   ultimate ancestor context, and look for it/store it there.  */

builtins_manager *
recording::context::get_builtins_manager ()
{
  if (m_parent_ctxt)
    return m_parent_ctxt->get_builtins_manager ();

  if (!m_builtins_manager)
    m_builtins_manager = new builtins_manager (this);

  return m_builtins_manager;
}

/* Get a recording::function instance, which is lazily-created and added
   to the context's lists of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_get_builtin_function.  */

recording::function *
recording::context::get_builtin_function (const char *name)
{
  builtins_manager *bm = get_builtins_manager ();
  return bm->get_builtin_function (name);
}

/* Create a recording::global instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_global.  */

recording::lvalue *
recording::context::new_global (recording::location *loc,
				enum gcc_jit_global_kind kind,
				recording::type *type,
				const char *name)
{
  recording::global *result =
    new recording::global (this, loc, kind, type, new_string (name));
  record (result);
  m_globals.safe_push (result);

  return result;
}

/* Create a recording::memento_of_new_string_literal instance and add it
   to this context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_string_literal.  */

recording::rvalue *
recording::context::new_string_literal (const char *value)
{
  recording::rvalue *result =
    new memento_of_new_string_literal (this, NULL, new_string (value));
  record (result);
  return result;
}

/* Create a recording::memento_of_new_rvalue_from_vector instance and add it
   to this context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_rvalue_from_vector.  */

recording::rvalue *
recording::context::new_rvalue_from_vector (location *loc,
					    vector_type *type,
					    rvalue **elements)
{
  recording::rvalue *result
    = new memento_of_new_rvalue_from_vector (this, loc, type, elements);
  record (result);
  return result;
}

/* Create a recording::unary_op instance and add it to this context's
   list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_unary_op.  */

recording::rvalue *
recording::context::new_unary_op (recording::location *loc,
				  enum gcc_jit_unary_op op,
				  recording::type *result_type,
				  recording::rvalue *a)
{
  recording::rvalue *result =
    new unary_op (this, loc, op, result_type, a);
  record (result);
  return result;
}

/* Create a recording::binary_op instance and add it to this context's
   list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_binary_op.  */

recording::rvalue *
recording::context::new_binary_op (recording::location *loc,
				   enum gcc_jit_binary_op op,
				   recording::type *result_type,
				   recording::rvalue *a,
				   recording::rvalue *b)
{
  recording::rvalue *result =
    new binary_op (this, loc, op, result_type, a, b);
  record (result);
  return result;
}

/* Create a recording::comparison instance and add it to this context's
   list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_comparison.  */

recording::rvalue *
recording::context::new_comparison (recording::location *loc,
				    enum gcc_jit_comparison op,
				    recording::rvalue *a,
				    recording::rvalue *b)
{
  recording::rvalue *result = new comparison (this, loc, op, a, b);
  record (result);
  return result;
}

/* Create a recording::cast instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_cast.  */

recording::rvalue *
recording::context::new_cast (recording::location *loc,
			      recording::rvalue *expr,
			      recording::type *type_)
{
  recording::rvalue *result = new cast (this, loc, expr, type_);
  record (result);
  return result;
}

/* Create a recording::call instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_call.  */

recording::rvalue *
recording::context::new_call (recording::location *loc,
			      function *func,
			      int numargs , recording::rvalue **args)
{
  recording::rvalue *result = new call (this, loc, func, numargs, args);
  record (result);
  return result;
}

/* Create a recording::call_through_ptr instance and add it to this
   context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_call_through_ptr.  */

recording::rvalue *
recording::context::new_call_through_ptr (recording::location *loc,
					  recording::rvalue *fn_ptr,
					  int numargs,
					  recording::rvalue **args)
  {
  recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
  record (result);
  return result;
}

/* Create a recording::array_access instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_array_access.  */

recording::lvalue *
recording::context::new_array_access (recording::location *loc,
				      recording::rvalue *ptr,
				      recording::rvalue *index)
{
  recording::lvalue *result = new array_access (this, loc, ptr, index);
  record (result);
  return result;
}

/* Create a recording::case_ instance and add it to this context's list
   of mementos.

   Implements the post-error-checking part of
   gcc_jit_context_new_case.  */

recording::case_ *
recording::context::new_case (recording::rvalue *min_value,
			      recording::rvalue *max_value,
			      recording::block *block)
{
  recording::case_ *result = new case_ (this, min_value, max_value, block);
  record (result);
  return result;
}

/* Set the given string option for this context, or add an error if
   it's not recognized.

   Implements the post-error-checking part of
   gcc_jit_context_set_str_option.  */

void
recording::context::set_str_option (enum gcc_jit_str_option opt,
				    const char *value)
{
  if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
    {
      add_error (NULL,
		 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
      return;
    }
  free (m_str_options[opt]);
  m_str_options[opt] = value ? xstrdup (value) : NULL;
  log_str_option (opt);
}

/* Set the given integer option for this context, or add an error if
   it's not recognized.

   Implements the post-error-checking part of
   gcc_jit_context_set_int_option.  */

void
recording::context::set_int_option (enum gcc_jit_int_option opt,
				    int value)
{
  if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
    {
      add_error (NULL,
		 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
      return;
    }
  m_int_options[opt] = value;
  log_int_option (opt);
}

/* Set the given boolean option for this context, or add an error if
   it's not recognized.

   Implements the post-error-checking part of
   gcc_jit_context_set_bool_option.  */

void
recording::context::set_bool_option (enum gcc_jit_bool_option opt,
				     int value)
{
  if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
    {
      add_error (NULL,
		 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
      return;
    }
  m_bool_options[opt] = value ? true : false;
  log_bool_option (opt);
}

void
recording::context::set_inner_bool_option (enum inner_bool_option inner_opt,
					   int value)
{
  gcc_assert (inner_opt >= 0 && inner_opt < NUM_INNER_BOOL_OPTIONS);
  m_inner_bool_options[inner_opt] = value ? true : false;
  log_inner_bool_option (inner_opt);
}


/* Add the given optname to this context's list of extra options.

   Implements the post-error-checking part of
   gcc_jit_context_add_command_line_option.  */

void
recording::context::add_command_line_option (const char *optname)
{
  m_command_line_options.safe_push (xstrdup (optname));
}

/* Add any user-provided extra options, starting with any from
   parent contexts.
   Called by playback::context::make_fake_args.  */

void
recording::context::append_command_line_options (vec <char *> *argvec)
{
  if (m_parent_ctxt)
    m_parent_ctxt->append_command_line_options (argvec);

  int i;
  char *optname;
  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
    argvec->safe_push (xstrdup (optname));
}

/* Add the given optname to this context's list of extra driver options.  */

void
recording::context::add_driver_option (const char *optname)
{
  m_driver_options.safe_push (xstrdup (optname));
}

/* Add any user-provided driver options, starting with any from
   parent contexts.
   Called by playback::context::invoke_driver.  */

void
recording::context::append_driver_options (auto_string_vec *argvec)
{
  if (m_parent_ctxt)
    m_parent_ctxt->append_driver_options (argvec);

  int i;
  char *optname;

  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
    argvec->safe_push (xstrdup (optname));
}

/* Add the given dumpname/out_ptr pair to this context's list of requested
   dumps.

   Implements the post-error-checking part of
   gcc_jit_context_enable_dump.  */

void
recording::context::enable_dump (const char *dumpname,
				 char **out_ptr)
{
  requested_dump d;
  gcc_assert (dumpname);
  gcc_assert (out_ptr);

  d.m_dumpname = dumpname;
  d.m_out_ptr = out_ptr;
  *out_ptr = NULL;
  m_requested_dumps.safe_push (d);
}

/* Validate this context, and if it passes, compile it to memory
   (within a mutex).

   Implements the post-error-checking part of
   gcc_jit_context_compile.  */

result *
recording::context::compile ()
{
  JIT_LOG_SCOPE (get_logger ());

  log_all_options ();

  validate ();

  if (errors_occurred ())
    return NULL;

  /* Set up a compile_to_memory playback context.  */
  ::gcc::jit::playback::compile_to_memory replayer (this);

  /* Use it.  */
  replayer.compile ();

  /* Get the jit::result (or NULL) from the
     compile_to_memory playback context.  */
  return replayer.get_result_obj ();
}

/* Validate this context, and if it passes, compile it to a file
   (within a mutex).

   Implements the post-error-checking part of
   gcc_jit_context_compile_to_file.  */

void
recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
				     const char *output_path)
{
  JIT_LOG_SCOPE (get_logger ());

  log_all_options ();

  validate ();

  if (errors_occurred ())
    return;

  /* Set up a compile_to_file playback context.  */
  ::gcc::jit::playback::compile_to_file replayer (this,
						  output_kind,
						  output_path);

  /* Use it.  */
  replayer.compile ();
}

/* Format the given error using printf's conventions, print
   it to stderr, and add it to the context.  */

void
recording::context::add_error (location *loc, const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  add_error_va (loc, fmt, ap);
  va_end (ap);
}

/* Format the given error using printf's conventions, print
   it to stderr, and add it to the context.  */

void
recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
{
  int len;
  char *malloced_msg;
  const char *errmsg;
  bool has_ownership;

  JIT_LOG_SCOPE (get_logger ());

  len = vasprintf (&malloced_msg, fmt, ap);
  if (malloced_msg == NULL || len < 0)
    {
      errmsg = "out of memory generating error message";
      has_ownership = false;
    }
  else
    {
      errmsg = malloced_msg;
      has_ownership = true;
    }
  if (get_logger ())
    get_logger ()->log ("error %i: %s", m_error_count, errmsg);

  const char *ctxt_progname =
    get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
  if (!ctxt_progname)
    ctxt_progname = "libgccjit.so";

  if (loc)
    fprintf (stderr, "%s: %s: error: %s\n",
	     ctxt_progname,
	     loc->get_debug_string (),
	     errmsg);
  else
    fprintf (stderr, "%s: error: %s\n",
	     ctxt_progname,
	     errmsg);

  if (!m_error_count)
    {
      m_first_error_str = const_cast <char *> (errmsg);
      m_owns_first_error_str = has_ownership;
    }

  if (m_owns_last_error_str)
    if (m_last_error_str != m_first_error_str)
      free (m_last_error_str);
  m_last_error_str = const_cast <char *> (errmsg);
  m_owns_last_error_str = has_ownership;

  m_error_count++;
}

/* Get the message for the first error that occurred on this context, or
   NULL if no errors have occurred on it.

   Implements the post-error-checking part of
   gcc_jit_context_get_first_error.  */

const char *
recording::context::get_first_error () const
{
  return m_first_error_str;
}

/* Get the message for the last error that occurred on this context, or
   NULL if no errors have occurred on it.

   Implements the post-error-checking part of
   gcc_jit_context_get_last_error.  */

const char *
recording::context::get_last_error () const
{
  return m_last_error_str;
}

/* Lazily generate and record a recording::type representing an opaque
   struct named "FILE".

   For use if client code tries to dereference the result of
   get_type (GCC_JIT_TYPE_FILE_PTR).  */

recording::type *
recording::context::get_opaque_FILE_type ()
{
  if (!m_FILE_type)
    m_FILE_type = new_struct_type (NULL, "FILE");
  return m_FILE_type;
}

/* Dump a C-like representation of the given context to the given path.
   If UPDATE_LOCATIONS is true, update the locations within the
   context's mementos to point to the dumpfile.

   Implements the post-error-checking part of
   gcc_jit_context_dump_to_file.  */

void
recording::context::dump_to_file (const char *path, bool update_locations)
{
  int i;
  dump d (*this, path, update_locations);

  /* Forward declaration of structs and unions.  */
  compound_type *st;
  FOR_EACH_VEC_ELT (m_compound_types, i, st)
    {
      d.write ("%s;\n\n", st->get_debug_string ());
    }

  /* Content of structs, where set.  */
  FOR_EACH_VEC_ELT (m_compound_types, i, st)
    if (st->get_fields ())
      {
	st->get_fields ()->write_to_dump (d);
	d.write ("\n");
      }

  /* Globals.  */
  global *g;
  FOR_EACH_VEC_ELT (m_globals, i, g)
    {
      g->write_to_dump (d);
    }
  if (!m_globals.is_empty ())
    d.write ("\n");

  function *fn;
  FOR_EACH_VEC_ELT (m_functions, i, fn)
    {
      fn->write_to_dump (d);
    }
}

static const char * const
 str_option_reproducer_strings[GCC_JIT_NUM_STR_OPTIONS] = {
  "GCC_JIT_STR_OPTION_PROGNAME"
};

static const char * const
 int_option_reproducer_strings[GCC_JIT_NUM_INT_OPTIONS] = {
  "GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL"
};

static const char * const
 bool_option_reproducer_strings[GCC_JIT_NUM_BOOL_OPTIONS] = {
  "GCC_JIT_BOOL_OPTION_DEBUGINFO",
  "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE",
  "GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE",
  "GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE",
  "GCC_JIT_BOOL_OPTION_DUMP_SUMMARY",
  "GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING",
  "GCC_JIT_BOOL_OPTION_SELFCHECK_GC",
  "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES"
};

static const char * const
 inner_bool_option_reproducer_strings[NUM_INNER_BOOL_OPTIONS] = {
  "gcc_jit_context_set_bool_allow_unreachable_blocks",
  "gcc_jit_context_set_bool_use_external_driver"
};

/* Write the current value of all options to the log file (if any).  */

void
recording::context::log_all_options () const
{
  int opt_idx;

  if (!get_logger ())
    return;

  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_STR_OPTIONS; opt_idx++)
    log_str_option ((enum gcc_jit_str_option)opt_idx);

  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_INT_OPTIONS; opt_idx++)
    log_int_option ((enum gcc_jit_int_option)opt_idx);

  for (opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++)
    log_bool_option ((enum gcc_jit_bool_option)opt_idx);
  for (opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
    log_inner_bool_option ((enum inner_bool_option)opt_idx);
}

/* Write the current value of the given string option to the
   log file (if any).  */

void
recording::context::log_str_option (enum gcc_jit_str_option opt) const
{
  gcc_assert (opt < GCC_JIT_NUM_STR_OPTIONS);
  if (get_logger ())
    {
      if (m_str_options[opt])
	log ("%s: \"%s\"",
	     str_option_reproducer_strings[opt],
	     m_str_options[opt]);
      else
	log ("%s: NULL",
	     str_option_reproducer_strings[opt]);
    }
}

/* Write the current value of the given int option to the
   log file (if any).  */

void
recording::context::log_int_option (enum gcc_jit_int_option opt) const
{
  gcc_assert (opt < GCC_JIT_NUM_INT_OPTIONS);
  if (get_logger ())
    log ("%s: %i",
	 int_option_reproducer_strings[opt],
	 m_int_options[opt]);
}

/* Write the current value of the given bool option to the
   log file (if any).  */

void
recording::context::log_bool_option (enum gcc_jit_bool_option opt) const
{
  gcc_assert (opt < GCC_JIT_NUM_BOOL_OPTIONS);
  if (get_logger ())
    log ("%s: %s",
	 bool_option_reproducer_strings[opt],
	 m_bool_options[opt] ? "true" : "false");
}

/* Write the current value of the given "inner" bool option to the
   log file (if any).  */

void
recording::context::log_inner_bool_option (enum inner_bool_option opt) const
{
  gcc_assert (opt < NUM_INNER_BOOL_OPTIONS);
  if (get_logger ())
    log ("%s: %s",
	 inner_bool_option_reproducer_strings[opt],
	 m_inner_bool_options[opt] ? "true" : "false");
}

/* Write C source code to PATH that attempts to replay the API
   calls made to this context (and its parents), for use in
   minimizing test cases for libgccjit.

   Implements the post-error-checking part of
   gcc_jit_context_dump_reproducer_to_file.  */

void
recording::context::dump_reproducer_to_file (const char *path)
{
  JIT_LOG_SCOPE (get_logger ());
  reproducer r (*this, path);

  /* Generate the "ancestry" of this context, as a list.  */
  auto_vec <context *> ascending_contexts;
  for (context *ctxt = this; ctxt; ctxt = ctxt->m_parent_ctxt)
    ascending_contexts.safe_push (ctxt);

  /* Reverse the list, giving a list of contexts from
     top-most parent context down through to youngest child context.
     We will use this list as the parameters of the functions in
     our generated file.  */
  unsigned num_ctxts = ascending_contexts.length ();
  auto_vec <context *> contexts (num_ctxts);
  for (unsigned i = 0; i < num_ctxts; i++)
    contexts.safe_push (ascending_contexts[num_ctxts - (i + 1)]);

  /* contexts[0] should be the top-level context.  */
  gcc_assert (contexts[0]);
  gcc_assert (contexts[0]->m_toplevel_ctxt == contexts[0]);

  /* The final element in contexts should be "this".  */
  gcc_assert (contexts[contexts.length () - 1] == this);
  gcc_assert (contexts[contexts.length () - 1]->m_toplevel_ctxt
	      == contexts[0]);

  r.write ("/* This code was autogenerated by"
	   " gcc_jit_context_dump_reproducer_to_file.\n\n");
  print_version (r.get_file (), "  ", false);
  r.write ("*/\n");
  r.write ("#include <libgccjit.h>\n\n");
  r.write ("#pragma GCC diagnostic ignored \"-Wunused-variable\"\n\n");
  r.write ("static void\nset_options (");
  r.write_params (contexts);
  r.write (");\n\n");
  r.write ("static void\ncreate_code (");
  r.write_params (contexts);
  r.write (");\n\n");
  r.write ("int\nmain (int argc, const char **argv)\n");
  r.write ("{\n");
  for (unsigned i = 0; i < num_ctxts; i++)
    r.write ("  gcc_jit_context *%s;\n",
	     r.get_identifier (contexts[i]));
  r.write ("  gcc_jit_result *result;\n"
	   "\n");

  /* Create the contexts.
     The top-level context is acquired from a clean slate, the others as
     children of the prior context.  */
  r.write ("  %s = gcc_jit_context_acquire ();\n",
	   r.get_identifier (contexts[0]));
  for (unsigned i = 1; i < num_ctxts; i++)
    r.write ("  %s = gcc_jit_context_new_child_context (%s);\n",
	     r.get_identifier (contexts[i]),
	     r.get_identifier (contexts[i - 1]));
  r.write ("  set_options (");
  r.write_args (contexts);
  r.write (");\n");
  r.write ("  create_code (");
  r.write_args (contexts);
  r.write (");\n");

  r.write ("  result = gcc_jit_context_compile (%s);\n",
	   r.get_identifier (this));

  for (unsigned i = num_ctxts; i > 0; i--)
    r.write ("  gcc_jit_context_release (%s);\n",
	     r.get_identifier (contexts[i - 1]));

  r.write ("  gcc_jit_result_release (result);\n"
	   "  return 0;\n"
	   "}\n\n");

  /* Define (char *) variables for use in calls to
     gcc_jit_context_enable_dump.  */
  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
    {
      if (m_requested_dumps.length ())
	{
	  r.write ("/* Requested dumps for %s.  */\n",
		   r.get_identifier (contexts[ctxt_idx]));
	  for (unsigned i = 0; i < m_requested_dumps.length (); i++)
	    r.write ("static char *dump_%p;\n",
		     (void *)&m_requested_dumps[i]);
	  r.write ("\n");
	}
    }

  /* Write out values of options.  */
  r.write ("static void\nset_options (");
  r.write_params (contexts);
  r.write (")\n{\n");
  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
    {
      if (ctxt_idx > 0)
	r.write ("\n");

      r.write ("  /* Set options for %s.  */\n",
	       r.get_identifier (contexts[ctxt_idx]));

      r.write ("  /* String options.  */\n");
      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_STR_OPTIONS; opt_idx++)
	{
	  r.write ("  gcc_jit_context_set_str_option (%s,\n"
		   "                                  %s,\n",
		   r.get_identifier (contexts[ctxt_idx]),
		   str_option_reproducer_strings[opt_idx]);
	  if (m_str_options[opt_idx])
	    r.write ("                                  \"%s\");\n",
		     m_str_options[opt_idx]);
	  else
	    r.write ("                                  NULL);\n");
	}
      r.write ("  /* Int options.  */\n");
      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_INT_OPTIONS; opt_idx++)
	r.write ("  gcc_jit_context_set_int_option (%s,\n"
		 "                                  %s,\n"
		 "                                  %i);\n",
		 r.get_identifier (contexts[ctxt_idx]),
		 int_option_reproducer_strings[opt_idx],
		 m_int_options[opt_idx]);
      r.write ("  /* Boolean options.  */\n");
      for (int opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++)
	r.write ("  gcc_jit_context_set_bool_option (%s,\n"
		 "                                  %s,\n"
		 "                                  %i);\n",
		 r.get_identifier (contexts[ctxt_idx]),
		 bool_option_reproducer_strings[opt_idx],
		 m_bool_options[opt_idx]);
      for (int opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
	r.write ("  %s (%s, %i);\n",
		 inner_bool_option_reproducer_strings[opt_idx],
		 r.get_identifier (contexts[ctxt_idx]),
		 m_inner_bool_options[opt_idx]);

      if (!m_command_line_options.is_empty ())
	{
	  int i;
	  char *optname;
	  r.write ("  /* User-provided command-line options.  */\n");
	  FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
	    r.write ("  gcc_jit_context_add_command_line_option (%s, \"%s\");\n",
		     r.get_identifier (contexts[ctxt_idx]),
		     optname);
	}

      if (!m_driver_options.is_empty ())
	{
	  int i;
	  char *optname;
	  r.write ("  /* User-provided driver options.  */\n");
	  FOR_EACH_VEC_ELT (m_driver_options, i, optname)
	    r.write ("  gcc_jit_context_add_driver_option (%s, \"%s\");\n",
		     r.get_identifier (contexts[ctxt_idx]),
		     optname);
	}

      if (m_requested_dumps.length ())
	{
	  r.write ("  /* Requested dumps.  */\n");
	  /* Dumpfiles that were requested via gcc_jit_context_enable_dump.  */
	  for (unsigned i = 0; i < m_requested_dumps.length (); i++)
	    {
	      r.write ("  gcc_jit_context_enable_dump (%s,\n"
		       "                               \"%s\",\n"
		       "                               &dump_%p);\n",
		       r.get_identifier (contexts[ctxt_idx]),
		       m_requested_dumps[i].m_dumpname,
		       (void *)&m_requested_dumps[i]);
	    }
	}
    }
  r.write ("}\n\n");

  r.write ("static void\ncreate_code (");
  r.write_params (contexts);
  r.write (")\n"
	   "{\n");
  for (unsigned ctxt_idx = 0; ctxt_idx < num_ctxts; ctxt_idx++)
    {
      memento *m;
      int i;
      if (ctxt_idx > 0)
	r.write ("\n\n");

      r.write ("  /* Replay of API calls for %s.  */\n",
	       r.get_identifier (contexts[ctxt_idx]));
      FOR_EACH_VEC_ELT (contexts[ctxt_idx]->m_mementos, i, m)
	m->write_reproducer (r);
    }
  r.write ("}\n");
}

/* Copy the requested dumps within this context and all ancestors into
   OUT. */

void
recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
{
  if (m_parent_ctxt)
    m_parent_ctxt->get_all_requested_dumps (out);

  out->reserve (m_requested_dumps.length ());
  out->splice (m_requested_dumps);
}

/* This is a pre-compilation check for the context (and any parents).

   Detect errors within the context, adding errors if any are found.  */

void
recording::context::validate ()
{
  JIT_LOG_SCOPE (get_logger ());

  if (m_parent_ctxt)
    m_parent_ctxt->validate ();

  int i;
  function *fn;
  FOR_EACH_VEC_ELT (m_functions, i, fn)
    fn->validate ();
}

/* The implementation of class gcc::jit::recording::memento.  */

/* Get a (const char *) debug description of the given memento, by
   calling the pure-virtual make_debug_string hook, caching the
   result.

   It is intended that this should only be called in debugging and
   error-handling paths, so this doesn't need to be particularly
   optimized.  */

const char *
recording::memento::get_debug_string ()
{
  if (!m_debug_string)
    m_debug_string = make_debug_string ();
  return m_debug_string->c_str ();
}

/* Default implementation of recording::memento::write_to_dump, writing
   an indented form of the memento's debug string to the dump.  */

void
recording::memento::write_to_dump (dump &d)
{
  d.write("  %s\n", get_debug_string ());
}

/* The implementation of class gcc::jit::recording::string.  */

/* Constructor for gcc::jit::recording::string::string, allocating a
   copy of the given text using new char[].  */

recording::string::string (context *ctxt, const char *text)
  : memento (ctxt)
{
  m_len = strlen (text);
  m_buffer = new char[m_len + 1];
  strcpy (m_buffer, text);
}

/* Destructor for gcc::jit::recording::string::string.  */

recording::string::~string ()
{
  delete[] m_buffer;
}

/* Function for making gcc::jit::recording::string instances on a
   context via printf-style formatting.

   It is intended that this should only be called in debugging and
   error-handling paths, so this doesn't need to be particularly
   optimized, hence the double-copy of the string is acceptable.  */

recording::string *
recording::string::from_printf (context *ctxt, const char *fmt, ...)
{
  int len;
  va_list ap;
  char *buf;
  recording::string *result;

  va_start (ap, fmt);
  len = vasprintf (&buf, fmt, ap);
  va_end (ap);

  if (buf == NULL || len < 0)
    {
      ctxt->add_error (NULL, "malloc failure");
      return NULL;
    }

  result = ctxt->new_string (buf);
  free (buf);
  return result;
}

/* Implementation of recording::memento::make_debug_string for strings,
   wrapping the given string in quotes and escaping as necessary.  */

recording::string *
recording::string::make_debug_string ()
{
  /* Hack to avoid infinite recursion into strings when logging all
     mementos: don't re-escape strings:  */
  if (m_buffer[0] == '"')
    return this;

  /* Wrap in quotes and do escaping etc */

  size_t sz = (1 /* opening quote */
	       + (m_len * 2) /* each char might get escaped */
	       + 1 /* closing quote */
	       + 1); /* nil termintator */
  char *tmp = new char[sz];
  size_t len = 0;

#define APPEND(CH)  do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
  APPEND('"'); /* opening quote */
  for (size_t i = 0; i < m_len ; i++)
    {
      char ch = m_buffer[i];
      if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
	APPEND('\\');
      APPEND(ch);
    }
  APPEND('"'); /* closing quote */
#undef APPEND
  tmp[len] = '\0'; /* nil termintator */

  string *result = m_ctxt->new_string (tmp);

  delete[] tmp;
  return result;
}

/* Implementation of recording::memento::write_reproducer for strings. */

void
recording::string::write_reproducer (reproducer &)
{
  /* Empty.  */
}

/* The implementation of class gcc::jit::recording::location.  */

/* Implementation of recording::memento::replay_into for locations.

   Create a new playback::location and store it into the
   recording::location's m_playback_obj field.  */

void
recording::location::replay_into (replayer *r)
{
  m_playback_obj = r->new_location (this,
				    m_filename->c_str (),
				    m_line,
				    m_column);
}

/* Implementation of recording::memento::make_debug_string for locations,
   turning them into the usual form:
     FILENAME:LINE:COLUMN
   like we do when emitting diagnostics.  */

recording::string *
recording::location::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s:%i:%i",
			      m_filename->c_str (), m_line, m_column);
}

/* Implementation of recording::memento::write_reproducer for locations. */

void
recording::location::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "loc");
  r.write ("  gcc_jit_location *%s =\n"
	   "    gcc_jit_context_new_location (%s, /* gcc_jit_context *ctxt */\n"
	   "    %s, /* const char *filename */\n"
	   "    %i, /* int line */\n"
	   "    %i);/* int column */\n",
	   id,
	   r.get_identifier (get_context ()),
	   m_filename->get_debug_string (),
	   m_line, m_column);
}

/* The implementation of class gcc::jit::recording::type.  */

/* Given a type T, get the type T*.

   If this doesn't already exist, generate a new memento_of_get_pointer
   instance and add it to this type's context's list of mementos.

   Otherwise, use the cached type.

   Implements the post-error-checking part of
   gcc_jit_type_get_pointer.  */

recording::type *
recording::type::get_pointer ()
{
  if (!m_pointer_to_this_type)
    {
      m_pointer_to_this_type = new memento_of_get_pointer (this);
      m_ctxt->record (m_pointer_to_this_type);
    }
  return m_pointer_to_this_type;
}

/* Given a type T, get the type const T.

   Implements the post-error-checking part of
   gcc_jit_type_get_const.  */

recording::type *
recording::type::get_const ()
{
  recording::type *result = new memento_of_get_const (this);
  m_ctxt->record (result);
  return result;
}

/* Given a type T, get the type volatile T.

   Implements the post-error-checking part of
   gcc_jit_type_get_volatile.  */

recording::type *
recording::type::get_volatile ()
{
  recording::type *result = new memento_of_get_volatile (this);
  m_ctxt->record (result);
  return result;
}

/* Given a type, get an aligned version of the type.

   Implements the post-error-checking part of
   gcc_jit_type_get_aligned.  */

recording::type *
recording::type::get_aligned (size_t alignment_in_bytes)
{
  recording::type *result
    = new memento_of_get_aligned (this, alignment_in_bytes);
  m_ctxt->record (result);
  return result;
}

/* Given a type, get a vector version of the type.

   Implements the post-error-checking part of
   gcc_jit_type_get_vector.  */

recording::type *
recording::type::get_vector (size_t num_units)
{
  recording::type *result
    = new vector_type (this, num_units);
  m_ctxt->record (result);
  return result;
}

const char *
recording::type::access_as_type (reproducer &r)
{
  return r.get_identifier (this);
}

/* Implementation of pure virtual hook recording::type::dereference for
   recording::memento_of_get_type.  */

recording::type *
recording::memento_of_get_type::dereference ()
{
  switch (m_kind)
    {
    default: gcc_unreachable ();

    case GCC_JIT_TYPE_VOID:
      return NULL;

    case GCC_JIT_TYPE_VOID_PTR:
      return m_ctxt->get_type (GCC_JIT_TYPE_VOID);

    case GCC_JIT_TYPE_BOOL:
    case GCC_JIT_TYPE_CHAR:
    case GCC_JIT_TYPE_SIGNED_CHAR:
    case GCC_JIT_TYPE_UNSIGNED_CHAR:
    case GCC_JIT_TYPE_SHORT:
    case GCC_JIT_TYPE_UNSIGNED_SHORT:
    case GCC_JIT_TYPE_INT:
    case GCC_JIT_TYPE_UNSIGNED_INT:
    case GCC_JIT_TYPE_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG:
    case GCC_JIT_TYPE_LONG_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
    case GCC_JIT_TYPE_FLOAT:
    case GCC_JIT_TYPE_DOUBLE:
    case GCC_JIT_TYPE_LONG_DOUBLE:
    case GCC_JIT_TYPE_COMPLEX_FLOAT:
    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
      /* Not a pointer: */
      return NULL;

    case GCC_JIT_TYPE_CONST_CHAR_PTR:
      return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();

    case GCC_JIT_TYPE_SIZE_T:
      /* Not a pointer: */
      return NULL;

    case GCC_JIT_TYPE_FILE_PTR:
      /* Give the client code back an opaque "struct FILE".  */
      return m_ctxt->get_opaque_FILE_type ();
    }
}

/* Implementation of pure virtual hook recording::type::is_int for
   recording::memento_of_get_type.  */

bool
recording::memento_of_get_type::is_int () const
{
  switch (m_kind)
    {
    default: gcc_unreachable ();

    case GCC_JIT_TYPE_VOID:
      return false;

    case GCC_JIT_TYPE_VOID_PTR:
      return false;

    case GCC_JIT_TYPE_BOOL:
      return false;

    case GCC_JIT_TYPE_CHAR:
    case GCC_JIT_TYPE_SIGNED_CHAR:
    case GCC_JIT_TYPE_UNSIGNED_CHAR:
    case GCC_JIT_TYPE_SHORT:
    case GCC_JIT_TYPE_UNSIGNED_SHORT:
    case GCC_JIT_TYPE_INT:
    case GCC_JIT_TYPE_UNSIGNED_INT:
    case GCC_JIT_TYPE_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG:
    case GCC_JIT_TYPE_LONG_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
      return true;

    case GCC_JIT_TYPE_FLOAT:
    case GCC_JIT_TYPE_DOUBLE:
    case GCC_JIT_TYPE_LONG_DOUBLE:
      return false;

    case GCC_JIT_TYPE_CONST_CHAR_PTR:
      return false;

    case GCC_JIT_TYPE_SIZE_T:
      return true;

    case GCC_JIT_TYPE_FILE_PTR:
      return false;

    case GCC_JIT_TYPE_COMPLEX_FLOAT:
    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
      return false;
    }
}

/* Implementation of pure virtual hook recording::type::is_float for
   recording::memento_of_get_type.  */

bool
recording::memento_of_get_type::is_float () const
{
  switch (m_kind)
    {
    default: gcc_unreachable ();

    case GCC_JIT_TYPE_VOID:
      return false;

    case GCC_JIT_TYPE_VOID_PTR:
      return false;

    case GCC_JIT_TYPE_BOOL:
      return false;

    case GCC_JIT_TYPE_CHAR:
    case GCC_JIT_TYPE_SIGNED_CHAR:
    case GCC_JIT_TYPE_UNSIGNED_CHAR:
    case GCC_JIT_TYPE_SHORT:
    case GCC_JIT_TYPE_UNSIGNED_SHORT:
    case GCC_JIT_TYPE_INT:
    case GCC_JIT_TYPE_UNSIGNED_INT:
    case GCC_JIT_TYPE_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG:
    case GCC_JIT_TYPE_LONG_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
      return false;

    case GCC_JIT_TYPE_FLOAT:
    case GCC_JIT_TYPE_DOUBLE:
    case GCC_JIT_TYPE_LONG_DOUBLE:
      return true;

    case GCC_JIT_TYPE_CONST_CHAR_PTR:
      return false;

    case GCC_JIT_TYPE_SIZE_T:
      return false;

    case GCC_JIT_TYPE_FILE_PTR:
      return false;

    case GCC_JIT_TYPE_COMPLEX_FLOAT:
    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
      return true;
    }
}

/* Implementation of pure virtual hook recording::type::is_bool for
   recording::memento_of_get_type.  */

bool
recording::memento_of_get_type::is_bool () const
{
  switch (m_kind)
    {
    default: gcc_unreachable ();

    case GCC_JIT_TYPE_VOID:
      return false;

    case GCC_JIT_TYPE_VOID_PTR:
      return false;

    case GCC_JIT_TYPE_BOOL:
      return true;

    case GCC_JIT_TYPE_CHAR:
    case GCC_JIT_TYPE_SIGNED_CHAR:
    case GCC_JIT_TYPE_UNSIGNED_CHAR:
    case GCC_JIT_TYPE_SHORT:
    case GCC_JIT_TYPE_UNSIGNED_SHORT:
    case GCC_JIT_TYPE_INT:
    case GCC_JIT_TYPE_UNSIGNED_INT:
    case GCC_JIT_TYPE_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG:
    case GCC_JIT_TYPE_LONG_LONG:
    case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
      return false;

    case GCC_JIT_TYPE_FLOAT:
    case GCC_JIT_TYPE_DOUBLE:
    case GCC_JIT_TYPE_LONG_DOUBLE:
      return false;

    case GCC_JIT_TYPE_CONST_CHAR_PTR:
      return false;

    case GCC_JIT_TYPE_SIZE_T:
      return false;

    case GCC_JIT_TYPE_FILE_PTR:
      return false;

    case GCC_JIT_TYPE_COMPLEX_FLOAT:
    case GCC_JIT_TYPE_COMPLEX_DOUBLE:
    case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
      return false;
    }
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_get_type.  */

void
recording::memento_of_get_type::replay_into (replayer *r)
{
  set_playback_obj (r->get_type (m_kind));
}

/* The implementation of class gcc::jit::recording::memento_of_get_type.  */

/* Descriptive strings for each of enum gcc_jit_types.  */

static const char * const get_type_strings[] = {
  "void",    /* GCC_JIT_TYPE_VOID */
  "void *",  /* GCC_JIT_TYPE_VOID_PTR */

  "bool",  /* GCC_JIT_TYPE_BOOL */

  "char",           /* GCC_JIT_TYPE_CHAR */
  "signed char",    /* GCC_JIT_TYPE_SIGNED_CHAR */
  "unsigned char",  /* GCC_JIT_TYPE_UNSIGNED_CHAR */

  "short",           /* GCC_JIT_TYPE_SHORT */
  "unsigned short",  /* GCC_JIT_TYPE_UNSIGNED_SHORT */

  "int",           /* GCC_JIT_TYPE_INT */
  "unsigned int",  /* GCC_JIT_TYPE_UNSIGNED_INT */

  "long",           /* GCC_JIT_TYPE_LONG  */
  "unsigned long",  /* GCC_JIT_TYPE_UNSIGNED_LONG, */

  "long long",           /* GCC_JIT_TYPE_LONG_LONG */
  "unsigned long long",  /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */

  "float",        /* GCC_JIT_TYPE_FLOAT */
  "double",       /* GCC_JIT_TYPE_DOUBLE */
  "long double",  /* GCC_JIT_TYPE_LONG_DOUBLE */

  "const char *",  /* GCC_JIT_TYPE_CONST_CHAR_PTR */

  "size_t",  /* GCC_JIT_TYPE_SIZE_T */

  "FILE *",  /* GCC_JIT_TYPE_FILE_PTR */

  "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
  "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
  "complex long double"  /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */

};

/* Implementation of recording::memento::make_debug_string for
   results of get_type, using a simple table of type names.  */

recording::string *
recording::memento_of_get_type::make_debug_string ()
{
  return m_ctxt->new_string (get_type_strings[m_kind]);
}

static const char * const get_type_enum_strings[] = {
  "GCC_JIT_TYPE_VOID",
  "GCC_JIT_TYPE_VOID_PTR",
  "GCC_JIT_TYPE_BOOL",
  "GCC_JIT_TYPE_CHAR",
  "GCC_JIT_TYPE_SIGNED_CHAR",
  "GCC_JIT_TYPE_UNSIGNED_CHAR",
  "GCC_JIT_TYPE_SHORT",
  "GCC_JIT_TYPE_UNSIGNED_SHORT",
  "GCC_JIT_TYPE_INT",
  "GCC_JIT_TYPE_UNSIGNED_INT",
  "GCC_JIT_TYPE_LONG",
  "GCC_JIT_TYPE_UNSIGNED_LONG",
  "GCC_JIT_TYPE_LONG_LONG",
  "GCC_JIT_TYPE_UNSIGNED_LONG_LONG",
  "GCC_JIT_TYPE_FLOAT",
  "GCC_JIT_TYPE_DOUBLE",
  "GCC_JIT_TYPE_LONG_DOUBLE",
  "GCC_JIT_TYPE_CONST_CHAR_PTR",
  "GCC_JIT_TYPE_SIZE_T",
  "GCC_JIT_TYPE_FILE_PTR",
  "GCC_JIT_TYPE_COMPLEX_FLOAT",
  "GCC_JIT_TYPE_COMPLEX_DOUBLE",
  "GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE"
};

void
recording::memento_of_get_type::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s = gcc_jit_context_get_type (%s, %s);\n",
	   id,
	   r.get_identifier (get_context ()),
	   get_type_enum_strings[m_kind]);
}

/* The implementation of class gcc::jit::recording::memento_of_get_pointer.  */

/* Override of default implementation of
   recording::type::accepts_writes_from for get_pointer.

   Require a pointer type, and allowing writes to
   (const T *) from a (T*), but not the other way around.  */

bool
recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
{
  /* Must be a pointer type: */
  type *rtype_points_to = rtype->is_pointer ();
  if (!rtype_points_to)
    return false;

  /* It's OK to assign to a (const T *) from a (T *).  */
  return m_other_type->unqualified ()
    ->accepts_writes_from (rtype_points_to);
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_get_pointer.  */

void
recording::memento_of_get_pointer::replay_into (replayer *)
{
  set_playback_obj (m_other_type->playback_type ()->get_pointer ());
}

/* Implementation of recording::memento::make_debug_string for
   results of get_pointer, adding " *" to the underlying type,
   with special-casing to handle function pointer types.  */

recording::string *
recording::memento_of_get_pointer::make_debug_string ()
{
  /* Special-case function pointer types, to put the "*" in parens between
     the return type and the params (for one level of dereferencing, at
     least).  */
  if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
    return fn_type->make_debug_string_with_ptr ();

  return string::from_printf (m_ctxt,
			      "%s *", m_other_type->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for get_pointer.  */

void
recording::memento_of_get_pointer::write_reproducer (reproducer &r)
{
  /* We need to special-case function pointer types; see the notes in
     recording::function_type::write_deferred_reproducer.  */
  if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
    {
      fn_type->write_deferred_reproducer (r, this);
      return;
    }

  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_type_get_pointer (%s);\n",
	   id,
	   r.get_identifier_as_type (m_other_type));
}

/* The implementation of class gcc::jit::recording::memento_of_get_const.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_get_const.  */

void
recording::memento_of_get_const::replay_into (replayer *)
{
  set_playback_obj (m_other_type->playback_type ()->get_const ());
}

/* Implementation of recording::memento::make_debug_string for
   results of get_const, prepending "const ".  */

recording::string *
recording::memento_of_get_const::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "const %s", m_other_type->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for const types. */

void
recording::memento_of_get_const::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_type_get_const (%s);\n",
	   id,
	   r.get_identifier_as_type (m_other_type));
}

/* The implementation of class gcc::jit::recording::memento_of_get_volatile.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_get_volatile.  */

void
recording::memento_of_get_volatile::replay_into (replayer *)
{
  set_playback_obj (m_other_type->playback_type ()->get_volatile ());
}

/* Implementation of recording::memento::make_debug_string for
   results of get_volatile, prepending "volatile ".  */

recording::string *
recording::memento_of_get_volatile::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "volatile %s", m_other_type->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for volatile
   types. */

void
recording::memento_of_get_volatile::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_type_get_volatile (%s);\n",
	   id,
	   r.get_identifier_as_type (m_other_type));
}

/* The implementation of class gcc::jit::recording::memento_of_get_aligned.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_get_aligned.  */

void
recording::memento_of_get_aligned::replay_into (replayer *)
{
  set_playback_obj
    (m_other_type->playback_type ()->get_aligned (m_alignment_in_bytes));
}

/* Implementation of recording::memento::make_debug_string for
   results of get_aligned.  */

recording::string *
recording::memento_of_get_aligned::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s  __attribute__((aligned(%zi)))",
			      m_other_type->get_debug_string (),
			      m_alignment_in_bytes);
}

/* Implementation of recording::memento::write_reproducer for aligned
   types. */

void
recording::memento_of_get_aligned::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_type_get_aligned (%s, %zi);\n",
	   id,
	   r.get_identifier_as_type (m_other_type),
	   m_alignment_in_bytes);
}

/* The implementation of class gcc::jit::recording::vector_type.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::vector_type.  */

void
recording::vector_type::replay_into (replayer *)
{
  set_playback_obj
    (m_other_type->playback_type ()->get_vector (m_num_units));
}

/* Implementation of recording::memento::make_debug_string for
   results of get_vector.  */

recording::string *
recording::vector_type::make_debug_string ()
{
  return string::from_printf
    (m_ctxt,
     "%s  __attribute__((vector_size(sizeof (%s) * %zi)))",
     m_other_type->get_debug_string (),
     m_other_type->get_debug_string (),
     m_num_units);
}

/* Implementation of recording::memento::write_reproducer for vector types. */

void
recording::vector_type::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_type_get_vector (%s, %zi);\n",
	   id,
	   r.get_identifier_as_type (m_other_type),
	   m_num_units);
}

/* The implementation of class gcc::jit::recording::array_type */

/* Implementation of pure virtual hook recording::type::dereference for
   recording::array_type.  */

recording::type *
recording::array_type::dereference ()
{
  return m_element_type;
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::array_type.  */

void
recording::array_type::replay_into (replayer *r)
{
  set_playback_obj (r->new_array_type (playback_location (r, m_loc),
				       m_element_type->playback_type (),
				       m_num_elements));
}

/* Implementation of recording::memento::make_debug_string for
   results of new_array_type.  */

recording::string *
recording::array_type::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s[%d]",
			      m_element_type->get_debug_string (),
			      m_num_elements);
}

/* Implementation of recording::memento::write_reproducer for array
   types. */

void
recording::array_type::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "array_type");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_context_new_array_type (%s,\n"
	   "                                    %s, /* gcc_jit_location *loc */\n"
	   "                                    %s, /* gcc_jit_type *element_type */\n"
	   "                                    %i); /* int num_elements */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_type (m_element_type),
	   m_num_elements);
}

/* The implementation of class gcc::jit::recording::function_type */

/* Constructor for gcc::jit::recording::function_type.  */

recording::function_type::function_type (context *ctxt,
					 type *return_type,
					 int num_params,
					 type **param_types,
					 int is_variadic)
: type (ctxt),
  m_return_type (return_type),
  m_param_types (),
  m_is_variadic (is_variadic)
{
  for (int i = 0; i< num_params; i++)
    m_param_types.safe_push (param_types[i]);
}

/* Implementation of pure virtual hook recording::type::dereference for
   recording::function_type.  */

recording::type *
recording::function_type::dereference ()
{
  return NULL;
}

/* Implementation of virtual hook recording::type::is_same_type_as for
   recording::function_type.

   We override this to avoid requiring identity of function pointer types,
   so that if client code has obtained the same signature in
   different ways (e.g. via gcc_jit_context_new_function_ptr_type
   vs gcc_jit_function_get_address), the different function_type
   instances are treated as compatible.

   We can't use type::accepts_writes_from for this as we need a stronger
   notion of "sameness": if we have a fn_ptr type that has args that are
   themselves fn_ptr types, then those args still need to match exactly.

   Alternatively, we could consolidate attempts to create identical
   function_type instances so that pointer equality works, but that runs
   into issues about the lifetimes of the cache (w.r.t. nested contexts).  */

bool
recording::function_type::is_same_type_as (type *other)
{
  gcc_assert (other);

  function_type *other_fn_type = other->dyn_cast_function_type ();
  if (!other_fn_type)
    return false;

  /* Everything must match.  */

  if (!m_return_type->is_same_type_as (other_fn_type->m_return_type))
    return false;

  if (m_param_types.length () != other_fn_type->m_param_types.length ())
    return false;

  unsigned i;
  type *param_type;
  FOR_EACH_VEC_ELT (m_param_types, i, param_type)
    if (!param_type->is_same_type_as (other_fn_type->m_param_types[i]))
      return false;

  if (m_is_variadic != other_fn_type->m_is_variadic)
    return false;

  /* Passed all tests.  */
  return true;
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::function_type.  */

void
recording::function_type::replay_into (replayer *r)
{
  /* Convert m_param_types to a vec of playback type.  */
  auto_vec <playback::type *> param_types;
  int i;
  recording::type *type;
  param_types.create (m_param_types.length ());
  FOR_EACH_VEC_ELT (m_param_types, i, type)
    param_types.safe_push (type->playback_type ());

  set_playback_obj (r->new_function_type (m_return_type->playback_type (),
					  &param_types,
					  m_is_variadic));
}

/* Special-casing for make_debug_string for get_pointer results for
   handling (one level) of pointers to functions.  */

recording::string *
recording::function_type::make_debug_string_with_ptr ()
{
  return make_debug_string_with ("(*) ");
}

/* Implementation of recording::memento::make_debug_string for
   results of new_function_type.  */

recording::string *
recording::function_type::make_debug_string ()
{
  return make_debug_string_with ("");
}

/* Build a debug string representation of the form:

     RESULT_TYPE INSERT (PARAM_TYPES)

   for use when handling 0 and 1 level of indirection to this
   function type.  */

recording::string *
recording::function_type::make_debug_string_with (const char *insert)
{
  /* First, build a buffer for the arguments.  */
  /* Calculate length of said buffer.  */
  size_t sz = 1; /* nil terminator */
  for (unsigned i = 0; i< m_param_types.length (); i++)
    {
      sz += strlen (m_param_types[i]->get_debug_string ());
      sz += 2; /* ", " separator */
    }
  if (m_is_variadic)
    sz += 5; /* ", ..." separator and ellipsis */

  /* Now allocate and populate the buffer.  */
  char *argbuf = new char[sz];
  size_t len = 0;

  for (unsigned i = 0; i< m_param_types.length (); i++)
    {
      strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
      len += strlen (m_param_types[i]->get_debug_string ());
      if (i + 1 < m_param_types.length ())
	{
	  strcpy (argbuf + len, ", ");
	  len += 2;
	}
    }
  if (m_is_variadic)
    {
      if (m_param_types.length ())
	{
	  strcpy (argbuf + len, ", ");
	  len += 2;
	}
      strcpy (argbuf + len, "...");
      len += 3;
    }
  argbuf[len] = '\0';

  /* ...and use it to get the string for the call as a whole.  */
  string *result = string::from_printf (m_ctxt,
					"%s %s(%s)",
					m_return_type->get_debug_string (),
					insert,
					argbuf);

  delete[] argbuf;

  return result;
}

/* Implementation of recording::memento::write_reproducer for function
   types.  */

void
recording::function_type::write_reproducer (reproducer &)
{
  /* see notes below.  */
}

/* There's a get_pointer within context::new_function_ptr_type:
   the type received by client code isn't the memento for the
   function_type, but instead the result of get_pointer on it.

   Hence we can't directly write a reproducer that gives function_type.
   Instead we special-case things within get_pointer, detecting this
   case, calling the following function.  */

void
recording::function_type::write_deferred_reproducer (reproducer &r,
						     memento *ptr_type)
{
  gcc_assert (ptr_type);
  r.make_identifier (this, "function_type");
  const char *ptr_id = r.make_identifier (ptr_type, "ptr_to");
  const char *param_types_id = r.make_tmp_identifier ("params_for", this);
  r.write ("  gcc_jit_type *%s[%i] = {\n",
	   param_types_id,
	   m_param_types.length ());
  int i;
  type *param_type;
  FOR_EACH_VEC_ELT (m_param_types, i, param_type)
    r.write ("    %s,\n", r.get_identifier_as_type (param_type));
  r.write ("  };\n");
  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_context_new_function_ptr_type (%s, /* gcc_jit_context *ctxt */\n"
	   "                                           %s, /* gcc_jit_location *loc */\n"
	   "                                           %s, /* gcc_jit_type *return_type */\n"
	   "                                           %i, /* int num_params */\n"
	   "                                           %s, /* gcc_jit_type **param_types */\n"
	   "                                           %i); /* int is_variadic */\n",
	   ptr_id,
	   r.get_identifier (get_context ()),
	   "NULL", /* location is not stored */
	   r.get_identifier_as_type (m_return_type),
	   m_param_types.length (),
	   param_types_id,
	   m_is_variadic);
}

/* The implementation of class gcc::jit::recording::field.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::field.  */

void
recording::field::replay_into (replayer *r)
{
  set_playback_obj (r->new_field (playback_location (r, m_loc),
				  m_type->playback_type (),
				  playback_string (m_name)));
}

/* Override the default implementation of
   recording::memento::write_to_dump.  Dump each field
   by dumping a line of the form:
      TYPE NAME;
   so that we can build up a struct/union field-byfield.  */

void
recording::field::write_to_dump (dump &d)
{
  d.write ("  %s %s;\n",
	   m_type->get_debug_string (),
	   m_name->c_str ());
}

/* Implementation of recording::memento::make_debug_string for
   results of new_field.  */

recording::string *
recording::field::make_debug_string ()
{
  return m_name;
}

/* Implementation of recording::memento::write_reproducer for fields.  */

void
recording::field::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "field");
  r.write("  gcc_jit_field *%s =\n"
	  "    gcc_jit_context_new_field (%s,\n"
	  "                               %s, /* gcc_jit_location *loc */\n"
	  "                               %s, /* gcc_jit_type *type, */\n"
	  "                               %s); /* const char *name */\n",
	  id,
	  r.get_identifier (get_context ()),
	  r.get_identifier (m_loc),
	  r.get_identifier_as_type (m_type),
	  m_name->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::compound_type */

/* The constructor for gcc::jit::recording::compound_type.  */

recording::compound_type::compound_type (context *ctxt,
					 location *loc,
					 string *name)
: type (ctxt),
  m_loc (loc),
  m_name (name),
  m_fields (NULL)
{
}

/* Set the fields of a compound type.

   Implements the post-error-checking part of
   gcc_jit_struct_set_fields, and is also used by
   gcc_jit_context_new_union_type.  */

void
recording::compound_type::set_fields (location *loc,
				      int num_fields,
				      field **field_array)
{
  m_loc = loc;
  gcc_assert (m_fields == NULL);

  m_fields = new fields (this, num_fields, field_array);
  m_ctxt->record (m_fields);
}

/* Implementation of pure virtual hook recording::type::dereference for
   recording::compound_type.  */

recording::type *
recording::compound_type::dereference ()
{
  return NULL; /* not a pointer */
}

/* The implementation of class gcc::jit::recording::struct_.  */

/* The constructor for gcc::jit::recording::struct_.  */

recording::struct_::struct_ (context *ctxt,
			     location *loc,
			     string *name)
: compound_type (ctxt, loc, name)
{
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::struct_.  */

void
recording::struct_::replay_into (replayer *r)
{
  set_playback_obj (
    r->new_compound_type (playback_location (r, get_loc ()),
			  get_name ()->c_str (),
			  true /* is_struct */));
}

const char *
recording::struct_::access_as_type (reproducer &r)
{
  return r.xstrdup_printf ("gcc_jit_struct_as_type (%s)",
			   r.get_identifier (this));
}

/* Implementation of recording::memento::make_debug_string for
   structs.  */

recording::string *
recording::struct_::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "struct %s", get_name ()->c_str ());
}

void
recording::struct_::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "struct");
  r.write ("  gcc_jit_struct *%s =\n"
	   "    gcc_jit_context_new_opaque_struct (%s,\n"
	   "                                       %s, /* gcc_jit_location *loc */\n"
	   "                                       %s); /* const char *name */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (get_loc ()),
	   get_name ()->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::union_.  */

/* The constructor for gcc::jit::recording::union_.  */

recording::union_::union_ (context *ctxt,
			   location *loc,
			   string *name)
: compound_type (ctxt, loc, name)
{
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::union_.  */

void
recording::union_::replay_into (replayer *r)
{
  set_playback_obj (
    r->new_compound_type (playback_location (r, get_loc ()),
			  get_name ()->c_str (),
			  false /* is_struct */));
}

/* Implementation of recording::memento::make_debug_string for
   unions.  */

recording::string *
recording::union_::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "union %s", get_name ()->c_str ());
}

/* Implementation of recording::memento::write_reproducer for unions.  */

void
recording::union_::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "union");

  const char *fields_id = r.make_tmp_identifier ("fields_for", this);
  r.write ("  gcc_jit_field *%s[%i] = {\n",
	   fields_id,
	   get_fields ()->length ());
  for (int i = 0; i < get_fields ()->length (); i++)
    r.write ("    %s,\n", r.get_identifier (get_fields ()->get_field (i)));
  r.write ("  };\n");

  r.write ("  gcc_jit_type *%s =\n"
	   "    gcc_jit_context_new_union_type (%s,\n"
	   "                                    %s, /* gcc_jit_location *loc */\n"
	   "                                    %s, /* const char *name */\n"
	   "                                    %i, /* int num_fields */\n"
	   "                                    %s); /* gcc_jit_field **fields */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (get_loc ()),
	   get_name ()->get_debug_string (),
	   get_fields ()->length (),
	   fields_id);
}

/* The implementation of class gcc::jit::recording::fields.  */

/* The constructor for gcc::jit::recording::fields.  */

recording::fields::fields (compound_type *struct_or_union,
			   int num_fields,
			   field **fields)
: memento (struct_or_union->m_ctxt),
  m_struct_or_union (struct_or_union),
  m_fields ()
{
  for (int i = 0; i < num_fields; i++)
    {
      gcc_assert (fields[i]->get_container () == NULL);
      fields[i]->set_container (m_struct_or_union);
      m_fields.safe_push (fields[i]);
    }
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::fields.  */

void
recording::fields::replay_into (replayer *)
{
  auto_vec<playback::field *> playback_fields;
  playback_fields.create (m_fields.length ());
  for (unsigned i = 0; i < m_fields.length (); i++)
    playback_fields.safe_push (m_fields[i]->playback_field ());
  m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
}

/* Override the default implementation of
   recording::memento::write_to_dump by writing a union/struct
   declaration of this form:

      struct/union NAME {
	TYPE_1 NAME_1;
	TYPE_2 NAME_2;
	....
	TYPE_N NAME_N;
      };

    to the dump.  */

void
recording::fields::write_to_dump (dump &d)
{
  int i;
  field *f;

  d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
  FOR_EACH_VEC_ELT (m_fields, i, f)
    f->write_to_dump (d);
  d.write ("};\n");
}

/* Implementation of recording::memento::write_reproducer for the fields
   subclass.  */

void
recording::fields::write_reproducer (reproducer &r)
{
  if (m_struct_or_union)
    if (m_struct_or_union->dyn_cast_struct () == NULL)
      /* We have a union; the fields have already been written by
	 union::write_reproducer.  */
      return;

  const char *fields_id = r.make_identifier (this, "fields");
  r.write ("  gcc_jit_field *%s[%i] = {\n",
	   fields_id,
	   m_fields.length ());
  int i;
  field *field;
  FOR_EACH_VEC_ELT (m_fields, i, field)
    r.write ("    %s,\n", r.get_identifier (field));
  r.write ("  };\n");

  r.write ("  gcc_jit_struct_set_fields (%s, /* gcc_jit_struct *struct_type */\n"
	   "                             %s, /* gcc_jit_location *loc */\n"
	   "                             %i, /* int num_fields */\n"
	   "                             %s); /* gcc_jit_field **fields */\n",
	   r.get_identifier (m_struct_or_union),
	   r.get_identifier ((memento *)NULL),
	   m_fields.length (),
	   fields_id);
}

/* Implementation of recording::memento::make_debug_string for
   field tables.  */

recording::string *
recording::fields::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "fields");
}

/* The implementation of class gcc::jit::recording::rvalue.  */

/* Create a recording::access_field_rvalue instance and add it to
   the rvalue's context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_rvalue_access_field.  */

recording::rvalue *
recording::rvalue::access_field (recording::location *loc,
				 field *field)
{
  recording::rvalue *result =
    new access_field_rvalue (m_ctxt, loc, this, field);
  m_ctxt->record (result);
  return result;
}

/* Create a recording::dereference_field_rvalue instance and add it to
   the rvalue's context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_rvalue_dereference_field.  */

recording::lvalue *
recording::rvalue::dereference_field (recording::location *loc,
				      field *field)
{
  recording::lvalue *result =
    new dereference_field_rvalue (m_ctxt, loc, this, field);
  m_ctxt->record (result);
  return result;
}

/* Create a recording::dereference_rvalue instance and add it to the
   rvalue's context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_rvalue_dereference.  */

recording::lvalue *
recording::rvalue::dereference (recording::location *loc)
{
  recording::lvalue *result =
    new dereference_rvalue (m_ctxt, loc, this);
  m_ctxt->record (result);
  return result;
}

/* An rvalue visitor, for validating that every rvalue within an expression
   trees within "STMT" has the correct scope (e.g. no access to locals
   of a different function).  */

class rvalue_usage_validator : public recording::rvalue_visitor
{
 public:
  rvalue_usage_validator (const char *api_funcname,
			  recording::context *ctxt,
			  recording::statement *stmt);

  void
  visit (recording::rvalue *rvalue) FINAL OVERRIDE;

 private:
  const char *m_api_funcname;
  recording::context *m_ctxt;
  recording::statement *m_stmt;
};

/* The trivial constructor for rvalue_usage_validator.  */

rvalue_usage_validator::rvalue_usage_validator (const char *api_funcname,
						recording::context *ctxt,
						recording::statement *stmt)
  : m_api_funcname (api_funcname),
    m_ctxt (ctxt),
    m_stmt (stmt)
{
}

/* Verify that the given rvalue is in the correct scope.  */

void
rvalue_usage_validator::visit (recording::rvalue *rvalue)
{
  gcc_assert (m_stmt->get_block ());
  recording::function *stmt_scope = m_stmt->get_block ()->get_function ();

  /* Most rvalues don't have a scope (only locals and params).  */
  if (rvalue->get_scope ())
    {
      if (rvalue->get_scope () != stmt_scope)
	m_ctxt->add_error
	  (rvalue->get_loc (),
	   "%s:"
	   " rvalue %s (type: %s)"
	   " has scope limited to function %s"
	   " but was used within function %s"
	   " (in statement: %s)",
	   m_api_funcname,
	   rvalue->get_debug_string (),
	   rvalue->get_type ()->get_debug_string (),
	   rvalue->get_scope ()->get_debug_string (),
	   stmt_scope->get_debug_string (),
	   m_stmt->get_debug_string ());
    }
  else
    {
      if (rvalue->dyn_cast_param ())
	m_ctxt->add_error
	  (rvalue->get_loc (),
	   "%s:"
	   " param %s (type: %s)"
	   " was used within function %s"
	   " (in statement: %s)"
	   " but is not associated with any function",
	   m_api_funcname,
	   rvalue->get_debug_string (),
	   rvalue->get_type ()->get_debug_string (),
	   stmt_scope->get_debug_string (),
	   m_stmt->get_debug_string ());
    }
}

/* Verify that it's valid to use this rvalue (and all expressions
   in the tree below it) within the given statement.

   For example, we must reject attempts to use a local from one
   function within a different function here, or we'll get
   an ICE deep inside toplev::main.  */

void
recording::rvalue::verify_valid_within_stmt (const char *api_funcname, statement *s)
{
  rvalue_usage_validator v (api_funcname,
			    s->get_context (),
			    s);

  /* Verify that it's OK to use this rvalue within s.  */
  v.visit (this);

  /* Traverse the expression tree below "this", verifying all rvalues
     within it.  */
  visit_children (&v);
}

/* Set the scope of this rvalue to be the given function.  This can only
   be done once on a given rvalue.  */

void
recording::rvalue::set_scope (function *scope)
{
  gcc_assert (scope);
  gcc_assert (m_scope == NULL);
  m_scope = scope;
}


/* Implementation of recording::rvalue::access_as_rvalue for rvalues
   themselves.
   Instances of rvalue don't need an upcast call.  */

const char *
recording::rvalue::access_as_rvalue (reproducer &r)
{
  return r.get_identifier (this);
}

/* Return a debug string for the given rvalue, wrapping it in parentheses
   if needed to mimic C's precedence rules, i.e. if OUTER_PREC is of
   stronger precedence that this rvalue's precedence.

   For example, given:

           MULT
          /    \
       PLUS     MINUS
      /    \   /     \
     A      B C       D

   we want to emit:

     (A + B) * (C - D)

   since MULT has strong precedence than PLUS and MINUS, whereas for:

           PLUS
          /    \
       MULT     DIVIDE
      /    \   /      \
     A      B C        D

   we can simply emit:

     A * B + C / D

   since PLUS has weaker precedence than MULT and DIVIDE.  */

const char *
recording::rvalue::get_debug_string_parens (enum precedence outer_prec)
{
  enum precedence this_prec = get_precedence ();

  /* If this_prec has stronger precedence than outer_prec, we don't
     need to wrap this in parens within the outer debug string.
     Stronger precedences occur earlier than weaker within the enum,
     so this is a less than test.  Equal precedences don't need
     parentheses.  */
  if (this_prec <= outer_prec)
    return get_debug_string();

  /* Otherwise, we need parentheses.  */

  /* Lazily-build and cache m_parenthesized_string.  */
  if (!m_parenthesized_string)
    {
      const char *debug_string = get_debug_string ();
      m_parenthesized_string = string::from_printf (get_context (),
						    "(%s)",
						    debug_string);
    }
  gcc_assert (m_parenthesized_string);
  return m_parenthesized_string->c_str ();
}


/* The implementation of class gcc::jit::recording::lvalue.  */

/* Create a recording::new_access_field_of_lvalue instance and add it to
   the lvalue's context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_lvalue_access_field.  */

recording::lvalue *
recording::lvalue::access_field (recording::location *loc,
				 field *field)
{
  recording::lvalue *result =
    new access_field_of_lvalue (m_ctxt, loc, this, field);
  m_ctxt->record (result);
  return result;
}

/* Implementation of recording::rvalue::access_as_rvalue for lvalues.
   Instances of lvalue need to be wrapped in a gcc_jit_lvalue_as_rvalue
   upcast call.  */

const char *
recording::lvalue::access_as_rvalue (reproducer &r)
{
  return r.xstrdup_printf ("gcc_jit_lvalue_as_rvalue (%s)",
			   r.get_identifier (this));
}

/* Implementation of recording::lvalue::access_as_lvalue for lvalues.
   Instances of lvalue don't need to be upcast.  */

const char *
recording::lvalue::access_as_lvalue (reproducer &r)
{
  return r.get_identifier (this);
}

/* Create a recording::get_address_of_lvalue instance and add it to
   the lvalue's context's list of mementos.

   Implements the post-error-checking part of
   gcc_jit_lvalue_get_address.  */

recording::rvalue *
recording::lvalue::get_address (recording::location *loc)
{
  recording::rvalue *result =
    new get_address_of_lvalue (m_ctxt, loc, this);
  m_ctxt->record (result);
  return result;
}

/* The implementation of class gcc::jit::recording::param.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::param.  */

void
recording::param::replay_into (replayer *r)
{
  set_playback_obj (r->new_param (playback_location (r, m_loc),
				  m_type->playback_type (),
				  m_name->c_str ()));
}

/* Implementation of recording::rvalue::access_as_rvalue for params.
   Instances of param need to be wrapped in a gcc_jit_param_as_rvalue
   upcast call.  */

const char *
recording::param::access_as_rvalue (reproducer &r)
{
  return r.xstrdup_printf ("gcc_jit_param_as_rvalue (%s)",
			   r.get_identifier (this));
}

/* Implementation of recording::lvalue::access_as_lvalue for params.
   Instances of param need to be wrapped in a gcc_jit_param_as_lvalue
   upcast call.  */

const char *
recording::param::access_as_lvalue (reproducer &r)
{
  return r.xstrdup_printf ("gcc_jit_param_as_lvalue (%s)",
			   r.get_identifier (this));
}

/* Implementation of recording::memento::write_reproducer for params. */

void
recording::param::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "param");
  r.write ("  gcc_jit_param *%s =\n"
	   "    gcc_jit_context_new_param (%s,\n"
	   "                               %s, /* gcc_jit_location *loc */\n"
	   "                               %s, /*gcc_jit_type *type */\n"
	   "                               %s); /* const char *name */\n",
	   id,
    r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_type (m_type),
	   m_name->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::function.  */

/* gcc::jit::recording::function's constructor.  */

recording::function::function (context *ctxt,
			       recording::location *loc,
			       enum gcc_jit_function_kind kind,
			       type *return_type,
			       recording::string *name,
			       int num_params,
			       recording::param **params,
			       int is_variadic,
			       enum built_in_function builtin_id)
: memento (ctxt),
  m_loc (loc),
  m_kind (kind),
  m_return_type (return_type),
  m_name (name),
  m_params (),
  m_is_variadic (is_variadic),
  m_builtin_id (builtin_id),
  m_locals (),
  m_blocks (),
  m_fn_ptr_type (NULL)
{
  for (int i = 0; i< num_params; i++)
    {
      param *param = params[i];
      gcc_assert (param);

      /* Associate each param with this function.

	 Verify that the param doesn't already have a function.  */
      if (param->get_scope ())
	{
	  /* We've already rejected attempts to reuse a param between
	     different functions (within gcc_jit_context_new_function), so
	     if the param *does* already have a function, it must be being
	     reused within the params array for this function.  We must
	     produce an error for this reuse (blocking the compile), since
	     otherwise we'd have an ICE later on.  */
	  gcc_assert (this == param->get_scope ());
	  ctxt->add_error
	    (loc,
	     "gcc_jit_context_new_function:"
	     " parameter %s (type: %s)"
	     " is used more than once when creating function %s",
	     param->get_debug_string (),
	     param->get_type ()->get_debug_string (),
	     name->c_str ());
	}
      else
	{
	  /* The normal, non-error case: associate this function with the
	     param.  */
	  param->set_scope (this);
	}

      m_params.safe_push (param);
    }
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::function.  */

void
recording::function::replay_into (replayer *r)
{
  /* Convert m_params to a vec of playback param.  */
  auto_vec <playback::param *> params;
  int i;
  recording::param *param;
  params.create (m_params.length ());
  FOR_EACH_VEC_ELT (m_params, i, param)
    params.safe_push (param->playback_param ());

  set_playback_obj (r->new_function (playback_location (r, m_loc),
				     m_kind,
				     m_return_type->playback_type (),
				     m_name->c_str (),
				     &params,
				     m_is_variadic,
				     m_builtin_id));
}

/* Create a recording::local instance and add it to
   the functions's context's list of mementos, and to the function's
   list of locals.

   Implements the post-error-checking part of
   gcc_jit_function_new_local.  */

recording::lvalue *
recording::function::new_local (recording::location *loc,
				type *type,
				const char *name)
{
  local *result = new local (this, loc, type, new_string (name));
  m_ctxt->record (result);
  m_locals.safe_push (result);
  return result;
}

/* Create a recording::block instance and add it to
   the functions's context's list of mementos, and to the function's
   list of blocks.

   Implements the post-error-checking part of
   gcc_jit_function_new_block.  */

recording::block*
recording::function::new_block (const char *name)
{
  gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);

  recording::block *result =
    new recording::block (this, m_blocks.length (), new_string (name));
  m_ctxt->record (result);
  m_blocks.safe_push (result);
  return result;
}

/* Override the default implementation of
   recording::memento::write_to_dump by dumping a C-like
   representation of the function; either like a prototype
   for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
   all other kinds of function.  */

void
recording::function::write_to_dump (dump &d)
{
  switch (m_kind)
    {
    default: gcc_unreachable ();
    case GCC_JIT_FUNCTION_EXPORTED:
    case GCC_JIT_FUNCTION_IMPORTED:
      d.write ("extern ");
      break;
    case GCC_JIT_FUNCTION_INTERNAL:
      d.write ("static ");
      break;
    case GCC_JIT_FUNCTION_ALWAYS_INLINE:
      d.write ("static inline ");
      break;
     }
  d.write ("%s\n", m_return_type->get_debug_string ());

  if (d.update_locations ())
    m_loc = d.make_location ();

  d.write ("%s (", get_debug_string ());

  int i;
  recording::param *param;
  FOR_EACH_VEC_ELT (m_params, i, param)
    {
      if (i > 0)
	d.write (", ");
      d.write ("%s %s",
	       param->get_type ()->get_debug_string (),
	       param->get_debug_string ());
    }
  d.write (")");
  if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
    {
      d.write ("; /* (imported) */\n\n");
    }
  else
    {
      int i;
      local *var = NULL;
      block *b;
      d.write ("\n{\n");

      /* Write locals: */
      FOR_EACH_VEC_ELT (m_locals, i, var)
	var->write_to_dump (d);
      if (m_locals.length ())
	d.write ("\n");

      /* Write each block: */
      FOR_EACH_VEC_ELT (m_blocks, i, b)
	{
	  if (i > 0)
	    d.write ("\n");
	  b->write_to_dump (d);
	}

      d.write ("}\n\n");
    }
}

/* Pre-compilation validation of a function, for those things we can't
   check until the context is (supposedly) fully-populated.  */

void
recording::function::validate ()
{
  /* Complain about empty functions with non-void return type.  */
  if (m_kind != GCC_JIT_FUNCTION_IMPORTED
      && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
    if (m_blocks.length () == 0)
      m_ctxt->add_error (m_loc,
			 "function %s returns non-void (type: %s)"
			 " but has no blocks",
			 get_debug_string (),
			 m_return_type->get_debug_string ());

  /* Check that all blocks are terminated.  */
  int num_invalid_blocks = 0;
  {
    int i;
    block *b;

    FOR_EACH_VEC_ELT (m_blocks, i, b)
      if (!b->validate ())
	num_invalid_blocks++;
  }

  /* Check that all blocks are reachable.  */
  if (!m_ctxt->get_inner_bool_option
        (INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS)
      && m_blocks.length () > 0 && num_invalid_blocks == 0)
    {
      /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
	 flag, starting at the initial block.  */
      auto_vec<block *> worklist (m_blocks.length ());
      worklist.safe_push (m_blocks[0]);
      while (worklist.length () > 0)
	{
	  block *b = worklist.pop ();
	  b->m_is_reachable = true;

	  /* Add successor blocks that aren't yet marked to the worklist.  */
	  /* We checked that each block has a terminating statement above .  */
	  vec <block *> successors = b->get_successor_blocks ();
	  int i;
	  block *succ;
	  FOR_EACH_VEC_ELT (successors, i, succ)
	    if (!succ->m_is_reachable)
	      worklist.safe_push (succ);
	  successors.release ();
	}

      /* Now complain about any blocks that haven't been marked.  */
      {
	int i;
	block *b;
	FOR_EACH_VEC_ELT (m_blocks, i, b)
	  if (!b->m_is_reachable)
	    m_ctxt->add_error (b->get_loc (),
			       "unreachable block: %s",
			       b->get_debug_string ());
      }
    }
}

/* Implements the post-error-checking part of
   gcc_jit_function_dump_to_dot.  */

void
recording::function::dump_to_dot (const char *path)
{
  FILE *fp  = fopen (path, "w");
  if (!fp)
    return;

  pretty_printer the_pp;
  the_pp.buffer->stream = fp;

  pretty_printer *pp = &the_pp;

  pp_printf (pp,
	     "digraph %s {\n", get_debug_string ());

  /* Blocks: */
  {
    int i;
    block *b;
    FOR_EACH_VEC_ELT (m_blocks, i, b)
      b->dump_to_dot (pp);
  }

  /* Edges: */
  {
    int i;
    block *b;
    FOR_EACH_VEC_ELT (m_blocks, i, b)
      b->dump_edges_to_dot (pp);
  }

  pp_printf (pp, "}\n");
  pp_flush (pp);
  fclose (fp);
}

/* Implements the post-error-checking part of
   gcc_jit_function_get_address.  */

recording::rvalue *
recording::function::get_address (recording::location *loc)
{
  /* Lazily create and cache the function pointer type.  */
  if (!m_fn_ptr_type)
    {
      /* Make a recording::function_type for this function.  */
      auto_vec <recording::type *> param_types (m_params.length ());
      unsigned i;
      recording::param *param;
      FOR_EACH_VEC_ELT (m_params, i, param)
	param_types.safe_push (param->get_type ());
      recording::function_type *fn_type
	= m_ctxt->new_function_type (m_return_type,
				     m_params.length (),
				     param_types.address (),
				     m_is_variadic);
      m_fn_ptr_type = fn_type->get_pointer ();
    }
  gcc_assert (m_fn_ptr_type);

  rvalue *result = new function_pointer (get_context (), loc, this, m_fn_ptr_type);
  m_ctxt->record (result);
  return result;
}

/* Implementation of recording::memento::make_debug_string for
   functions.  */

recording::string *
recording::function::make_debug_string ()
{
  return m_name;
}

/* A table of enum gcc_jit_function_kind values expressed in string
   form.  */

static const char * const names_of_function_kinds[] = {
  "GCC_JIT_FUNCTION_EXPORTED",
  "GCC_JIT_FUNCTION_INTERNAL",
  "GCC_JIT_FUNCTION_IMPORTED",
  "GCC_JIT_FUNCTION_ALWAYS_INLINE"
};

/* Implementation of recording::memento::write_reproducer for functions. */

void
recording::function::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "func");

  if (m_builtin_id)
    {
      r.write ("  gcc_jit_function *%s =\n"
	       "    gcc_jit_context_get_builtin_function (%s,\n"
	       "                                          %s);\n",
	       id,
	       r.get_identifier (get_context ()),
	       m_name->get_debug_string ());
      return;
    }
  const char *params_id = r.make_tmp_identifier ("params_for", this);
  r.write ("  gcc_jit_param *%s[%i] = {\n",
	   params_id,
	   m_params.length ());
  int i;
  param *param;
  FOR_EACH_VEC_ELT (m_params, i, param)
    r.write ("    %s,\n", r.get_identifier (param));
  r.write ("  };\n");
  r.write ("  gcc_jit_function *%s =\n"
	   "    gcc_jit_context_new_function (%s, /* gcc_jit_context *ctxt */\n"
	   "                                  %s, /* gcc_jit_location *loc */\n"
	   "                                  %s, /* enum gcc_jit_function_kind kind */\n"
	   "                                  %s, /* gcc_jit_type *return_type */\n"
	   "                                  %s, /* const char *name */\n"
	   "                                  %i, /* int num_params */\n"
	   "                                  %s, /* gcc_jit_param **params */\n"
	   "                                  %i); /* int is_variadic */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   names_of_function_kinds[m_kind],
	   r.get_identifier_as_type (m_return_type),
	   m_name->get_debug_string (),
	   m_params.length (),
	   params_id,
	   m_is_variadic);
}


/* The implementation of class gcc::jit::recording::block.  */

/* Create a recording::eval instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_add_eval.  */

recording::statement *
recording::block::add_eval (recording::location *loc,
			    recording::rvalue *rvalue)
{
  statement *result = new eval (this, loc, rvalue);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  return result;
}

/* Create a recording::assignment instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_add_assignment.  */

recording::statement *
recording::block::add_assignment (recording::location *loc,
				  recording::lvalue *lvalue,
				  recording::rvalue *rvalue)
{
  statement *result = new assignment (this, loc, lvalue, rvalue);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  return result;
}

/* Create a recording::assignment_op instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_add_assignment_op.  */

recording::statement *
recording::block::add_assignment_op (recording::location *loc,
				     recording::lvalue *lvalue,
				     enum gcc_jit_binary_op op,
				     recording::rvalue *rvalue)
{
  statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  return result;
}

/* Create a recording::comment instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_add_comment.  */

recording::statement *
recording::block::add_comment (recording::location *loc,
			       const char *text)
{
  statement *result = new comment (this, loc, new_string (text));
  m_ctxt->record (result);
  m_statements.safe_push (result);
  return result;
}

/* Create a recording::end_with_conditional instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_end_with_conditional.  */

recording::statement *
recording::block::end_with_conditional (recording::location *loc,
					recording::rvalue *boolval,
					recording::block *on_true,
					recording::block *on_false)
{
  statement *result = new conditional (this, loc, boolval, on_true, on_false);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  m_has_been_terminated = true;
  return result;
}

/* Create a recording::end_with_jump instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_end_with_jump.  */

recording::statement *
recording::block::end_with_jump (recording::location *loc,
				 recording::block *target)
{
  statement *result = new jump (this, loc, target);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  m_has_been_terminated = true;
  return result;
}

/* Create a recording::end_with_return instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the post-error-checking parts of
   gcc_jit_block_end_with_return and
   gcc_jit_block_end_with_void_return.  */

recording::statement *
recording::block::end_with_return (recording::location *loc,
				   recording::rvalue *rvalue)
{
  /* This is used by both gcc_jit_function_add_return and
     gcc_jit_function_add_void_return; rvalue will be non-NULL for
     the former and NULL for the latter.  */
  statement *result = new return_ (this, loc, rvalue);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  m_has_been_terminated = true;
  return result;
}

/* Create a recording::switch_ instance and add it to
   the block's context's list of mementos, and to the block's
   list of statements.

   Implements the heart of gcc_jit_block_end_with_switch.  */

recording::statement *
recording::block::end_with_switch (recording::location *loc,
				   recording::rvalue *expr,
				   recording::block *default_block,
				   int num_cases,
				   recording::case_ **cases)
{
  statement *result = new switch_ (this, loc,
				   expr,
				   default_block,
				   num_cases,
				   cases);
  m_ctxt->record (result);
  m_statements.safe_push (result);
  m_has_been_terminated = true;
  return result;
}

/* Override the default implementation of
   recording::memento::write_to_dump for blocks by writing
   an unindented block name as a label, followed by the indented
   statements:

    BLOCK_NAME:
      STATEMENT_1;
      STATEMENT_2;
      ...
      STATEMENT_N;  */

void
recording::block::write_to_dump (dump &d)
{
  d.write ("%s:\n", get_debug_string ());

  int i;
  statement *s;
  FOR_EACH_VEC_ELT (m_statements, i, s)
    s->write_to_dump (d);
}

/* Validate a block by ensuring that it has been terminated.  */

bool
recording::block::validate ()
{
  /* Check for termination.  */
  if (!has_been_terminated ())
    {
      statement *stmt = get_last_statement ();
      location *loc = stmt ? stmt->get_loc () : NULL;
      m_func->get_context ()->add_error (loc,
					 "unterminated block in %s: %s",
					 m_func->get_debug_string (),
					 get_debug_string ());
      return false;
    }

  return true;
}

/* Get the source-location of a block by using that of the first
   statement within it, if any.  */

recording::location *
recording::block::get_loc () const
{
  recording::statement *stmt = get_first_statement ();
  if (stmt)
    return stmt->get_loc ();
  else
    return NULL;
}

/* Get the first statement within a block, if any.  */

recording::statement *
recording::block::get_first_statement () const
{
  if (m_statements.length ())
    return m_statements[0];
  else
    return NULL;
}

/* Get the last statement within a block, if any.  */

recording::statement *
recording::block::get_last_statement () const
{
  if (m_statements.length ())
    return m_statements[m_statements.length () - 1];
  else
    return NULL;
}

/* Assuming that this block has been terminated, get the successor blocks
   as a vector.  Ownership of the vector transfers to the caller, which
   must call its release () method.

   Used when validating functions, and when dumping dot representations
   of them.  */

vec <recording::block *>
recording::block::get_successor_blocks () const
{
  gcc_assert (m_has_been_terminated);
  statement *last_statement = get_last_statement ();
  gcc_assert (last_statement);
  return last_statement->get_successor_blocks ();
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::block.  */

void
recording::block::replay_into (replayer *)
{
  set_playback_obj (m_func->playback_function ()
		      ->new_block (playback_string (m_name)));
}

/* Implementation of recording::memento::make_debug_string for
   blocks.  */

recording::string *
recording::block::make_debug_string ()
{
  if (m_name)
    return m_name;
  else
    return string::from_printf (m_ctxt,
				"<UNNAMED BLOCK %p>",
				(void *)this);
}

/* Implementation of recording::memento::write_reproducer for blocks. */

void
recording::block::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "block");
  r.write ("  gcc_jit_block *%s =\n"
	   "    gcc_jit_function_new_block (%s, %s);\n",
	   id,
	   r.get_identifier (m_func),
	   m_name ? m_name->get_debug_string () : "NULL");
}

/* Dump a block in graphviz form into PP, capturing the block name (if
   any) and the statements.  */

void
recording::block::dump_to_dot (pretty_printer *pp)
{
  pp_printf (pp,
	     ("\tblock_%d "
	      "[shape=record,style=filled,fillcolor=white,label=\"{"),
	     m_index);
  pp_write_text_to_stream (pp);
  if (m_name)
    {
      pp_string (pp, m_name->c_str ());
      pp_string (pp, ":");
      pp_newline (pp);
      pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
    }

  int i;
  statement *s;
  FOR_EACH_VEC_ELT (m_statements, i, s)
    {
      pp_string (pp, s->get_debug_string ());
      pp_newline (pp);
      pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
    }

  pp_printf (pp,
	     "}\"];\n\n");
  pp_flush (pp);
}

/* Dump the out-edges of the block in graphviz form into PP.  */

void
recording::block::dump_edges_to_dot (pretty_printer *pp)
{
  vec <block *> successors = get_successor_blocks ();
  int i;
  block *succ;
  FOR_EACH_VEC_ELT (successors, i, succ)
    pp_printf (pp,
	       "\tblock_%d:s -> block_%d:n;\n",
	       m_index, succ->m_index);
  successors.release ();
}

/* The implementation of class gcc::jit::recording::global.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::global.  */

void
recording::global::replay_into (replayer *r)
{
  set_playback_obj (r->new_global (playback_location (r, m_loc),
				   m_kind,
				   m_type->playback_type (),
				   playback_string (m_name)));
}

/* Override the default implementation of
   recording::memento::write_to_dump for globals.
   This will be of the form:

   GCC_JIT_GLOBAL_EXPORTED:
      "TYPE NAME;"
      e.g. "int foo;"

   GCC_JIT_GLOBAL_INTERNAL:
      "static TYPE NAME;"
      e.g. "static int foo;"

   GCC_JIT_GLOBAL_IMPORTED:
      "extern TYPE NAME;"
      e.g. "extern int foo;"

   These are written to the top of the dump by
   recording::context::dump_to_file.  */

void
recording::global::write_to_dump (dump &d)
{
  if (d.update_locations ())
    m_loc = d.make_location ();

  switch (m_kind)
    {
    default:
      gcc_unreachable ();

    case GCC_JIT_GLOBAL_EXPORTED:
      break;

    case GCC_JIT_GLOBAL_INTERNAL:
      d.write ("static ");
      break;

    case GCC_JIT_GLOBAL_IMPORTED:
      d.write ("extern ");
      break;
    }
  d.write ("%s %s;\n",
	   m_type->get_debug_string (),
	   get_debug_string ());
}

/* A table of enum gcc_jit_global_kind values expressed in string
   form.  */

static const char * const global_kind_reproducer_strings[] = {
  "GCC_JIT_GLOBAL_EXPORTED",
  "GCC_JIT_GLOBAL_INTERNAL",
  "GCC_JIT_GLOBAL_IMPORTED"
};

/* Implementation of recording::memento::write_reproducer for globals. */

void
recording::global::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "block");
  r.write ("  gcc_jit_lvalue *%s =\n"
    "    gcc_jit_context_new_global (%s, /* gcc_jit_context *ctxt */\n"
    "                                %s, /* gcc_jit_location *loc */\n"
    "                                %s, /* enum gcc_jit_global_kind kind */\n"
    "                                %s, /* gcc_jit_type *type */\n"
    "                                %s); /* const char *name */\n",
    id,
    r.get_identifier (get_context ()),
    r.get_identifier (m_loc),
    global_kind_reproducer_strings[m_kind],
    r.get_identifier_as_type (get_type ()),
    m_name->get_debug_string ());
}

/* The implementation of the various const-handling classes:
   gcc::jit::recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */

/* Explicit specialization of the various mementos we're interested in.  */
template class recording::memento_of_new_rvalue_from_const <int>;
template class recording::memento_of_new_rvalue_from_const <long>;
template class recording::memento_of_new_rvalue_from_const <double>;
template class recording::memento_of_new_rvalue_from_const <void *>;

/* Implementation of the pure virtual hook recording::memento::replay_into
   for recording::memento_of_new_rvalue_from_const <HOST_TYPE>.  */

template <typename HOST_TYPE>
void
recording::
memento_of_new_rvalue_from_const <HOST_TYPE>::replay_into (replayer *r)
{
    set_playback_obj
      (r->new_rvalue_from_const <HOST_TYPE> (m_type->playback_type (),
					     m_value));
}

/* The make_debug_string and write_reproducer methods vary between the
   various
     memento_of_new_rvalue_from_const <HOST_TYPE>
   classes, so we explicitly write specializations of them.

   I (dmalcolm) find the code to be clearer if the "recording" vs "playback"
   namespaces are written out explicitly, which is why most of this file
   doesn't abbreviate things by entering the "recording" namespace.

   However, these specializations are required to be in the same namespace
   as the template, hence we now have to enter the gcc::jit::recording
   namespace.  */

namespace recording
{

/* The make_debug_string specialization for <int>, which renders it as
     (TARGET_TYPE)LITERAL
   e.g.
     "(int)42".  */

template <>
string *
memento_of_new_rvalue_from_const <int>::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "(%s)%i",
			      m_type->get_debug_string (),
			      m_value);
}

/* The get_wide_int specialization for <int>.  */

template <>
bool
memento_of_new_rvalue_from_const <int>::get_wide_int (wide_int *out) const
{
  *out = wi::shwi (m_value, sizeof (m_value) * 8);
  return true;
}

/* The write_reproducer specialization for <int>.  */

template <>
void
memento_of_new_rvalue_from_const <int>::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
    "    gcc_jit_context_new_rvalue_from_int (%s, /* gcc_jit_context *ctxt */\n"
    "                                         %s, /* gcc_jit_type *numeric_type */\n"
    "                                         %i); /* int value */\n",
    id,
    r.get_identifier (get_context ()),
    r.get_identifier_as_type (m_type),
    m_value);
}

/* The make_debug_string specialization for <long>, rendering it as
     (TARGET_TYPE)LITERAL
   e.g.
     "(long)42".  */

template <>
string *
memento_of_new_rvalue_from_const <long>::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "(%s)%li",
			      m_type->get_debug_string (),
			      m_value);
}

/* The get_wide_int specialization for <long>.  */

template <>
bool
memento_of_new_rvalue_from_const <long>::get_wide_int (wide_int *out) const
{
  *out = wi::shwi (m_value, sizeof (m_value) * 8);
  return true;
}

/* The write_reproducer specialization for <long>.  */

template <>
void
recording::memento_of_new_rvalue_from_const <long>::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");

  /* We have to special-case LONG_MIN, since e.g.
       -9223372036854775808L
     is parsed as
       -(9223372036854775808L)
     and hence we'd get:
	error: integer constant is so large that it is unsigned [-Werror]
	Workaround this by writing (LONG_MIN + 1) - 1.  */
  if (m_value == LONG_MIN)
    {
      r.write ("  gcc_jit_rvalue *%s =\n"
	       "    gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
	       "                                          %s, /* gcc_jit_type *numeric_type */\n"
	       "                                          %ldL - 1); /* long value */\n",
	       id,
	       r.get_identifier (get_context ()),
	       r.get_identifier_as_type (m_type),
	       m_value + 1);
      return;
    }

  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_rvalue_from_long (%s, /* gcc_jit_context *ctxt */\n"
	   "                                          %s, /* gcc_jit_type *numeric_type */\n"
	   "                                          %ldL); /* long value */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier_as_type (m_type),
	   m_value);
	   }

/* The make_debug_string specialization for <double>, rendering it as
     (TARGET_TYPE)LITERAL
   e.g.
     "(float)42.0".  */

template <>
string *
memento_of_new_rvalue_from_const <double>::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "(%s)%f",
			      m_type->get_debug_string (),
			      m_value);
}

/* The get_wide_int specialization for <double>.  */

template <>
bool
memento_of_new_rvalue_from_const <double>::get_wide_int (wide_int *) const
{
  return false;
}

/* The write_reproducer specialization for <double>.  */

template <>
void
recording::memento_of_new_rvalue_from_const <double>::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
    "    gcc_jit_context_new_rvalue_from_double (%s, /* gcc_jit_context *ctxt */\n"
    "                                            %s, /* gcc_jit_type *numeric_type */\n"
    "                                            %f); /* double value */\n",
    id,
    r.get_identifier (get_context ()),
    r.get_identifier_as_type (m_type),
    m_value);
}

/* The make_debug_string specialization for <void *>, rendering it as
     (TARGET_TYPE)HEX
   e.g.
     "(int *)0xdeadbeef"

   Zero is rendered as NULL e.g.
     "(int *)NULL".  */

template <>
string *
memento_of_new_rvalue_from_const <void *>::make_debug_string ()
{
  if (m_value != NULL)
    return string::from_printf (m_ctxt,
				"(%s)%p",
				m_type->get_debug_string (), m_value);
  else
    return string::from_printf (m_ctxt,
				"(%s)NULL",
				m_type->get_debug_string ());
}

/* The get_wide_int specialization for <void *>.  */

template <>
bool
memento_of_new_rvalue_from_const <void *>::get_wide_int (wide_int *) const
{
  return false;
}

/* Implementation of recording::memento::write_reproducer for <void *>
   values. */

template <>
void
memento_of_new_rvalue_from_const <void *>::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  if (m_value)
    r.write ("  gcc_jit_rvalue *%s =\n"
	     "    gcc_jit_context_new_rvalue_from_ptr (%s, /* gcc_jit_context *ctxt */\n"
	     "                                         %s, /* gcc_jit_type *pointer_type */\n"
	     "                                         (void *)%p); /* void *value */\n",
	     id,
	     r.get_identifier (get_context ()),
	     r.get_identifier_as_type (m_type),
	     m_value);
  else
    r.write ("  gcc_jit_rvalue *%s =\n"
	     "    gcc_jit_context_null (%s, /* gcc_jit_context *ctxt */\n"
	     "                          %s); /* gcc_jit_type *pointer_type */\n",
	     id,
	     r.get_identifier (get_context ()),
	     r.get_identifier_as_type (m_type));
}

/* We're done specializing make_debug_string and write_reproducer, so we
   can exit the gcc::jit::recording namespace.  */

} // namespace recording

/* The implementation of class gcc::jit::recording::memento_of_new_string_literal.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_new_string_literal.  */

void
recording::memento_of_new_string_literal::replay_into (replayer *r)
{
  set_playback_obj (r->new_string_literal (m_value->c_str ()));
}

/* Implementation of recording::memento::make_debug_string for
   string literals.  */

recording::string *
recording::memento_of_new_string_literal::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s",
			      m_value->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for string literal
   values. */

void
recording::memento_of_new_string_literal::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
    "    gcc_jit_context_new_string_literal (%s, /* gcc_jit_context *ctxt */\n"
    "                                        %s); /* const char *value */\n",
    id,
    r.get_identifier (get_context ()),
    m_value->get_debug_string ());
}

/* The implementation of class
   gcc::jit::recording::memento_of_new_rvalue_from_vector.  */

/* The constructor for
   gcc::jit::recording::memento_of_new_rvalue_from_vector.  */

recording::memento_of_new_rvalue_from_vector::
memento_of_new_rvalue_from_vector (context *ctxt,
				   location *loc,
				   vector_type *type,
				   rvalue **elements)
: rvalue (ctxt, loc, type),
  m_vector_type (type),
  m_elements ()
{
  for (unsigned i = 0; i < type->get_num_units (); i++)
    m_elements.safe_push (elements[i]);
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::memento_of_new_rvalue_from_vector.  */

void
recording::memento_of_new_rvalue_from_vector::replay_into (replayer *r)
{
  auto_vec<playback::rvalue *> playback_elements;
  playback_elements.create (m_elements.length ());
  for (unsigned i = 0; i< m_elements.length (); i++)
    playback_elements.safe_push (m_elements[i]->playback_rvalue ());

  set_playback_obj (r->new_rvalue_from_vector (playback_location (r, m_loc),
					       m_type->playback_type (),
					       playback_elements));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::memento_of_new_rvalue_from_vector.  */

void
recording::memento_of_new_rvalue_from_vector::visit_children (rvalue_visitor *v)
{
  for (unsigned i = 0; i< m_elements.length (); i++)
    v->visit (m_elements[i]);
}

/* Implementation of recording::memento::make_debug_string for
   vectors.  */

recording::string *
recording::memento_of_new_rvalue_from_vector::make_debug_string ()
{
  comma_separated_string elements (m_elements, get_precedence ());

  /* Now build a string.  */
  string *result = string::from_printf (m_ctxt,
					"{%s}",
					elements.as_char_ptr ());

 return result;

}

/* Implementation of recording::memento::write_reproducer for
   vectors.  */

void
recording::memento_of_new_rvalue_from_vector::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "vector");
  const char *elements_id = r.make_tmp_identifier ("elements_for_", this);
  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
	   elements_id,
	   m_elements.length ());
  for (unsigned i = 0; i< m_elements.length (); i++)
    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_elements[i]));
  r.write ("  };\n");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_rvalue_from_vector (%s, /* gcc_jit_context *ctxt */\n"
	   "                                            %s, /* gcc_jit_location *loc */\n"
	   "                                            %s, /* gcc_jit_type *vec_type */\n"
	   "                                            %i, /* size_t num_elements  */ \n"
	   "                                            %s); /* gcc_jit_rvalue **elements*/\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier (m_vector_type),
	   m_elements.length (),
	   elements_id);
}

/* The implementation of class gcc::jit::recording::unary_op.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::unary_op.  */

void
recording::unary_op::replay_into (replayer *r)
{
  set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
				     m_op,
				     get_type ()->playback_type (),
				     m_a->playback_rvalue ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::unary_op.  */
void
recording::unary_op::visit_children (rvalue_visitor *v)
{
  v->visit (m_a);
}

/* Implementation of recording::memento::make_debug_string for
   unary ops.  */

static const char * const unary_op_strings[] = {
  "-", /* GCC_JIT_UNARY_OP_MINUS */
  "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
  "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
  "abs ", /* GCC_JIT_UNARY_OP_ABS */
};

recording::string *
recording::unary_op::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s(%s)",
			      unary_op_strings[m_op],
			      m_a->get_debug_string ());
}

static const char * const unary_op_reproducer_strings[] = {
  "GCC_JIT_UNARY_OP_MINUS",
  "GCC_JIT_UNARY_OP_BITWISE_NEGATE",
  "GCC_JIT_UNARY_OP_LOGICAL_NEGATE",
  "GCC_JIT_UNARY_OP_ABS"
};

/* Implementation of recording::memento::write_reproducer for unary ops.  */

void
recording::unary_op::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_unary_op (%s,\n"
	   "                                  %s, /* gcc_jit_location *loc */\n"
	   "                                  %s, /* enum gcc_jit_unary_op op */\n"
	   "                                  %s, /* gcc_jit_type *result_type */\n"
	   "                                  %s); /* gcc_jit_rvalue *a */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   unary_op_reproducer_strings[m_op],
	   r.get_identifier_as_type (get_type ()),
	   r.get_identifier_as_rvalue (m_a));
}

/* The implementation of class gcc::jit::recording::binary_op.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::binary_op.  */

void
recording::binary_op::replay_into (replayer *r)
{
  set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
				      m_op,
				      get_type ()->playback_type (),
				      m_a->playback_rvalue (),
				      m_b->playback_rvalue ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::binary_op.  */
void
recording::binary_op::visit_children (rvalue_visitor *v)
{
  v->visit (m_a);
  v->visit (m_b);
}

/* Implementation of recording::memento::make_debug_string for
   binary ops.  */

static const char * const binary_op_strings[] = {
  "+", /* GCC_JIT_BINARY_OP_PLUS */
  "-", /* GCC_JIT_BINARY_OP_MINUS */
  "*", /* GCC_JIT_BINARY_OP_MULT */
  "/", /* GCC_JIT_BINARY_OP_DIVIDE */
  "%", /* GCC_JIT_BINARY_OP_MODULO */
  "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
  "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
  "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
  "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
  "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
  "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
  ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
};

recording::string *
recording::binary_op::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s %s %s",
			      m_a->get_debug_string_parens (prec),
			      binary_op_strings[m_op],
			      m_b->get_debug_string_parens (prec));
}

static const char * const binary_op_reproducer_strings[] = {
  "GCC_JIT_BINARY_OP_PLUS",
  "GCC_JIT_BINARY_OP_MINUS",
  "GCC_JIT_BINARY_OP_MULT",
  "GCC_JIT_BINARY_OP_DIVIDE",
  "GCC_JIT_BINARY_OP_MODULO",
  "GCC_JIT_BINARY_OP_BITWISE_AND",
  "GCC_JIT_BINARY_OP_BITWISE_XOR",
  "GCC_JIT_BINARY_OP_BITWISE_OR",
  "GCC_JIT_BINARY_OP_LOGICAL_AND",
  "GCC_JIT_BINARY_OP_LOGICAL_OR",
  "GCC_JIT_BINARY_OP_LSHIFT",
  "GCC_JIT_BINARY_OP_RSHIFT"
};

/* Implementation of recording::memento::write_reproducer for binary ops.  */

void
recording::binary_op::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_binary_op (%s,\n"
	   "                                   %s, /* gcc_jit_location *loc */\n"
	   "                                   %s, /* enum gcc_jit_binary_op op */\n"
	   "                                   %s, /* gcc_jit_type *result_type */\n"
	   "                                   %s, /* gcc_jit_rvalue *a */\n"
	   "                                   %s); /* gcc_jit_rvalue *b */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   binary_op_reproducer_strings[m_op],
	   r.get_identifier_as_type (get_type ()),
	   r.get_identifier_as_rvalue (m_a),
	   r.get_identifier_as_rvalue (m_b));
}

namespace recording {
static const enum precedence binary_op_precedence[] = {
  PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_PLUS */
  PRECEDENCE_ADDITIVE, /* GCC_JIT_BINARY_OP_MINUS */

  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MULT */
  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_DIVIDE */
  PRECEDENCE_MULTIPLICATIVE, /* GCC_JIT_BINARY_OP_MODULO */

  PRECEDENCE_BITWISE_AND, /* GCC_JIT_BINARY_OP_BITWISE_AND */
  PRECEDENCE_BITWISE_XOR, /* GCC_JIT_BINARY_OP_BITWISE_XOR */
  PRECEDENCE_BITWISE_IOR, /* GCC_JIT_BINARY_OP_BITWISE_OR */
  PRECEDENCE_LOGICAL_AND, /* GCC_JIT_BINARY_OP_LOGICAL_AND */
  PRECEDENCE_LOGICAL_OR, /* GCC_JIT_BINARY_OP_LOGICAL_OR */
  PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_LSHIFT */
  PRECEDENCE_SHIFT, /* GCC_JIT_BINARY_OP_RSHIFT */
};
} /* namespace recording */

enum recording::precedence
recording::binary_op::get_precedence () const
{
  return binary_op_precedence[m_op];
}

/* The implementation of class gcc::jit::recording::comparison.  */

/* Implementation of recording::memento::make_debug_string for
   comparisons.  */

static const char * const comparison_strings[] =
{
  "==", /* GCC_JIT_COMPARISON_EQ */
  "!=", /* GCC_JIT_COMPARISON_NE */
  "<",  /* GCC_JIT_COMPARISON_LT */
  "<=", /* GCC_JIT_COMPARISON_LE */
  ">",  /* GCC_JIT_COMPARISON_GT */
  ">=", /* GCC_JIT_COMPARISON_GE */
};

recording::string *
recording::comparison::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s %s %s",
			      m_a->get_debug_string_parens (prec),
			      comparison_strings[m_op],
			      m_b->get_debug_string_parens (prec));
}

/* A table of enum gcc_jit_comparison values expressed in string
   form.  */

static const char * const comparison_reproducer_strings[] =
{
  "GCC_JIT_COMPARISON_EQ",
  "GCC_JIT_COMPARISON_NE",
  "GCC_JIT_COMPARISON_LT",
  "GCC_JIT_COMPARISON_LE",
  "GCC_JIT_COMPARISON_GT",
  "GCC_JIT_COMPARISON_GE"
};

/* Implementation of recording::memento::write_reproducer for comparisons.  */

void
recording::comparison::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_comparison (%s,\n"
	   "                                    %s, /* gcc_jit_location *loc */\n"
	   "                                    %s, /* enum gcc_jit_comparison op */\n"
	   "                                    %s, /* gcc_jit_rvalue *a */\n"
	   "                                    %s); /* gcc_jit_rvalue *b */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   comparison_reproducer_strings[m_op],
	   r.get_identifier_as_rvalue (m_a),
	   r.get_identifier_as_rvalue (m_b));
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::comparison.  */

void
recording::comparison::replay_into (replayer *r)
{
  set_playback_obj (r->new_comparison (playback_location (r, m_loc),
				       m_op,
				       m_a->playback_rvalue (),
				       m_b->playback_rvalue ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::comparison.  */

void
recording::comparison::visit_children (rvalue_visitor *v)
{
  v->visit (m_a);
  v->visit (m_b);
}

namespace recording {
static const enum precedence comparison_precedence[] =
{
  PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_EQ */
  PRECEDENCE_EQUALITY, /* GCC_JIT_COMPARISON_NE */

  PRECEDENCE_RELATIONAL,  /* GCC_JIT_COMPARISON_LT */
  PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_LE */
  PRECEDENCE_RELATIONAL,  /* GCC_JIT_COMPARISON_GT */
  PRECEDENCE_RELATIONAL, /* GCC_JIT_COMPARISON_GE */
};
} /* namespace recording */

enum recording::precedence
recording::comparison::get_precedence () const
{
  return comparison_precedence[m_op];
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::cast.  */

void
recording::cast::replay_into (replayer *r)
{
  set_playback_obj (r->new_cast (playback_location (r, m_loc),
				 m_rvalue->playback_rvalue (),
				 get_type ()->playback_type ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::cast.  */
void
recording::cast::visit_children (rvalue_visitor *v)
{
  v->visit (m_rvalue);
}

/* Implementation of recording::memento::make_debug_string for
   casts.  */

recording::string *
recording::cast::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "(%s)%s",
			      get_type ()->get_debug_string (),
			      m_rvalue->get_debug_string_parens (prec));
}

/* Implementation of recording::memento::write_reproducer for casts.  */

void
recording::cast::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_cast (%s,\n"
	   "                              %s, /* gcc_jit_location *loc */\n"
	   "                              %s, /* gcc_jit_rvalue *rvalue */\n"
	   "                              %s); /* gcc_jit_type *type */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_rvalue (m_rvalue),
	   r.get_identifier_as_type (get_type ()));
}

/* The implementation of class gcc::jit::recording::base_call.  */

/* The constructor for gcc::jit::recording::base_call.  */

recording::base_call::base_call (context *ctxt,
				 location *loc,
				 type *type_,
				 int numargs,
				 rvalue **args)
: rvalue (ctxt, loc, type_),
  m_args (),
  m_require_tail_call (0)
{
  for (int i = 0; i< numargs; i++)
    m_args.safe_push (args[i]);
}

/* Subroutine for use by call and call_though_ptr's write_reproducer
   methods.  */

void
recording::base_call::write_reproducer_tail_call (reproducer &r,
						  const char *id)
{
  if (m_require_tail_call)
    {
      r.write ("  gcc_jit_rvalue_set_bool_require_tail_call (%s,  /* gcc_jit_rvalue *call*/\n"
	       "                                             %i); /* int require_tail_call*/\n",
	       id,
	       1);
    }
}

/* The implementation of class gcc::jit::recording::call.  */

/* The constructor for gcc::jit::recording::call.  */

recording::call::call (recording::context *ctxt,
		       recording::location *loc,
		       recording::function *func,
		       int numargs,
		       rvalue **args)
: base_call (ctxt, loc, func->get_return_type (), numargs, args),
  m_func (func)
{
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::call.  */

void
recording::call::replay_into (replayer *r)
{
  auto_vec<playback::rvalue *> playback_args;
  playback_args.create (m_args.length ());
  for (unsigned i = 0; i< m_args.length (); i++)
    playback_args.safe_push (m_args[i]->playback_rvalue ());

  set_playback_obj (r->new_call (playback_location (r, m_loc),
				 m_func->playback_function (),
				 &playback_args,
				 m_require_tail_call));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::call.  */

void
recording::call::visit_children (rvalue_visitor *v)
{
  for (unsigned i = 0; i< m_args.length (); i++)
    v->visit (m_args[i]);
}

/* Implementation of recording::memento::make_debug_string for
   function calls.  */

recording::string *
recording::call::make_debug_string ()
{
  /* First, build a buffer for the arguments.  */
  comma_separated_string args (m_args, get_precedence ());

  /* ...and use it to get the string for the call as a whole.  */
  string *result = string::from_printf (m_ctxt,
					"%s (%s)",
					m_func->get_debug_string (),
					args.as_char_ptr ());

  return result;
}

void
recording::call::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "call");
  const char *args_id = r.make_tmp_identifier ("args_for_", this);
  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
	   args_id,
	   m_args.length ());
  for (unsigned i = 0; i< m_args.length (); i++)
    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_args[i]));
  r.write ("  };\n");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_call (%s, /* gcc_jit_context *ctxt */\n"
	   "                              %s, /* gcc_jit_location *loc */\n"
	   "                              %s, /* gcc_jit_function *func */\n"
	   "                              %i, /* int numargs  */ \n"
	   "                              %s); /* gcc_jit_rvalue **args*/\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier (m_func),
	   m_args.length (),
	   args_id);
  write_reproducer_tail_call (r, id);
}

/* The implementation of class gcc::jit::recording::call_through_ptr.  */

/* The constructor for recording::call_through_ptr. */

recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
					       recording::location *loc,
					       recording::rvalue *fn_ptr,
					       int numargs,
					       rvalue **args)
: base_call (ctxt, loc,
	     fn_ptr->get_type ()->dereference ()
	       ->as_a_function_type ()->get_return_type (),
	     numargs, args),
  m_fn_ptr (fn_ptr)
{
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::call_through_ptr.  */

void
recording::call_through_ptr::replay_into (replayer *r)
{
  auto_vec<playback::rvalue *> playback_args;
  playback_args.create (m_args.length ());
  for (unsigned i = 0; i< m_args.length (); i++)
    playback_args.safe_push (m_args[i]->playback_rvalue ());

  set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
					     m_fn_ptr->playback_rvalue (),
					     &playback_args,
					     m_require_tail_call));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::call_through_ptr.  */

void
recording::call_through_ptr::visit_children (rvalue_visitor *v)
{
  v->visit (m_fn_ptr);
  for (unsigned i = 0; i< m_args.length (); i++)
    v->visit (m_args[i]);
}

/* Implementation of recording::memento::make_debug_string for
   calls through function ptrs.  */

recording::string *
recording::call_through_ptr::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  /* First, build a buffer for the arguments.  */
  /* Calculate length of said buffer.  */
  size_t sz = 1; /* nil terminator */
  for (unsigned i = 0; i< m_args.length (); i++)
    {
      sz += strlen (m_args[i]->get_debug_string_parens (prec));
      sz += 2; /* ", " separator */
    }

  /* Now allocate and populate the buffer.  */
  char *argbuf = new char[sz];
  size_t len = 0;

  for (unsigned i = 0; i< m_args.length (); i++)
    {
      strcpy (argbuf + len, m_args[i]->get_debug_string_parens (prec));
      len += strlen (m_args[i]->get_debug_string_parens (prec));
      if (i + 1 < m_args.length ())
	{
	  strcpy (argbuf + len, ", ");
	  len += 2;
	}
    }
  argbuf[len] = '\0';

  /* ...and use it to get the string for the call as a whole.  */
  string *result = string::from_printf (m_ctxt,
					"%s (%s)",
					m_fn_ptr->get_debug_string_parens (prec),
					argbuf);

  delete[] argbuf;

  return result;
}

/* Implementation of recording::memento::write_reproducer for
   call_through_ptr.  */

void
recording::call_through_ptr::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "call");
  const char *args_id = r.make_tmp_identifier ("args_for_", this);
  r.write ("  gcc_jit_rvalue *%s[%i] = {\n",
	     args_id,
	     m_args.length ());
  for (unsigned i = 0; i< m_args.length (); i++)
    r.write ("    %s,\n", r.get_identifier_as_rvalue (m_args[i]));
  r.write ("  };\n");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_context_new_call_through_ptr (%s, /* gcc_jit_context *ctxt */\n"
	   "                              %s, /* gcc_jit_location *loc */\n"
	   "                              %s, /* gcc_jit_rvalue *fn_ptr */\n"
	   "                              %i, /* int numargs  */ \n"
	   "                              %s); /* gcc_jit_rvalue **args*/\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_rvalue (m_fn_ptr),
	   m_args.length (),
	   args_id);
  write_reproducer_tail_call (r, id);
}

/* The implementation of class gcc::jit::recording::array_access.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::array_access.  */

void
recording::array_access::replay_into (replayer *r)
{
  set_playback_obj (
    r->new_array_access (playback_location (r, m_loc),
			 m_ptr->playback_rvalue (),
			 m_index->playback_rvalue ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::array_access.  */

void
recording::array_access::visit_children (rvalue_visitor *v)
{
  v->visit (m_ptr);
  v->visit (m_index);
}

/* Implementation of recording::memento::make_debug_string for
   array accesses.  */

recording::string *
recording::array_access::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s[%s]",
			      m_ptr->get_debug_string_parens (prec),
			      m_index->get_debug_string_parens (prec));
}

/* Implementation of recording::memento::write_reproducer for
   array_access.  */

void
recording::array_access::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "lvalue");
  r.write ("  gcc_jit_lvalue *%s = \n"
	   "    gcc_jit_context_new_array_access (%s, /* gcc_jit_context *ctxt */\n"
	   "                                      %s, /*gcc_jit_location *loc */\n"
	   "                                      %s, /* gcc_jit_rvalue *ptr */\n"
	   "                                      %s); /* gcc_jit_rvalue *index */\n",
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_rvalue (m_ptr),
	   r.get_identifier_as_rvalue (m_index));
}

/* The implementation of class gcc::jit::recording::access_field_of_lvalue.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::access_field_of_lvalue.  */

void
recording::access_field_of_lvalue::replay_into (replayer *r)
{
  set_playback_obj (
    m_lvalue->playback_lvalue ()
      ->access_field (playback_location (r, m_loc),
		      m_field->playback_field ()));

}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::access_field_of_lvalue.  */

void
recording::access_field_of_lvalue::visit_children (rvalue_visitor *v)
{
  v->visit (m_lvalue);
}

/* Implementation of recording::memento::make_debug_string for
   accessing a field of an lvalue.  */

recording::string *
recording::access_field_of_lvalue::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s.%s",
			      m_lvalue->get_debug_string_parens (prec),
			      m_field->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   access_field_of_lvalue.  */

void
recording::access_field_of_lvalue::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "lvalue");
  r.write ("  gcc_jit_lvalue *%s = \n"
	   "    gcc_jit_lvalue_access_field (%s, /*gcc_jit_lvalue *struct_or_union */\n"
	   "                                 %s, /*gcc_jit_location *loc */\n"
	   "                                 %s);\n",
	   id,
	   r.get_identifier_as_lvalue (m_lvalue),
	   r.get_identifier (m_loc),
	   r.get_identifier (m_field));
}

/* The implementation of class gcc::jit::recording::access_field_rvalue.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::access_field_rvalue.  */

void
recording::access_field_rvalue::replay_into (replayer *r)
{
  set_playback_obj (
    m_rvalue->playback_rvalue ()
      ->access_field (playback_location (r, m_loc),
		      m_field->playback_field ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::access_field_rvalue.  */

void
recording::access_field_rvalue::visit_children (rvalue_visitor *v)
{
  v->visit (m_rvalue);
}

/* Implementation of recording::memento::make_debug_string for
   accessing a field of an rvalue.  */

recording::string *
recording::access_field_rvalue::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s.%s",
			      m_rvalue->get_debug_string_parens (prec),
			      m_field->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   access_field_rvalue.  */

void
recording::access_field_rvalue::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "rvalue");
  r.write ("  gcc_jit_rvalue *%s = \n"
	   "    gcc_jit_rvalue_access_field (%s, /*gcc_jit_rvalue *struct_or_union */\n"
	   "                                 %s, /*gcc_jit_location *loc */\n"
	   "                                 %s);\n",
	   id,
	   r.get_identifier_as_rvalue (m_rvalue),
	   r.get_identifier (m_loc),
	   r.get_identifier (m_field));
}

/* The implementation of class
   gcc::jit::recording::dereference_field_rvalue.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::dereference_field_rvalue.  */

void
recording::dereference_field_rvalue::replay_into (replayer *r)
{
  set_playback_obj (
    m_rvalue->playback_rvalue ()->
      dereference_field (playback_location (r, m_loc),
			 m_field->playback_field ()));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::dereference_field_rvalue.  */

void
recording::dereference_field_rvalue::visit_children (rvalue_visitor *v)
{
  v->visit (m_rvalue);
}

/* Implementation of recording::memento::make_debug_string for
   dereferencing a field of an rvalue.  */

recording::string *
recording::dereference_field_rvalue::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "%s->%s",
			      m_rvalue->get_debug_string_parens (prec),
			      m_field->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   dereference_field_rvalue.  */

void
recording::dereference_field_rvalue::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "lvalue");
  r.write ("  gcc_jit_lvalue *%s=\n"
	   "    gcc_jit_rvalue_dereference_field (%s, /* gcc_jit_rvalue *ptr */\n"
	   "                                      %s, /* gcc_jit_location *loc */\n"
	   "                                      %s); /* gcc_jit_field *field */\n",
	   id,
	   r.get_identifier_as_rvalue (m_rvalue),
	   r.get_identifier (m_loc),
	   r.get_identifier (m_field));
}

/* The implementation of class gcc::jit::recording::dereference_rvalue.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::dereference_rvalue.  */

void
recording::dereference_rvalue::replay_into (replayer *r)
{
  set_playback_obj (
    m_rvalue->playback_rvalue ()->
      dereference (playback_location (r, m_loc)));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::dereference_rvalue.  */

void
recording::dereference_rvalue::visit_children (rvalue_visitor *v)
{
  v->visit (m_rvalue);
}

/* Implementation of recording::memento::make_debug_string for
   dereferencing an rvalue.  */

recording::string *
recording::dereference_rvalue::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "*%s",
			      m_rvalue->get_debug_string_parens (prec));
}

/* Implementation of recording::memento::write_reproducer for
   dereference_rvalue.  */

void
recording::dereference_rvalue::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "dereference");
  r.write ("  gcc_jit_lvalue *%s =\n"
	   "    gcc_jit_rvalue_dereference (%s, /* gcc_jit_rvalue *rvalue */\n"
	   "                                %s); /* gcc_jit_location *loc */\n",
	   id,
	   r.get_identifier_as_rvalue (m_rvalue),
	   r.get_identifier (m_loc));
}

/* The implementation of class gcc::jit::recording::get_address_of_lvalue.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::get_address_of_lvalue.  */

void
recording::get_address_of_lvalue::replay_into (replayer *r)
{
  set_playback_obj (
    m_lvalue->playback_lvalue ()->
      get_address (playback_location (r, m_loc)));
}

/* Implementation of pure virtual hook recording::rvalue::visit_children
   for recording::get_address_of_lvalue.  */

void
recording::get_address_of_lvalue::visit_children (rvalue_visitor *v)
{
  v->visit (m_lvalue);
}

/* Implementation of recording::memento::make_debug_string for
   getting the address of an lvalue.  */

recording::string *
recording::get_address_of_lvalue::make_debug_string ()
{
  enum precedence prec = get_precedence ();
  return string::from_printf (m_ctxt,
			      "&%s",
			      m_lvalue->get_debug_string_parens (prec));
}

/* Implementation of recording::memento::write_reproducer for
   get_address_of_lvalue.  */

void
recording::get_address_of_lvalue::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "address_of");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_lvalue_get_address (%s, /* gcc_jit_lvalue *lvalue */\n"
	   "                                %s); /* gcc_jit_location *loc */\n",
	   id,
	   r.get_identifier_as_lvalue (m_lvalue),
	   r.get_identifier (m_loc));
}

/* The implementation of class gcc::jit::recording::function_pointer.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::function_pointer.  */

void
recording::function_pointer::replay_into (replayer *r)
{
  set_playback_obj (
    m_fn->playback_function ()->
      get_address (playback_location (r, m_loc)));
}

void
recording::function_pointer::visit_children (rvalue_visitor *)
{
  /* Empty.  */
}

/* Implementation of recording::memento::make_debug_string for
   getting the address of an lvalue.  */

recording::string *
recording::function_pointer::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s",
			      m_fn->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   function_pointer.  */

void
recording::function_pointer::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "address_of");
  r.write ("  gcc_jit_rvalue *%s =\n"
	   "    gcc_jit_function_get_address (%s, /* gcc_jit_function *fn */\n"
	   "                                  %s); /* gcc_jit_location *loc */\n",
	   id,
	   r.get_identifier (m_fn),
	   r.get_identifier (m_loc));
}

/* The implementation of class gcc::jit::recording::local.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::local.  */

void
recording::local::replay_into (replayer *r)
{
  set_playback_obj (
    m_func->playback_function ()
      ->new_local (playback_location (r, m_loc),
		   m_type->playback_type (),
		   playback_string (m_name)));
}

/* Override the default implementation of
   recording::memento::write_to_dump for locals by writing
      TYPE NAME;
   for use at the top of the function body as if it were a
   declaration.  */

void
recording::local::write_to_dump (dump &d)
{
  if (d.update_locations ())
    m_loc = d.make_location ();
  d.write("  %s %s;\n",
	  m_type->get_debug_string (),
	  get_debug_string ());
}

void
recording::local::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "local");
  r.write ("  gcc_jit_lvalue *%s =\n"
	   "    gcc_jit_function_new_local (%s, /* gcc_jit_function *func */\n"
	   "                                %s, /* gcc_jit_location *loc */\n"
	   "                                %s, /* gcc_jit_type *type */\n"
	   "                                %s); /* const char *name */\n",
	   id,
	   r.get_identifier (m_func),
	   r.get_identifier (m_loc),
	   r.get_identifier_as_type (m_type),
	   m_name->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::statement.  */

/* We poison the default implementation of
   gcc::jit::recording::statement::get_successor_blocks
   since this vfunc must only ever be called on terminator
   statements.  */

vec <recording::block *>
recording::statement::get_successor_blocks () const
{
  /* The base class implementation is for non-terminating statements,
     and thus should never be called.  */
  gcc_unreachable ();
  vec <block *> result;
  result.create (0);
  return result;
}

/* Extend the default implementation of
   recording::memento::write_to_dump for statements by (if requested)
   updating the location of the statement to the current location in
   the dumpfile.  */

void
recording::statement::write_to_dump (dump &d)
{
  memento::write_to_dump (d);
  if (d.update_locations ())
    m_loc = d.make_location ();
}

/* The implementation of class gcc::jit::recording::eval.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::eval.  */

void
recording::eval::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_eval (playback_location (r),
		m_rvalue->playback_rvalue ());
}

/* Implementation of recording::memento::make_debug_string for
   an eval statement.  */

recording::string *
recording::eval::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "(void)%s;",
			      m_rvalue->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   eval statements.  */

void
recording::eval::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_add_eval (%s, /*gcc_jit_block *block */\n"
	   "                          %s, /* gcc_jit_location *loc */\n"
	   "                          %s); /* gcc_jit_rvalue *rvalue */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   r.get_identifier_as_rvalue (m_rvalue));
}

/* The implementation of class gcc::jit::recording::assignment.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::assignment.  */

void
recording::assignment::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_assignment (playback_location (r),
		      m_lvalue->playback_lvalue (),
		      m_rvalue->playback_rvalue ());
}

/* Implementation of recording::memento::make_debug_string for
   an assignment statement.  */

recording::string *
recording::assignment::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s = %s;",
			      m_lvalue->get_debug_string (),
			      m_rvalue->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   assignment statements.  */

void
recording::assignment::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_add_assignment (%s, /*gcc_jit_block *block */\n"
	   "                                %s, /* gcc_jit_location *loc */\n"
	   "                                %s, /* gcc_jit_lvalue *lvalue */\n"
	   "                                %s); /* gcc_jit_rvalue *rvalue */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   r.get_identifier_as_lvalue (m_lvalue),
	   r.get_identifier_as_rvalue (m_rvalue));
}

/* The implementation of class gcc::jit::recording::assignment_op.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::assignment_op.  */

void
recording::assignment_op::replay_into (replayer *r)
{
  playback::type *result_type =
    m_lvalue->playback_lvalue ()->get_type ();

  playback::rvalue *binary_op =
    r->new_binary_op (playback_location (r),
		      m_op,
		      result_type,
		      m_lvalue->playback_rvalue (),
		      m_rvalue->playback_rvalue ());

  playback_block (get_block ())
    ->add_assignment (playback_location (r),
		      m_lvalue->playback_lvalue (),
		      binary_op);
}

/* Implementation of recording::memento::make_debug_string for
   an assignment_op statement.  */

recording::string *
recording::assignment_op::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "%s %s= %s;",
			      m_lvalue->get_debug_string (),
			      binary_op_strings[m_op],
			      m_rvalue->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   assignment_op statements.  */

void
recording::assignment_op::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_add_assignment_op (%s, /*gcc_jit_block *block */\n"
	   "                                   %s, /* gcc_jit_location *loc */\n"
	   "                                   %s, /* gcc_jit_lvalue *lvalue */\n"
	   "                                   %s, /* enum gcc_jit_binary_op op */\n"
	   "                                   %s); /* gcc_jit_rvalue *rvalue */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   r.get_identifier_as_lvalue (m_lvalue),
	   binary_op_reproducer_strings[m_op],
	   r.get_identifier_as_rvalue (m_rvalue));
}

/* The implementation of class gcc::jit::recording::comment.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::comment.  */

void
recording::comment::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_comment (playback_location (r),
		   m_text->c_str ());
}

/* Implementation of recording::memento::make_debug_string for
   a comment "statement".  */

recording::string *
recording::comment::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "/* %s */",
			      m_text->c_str ());
}

/* Implementation of recording::memento::write_reproducer for
   comments.  */

void
recording::comment::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_add_comment (%s, /*gcc_jit_block *block */\n"
	   "                             %s, /* gcc_jit_location *loc */\n"
	   "                             %s); /* const char *text */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   m_text->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::conditional.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::conditional.  */

void
recording::conditional::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_conditional (playback_location (r),
		       m_boolval->playback_rvalue (),
		       playback_block (m_on_true),
		       playback_block (m_on_false));
}

/* Override the poisoned default implementation of
   gcc::jit::recording::statement::get_successor_blocks

   A conditional jump has 2 successor blocks.  */

vec <recording::block *>
recording::conditional::get_successor_blocks () const
{
  vec <block *> result;
  result.create (2);
  result.quick_push (m_on_true);
  result.quick_push (m_on_false);
  return result;
}

/* Implementation of recording::memento::make_debug_string for
   a conditional jump statement.  */

recording::string *
recording::conditional::make_debug_string ()
{
  if (m_on_false)
    return string::from_printf (m_ctxt,
				"if (%s) goto %s; else goto %s;",
				m_boolval->get_debug_string (),
				m_on_true->get_debug_string (),
				m_on_false->get_debug_string ());
  else
    return string::from_printf (m_ctxt,
				"if (%s) goto %s;",
				m_boolval->get_debug_string (),
				m_on_true->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   conditional statements.  */

void
recording::conditional::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_end_with_conditional (%s, /*gcc_jit_block *block */\n"
	   "                                      %s, /* gcc_jit_location *loc */\n"
	   "                                      %s, /* gcc_jit_rvalue *boolval */\n"
	   "                                      %s, /* gcc_jit_block *on_true */\n"
	   "                                      %s); /* gcc_jit_block *on_false */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   r.get_identifier_as_rvalue (m_boolval),
	   r.get_identifier (m_on_true),
	   r.get_identifier (m_on_false));
}

/* The implementation of class gcc::jit::recording::jump.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::jump.  */

void
recording::jump::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_jump (playback_location (r),
		m_target->playback_block ());
}

/* Override the poisoned default implementation of
   gcc::jit::recording::statement::get_successor_blocks

   An unconditional jump has 1 successor block.  */

vec <recording::block *>
recording::jump::get_successor_blocks () const
{
  vec <block *> result;
  result.create (1);
  result.quick_push (m_target);
  return result;
}

/* Implementation of recording::memento::make_debug_string for
   a unconditional jump statement.  */

recording::string *
recording::jump::make_debug_string ()
{
  return string::from_printf (m_ctxt,
			      "goto %s;",
			      m_target->get_debug_string ());
}

/* Implementation of recording::memento::write_reproducer for
   jump statements.  */

void
recording::jump::write_reproducer (reproducer &r)
{
  r.write ("  gcc_jit_block_end_with_jump (%s, /*gcc_jit_block *block */\n"
	   "                               %s, /* gcc_jit_location *loc */\n"
	   "                               %s); /* gcc_jit_block *target */\n",
	   r.get_identifier (get_block ()),
	   r.get_identifier (get_loc ()),
	   r.get_identifier (m_target));
}

/* The implementation of class gcc::jit::recording::return_.  */

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::return_.  */

void
recording::return_::replay_into (replayer *r)
{
  playback_block (get_block ())
    ->add_return (playback_location (r),
		  m_rvalue ? m_rvalue->playback_rvalue () : NULL);
}

/* Override the poisoned default implementation of
   gcc::jit::recording::statement::get_successor_blocks

   A return statement has no successor block.  */

vec <recording::block *>
recording::return_::get_successor_blocks () const
{
  vec <block *> result;
  result.create (0);
  return result;
}

/* Implementation of recording::memento::make_debug_string for
   a return statement (covers both those with and without rvalues).  */

recording::string *
recording::return_::make_debug_string ()
{
  if (m_rvalue)
    return string::from_printf (m_ctxt,
				"return %s;",
				m_rvalue->get_debug_string ());
  else
    return string::from_printf (m_ctxt,
				"return;");
}

/* Implementation of recording::memento::write_reproducer for
   return statements.  */

void
recording::return_::write_reproducer (reproducer &r)
{
  if (m_rvalue)
    r.write ("  gcc_jit_block_end_with_return (%s, /*gcc_jit_block *block */\n"
	     "                                 %s, /* gcc_jit_location *loc */\n"
	     "                                 %s); /* gcc_jit_rvalue *rvalue */\n",
	     r.get_identifier (get_block ()),
	     r.get_identifier (get_loc ()),
	     r.get_identifier_as_rvalue (m_rvalue));
  else
    r.write ("  gcc_jit_block_end_with_void_return (%s, /*gcc_jit_block *block */\n"
	     "                                      %s); /* gcc_jit_location *loc */\n",
	     r.get_identifier (get_block ()),
	     r.get_identifier (get_loc ()));
}

/* The implementation of class gcc::jit::recording::case_.  */

void
recording::case_::write_reproducer (reproducer &r)
{
  const char *id = r.make_identifier (this, "case");
  const char *fmt =
    "  gcc_jit_case *%s = \n"
    "    gcc_jit_context_new_case (%s, /*gcc_jit_context *ctxt */\n"
    "                              %s, /* gcc_jit_rvalue *min_value */\n"
    "                              %s, /* gcc_jit_rvalue *max_value */\n"
    "                              %s); /* gcc_jit_block *dest_block */\n";
  r.write (fmt,
	   id,
	   r.get_identifier (get_context ()),
	   r.get_identifier_as_rvalue (m_min_value),
	   r.get_identifier_as_rvalue (m_max_value),
	   r.get_identifier (m_dest_block));
}

recording::string *
recording::case_::make_debug_string ()
{
  return string::from_printf (get_context (),
			      "case %s ... %s: goto %s;",
			      m_min_value->get_debug_string (),
			      m_max_value->get_debug_string (),
			      m_dest_block->get_debug_string ());
}

/* The implementation of class gcc::jit::recording::switch_.  */

/* gcc::jit::recording::switch_'s constructor.  */

recording::switch_::switch_ (block *b,
			     location *loc,
			     rvalue *expr,
			     block *default_block,
			     int num_cases,
			     case_ **cases)
: statement (b, loc),
  m_expr (expr),
  m_default_block (default_block)
{
  m_cases.reserve_exact (num_cases);
  for (int i = 0; i< num_cases; i++)
    m_cases.quick_push (cases[i]);
}

/* Implementation of pure virtual hook recording::memento::replay_into
   for recording::switch_.  */

void
recording::switch_::replay_into (replayer *r)
{
  auto_vec <playback::case_> pcases;
  int i;
  recording::case_ *rcase;
  pcases.reserve_exact (m_cases.length ());
  FOR_EACH_VEC_ELT (m_cases, i, rcase)
    {
      playback::case_ pcase (rcase->get_min_value ()->playback_rvalue (),
			     rcase->get_max_value ()->playback_rvalue (),
			     rcase->get_dest_block ()->playback_block ());
      pcases.safe_push (pcase);
    }
  playback_block (get_block ())
    ->add_switch (playback_location (r),
		  m_expr->playback_rvalue (),
		  m_default_block->playback_block (),
		  &pcases);
}

/* Override the poisoned default implementation of
   gcc::jit::recording::statement::get_successor_blocks

   A switch statement has (NUM_CASES + 1) successor blocks.  */

vec <recording::block *>
recording::switch_::get_successor_blocks () const
{
  vec <block *> result;
  result.create (m_cases.length () + 1);
  result.quick_push (m_default_block);
  int i;
  case_ *c;
  FOR_EACH_VEC_ELT (m_cases, i, c)
    result.quick_push (c->get_dest_block ());
  return result;
}

/* Implementation of recording::memento::make_debug_string for
   a switch statement.  */

recording::string *
recording::switch_::make_debug_string ()
{
  auto_vec <char> cases_str;
  int i;
  case_ *c;
  FOR_EACH_VEC_ELT (m_cases, i, c)
    {
      size_t len = strlen (c->get_debug_string ());
      unsigned idx = cases_str.length ();
      cases_str.safe_grow (idx + 1 + len);
      cases_str[idx] = ' ';
      memcpy (&(cases_str[idx + 1]),
	      c->get_debug_string (),
	      len);
    }
  cases_str.safe_push ('\0');

  return string::from_printf (m_ctxt,
			      "switch (%s) {default: goto %s;%s}",
			      m_expr->get_debug_string (),
			      m_default_block->get_debug_string (),
			      &cases_str[0]);
}

/* Implementation of recording::memento::write_reproducer for
   switch statements.  */

void
recording::switch_::write_reproducer (reproducer &r)
{
  r.make_identifier (this, "switch");
  int i;
  case_ *c;
  const char *cases_id =
    r.make_tmp_identifier ("cases_for", this);
  r.write ("  gcc_jit_case *%s[%i] = {\n",
	   cases_id,
	   m_cases.length ());
  FOR_EACH_VEC_ELT (m_cases, i, c)
    r.write ("    %s,\n", r.get_identifier (c));
  r.write ("  };\n");
  const char *fmt =
    "  gcc_jit_block_end_with_switch (%s, /*gcc_jit_block *block */\n"
    "                                 %s, /* gcc_jit_location *loc */\n"
    "                                 %s, /* gcc_jit_rvalue *expr */\n"
    "                                 %s, /* gcc_jit_block *default_block */\n"
    "                                 %i, /* int num_cases */\n"
    "                                 %s); /* gcc_jit_case **cases */\n";
    r.write (fmt,
	     r.get_identifier (get_block ()),
	     r.get_identifier (get_loc ()),
	     r.get_identifier_as_rvalue (m_expr),
	     r.get_identifier (m_default_block),
	     m_cases.length (),
	     cases_id);
}

} // namespace gcc::jit

} // namespace gcc
