/* A C++ API for libgccjit, purely as inline wrapper functions.
   Copyright (C) 2014-2021 Free Software Foundation, Inc.

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

#ifndef LIBGCCJIT_PLUS_PLUS_H
#define LIBGCCJIT_PLUS_PLUS_H

#include "libgccjit.h"

#include <limits>
#include <ostream>
#include <vector>

/****************************************************************************
 C++ API
 ****************************************************************************/

namespace gccjit
{
  /* Indentation indicates inheritance.  */
  class context;
  class error;
  class object;
    class location;
    class field;
    class type;
      class struct_;
    class function;
    class block;
    class rvalue;
     class lvalue;
       class param;
    class case_;
    class extended_asm;
  class timer;
  class auto_time;

  namespace version {};

  /* Errors within the API become C++ exceptions of this class.  */
  class error
  {
  };

  class object
  {
  public:
    context get_context () const;

    std::string get_debug_string () const;

  protected:
    object ();
    object (gcc_jit_object *obj);

    gcc_jit_object *get_inner_object () const;

  private:
    gcc_jit_object *m_inner_obj;
  };

  inline std::ostream& operator << (std::ostream& stream, const object &obj);

  /* Some client code will want to supply source code locations, others
     won't.  To avoid doubling the number of entrypoints, everything
     accepting a location also has a default argument.  To do this, the
     other classes need to see that "location" has a default constructor,
     hence we need to declare it first.  */
  class location : public object
  {
  public:
    location ();
    location (gcc_jit_location *loc);

    gcc_jit_location *get_inner_location () const;
  };

  class context
  {
  public:
    static context acquire ();
    context ();
    context (gcc_jit_context *ctxt);

    gccjit::context new_child_context ();

    gcc_jit_context *get_inner_context () { return m_inner_ctxt; }

    void release ();

    gcc_jit_result *compile ();

    void compile_to_file (enum gcc_jit_output_kind output_kind,
			  const char *output_path);

    void dump_to_file (const std::string &path,
		       bool update_locations);

    void set_logfile (FILE *logfile,
		      int flags,
		      int verbosity);

    void dump_reproducer_to_file (const char *path);

    void set_str_option (enum gcc_jit_str_option opt,
			 const char *value);

    void set_int_option (enum gcc_jit_int_option opt,
			 int value);

    void set_bool_option (enum gcc_jit_bool_option opt,
			  int value);

    void set_bool_allow_unreachable_blocks (int bool_value);
    void set_bool_use_external_driver (int bool_value);

    void add_command_line_option (const char *optname);
    void add_driver_option (const char *optname);

    void set_timer (gccjit::timer t);
    gccjit::timer get_timer () const;

    location
    new_location (const std::string &filename,
		  int line,
		  int column);

    type get_type (enum gcc_jit_types kind);
    type get_int_type (size_t num_bytes, int is_signed);

    /* A way to map a specific int type, using the compiler to
       get the details automatically e.g.:
	  gccjit::type type = get_int_type <my_int_type_t> ();  */
    template <typename T>
    type get_int_type ();

    type new_array_type (type element_type, int num_elements,
			 location loc = location ());

    field new_field (type type_, const std::string &name,
		     location loc = location ());

    field new_bitfield (type type_, int width, const std::string &name,
			location loc = location ());

    struct_ new_struct_type (const std::string &name,
			     std::vector<field> &fields,
			     location loc = location ());

    struct_ new_opaque_struct_type (const std::string &name,
				    location loc = location ());

    param new_param (type type_,
		     const std::string &name,
		     location loc = location ());

    function new_function (enum gcc_jit_function_kind kind,
			   type return_type,
			   const std::string &name,
			   std::vector<param> &params,
			   int is_variadic,
			   location loc = location ());

    function get_builtin_function (const std::string &name);

    lvalue new_global (enum gcc_jit_global_kind kind,
		       type type_,
		       const std::string &name,
		       location loc = location ());

    rvalue new_rvalue (type numeric_type,
		       int value) const;
    rvalue new_rvalue (type numeric_type,
		       long value) const;
    rvalue zero (type numeric_type) const;
    rvalue one (type numeric_type) const;
    rvalue new_rvalue (type numeric_type,
		       double value) const;
    rvalue new_rvalue (type pointer_type,
		       void *value) const;
    rvalue new_rvalue (const std::string &value) const;
    rvalue new_rvalue (type vector_type,
		       std::vector<rvalue> elements) const;

    /* Generic unary operations...  */
    rvalue new_unary_op (enum gcc_jit_unary_op op,
			 type result_type,
			 rvalue a,
			 location loc = location ());

    /* ...and shorter ways to spell the various specific kinds of
       unary op.  */
    rvalue new_minus (type result_type,
		      rvalue a,
		      location loc = location ());
    rvalue new_bitwise_negate (type result_type,
			       rvalue a,
			       location loc = location ());
    rvalue new_logical_negate (type result_type,
			       rvalue a,
			       location loc = location ());

    /* Generic binary operations...  */
    rvalue new_binary_op (enum gcc_jit_binary_op op,
			  type result_type,
			  rvalue a, rvalue b,
			  location loc = location ());

    /* ...and shorter ways to spell the various specific kinds of
       binary op.  */
    rvalue new_plus (type result_type,
		     rvalue a, rvalue b,
		     location loc = location ());
    rvalue new_minus (type result_type,
		      rvalue a, rvalue b,
		      location loc = location ());
    rvalue new_mult (type result_type,
		     rvalue a, rvalue b,
		     location loc = location ());
    rvalue new_divide (type result_type,
		       rvalue a, rvalue b,
		       location loc = location ());
    rvalue new_modulo (type result_type,
		       rvalue a, rvalue b,
		       location loc = location ());
    rvalue new_bitwise_and (type result_type,
			    rvalue a, rvalue b,
			    location loc = location ());
    rvalue new_bitwise_xor (type result_type,
			    rvalue a, rvalue b,
			    location loc = location ());
    rvalue new_bitwise_or (type result_type,
			   rvalue a, rvalue b,
			   location loc = location ());
    rvalue new_logical_and (type result_type,
			    rvalue a, rvalue b,
			    location loc = location ());
    rvalue new_logical_or (type result_type,
			   rvalue a, rvalue b,
			   location loc = location ());

    /* Generic comparisons...  */
    rvalue new_comparison (enum gcc_jit_comparison op,
			   rvalue a, rvalue b,
			   location loc = location ());
    /* ...and shorter ways to spell the various specific kinds of
       comparison.  */
    rvalue new_eq (rvalue a, rvalue b,
		   location loc = location ());
    rvalue new_ne (rvalue a, rvalue b,
		   location loc = location ());
    rvalue new_lt (rvalue a, rvalue b,
		   location loc = location ());
    rvalue new_le (rvalue a, rvalue b,
		   location loc = location ());
    rvalue new_gt (rvalue a, rvalue b,
		   location loc = location ());
    rvalue new_ge (rvalue a, rvalue b,
		   location loc = location ());

    /* The most general way of creating a function call.  */
    rvalue new_call (function func,
		     std::vector<rvalue> &args,
		     location loc = location ());

    /* In addition, we provide a series of overloaded "new_call" methods
       for specific numbers of args (from 0 - 6), to avoid the need for
       client code to manually build a vector.  */
    rvalue new_call (function func,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0, rvalue arg1,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0, rvalue arg1, rvalue arg2,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0, rvalue arg1, rvalue arg2,
		     rvalue arg3,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0, rvalue arg1, rvalue arg2,
		     rvalue arg3, rvalue arg4,
		     location loc = location ());
    rvalue new_call (function func,
		     rvalue arg0, rvalue arg1, rvalue arg2,
		     rvalue arg3, rvalue arg4, rvalue arg5,
		     location loc = location ());

    rvalue new_cast (rvalue expr,
		     type type_,
		     location loc = location ());

    lvalue new_array_access (rvalue ptr,
			     rvalue index,
			     location loc = location ());

    case_ new_case (rvalue min_value,
		    rvalue max_value,
		    block dest_block);

    void add_top_level_asm (const char *asm_stmts,
			    location loc = location ());

  private:
    gcc_jit_context *m_inner_ctxt;
  };

  class field : public object
  {
  public:
    field ();
    field (gcc_jit_field *inner);

    gcc_jit_field *get_inner_field () const;
  };

  class type : public object
  {
  public:
    type ();
    type (gcc_jit_type *inner);

    gcc_jit_type *get_inner_type () const;

    type get_pointer ();
    type get_const ();
    type get_volatile ();
    type get_aligned (size_t alignment_in_bytes);
    type get_vector (size_t num_units);

    // Shortcuts for getting values of numeric types:
    rvalue zero ();
    rvalue one ();
 };

  class struct_ : public type
  {
  public:
    struct_ ();
    struct_ (gcc_jit_struct *inner);

    gcc_jit_struct *get_inner_struct () const;
  };

  class function : public object
  {
  public:
    function ();
    function (gcc_jit_function *func);

    gcc_jit_function *get_inner_function () const;

    void dump_to_dot (const std::string &path);

    param get_param (int index) const;

    block new_block ();
    block new_block (const std::string &name);

    lvalue new_local (type type_,
		      const std::string &name,
		      location loc = location ());

    rvalue get_address (location loc = location ());

    /* A series of overloaded operator () with various numbers of arguments
       for a very terse way of creating a call to this function.  The call
       is created within the same context as the function itself, which may
       not be what you want.  */
    rvalue operator() (location loc = location ());
    rvalue operator() (rvalue arg0,
		       location loc = location ());
    rvalue operator() (rvalue arg0, rvalue arg1,
		       location loc = location ());
    rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
		       location loc = location ());
  };

  class block : public object
  {
  public:
    block ();
    block (gcc_jit_block *inner);

    gcc_jit_block *get_inner_block () const;

    function get_function () const;

    void add_eval (rvalue rvalue,
		   location loc = location ());

    void add_assignment (lvalue lvalue,
			 rvalue rvalue,
			 location loc = location ());

    void add_assignment_op (lvalue lvalue,
			    enum gcc_jit_binary_op op,
			    rvalue rvalue,
			    location loc = location ());

    /* A way to add a function call to the body of a function being
       defined, with various numbers of args.  */
    rvalue add_call (function other,
		     location loc = location ());
    rvalue add_call (function other,
		     rvalue arg0,
		     location loc = location ());
    rvalue add_call (function other,
		     rvalue arg0, rvalue arg1,
		     location loc = location ());
    rvalue add_call (function other,
		     rvalue arg0, rvalue arg1, rvalue arg2,
		     location loc = location ());
    rvalue add_call (function other,
		     rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
		     location loc = location ());

    void add_comment (const std::string &text,
		      location loc = location ());

    void end_with_conditional (rvalue boolval,
			       block on_true,
			       block on_false,
			       location loc = location ());

    void end_with_jump (block target,
			location loc = location ());

    void end_with_return (rvalue rvalue,
			  location loc = location ());
    void end_with_return (location loc = location ());

    void end_with_switch (rvalue expr,
			  block default_block,
			  std::vector <case_> cases,
			  location loc = location ());

    extended_asm add_extended_asm (const std::string &asm_template,
				   location loc = location ());
    extended_asm end_with_extended_asm_goto (const std::string &asm_template,
					     std::vector<block> goto_blocks,
					     block *fallthrough_block,
					     location loc = location ());
  };

  class rvalue : public object
  {
  public:
    rvalue ();
    rvalue (gcc_jit_rvalue *inner);
    gcc_jit_rvalue *get_inner_rvalue () const;

    type get_type ();

    rvalue access_field (field field,
			 location loc = location ());

    lvalue dereference_field (field field,
			      location loc = location ());

    lvalue dereference (location loc = location ());

    rvalue cast_to (type type_,
		    location loc = location ());

    /* Array access.  */
    lvalue operator[] (rvalue index);
    lvalue operator[] (int index);
  };

  class lvalue : public rvalue
  {
  public:
    lvalue ();
    lvalue (gcc_jit_lvalue *inner);

    gcc_jit_lvalue *get_inner_lvalue () const;

    lvalue access_field (field field,
			 location loc = location ());

    rvalue get_address (location loc = location ());
    lvalue set_initializer (const void *blob, size_t num_bytes);
  };

  class param : public lvalue
  {
  public:
    param ();
    param (gcc_jit_param *inner);

    gcc_jit_param *get_inner_param () const;
  };

  class case_ : public object
  {
  public:
    case_ ();
    case_ (gcc_jit_case *inner);

    gcc_jit_case *get_inner_case () const;
  };

  class extended_asm : public object
  {
  public:
    extended_asm ();
    extended_asm (gcc_jit_extended_asm *inner);

    extended_asm &
    set_volatile_flag (bool flag);

    extended_asm &
    set_inline_flag (bool flag);

    extended_asm&
    add_output_operand (const std::string &asm_symbolic_name,
			const std::string &constraint,
			gccjit::lvalue dest);
    extended_asm&
    add_output_operand (const std::string &constraint,
			gccjit::lvalue dest);

    extended_asm&
    add_input_operand (const std::string &asm_symbolic_name,
		       const std::string &constraint,
		       gccjit::rvalue src);
    extended_asm&
    add_input_operand (const std::string &constraint,
		       gccjit::rvalue src);

    extended_asm&
    add_clobber (const std::string &victim);

    gcc_jit_extended_asm *get_inner_extended_asm () const;
  };

  /* Overloaded operators, for those who want the most terse API
     (at the possible risk of being a little too magical).

     In each case, the first parameter is used to determine which context
     owns the resulting expression, and, where appropriate,  what the
     latter's type is. */

  /* Unary operators.  */
  rvalue operator- (rvalue a); // unary minus
  rvalue operator~ (rvalue a); // unary bitwise negate
  rvalue operator! (rvalue a); // unary logical negate

  /* Binary operators.  */
  rvalue operator+ (rvalue a, rvalue b);
  rvalue operator- (rvalue a, rvalue b);
  rvalue operator* (rvalue a, rvalue b);
  rvalue operator/ (rvalue a, rvalue b);
  rvalue operator% (rvalue a, rvalue b);
  rvalue operator& (rvalue a, rvalue b); //  bitwise and
  rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
  rvalue operator| (rvalue a, rvalue b); // bitwise_or
  rvalue operator&& (rvalue a, rvalue b); // logical_and
  rvalue operator|| (rvalue a, rvalue b); // logical_or

  /* Comparisons.  */
  rvalue operator== (rvalue a, rvalue b);
  rvalue operator!= (rvalue a, rvalue b);
  rvalue operator< (rvalue a, rvalue b);
  rvalue operator<= (rvalue a, rvalue b);
  rvalue operator> (rvalue a, rvalue b);
  rvalue operator>= (rvalue a, rvalue b);

  /* Dereferencing. */
  lvalue operator* (rvalue ptr);

  class timer
  {
  public:
    timer ();
    timer (gcc_jit_timer *inner_timer);

    void push (const char *item_name);
    void pop (const char *item_name);
    void print (FILE *f_out) const;

    void release ();

    gcc_jit_timer *get_inner_timer () const;

  private:
    gcc_jit_timer *m_inner_timer;
  };

  class auto_time
  {
  public:
    auto_time (timer t, const char *item_name);
    auto_time (context ctxt, const char *item_name);
    ~auto_time ();

  private:
    timer m_timer;
    const char *m_item_name;
  };
}

/****************************************************************************
 Implementation of the API
 ****************************************************************************/
namespace gccjit {

// class context
inline context context::acquire ()
{
  return context (gcc_jit_context_acquire ());
}
inline context::context () : m_inner_ctxt (NULL) {}
inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
{
  if (!inner)
    throw error ();
}

inline gccjit::context
context::new_child_context ()
{
  return context (gcc_jit_context_new_child_context (m_inner_ctxt));
}

inline void
context::release ()
{
  gcc_jit_context_release (m_inner_ctxt);
  m_inner_ctxt = NULL;
}

inline gcc_jit_result *
context::compile ()
{
  gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
  if (!result)
    throw error ();
  return result;
}

inline void
context::compile_to_file (enum gcc_jit_output_kind output_kind,
			  const char *output_path)
{
  gcc_jit_context_compile_to_file (m_inner_ctxt,
				   output_kind,
				   output_path);
}

inline void
context::dump_to_file (const std::string &path,
		       bool update_locations)
{
  gcc_jit_context_dump_to_file (m_inner_ctxt,
				path.c_str (),
				update_locations);
}

inline void
context::set_logfile (FILE *logfile,
		      int flags,
		      int verbosity)
{
  gcc_jit_context_set_logfile (m_inner_ctxt,
			       logfile,
			       flags,
			       verbosity);
}

inline void
context::dump_reproducer_to_file (const char *path)
{
  gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
					   path);
}

inline void
context::set_str_option (enum gcc_jit_str_option opt,
			 const char *value)
{
  gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);

}

inline void
context::set_int_option (enum gcc_jit_int_option opt,
			 int value)
{
  gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);

}

inline void
context::set_bool_option (enum gcc_jit_bool_option opt,
			  int value)
{
  gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
}

inline void
context::set_bool_allow_unreachable_blocks (int bool_value)
{
  gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
						     bool_value);
}

inline void
context::set_bool_use_external_driver (int bool_value)
{
  gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt,
						bool_value);
}

inline void
context::add_command_line_option (const char *optname)
{
  gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
}

inline void
context::add_driver_option (const char *optname)
{
  gcc_jit_context_add_driver_option (m_inner_ctxt, optname);
}

inline void
context::set_timer (gccjit::timer t)
{
  gcc_jit_context_set_timer (m_inner_ctxt, t.get_inner_timer ());
}

inline gccjit::timer
context::get_timer () const
{
  return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt));
}


inline location
context::new_location (const std::string &filename,
		       int line,
		       int column)
{
  return location (gcc_jit_context_new_location (m_inner_ctxt,
						 filename.c_str (),
						 line,
						 column));
}

inline type
context::get_type (enum gcc_jit_types kind)
{
  return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
}

inline type
context::get_int_type (size_t num_bytes, int is_signed)
{
  return type (gcc_jit_context_get_int_type (m_inner_ctxt,
					     num_bytes,
					     is_signed));
}

template <typename T>
inline type
context::get_int_type ()
{
  return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
}

inline type
context::new_array_type (type element_type, int num_elements, location loc)
{
  return type (gcc_jit_context_new_array_type (
		 m_inner_ctxt,
		 loc.get_inner_location (),
		 element_type.get_inner_type (),
		 num_elements));
}

inline field
context::new_field (type type_, const std::string &name, location loc)
{
  return field (gcc_jit_context_new_field (m_inner_ctxt,
					   loc.get_inner_location (),
					   type_.get_inner_type (),
					   name.c_str ()));
}

inline field
context::new_bitfield (type type_, int width, const std::string &name,
		       location loc)
{
  return field (gcc_jit_context_new_bitfield (m_inner_ctxt,
					      loc.get_inner_location (),
					      type_.get_inner_type (),
					      width,
					      name.c_str ()));
}

inline struct_
context::new_struct_type (const std::string &name,
			  std::vector<field> &fields,
			  location loc)
{
  /* Treat std::vector as an array, relying on it not being resized: */
  field *as_array_of_wrappers = &fields[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.	*/
  gcc_jit_field **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);

  return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
						   loc.get_inner_location (),
						   name.c_str (),
						   fields.size (),
						   as_array_of_ptrs));
}

inline struct_
context::new_opaque_struct_type (const std::string &name,
				 location loc)
{
  return struct_ (gcc_jit_context_new_opaque_struct (
		    m_inner_ctxt,
		    loc.get_inner_location (),
		    name.c_str ()));
}

inline param
context::new_param (type type_,
		    const std::string &name,
		    location loc)
{
  return param (gcc_jit_context_new_param (m_inner_ctxt,
					   loc.get_inner_location (),
					   type_.get_inner_type (),
					   name.c_str ()));
}

inline function
context::new_function (enum gcc_jit_function_kind kind,
		       type return_type,
		       const std::string &name,
		       std::vector<param> &params,
		       int is_variadic,
		       location loc)
{
  /* Treat std::vector as an array, relying on it not being resized: */
  param *as_array_of_wrappers = &params[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.	*/
  gcc_jit_param **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);

  return function (gcc_jit_context_new_function (m_inner_ctxt,
						 loc.get_inner_location (),
						 kind,
						 return_type.get_inner_type (),
						 name.c_str (),
						 params.size (),
						 as_array_of_ptrs,
						 is_variadic));
}

inline function
context::get_builtin_function (const std::string &name)
{
  return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
							 name.c_str ()));
}

inline lvalue
context::new_global (enum gcc_jit_global_kind kind,
		     type type_,
		     const std::string &name,
		     location loc)
{
  return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
					     loc.get_inner_location (),
					     kind,
					     type_.get_inner_type (),
					     name.c_str ()));
}

inline rvalue
context::new_rvalue (type numeric_type,
		     int value) const
{
  return rvalue (
    gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
					 numeric_type.get_inner_type (),
					 value));
}

inline rvalue
context::new_rvalue (type numeric_type,
		     long value) const
{
  return rvalue (
    gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
					  numeric_type.get_inner_type (),
					  value));
}

inline rvalue
context::zero (type numeric_type) const
{
  return rvalue (gcc_jit_context_zero (m_inner_ctxt,
				       numeric_type.get_inner_type ()));
}

inline rvalue
context::one (type numeric_type) const
{
  return rvalue (gcc_jit_context_one (m_inner_ctxt,
				       numeric_type.get_inner_type ()));
}

inline rvalue
context::new_rvalue (type numeric_type,
		     double value) const
{
  return rvalue (
    gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
					    numeric_type.get_inner_type (),
					    value));
}

inline rvalue
context::new_rvalue (type pointer_type,
		     void *value) const
{
  return rvalue (
    gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
					 pointer_type.get_inner_type (),
					 value));
}

inline rvalue
context::new_rvalue (const std::string &value) const
{
  return rvalue (
    gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
}

inline rvalue
context::new_rvalue (type vector_type,
		     std::vector<rvalue> elements) const
{
  /* Treat std::vector as an array, relying on it not being resized: */
  rvalue *as_array_of_wrappers = &elements[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.	*/
  gcc_jit_rvalue **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);

  return rvalue (
    gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt,
					    NULL,
					    vector_type.get_inner_type (),
					    elements.size (),
					    as_array_of_ptrs));
}

inline rvalue
context::new_unary_op (enum gcc_jit_unary_op op,
		       type result_type,
		       rvalue a,
		       location loc)
{
  return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
					       loc.get_inner_location (),
					       op,
					       result_type.get_inner_type (),
					       a.get_inner_rvalue ()));
}
inline rvalue
context::new_minus (type result_type,
		    rvalue a,
		    location loc)
{
  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
			       result_type, a, loc));
}
inline rvalue
context::new_bitwise_negate (type result_type,
			     rvalue a,
			     location loc)
{
  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
			       result_type, a, loc));
}
inline rvalue
context::new_logical_negate (type result_type,
			     rvalue a,
			     location loc)
{
  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
			       result_type, a, loc));
}

inline rvalue
context::new_binary_op (enum gcc_jit_binary_op op,
			type result_type,
			rvalue a, rvalue b,
			location loc)
{
  return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
						loc.get_inner_location (),
						op,
						result_type.get_inner_type (),
						a.get_inner_rvalue (),
						b.get_inner_rvalue ()));
}
inline rvalue
context::new_plus (type result_type,
		   rvalue a, rvalue b,
		   location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
			result_type, a, b, loc);
}
inline rvalue
context::new_minus (type result_type,
		    rvalue a, rvalue b,
		    location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
			result_type, a, b, loc);
}
inline rvalue
context::new_mult (type result_type,
		   rvalue a, rvalue b,
		   location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_MULT,
			result_type, a, b, loc);
}
inline rvalue
context::new_divide (type result_type,
		     rvalue a, rvalue b,
		     location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
			result_type, a, b, loc);
}
inline rvalue
context::new_modulo (type result_type,
		     rvalue a, rvalue b,
		     location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
			result_type, a, b, loc);
}
inline rvalue
context::new_bitwise_and (type result_type,
			  rvalue a, rvalue b,
			  location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
			result_type, a, b, loc);
}
inline rvalue
context::new_bitwise_xor (type result_type,
			  rvalue a, rvalue b,
			  location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
			result_type, a, b, loc);
}
inline rvalue
context::new_bitwise_or (type result_type,
			 rvalue a, rvalue b,
			 location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
			result_type, a, b, loc);
}
inline rvalue
context::new_logical_and (type result_type,
			  rvalue a, rvalue b,
			  location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
			result_type, a, b, loc);
}
inline rvalue
context::new_logical_or (type result_type,
			 rvalue a, rvalue b,
			 location loc)
{
  return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
			result_type, a, b, loc);
}

inline rvalue
context::new_comparison (enum gcc_jit_comparison op,
			 rvalue a, rvalue b,
			 location loc)
{
  return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
						 loc.get_inner_location (),
						 op,
						 a.get_inner_rvalue (),
						 b.get_inner_rvalue ()));
}
inline rvalue
context::new_eq (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_EQ,
			 a, b, loc);
}
inline rvalue
context::new_ne (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_NE,
			 a, b, loc);
}
inline rvalue
context::new_lt (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_LT,
			 a, b, loc);
}
inline rvalue
context::new_le (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_LE,
			 a, b, loc);
}
inline rvalue
context::new_gt (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_GT,
			 a, b, loc);
}
inline rvalue
context::new_ge (rvalue a, rvalue b,
		 location loc)
{
  return new_comparison (GCC_JIT_COMPARISON_GE,
			 a, b, loc);
}

inline rvalue
context::new_call (function func,
		   std::vector<rvalue> &args,
		   location loc)
{
  /* Treat std::vector as an array, relying on it not being resized: */
  rvalue *as_array_of_wrappers = &args[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.	*/
  gcc_jit_rvalue **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
  return gcc_jit_context_new_call (m_inner_ctxt,
				   loc.get_inner_location (),
				   func.get_inner_function (),
				   args.size (),
				   as_array_of_ptrs);
}
inline rvalue
context::new_call (function func,
		   location loc)
{
  std::vector<rvalue> args;
  return new_call (func, args, loc);
}

inline rvalue
context::new_call (function func,
		   rvalue arg0,
		   location loc)
{
  std::vector<rvalue> args(1);
  args[0] = arg0;
  return new_call (func, args, loc);
}
inline rvalue
context::new_call (function func,
		   rvalue arg0, rvalue arg1,
		   location loc)
{
  std::vector<rvalue> args(2);
  args[0] = arg0;
  args[1] = arg1;
  return new_call (func, args, loc);
}
inline rvalue
context::new_call (function func,
		   rvalue arg0, rvalue arg1, rvalue arg2,
		   location loc)
{
  std::vector<rvalue> args(3);
  args[0] = arg0;
  args[1] = arg1;
  args[2] = arg2;
  return new_call (func, args, loc);
}
inline rvalue
context::new_call (function func,
		   rvalue arg0, rvalue arg1, rvalue arg2,
		   rvalue arg3,
		   location loc)
{
  std::vector<rvalue> args(4);
  args[0] = arg0;
  args[1] = arg1;
  args[2] = arg2;
  args[3] = arg3;
  return new_call (func, args, loc);
}
inline rvalue
context::new_call (function func,
		   rvalue arg0, rvalue arg1, rvalue arg2,
		   rvalue arg3, rvalue arg4,
		   location loc)
{
  std::vector<rvalue> args(5);
  args[0] = arg0;
  args[1] = arg1;
  args[2] = arg2;
  args[3] = arg3;
  args[4] = arg4;
  return new_call (func, args, loc);
}
inline rvalue
context::new_call (function func,
		   rvalue arg0, rvalue arg1, rvalue arg2,
		   rvalue arg3, rvalue arg4, rvalue arg5,
		   location loc)
{
  std::vector<rvalue> args(6);
  args[0] = arg0;
  args[1] = arg1;
  args[2] = arg2;
  args[3] = arg3;
  args[4] = arg4;
  args[5] = arg5;
  return new_call (func, args, loc);
}

inline rvalue
context::new_cast (rvalue expr,
		   type type_,
		   location loc)
{
  return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
					   loc.get_inner_location (),
					   expr.get_inner_rvalue (),
					   type_.get_inner_type ()));
}

inline lvalue
context::new_array_access (rvalue ptr,
			   rvalue index,
			   location loc)
{
  return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
						   loc.get_inner_location (),
						   ptr.get_inner_rvalue (),
						   index.get_inner_rvalue ()));
}

inline case_
context::new_case (rvalue min_value,
		   rvalue max_value,
		   block dest_block)
{
  return case_ (gcc_jit_context_new_case (m_inner_ctxt,
					  min_value.get_inner_rvalue (),
					  max_value.get_inner_rvalue (),
					  dest_block.get_inner_block ()));
}

inline void
context::add_top_level_asm (const char *asm_stmts, location loc)
{
  gcc_jit_context_add_top_level_asm (m_inner_ctxt,
				     loc.get_inner_location (),
				     asm_stmts);
}

// class object
inline context
object::get_context () const
{
  return context (gcc_jit_object_get_context (m_inner_obj));
}

inline std::string
object::get_debug_string () const
{
  return gcc_jit_object_get_debug_string (m_inner_obj);
}

inline object::object () : m_inner_obj (NULL) {}
inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
{
  if (!obj)
    throw error ();
}

inline gcc_jit_object *
object::get_inner_object () const
{
  return m_inner_obj;
}

inline std::ostream&
operator << (std::ostream& stream, const object &obj)
{
  return stream << obj.get_debug_string ();
}

// class location
inline location::location () : object () {}
inline location::location (gcc_jit_location *loc)
  : object (gcc_jit_location_as_object (loc))
{}

inline gcc_jit_location *
location::get_inner_location () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
}

// class field
inline field::field () : object () {}
inline field::field (gcc_jit_field *inner)
  : object (gcc_jit_field_as_object (inner))
{}

inline gcc_jit_field *
field::get_inner_field () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
}

// class type
inline type::type () : object () {}
inline type::type (gcc_jit_type *inner)
  : object (gcc_jit_type_as_object (inner))
{}

inline gcc_jit_type *
type::get_inner_type () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
}

inline type
type::get_pointer ()
{
  return type (gcc_jit_type_get_pointer (get_inner_type ()));
}

inline type
type::get_const ()
{
  return type (gcc_jit_type_get_const (get_inner_type ()));
}

inline type
type::get_volatile ()
{
  return type (gcc_jit_type_get_volatile (get_inner_type ()));
}

inline type
type::get_aligned (size_t alignment_in_bytes)
{
  return type (gcc_jit_type_get_aligned (get_inner_type (),
					 alignment_in_bytes));
}

inline type
type::get_vector (size_t num_units)
{
  return type (gcc_jit_type_get_vector (get_inner_type (),
					num_units));
}

inline rvalue
type::zero ()
{
  return get_context ().new_rvalue (*this, 0);
}

inline rvalue
type::one ()
{
  return get_context ().new_rvalue (*this, 1);
}

// class struct_
inline struct_::struct_ () : type (NULL) {}
inline struct_::struct_ (gcc_jit_struct *inner) :
  type (gcc_jit_struct_as_type (inner))
{
}

inline gcc_jit_struct *
struct_::get_inner_struct () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
}

// class function
inline function::function () : object () {}
inline function::function (gcc_jit_function *inner)
  : object (gcc_jit_function_as_object (inner))
{}

inline gcc_jit_function *
function::get_inner_function () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
}

inline void
function::dump_to_dot (const std::string &path)
{
  gcc_jit_function_dump_to_dot (get_inner_function (),
				path.c_str ());
}

inline param
function::get_param (int index) const
{
  return param (gcc_jit_function_get_param (get_inner_function (),
					    index));
}

inline block
function::new_block ()
{
  return block (gcc_jit_function_new_block (get_inner_function (),
					    NULL));
}

inline block
function::new_block (const std::string &name)
{
  return block (gcc_jit_function_new_block (get_inner_function (),
					    name.c_str ()));
}

inline lvalue
function::new_local (type type_,
		     const std::string &name,
		     location loc)
{
  return lvalue (gcc_jit_function_new_local (get_inner_function (),
					     loc.get_inner_location (),
					     type_.get_inner_type (),
					     name.c_str ()));
}

inline rvalue
function::get_address (location loc)
{
  return rvalue (gcc_jit_function_get_address (get_inner_function (),
					       loc.get_inner_location ()));
}

inline function
block::get_function () const
{
  return function (gcc_jit_block_get_function ( get_inner_block ()));
}

inline void
block::add_eval (rvalue rvalue,
		 location loc)
{
  gcc_jit_block_add_eval (get_inner_block (),
			  loc.get_inner_location (),
			  rvalue.get_inner_rvalue ());
}

inline void
block::add_assignment (lvalue lvalue,
		       rvalue rvalue,
		       location loc)
{
  gcc_jit_block_add_assignment (get_inner_block (),
				loc.get_inner_location (),
				lvalue.get_inner_lvalue (),
				rvalue.get_inner_rvalue ());
}

inline void
block::add_assignment_op (lvalue lvalue,
			  enum gcc_jit_binary_op op,
			  rvalue rvalue,
			  location loc)
{
  gcc_jit_block_add_assignment_op (get_inner_block (),
				   loc.get_inner_location (),
				   lvalue.get_inner_lvalue (),
				   op,
				   rvalue.get_inner_rvalue ());
}

inline void
block::add_comment (const std::string &text,
		    location loc)
{
  gcc_jit_block_add_comment (get_inner_block (),
			     loc.get_inner_location (),
			     text.c_str ());
}

inline void
block::end_with_conditional (rvalue boolval,
			     block on_true,
			     block on_false,
			     location loc)
{
  gcc_jit_block_end_with_conditional (get_inner_block (),
				      loc.get_inner_location (),
				      boolval.get_inner_rvalue (),
				      on_true.get_inner_block (),
				      on_false.get_inner_block ());
}

inline void
block::end_with_jump (block target,
		      location loc)
{
  gcc_jit_block_end_with_jump (get_inner_block (),
			       loc.get_inner_location (),
			       target.get_inner_block ());
}

inline void
block::end_with_return (rvalue rvalue,
			location loc)
{
  gcc_jit_block_end_with_return (get_inner_block (),
				 loc.get_inner_location (),
				 rvalue.get_inner_rvalue ());
}

inline void
block::end_with_return (location loc)
{
  gcc_jit_block_end_with_void_return (get_inner_block (),
				      loc.get_inner_location ());
}

inline void
block::end_with_switch (rvalue expr,
			block default_block,
			std::vector <case_> cases,
			location loc)
{
  /* Treat std::vector as an array, relying on it not being resized: */
  case_ *as_array_of_wrappers = &cases[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.	*/
  gcc_jit_case **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_case **> (as_array_of_wrappers);
  gcc_jit_block_end_with_switch (get_inner_block (),
				 loc.get_inner_location (),
				 expr.get_inner_rvalue (),
				 default_block.get_inner_block (),
				 cases.size (),
				 as_array_of_ptrs);
}

inline extended_asm
block::add_extended_asm (const std::string &asm_template,
			 location loc)
{
  return gcc_jit_block_add_extended_asm (get_inner_block (),
					 loc.get_inner_location (),
					 asm_template.c_str ());
}

inline extended_asm
block::end_with_extended_asm_goto (const std::string &asm_template,
				   std::vector<block> goto_blocks,
				   block *fallthrough_block,
				   location loc)
{
  /* Treat std::vector as an array, relying on it not being resized: */
  block *as_array_of_wrappers = &goto_blocks[0];

  /* Treat the array as being of the underlying pointers, relying on
     the wrapper type being such a pointer internally.  */
  gcc_jit_block **as_array_of_ptrs =
    reinterpret_cast<gcc_jit_block **> (as_array_of_wrappers);
  return gcc_jit_block_end_with_extended_asm_goto
    (get_inner_block (),
     loc.get_inner_location (),
     asm_template.c_str (),
     goto_blocks.size (),
     as_array_of_ptrs,
     fallthrough_block ? fallthrough_block->get_inner_block () : NULL);
}

inline rvalue
block::add_call (function other,
		 location loc)
{
  rvalue c = get_context ().new_call (other, loc);
  add_eval (c);
  return c;
}
inline rvalue
block::add_call (function other,
		 rvalue arg0,
		 location loc)
{
  rvalue c = get_context ().new_call (other, arg0, loc);
  add_eval (c);
  return c;
}
inline rvalue
block::add_call (function other,
		 rvalue arg0, rvalue arg1,
		 location loc)
{
  rvalue c = get_context ().new_call (other, arg0, arg1, loc);
  add_eval (c);
  return c;
}
inline rvalue
block::add_call (function other,
		 rvalue arg0, rvalue arg1, rvalue arg2,
		 location loc)
{
  rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
  add_eval (c);
  return c;
}

inline rvalue
block::add_call (function other,
		 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
		 location loc)
{
  rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
  add_eval (c);
  return c;
}

inline rvalue
function::operator() (location loc)
{
  return get_context ().new_call (*this, loc);
}
inline rvalue
function::operator() (rvalue arg0,
		      location loc)
{
  return get_context ().new_call (*this,
				  arg0,
				  loc);
}
inline rvalue
function::operator() (rvalue arg0, rvalue arg1,
		      location loc)
{
  return get_context ().new_call (*this,
				  arg0, arg1,
				  loc);
}
inline rvalue
function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
		      location loc)
{
  return get_context ().new_call (*this,
				  arg0, arg1, arg2,
				  loc);
}

// class block
inline block::block () : object () {}
inline block::block (gcc_jit_block *inner)
  : object (gcc_jit_block_as_object (inner))
{}

inline gcc_jit_block *
block::get_inner_block () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
}

//  class rvalue
inline rvalue::rvalue () : object () {}
inline rvalue::rvalue (gcc_jit_rvalue *inner)
  : object (gcc_jit_rvalue_as_object (inner))
{}

inline gcc_jit_rvalue *
rvalue::get_inner_rvalue () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
}

inline type
rvalue::get_type ()
{
  return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
}

inline rvalue
rvalue::access_field (field field,
		      location loc)
{
  return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
					      loc.get_inner_location (),
					      field.get_inner_field ()));
}

inline lvalue
rvalue::dereference_field (field field,
			   location loc)
{
  return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
						   loc.get_inner_location (),
						   field.get_inner_field ()));
}

inline lvalue
rvalue::dereference (location loc)
{
  return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
					     loc.get_inner_location ()));
}

inline rvalue
rvalue::cast_to (type type_,
		 location loc)
{
  return get_context ().new_cast (*this, type_, loc);
}

inline lvalue
rvalue::operator[] (rvalue index)
{
  return get_context ().new_array_access (*this, index);
}

inline lvalue
rvalue::operator[] (int index)
{
  context ctxt = get_context ();
  type int_t = ctxt.get_int_type <int> ();
  return ctxt.new_array_access (*this,
				ctxt.new_rvalue (int_t,
						 index));
}

// class lvalue : public rvalue
inline lvalue::lvalue () : rvalue () {}
inline lvalue::lvalue (gcc_jit_lvalue *inner)
  : rvalue (gcc_jit_lvalue_as_rvalue (inner))
{}

inline gcc_jit_lvalue *
lvalue::get_inner_lvalue () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
}

inline lvalue
lvalue::access_field (field field, location loc)
{
  return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
					      loc.get_inner_location (),
					      field.get_inner_field ()));
}

inline rvalue
lvalue::get_address (location loc)
{
  return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
					     loc.get_inner_location ()));
}

inline lvalue
lvalue::set_initializer (const void *blob, size_t num_bytes)
{
  gcc_jit_global_set_initializer (get_inner_lvalue (),
                                  blob,
                                  num_bytes);
  return *this;
}

// class param : public lvalue
inline param::param () : lvalue () {}
inline param::param (gcc_jit_param *inner)
  : lvalue (gcc_jit_param_as_lvalue (inner))
{}

// class case_ : public object
inline case_::case_ () : object () {}
inline case_::case_ (gcc_jit_case *inner)
  : object (gcc_jit_case_as_object (inner))
{
}

inline gcc_jit_case *
case_::get_inner_case () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_case *> (get_inner_object ());
}

// class extended_asm : public object
inline extended_asm::extended_asm () : object () {}
inline extended_asm::extended_asm (gcc_jit_extended_asm *inner)
  : object (gcc_jit_extended_asm_as_object (inner))
{
}

inline extended_asm&
extended_asm::set_volatile_flag (bool flag)
{
  gcc_jit_extended_asm_set_volatile_flag (get_inner_extended_asm (), flag);
  return *this;
}

inline extended_asm&
extended_asm::set_inline_flag (bool flag)
{
  gcc_jit_extended_asm_set_inline_flag (get_inner_extended_asm (), flag);
  return *this;
}

inline extended_asm&
extended_asm::add_output_operand (const std::string &asm_symbolic_name,
				  const std::string &constraint,
				  gccjit::lvalue dest)
{
  gcc_jit_extended_asm_add_output_operand
    (get_inner_extended_asm (),
     asm_symbolic_name.c_str (),
     constraint.c_str (),
     dest.get_inner_lvalue ());
  return *this;
}

inline extended_asm&
extended_asm::add_output_operand (const std::string &constraint,
				  gccjit::lvalue dest)
{
  gcc_jit_extended_asm_add_output_operand
    (get_inner_extended_asm (),
     NULL, /* asm_symbolic_name */
     constraint.c_str (),
     dest.get_inner_lvalue ());
  return *this;
}

inline extended_asm&
extended_asm::add_input_operand (const std::string &asm_symbolic_name,
				 const std::string &constraint,
				 gccjit::rvalue src)
{
  gcc_jit_extended_asm_add_input_operand
    (get_inner_extended_asm (),
     asm_symbolic_name.c_str (),
     constraint.c_str (),
     src.get_inner_rvalue ());
  return *this;
}

inline extended_asm&
extended_asm::add_input_operand (const std::string &constraint,
				 gccjit::rvalue src)
{
  gcc_jit_extended_asm_add_input_operand
    (get_inner_extended_asm (),
     NULL, /* asm_symbolic_name */
     constraint.c_str (),
     src.get_inner_rvalue ());
  return *this;
}

inline extended_asm&
extended_asm::add_clobber (const std::string &victim)
{
  gcc_jit_extended_asm_add_clobber (get_inner_extended_asm (),
				    victim.c_str ());
  return *this;
}

inline gcc_jit_extended_asm *
extended_asm::get_inner_extended_asm () const
{
  /* Manual downcast: */
  return reinterpret_cast<gcc_jit_extended_asm *> (get_inner_object ());
}

/* Overloaded operators.  */
// Unary operators
inline rvalue operator- (rvalue a)
{
  return a.get_context ().new_minus (a.get_type (), a);
}
inline rvalue operator~ (rvalue a)
{
  return a.get_context ().new_bitwise_negate (a.get_type (), a);
}
inline rvalue operator! (rvalue a)
{
  return a.get_context ().new_logical_negate (a.get_type (), a);
}

// Binary operators
inline rvalue operator+ (rvalue a, rvalue b)
{
  return a.get_context ().new_plus (a.get_type (), a, b);
}
inline rvalue operator- (rvalue a, rvalue b)
{
  return a.get_context ().new_minus (a.get_type (), a, b);
}
inline rvalue operator* (rvalue a, rvalue b)
{
  return a.get_context ().new_mult (a.get_type (), a, b);
}
inline rvalue operator/ (rvalue a, rvalue b)
{
  return a.get_context ().new_divide (a.get_type (), a, b);
}
inline rvalue operator% (rvalue a, rvalue b)
{
  return a.get_context ().new_modulo (a.get_type (), a, b);
}
inline rvalue operator& (rvalue a, rvalue b)
{
  return a.get_context ().new_bitwise_and (a.get_type (), a, b);
}
inline rvalue operator^ (rvalue a, rvalue b)
{
  return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
}
inline rvalue operator| (rvalue a, rvalue b)
{
  return a.get_context ().new_bitwise_or (a.get_type (), a, b);
}
inline rvalue operator&& (rvalue a, rvalue b)
{
  return a.get_context ().new_logical_and (a.get_type (), a, b);
}
inline rvalue operator|| (rvalue a, rvalue b)
{
  return a.get_context ().new_logical_or (a.get_type (), a, b);
}

/* Comparisons.  */
inline rvalue operator== (rvalue a, rvalue b)
{
  return a.get_context ().new_eq (a, b);
}
inline rvalue operator!= (rvalue a, rvalue b)
{
  return a.get_context ().new_ne (a, b);
}
inline rvalue operator< (rvalue a, rvalue b)
{
  return a.get_context ().new_lt (a, b);
}
inline rvalue operator<= (rvalue a, rvalue b)
{
  return a.get_context ().new_le (a, b);
}
inline rvalue operator> (rvalue a, rvalue b)
{
  return a.get_context ().new_gt (a, b);
}
inline rvalue operator>= (rvalue a, rvalue b)
{
  return a.get_context ().new_ge (a, b);
}

/* Dereferencing. */
inline lvalue operator* (rvalue ptr)
{
  return ptr.dereference ();
}

// class timer
inline
timer::timer ()
{
  m_inner_timer = gcc_jit_timer_new ();
}

inline
timer::timer (gcc_jit_timer *inner_timer)
{
  m_inner_timer = inner_timer;
}

inline void
timer::push (const char *item_name)
{
  gcc_jit_timer_push (m_inner_timer, item_name);

}

inline void
timer::pop (const char *item_name)
{
  gcc_jit_timer_pop (m_inner_timer, item_name);
}

inline void
timer::print (FILE *f_out) const
{
  gcc_jit_timer_print (m_inner_timer, f_out);
}

inline gcc_jit_timer *
timer::get_inner_timer () const
{
  return m_inner_timer;
}

inline void
timer::release ()
{
  gcc_jit_timer_release (m_inner_timer);
  m_inner_timer = NULL;
}

// class auto_time

inline
auto_time::auto_time (timer t, const char *item_name)
  : m_timer (t),
    m_item_name (item_name)
{
  t.push (item_name);
}

inline
auto_time::auto_time (context ctxt, const char *item_name)
  : m_timer (ctxt.get_timer ()),
    m_item_name (item_name)
{
  m_timer.push (item_name);
}

inline
auto_time::~auto_time ()
{
  m_timer.pop (m_item_name);
}

namespace version
{
inline int
major_v ()
{
  return gcc_jit_version_major ();
}

inline int
minor_v ()
{
  return gcc_jit_version_minor ();
}

inline int
patchlevel_v ()
{
  return gcc_jit_version_patchlevel ();
}
} // namespace version
} // namespace gccjit

#endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */
