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