1/* A C++ API for libgccjit, purely as inline wrapper functions.
2   Copyright (C) 2014-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3.  If not see
18<http://www.gnu.org/licenses/>.  */
19
20#ifndef LIBGCCJIT_PLUS_PLUS_H
21#define LIBGCCJIT_PLUS_PLUS_H
22
23#include "libgccjit.h"
24
25#include <limits>
26#include <ostream>
27#include <vector>
28
29/****************************************************************************
30 C++ API
31 ****************************************************************************/
32
33namespace gccjit
34{
35  /* Indentation indicates inheritance.  */
36  class context;
37  class error;
38  class object;
39    class location;
40    class field;
41    class type;
42      class struct_;
43    class function;
44    class block;
45    class rvalue;
46     class lvalue;
47       class param;
48    class case_;
49
50  /* Errors within the API become C++ exceptions of this class.  */
51  class error
52  {
53  };
54
55  class object
56  {
57  public:
58    context get_context () const;
59
60    std::string get_debug_string () const;
61
62  protected:
63    object ();
64    object (gcc_jit_object *obj);
65
66    gcc_jit_object *get_inner_object () const;
67
68  private:
69    gcc_jit_object *m_inner_obj;
70  };
71
72  inline std::ostream& operator << (std::ostream& stream, const object &obj);
73
74  /* Some client code will want to supply source code locations, others
75     won't.  To avoid doubling the number of entrypoints, everything
76     accepting a location also has a default argument.  To do this, the
77     other classes need to see that "location" has a default constructor,
78     hence we need to declare it first.  */
79  class location : public object
80  {
81  public:
82    location ();
83    location (gcc_jit_location *loc);
84
85    gcc_jit_location *get_inner_location () const;
86  };
87
88  class context
89  {
90  public:
91    static context acquire ();
92    context ();
93    context (gcc_jit_context *ctxt);
94
95    gccjit::context new_child_context ();
96
97    gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
98
99    void release ();
100
101    gcc_jit_result *compile ();
102
103    void compile_to_file (enum gcc_jit_output_kind output_kind,
104			  const char *output_path);
105
106    void dump_to_file (const std::string &path,
107		       bool update_locations);
108
109    void set_logfile (FILE *logfile,
110		      int flags,
111		      int verbosity);
112
113    void dump_reproducer_to_file (const char *path);
114
115    void set_str_option (enum gcc_jit_str_option opt,
116			 const char *value);
117
118    void set_int_option (enum gcc_jit_int_option opt,
119			 int value);
120
121    void set_bool_option (enum gcc_jit_bool_option opt,
122			  int value);
123
124    void set_bool_allow_unreachable_blocks (int bool_value);
125
126    void add_command_line_option (const char *optname);
127
128    location
129    new_location (const std::string &filename,
130		  int line,
131		  int column);
132
133    type get_type (enum gcc_jit_types kind);
134    type get_int_type (size_t num_bytes, int is_signed);
135
136    /* A way to map a specific int type, using the compiler to
137       get the details automatically e.g.:
138	  gccjit::type type = get_int_type <my_int_type_t> ();  */
139    template <typename T>
140    type get_int_type ();
141
142    type new_array_type (type element_type, int num_elements,
143			 location loc = location ());
144
145    field new_field (type type_, const std::string &name,
146		     location loc = location ());
147
148    struct_ new_struct_type (const std::string &name,
149			     std::vector<field> &fields,
150			     location loc = location ());
151
152    struct_ new_opaque_struct_type (const std::string &name,
153				    location loc = location ());
154
155    param new_param (type type_,
156		     const std::string &name,
157		     location loc = location ());
158
159    function new_function (enum gcc_jit_function_kind kind,
160			   type return_type,
161			   const std::string &name,
162			   std::vector<param> &params,
163			   int is_variadic,
164			   location loc = location ());
165
166    function get_builtin_function (const std::string &name);
167
168    lvalue new_global (enum gcc_jit_global_kind kind,
169		       type type_,
170		       const std::string &name,
171		       location loc = location ());
172
173    rvalue new_rvalue (type numeric_type,
174		       int value) const;
175    rvalue new_rvalue (type numeric_type,
176		       long value) const;
177    rvalue zero (type numeric_type) const;
178    rvalue one (type numeric_type) const;
179    rvalue new_rvalue (type numeric_type,
180		       double value) const;
181    rvalue new_rvalue (type pointer_type,
182		       void *value) const;
183    rvalue new_rvalue (const std::string &value) const;
184
185    /* Generic unary operations...  */
186    rvalue new_unary_op (enum gcc_jit_unary_op op,
187			 type result_type,
188			 rvalue a,
189			 location loc = location ());
190
191    /* ...and shorter ways to spell the various specific kinds of
192       unary op.  */
193    rvalue new_minus (type result_type,
194		      rvalue a,
195		      location loc = location ());
196    rvalue new_bitwise_negate (type result_type,
197			       rvalue a,
198			       location loc = location ());
199    rvalue new_logical_negate (type result_type,
200			       rvalue a,
201			       location loc = location ());
202
203    /* Generic binary operations...  */
204    rvalue new_binary_op (enum gcc_jit_binary_op op,
205			  type result_type,
206			  rvalue a, rvalue b,
207			  location loc = location ());
208
209    /* ...and shorter ways to spell the various specific kinds of
210       binary op.  */
211    rvalue new_plus (type result_type,
212		     rvalue a, rvalue b,
213		     location loc = location ());
214    rvalue new_minus (type result_type,
215		      rvalue a, rvalue b,
216		      location loc = location ());
217    rvalue new_mult (type result_type,
218		     rvalue a, rvalue b,
219		     location loc = location ());
220    rvalue new_divide (type result_type,
221		       rvalue a, rvalue b,
222		       location loc = location ());
223    rvalue new_modulo (type result_type,
224		       rvalue a, rvalue b,
225		       location loc = location ());
226    rvalue new_bitwise_and (type result_type,
227			    rvalue a, rvalue b,
228			    location loc = location ());
229    rvalue new_bitwise_xor (type result_type,
230			    rvalue a, rvalue b,
231			    location loc = location ());
232    rvalue new_bitwise_or (type result_type,
233			   rvalue a, rvalue b,
234			   location loc = location ());
235    rvalue new_logical_and (type result_type,
236			    rvalue a, rvalue b,
237			    location loc = location ());
238    rvalue new_logical_or (type result_type,
239			   rvalue a, rvalue b,
240			   location loc = location ());
241
242    /* Generic comparisons...  */
243    rvalue new_comparison (enum gcc_jit_comparison op,
244			   rvalue a, rvalue b,
245			   location loc = location ());
246    /* ...and shorter ways to spell the various specific kinds of
247       comparison.  */
248    rvalue new_eq (rvalue a, rvalue b,
249		   location loc = location ());
250    rvalue new_ne (rvalue a, rvalue b,
251		   location loc = location ());
252    rvalue new_lt (rvalue a, rvalue b,
253		   location loc = location ());
254    rvalue new_le (rvalue a, rvalue b,
255		   location loc = location ());
256    rvalue new_gt (rvalue a, rvalue b,
257		   location loc = location ());
258    rvalue new_ge (rvalue a, rvalue b,
259		   location loc = location ());
260
261    /* The most general way of creating a function call.  */
262    rvalue new_call (function func,
263		     std::vector<rvalue> &args,
264		     location loc = location ());
265
266    /* In addition, we provide a series of overloaded "new_call" methods
267       for specific numbers of args (from 0 - 6), to avoid the need for
268       client code to manually build a vector.  */
269    rvalue new_call (function func,
270		     location loc = location ());
271    rvalue new_call (function func,
272		     rvalue arg0,
273		     location loc = location ());
274    rvalue new_call (function func,
275		     rvalue arg0, rvalue arg1,
276		     location loc = location ());
277    rvalue new_call (function func,
278		     rvalue arg0, rvalue arg1, rvalue arg2,
279		     location loc = location ());
280    rvalue new_call (function func,
281		     rvalue arg0, rvalue arg1, rvalue arg2,
282		     rvalue arg3,
283		     location loc = location ());
284    rvalue new_call (function func,
285		     rvalue arg0, rvalue arg1, rvalue arg2,
286		     rvalue arg3, rvalue arg4,
287		     location loc = location ());
288    rvalue new_call (function func,
289		     rvalue arg0, rvalue arg1, rvalue arg2,
290		     rvalue arg3, rvalue arg4, rvalue arg5,
291		     location loc = location ());
292
293    rvalue new_cast (rvalue expr,
294		     type type_,
295		     location loc = location ());
296
297    lvalue new_array_access (rvalue ptr,
298			     rvalue index,
299			     location loc = location ());
300
301    case_ new_case (rvalue min_value,
302		    rvalue max_value,
303		    block dest_block);
304
305  private:
306    gcc_jit_context *m_inner_ctxt;
307  };
308
309  class field : public object
310  {
311  public:
312    field ();
313    field (gcc_jit_field *inner);
314
315    gcc_jit_field *get_inner_field () const;
316  };
317
318  class type : public object
319  {
320  public:
321    type ();
322    type (gcc_jit_type *inner);
323
324    gcc_jit_type *get_inner_type () const;
325
326    type get_pointer ();
327    type get_volatile ();
328
329    // Shortcuts for getting values of numeric types:
330    rvalue zero ();
331    rvalue one ();
332 };
333
334  class struct_ : public type
335  {
336  public:
337    struct_ ();
338    struct_ (gcc_jit_struct *inner);
339
340    gcc_jit_struct *get_inner_struct () const;
341  };
342
343  class function : public object
344  {
345  public:
346    function ();
347    function (gcc_jit_function *func);
348
349    gcc_jit_function *get_inner_function () const;
350
351    void dump_to_dot (const std::string &path);
352
353    param get_param (int index) const;
354
355    block new_block ();
356    block new_block (const std::string &name);
357
358    lvalue new_local (type type_,
359		      const std::string &name,
360		      location loc = location ());
361
362    /* A series of overloaded operator () with various numbers of arguments
363       for a very terse way of creating a call to this function.  The call
364       is created within the same context as the function itself, which may
365       not be what you want.  */
366    rvalue operator() (location loc = location ());
367    rvalue operator() (rvalue arg0,
368		       location loc = location ());
369    rvalue operator() (rvalue arg0, rvalue arg1,
370		       location loc = location ());
371    rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
372		       location loc = location ());
373  };
374
375  class block : public object
376  {
377  public:
378    block ();
379    block (gcc_jit_block *inner);
380
381    gcc_jit_block *get_inner_block () const;
382
383    function get_function () const;
384
385    void add_eval (rvalue rvalue,
386		   location loc = location ());
387
388    void add_assignment (lvalue lvalue,
389			 rvalue rvalue,
390			 location loc = location ());
391
392    void add_assignment_op (lvalue lvalue,
393			    enum gcc_jit_binary_op op,
394			    rvalue rvalue,
395			    location loc = location ());
396
397    /* A way to add a function call to the body of a function being
398       defined, with various numbers of args.  */
399    rvalue add_call (function other,
400		     location loc = location ());
401    rvalue add_call (function other,
402		     rvalue arg0,
403		     location loc = location ());
404    rvalue add_call (function other,
405		     rvalue arg0, rvalue arg1,
406		     location loc = location ());
407    rvalue add_call (function other,
408		     rvalue arg0, rvalue arg1, rvalue arg2,
409		     location loc = location ());
410    rvalue add_call (function other,
411		     rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
412		     location loc = location ());
413
414    void add_comment (const std::string &text,
415		      location loc = location ());
416
417    void end_with_conditional (rvalue boolval,
418			       block on_true,
419			       block on_false,
420			       location loc = location ());
421
422    void end_with_jump (block target,
423			location loc = location ());
424
425    void end_with_return (rvalue rvalue,
426			  location loc = location ());
427    void end_with_return (location loc = location ());
428
429    void end_with_switch (rvalue expr,
430			  block default_block,
431			  std::vector <case_> cases,
432			  location loc = location ());
433  };
434
435  class rvalue : public object
436  {
437  public:
438    rvalue ();
439    rvalue (gcc_jit_rvalue *inner);
440    gcc_jit_rvalue *get_inner_rvalue () const;
441
442    type get_type ();
443
444    rvalue access_field (field field,
445			 location loc = location ());
446
447    lvalue dereference_field (field field,
448			      location loc = location ());
449
450    lvalue dereference (location loc = location ());
451
452    rvalue cast_to (type type_,
453		    location loc = location ());
454
455    /* Array access.  */
456    lvalue operator[] (rvalue index);
457    lvalue operator[] (int index);
458  };
459
460  class lvalue : public rvalue
461  {
462  public:
463    lvalue ();
464    lvalue (gcc_jit_lvalue *inner);
465
466    gcc_jit_lvalue *get_inner_lvalue () const;
467
468    lvalue access_field (field field,
469			 location loc = location ());
470
471    rvalue get_address (location loc = location ());
472  };
473
474  class param : public lvalue
475  {
476  public:
477    param ();
478    param (gcc_jit_param *inner);
479
480    gcc_jit_param *get_inner_param () const;
481  };
482
483  class case_ : public object
484  {
485  public:
486    case_ ();
487    case_ (gcc_jit_case *inner);
488
489    gcc_jit_case *get_inner_case () const;
490  };
491
492  /* Overloaded operators, for those who want the most terse API
493     (at the possible risk of being a little too magical).
494
495     In each case, the first parameter is used to determine which context
496     owns the resulting expression, and, where appropriate,  what the
497     latter's type is. */
498
499  /* Unary operators.  */
500  rvalue operator- (rvalue a); // unary minus
501  rvalue operator~ (rvalue a); // unary bitwise negate
502  rvalue operator! (rvalue a); // unary logical negate
503
504  /* Binary operators.  */
505  rvalue operator+ (rvalue a, rvalue b);
506  rvalue operator- (rvalue a, rvalue b);
507  rvalue operator* (rvalue a, rvalue b);
508  rvalue operator/ (rvalue a, rvalue b);
509  rvalue operator% (rvalue a, rvalue b);
510  rvalue operator& (rvalue a, rvalue b); //  bitwise and
511  rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
512  rvalue operator| (rvalue a, rvalue b); // bitwise_or
513  rvalue operator&& (rvalue a, rvalue b); // logical_and
514  rvalue operator|| (rvalue a, rvalue b); // logical_or
515
516  /* Comparisons.  */
517  rvalue operator== (rvalue a, rvalue b);
518  rvalue operator!= (rvalue a, rvalue b);
519  rvalue operator< (rvalue a, rvalue b);
520  rvalue operator<= (rvalue a, rvalue b);
521  rvalue operator> (rvalue a, rvalue b);
522  rvalue operator>= (rvalue a, rvalue b);
523
524  /* Dereferencing. */
525  lvalue operator* (rvalue ptr);
526}
527
528/****************************************************************************
529 Implementation of the API
530 ****************************************************************************/
531namespace gccjit {
532
533// class context
534inline context context::acquire ()
535{
536  return context (gcc_jit_context_acquire ());
537}
538inline context::context () : m_inner_ctxt (NULL) {}
539inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
540{
541  if (!inner)
542    throw error ();
543}
544
545inline gccjit::context
546context::new_child_context ()
547{
548  return context (gcc_jit_context_new_child_context (m_inner_ctxt));
549}
550
551inline void
552context::release ()
553{
554  gcc_jit_context_release (m_inner_ctxt);
555  m_inner_ctxt = NULL;
556}
557
558inline gcc_jit_result *
559context::compile ()
560{
561  gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
562  if (!result)
563    throw error ();
564  return result;
565}
566
567inline void
568context::compile_to_file (enum gcc_jit_output_kind output_kind,
569			  const char *output_path)
570{
571  gcc_jit_context_compile_to_file (m_inner_ctxt,
572				   output_kind,
573				   output_path);
574}
575
576inline void
577context::dump_to_file (const std::string &path,
578		       bool update_locations)
579{
580  gcc_jit_context_dump_to_file (m_inner_ctxt,
581				path.c_str (),
582				update_locations);
583}
584
585inline void
586context::set_logfile (FILE *logfile,
587		      int flags,
588		      int verbosity)
589{
590  gcc_jit_context_set_logfile (m_inner_ctxt,
591			       logfile,
592			       flags,
593			       verbosity);
594}
595
596inline void
597context::dump_reproducer_to_file (const char *path)
598{
599  gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
600					   path);
601}
602
603inline void
604context::set_str_option (enum gcc_jit_str_option opt,
605			 const char *value)
606{
607  gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
608
609}
610
611inline void
612context::set_int_option (enum gcc_jit_int_option opt,
613			 int value)
614{
615  gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
616
617}
618
619inline void
620context::set_bool_option (enum gcc_jit_bool_option opt,
621			  int value)
622{
623  gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
624}
625
626inline void
627context::set_bool_allow_unreachable_blocks (int bool_value)
628{
629  gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
630						     bool_value);
631}
632
633inline void
634context::add_command_line_option (const char *optname)
635{
636  gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
637}
638
639inline location
640context::new_location (const std::string &filename,
641		       int line,
642		       int column)
643{
644  return location (gcc_jit_context_new_location (m_inner_ctxt,
645						 filename.c_str (),
646						 line,
647						 column));
648}
649
650inline type
651context::get_type (enum gcc_jit_types kind)
652{
653  return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
654}
655
656inline type
657context::get_int_type (size_t num_bytes, int is_signed)
658{
659  return type (gcc_jit_context_get_int_type (m_inner_ctxt,
660					     num_bytes,
661					     is_signed));
662}
663
664template <typename T>
665inline type
666context::get_int_type ()
667{
668  return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
669}
670
671inline type
672context::new_array_type (type element_type, int num_elements, location loc)
673{
674  return type (gcc_jit_context_new_array_type (
675		 m_inner_ctxt,
676		 loc.get_inner_location (),
677		 element_type.get_inner_type (),
678		 num_elements));
679}
680
681inline field
682context::new_field (type type_, const std::string &name, location loc)
683{
684  return field (gcc_jit_context_new_field (m_inner_ctxt,
685					   loc.get_inner_location (),
686					   type_.get_inner_type (),
687					   name.c_str ()));
688}
689
690inline struct_
691context::new_struct_type (const std::string &name,
692			  std::vector<field> &fields,
693			  location loc)
694{
695  /* Treat std::vector as an array, relying on it not being resized: */
696  field *as_array_of_wrappers = &fields[0];
697
698  /* Treat the array as being of the underlying pointers, relying on
699     the wrapper type being such a pointer internally.	*/
700  gcc_jit_field **as_array_of_ptrs =
701    reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
702
703  return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
704						   loc.get_inner_location (),
705						   name.c_str (),
706						   fields.size (),
707						   as_array_of_ptrs));
708}
709
710inline struct_
711context::new_opaque_struct_type (const std::string &name,
712				 location loc)
713{
714  return struct_ (gcc_jit_context_new_opaque_struct (
715		    m_inner_ctxt,
716		    loc.get_inner_location (),
717		    name.c_str ()));
718}
719
720inline param
721context::new_param (type type_,
722		    const std::string &name,
723		    location loc)
724{
725  return param (gcc_jit_context_new_param (m_inner_ctxt,
726					   loc.get_inner_location (),
727					   type_.get_inner_type (),
728					   name.c_str ()));
729}
730
731inline function
732context::new_function (enum gcc_jit_function_kind kind,
733		       type return_type,
734		       const std::string &name,
735		       std::vector<param> &params,
736		       int is_variadic,
737		       location loc)
738{
739  /* Treat std::vector as an array, relying on it not being resized: */
740  param *as_array_of_wrappers = &params[0];
741
742  /* Treat the array as being of the underlying pointers, relying on
743     the wrapper type being such a pointer internally.	*/
744  gcc_jit_param **as_array_of_ptrs =
745    reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
746
747  return function (gcc_jit_context_new_function (m_inner_ctxt,
748						 loc.get_inner_location (),
749						 kind,
750						 return_type.get_inner_type (),
751						 name.c_str (),
752						 params.size (),
753						 as_array_of_ptrs,
754						 is_variadic));
755}
756
757inline function
758context::get_builtin_function (const std::string &name)
759{
760  return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
761							 name.c_str ()));
762}
763
764inline lvalue
765context::new_global (enum gcc_jit_global_kind kind,
766		     type type_,
767		     const std::string &name,
768		     location loc)
769{
770  return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
771					     loc.get_inner_location (),
772					     kind,
773					     type_.get_inner_type (),
774					     name.c_str ()));
775}
776
777inline rvalue
778context::new_rvalue (type numeric_type,
779		     int value) const
780{
781  return rvalue (
782    gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
783					 numeric_type.get_inner_type (),
784					 value));
785}
786
787inline rvalue
788context::new_rvalue (type numeric_type,
789		     long value) const
790{
791  return rvalue (
792    gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
793					  numeric_type.get_inner_type (),
794					  value));
795}
796
797inline rvalue
798context::zero (type numeric_type) const
799{
800  return rvalue (gcc_jit_context_zero (m_inner_ctxt,
801				       numeric_type.get_inner_type ()));
802}
803
804inline rvalue
805context::one (type numeric_type) const
806{
807  return rvalue (gcc_jit_context_one (m_inner_ctxt,
808				       numeric_type.get_inner_type ()));
809}
810
811inline rvalue
812context::new_rvalue (type numeric_type,
813		     double value) const
814{
815  return rvalue (
816    gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
817					    numeric_type.get_inner_type (),
818					    value));
819}
820
821inline rvalue
822context::new_rvalue (type pointer_type,
823		     void *value) const
824{
825  return rvalue (
826    gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
827					 pointer_type.get_inner_type (),
828					 value));
829}
830
831inline rvalue
832context::new_rvalue (const std::string &value) const
833{
834  return rvalue (
835    gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
836}
837
838inline rvalue
839context::new_unary_op (enum gcc_jit_unary_op op,
840		       type result_type,
841		       rvalue a,
842		       location loc)
843{
844  return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
845					       loc.get_inner_location (),
846					       op,
847					       result_type.get_inner_type (),
848					       a.get_inner_rvalue ()));
849}
850inline rvalue
851context::new_minus (type result_type,
852		    rvalue a,
853		    location loc)
854{
855  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
856			       result_type, a, loc));
857}
858inline rvalue
859context::new_bitwise_negate (type result_type,
860			     rvalue a,
861			     location loc)
862{
863  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
864			       result_type, a, loc));
865}
866inline rvalue
867context::new_logical_negate (type result_type,
868			     rvalue a,
869			     location loc)
870{
871  return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
872			       result_type, a, loc));
873}
874
875inline rvalue
876context::new_binary_op (enum gcc_jit_binary_op op,
877			type result_type,
878			rvalue a, rvalue b,
879			location loc)
880{
881  return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
882						loc.get_inner_location (),
883						op,
884						result_type.get_inner_type (),
885						a.get_inner_rvalue (),
886						b.get_inner_rvalue ()));
887}
888inline rvalue
889context::new_plus (type result_type,
890		   rvalue a, rvalue b,
891		   location loc)
892{
893  return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
894			result_type, a, b, loc);
895}
896inline rvalue
897context::new_minus (type result_type,
898		    rvalue a, rvalue b,
899		    location loc)
900{
901  return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
902			result_type, a, b, loc);
903}
904inline rvalue
905context::new_mult (type result_type,
906		   rvalue a, rvalue b,
907		   location loc)
908{
909  return new_binary_op (GCC_JIT_BINARY_OP_MULT,
910			result_type, a, b, loc);
911}
912inline rvalue
913context::new_divide (type result_type,
914		     rvalue a, rvalue b,
915		     location loc)
916{
917  return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
918			result_type, a, b, loc);
919}
920inline rvalue
921context::new_modulo (type result_type,
922		     rvalue a, rvalue b,
923		     location loc)
924{
925  return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
926			result_type, a, b, loc);
927}
928inline rvalue
929context::new_bitwise_and (type result_type,
930			  rvalue a, rvalue b,
931			  location loc)
932{
933  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
934			result_type, a, b, loc);
935}
936inline rvalue
937context::new_bitwise_xor (type result_type,
938			  rvalue a, rvalue b,
939			  location loc)
940{
941  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
942			result_type, a, b, loc);
943}
944inline rvalue
945context::new_bitwise_or (type result_type,
946			 rvalue a, rvalue b,
947			 location loc)
948{
949  return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
950			result_type, a, b, loc);
951}
952inline rvalue
953context::new_logical_and (type result_type,
954			  rvalue a, rvalue b,
955			  location loc)
956{
957  return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
958			result_type, a, b, loc);
959}
960inline rvalue
961context::new_logical_or (type result_type,
962			 rvalue a, rvalue b,
963			 location loc)
964{
965  return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
966			result_type, a, b, loc);
967}
968
969inline rvalue
970context::new_comparison (enum gcc_jit_comparison op,
971			 rvalue a, rvalue b,
972			 location loc)
973{
974  return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
975						 loc.get_inner_location (),
976						 op,
977						 a.get_inner_rvalue (),
978						 b.get_inner_rvalue ()));
979}
980inline rvalue
981context::new_eq (rvalue a, rvalue b,
982		 location loc)
983{
984  return new_comparison (GCC_JIT_COMPARISON_EQ,
985			 a, b, loc);
986}
987inline rvalue
988context::new_ne (rvalue a, rvalue b,
989		 location loc)
990{
991  return new_comparison (GCC_JIT_COMPARISON_NE,
992			 a, b, loc);
993}
994inline rvalue
995context::new_lt (rvalue a, rvalue b,
996		 location loc)
997{
998  return new_comparison (GCC_JIT_COMPARISON_LT,
999			 a, b, loc);
1000}
1001inline rvalue
1002context::new_le (rvalue a, rvalue b,
1003		 location loc)
1004{
1005  return new_comparison (GCC_JIT_COMPARISON_LE,
1006			 a, b, loc);
1007}
1008inline rvalue
1009context::new_gt (rvalue a, rvalue b,
1010		 location loc)
1011{
1012  return new_comparison (GCC_JIT_COMPARISON_GT,
1013			 a, b, loc);
1014}
1015inline rvalue
1016context::new_ge (rvalue a, rvalue b,
1017		 location loc)
1018{
1019  return new_comparison (GCC_JIT_COMPARISON_GE,
1020			 a, b, loc);
1021}
1022
1023inline rvalue
1024context::new_call (function func,
1025		   std::vector<rvalue> &args,
1026		   location loc)
1027{
1028  /* Treat std::vector as an array, relying on it not being resized: */
1029  rvalue *as_array_of_wrappers = &args[0];
1030
1031  /* Treat the array as being of the underlying pointers, relying on
1032     the wrapper type being such a pointer internally.	*/
1033  gcc_jit_rvalue **as_array_of_ptrs =
1034    reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
1035  return gcc_jit_context_new_call (m_inner_ctxt,
1036				   loc.get_inner_location (),
1037				   func.get_inner_function (),
1038				   args.size (),
1039				   as_array_of_ptrs);
1040}
1041inline rvalue
1042context::new_call (function func,
1043		   location loc)
1044{
1045  std::vector<rvalue> args;
1046  return new_call (func, args, loc);
1047}
1048
1049inline rvalue
1050context::new_call (function func,
1051		   rvalue arg0,
1052		   location loc)
1053{
1054  std::vector<rvalue> args(1);
1055  args[0] = arg0;
1056  return new_call (func, args, loc);
1057}
1058inline rvalue
1059context::new_call (function func,
1060		   rvalue arg0, rvalue arg1,
1061		   location loc)
1062{
1063  std::vector<rvalue> args(2);
1064  args[0] = arg0;
1065  args[1] = arg1;
1066  return new_call (func, args, loc);
1067}
1068inline rvalue
1069context::new_call (function func,
1070		   rvalue arg0, rvalue arg1, rvalue arg2,
1071		   location loc)
1072{
1073  std::vector<rvalue> args(3);
1074  args[0] = arg0;
1075  args[1] = arg1;
1076  args[2] = arg2;
1077  return new_call (func, args, loc);
1078}
1079inline rvalue
1080context::new_call (function func,
1081		   rvalue arg0, rvalue arg1, rvalue arg2,
1082		   rvalue arg3,
1083		   location loc)
1084{
1085  std::vector<rvalue> args(4);
1086  args[0] = arg0;
1087  args[1] = arg1;
1088  args[2] = arg2;
1089  args[3] = arg3;
1090  return new_call (func, args, loc);
1091}
1092inline rvalue
1093context::new_call (function func,
1094		   rvalue arg0, rvalue arg1, rvalue arg2,
1095		   rvalue arg3, rvalue arg4,
1096		   location loc)
1097{
1098  std::vector<rvalue> args(5);
1099  args[0] = arg0;
1100  args[1] = arg1;
1101  args[2] = arg2;
1102  args[3] = arg3;
1103  args[4] = arg4;
1104  return new_call (func, args, loc);
1105}
1106inline rvalue
1107context::new_call (function func,
1108		   rvalue arg0, rvalue arg1, rvalue arg2,
1109		   rvalue arg3, rvalue arg4, rvalue arg5,
1110		   location loc)
1111{
1112  std::vector<rvalue> args(6);
1113  args[0] = arg0;
1114  args[1] = arg1;
1115  args[2] = arg2;
1116  args[3] = arg3;
1117  args[4] = arg4;
1118  args[5] = arg5;
1119  return new_call (func, args, loc);
1120}
1121
1122inline rvalue
1123context::new_cast (rvalue expr,
1124		   type type_,
1125		   location loc)
1126{
1127  return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1128					   loc.get_inner_location (),
1129					   expr.get_inner_rvalue (),
1130					   type_.get_inner_type ()));
1131}
1132
1133inline lvalue
1134context::new_array_access (rvalue ptr,
1135			   rvalue index,
1136			   location loc)
1137{
1138  return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1139						   loc.get_inner_location (),
1140						   ptr.get_inner_rvalue (),
1141						   index.get_inner_rvalue ()));
1142}
1143
1144inline case_
1145context::new_case (rvalue min_value,
1146		   rvalue max_value,
1147		   block dest_block)
1148{
1149  return case_ (gcc_jit_context_new_case (m_inner_ctxt,
1150					  min_value.get_inner_rvalue (),
1151					  max_value.get_inner_rvalue (),
1152					  dest_block.get_inner_block ()));
1153}
1154
1155// class object
1156inline context
1157object::get_context () const
1158{
1159  return context (gcc_jit_object_get_context (m_inner_obj));
1160}
1161
1162inline std::string
1163object::get_debug_string () const
1164{
1165  return gcc_jit_object_get_debug_string (m_inner_obj);
1166}
1167
1168inline object::object () : m_inner_obj (NULL) {}
1169inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1170{
1171  if (!obj)
1172    throw error ();
1173}
1174
1175inline gcc_jit_object *
1176object::get_inner_object () const
1177{
1178  return m_inner_obj;
1179}
1180
1181inline std::ostream&
1182operator << (std::ostream& stream, const object &obj)
1183{
1184  return stream << obj.get_debug_string ();
1185}
1186
1187// class location
1188inline location::location () : object () {}
1189inline location::location (gcc_jit_location *loc)
1190  : object (gcc_jit_location_as_object (loc))
1191{}
1192
1193inline gcc_jit_location *
1194location::get_inner_location () const
1195{
1196  /* Manual downcast: */
1197  return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1198}
1199
1200// class field
1201inline field::field () : object () {}
1202inline field::field (gcc_jit_field *inner)
1203  : object (gcc_jit_field_as_object (inner))
1204{}
1205
1206inline gcc_jit_field *
1207field::get_inner_field () const
1208{
1209  /* Manual downcast: */
1210  return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1211}
1212
1213// class type
1214inline type::type () : object () {}
1215inline type::type (gcc_jit_type *inner)
1216  : object (gcc_jit_type_as_object (inner))
1217{}
1218
1219inline gcc_jit_type *
1220type::get_inner_type () const
1221{
1222  /* Manual downcast: */
1223  return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1224}
1225
1226inline type
1227type::get_pointer ()
1228{
1229  return type (gcc_jit_type_get_pointer (get_inner_type ()));
1230}
1231
1232inline type
1233type::get_volatile ()
1234{
1235  return type (gcc_jit_type_get_volatile (get_inner_type ()));
1236}
1237
1238inline rvalue
1239type::zero ()
1240{
1241  return get_context ().new_rvalue (*this, 0);
1242}
1243
1244inline rvalue
1245type::one ()
1246{
1247  return get_context ().new_rvalue (*this, 1);
1248}
1249
1250// class struct_
1251inline struct_::struct_ () : type (NULL) {}
1252inline struct_::struct_ (gcc_jit_struct *inner) :
1253  type (gcc_jit_struct_as_type (inner))
1254{
1255}
1256
1257inline gcc_jit_struct *
1258struct_::get_inner_struct () const
1259{
1260  /* Manual downcast: */
1261  return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1262}
1263
1264// class function
1265inline function::function () : object () {}
1266inline function::function (gcc_jit_function *inner)
1267  : object (gcc_jit_function_as_object (inner))
1268{}
1269
1270inline gcc_jit_function *
1271function::get_inner_function () const
1272{
1273  /* Manual downcast: */
1274  return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1275}
1276
1277inline void
1278function::dump_to_dot (const std::string &path)
1279{
1280  gcc_jit_function_dump_to_dot (get_inner_function (),
1281				path.c_str ());
1282}
1283
1284inline param
1285function::get_param (int index) const
1286{
1287  return param (gcc_jit_function_get_param (get_inner_function (),
1288					    index));
1289}
1290
1291inline block
1292function::new_block ()
1293{
1294  return block (gcc_jit_function_new_block (get_inner_function (),
1295					    NULL));
1296}
1297
1298inline block
1299function::new_block (const std::string &name)
1300{
1301  return block (gcc_jit_function_new_block (get_inner_function (),
1302					    name.c_str ()));
1303}
1304
1305inline lvalue
1306function::new_local (type type_,
1307		     const std::string &name,
1308		     location loc)
1309{
1310  return lvalue (gcc_jit_function_new_local (get_inner_function (),
1311					     loc.get_inner_location (),
1312					     type_.get_inner_type (),
1313					     name.c_str ()));
1314}
1315
1316inline function
1317block::get_function () const
1318{
1319  return function (gcc_jit_block_get_function ( get_inner_block ()));
1320}
1321
1322inline void
1323block::add_eval (rvalue rvalue,
1324		 location loc)
1325{
1326  gcc_jit_block_add_eval (get_inner_block (),
1327			  loc.get_inner_location (),
1328			  rvalue.get_inner_rvalue ());
1329}
1330
1331inline void
1332block::add_assignment (lvalue lvalue,
1333		       rvalue rvalue,
1334		       location loc)
1335{
1336  gcc_jit_block_add_assignment (get_inner_block (),
1337				loc.get_inner_location (),
1338				lvalue.get_inner_lvalue (),
1339				rvalue.get_inner_rvalue ());
1340}
1341
1342inline void
1343block::add_assignment_op (lvalue lvalue,
1344			  enum gcc_jit_binary_op op,
1345			  rvalue rvalue,
1346			  location loc)
1347{
1348  gcc_jit_block_add_assignment_op (get_inner_block (),
1349				   loc.get_inner_location (),
1350				   lvalue.get_inner_lvalue (),
1351				   op,
1352				   rvalue.get_inner_rvalue ());
1353}
1354
1355inline void
1356block::add_comment (const std::string &text,
1357		    location loc)
1358{
1359  gcc_jit_block_add_comment (get_inner_block (),
1360			     loc.get_inner_location (),
1361			     text.c_str ());
1362}
1363
1364inline void
1365block::end_with_conditional (rvalue boolval,
1366			     block on_true,
1367			     block on_false,
1368			     location loc)
1369{
1370  gcc_jit_block_end_with_conditional (get_inner_block (),
1371				      loc.get_inner_location (),
1372				      boolval.get_inner_rvalue (),
1373				      on_true.get_inner_block (),
1374				      on_false.get_inner_block ());
1375}
1376
1377inline void
1378block::end_with_jump (block target,
1379		      location loc)
1380{
1381  gcc_jit_block_end_with_jump (get_inner_block (),
1382			       loc.get_inner_location (),
1383			       target.get_inner_block ());
1384}
1385
1386inline void
1387block::end_with_return (rvalue rvalue,
1388			location loc)
1389{
1390  gcc_jit_block_end_with_return (get_inner_block (),
1391				 loc.get_inner_location (),
1392				 rvalue.get_inner_rvalue ());
1393}
1394
1395inline void
1396block::end_with_return (location loc)
1397{
1398  gcc_jit_block_end_with_void_return (get_inner_block (),
1399				      loc.get_inner_location ());
1400}
1401
1402inline void
1403block::end_with_switch (rvalue expr,
1404			block default_block,
1405			std::vector <case_> cases,
1406			location loc)
1407{
1408  /* Treat std::vector as an array, relying on it not being resized: */
1409  case_ *as_array_of_wrappers = &cases[0];
1410
1411  /* Treat the array as being of the underlying pointers, relying on
1412     the wrapper type being such a pointer internally.	*/
1413  gcc_jit_case **as_array_of_ptrs =
1414    reinterpret_cast<gcc_jit_case **> (as_array_of_wrappers);
1415  gcc_jit_block_end_with_switch (get_inner_block (),
1416				 loc.get_inner_location (),
1417				 expr.get_inner_rvalue (),
1418				 default_block.get_inner_block (),
1419				 cases.size (),
1420				 as_array_of_ptrs);
1421}
1422
1423inline rvalue
1424block::add_call (function other,
1425		 location loc)
1426{
1427  rvalue c = get_context ().new_call (other, loc);
1428  add_eval (c);
1429  return c;
1430}
1431inline rvalue
1432block::add_call (function other,
1433		 rvalue arg0,
1434		 location loc)
1435{
1436  rvalue c = get_context ().new_call (other, arg0, loc);
1437  add_eval (c);
1438  return c;
1439}
1440inline rvalue
1441block::add_call (function other,
1442		 rvalue arg0, rvalue arg1,
1443		 location loc)
1444{
1445  rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1446  add_eval (c);
1447  return c;
1448}
1449inline rvalue
1450block::add_call (function other,
1451		 rvalue arg0, rvalue arg1, rvalue arg2,
1452		 location loc)
1453{
1454  rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1455  add_eval (c);
1456  return c;
1457}
1458
1459inline rvalue
1460block::add_call (function other,
1461		 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1462		 location loc)
1463{
1464  rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1465  add_eval (c);
1466  return c;
1467}
1468
1469inline rvalue
1470function::operator() (location loc)
1471{
1472  return get_context ().new_call (*this, loc);
1473}
1474inline rvalue
1475function::operator() (rvalue arg0,
1476		      location loc)
1477{
1478  return get_context ().new_call (*this,
1479				  arg0,
1480				  loc);
1481}
1482inline rvalue
1483function::operator() (rvalue arg0, rvalue arg1,
1484		      location loc)
1485{
1486  return get_context ().new_call (*this,
1487				  arg0, arg1,
1488				  loc);
1489}
1490inline rvalue
1491function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1492		      location loc)
1493{
1494  return get_context ().new_call (*this,
1495				  arg0, arg1, arg2,
1496				  loc);
1497}
1498
1499// class block
1500inline block::block () : object () {}
1501inline block::block (gcc_jit_block *inner)
1502  : object (gcc_jit_block_as_object (inner))
1503{}
1504
1505inline gcc_jit_block *
1506block::get_inner_block () const
1507{
1508  /* Manual downcast: */
1509  return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1510}
1511
1512//  class rvalue
1513inline rvalue::rvalue () : object () {}
1514inline rvalue::rvalue (gcc_jit_rvalue *inner)
1515  : object (gcc_jit_rvalue_as_object (inner))
1516{}
1517
1518inline gcc_jit_rvalue *
1519rvalue::get_inner_rvalue () const
1520{
1521  /* Manual downcast: */
1522  return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1523}
1524
1525inline type
1526rvalue::get_type ()
1527{
1528  return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1529}
1530
1531inline rvalue
1532rvalue::access_field (field field,
1533		      location loc)
1534{
1535  return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1536					      loc.get_inner_location (),
1537					      field.get_inner_field ()));
1538}
1539
1540inline lvalue
1541rvalue::dereference_field (field field,
1542			   location loc)
1543{
1544  return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1545						   loc.get_inner_location (),
1546						   field.get_inner_field ()));
1547}
1548
1549inline lvalue
1550rvalue::dereference (location loc)
1551{
1552  return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1553					     loc.get_inner_location ()));
1554}
1555
1556inline rvalue
1557rvalue::cast_to (type type_,
1558		 location loc)
1559{
1560  return get_context ().new_cast (*this, type_, loc);
1561}
1562
1563inline lvalue
1564rvalue::operator[] (rvalue index)
1565{
1566  return get_context ().new_array_access (*this, index);
1567}
1568
1569inline lvalue
1570rvalue::operator[] (int index)
1571{
1572  context ctxt = get_context ();
1573  type int_t = ctxt.get_int_type <int> ();
1574  return ctxt.new_array_access (*this,
1575				ctxt.new_rvalue (int_t,
1576						 index));
1577}
1578
1579// class lvalue : public rvalue
1580inline lvalue::lvalue () : rvalue () {}
1581inline lvalue::lvalue (gcc_jit_lvalue *inner)
1582  : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1583{}
1584
1585inline gcc_jit_lvalue *
1586lvalue::get_inner_lvalue () const
1587{
1588  /* Manual downcast: */
1589  return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1590}
1591
1592inline lvalue
1593lvalue::access_field (field field, location loc)
1594{
1595  return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1596					      loc.get_inner_location (),
1597					      field.get_inner_field ()));
1598}
1599
1600inline rvalue
1601lvalue::get_address (location loc)
1602{
1603  return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1604					     loc.get_inner_location ()));
1605}
1606
1607// class param : public lvalue
1608inline param::param () : lvalue () {}
1609inline param::param (gcc_jit_param *inner)
1610  : lvalue (gcc_jit_param_as_lvalue (inner))
1611{}
1612
1613// class case_ : public object
1614inline case_::case_ () : object () {}
1615inline case_::case_ (gcc_jit_case *inner)
1616  : object (gcc_jit_case_as_object (inner))
1617{
1618}
1619
1620inline gcc_jit_case *
1621case_::get_inner_case () const
1622{
1623  /* Manual downcast: */
1624  return reinterpret_cast<gcc_jit_case *> (get_inner_object ());
1625}
1626
1627/* Overloaded operators.  */
1628// Unary operators
1629inline rvalue operator- (rvalue a)
1630{
1631  return a.get_context ().new_minus (a.get_type (), a);
1632}
1633inline rvalue operator~ (rvalue a)
1634{
1635  return a.get_context ().new_bitwise_negate (a.get_type (), a);
1636}
1637inline rvalue operator! (rvalue a)
1638{
1639  return a.get_context ().new_logical_negate (a.get_type (), a);
1640}
1641
1642// Binary operators
1643inline rvalue operator+ (rvalue a, rvalue b)
1644{
1645  return a.get_context ().new_plus (a.get_type (), a, b);
1646}
1647inline rvalue operator- (rvalue a, rvalue b)
1648{
1649  return a.get_context ().new_minus (a.get_type (), a, b);
1650}
1651inline rvalue operator* (rvalue a, rvalue b)
1652{
1653  return a.get_context ().new_mult (a.get_type (), a, b);
1654}
1655inline rvalue operator/ (rvalue a, rvalue b)
1656{
1657  return a.get_context ().new_divide (a.get_type (), a, b);
1658}
1659inline rvalue operator% (rvalue a, rvalue b)
1660{
1661  return a.get_context ().new_modulo (a.get_type (), a, b);
1662}
1663inline rvalue operator& (rvalue a, rvalue b)
1664{
1665  return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1666}
1667inline rvalue operator^ (rvalue a, rvalue b)
1668{
1669  return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1670}
1671inline rvalue operator| (rvalue a, rvalue b)
1672{
1673  return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1674}
1675inline rvalue operator&& (rvalue a, rvalue b)
1676{
1677  return a.get_context ().new_logical_and (a.get_type (), a, b);
1678}
1679inline rvalue operator|| (rvalue a, rvalue b)
1680{
1681  return a.get_context ().new_logical_or (a.get_type (), a, b);
1682}
1683
1684/* Comparisons.  */
1685inline rvalue operator== (rvalue a, rvalue b)
1686{
1687  return a.get_context ().new_eq (a, b);
1688}
1689inline rvalue operator!= (rvalue a, rvalue b)
1690{
1691  return a.get_context ().new_ne (a, b);
1692}
1693inline rvalue operator< (rvalue a, rvalue b)
1694{
1695  return a.get_context ().new_lt (a, b);
1696}
1697inline rvalue operator<= (rvalue a, rvalue b)
1698{
1699  return a.get_context ().new_le (a, b);
1700}
1701inline rvalue operator> (rvalue a, rvalue b)
1702{
1703  return a.get_context ().new_gt (a, b);
1704}
1705inline rvalue operator>= (rvalue a, rvalue b)
1706{
1707  return a.get_context ().new_ge (a, b);
1708}
1709
1710/* Dereferencing. */
1711inline lvalue operator* (rvalue ptr)
1712{
1713  return ptr.dereference ();
1714}
1715
1716} // namespace gccjit
1717
1718#endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */
1719