/* Implementation of the C API; all wrappers into the internal C++ API
   Copyright (C) 2013-2025 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"
#define INCLUDE_MUTEX
#include "system.h"
#include "coretypes.h"
#include "timevar.h"
#include "typed-splay-tree.h"
#include "cppbuiltin.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_function_type : public gcc::jit::recording::function_type
{
};

struct gcc_jit_vector_type : public gcc::jit::recording::vector_type
{
};

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

struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
{
};

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
{
};

struct gcc_jit_extended_asm : public gcc::jit::recording::extended_asm
{
};


/**********************************************************************
 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_PRINTF3(TEST_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;							\
      }								\
  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::recording::location *loc,
	   const char *fmt, ...)
  GNU_PRINTF(3, 4);

static void
jit_error (gcc::jit::recording::context *ctxt,
	   gcc::jit::recording::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 wrapping compatible_types.  */

int
gcc_jit_compatible_types (gcc_jit_type *ltype,
			  gcc_jit_type *rtype)
{
  RETURN_VAL_IF_FAIL (ltype, 0, NULL, NULL, "NULL ltype");
  RETURN_VAL_IF_FAIL (rtype, 0, NULL, NULL, "NULL rtype");
  return compatible_types (ltype, 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.cc. */

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.cc.  */

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.cc. */

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.cc.  */

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.cc  */

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 < NUM_GCC_JIT_TYPES),
    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.cc.  */

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.cc  */

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.cc.  */

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.cc.  */

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::type::get_restrict method, in
   jit-recording.cc.  */

gcc_jit_type *
gcc_jit_type_get_restrict (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
  RETURN_NULL_IF_FAIL (type->is_pointer (), NULL, NULL, "not a pointer type");

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

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

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

ssize_t
gcc_jit_type_get_size (gcc_jit_type *type)
{
  RETURN_VAL_IF_FAIL (type, -1, NULL, NULL, "NULL type");
  RETURN_VAL_IF_FAIL
    (type->is_int () || type->is_float () || type->is_pointer (), -1, NULL, NULL,
     "only getting the size of integer or floating-point or pointer types is supported for now");
  return type->get_size ();
}

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

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

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

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

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

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

int
gcc_jit_type_is_bool (gcc_jit_type *type)
{
  RETURN_VAL_IF_FAIL (type, FALSE, NULL, NULL, "NULL type");

  return type->is_bool ();
}

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

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

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

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

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

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

int
gcc_jit_type_is_integral (gcc_jit_type *type)
{
  RETURN_VAL_IF_FAIL (type, FALSE, NULL, NULL, "NULL type");

  return type->is_int ();
}

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

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

gcc_jit_vector_type *
gcc_jit_type_dyncast_vector (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
  gcc::jit::recording::vector_type *vector_type = type->is_vector ();
  return (gcc_jit_vector_type *)vector_type;
}

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

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

gcc_jit_struct *
gcc_jit_type_is_struct (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
  gcc::jit::recording::struct_ *struct_type = type->is_struct ();
  return (gcc_jit_struct *)struct_type;
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::vector_type::get_num_units method, in
   jit-recording.cc.  */

size_t
gcc_jit_vector_type_get_num_units (gcc_jit_vector_type *vector_type)
{
  RETURN_VAL_IF_FAIL (vector_type, 0, NULL, NULL, "NULL vector_type");
  return vector_type->get_num_units ();
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::vector_type::get_element_type method, in
   jit-recording.cc.  */

gcc_jit_type *
gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *vector_type)
{
  RETURN_NULL_IF_FAIL (vector_type, NULL, NULL, "NULL vector_type");
  return (gcc_jit_type *)vector_type->get_element_type ();
}

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

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

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

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

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

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

gcc_jit_function_type *
gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
  gcc::jit::recording::type *func_ptr_type = type->dereference ();
  if (!func_ptr_type)
  {
    return NULL;
  }

  return (gcc_jit_function_type *)func_ptr_type->dyn_cast_function_type ();
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::function_type::get_return_type method, in
   jit-recording.cc.  */

gcc_jit_type *
gcc_jit_function_type_get_return_type (gcc_jit_function_type *function_type)
{
  RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL function_type");
  return (gcc_jit_type *)function_type->get_return_type ();
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::function_type::get_param_types method, in
   jit-recording.cc.  */

size_t
gcc_jit_function_type_get_param_count (gcc_jit_function_type *function_type)
{
  RETURN_VAL_IF_FAIL (function_type, 0, NULL, NULL, "NULL function_type");
  return function_type->get_param_types ().length ();
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::function_type::get_param_types method, in
   jit-recording.cc.  */

gcc_jit_type *
gcc_jit_function_type_get_param_type (gcc_jit_function_type *function_type,
				size_t index)
{
  RETURN_NULL_IF_FAIL (function_type, NULL, NULL, "NULL function_type");
  size_t num_params = function_type->get_param_types ().length ();
  gcc::jit::recording::context *ctxt = function_type->m_ctxt;
  RETURN_NULL_IF_FAIL_PRINTF3 (index < num_params,
			       ctxt, NULL,
			       "index of %zu is too large (%s has %zu params)",
			       index,
			       function_type->get_debug_string (),
			       num_params);
  return (gcc_jit_type *)function_type->get_param_types ()[index];
}

/* 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.cc.  */

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_NULL_IF_FAIL (!element_type->is_void (), ctxt, loc,
		       "void type for elements");

  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.cc.  */

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_NULL_IF_FAIL_PRINTF1 (
    !type->is_void (),
    ctxt, loc,
    "void type for field \"%s\"",
    name);

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

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

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

gcc_jit_field *
gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
			      gcc_jit_location *loc,
			      gcc_jit_type *type,
			      int width,
			      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 (name, ctxt, loc, "NULL name");
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
			       ctxt, loc,
			       "bit-field %s has non integral type %s",
			       name, type->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    width > 0, ctxt, loc,
    "invalid width %d for bitfield \"%s\" (must be > 0)",
    width, 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_bitfield (loc, type, width, 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.cc  */

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.cc.  */

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.cc.  */

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::fields::get_field method in
   jit-recording.cc.  */
extern gcc_jit_field *
gcc_jit_struct_get_field (gcc_jit_struct *struct_type,
			   size_t index)
{
  RETURN_NULL_IF_FAIL (struct_type, NULL, NULL, "NULL struct type");
  RETURN_NULL_IF_FAIL (struct_type->get_fields (), NULL, NULL,
				"NULL struct fields");
  size_t num_fields = struct_type->get_fields ()->length ();
  RETURN_NULL_IF_FAIL_PRINTF3 (index < num_fields,
			       NULL, NULL,
			       "index of %zu is too large (%s has %zu fields)",
			       index,
			       struct_type->get_debug_string (),
			       num_fields);
  return (gcc_jit_field *)struct_type->get_fields ()->get_field (index);
}

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

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

size_t
gcc_jit_struct_get_field_count (gcc_jit_struct *struct_type)
{
  RETURN_VAL_IF_FAIL (struct_type, 0, NULL, NULL, "NULL struct type");
  return struct_type->get_fields ()->length ();
}

/* 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.cc  */

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.cc  */

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_NULL_IF_FAIL_PRINTF1 (!param_types[i]->is_void (),
				   ctxt, loc,
				   "void type for param %i", 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.cc  */

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_NULL_IF_FAIL_PRINTF1 (!type->is_void (),
			       ctxt, loc,
			       "void type for param \"%s\"", 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.cc.  */

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 identifiers 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.  */
  {
    const char* special_chars_allowed
      = ctxt->get_str_option (GCC_JIT_STR_OPTION_SPECIAL_CHARS_IN_FUNC_NAMES);
    /* Leading char: */
    char ch = *name;
    RETURN_NULL_IF_FAIL_PRINTF2 (
	ISALPHA (ch) || ch == '_' || (special_chars_allowed
	  && strchr (special_chars_allowed, 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 == '_' || (special_chars_allowed
	    && strchr (special_chars_allowed, 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.cc.  */

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::get_params method, in
   jit-recording.h.
  */

size_t
gcc_jit_function_get_param_count (gcc_jit_function *func)
{
  RETURN_VAL_IF_FAIL (func, 0, NULL, NULL, "NULL function");
  gcc::jit::recording::context *ctxt = func->m_ctxt;
  JIT_LOG_FUNC (ctxt->get_logger ());
  return func->get_params ().length ();
}

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

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

gcc_jit_type *
gcc_jit_function_get_return_type (gcc_jit_function *func)
{
    RETURN_NULL_IF_FAIL (func, NULL, NULL, "NULL function_type");
    return (gcc_jit_type *)func->get_return_type ();
}

/* 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.cc.  */

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.cc.  */

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.cc.  */

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_NULL_IF_FAIL_PRINTF1 (
    !type->is_void (),
    ctxt, loc,
    "void type for global \"%s\"",
    name);

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

extern gcc_jit_rvalue *
gcc_jit_context_new_struct_constructor (gcc_jit_context *ctxt,
					gcc_jit_location *loc,
					gcc_jit_type *type,
					size_t num_values,
					gcc_jit_field **fields,
					gcc_jit_rvalue **values)
{
  using namespace gcc::jit::recording;

  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");

  RETURN_NULL_IF_FAIL_PRINTF1 (type->is_struct (),
			       ctxt, loc,
			       "constructor type is not a struct: %s",
			       type->get_debug_string ());

  compound_type *ct = reinterpret_cast<compound_type *>(type);
  gcc::jit::recording::fields *fields_struct = ct->get_fields ();
  size_t n_fields = fields_struct->length ();

  RETURN_NULL_IF_FAIL_PRINTF1 (ct->has_known_size (),
			       ctxt, loc,
			       "struct can't be opaque: %s",
			       type->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF1 (n_fields,
			       ctxt, loc,
			       "no fields in struct: %s",
			       type->get_debug_string ());

  /* If there is no array input we just short circuit to zero the struct.  */
  if (!num_values)
    return (gcc_jit_rvalue *)ctxt->new_ctor (loc, type, 0, NULL, NULL);

  RETURN_NULL_IF_FAIL_PRINTF3 (n_fields >= num_values,
			       ctxt, loc,
			       "more values in constructor (n=%zu) than fields"
			       " in target %s (n=%zu)",
			       num_values,
			       type->get_debug_string (),
			       n_fields);

  /* It is OK if fields are null here, indicating definiton order,
     but there has to be a values array.  */
  RETURN_NULL_IF_FAIL (values,
		       ctxt, loc,
		       "'values' NULL with non-zero 'num_values'");

  size_t idx = 0; /* Runner index for fields in the type object.  */

  for (size_t i = 0; i < num_values; i++)
    {
      gcc::jit::recording::rvalue *rv = values[i];

      /* rv kan be NULL, which would indicate zero init for the field.  */
      gcc::jit::recording::type *rv_type = rv ? rv->get_type () : nullptr;

      /* If fields are specified we need to check that they are in
	 definition order.  */
      if (fields)
	{
	  gcc::jit::recording::field *f = fields[i];

	  RETURN_NULL_IF_FAIL_PRINTF1 (
	    f,
	    ctxt, loc,
	    "NULL field in 'fields', at index %zu", i);

	  RETURN_NULL_IF_FAIL_PRINTF3 (
	    f->get_container () ==
	    static_cast<gcc::jit::recording::type*>(type),
	    ctxt, loc,
	    "field object at index %zu (%s), was not used when creating "
	    "the %s",
	    i,
	    f->get_debug_string (),
	    type->get_debug_string ());

	  /* Fields in the constructor need to be in struct definition
	     order, but there can be gaps.  */
	  size_t j;
	  for (j = idx; j < n_fields; j++)
	    {
	      field *fs = fields_struct->get_field (j);
	      if (fs == f)
		{
		  idx = j; /* Advance runner index for next iteration.  */
		  break;
		}
	    }

	  RETURN_NULL_IF_FAIL_PRINTF3 (
	    j != n_fields,
	    ctxt, loc,
	    "field at index %zu in 'fields' is not in definition order "
	    "(struct: %s) (ctor field: %s)",
	    i,
	    type->get_debug_string (),
	    f->get_debug_string ());

	  /* Check that the specified field has the same type as the
	     value, unless the value is null (a zero value init).  */
	  RETURN_NULL_IF_FAIL_PRINTF5 (
	    !rv || gcc::jit::types_kinda_same (rv_type,
					       f->get_type ()),
	    ctxt, loc,
	    "value and field not the same unqualified type, at index %zu"
	    " (%s.%s: %s)(value type: %s)",
	    i,
	    type->get_debug_string (),
	    f->get_debug_string (),
	    f->get_type ()->get_debug_string (),
	    rv_type->get_debug_string ());
	}

      /* If no fields are specified, check that the value has the same type
	 as the field in the definition of the struct.  */
      if (rv && !fields)
	{
	  RETURN_NULL_IF_FAIL_PRINTF5 (
	    gcc::jit::types_kinda_same (rv_type,
					fields_struct->
					  get_field (i)->get_type ()),
	    ctxt, loc,
	    "value and field not the same unqualified type, at index %zu"
	    " (%s.%s: %s)(value type: %s)",
	    i,
	    type->get_debug_string (),
	    fields_struct->get_field (i)->get_debug_string (),
	    fields_struct->get_field (i)->get_type ()->get_debug_string (),
	    rv_type->get_debug_string ());
	}

      if (rv)
	{
	  RETURN_NULL_IF_FAIL_PRINTF1 (
	    !rv_type->is_void (),
	    ctxt, loc,
	    "can't construct the void type, at index %zu", i);
	}
    }

  return (gcc_jit_rvalue *)ctxt->new_ctor (
    loc,
    type,
    num_values,
    reinterpret_cast<gcc::jit::recording::field**>(fields),
    reinterpret_cast<gcc::jit::recording::rvalue**>(values));
}

extern gcc_jit_rvalue *
gcc_jit_context_new_union_constructor (gcc_jit_context *ctxt,
				       gcc_jit_location *loc,
				       gcc_jit_type *type,
				       gcc_jit_field *field,
				       gcc_jit_rvalue *value)
{
  using namespace gcc::jit::recording;

  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");

  RETURN_NULL_IF_FAIL_PRINTF1 (type->is_union (),
			       ctxt, loc,
			       "constructor type is not an union: %s",
			       type->get_debug_string ());

  compound_type *ct = reinterpret_cast<compound_type *>(type);
  gcc::jit::recording::fields *fields_union = ct->get_fields ();
  size_t n_fields = fields_union->length ();

  RETURN_NULL_IF_FAIL_PRINTF1 (ct->has_known_size (),
			       ctxt, loc,
			       "union can't be opaque: %s",
			       type->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF1 (n_fields,
			       ctxt, loc,
			       "no fields in union: %s",
			       type->get_debug_string ());

  /* If value is NULL we are just supposed to zero the whole union.  */
  if (!value)
    return (gcc_jit_rvalue *)ctxt->new_ctor (loc, type, 0, NULL, NULL);

  gcc::jit::recording::type *rv_type = value->get_type ();

  RETURN_NULL_IF_FAIL (
    !rv_type->is_void (),
    ctxt, loc,
    "can't construct the void type");

  if (field)
    {
      RETURN_NULL_IF_FAIL_PRINTF2 (
	field->get_container () ==
	static_cast<gcc::jit::recording::type*>(type),
	ctxt, loc,
	"field object (%s) was not used when creating "
	"the type %s",
	field->get_debug_string (),
	type->get_debug_string ());

      RETURN_NULL_IF_FAIL_PRINTF4 (
	gcc::jit::types_kinda_same (rv_type,
				    field->get_type ()),
	ctxt, loc,
	"value and field are not the same unqualified type"
	" (%s.%s: %s)(value type: %s)",
	type->get_debug_string (),
	field->get_debug_string (),
	field->get_type ()->get_debug_string (),
	rv_type->get_debug_string ());
    }
  /* If no field is specified, check that the value has the same type
     as the first field in the definition of the union.  */
  if (!field)
    RETURN_NULL_IF_FAIL_PRINTF2 (
      gcc::jit::types_kinda_same (rv_type,
				  fields_union->
				    get_field (0)->get_type ()),
      ctxt, loc,
      "value and first union field not the same unqualified type"
      " (field type: %s)(value type: %s)",
      fields_union->get_field (0)->get_type ()->get_debug_string (),
      rv_type->get_debug_string ());


  return (gcc_jit_rvalue *)ctxt->new_ctor (
    loc,
    type,
    1,
    /* A NULL fields array tells new_ctor to take fields from the type obj.  */
    reinterpret_cast<gcc::jit::recording::field**>(field ? &field : NULL),
    reinterpret_cast<gcc::jit::recording::rvalue**>(&value));
}

extern gcc_jit_rvalue *
gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,
				       gcc_jit_location *loc,
				       gcc_jit_type *type,
				       size_t num_values,
				       gcc_jit_rvalue **values)
{
  using namespace gcc::jit::recording;

  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");

  RETURN_NULL_IF_FAIL (type->is_array () != NULL,
		       ctxt, loc,
		       "constructor type not an array");

  if (!num_values)
    values = NULL;

  if (num_values)
    {
      RETURN_NULL_IF_FAIL (
	values,
	ctxt, loc,
	"'values' NULL with non-zero 'num_values'");

      gcc::jit::recording::array_type *arr_type =
	reinterpret_cast<gcc::jit::recording::array_type*>(type);
      size_t n_el = arr_type->num_elements ();

      RETURN_NULL_IF_FAIL_PRINTF2 (
	n_el >= num_values,
	ctxt, loc,
	"array constructor has more values than the array type's length"
	" (array type length: %zu, constructor length: %zu)",
	n_el,
	num_values);

      /* For arrays, all values need to be the same base type.  */
      gcc::jit::recording::type *type0 = NULL;
      size_t i = 0;
      /* Find first non-null value.  */
      for (;i < num_values; i++)
	{
	  if (values[i])
	    break;
	}

      if (i < num_values) /* All values might be null and i == num_values.  */
	type0 = values[i]->get_type ();

      /* If we got a type0, check that all other values have
	 the same type.  */
      for (; i < num_values; i++)
	{
	  if (values[i])
	    RETURN_NULL_IF_FAIL_PRINTF3 (
	      gcc::jit::types_kinda_same (type0,
					  values[i]->get_type ()),
	      ctxt, loc,
	      "value type at index %zu differ from first value type"
	      " (first type: %s)(different type: %s)",
	      i,
	      type0->get_debug_string (),
	      values[i]->get_type ()->get_debug_string ());
	}

      /* Compare type0 with the element type specified in the
	 type of the array.  */
      if (type0)
	{
	  gcc::jit::recording::type *el_type =
	    type->is_array ();

	  RETURN_NULL_IF_FAIL_PRINTF2 (
	    gcc::jit::types_kinda_same (type0, el_type),
	    ctxt, loc,
	    "array element value types differ from types in 'values'"
	    " (element type: %s)('values' type: %s)",
	    el_type->get_debug_string (),
	    type0->get_debug_string ());
	}
    }

  return (gcc_jit_rvalue *)ctxt->new_ctor (
    loc,
    type,
    num_values,
    NULL,
    reinterpret_cast<gcc::jit::recording::rvalue**>(values));
}

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

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

gcc_jit_function *
gcc_jit_context_get_target_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_target_builtin_function (name));
}

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

extern gcc_jit_lvalue *
gcc_jit_global_set_initializer_rvalue (gcc_jit_lvalue *global,
				       gcc_jit_rvalue *init_rvalue)
{
  RETURN_NULL_IF_FAIL (global, NULL, NULL,"NULL global");

  gcc::jit::recording::context *ctxt = global->get_context ();
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL,"NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (init_rvalue, ctxt, NULL,"NULL init_rvalue");

  RETURN_NULL_IF_FAIL_PRINTF1 (global->is_global (),
			       ctxt, NULL,
			       "lvalue \"%s\" not a global",
			       global->get_debug_string ());

  gcc::jit::recording::global *gbl =
    reinterpret_cast<gcc::jit::recording::global *> (global);

  RETURN_NULL_IF_FAIL_PRINTF1 (gbl->get_kind () !=
			       GCC_JIT_GLOBAL_IMPORTED,
			       ctxt, NULL,
			       "can't initialize \"%s\", it is imported",
			       global->get_debug_string ());

  RETURN_NULL_IF_FAIL_PRINTF4 (gcc::jit::types_kinda_same (
				 global->get_type (),
				 init_rvalue->get_type ()),
			       ctxt, NULL,
			       "mismatching types:"
			       " initializing %s (type: %s) with %s (type: %s)",
			       global->get_debug_string (),
			       global->get_type ()->get_debug_string (),
			       init_rvalue->get_debug_string (),
			       init_rvalue->get_type ()->get_debug_string ());

  /* Check that there are no initializers set for the global yet.  */
  RETURN_NULL_IF_FAIL_PRINTF1 (!gbl->test_flags_anyof (
				  gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT |
				  gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_BLOB_INIT),
			       ctxt, NULL,
			       "global variable already initialized: %s",
			       global->get_debug_string ());

  /* The global need to know during playback that it will be
     initialized.  */
  gbl->set_flags (gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT);

  ctxt->new_global_init_rvalue (global, init_rvalue);

  return global;
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::global::set_initializer method, in
   jit-recording.cc.  */

extern gcc_jit_lvalue *
gcc_jit_global_set_initializer (gcc_jit_lvalue *global,
				const void *blob,
				size_t num_bytes)
{
  RETURN_NULL_IF_FAIL (global, NULL, NULL, "NULL global");
  RETURN_NULL_IF_FAIL (blob, NULL, NULL, "NULL blob");
  RETURN_NULL_IF_FAIL_PRINTF1 (global->is_global (), NULL, NULL,
			       "lvalue \"%s\" not a global",
			       global->get_debug_string ());

  gcc::jit::recording::type *lval_type = global->get_type ();
  RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->is_array (), NULL, NULL,
			       "global \"%s\" is not an array",
			       global->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->dereference ()->is_int (), NULL, NULL,
			       "global \"%s\" is not an array of integral type",
			       global->get_debug_string ());
  size_t lvalue_size =
    lval_type->dereference ()->get_size ()
    * static_cast <gcc::jit::recording::array_type *> (lval_type)->num_elements ();
  RETURN_NULL_IF_FAIL_PRINTF3 (
    lvalue_size == num_bytes, NULL, NULL,
    "mismatching sizes:"
    " global \"%s\" has size %zu whereas initializer has size %zu",
    global->get_debug_string (), lvalue_size, num_bytes);

  /* Check that the rvalue initializer is not set for this global.
     Note that we do not check if this blob type initializer is
     already set, since that check was not present when the entrypoint
     was initially written.  */
  gcc::jit::recording::global *gbl =
    reinterpret_cast<gcc::jit::recording::global *> (global);
  RETURN_NULL_IF_FAIL_PRINTF1 (!gbl->test_flags_anyof (
				  gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_RVAL_INIT),
			       NULL, NULL,
			       "global variable already initialized: %s",
			       global->get_debug_string ());

  gbl->set_initializer (blob, num_bytes);
  /* The global need to know during playback that it will be
     initialized.  */
  gbl->set_flags (gcc::jit::GLOBAL_VAR_FLAGS_WILL_BE_BLOB_INIT);

  return global;
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::global::set_readonly method, in
   jit-recording.cc.  */

extern void
gcc_jit_global_set_readonly (gcc_jit_lvalue *global)
{
  RETURN_IF_FAIL (global, NULL, NULL, "NULL global");
  RETURN_IF_FAIL_PRINTF1 (global->is_global (), NULL, NULL,
			       "lvalue \"%s\" not a global",
			       global->get_debug_string ());

  global->set_readonly ();
}

/* 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_const <int> method in
   jit-recording.cc.  */

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));
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::context::new_rvalue_from_const <long> method
   in jit-recording.cc.  */

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_const <double> method in
   jit-recording.cc.  */

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_const <void *> method
   in jit-recording.cc.  */

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_sizeof method in
   jit-recording.cc.  */

gcc_jit_rvalue *
gcc_jit_context_new_sizeof (gcc_jit_context *ctxt,
			    gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
  JIT_LOG_FUNC (ctxt->get_logger ());

  return ((gcc_jit_rvalue *)ctxt
	  ->new_sizeof (type));
}

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

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

gcc_jit_rvalue *
gcc_jit_context_new_alignof (gcc_jit_context *ctxt,
			     gcc_jit_type *type)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  RETURN_NULL_IF_FAIL (type, ctxt, NULL, "NULL type");
  JIT_LOG_FUNC (ctxt->get_logger ());

  return ((gcc_jit_rvalue *)ctxt
	  ->new_alignof (type));
}

/* 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.cc.  */

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.cc.  */

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_PRINTF3 (
    result_type->is_numeric () || result_type->is_numeric_vector (), ctxt, loc,
    "gcc_jit_unary_op %s with operand %s "
    "has non-numeric result_type: %s",
    gcc::jit::unary_op_reproducer_strings[op],
    rvalue->get_debug_string (),
    result_type->get_debug_string ());
  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.cc.  */

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 (
    compatible_types (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_NULL_IF_FAIL_PRINTF4 (
    result_type->is_numeric () || result_type->is_numeric_vector (), ctxt, loc,
    "gcc_jit_binary_op %s with operands a: %s b: %s "
    "has non-numeric result_type: %s",
    gcc::jit::binary_op_reproducer_strings[op],
    a->get_debug_string (), b->get_debug_string (),
    result_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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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");
  gcc::jit::recording::vector_type *vector_type = type->dyn_cast_vector_type ();
  RETURN_NULL_IF_FAIL (vector_type == NULL, ctxt, loc,
		       "cannot cast vector types");
  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_bitcast method in jit-recording.c.  */

gcc_jit_rvalue *
gcc_jit_context_new_bitcast (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");
  /* We cannot check if the size of rvalue matches the size of type here, so
   we'll do it at playback. */

  return static_cast <gcc_jit_rvalue *> (ctxt->new_bitcast (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.cc.  */

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::context::new_convert_vector method in
   jit-recording.cc.  */

gcc_jit_rvalue *
gcc_jit_context_convert_vector (gcc_jit_context *ctxt,
				gcc_jit_location *loc,
				gcc_jit_rvalue *vector,
				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 (vector, ctxt, loc, "NULL vector");
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");

  gcc::jit::recording::vector_type *value_vec_type
    = vector->get_type ()->dyn_cast_vector_type ();
  RETURN_NULL_IF_FAIL_PRINTF1 (value_vec_type, ctxt, loc,
			       "%s is not a value of a vector type",
			       vector->get_debug_string ());
  gcc::jit::recording::vector_type *as_vec_type
    = type->dyn_cast_vector_type ();
  RETURN_NULL_IF_FAIL_PRINTF1 (as_vec_type, ctxt, loc,
			       "%s is not a vector type",
			       type->get_debug_string ());
  RETURN_NULL_IF_FAIL_PRINTF2 (
    as_vec_type->get_num_units () == value_vec_type->get_num_units (), ctxt,
    loc, "%s should contain the same number of elements as %s",
    vector->get_debug_string (), type->get_debug_string ());

  return (gcc_jit_rvalue *)ctxt->new_convert_vector (loc, vector, type);
}

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

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

extern gcc_jit_lvalue *
gcc_jit_context_new_vector_access (gcc_jit_context *ctxt,
				   gcc_jit_location *loc,
				   gcc_jit_rvalue *vector,
				   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 (vector, ctxt, loc, "NULL vector");
  RETURN_NULL_IF_FAIL (index, ctxt, loc, "NULL index");
  RETURN_NULL_IF_FAIL_PRINTF2 (
    vector->get_type ()->dyn_cast_vector_type (),
    ctxt, loc,
    "vector: %s (type: %s) is not a vector",
    vector->get_debug_string (),
    vector->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_vector_access (loc, vector, 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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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::lvalue::set_tls_model method in jit-recording.cc.  */

void
gcc_jit_lvalue_set_tls_model (gcc_jit_lvalue *lvalue,
			    enum gcc_jit_tls_model model)
{
  RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
  JIT_LOG_FUNC (lvalue->get_context ()->get_logger ());
  RETURN_IF_FAIL_PRINTF1 (lvalue->is_global (), lvalue->get_context (), NULL,
			       "lvalue \"%s\" not a global",
			       lvalue->get_debug_string ());

  lvalue->set_tls_model (model);
}

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

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

void
gcc_jit_lvalue_set_link_section (gcc_jit_lvalue *lvalue,
			    const char *section_name)
{
  RETURN_IF_FAIL (section_name, NULL, NULL, "NULL section_name");
  lvalue->set_link_section (section_name);
}

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

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

unsigned
gcc_jit_lvalue_get_alignment (gcc_jit_lvalue *lvalue)
{
  RETURN_VAL_IF_FAIL (lvalue, 0, NULL, NULL, "NULL lvalue");
  return lvalue->get_alignment ();
}

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

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

void
gcc_jit_lvalue_set_alignment (gcc_jit_lvalue *lvalue,
			      unsigned bytes)
{
  RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
  RETURN_IF_FAIL ((bytes & (bytes - 1)) == 0, NULL, NULL,
		  "alignment is not a power of 2");
  lvalue->set_alignment (bytes);
}

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

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

void
gcc_jit_lvalue_set_register_name (gcc_jit_lvalue *lvalue,
				  const char *reg_name)
{
  RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
  RETURN_IF_FAIL (reg_name, NULL, NULL, "NULL reg_name");
  lvalue->set_register_name (reg_name);
}

/* 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.cc.  */

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_NULL_IF_FAIL_PRINTF1 (
    !type->is_void (),
    ctxt, loc,
    "void type for local \"%s\"",
    name);

  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::function::new_temp method in jit-recording.cc.  */

gcc_jit_lvalue *
gcc_jit_function_new_temp (gcc_jit_function *func,
			   gcc_jit_location *loc,
			   gcc_jit_type *type)
{
  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 temps to an imported function");
  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
  RETURN_NULL_IF_FAIL_PRINTF1 (
    type->has_known_size (),
    ctxt, loc,
    "unknown size for temp (type: %s)",
    type->get_debug_string ());
  RETURN_NULL_IF_FAIL (
    !type->is_void (),
    ctxt, loc,
    "void type for temp");

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

/* 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.cc.  */

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.cc.  */

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 ());
  RETURN_IF_FAIL_PRINTF1 (
    !lvalue->get_readonly (),
    ctxt, loc,
    "cannot assign to readonly variable: %s",
    lvalue->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.cc.  */

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 ());
  // TODO: check if it is a numeric vector?
  RETURN_IF_FAIL_PRINTF3 (
    lvalue->get_type ()->is_numeric (), ctxt, loc,
    "gcc_jit_block_add_assignment_op %s has non-numeric lvalue %s (type: %s)",
    gcc::jit::binary_op_reproducer_strings[op],
    lvalue->get_debug_string (), lvalue->get_type ()->get_debug_string ());
  RETURN_IF_FAIL_PRINTF3 (
    rvalue->get_type ()->is_numeric (), ctxt, loc,
    "gcc_jit_block_add_assignment_op %s has non-numeric rvalue %s (type: %s)",
    gcc::jit::binary_op_reproducer_strings[op],
    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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc: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.cc: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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

void
gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context *ctxt,
						 int enabled)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  JIT_LOG_FUNC (ctxt->get_logger ());
  ctxt->set_inner_bool_option (
    gcc::jit::INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR,
    enabled);
}

/* 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.cc.  */

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.cc.  */

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.

   The real work is done by the
   gcc::jit::recording::context::add_driver_option method in
   jit-recording.cc.  */

void
gcc_jit_context_add_driver_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_driver_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.cc.  */

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.cc.  */

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.cc.  */

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::set_str_option method in
   jit-recording.cc.  */

void
gcc_jit_context_set_output_ident (gcc_jit_context *ctxt,
				  const char* output_ident)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
  RETURN_IF_FAIL (output_ident, ctxt, NULL, "NULL output_ident");
  JIT_LOG_FUNC (ctxt->get_logger ());

  ctxt->set_output_ident (output_ident);
}

/* 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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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.cc.  */

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_NULL_IF_FAIL (!type->is_void (), ctxt, NULL, "void type");

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

void
gcc_jit_function_add_attribute (gcc_jit_function *func,
				gcc_jit_fn_attribute attribute)
{
  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
  RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
		  NULL,
		  NULL,
		  "attribute should be a `gcc_jit_fn_attribute` enum value");

  func->add_attribute (attribute);
}

void
gcc_jit_function_add_string_attribute (gcc_jit_function *func,
				       gcc_jit_fn_attribute attribute,
				       const char* value)
{
  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
  RETURN_IF_FAIL (value, NULL, NULL, "NULL value");
  RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
		  NULL,
		  NULL,
		  "attribute should be a `gcc_jit_fn_attribute` enum value");

  func->add_string_attribute (attribute, value);
}

/* This function adds an attribute with multiple integer values.  For example
   `nonnull(1, 2)`.  The numbers in `values` are supposed to map how they
   should be written in C code.  So for `nonnull(1, 2)`, you should pass `1`
   and `2` in `values` (and set `length` to `2`). */
void
gcc_jit_function_add_integer_array_attribute (gcc_jit_function *func,
					      gcc_jit_fn_attribute attribute,
					      const int* values,
					      size_t length)
{
  RETURN_IF_FAIL (func, NULL, NULL, "NULL func");
  RETURN_IF_FAIL (values, NULL, NULL, "NULL values");
  RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_FN_ATTRIBUTE_MAX),
		  NULL,
		  NULL,
		  "attribute should be a `gcc_jit_fn_attribute` enum value");

  func->add_integer_array_attribute (attribute, values, length);
}

void
gcc_jit_lvalue_add_string_attribute (gcc_jit_lvalue *variable,
				     gcc_jit_variable_attribute attribute,
				     const char* value)
{
  RETURN_IF_FAIL (variable, NULL, NULL, "NULL variable");
  RETURN_IF_FAIL (value, NULL, NULL, "NULL value");
  RETURN_IF_FAIL (variable->is_global () || variable->is_local (),
		  NULL,
		  NULL,
		  "variable should be a variable");
  RETURN_IF_FAIL ((attribute >= 0 && attribute < GCC_JIT_VARIABLE_ATTRIBUTE_MAX),
		  NULL,
		  NULL,
		  "attribute should be a `gcc_jit_variable_attribute` enum value");

  variable->add_string_attribute (attribute, value);
}

/* 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.cc.  */

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.cc.  */

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.cc.  */

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);
}

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

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

gcc_jit_rvalue *
gcc_jit_context_new_rvalue_vector_perm (gcc_jit_context *ctxt,
					gcc_jit_location *loc,
					gcc_jit_rvalue *elements1,
					gcc_jit_rvalue *elements2,
					gcc_jit_rvalue *mask)
{
  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL ctxt");
  JIT_LOG_FUNC (ctxt->get_logger ());
  RETURN_NULL_IF_FAIL (elements1, ctxt, loc, "NULL elements1");
  RETURN_NULL_IF_FAIL (elements2, ctxt, loc, "NULL elements2");
  RETURN_NULL_IF_FAIL (mask, ctxt, loc, "NULL mask");

  /* LOC can be NULL.  */

  gcc::jit::recording::type *elements1_type = elements1->get_type ();
  gcc::jit::recording::type *elements2_type = elements2->get_type ();
  RETURN_NULL_IF_FAIL_PRINTF4 (
    compatible_types (elements1->get_type ()->unqualified (),
		      elements2->get_type ()->unqualified ()),
    ctxt, loc,
    "mismatching types for vector perm:"
    " elements1: %s (type: %s) elements2: %s (type: %s)",
    elements1->get_debug_string (),
    elements1_type->get_debug_string (),
    elements2->get_debug_string (),
    elements2_type->get_debug_string ());

  gcc::jit::recording::type *mask_type = mask->get_type ();
  gcc::jit::recording::vector_type *mask_vector_type =
    mask_type->dyn_cast_vector_type ();
  gcc::jit::recording::vector_type *elements1_vector_type =
    elements1_type->dyn_cast_vector_type ();

  size_t mask_len = mask_vector_type->get_num_units ();
  size_t elements1_len = elements1_vector_type->get_num_units ();

  RETURN_NULL_IF_FAIL_PRINTF2 (
    mask_len == elements1_len,
    ctxt, loc,
    "mismatching length for mask:"
    " elements1 length: %ld mask length: %ld",
    mask_len,
    elements1_len);

  gcc::jit::recording::type *mask_element_type =
    mask_vector_type->get_element_type ();

  RETURN_NULL_IF_FAIL (
    mask_element_type->is_int (),
    ctxt, loc,
    "elements of mask must be of an integer type");

  gcc::jit::recording::type *elements1_element_type =
    elements1_vector_type->get_element_type ();
  size_t mask_element_size = mask_element_type->get_size ();
  size_t elements1_element_size = elements1_element_type->get_size ();

  RETURN_NULL_IF_FAIL_PRINTF2 (
    mask_element_size == elements1_element_size,
    ctxt, loc,
    "mismatching size for mask element type:"
    " elements1 element type: %ld mask element type: %ld",
    mask_element_size,
    elements1_element_size);

  return (gcc_jit_rvalue *)ctxt->new_rvalue_vector_perm (loc, elements1,
							 elements2, mask);
}

/* A mutex around the cached state in parse_basever.
   Ideally this would be within parse_basever, but the mutex is only needed
   by libgccjit.  */

static std::mutex version_mutex;

struct jit_version_info
{
  /* Default constructor.  Populate via parse_basever,
     guarded by version_mutex.  */
  jit_version_info ()
  {
    std::lock_guard<std::mutex> g (version_mutex);
    parse_basever (&major, &minor, &patchlevel);
  }

  int major;
  int minor;
  int patchlevel;
};


extern int
gcc_jit_version_major (void)
{
  jit_version_info vi;
  return vi.major;
}

extern int
gcc_jit_version_minor (void)
{
  jit_version_info vi;
  return vi.minor;
}

extern int
gcc_jit_version_patchlevel (void)
{
  jit_version_info vi;
  return vi.patchlevel;
}

/**********************************************************************
 Asm support.
 **********************************************************************/

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

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

gcc_jit_extended_asm *
gcc_jit_block_add_extended_asm (gcc_jit_block *block,
				gcc_jit_location *loc,
				const char *asm_template)
{
  RETURN_NULL_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_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");

  return (gcc_jit_extended_asm *)block->add_extended_asm (loc, asm_template);
}

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

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

gcc_jit_extended_asm *
gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,
					  gcc_jit_location *loc,
					  const char *asm_template,
					  int num_goto_blocks,
					  gcc_jit_block **goto_blocks,
					  gcc_jit_block *fallthrough_block)
{
  RETURN_NULL_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_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
  RETURN_NULL_IF_FAIL (num_goto_blocks >= 0, ctxt, loc, "num_goto_blocks < 0");
  for (int i = 0; i < num_goto_blocks; i++)
    RETURN_NULL_IF_FAIL_PRINTF1 (goto_blocks[i],
				 ctxt, loc,
				 "NULL goto_blocks[%i]", i);
  /* fallthrough_block can be NULL.  */
  return (gcc_jit_extended_asm *)block->end_with_extended_asm_goto
    (loc, asm_template,
     num_goto_blocks, (gcc::jit::recording::block **)goto_blocks,
     fallthrough_block);
}

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

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

gcc_jit_object *
gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
{
  RETURN_NULL_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");

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

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

   After error-checking, the real work is done by the
   gcc::jit::recording::extended_asm::set_volatile_flag, in
   jit-recording.cc.  */

void
gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
					int flag)
{
  RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
  ext_asm->set_volatile_flag (flag);
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::extended_asm::set_inline_flag, in
   jit-recording.cc.  */

void
gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,
				      int flag)
{
  RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
  ext_asm->set_inline_flag (flag);
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::extended_asm::add_output_operand, in
   jit-recording.cc.  */

void
gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,
					 const char *asm_symbolic_name,
					 const char *constraint,
					 gcc_jit_lvalue *dest)
{
  RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
  gcc::jit::recording::context *ctxt = ext_asm->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  gcc::jit::recording::location *loc = ext_asm->get_loc ();
  /* asm_symbolic_name can be NULL.  */
  RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
  RETURN_IF_FAIL (dest, ctxt, loc, "NULL dest");
  RETURN_IF_FAIL (!ext_asm->is_goto (), ctxt, loc,
		  "cannot add output operand to asm goto");
  ext_asm->add_output_operand (asm_symbolic_name, constraint, dest);
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::extended_asm::add_input_operand, in
   jit-recording.cc.  */

extern void
gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,
					const char *asm_symbolic_name,
					const char *constraint,
					gcc_jit_rvalue *src)
{
  RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
  gcc::jit::recording::context *ctxt = ext_asm->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  gcc::jit::recording::location *loc = ext_asm->get_loc ();
  /* asm_symbolic_name can be NULL.  */
  RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
  RETURN_IF_FAIL (src, ctxt, loc, "NULL src");
  ext_asm->add_input_operand (asm_symbolic_name, constraint, src);
}

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

   After error-checking, the real work is done by the
   gcc::jit::recording::extended_asm::add_clobber, in
   jit-recording.cc.  */

void
gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,
				  const char *victim)
{
  RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
  gcc::jit::recording::context *ctxt = ext_asm->get_context ();
  JIT_LOG_FUNC (ctxt->get_logger ());
  gcc::jit::recording::location *loc = ext_asm->get_loc ();
  RETURN_IF_FAIL (victim, ctxt, loc, "NULL victim");
  ext_asm->add_clobber (victim);
}

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

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

void
gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
				   gcc_jit_location *loc,
				   const char *asm_stmts)
{
  RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
  JIT_LOG_FUNC (ctxt->get_logger ());
  /* LOC can be NULL.  */
  RETURN_IF_FAIL (asm_stmts, ctxt, NULL, "NULL asm_stmts");
  ctxt->add_top_level_asm (loc, asm_stmts);
}
