/* A C++ API for libgccjit, purely as inline wrapper functions.
   Copyright (C) 2014-2025 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;

    rvalue new_struct_ctor (type type_,
			    std::vector<field> &fields,
			    std::vector<rvalue> &values,
			    location loc = location ());

    rvalue new_array_ctor (type type_,
			   std::vector<rvalue> &values,
			   location loc = location ());

    rvalue new_union_ctor (type type_,
			   field field,
			   rvalue value,
			   location loc = location ());

    /* 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);
    type get_restrict ();

    // 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);
    lvalue set_initializer_rvalue (rvalue init_value);
  };

  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.data ();

  /* 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.data ();

  /* 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.data ();

  /* 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.data ();

  /* 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_restrict ()
{
  return type (gcc_jit_type_get_restrict (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.data ();

  /* 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.data ();

  /* 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;
}

inline lvalue
lvalue::set_initializer_rvalue (rvalue init_value)
{
  return lvalue (gcc_jit_global_set_initializer_rvalue (
		   get_inner_lvalue (),
		   init_value.get_inner_rvalue ()));
}

inline rvalue
context::new_struct_ctor (type type_,
			  std::vector<field> &fields,
			  std::vector<rvalue> &values,
			  location loc)
{
  field *pfields = nullptr;
  if (fields.size ())
    pfields = fields.data ();

  gcc_jit_field **fields_arr =
    reinterpret_cast<gcc_jit_field **> (pfields);

  rvalue *pvalues = nullptr;
  if (values.size ())
    pvalues = values.data ();

  gcc_jit_rvalue **values_arr =
    reinterpret_cast<gcc_jit_rvalue **> (pvalues);

  return rvalue (
	   gcc_jit_context_new_struct_constructor (
	     m_inner_ctxt,
	     loc.get_inner_location (),
	     type_.get_inner_type (),
	     (int)values.size (),
	     fields_arr,
	     values_arr));
}

inline rvalue
context::new_array_ctor (type type_,
			 std::vector<rvalue> &values,
			 location loc)
{
  rvalue *pvalues = nullptr;
  if (values.size ())
    pvalues = values.data ();

  gcc_jit_rvalue **values_arr =
    reinterpret_cast<gcc_jit_rvalue **> (pvalues);

  return rvalue (
	   gcc_jit_context_new_array_constructor (
	     m_inner_ctxt,
	     loc.get_inner_location (),
	     type_.get_inner_type (),
	     (int)values.size (),
	     values_arr));
}

inline rvalue
context::new_union_ctor (type type_,
			 field field,
			 rvalue value,
			 location loc)
{
  return rvalue (
	   gcc_jit_context_new_union_constructor (
	     m_inner_ctxt,
	     loc.get_inner_location (),
	     type_.get_inner_type (),
	     field.get_inner_field (),
	     value.get_inner_rvalue ()));
}


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