/* Implementation of the C API; all wrappers into the internal C++ API
   Copyright (C) 2013-2018 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 "timevar.h"
#include "typed-splay-tree.h"

#include "libgccjit.h"
#include "jit-recording.h"
#include "jit-result.h"

/* The opaque types used by the public API are actually subclasses
   of the gcc::jit::recording classes.  */

struct gcc_jit_context : public gcc::jit::recording::context
{
  gcc_jit_context (gcc_jit_context *parent_ctxt) :
    context (parent_ctxt)
  {}
};

struct gcc_jit_result : public gcc::jit::result
{
};

struct gcc_jit_object : public gcc::jit::recording::memento
{
};

struct gcc_jit_location : public gcc::jit::recording::location
{
};

struct gcc_jit_type : public gcc::jit::recording::type
{
};

struct gcc_jit_struct : public gcc::jit::recording::struct_
{
};

struct gcc_jit_field : public gcc::jit::recording::field
{
};

struct gcc_jit_function : public gcc::jit::recording::function
{
};

struct gcc_jit_block : public gcc::jit::recording::block
{
};

struct gcc_jit_rvalue : public gcc::jit::recording::rvalue
{
};

struct gcc_jit_lvalue : public gcc::jit::recording::lvalue
{
};

struct gcc_jit_param : public gcc::jit::recording::param
{
};

struct gcc_jit_case : public gcc::jit::recording::case_
{
};

struct gcc_jit_timer : public timer
{
};

/**********************************************************************
 Error-handling.

 We try to gracefully handle API usage errors by being defensive
 at the API boundary.
 **********************************************************************/

#define JIT_BEGIN_STMT do {
#define JIT_END_STMT   } while(0)

/* Each of these error-handling macros determines if TEST_EXPR holds.

   If TEXT_EXPR fails to hold we return from the enclosing function and
   print an error, either via adding an error on the given context CTXT
   if CTXT is non-NULL, falling back to simply printing to stderr if CTXT
   is NULL.

   They have to be macros since they inject their "return" into the
   function they are placed in.

   The variant macros express:

     (A) whether or not we need to return a value:
	    RETURN_VAL_IF_FAIL* vs
	    RETURN_IF_FAIL*,
	 with the former returning RETURN_EXPR, and
	    RETURN_NULL_IF_FAIL*
	 for the common case where a NULL value is to be returned on
	 error, and

     (B) whether the error message is to be directly printed:
	   RETURN_*IF_FAIL
	 or is a format string with some number of arguments:
	   RETURN_*IF_FAIL_PRINTF*

   They all use JIT_BEGIN_STMT/JIT_END_STMT so they can be written with
   trailing semicolons.
*/

#define RETURN_VAL_IF_FAIL(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_MSG)	\
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));	\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF1(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,			\
		   __func__, (A0));				\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF2(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1));				\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF3(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1), (A2));			\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF4(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1), (A2), (A3));			\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF5(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1), (A2), (A3), (A4));	\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_VAL_IF_FAIL_PRINTF6(TEST_EXPR, RETURN_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1), (A2), (A3), (A4), (A5));	\
	return (RETURN_EXPR);						\
      }								\
  JIT_END_STMT

#define RETURN_NULL_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG) \
  RETURN_VAL_IF_FAIL ((TEST_EXPR), NULL, (CTXT), (LOC), (ERR_MSG))

#define RETURN_NULL_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
  RETURN_VAL_IF_FAIL_PRINTF1 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0)

#define RETURN_NULL_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
  RETURN_VAL_IF_FAIL_PRINTF2 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1)

#define RETURN_NULL_IF_FAIL_PRINTF3(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2) \
  RETURN_VAL_IF_FAIL_PRINTF3 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2)

#define RETURN_NULL_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
  RETURN_VAL_IF_FAIL_PRINTF4 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3)

#define RETURN_NULL_IF_FAIL_PRINTF5(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4) \
  RETURN_VAL_IF_FAIL_PRINTF5 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4)

#define RETURN_NULL_IF_FAIL_PRINTF6(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5) \
  RETURN_VAL_IF_FAIL_PRINTF6 (TEST_EXPR, NULL, CTXT, LOC, ERR_FMT, A0, A1, A2, A3, A4, A5)

#define RETURN_IF_FAIL(TEST_EXPR, CTXT, LOC, ERR_MSG)			\
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: %s", __func__, (ERR_MSG));		\
	return;							\
      }								\
  JIT_END_STMT

#define RETURN_IF_FAIL_PRINTF1(TEST_EXPR, CTXT, LOC, ERR_FMT, A0) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0));					\
	return;							\
      }								\
  JIT_END_STMT

#define RETURN_IF_FAIL_PRINTF2(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1));				\
	return;							\
      }								\
  JIT_END_STMT

#define RETURN_IF_FAIL_PRINTF4(TEST_EXPR, CTXT, LOC, ERR_FMT, A0, A1, A2, A3) \
  JIT_BEGIN_STMT							\
    if (!(TEST_EXPR))							\
      {								\
	jit_error ((CTXT), (LOC), "%s: " ERR_FMT,				\
		   __func__, (A0), (A1), (A2), (A3));			\
	return;							\
      }								\
  JIT_END_STMT

/* Check that BLOCK is non-NULL, and that it's OK to add statements to
   it.  This will fail if BLOCK has already been terminated by some
   kind of jump or a return.  */
#define RETURN_IF_NOT_VALID_BLOCK(BLOCK, LOC)				\
  JIT_BEGIN_STMT							\
    RETURN_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
    RETURN_IF_FAIL_PRINTF2 (						\
      !(BLOCK)->has_been_terminated (),				\
      (BLOCK)->get_context (),						\
      (LOC),								\
      "adding to terminated block: %s (already terminated by: %s)",	\
      (BLOCK)->get_debug_string (),					\
      (BLOCK)->get_last_statement ()->get_debug_string ());		\
  JIT_END_STMT

/* As RETURN_IF_NOT_VALID_BLOCK, but injecting a "return NULL;" if it
   fails.  */
#define RETURN_NULL_IF_NOT_VALID_BLOCK(BLOCK, LOC)			\
  JIT_BEGIN_STMT							\
    RETURN_NULL_IF_FAIL ((BLOCK), NULL, (LOC), "NULL block");		\
    RETURN_NULL_IF_FAIL_PRINTF2 (					\
      !(BLOCK)->has_been_terminated (),				\
      (BLOCK)->get_context (),						\
      (LOC),								\
      "adding to terminated block: %s (already terminated by: %s)",	\
      (BLOCK)->get_debug_string (),					\
      (BLOCK)->get_last_statement ()->get_debug_string ());		\
  JIT_END_STMT

/* Format the given string, and report it as an error, either on CTXT
   if non-NULL, or by printing to stderr if we have a NULL context.
   LOC gives the source location where the error occcurred, and can be
   NULL.  */

static void
jit_error (gcc::jit::recording::context *ctxt,
	   gcc_jit_location *loc,
	   const char *fmt, ...)
  GNU_PRINTF(3, 4);

static void
jit_error (gcc::jit::recording::context *ctxt,
	   gcc_jit_location *loc,
	   const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);

  if (ctxt)
    ctxt->add_error_va (loc, fmt, ap);
  else
    {
      /* No context?  Send to stderr.  */
      vfprintf (stderr, fmt, ap);
      fprintf (stderr, "\n");
    }

  va_end (ap);
}

/* Determine whether or not we can write to lvalues of type LTYPE from
   rvalues of type RTYPE, detecting type errors such as attempting to
   write to an int with a string literal (without an explicit cast).

   This is implemented by calling the
   gcc::jit::recording::type::accepts_writes_from virtual function on
   LTYPE.  */

static bool
compatible_types (gcc::jit::recording::type *ltype,
		  gcc::jit::recording::type *rtype)
{
  return ltype->accepts_writes_from (rtype);
}

/* Public entrypoint for acquiring a gcc_jit_context.
   Note that this creates a new top-level context; contrast with
   gcc_jit_context_new_child_context below.

   The real work is done in the constructor for
   gcc::jit::recording::context in jit-recording.c. */

gcc_jit_context *
gcc_jit_context_acquire (void)
{
  gcc_jit_context *ctxt = new gcc_jit_context (NULL);
  ctxt->log ("new top-level ctxt: %p", (void *)ctxt);
  return ctxt;
}

/* Public entrypoint for releasing a gcc_jit_context.
   The real work is done in the destructor for
   gcc::jit::recording::context in jit-recording.c.  */

void
gcc_jit_context_release (gcc_jit_context *ctxt)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
  JIT_LOG_FUNC (ctxt->get_logger ());
  ctxt->log ("deleting ctxt: %p", (void *)ctxt);
  delete ctxt;
}

/* Public entrypoint for creating a child context within
   PARENT_CTXT.  See description in libgccjit.h.

   The real work is done in the constructor for
   gcc::jit::recording::context in jit-recording.c. */

gcc_jit_context *
gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt)
{
  RETURN_NULL_IF_FAIL (parent_ctxt, NULL, NULL, "NULL parent ctxt");
  JIT_LOG_FUNC (parent_ctxt->get_logger ());
  parent_ctxt->log ("parent_ctxt: %p", (void *)parent_ctxt);
  gcc_jit_context *child_ctxt = new gcc_jit_context (parent_ctxt);
  child_ctxt->log ("new child_ctxt: %p", (void *)child_ctxt);
  return child_ctxt;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
     gcc::jit::recording::context::new_location
   method in jit-recording.c.  */

gcc_jit_location *
gcc_jit_context_new_location (gcc_jit_context *ctxt,
			      const char *filename,
			      int line,
			      int column)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  return (gcc_jit_location *)ctxt->new_location (filename, line, column, true);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a location is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_location_as_object (gcc_jit_location *loc)
{
  RETURN_NULL_IF_FAIL (loc, NULL, NULL, "NULL location");

  return static_cast <gcc_jit_object *> (loc->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a type is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_type_as_object (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  return static_cast <gcc_jit_object *> (type->as_object ());
}

/* Public entrypoint for getting a specific type from a context.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::get_type method, in
   jit-recording.c  */

gcc_jit_type *
gcc_jit_context_get_type (gcc_jit_context *ctxt,
			  enum gcc_jit_types type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_PRINTF1 (
    (type >= GCC_JIT_TYPE_VOID
     && type <= GCC_JIT_TYPE_FILE_PTR),
    ctxt, NULL,
    "unrecognized value for enum gcc_jit_types: %i", type);

  return (gcc_jit_type *)ctxt->get_type (type);
}

/* Public entrypoint for getting the integer type of the given size and
   signedness.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::get_int_type method,
   in jit-recording.c.  */

gcc_jit_type *
gcc_jit_context_get_int_type (gcc_jit_context *ctxt,
			      int num_bytes, int is_signed)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (num_bytes >= 0, ctxt, NULL, "negative size");

  return (gcc_jit_type *)ctxt->get_int_type (num_bytes, is_signed);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::type::get_pointer method, in
   jit-recording.c  */

gcc_jit_type *
gcc_jit_type_get_pointer (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  return (gcc_jit_type *)type->get_pointer ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::type::get_const method, in
   jit-recording.c.  */

gcc_jit_type *
gcc_jit_type_get_const (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  return (gcc_jit_type *)type->get_const ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::type::get_volatile method, in
   jit-recording.c.  */

gcc_jit_type *
gcc_jit_type_get_volatile (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  return (gcc_jit_type *)type->get_volatile ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_array_type method, in
   jit-recording.c.  */

gcc_jit_type *
gcc_jit_context_new_array_type (gcc_jit_context *ctxt,
				gcc_jit_location *loc,
				gcc_jit_type *element_type,
				int num_elements)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size");

  return (gcc_jit_type *)ctxt->new_array_type (loc,
					       element_type,
					       num_elements);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_field method, in
   jit-recording.c.  */

gcc_jit_field *
gcc_jit_context_new_field (gcc_jit_context *ctxt,
			   gcc_jit_location *loc,
			   gcc_jit_type *type,
			   const char *name)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  RETURN_NULL_IF_FAIL_PRINTF2 (
    type->has_known_size (),
    ctxt, loc,
    "unknown size for field \"%s\" (type: %s)",
    name,
    type->get_debug_string ());

  return (gcc_jit_field *)ctxt->new_field (loc, type, name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a field is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_field_as_object (gcc_jit_field *field)
{
  RETURN_NULL_IF_FAIL (field, NULL, NULL, "NULL field");

  return static_cast <gcc_jit_object *> (field->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_struct_type method,
   immediately followed by a "set_fields" call on the resulting
   gcc::jit::recording::compound_type *, both in jit-recording.c  */

gcc_jit_struct *
gcc_jit_context_new_struct_type (gcc_jit_context *ctxt,
				 gcc_jit_location *loc,
				 const char *name,
				 int num_fields,
				 gcc_jit_field **fields)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  if (num_fields)
    RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
  for (int i = 0; i < num_fields; i++)
    {
      RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
      RETURN_NULL_IF_FAIL_PRINTF2 (
	fields[i]->get_container () == NULL,
	ctxt, loc,
	"%s is already a field of %s",
	fields[i]->get_debug_string (),
	fields[i]->get_container ()->get_debug_string ());
    }

  gcc::jit::recording::struct_ *result =
    ctxt->new_struct_type (loc, name);
  result->set_fields (loc,
		      num_fields,
		      (gcc::jit::recording::field **)fields);
  return static_cast<gcc_jit_struct *> (result);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_struct_type method in
   jit-recording.c.  */

gcc_jit_struct *
gcc_jit_context_new_opaque_struct (gcc_jit_context *ctxt,
				   gcc_jit_location *loc,
				   const char *name)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");

  return (gcc_jit_struct *)ctxt->new_struct_type (loc, name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::struct_::as_object method in
   jit-recording.h.  */

gcc_jit_type *
gcc_jit_struct_as_type (gcc_jit_struct *struct_type)
{
  RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct_type");

  return static_cast <gcc_jit_type *> (struct_type->as_type ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::compound_type::set_fields method in
   jit-recording.c.  */

void
gcc_jit_struct_set_fields (gcc_jit_struct *struct_type,
			   gcc_jit_location *loc,
			   int num_fields,
			   gcc_jit_field **fields)
{
  RETURN_IF_FAIL (struct_type, NULL, loc, "NULL struct_type");
  gcc::jit::recording::context *ctxt = struct_type->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL_PRINTF1 (
    struct_type->get_fields () == NULL, ctxt, loc,
    "%s already has had fields set",
    struct_type->get_debug_string ());
  if (num_fields)
    RETURN_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
  for (int i = 0; i < num_fields; i++)
    {
      RETURN_IF_FAIL_PRINTF2 (
	fields[i],
	ctxt, loc,
	"%s: NULL field ptr at index %i",
	struct_type->get_debug_string (),
	i);
      RETURN_IF_FAIL_PRINTF2 (
	fields[i]->get_container () == NULL,
	ctxt, loc,
	"%s is already a field of %s",
	fields[i]->get_debug_string (),
	fields[i]->get_container ()->get_debug_string ());
    }

  struct_type->set_fields (loc, num_fields,
			   (gcc::jit::recording::field **)fields);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_union_type method,
   immediately followed by a "set_fields" call on the resulting
   gcc::jit::recording::compound_type *, both in jit-recording.c  */

gcc_jit_type *
gcc_jit_context_new_union_type (gcc_jit_context *ctxt,
				gcc_jit_location *loc,
				const char *name,
				int num_fields,
				gcc_jit_field **fields)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  if (num_fields)
    RETURN_NULL_IF_FAIL (fields, ctxt, loc, "NULL fields ptr");
  for (int i = 0; i < num_fields; i++)
    {
      RETURN_NULL_IF_FAIL (fields[i], ctxt, loc, "NULL field ptr");
      RETURN_NULL_IF_FAIL_PRINTF2 (
	fields[i]->get_container () == NULL,
	ctxt, loc,
	"%s is already a field of %s",
	fields[i]->get_debug_string (),
	fields[i]->get_container ()->get_debug_string ());
    }

  gcc::jit::recording::union_ *result =
    ctxt->new_union_type (loc, name);
  result->set_fields (loc,
		      num_fields,
		      (gcc::jit::recording::field **)fields);
  return (gcc_jit_type *) (result);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_function_ptr_type method,
   in jit-recording.c  */

gcc_jit_type *
gcc_jit_context_new_function_ptr_type (gcc_jit_context *ctxt,
				       gcc_jit_location *loc,
				       gcc_jit_type *return_type,
				       int num_params,
				       gcc_jit_type **param_types,
				       int is_variadic)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
  RETURN_NULL_IF_FAIL (
    (num_params == 0) || param_types,
    ctxt, loc,
    "NULL param_types creating function pointer type");
  for (int i = 0; i < num_params; i++)
    RETURN_NULL_IF_FAIL_PRINTF1 (
      param_types[i],
      ctxt, loc,
      "NULL parameter type %i creating function pointer type", i);

  return (gcc_jit_type*)
    ctxt->new_function_ptr_type (loc, return_type,
				 num_params,
				 (gcc::jit::recording::type **)param_types,
				 is_variadic);
}

/* Constructing functions.  */

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_param method, in jit-recording.c  */

gcc_jit_param *
gcc_jit_context_new_param (gcc_jit_context *ctxt,
			   gcc_jit_location *loc,
			   gcc_jit_type *type,
			   const char *name)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");

  return (gcc_jit_param *)ctxt->new_param (loc, type, name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a param is a memento),
   in jit-recording.h.  */

gcc_jit_object *
gcc_jit_param_as_object (gcc_jit_param *param)
{
  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");

  return static_cast <gcc_jit_object *> (param->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::param::as_lvalue method in jit-recording.h.  */

gcc_jit_lvalue *
gcc_jit_param_as_lvalue (gcc_jit_param *param)
{
  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");

  return (gcc_jit_lvalue *)param->as_lvalue ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::lvalue::as_rvalue method (a param is an rvalue),
   in jit-recording.h.  */

gcc_jit_rvalue *
gcc_jit_param_as_rvalue (gcc_jit_param *param)
{
  RETURN_NULL_IF_FAIL (param, NULL, NULL, "NULL param");

  return (gcc_jit_rvalue *)param->as_rvalue ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_function method, in
   jit-recording.c.  */

gcc_jit_function *
gcc_jit_context_new_function (gcc_jit_context *ctxt,
			      gcc_jit_location *loc,
			      enum gcc_jit_function_kind kind,
			      gcc_jit_type *return_type,
			      const char *name,
			      int num_params,
			      gcc_jit_param **params,
			      int is_variadic)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    ((kind >= GCC_JIT_FUNCTION_EXPORTED)
     && (kind <= GCC_JIT_FUNCTION_ALWAYS_INLINE)),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_function_kind: %i",
    kind);
  RETURN_NULL_IF_FAIL (return_type, ctxt, loc, "NULL return_type");
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  /* The assembler can only handle certain names, so for now, enforce
     C's rules for identiers upon the name, using ISALPHA and ISALNUM
     from safe-ctype.h to ignore the current locale.
     Eventually we'll need some way to interact with e.g. C++ name
     mangling.  */
  {
    /* Leading char: */
    char ch = *name;
    RETURN_NULL_IF_FAIL_PRINTF2 (
	ISALPHA (ch) || ch == '_',
	ctxt, loc,
	"name \"%s\" contains invalid character: '%c'",
	name, ch);
    /* Subsequent chars: */
    for (const char *ptr = name + 1; (ch = *ptr); ptr++)
      {
	RETURN_NULL_IF_FAIL_PRINTF2 (
	  ISALNUM (ch) || ch == '_',
	  ctxt, loc,
	  "name \"%s\" contains invalid character: '%c'",
	  name, ch);
      }
  }
  RETURN_NULL_IF_FAIL_PRINTF1 (
    (num_params == 0) || params,
    ctxt, loc,
    "NULL params creating function %s", name);
  for (int i = 0; i < num_params; i++)
    {
      RETURN_NULL_IF_FAIL_PRINTF2 (
	params[i],
	ctxt, loc,
	"NULL parameter %i creating function %s", i, name);
      RETURN_NULL_IF_FAIL_PRINTF5 (
	params[i]->get_scope () == NULL,
	ctxt, loc,
	"parameter %i \"%s\""
	" (type: %s)"
	" for function %s"
	" was already used for function %s",
	i, params[i]->get_debug_string (),
	params[i]->get_type ()->get_debug_string (),
	name,
	params[i]->get_scope ()->get_debug_string ());
    }

  return (gcc_jit_function*)
    ctxt->new_function (loc, kind, return_type, name,
			num_params,
			(gcc::jit::recording::param **)params,
			is_variadic,
			BUILT_IN_NONE);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::get_builtin_function method, in
   jit-recording.c.  */

gcc_jit_function *
gcc_jit_context_get_builtin_function (gcc_jit_context *ctxt,
				      const char *name)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (name, ctxt, NULL, "NULL name");

  return static_cast <gcc_jit_function *> (ctxt->get_builtin_function (name));
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a function is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_function_as_object (gcc_jit_function *func)
{
  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");

  return static_cast <gcc_jit_object *> (func->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::function::get_param method, in
   jit-recording.h.  */

gcc_jit_param *
gcc_jit_function_get_param (gcc_jit_function *func, int index)
{
  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
  gcc::jit::recording::context *ctxt = func->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (index >= 0, ctxt, NULL, "negative index");
  int num_params = func->get_params ().length ();
  RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
			       ctxt, NULL,
			       "index of %d is too large (%s has %d params)",
			       index,
			       func->get_debug_string (),
			       num_params);

  return static_cast <gcc_jit_param *> (func->get_param (index));
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::function::dump_to_dot method, in
   jit-recording.c.  */

void
gcc_jit_function_dump_to_dot (gcc_jit_function *func,
			      const char *path)
{
  RETURN_IF_FAIL (func, NULL, NULL, "NULL function");
  gcc::jit::recording::context *ctxt = func->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");

  func->dump_to_dot (path);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::function::new_block method, in
   jit-recording.c.  */

gcc_jit_block*
gcc_jit_function_new_block (gcc_jit_function *func,
			    const char *name)
{
  RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function");
  JIT_LOG_FUNC (func->get_context ()->get_logger ());
  RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
		       func->get_context (), NULL,
		       "cannot add block to an imported function");
  /* name can be NULL.  */

  return (gcc_jit_block *)func->new_block (name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a block is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_block_as_object (gcc_jit_block *block)
{
  RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");

  return static_cast <gcc_jit_object *> (block->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::get_function method, in
   jit-recording.h.  */

gcc_jit_function *
gcc_jit_block_get_function (gcc_jit_block *block)
{
  RETURN_NULL_IF_FAIL (block, NULL, NULL, "NULL block");

  return static_cast <gcc_jit_function *> (block->get_function ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_global method, in
   jit-recording.c.  */

gcc_jit_lvalue *
gcc_jit_context_new_global (gcc_jit_context *ctxt,
			    gcc_jit_location *loc,
			    enum gcc_jit_global_kind kind,
			    gcc_jit_type *type,
			    const char *name)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    ((kind >= GCC_JIT_GLOBAL_EXPORTED)
     && (kind <= GCC_JIT_GLOBAL_IMPORTED)),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_global_kind: %i",
    kind);
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  RETURN_NULL_IF_FAIL_PRINTF2 (
    type->has_known_size (),
    ctxt, loc,
    "unknown size for global \"%s\" (type: %s)",
    name,
    type->get_debug_string ());

  return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (an lvalue is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
{
  RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");

  return static_cast <gcc_jit_object *> (lvalue->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::lvalue::as_rvalue method in jit-recording.h.  */

gcc_jit_rvalue *
gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
{
  RETURN_NULL_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");

  return (gcc_jit_rvalue *)lvalue->as_rvalue ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (an rvalue is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
{
  RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");

  return static_cast <gcc_jit_object *> (rvalue->as_object ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::rvalue::get_type method, in
   jit-recording.h.  */

gcc_jit_type *
gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
{
  RETURN_NULL_IF_FAIL (rvalue, NULL, NULL, "NULL rvalue");

  return static_cast <gcc_jit_type *> (rvalue->get_type ());
}

/* Verify that NUMERIC_TYPE is non-NULL, and that it is a "numeric"
   type i.e. it satisfies gcc::jit::type::is_numeric (), such as the
   result of gcc_jit_context_get_type (GCC_JIT_TYPE_INT).  */

#define RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE(CTXT, NUMERIC_TYPE) \
  JIT_BEGIN_STMT						     \
  RETURN_NULL_IF_FAIL (NUMERIC_TYPE, CTXT, NULL, "NULL type"); \
  RETURN_NULL_IF_FAIL_PRINTF1 (                                \
    NUMERIC_TYPE->is_numeric (), ctxt, NULL,                   \
    "not a numeric type: %s",                                  \
    NUMERIC_TYPE->get_debug_string ()); \
  JIT_END_STMT

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_rvalue_from_int method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_int (gcc_jit_context *ctxt,
				     gcc_jit_type *numeric_type,
				     int value)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);

  return ((gcc_jit_rvalue *)ctxt
	  ->new_rvalue_from_const <int> (numeric_type, value));
}

/* FIXME. */

gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_long (gcc_jit_context *ctxt,
				      gcc_jit_type *numeric_type,
				      long value)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);

  return ((gcc_jit_rvalue *)ctxt
	  ->new_rvalue_from_const <long> (numeric_type, value));
}

/* Public entrypoint.  See description in libgccjit.h.

   This is essentially equivalent to:
      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
   albeit with slightly different error messages if an error occurs.  */

gcc_jit_rvalue *
gcc_jit_context_zero (gcc_jit_context *ctxt,
		      gcc_jit_type *numeric_type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);

  return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0);
}

/* Public entrypoint.  See description in libgccjit.h.

   This is essentially equivalent to:
      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
   albeit with slightly different error messages if an error occurs.  */

gcc_jit_rvalue *
gcc_jit_context_one (gcc_jit_context *ctxt,
		     gcc_jit_type *numeric_type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);

  return gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_rvalue_from_double method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_double (gcc_jit_context *ctxt,
					gcc_jit_type *numeric_type,
					double value)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL_NONNULL_NUMERIC_TYPE (ctxt, numeric_type);

  return ((gcc_jit_rvalue *)ctxt
	  ->new_rvalue_from_const <double> (numeric_type, value));
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_rvalue_from_ptr method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt,
				     gcc_jit_type *pointer_type,
				     void *value)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
  RETURN_NULL_IF_FAIL_PRINTF1 (
    pointer_type->is_pointer (),
    ctxt, NULL,
    "not a pointer type (type: %s)",
    pointer_type->get_debug_string ());

  return ((gcc_jit_rvalue *)ctxt
	  ->new_rvalue_from_const <void *> (pointer_type, value));
}

/* Public entrypoint.  See description in libgccjit.h.

   This is essentially equivalent to:
      gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
   albeit with slightly different error messages if an error occurs.  */

gcc_jit_rvalue *
gcc_jit_context_null (gcc_jit_context *ctxt,
		      gcc_jit_type *pointer_type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type");
  RETURN_NULL_IF_FAIL_PRINTF1 (
    pointer_type->is_pointer (),
    ctxt, NULL,
    "not a pointer type (type: %s)",
    pointer_type->get_debug_string ());

  return gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_string_literal method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_string_literal (gcc_jit_context *ctxt,
				    const char *value)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (value, ctxt, NULL, "NULL value");

  return (gcc_jit_rvalue *)ctxt->new_string_literal (value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_unary_op method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
			      gcc_jit_location *loc,
			      enum gcc_jit_unary_op op,
			      gcc_jit_type *result_type,
			      gcc_jit_rvalue *rvalue)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    (op >= GCC_JIT_UNARY_OP_MINUS
     && op <= GCC_JIT_UNARY_OP_ABS),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_unary_op: %i",
    op);
  RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
  RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");

  return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
}

/* Determine if OP is a valid value for enum gcc_jit_binary_op.
   For use by both gcc_jit_context_new_binary_op and
   gcc_jit_block_add_assignment_op.  */

static bool
valid_binary_op_p (enum gcc_jit_binary_op op)
{
  return (op >= GCC_JIT_BINARY_OP_PLUS
	  && op <= GCC_JIT_BINARY_OP_RSHIFT);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_binary_op method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
			       gcc_jit_location *loc,
			       enum gcc_jit_binary_op op,
			       gcc_jit_type *result_type,
			       gcc_jit_rvalue *a, gcc_jit_rvalue *b)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    valid_binary_op_p (op),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_binary_op: %i",
    op);
  RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
  RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
  RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
  RETURN_NULL_IF_FAIL_PRINTF4 (
    a->get_type ()->unqualified () == b->get_type ()->unqualified (),
    ctxt, loc,
    "mismatching types for binary op:"
    " a: %s (type: %s) b: %s (type: %s)",
    a->get_debug_string (),
    a->get_type ()->get_debug_string (),
    b->get_debug_string (),
    b->get_type ()->get_debug_string ());

  return (gcc_jit_rvalue *)ctxt->new_binary_op (loc, op, result_type, a, b);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_comparison method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_comparison (gcc_jit_context *ctxt,
				gcc_jit_location *loc,
				enum gcc_jit_comparison op,
				gcc_jit_rvalue *a, gcc_jit_rvalue *b)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    (op >= GCC_JIT_COMPARISON_EQ
     && op <= GCC_JIT_COMPARISON_GE),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_comparison: %i",
    op);
  RETURN_NULL_IF_FAIL (a, ctxt, loc, "NULL a");
  RETURN_NULL_IF_FAIL (b, ctxt, loc, "NULL b");
  RETURN_NULL_IF_FAIL_PRINTF4 (
    a->get_type ()->unqualified () == b->get_type ()->unqualified (),
    ctxt, loc,
    "mismatching types for comparison:"
    " a: %s (type: %s) b: %s (type: %s)",
    a->get_debug_string (),
    a->get_type ()->get_debug_string (),
    b->get_debug_string (),
    b->get_type ()->get_debug_string ());

  return (gcc_jit_rvalue *)ctxt->new_comparison (loc, op, a, b);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_call method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_call (gcc_jit_context *ctxt,
			  gcc_jit_location *loc,
			  gcc_jit_function *func,
			  int numargs , gcc_jit_rvalue **args)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (func, ctxt, loc, "NULL function");
  if (numargs)
    RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");

  int min_num_params = func->get_params ().length ();
  bool is_variadic = func->is_variadic ();

  RETURN_NULL_IF_FAIL_PRINTF3 (
    numargs >= min_num_params,
    ctxt, loc,
    "not enough arguments to function \"%s\""
    " (got %i args, expected %i)",
    func->get_name ()->c_str (),
    numargs, min_num_params);

  RETURN_NULL_IF_FAIL_PRINTF3 (
    (numargs == min_num_params || is_variadic),
    ctxt, loc,
    "too many arguments to function \"%s\""
    " (got %i args, expected %i)",
    func->get_name ()->c_str (),
    numargs, min_num_params);

  for (int i = 0; i < min_num_params; i++)
    {
      gcc::jit::recording::param *param = func->get_param (i);
      gcc_jit_rvalue *arg = args[i];

      RETURN_NULL_IF_FAIL_PRINTF4 (
	arg,
	ctxt, loc,
	"NULL argument %i to function \"%s\":"
	" param %s (type: %s)",
	i + 1,
	func->get_name ()->c_str (),
	param->get_debug_string (),
	param->get_type ()->get_debug_string ());

      RETURN_NULL_IF_FAIL_PRINTF6 (
	compatible_types (param->get_type (),
			  arg->get_type ()),
	ctxt, loc,
	"mismatching types for argument %d of function \"%s\":"
	" assignment to param %s (type: %s) from %s (type: %s)",
	i + 1,
	func->get_name ()->c_str (),
	param->get_debug_string (),
	param->get_type ()->get_debug_string (),
	arg->get_debug_string (),
	arg->get_type ()->get_debug_string ());
    }

  return (gcc_jit_rvalue *)ctxt->new_call (loc,
					   func,
					   numargs,
					   (gcc::jit::recording::rvalue **)args);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_call_through_ptr method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,
				      gcc_jit_location *loc,
				      gcc_jit_rvalue *fn_ptr,
				      int numargs, gcc_jit_rvalue **args)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (fn_ptr, ctxt, loc, "NULL fn_ptr");
  if (numargs)
    RETURN_NULL_IF_FAIL (args, ctxt, loc, "NULL args");

  gcc::jit::recording::type *ptr_type = fn_ptr->get_type ()->dereference ();
  RETURN_NULL_IF_FAIL_PRINTF2 (
    ptr_type, ctxt, loc,
    "fn_ptr is not a ptr: %s"
    " type: %s",
    fn_ptr->get_debug_string (),
    fn_ptr->get_type ()->get_debug_string ());

  gcc::jit::recording::function_type *fn_type =
    ptr_type->dyn_cast_function_type();
  RETURN_NULL_IF_FAIL_PRINTF2 (
    fn_type, ctxt, loc,
    "fn_ptr is not a function ptr: %s"
    " type: %s",
    fn_ptr->get_debug_string (),
    fn_ptr->get_type ()->get_debug_string ());

  int min_num_params = fn_type->get_param_types ().length ();
  bool is_variadic = fn_type->is_variadic ();

  RETURN_NULL_IF_FAIL_PRINTF3 (
    numargs >= min_num_params,
    ctxt, loc,
    "not enough arguments to fn_ptr: %s"
    " (got %i args, expected %i)",
    fn_ptr->get_debug_string (),
    numargs, min_num_params);

  RETURN_NULL_IF_FAIL_PRINTF3 (
    (numargs == min_num_params || is_variadic),
    ctxt, loc,
    "too many arguments to fn_ptr: %s"
    " (got %i args, expected %i)",
    fn_ptr->get_debug_string (),
    numargs, min_num_params);

  for (int i = 0; i < min_num_params; i++)
    {
      gcc::jit::recording::type *param_type = fn_type->get_param_types ()[i];
      gcc_jit_rvalue *arg = args[i];

      RETURN_NULL_IF_FAIL_PRINTF3 (
	arg,
	ctxt, loc,
	"NULL argument %i to fn_ptr: %s"
	" (type: %s)",
	i + 1,
	fn_ptr->get_debug_string (),
	param_type->get_debug_string ());

      RETURN_NULL_IF_FAIL_PRINTF6 (
	compatible_types (param_type,
			  arg->get_type ()),
	ctxt, loc,
	"mismatching types for argument %d of fn_ptr: %s:"
	" assignment to param %d (type: %s) from %s (type: %s)",
	i + 1,
	fn_ptr->get_debug_string (),
	i + 1,
	param_type->get_debug_string (),
	arg->get_debug_string (),
	arg->get_type ()->get_debug_string ());
    }

  return (gcc_jit_rvalue *)(
	    ctxt->new_call_through_ptr (loc,
					fn_ptr,
					numargs,
					(gcc::jit::recording::rvalue **)args));
}

/* Helper function for determining if we can cast an rvalue from SRC_TYPE
   to DST_TYPE, for use by gcc_jit_context_new_cast.

   We only permit these kinds of cast:

     int <-> float
     int <-> bool
     P*  <-> Q*   for pointer types P and Q.  */

static bool
is_valid_cast (gcc::jit::recording::type *src_type,
	       gcc_jit_type *dst_type)
{
  bool src_is_int = src_type->is_int ();
  bool dst_is_int = dst_type->is_int ();
  bool src_is_float = src_type->is_float ();
  bool dst_is_float = dst_type->is_float ();
  bool src_is_bool = src_type->is_bool ();
  bool dst_is_bool = dst_type->is_bool ();

  if (src_is_int)
    if (dst_is_int || dst_is_float || dst_is_bool)
      return true;

  if (src_is_float)
    if (dst_is_int || dst_is_float)
      return true;

  if (src_is_bool)
    if (dst_is_int || dst_is_bool)
      return true;

  /* Permit casts between pointer types.  */
  gcc::jit::recording::type *deref_src_type = src_type->is_pointer ();
  gcc::jit::recording::type *deref_dst_type = dst_type->is_pointer ();
  if (deref_src_type && deref_dst_type)
    return true;

  return false;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_cast method in jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_cast (gcc_jit_context *ctxt,
			  gcc_jit_location *loc,
			  gcc_jit_rvalue *rvalue,
			  gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL_PRINTF3 (
    is_valid_cast (rvalue->get_type (), type),
    ctxt, loc,
    "cannot cast %s from type: %s to type: %s",
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string (),
    type->get_debug_string ());

  return static_cast <gcc_jit_rvalue *> (ctxt->new_cast (loc, rvalue, type));
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_array_access method in
   jit-recording.c.  */

extern gcc_jit_lvalue *
gcc_jit_context_new_array_access (gcc_jit_context *ctxt,
				  gcc_jit_location *loc,
				  gcc_jit_rvalue *ptr,
				  gcc_jit_rvalue *index)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (ptr, ctxt, loc, "NULL ptr");
  RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
  RETURN_NULL_IF_FAIL_PRINTF2 (
    ptr->get_type ()->dereference (),
    ctxt, loc,
    "ptr: %s (type: %s) is not a pointer or array",
    ptr->get_debug_string (),
    ptr->get_type ()->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    index->get_type ()->is_numeric (),
    ctxt, loc,
    "index: %s (type: %s) is not of numeric type",
    index->get_debug_string (),
    index->get_type ()->get_debug_string ());

  return (gcc_jit_lvalue *)ctxt->new_array_access (loc, ptr, index);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::memento::get_context method in
   jit-recording.h.  */

gcc_jit_context *
gcc_jit_object_get_context (gcc_jit_object *obj)
{
  RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");

  return static_cast <gcc_jit_context *> (obj->get_context ());
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::memento::get_debug_string method in
   jit-recording.c.  */

const char *
gcc_jit_object_get_debug_string (gcc_jit_object *obj)
{
  RETURN_NULL_IF_FAIL (obj, NULL, NULL, "NULL object");

  return obj->get_debug_string ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::lvalue::access_field method in
   jit-recording.c.  */

gcc_jit_lvalue *
gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_,
			     gcc_jit_location *loc,
			     gcc_jit_field *field)
{
  RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
  gcc::jit::recording::context *ctxt = struct_->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
			       "field %s has not been placed in a struct",
			       field->get_debug_string ());
  gcc::jit::recording::type *underlying_type =
    struct_->get_type ();
  RETURN_NULL_IF_FAIL_PRINTF2 (
    (field->get_container ()->unqualified ()
     == underlying_type->unqualified ()),
    struct_->m_ctxt, loc,
    "%s is not a field of %s",
    field->get_debug_string (),
    underlying_type->get_debug_string ());

  return (gcc_jit_lvalue *)struct_->access_field (loc, field);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::rvalue::access_field method in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_,
			     gcc_jit_location *loc,
			     gcc_jit_field *field)
{
  RETURN_NULL_IF_FAIL (struct_, NULL, loc, "NULL struct");
  gcc::jit::recording::context *ctxt = struct_->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (field, ctxt, loc, "NULL field");
  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
			       "field %s has not been placed in a struct",
			       field->get_debug_string ());
  gcc::jit::recording::type *underlying_type =
    struct_->get_type ();
  RETURN_NULL_IF_FAIL_PRINTF2 (
    (field->get_container ()->unqualified ()
     == underlying_type->unqualified ()),
    struct_->m_ctxt, loc,
    "%s is not a field of %s",
    field->get_debug_string (),
    underlying_type->get_debug_string ());

  return (gcc_jit_rvalue *)struct_->access_field (loc, field);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::rvalue::deference_field method in
   jit-recording.c.  */

gcc_jit_lvalue *
gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr,
				  gcc_jit_location *loc,
				  gcc_jit_field *field)
{
  RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr");
  JIT_LOG_FUNC (ptr->get_context ()->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field");
  gcc::jit::recording::type *underlying_type =
    ptr->get_type ()->is_pointer ();
  RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc,
			       "field %s has not been placed in a struct",
			       field->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF3 (
    underlying_type,
    ptr->m_ctxt, loc,
    "dereference of non-pointer %s (type: %s) when accessing ->%s",
    ptr->get_debug_string (),
    ptr->get_type ()->get_debug_string (),
    field->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    (field->get_container ()->unqualified ()
     == underlying_type->unqualified ()),
    ptr->m_ctxt, loc,
    "%s is not a field of %s",
    field->get_debug_string (),
    underlying_type->get_debug_string ());

  return (gcc_jit_lvalue *)ptr->dereference_field (loc, field);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::rvalue::deference method in
   jit-recording.c.  */

gcc_jit_lvalue *
gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue,
			    gcc_jit_location *loc)
{
  RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue");
  JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
  /* LOC can be NULL.  */

  gcc::jit::recording::type *underlying_type =
    rvalue->get_type ()->is_pointer ();

  RETURN_NULL_IF_FAIL_PRINTF2 (
    underlying_type,
    rvalue->m_ctxt, loc,
    "dereference of non-pointer %s (type: %s)",
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string ());

  RETURN_NULL_IF_FAIL_PRINTF2 (
    !underlying_type->is_void (),
    rvalue->m_ctxt, loc,
    "dereference of void pointer %s (type: %s)",
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string ());

  return (gcc_jit_lvalue *)rvalue->dereference (loc);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::lvalue::get_address method in jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,
			    gcc_jit_location *loc)
{
  RETURN_NULL_IF_FAIL (lvalue, NULL, loc, "NULL lvalue");
  JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
  /* LOC can be NULL.  */

  return (gcc_jit_rvalue *)lvalue->get_address (loc);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::function::new_local method in jit-recording.c.  */

gcc_jit_lvalue *
gcc_jit_function_new_local (gcc_jit_function *func,
			    gcc_jit_location *loc,
			    gcc_jit_type *type,
			    const char *name)
{
  RETURN_NULL_IF_FAIL (func, NULL, loc, "NULL function");
  gcc::jit::recording::context *ctxt = func->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (func->get_kind () != GCC_JIT_FUNCTION_IMPORTED,
		       ctxt, loc,
		       "Cannot add locals to an imported function");
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
  RETURN_NULL_IF_FAIL_PRINTF2 (
    type->has_known_size (),
    ctxt, loc,
    "unknown size for local \"%s\" (type: %s)",
    name,
    type->get_debug_string ());

  return (gcc_jit_lvalue *)func->new_local (loc, type, name);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::add_eval method in jit-recording.c.  */

void
gcc_jit_block_add_eval (gcc_jit_block *block,
			gcc_jit_location *loc,
			gcc_jit_rvalue *rvalue)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");

  gcc::jit::recording::statement *stmt = block->add_eval (loc, rvalue);

  /* "stmt" should be good enough to be usable in error-messages,
     but might still not be compilable; perform some more
     error-checking here.  We do this here so that the error messages
     can contain a stringified version of "stmt", whilst appearing
     as close as possible to the point of failure.  */
  rvalue->verify_valid_within_stmt (__func__, stmt);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::add_assignment method in
   jit-recording.c.  */

void
gcc_jit_block_add_assignment (gcc_jit_block *block,
			      gcc_jit_location *loc,
			      gcc_jit_lvalue *lvalue,
			      gcc_jit_rvalue *rvalue)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
  RETURN_IF_FAIL_PRINTF4 (
    compatible_types (lvalue->get_type (),
		      rvalue->get_type ()),
    ctxt, loc,
    "mismatching types:"
    " assignment to %s (type: %s) from %s (type: %s)",
    lvalue->get_debug_string (),
    lvalue->get_type ()->get_debug_string (),
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string ());

  gcc::jit::recording::statement *stmt = block->add_assignment (loc, lvalue, rvalue);

  /* "stmt" should be good enough to be usable in error-messages,
     but might still not be compilable; perform some more
     error-checking here.  We do this here so that the error messages
     can contain a stringified version of "stmt", whilst appearing
     as close as possible to the point of failure.  */
  lvalue->verify_valid_within_stmt (__func__, stmt);
  rvalue->verify_valid_within_stmt (__func__, stmt);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::add_assignment_op method in
   jit-recording.c.  */

void
gcc_jit_block_add_assignment_op (gcc_jit_block *block,
				 gcc_jit_location *loc,
				 gcc_jit_lvalue *lvalue,
				 enum gcc_jit_binary_op op,
				 gcc_jit_rvalue *rvalue)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (lvalue, ctxt, loc, "NULL lvalue");
  RETURN_IF_FAIL_PRINTF1 (
    valid_binary_op_p (op),
    ctxt, loc,
    "unrecognized value for enum gcc_jit_binary_op: %i",
    op);
  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
  RETURN_IF_FAIL_PRINTF4 (
    compatible_types (lvalue->get_type (),
		      rvalue->get_type ()),
    ctxt, loc,
    "mismatching types:"
    " assignment to %s (type: %s) involving %s (type: %s)",
    lvalue->get_debug_string (),
    lvalue->get_type ()->get_debug_string (),
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string ());

  gcc::jit::recording::statement *stmt = block->add_assignment_op (loc, lvalue, op, rvalue);

  /* "stmt" should be good enough to be usable in error-messages,
     but might still not be compilable; perform some more
     error-checking here.  We do this here so that the error messages
     can contain a stringified version of "stmt", whilst appearing
     as close as possible to the point of failure.  */
  lvalue->verify_valid_within_stmt (__func__, stmt);
  rvalue->verify_valid_within_stmt (__func__, stmt);
}

/* Internal helper function for determining if rvalue BOOLVAL is of
   boolean type.  For use by gcc_jit_block_end_with_conditional.  */

static bool
is_bool (gcc_jit_rvalue *boolval)
{
  gcc::jit::recording::type *actual_type = boolval->get_type ();
  gcc::jit::recording::type *bool_type =
    boolval->m_ctxt->get_type (GCC_JIT_TYPE_BOOL);
  return actual_type == bool_type;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::end_with_conditional method in
   jit-recording.c.  */

void
gcc_jit_block_end_with_conditional (gcc_jit_block *block,
				    gcc_jit_location *loc,
				    gcc_jit_rvalue *boolval,
				    gcc_jit_block *on_true,
				    gcc_jit_block *on_false)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (boolval, ctxt, loc, "NULL boolval");
  RETURN_IF_FAIL_PRINTF2 (
   is_bool (boolval), ctxt, loc,
   "%s (type: %s) is not of boolean type ",
   boolval->get_debug_string (),
   boolval->get_type ()->get_debug_string ());
  RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_true");
  RETURN_IF_FAIL (on_true, ctxt, loc, "NULL on_false");
  RETURN_IF_FAIL_PRINTF4 (
    block->get_function () == on_true->get_function (),
    ctxt, loc,
    "\"on_true\" block is not in same function:"
    " source block %s is in function %s"
    " whereas target block %s is in function %s",
    block->get_debug_string (),
    block->get_function ()->get_debug_string (),
    on_true->get_debug_string (),
    on_true->get_function ()->get_debug_string ());
  RETURN_IF_FAIL_PRINTF4 (
    block->get_function () == on_false->get_function (),
    ctxt, loc,
    "\"on_false\" block is not in same function:"
    " source block %s is in function %s"
    " whereas target block %s is in function %s",
    block->get_debug_string (),
    block->get_function ()->get_debug_string (),
    on_false->get_debug_string (),
    on_false->get_function ()->get_debug_string ());

  gcc::jit::recording::statement *stmt = block->end_with_conditional (loc, boolval, on_true, on_false);

  /* "stmt" should be good enough to be usable in error-messages,
     but might still not be compilable; perform some more
     error-checking here.  We do this here so that the error messages
     can contain a stringified version of "stmt", whilst appearing
     as close as possible to the point of failure.  */
  boolval->verify_valid_within_stmt (__func__, stmt);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::add_comment method in
   jit-recording.c.  */

void
gcc_jit_block_add_comment (gcc_jit_block *block,
			   gcc_jit_location *loc,
			   const char *text)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (text, ctxt, loc, "NULL text");

  block->add_comment (loc, text);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::end_with_jump method in
   jit-recording.c.  */

void
gcc_jit_block_end_with_jump (gcc_jit_block *block,
			     gcc_jit_location *loc,
			     gcc_jit_block *target)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (target, ctxt, loc, "NULL target");
  RETURN_IF_FAIL_PRINTF4 (
    block->get_function () == target->get_function (),
    ctxt, loc,
    "target block is not in same function:"
    " source block %s is in function %s"
    " whereas target block %s is in function %s",
    block->get_debug_string (),
    block->get_function ()->get_debug_string (),
    target->get_debug_string (),
    target->get_function ()->get_debug_string ());

  block->end_with_jump (loc, target);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::end_with_return method in
   jit-recording.c.  */

void
gcc_jit_block_end_with_return (gcc_jit_block *block,
			       gcc_jit_location *loc,
			       gcc_jit_rvalue *rvalue)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  gcc::jit::recording::function *func = block->get_function ();
  RETURN_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
  RETURN_IF_FAIL_PRINTF4 (
    compatible_types (
      func->get_return_type (),
      rvalue->get_type ()),
    ctxt, loc,
    "mismatching types:"
    " return of %s (type: %s) in function %s (return type: %s)",
    rvalue->get_debug_string (),
    rvalue->get_type ()->get_debug_string (),
    func->get_debug_string (),
    func->get_return_type ()->get_debug_string ());

  gcc::jit::recording::statement *stmt = block->end_with_return (loc, rvalue);

  /* "stmt" should be good enough to be usable in error-messages,
     but might still not be compilable; perform some more
     error-checking here.  We do this here so that the error messages
     can contain a stringified version of "stmt", whilst appearing
     as close as possible to the point of failure.  */
  rvalue->verify_valid_within_stmt (__func__, stmt);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::end_with_return method in
   jit-recording.c.  */

void
gcc_jit_block_end_with_void_return (gcc_jit_block *block,
				    gcc_jit_location *loc)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  gcc::jit::recording::function *func = block->get_function ();
  RETURN_IF_FAIL_PRINTF2 (
    func->get_return_type () == ctxt->get_type (GCC_JIT_TYPE_VOID),
    ctxt, loc,
    "mismatching types:"
    " void return in function %s (return type: %s)",
    func->get_debug_string (),
    func->get_return_type ()->get_debug_string ());

  block->end_with_return (loc, NULL);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_case method in
   jit-recording.c.  */

gcc_jit_case *
gcc_jit_context_new_case (gcc_jit_context *ctxt,
			  gcc_jit_rvalue *min_value,
			  gcc_jit_rvalue *max_value,
			  gcc_jit_block *block)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (min_value, ctxt, NULL, "NULL min_value");
  RETURN_NULL_IF_FAIL (max_value, ctxt, NULL, "NULL max_value");
  RETURN_NULL_IF_FAIL (block, ctxt, NULL, "NULL block");

  RETURN_NULL_IF_FAIL_PRINTF1 (min_value->is_constant (), ctxt, NULL,
			       "min_value is not a constant: %s",
			       min_value->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF1 (max_value->is_constant (), ctxt, NULL,
			       "max_value is not a constant: %s",
			       max_value->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    min_value->get_type ()->is_int (),
    ctxt, NULL,
    "min_value: %s (type: %s) is not of integer type",
    min_value->get_debug_string (),
    min_value->get_type ()->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    max_value->get_type ()->is_int (),
    ctxt, NULL,
    "max_value: %s (type: %s) is not of integer type",
    max_value->get_debug_string (),
    max_value->get_type ()->get_debug_string ());

  wide_int wi_min, wi_max;
  if (!min_value->get_wide_int (&wi_min))
    gcc_unreachable ();
  if (!max_value->get_wide_int (&wi_max))
    gcc_unreachable ();
  RETURN_NULL_IF_FAIL_PRINTF2 (
    wi::les_p (wi_min, wi_max),
    ctxt, NULL,
    "min_value: %s > max_value: %s",
    min_value->get_debug_string (),
    max_value->get_debug_string ());
  return (gcc_jit_case *)ctxt->new_case (min_value,
					 max_value,
					 block);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this calls the trivial
   gcc::jit::recording::memento::as_object method (a case is a
   memento), in jit-recording.h.  */

gcc_jit_object *
gcc_jit_case_as_object (gcc_jit_case *case_)
{
  RETURN_NULL_IF_FAIL (case_, NULL, NULL, "NULL case");

  return static_cast <gcc_jit_object *> (case_->as_object ());
}

/* Helper function for gcc_jit_block_end_with_switch and
   valid_case_for_switch.  */

static bool
valid_dest_for_switch (gcc::jit::recording::context *ctxt,
		       gcc_jit_location *loc,
		       const char *api_funcname,
		       gcc::jit::recording::block *switch_block,
		       gcc::jit::recording::block *dest_block,
		       const char *dest_block_desc)
{
  if (!dest_block)
    {
      jit_error (ctxt, loc, "%s: NULL %s", api_funcname, dest_block_desc);
      return false;
    }
  gcc::jit::recording::function *switch_fn = switch_block->get_function ();
  gcc::jit::recording::function *dest_fn = dest_block->get_function ();
  if (switch_fn != dest_fn)
    {
      jit_error (ctxt, loc,
		 "%s: %s is not in same function:"
		 " switch block %s is in function %s"
		 " whereas %s %s is in function %s",
		 api_funcname,
		 dest_block_desc,
		 switch_block->get_debug_string (),
		 switch_fn->get_debug_string (),
		 dest_block_desc,
		 dest_block->get_debug_string (),
		 dest_fn->get_debug_string ());
      return false;
    }
  return true;
}

/* Helper function for gcc_jit_block_end_with_switch.  */

static bool
valid_case_for_switch (gcc::jit::recording::context *ctxt,
		       gcc_jit_location *loc,
		       const char *api_funcname,
		       gcc_jit_block *switch_block,
		       gcc_jit_rvalue *expr,
		       gcc_jit_case *case_,
		       const char *case_desc,
		       int case_idx)
{
  if (!case_)
    {
      jit_error (ctxt, loc,
		 "%s:"
		 " NULL case %i",
		 api_funcname,
		 case_idx);
      return false;
    }
  if (!valid_dest_for_switch (ctxt, loc,
			      api_funcname,
			      switch_block,
			      case_->get_dest_block (),
			      case_desc))
    return false;
  gcc::jit::recording::type *expr_type = expr->get_type ();
  if (expr_type != case_->get_min_value ()->get_type ())
    {
      jit_error (ctxt, loc,
		 "%s:"
		 " mismatching types between case and expression:"
		 " cases[%i]->min_value: %s (type: %s)"
		 " expr: %s (type: %s)",
		 api_funcname,
		 case_idx,
		 case_->get_min_value ()->get_debug_string (),
		 case_->get_min_value ()->get_type ()->get_debug_string (),
		 expr->get_debug_string (),
		 expr_type->get_debug_string ());
      return false;
    }
  if (expr_type != case_->get_max_value ()->get_type ())
    {
      jit_error (ctxt, loc,
		 "%s:"
		 " mismatching types between case and expression:"
		 " cases[%i]->max_value: %s (type: %s)"
		 " expr: %s (type: %s)",
		 api_funcname,
		 case_idx,
		 case_->get_max_value ()->get_debug_string (),
		 case_->get_max_value ()->get_type ()->get_debug_string (),
		 expr->get_debug_string (),
		 expr_type->get_debug_string ());
      return false;
    }
  return true;
}

/* A class for holding the data we need to perform error-checking
   on a libgccjit API call.  */

class api_call_validator
{
 public:
  api_call_validator (gcc::jit::recording::context *ctxt,
		      gcc_jit_location *loc,
		      const char *funcname)
  : m_ctxt (ctxt),
    m_loc (loc),
    m_funcname (funcname)
  {}

 protected:
  gcc::jit::recording::context *m_ctxt;
  gcc_jit_location *m_loc;
  const char *m_funcname;
};

/* A class for verifying that the ranges of cases within
   gcc_jit_block_end_with_switch don't overlap.  */

class case_range_validator : public api_call_validator
{
 public:
  case_range_validator (gcc::jit::recording::context *ctxt,
			gcc_jit_location *loc,
			const char *funcname);

  bool
  validate (gcc_jit_case *case_, int idx);

 private:
  static int
  case_compare (gcc::jit::recording::rvalue *k1,
		gcc::jit::recording::rvalue *k2);

  static wide_int
  get_wide_int (gcc::jit::recording::rvalue *k);

 private:
  typed_splay_tree <gcc::jit::recording::rvalue *, gcc_jit_case *> m_cases;
};

/* case_range_validator's ctor.  */

case_range_validator::case_range_validator (gcc::jit::recording::context *ctxt,
					    gcc_jit_location *loc,
					    const char *funcname)
: api_call_validator (ctxt, loc, funcname),
  m_cases (case_compare, NULL, NULL)
{
}

/* Ensure that the range of CASE_ does not overlap with any of the
   ranges of cases we've already seen.
   Return true if everything is OK.
   Return false and emit an error if there is an overlap.
   Compare with c-family/c-common.c:c_add_case_label.  */

bool
case_range_validator::validate (gcc_jit_case *case_,
				int case_idx)
{
  /* Look up the LOW_VALUE in the table of case labels we already
     have.  */
  gcc_jit_case *other = m_cases.lookup (case_->get_min_value ());

  /* If there was not an exact match, check for overlapping ranges.  */
  if (!other)
    {
      gcc_jit_case *pred;
      gcc_jit_case *succ;

      /* Even though there wasn't an exact match, there might be an
	 overlap between this case range and another case range.
	 Since we've (inductively) not allowed any overlapping case
	 ranges, we simply need to find the greatest low case label
	 that is smaller that CASE_MIN_VALUE, and the smallest low case
	 label that is greater than CASE_MAX_VALUE.  If there is an overlap
	 it will occur in one of these two ranges.  */
      pred = m_cases.predecessor (case_->get_min_value ());
      succ = m_cases.successor (case_->get_max_value ());

      /* Check to see if the PRED overlaps.  It is smaller than
	 the LOW_VALUE, so we only need to check its max value.  */
      if (pred)
	{
	  wide_int wi_case_min = get_wide_int (case_->get_min_value ());
	  wide_int wi_pred_max = get_wide_int (pred->get_max_value ());
	  if (wi::ges_p (wi_pred_max, wi_case_min))
	    other = pred;
	}

      if (!other && succ)
	{
	  /* Check to see if the SUCC overlaps.  The low end of that
	     range is bigger than the low end of the current range.  */
	  wide_int wi_case_max = get_wide_int (case_->get_max_value ());
	  wide_int wi_succ_min = get_wide_int (succ->get_min_value ());
	  if (wi::les_p (wi_succ_min, wi_case_max))
	    other = succ;
	}
    }

  /* If there was an overlap, issue an error.  */
  if (other)
    {
      jit_error (m_ctxt, m_loc,
		 "%s: duplicate (or overlapping) cases values:"
		 " case %i: %s overlaps %s",
		 m_funcname,
		 case_idx,
		 case_->get_debug_string (),
		 other->get_debug_string ());
      return false;
    }

  /* Register this case label in the splay tree.  */
  m_cases.insert (case_->get_min_value (),
		  case_);
  return true;
}

/* Compare with c-family/c-common.c:case_compare, which acts on tree
   nodes, rather than rvalue *.

   Comparator for case label values.  K1 and K2 must be constant integer
   values (anything else should have been rejected by
   gcc_jit_context_new_case.

   Returns -1 if K1 is ordered before K2, -1 if K1 is ordered after
   K2, and 0 if K1 and K2 are equal.  */

int
case_range_validator::case_compare (gcc::jit::recording::rvalue * k1,
				    gcc::jit::recording::rvalue * k2)
{
  wide_int wi1 = get_wide_int (k1);
  wide_int wi2 = get_wide_int (k2);
  return wi::cmps(wi1, wi2);
}

/* Given a const int rvalue K, get the underlying value as a wide_int.  */

wide_int
case_range_validator::get_wide_int (gcc::jit::recording::rvalue *k)
{
  wide_int wi;
  bool got_wi = k->get_wide_int (&wi);
  gcc_assert (got_wi);
  return wi;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::block::end_with_switch method in
   jit-recording.c.  */

void
gcc_jit_block_end_with_switch (gcc_jit_block *block,
			       gcc_jit_location *loc,
			       gcc_jit_rvalue *expr,
			       gcc_jit_block *default_block,
			       int num_cases,
			       gcc_jit_case **cases)
{
  RETURN_IF_NOT_VALID_BLOCK (block, loc);
  gcc::jit::recording::context *ctxt = block->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (expr, ctxt, loc,
		  "NULL expr");
  gcc::jit::recording::type *expr_type = expr->get_type ();
  RETURN_IF_FAIL_PRINTF2 (
    expr_type->is_int (),
    ctxt, loc,
    "expr: %s (type: %s) is not of integer type",
    expr->get_debug_string (),
    expr_type->get_debug_string ());
  if (!valid_dest_for_switch (ctxt, loc,
			      __func__,
			      block,
			      default_block,
			      "default_block"))
    return;
  RETURN_IF_FAIL (num_cases >= 0, ctxt, loc, "num_cases < 0");
  case_range_validator crv (ctxt, loc, __func__);
  for (int i = 0; i < num_cases; i++)
    {
      char case_desc[32];
      snprintf (case_desc, sizeof (case_desc),
		"cases[%i]", i);
      if (!valid_case_for_switch (ctxt, loc,
				  __func__,
				  block,
				  expr,
				  cases[i],
				  case_desc,
				  i))
	return;
      if (!crv.validate (cases[i], i))
	return;
    }

  block->end_with_switch (loc, expr, default_block,
			  num_cases,
			  (gcc::jit::recording::case_ **)cases);
}

/**********************************************************************
 Option-management
 **********************************************************************/

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::set_str_option method in
   jit-recording.c.  */

void
gcc_jit_context_set_str_option (gcc_jit_context *ctxt,
				enum gcc_jit_str_option opt,
				const char *value)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* opt is checked by the inner function.
     value can be NULL.  */

  ctxt->set_str_option (opt, value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::set_int_option method in
   jit-recording.c.  */

void
gcc_jit_context_set_int_option (gcc_jit_context *ctxt,
				enum gcc_jit_int_option opt,
				int value)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* opt is checked by the inner function.  */

  ctxt->set_int_option (opt, value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::set_bool_option method in
   jit-recording.c.  */

void
gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
				 enum gcc_jit_bool_option opt,
				 int value)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* opt is checked by the inner function.  */

  ctxt->set_bool_option (opt, value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::set_inner_bool_option method in
   jit-recording.c.  */

void
gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
						   int bool_value)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  ctxt->set_inner_bool_option (
    gcc::jit::INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
    bool_value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::set_inner_bool_option method in
   jit-recording.c.  */

extern void
gcc_jit_context_set_bool_use_external_driver (gcc_jit_context *ctxt,
					      int bool_value)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  ctxt->set_inner_bool_option (
    gcc::jit::INNER_BOOL_OPTION_USE_EXTERNAL_DRIVER,
    bool_value);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::add_command_line_option method in
   jit-recording.c.  */

void
gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
					 const char *optname)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
  if (ctxt->get_logger ())
    ctxt->get_logger ()->log ("optname: %s", optname);

  ctxt->add_command_line_option (optname);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::enable_dump method in
   jit-recording.c.  */

void
gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
			     const char *dumpname,
			     char **out_ptr)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL (dumpname, ctxt, NULL, "NULL dumpname");
  RETURN_IF_FAIL (out_ptr, ctxt, NULL, "NULL out_ptr");

  ctxt->enable_dump (dumpname, out_ptr);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::compile method in
   jit-recording.c.  */

gcc_jit_result *
gcc_jit_context_compile (gcc_jit_context *ctxt)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");

  JIT_LOG_FUNC (ctxt->get_logger ());

  ctxt->log ("in-memory compile of ctxt: %p", (void *)ctxt);

  gcc_jit_result *result = (gcc_jit_result *)ctxt->compile ();

  ctxt->log ("%s: returning (gcc_jit_result *)%p",
	     __func__, (void *)result);

  return result;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::compile_to_file method in
   jit-recording.c.  */

void
gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
				 enum gcc_jit_output_kind output_kind,
				 const char *output_path)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL_PRINTF1 (
    ((output_kind >= GCC_JIT_OUTPUT_KIND_ASSEMBLER)
     && (output_kind <= GCC_JIT_OUTPUT_KIND_EXECUTABLE)),
    ctxt, NULL,
    "unrecognized output_kind: %i",
    output_kind);
  RETURN_IF_FAIL (output_path, ctxt, NULL, "NULL output_path");

  ctxt->log ("compile_to_file of ctxt: %p", (void *)ctxt);
  ctxt->log ("output_kind: %i", output_kind);
  ctxt->log ("output_path: %s", output_path);

  ctxt->compile_to_file (output_kind, output_path);
}


/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::dump_to_file method in
   jit-recording.c.  */

void
gcc_jit_context_dump_to_file (gcc_jit_context *ctxt,
			      const char *path,
			      int update_locations)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
  ctxt->dump_to_file (path, update_locations);
}

/* Public entrypoint.  See description in libgccjit.h.  */

void
gcc_jit_context_set_logfile (gcc_jit_context *ctxt,
			     FILE *logfile,
			     int flags,
			     int verbosity)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL ((flags == 0), ctxt, NULL, "flags must be 0 for now");
  RETURN_IF_FAIL ((verbosity == 0), ctxt, NULL, "verbosity must be 0 for now");

  gcc::jit::logger *logger;
  if (logfile)
    logger = new gcc::jit::logger (logfile, flags, verbosity);
  else
    logger = NULL;
  ctxt->set_logger (logger);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::dump_reproducer_to_file method in
   jit-recording.c.  */

void
gcc_jit_context_dump_reproducer_to_file (gcc_jit_context *ctxt,
					 const char *path)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_IF_FAIL (path, ctxt, NULL, "NULL path");
  ctxt->dump_reproducer_to_file (path);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::get_first_error method in
   jit-recording.c.  */

const char *
gcc_jit_context_get_first_error (gcc_jit_context *ctxt)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());

  return ctxt->get_first_error ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::get_last_error method in
   jit-recording.c.  */

const char *
gcc_jit_context_get_last_error (gcc_jit_context *ctxt)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");

  return ctxt->get_last_error ();
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::result::get_code method in jit-result.c.  */

void *
gcc_jit_result_get_code (gcc_jit_result *result,
			 const char *fnname)
{
  RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
  JIT_LOG_FUNC (result->get_logger ());
  RETURN_NULL_IF_FAIL (fnname, NULL, NULL, "NULL fnname");

  result->log ("locating fnname: %s", fnname);
  void *code = result->get_code (fnname);
  result->log ("%s: returning (void *)%p", __func__, code);

  return code;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::result::get_global method in jit-result.c.  */

void *
gcc_jit_result_get_global (gcc_jit_result *result,
			   const char *name)
{
  RETURN_NULL_IF_FAIL (result, NULL, NULL, "NULL result");
  JIT_LOG_FUNC (result->get_logger ());
  RETURN_NULL_IF_FAIL (name, NULL, NULL, "NULL name");

  void *global = result->get_global (name);
  result->log ("%s: returning (void *)%p", __func__, global);

  return global;
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, this is essentially a wrapper around the
   destructor for gcc::jit::result in jit-result.c.  */

void
gcc_jit_result_release (gcc_jit_result *result)
{
  RETURN_IF_FAIL (result, NULL, NULL, "NULL result");
  JIT_LOG_FUNC (result->get_logger ());
  result->log ("deleting result: %p", (void *)result);
  delete result;
}

/**********************************************************************
 Timing support.
 **********************************************************************/

/* Create a gcc_jit_timer instance, and start timing.  */

gcc_jit_timer *
gcc_jit_timer_new (void)
{
  gcc_jit_timer *timer = new gcc_jit_timer ();
  timer->start (TV_TOTAL);
  timer->push (TV_JIT_CLIENT_CODE);
  return timer;
}

/* Release a gcc_jit_timer instance.  */

void
gcc_jit_timer_release (gcc_jit_timer *timer)
{
  RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");

  delete timer;
}

/* Associate a gcc_jit_timer instance with a context.  */

void
gcc_jit_context_set_timer (gcc_jit_context *ctxt,
			   gcc_jit_timer *timer)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
  RETURN_IF_FAIL (timer, ctxt, NULL, "NULL timer");

  ctxt->set_timer (timer);
}

/* Get the timer associated with a context (if any).  */

gcc_jit_timer *
gcc_jit_context_get_timer (gcc_jit_context *ctxt)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");

  return (gcc_jit_timer *)ctxt->get_timer ();
}

/* Push the given item onto the timing stack.  */

void
gcc_jit_timer_push (gcc_jit_timer *timer,
		    const char *item_name)
{
  RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
  RETURN_IF_FAIL (item_name, NULL, NULL, "NULL item_name");
  timer->push_client_item (item_name);
}

/* Pop the top item from the timing stack.  */

void
gcc_jit_timer_pop (gcc_jit_timer *timer,
		   const char *item_name)
{
  RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");

  if (item_name)
    {
      const char *top_item_name = timer->get_topmost_item_name ();

      RETURN_IF_FAIL_PRINTF1
	(top_item_name, NULL, NULL,
	 "pop of empty timing stack (attempting to pop: \"%s\")",
	 item_name);

      RETURN_IF_FAIL_PRINTF2
	(strcmp (item_name, top_item_name) == 0, NULL, NULL,
	 "mismatching item_name:"
	 " top of timing stack: \"%s\","
	 " attempting to pop: \"%s\"",
	 top_item_name,
	 item_name);
    }

  timer->pop_client_item ();
}

/* Print timing information to the given stream about activity since
   the timer was started.  */

void
gcc_jit_timer_print (gcc_jit_timer *timer,
		     FILE *f_out)
{
  RETURN_IF_FAIL (timer, NULL, NULL, "NULL timer");
  RETURN_IF_FAIL (f_out, NULL, NULL, "NULL f_out");

  timer->pop (TV_JIT_CLIENT_CODE);
  timer->stop (TV_TOTAL);
  timer->print (f_out);
  timer->start (TV_TOTAL);
  timer->push (TV_JIT_CLIENT_CODE);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is effectively done by the
   gcc::jit::base_call::set_require_tail_call setter in jit-recording.h.  */

void
gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *rvalue,
					   int require_tail_call)
{
  RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL call");
  JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());

  /* Verify that it's a call.  */
  gcc::jit::recording::base_call *call = rvalue->dyn_cast_base_call ();
  RETURN_IF_FAIL_PRINTF1 (call, NULL, NULL, "not a call: %s",
			  rvalue->get_debug_string ());

  call->set_require_tail_call (require_tail_call);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::type::get_aligned method, in
   jit-recording.c.  */

gcc_jit_type *
gcc_jit_type_get_aligned (gcc_jit_type *type,
			  size_t alignment_in_bytes)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  gcc::jit::recording::context *ctxt = type->m_ctxt;

  JIT_LOG_FUNC (ctxt->get_logger ());

  RETURN_NULL_IF_FAIL_PRINTF1
    (pow2_or_zerop (alignment_in_bytes), ctxt, NULL,
     "alignment not a power of two: %zi",
     alignment_in_bytes);

  return (gcc_jit_type *)type->get_aligned (alignment_in_bytes);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::type::get_vector method, in
   jit-recording.c.  */

gcc_jit_type *
gcc_jit_type_get_vector (gcc_jit_type *type, size_t num_units)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");

  gcc::jit::recording::context *ctxt = type->m_ctxt;

  JIT_LOG_FUNC (ctxt->get_logger ());

  RETURN_NULL_IF_FAIL_PRINTF1
    (type->is_int () || type->is_float (), ctxt, NULL,
     "type is not integral or floating point: %s",
     type->get_debug_string ());

  RETURN_NULL_IF_FAIL_PRINTF1
    (pow2_or_zerop (num_units), ctxt, NULL,
     "num_units not a power of two: %zi",
     num_units);

  return (gcc_jit_type *)type->get_vector (num_units);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::function::get_address method, in
   jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_function_get_address (gcc_jit_function *fn,
			      gcc_jit_location *loc)
{
  RETURN_NULL_IF_FAIL (fn, NULL, NULL, "NULL function");

  gcc::jit::recording::context *ctxt = fn->m_ctxt;

  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */

  return (gcc_jit_rvalue *)fn->get_address (loc);
}

/* Public entrypoint.  See description in libgccjit.h.

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_rvalue_from_vector method, in
   jit-recording.c.  */

extern gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector (gcc_jit_context *ctxt,
					gcc_jit_location *loc,
					gcc_jit_type *vec_type,
					size_t num_elements,
					gcc_jit_rvalue **elements)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
  JIT_LOG_FUNC (ctxt->get_logger ());

  /* LOC can be NULL.  */
  RETURN_NULL_IF_FAIL (vec_type, ctxt, loc, "NULL vec_type");

  /* "vec_type" must be a vector type.  */
  gcc::jit::recording::vector_type *as_vec_type
    = vec_type->dyn_cast_vector_type ();
  RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
			       "%s is not a vector type",
			       vec_type->get_debug_string ());

  /* "num_elements" must match.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (
    num_elements == as_vec_type->get_num_units (), ctxt, loc,
    "num_elements != %zi", as_vec_type->get_num_units ());

  /* "elements must be non-NULL.  */
  RETURN_NULL_IF_FAIL (elements, ctxt, loc, "NULL elements");

  /* Each of "elements" must be non-NULL and of the correct type.  */
  gcc::jit::recording::type *element_type
    = as_vec_type->get_element_type ();
  for (size_t i = 0; i < num_elements; i++)
    {
      RETURN_NULL_IF_FAIL_PRINTF1 (
	elements[i], ctxt, loc, "NULL elements[%zi]", i);
      RETURN_NULL_IF_FAIL_PRINTF4 (
	compatible_types (element_type,
			  elements[i]->get_type ()),
	ctxt, loc,
	"mismatching type for element[%zi] (expected type: %s): %s (type: %s)",
	i,
	element_type->get_debug_string (),
	elements[i]->get_debug_string (),
	elements[i]->get_type ()->get_debug_string ());
    }

  return (gcc_jit_rvalue *)ctxt->new_rvalue_from_vector
    (loc,
     as_vec_type,
     (gcc::jit::recording::rvalue **)elements);
}
