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

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

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[0];

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

  rvalue *pvalues = nullptr;
  if (values.size ())
    pvalues = &values[0];

  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[0];

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