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