xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/jit/libgccjit++.h (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2    Copyright (C) 2014-2015 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along 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 
33 namespace 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  ****************************************************************************/
531 namespace gccjit {
532 
533 // class context
534 inline context context::acquire ()
535 {
536   return context (gcc_jit_context_acquire ());
537 }
538 inline context::context () : m_inner_ctxt (NULL) {}
539 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
540 {
541   if (!inner)
542     throw error ();
543 }
544 
545 inline gccjit::context
546 context::new_child_context ()
547 {
548   return context (gcc_jit_context_new_child_context (m_inner_ctxt));
549 }
550 
551 inline void
552 context::release ()
553 {
554   gcc_jit_context_release (m_inner_ctxt);
555   m_inner_ctxt = NULL;
556 }
557 
558 inline gcc_jit_result *
559 context::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 
567 inline void
568 context::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 
576 inline void
577 context::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 
585 inline void
586 context::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 
596 inline void
597 context::dump_reproducer_to_file (const char *path)
598 {
599   gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
600 					   path);
601 }
602 
603 inline void
604 context::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 
611 inline void
612 context::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 
619 inline void
620 context::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 
626 inline void
627 context::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 
633 inline void
634 context::add_command_line_option (const char *optname)
635 {
636   gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
637 }
638 
639 inline location
640 context::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 
650 inline type
651 context::get_type (enum gcc_jit_types kind)
652 {
653   return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
654 }
655 
656 inline type
657 context::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 
664 template <typename T>
665 inline type
666 context::get_int_type ()
667 {
668   return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
669 }
670 
671 inline type
672 context::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 
681 inline field
682 context::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 
690 inline struct_
691 context::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 
710 inline struct_
711 context::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 
720 inline param
721 context::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 
731 inline function
732 context::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 
757 inline function
758 context::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 
764 inline lvalue
765 context::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 
777 inline rvalue
778 context::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 
787 inline rvalue
788 context::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 
797 inline rvalue
798 context::zero (type numeric_type) const
799 {
800   return rvalue (gcc_jit_context_zero (m_inner_ctxt,
801 				       numeric_type.get_inner_type ()));
802 }
803 
804 inline rvalue
805 context::one (type numeric_type) const
806 {
807   return rvalue (gcc_jit_context_one (m_inner_ctxt,
808 				       numeric_type.get_inner_type ()));
809 }
810 
811 inline rvalue
812 context::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 
821 inline rvalue
822 context::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 
831 inline rvalue
832 context::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 
838 inline rvalue
839 context::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 }
850 inline rvalue
851 context::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 }
858 inline rvalue
859 context::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 }
866 inline rvalue
867 context::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 
875 inline rvalue
876 context::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 }
888 inline rvalue
889 context::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 }
896 inline rvalue
897 context::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 }
904 inline rvalue
905 context::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 }
912 inline rvalue
913 context::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 }
920 inline rvalue
921 context::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 }
928 inline rvalue
929 context::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 }
936 inline rvalue
937 context::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 }
944 inline rvalue
945 context::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 }
952 inline rvalue
953 context::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 }
960 inline rvalue
961 context::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 
969 inline rvalue
970 context::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 }
980 inline rvalue
981 context::new_eq (rvalue a, rvalue b,
982 		 location loc)
983 {
984   return new_comparison (GCC_JIT_COMPARISON_EQ,
985 			 a, b, loc);
986 }
987 inline rvalue
988 context::new_ne (rvalue a, rvalue b,
989 		 location loc)
990 {
991   return new_comparison (GCC_JIT_COMPARISON_NE,
992 			 a, b, loc);
993 }
994 inline rvalue
995 context::new_lt (rvalue a, rvalue b,
996 		 location loc)
997 {
998   return new_comparison (GCC_JIT_COMPARISON_LT,
999 			 a, b, loc);
1000 }
1001 inline rvalue
1002 context::new_le (rvalue a, rvalue b,
1003 		 location loc)
1004 {
1005   return new_comparison (GCC_JIT_COMPARISON_LE,
1006 			 a, b, loc);
1007 }
1008 inline rvalue
1009 context::new_gt (rvalue a, rvalue b,
1010 		 location loc)
1011 {
1012   return new_comparison (GCC_JIT_COMPARISON_GT,
1013 			 a, b, loc);
1014 }
1015 inline rvalue
1016 context::new_ge (rvalue a, rvalue b,
1017 		 location loc)
1018 {
1019   return new_comparison (GCC_JIT_COMPARISON_GE,
1020 			 a, b, loc);
1021 }
1022 
1023 inline rvalue
1024 context::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 }
1041 inline rvalue
1042 context::new_call (function func,
1043 		   location loc)
1044 {
1045   std::vector<rvalue> args;
1046   return new_call (func, args, loc);
1047 }
1048 
1049 inline rvalue
1050 context::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 }
1058 inline rvalue
1059 context::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 }
1068 inline rvalue
1069 context::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 }
1079 inline rvalue
1080 context::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 }
1092 inline rvalue
1093 context::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 }
1106 inline rvalue
1107 context::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 
1122 inline rvalue
1123 context::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 
1133 inline lvalue
1134 context::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 
1144 inline case_
1145 context::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
1156 inline context
1157 object::get_context () const
1158 {
1159   return context (gcc_jit_object_get_context (m_inner_obj));
1160 }
1161 
1162 inline std::string
1163 object::get_debug_string () const
1164 {
1165   return gcc_jit_object_get_debug_string (m_inner_obj);
1166 }
1167 
1168 inline object::object () : m_inner_obj (NULL) {}
1169 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1170 {
1171   if (!obj)
1172     throw error ();
1173 }
1174 
1175 inline gcc_jit_object *
1176 object::get_inner_object () const
1177 {
1178   return m_inner_obj;
1179 }
1180 
1181 inline std::ostream&
1182 operator << (std::ostream& stream, const object &obj)
1183 {
1184   return stream << obj.get_debug_string ();
1185 }
1186 
1187 // class location
1188 inline location::location () : object () {}
1189 inline location::location (gcc_jit_location *loc)
1190   : object (gcc_jit_location_as_object (loc))
1191 {}
1192 
1193 inline gcc_jit_location *
1194 location::get_inner_location () const
1195 {
1196   /* Manual downcast: */
1197   return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1198 }
1199 
1200 // class field
1201 inline field::field () : object () {}
1202 inline field::field (gcc_jit_field *inner)
1203   : object (gcc_jit_field_as_object (inner))
1204 {}
1205 
1206 inline gcc_jit_field *
1207 field::get_inner_field () const
1208 {
1209   /* Manual downcast: */
1210   return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1211 }
1212 
1213 // class type
1214 inline type::type () : object () {}
1215 inline type::type (gcc_jit_type *inner)
1216   : object (gcc_jit_type_as_object (inner))
1217 {}
1218 
1219 inline gcc_jit_type *
1220 type::get_inner_type () const
1221 {
1222   /* Manual downcast: */
1223   return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1224 }
1225 
1226 inline type
1227 type::get_pointer ()
1228 {
1229   return type (gcc_jit_type_get_pointer (get_inner_type ()));
1230 }
1231 
1232 inline type
1233 type::get_volatile ()
1234 {
1235   return type (gcc_jit_type_get_volatile (get_inner_type ()));
1236 }
1237 
1238 inline rvalue
1239 type::zero ()
1240 {
1241   return get_context ().new_rvalue (*this, 0);
1242 }
1243 
1244 inline rvalue
1245 type::one ()
1246 {
1247   return get_context ().new_rvalue (*this, 1);
1248 }
1249 
1250 // class struct_
1251 inline struct_::struct_ () : type (NULL) {}
1252 inline struct_::struct_ (gcc_jit_struct *inner) :
1253   type (gcc_jit_struct_as_type (inner))
1254 {
1255 }
1256 
1257 inline gcc_jit_struct *
1258 struct_::get_inner_struct () const
1259 {
1260   /* Manual downcast: */
1261   return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1262 }
1263 
1264 // class function
1265 inline function::function () : object () {}
1266 inline function::function (gcc_jit_function *inner)
1267   : object (gcc_jit_function_as_object (inner))
1268 {}
1269 
1270 inline gcc_jit_function *
1271 function::get_inner_function () const
1272 {
1273   /* Manual downcast: */
1274   return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1275 }
1276 
1277 inline void
1278 function::dump_to_dot (const std::string &path)
1279 {
1280   gcc_jit_function_dump_to_dot (get_inner_function (),
1281 				path.c_str ());
1282 }
1283 
1284 inline param
1285 function::get_param (int index) const
1286 {
1287   return param (gcc_jit_function_get_param (get_inner_function (),
1288 					    index));
1289 }
1290 
1291 inline block
1292 function::new_block ()
1293 {
1294   return block (gcc_jit_function_new_block (get_inner_function (),
1295 					    NULL));
1296 }
1297 
1298 inline block
1299 function::new_block (const std::string &name)
1300 {
1301   return block (gcc_jit_function_new_block (get_inner_function (),
1302 					    name.c_str ()));
1303 }
1304 
1305 inline lvalue
1306 function::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 
1316 inline function
1317 block::get_function () const
1318 {
1319   return function (gcc_jit_block_get_function ( get_inner_block ()));
1320 }
1321 
1322 inline void
1323 block::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 
1331 inline void
1332 block::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 
1342 inline void
1343 block::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 
1355 inline void
1356 block::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 
1364 inline void
1365 block::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 
1377 inline void
1378 block::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 
1386 inline void
1387 block::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 
1395 inline void
1396 block::end_with_return (location loc)
1397 {
1398   gcc_jit_block_end_with_void_return (get_inner_block (),
1399 				      loc.get_inner_location ());
1400 }
1401 
1402 inline void
1403 block::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 
1423 inline rvalue
1424 block::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 }
1431 inline rvalue
1432 block::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 }
1440 inline rvalue
1441 block::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 }
1449 inline rvalue
1450 block::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 
1459 inline rvalue
1460 block::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 
1469 inline rvalue
1470 function::operator() (location loc)
1471 {
1472   return get_context ().new_call (*this, loc);
1473 }
1474 inline rvalue
1475 function::operator() (rvalue arg0,
1476 		      location loc)
1477 {
1478   return get_context ().new_call (*this,
1479 				  arg0,
1480 				  loc);
1481 }
1482 inline rvalue
1483 function::operator() (rvalue arg0, rvalue arg1,
1484 		      location loc)
1485 {
1486   return get_context ().new_call (*this,
1487 				  arg0, arg1,
1488 				  loc);
1489 }
1490 inline rvalue
1491 function::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
1500 inline block::block () : object () {}
1501 inline block::block (gcc_jit_block *inner)
1502   : object (gcc_jit_block_as_object (inner))
1503 {}
1504 
1505 inline gcc_jit_block *
1506 block::get_inner_block () const
1507 {
1508   /* Manual downcast: */
1509   return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1510 }
1511 
1512 //  class rvalue
1513 inline rvalue::rvalue () : object () {}
1514 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1515   : object (gcc_jit_rvalue_as_object (inner))
1516 {}
1517 
1518 inline gcc_jit_rvalue *
1519 rvalue::get_inner_rvalue () const
1520 {
1521   /* Manual downcast: */
1522   return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1523 }
1524 
1525 inline type
1526 rvalue::get_type ()
1527 {
1528   return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1529 }
1530 
1531 inline rvalue
1532 rvalue::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 
1540 inline lvalue
1541 rvalue::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 
1549 inline lvalue
1550 rvalue::dereference (location loc)
1551 {
1552   return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1553 					     loc.get_inner_location ()));
1554 }
1555 
1556 inline rvalue
1557 rvalue::cast_to (type type_,
1558 		 location loc)
1559 {
1560   return get_context ().new_cast (*this, type_, loc);
1561 }
1562 
1563 inline lvalue
1564 rvalue::operator[] (rvalue index)
1565 {
1566   return get_context ().new_array_access (*this, index);
1567 }
1568 
1569 inline lvalue
1570 rvalue::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
1580 inline lvalue::lvalue () : rvalue () {}
1581 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1582   : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1583 {}
1584 
1585 inline gcc_jit_lvalue *
1586 lvalue::get_inner_lvalue () const
1587 {
1588   /* Manual downcast: */
1589   return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1590 }
1591 
1592 inline lvalue
1593 lvalue::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 
1600 inline rvalue
1601 lvalue::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
1608 inline param::param () : lvalue () {}
1609 inline param::param (gcc_jit_param *inner)
1610   : lvalue (gcc_jit_param_as_lvalue (inner))
1611 {}
1612 
1613 // class case_ : public object
1614 inline case_::case_ () : object () {}
1615 inline case_::case_ (gcc_jit_case *inner)
1616   : object (gcc_jit_case_as_object (inner))
1617 {
1618 }
1619 
1620 inline gcc_jit_case *
1621 case_::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
1629 inline rvalue operator- (rvalue a)
1630 {
1631   return a.get_context ().new_minus (a.get_type (), a);
1632 }
1633 inline rvalue operator~ (rvalue a)
1634 {
1635   return a.get_context ().new_bitwise_negate (a.get_type (), a);
1636 }
1637 inline rvalue operator! (rvalue a)
1638 {
1639   return a.get_context ().new_logical_negate (a.get_type (), a);
1640 }
1641 
1642 // Binary operators
1643 inline rvalue operator+ (rvalue a, rvalue b)
1644 {
1645   return a.get_context ().new_plus (a.get_type (), a, b);
1646 }
1647 inline rvalue operator- (rvalue a, rvalue b)
1648 {
1649   return a.get_context ().new_minus (a.get_type (), a, b);
1650 }
1651 inline rvalue operator* (rvalue a, rvalue b)
1652 {
1653   return a.get_context ().new_mult (a.get_type (), a, b);
1654 }
1655 inline rvalue operator/ (rvalue a, rvalue b)
1656 {
1657   return a.get_context ().new_divide (a.get_type (), a, b);
1658 }
1659 inline rvalue operator% (rvalue a, rvalue b)
1660 {
1661   return a.get_context ().new_modulo (a.get_type (), a, b);
1662 }
1663 inline rvalue operator& (rvalue a, rvalue b)
1664 {
1665   return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1666 }
1667 inline rvalue operator^ (rvalue a, rvalue b)
1668 {
1669   return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1670 }
1671 inline rvalue operator| (rvalue a, rvalue b)
1672 {
1673   return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1674 }
1675 inline rvalue operator&& (rvalue a, rvalue b)
1676 {
1677   return a.get_context ().new_logical_and (a.get_type (), a, b);
1678 }
1679 inline rvalue operator|| (rvalue a, rvalue b)
1680 {
1681   return a.get_context ().new_logical_or (a.get_type (), a, b);
1682 }
1683 
1684 /* Comparisons.  */
1685 inline rvalue operator== (rvalue a, rvalue b)
1686 {
1687   return a.get_context ().new_eq (a, b);
1688 }
1689 inline rvalue operator!= (rvalue a, rvalue b)
1690 {
1691   return a.get_context ().new_ne (a, b);
1692 }
1693 inline rvalue operator< (rvalue a, rvalue b)
1694 {
1695   return a.get_context ().new_lt (a, b);
1696 }
1697 inline rvalue operator<= (rvalue a, rvalue b)
1698 {
1699   return a.get_context ().new_le (a, b);
1700 }
1701 inline rvalue operator> (rvalue a, rvalue b)
1702 {
1703   return a.get_context ().new_gt (a, b);
1704 }
1705 inline rvalue operator>= (rvalue a, rvalue b)
1706 {
1707   return a.get_context ().new_ge (a, b);
1708 }
1709 
1710 /* Dereferencing. */
1711 inline lvalue operator* (rvalue ptr)
1712 {
1713   return ptr.dereference ();
1714 }
1715 
1716 } // namespace gccjit
1717 
1718 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */
1719