PR c/79855: add full stop to store merging param descriptions
[official-gcc.git] / gcc / jit / libgccjit++.h
blob8dc2112367b8947d16105a612a7f6d49293d3444
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #ifndef LIBGCCJIT_PLUS_PLUS_H
21 #define LIBGCCJIT_PLUS_PLUS_H
23 #include "libgccjit.h"
25 #include <limits>
26 #include <ostream>
27 #include <vector>
29 /****************************************************************************
30 C++ API
31 ****************************************************************************/
33 namespace gccjit
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;
52 /* Errors within the API become C++ exceptions of this class. */
53 class error
57 class object
59 public:
60 context get_context () const;
62 std::string get_debug_string () const;
64 protected:
65 object ();
66 object (gcc_jit_object *obj);
68 gcc_jit_object *get_inner_object () const;
70 private:
71 gcc_jit_object *m_inner_obj;
74 inline std::ostream& operator << (std::ostream& stream, const object &obj);
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
83 public:
84 location ();
85 location (gcc_jit_location *loc);
87 gcc_jit_location *get_inner_location () const;
90 class context
92 public:
93 static context acquire ();
94 context ();
95 context (gcc_jit_context *ctxt);
97 gccjit::context new_child_context ();
99 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
101 void release ();
103 gcc_jit_result *compile ();
105 void compile_to_file (enum gcc_jit_output_kind output_kind,
106 const char *output_path);
108 void dump_to_file (const std::string &path,
109 bool update_locations);
111 void set_logfile (FILE *logfile,
112 int flags,
113 int verbosity);
115 void dump_reproducer_to_file (const char *path);
117 void set_str_option (enum gcc_jit_str_option opt,
118 const char *value);
120 void set_int_option (enum gcc_jit_int_option opt,
121 int value);
123 void set_bool_option (enum gcc_jit_bool_option opt,
124 int value);
126 void set_bool_allow_unreachable_blocks (int bool_value);
127 void set_bool_use_external_driver (int bool_value);
129 void add_command_line_option (const char *optname);
131 void set_timer (gccjit::timer t);
132 gccjit::timer get_timer () const;
134 location
135 new_location (const std::string &filename,
136 int line,
137 int column);
139 type get_type (enum gcc_jit_types kind);
140 type get_int_type (size_t num_bytes, int is_signed);
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 ();
148 type new_array_type (type element_type, int num_elements,
149 location loc = location ());
151 field new_field (type type_, const std::string &name,
152 location loc = location ());
154 struct_ new_struct_type (const std::string &name,
155 std::vector<field> &fields,
156 location loc = location ());
158 struct_ new_opaque_struct_type (const std::string &name,
159 location loc = location ());
161 param new_param (type type_,
162 const std::string &name,
163 location loc = location ());
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 ());
172 function get_builtin_function (const std::string &name);
174 lvalue new_global (enum gcc_jit_global_kind kind,
175 type type_,
176 const std::string &name,
177 location loc = location ());
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;
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
299 rvalue new_cast (rvalue expr,
300 type type_,
301 location loc = location ());
303 lvalue new_array_access (rvalue ptr,
304 rvalue index,
305 location loc = location ());
307 case_ new_case (rvalue min_value,
308 rvalue max_value,
309 block dest_block);
311 private:
312 gcc_jit_context *m_inner_ctxt;
315 class field : public object
317 public:
318 field ();
319 field (gcc_jit_field *inner);
321 gcc_jit_field *get_inner_field () const;
324 class type : public object
326 public:
327 type ();
328 type (gcc_jit_type *inner);
330 gcc_jit_type *get_inner_type () const;
332 type get_pointer ();
333 type get_volatile ();
335 // Shortcuts for getting values of numeric types:
336 rvalue zero ();
337 rvalue one ();
340 class struct_ : public type
342 public:
343 struct_ ();
344 struct_ (gcc_jit_struct *inner);
346 gcc_jit_struct *get_inner_struct () const;
349 class function : public object
351 public:
352 function ();
353 function (gcc_jit_function *func);
355 gcc_jit_function *get_inner_function () const;
357 void dump_to_dot (const std::string &path);
359 param get_param (int index) const;
361 block new_block ();
362 block new_block (const std::string &name);
364 lvalue new_local (type type_,
365 const std::string &name,
366 location loc = location ());
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 ());
381 class block : public object
383 public:
384 block ();
385 block (gcc_jit_block *inner);
387 gcc_jit_block *get_inner_block () const;
389 function get_function () const;
391 void add_eval (rvalue rvalue,
392 location loc = location ());
394 void add_assignment (lvalue lvalue,
395 rvalue rvalue,
396 location loc = location ());
398 void add_assignment_op (lvalue lvalue,
399 enum gcc_jit_binary_op op,
400 rvalue rvalue,
401 location loc = location ());
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 ());
420 void add_comment (const std::string &text,
421 location loc = location ());
423 void end_with_conditional (rvalue boolval,
424 block on_true,
425 block on_false,
426 location loc = location ());
428 void end_with_jump (block target,
429 location loc = location ());
431 void end_with_return (rvalue rvalue,
432 location loc = location ());
433 void end_with_return (location loc = location ());
435 void end_with_switch (rvalue expr,
436 block default_block,
437 std::vector <case_> cases,
438 location loc = location ());
441 class rvalue : public object
443 public:
444 rvalue ();
445 rvalue (gcc_jit_rvalue *inner);
446 gcc_jit_rvalue *get_inner_rvalue () const;
448 type get_type ();
450 rvalue access_field (field field,
451 location loc = location ());
453 lvalue dereference_field (field field,
454 location loc = location ());
456 lvalue dereference (location loc = location ());
458 rvalue cast_to (type type_,
459 location loc = location ());
461 /* Array access. */
462 lvalue operator[] (rvalue index);
463 lvalue operator[] (int index);
466 class lvalue : public rvalue
468 public:
469 lvalue ();
470 lvalue (gcc_jit_lvalue *inner);
472 gcc_jit_lvalue *get_inner_lvalue () const;
474 lvalue access_field (field field,
475 location loc = location ());
477 rvalue get_address (location loc = location ());
480 class param : public lvalue
482 public:
483 param ();
484 param (gcc_jit_param *inner);
486 gcc_jit_param *get_inner_param () const;
489 class case_ : public object
491 public:
492 case_ ();
493 case_ (gcc_jit_case *inner);
495 gcc_jit_case *get_inner_case () const;
498 /* Overloaded operators, for those who want the most terse API
499 (at the possible risk of being a little too magical).
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. */
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
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
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);
530 /* Dereferencing. */
531 lvalue operator* (rvalue ptr);
533 class timer
535 public:
536 timer ();
537 timer (gcc_jit_timer *inner_timer);
539 void push (const char *item_name);
540 void pop (const char *item_name);
541 void print (FILE *f_out) const;
543 void release ();
545 gcc_jit_timer *get_inner_timer () const;
547 private:
548 gcc_jit_timer *m_inner_timer;
551 class auto_time
553 public:
554 auto_time (timer t, const char *item_name);
555 auto_time (context ctxt, const char *item_name);
556 ~auto_time ();
558 private:
559 timer m_timer;
560 const char *m_item_name;
564 /****************************************************************************
565 Implementation of the API
566 ****************************************************************************/
567 namespace gccjit {
569 // class context
570 inline context context::acquire ()
572 return context (gcc_jit_context_acquire ());
574 inline context::context () : m_inner_ctxt (NULL) {}
575 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
577 if (!inner)
578 throw error ();
581 inline gccjit::context
582 context::new_child_context ()
584 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
587 inline void
588 context::release ()
590 gcc_jit_context_release (m_inner_ctxt);
591 m_inner_ctxt = NULL;
594 inline gcc_jit_result *
595 context::compile ()
597 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
598 if (!result)
599 throw error ();
600 return result;
603 inline void
604 context::compile_to_file (enum gcc_jit_output_kind output_kind,
605 const char *output_path)
607 gcc_jit_context_compile_to_file (m_inner_ctxt,
608 output_kind,
609 output_path);
612 inline void
613 context::dump_to_file (const std::string &path,
614 bool update_locations)
616 gcc_jit_context_dump_to_file (m_inner_ctxt,
617 path.c_str (),
618 update_locations);
621 inline void
622 context::set_logfile (FILE *logfile,
623 int flags,
624 int verbosity)
626 gcc_jit_context_set_logfile (m_inner_ctxt,
627 logfile,
628 flags,
629 verbosity);
632 inline void
633 context::dump_reproducer_to_file (const char *path)
635 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
636 path);
639 inline void
640 context::set_str_option (enum gcc_jit_str_option opt,
641 const char *value)
643 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
647 inline void
648 context::set_int_option (enum gcc_jit_int_option opt,
649 int value)
651 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
655 inline void
656 context::set_bool_option (enum gcc_jit_bool_option opt,
657 int value)
659 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
662 inline void
663 context::set_bool_allow_unreachable_blocks (int bool_value)
665 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
666 bool_value);
669 inline void
670 context::set_bool_use_external_driver (int bool_value)
672 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt,
673 bool_value);
676 inline void
677 context::add_command_line_option (const char *optname)
679 gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
682 inline void
683 context::set_timer (gccjit::timer t)
685 gcc_jit_context_set_timer (m_inner_ctxt, t.get_inner_timer ());
688 inline gccjit::timer
689 context::get_timer () const
691 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt));
695 inline location
696 context::new_location (const std::string &filename,
697 int line,
698 int column)
700 return location (gcc_jit_context_new_location (m_inner_ctxt,
701 filename.c_str (),
702 line,
703 column));
706 inline type
707 context::get_type (enum gcc_jit_types kind)
709 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
712 inline type
713 context::get_int_type (size_t num_bytes, int is_signed)
715 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
716 num_bytes,
717 is_signed));
720 template <typename T>
721 inline type
722 context::get_int_type ()
724 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
727 inline type
728 context::new_array_type (type element_type, int num_elements, location loc)
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));
737 inline field
738 context::new_field (type type_, const std::string &name, location loc)
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 ()));
746 inline struct_
747 context::new_struct_type (const std::string &name,
748 std::vector<field> &fields,
749 location loc)
751 /* Treat std::vector as an array, relying on it not being resized: */
752 field *as_array_of_wrappers = &fields[0];
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);
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));
766 inline struct_
767 context::new_opaque_struct_type (const std::string &name,
768 location loc)
770 return struct_ (gcc_jit_context_new_opaque_struct (
771 m_inner_ctxt,
772 loc.get_inner_location (),
773 name.c_str ()));
776 inline param
777 context::new_param (type type_,
778 const std::string &name,
779 location loc)
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 ()));
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)
795 /* Treat std::vector as an array, relying on it not being resized: */
796 param *as_array_of_wrappers = &params[0];
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);
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));
813 inline function
814 context::get_builtin_function (const std::string &name)
816 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
817 name.c_str ()));
820 inline lvalue
821 context::new_global (enum gcc_jit_global_kind kind,
822 type type_,
823 const std::string &name,
824 location loc)
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 ()));
833 inline rvalue
834 context::new_rvalue (type numeric_type,
835 int value) const
837 return rvalue (
838 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
839 numeric_type.get_inner_type (),
840 value));
843 inline rvalue
844 context::new_rvalue (type numeric_type,
845 long value) const
847 return rvalue (
848 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
849 numeric_type.get_inner_type (),
850 value));
853 inline rvalue
854 context::zero (type numeric_type) const
856 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
857 numeric_type.get_inner_type ()));
860 inline rvalue
861 context::one (type numeric_type) const
863 return rvalue (gcc_jit_context_one (m_inner_ctxt,
864 numeric_type.get_inner_type ()));
867 inline rvalue
868 context::new_rvalue (type numeric_type,
869 double value) const
871 return rvalue (
872 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
873 numeric_type.get_inner_type (),
874 value));
877 inline rvalue
878 context::new_rvalue (type pointer_type,
879 void *value) const
881 return rvalue (
882 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
883 pointer_type.get_inner_type (),
884 value));
887 inline rvalue
888 context::new_rvalue (const std::string &value) const
890 return rvalue (
891 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
894 inline rvalue
895 context::new_unary_op (enum gcc_jit_unary_op op,
896 type result_type,
897 rvalue a,
898 location loc)
900 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
901 loc.get_inner_location (),
903 result_type.get_inner_type (),
904 a.get_inner_rvalue ()));
906 inline rvalue
907 context::new_minus (type result_type,
908 rvalue a,
909 location loc)
911 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
912 result_type, a, loc));
914 inline rvalue
915 context::new_bitwise_negate (type result_type,
916 rvalue a,
917 location loc)
919 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
920 result_type, a, loc));
922 inline rvalue
923 context::new_logical_negate (type result_type,
924 rvalue a,
925 location loc)
927 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
928 result_type, a, loc));
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)
937 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
938 loc.get_inner_location (),
940 result_type.get_inner_type (),
941 a.get_inner_rvalue (),
942 b.get_inner_rvalue ()));
944 inline rvalue
945 context::new_plus (type result_type,
946 rvalue a, rvalue b,
947 location loc)
949 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
950 result_type, a, b, loc);
952 inline rvalue
953 context::new_minus (type result_type,
954 rvalue a, rvalue b,
955 location loc)
957 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
958 result_type, a, b, loc);
960 inline rvalue
961 context::new_mult (type result_type,
962 rvalue a, rvalue b,
963 location loc)
965 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
966 result_type, a, b, loc);
968 inline rvalue
969 context::new_divide (type result_type,
970 rvalue a, rvalue b,
971 location loc)
973 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
974 result_type, a, b, loc);
976 inline rvalue
977 context::new_modulo (type result_type,
978 rvalue a, rvalue b,
979 location loc)
981 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
982 result_type, a, b, loc);
984 inline rvalue
985 context::new_bitwise_and (type result_type,
986 rvalue a, rvalue b,
987 location loc)
989 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
990 result_type, a, b, loc);
992 inline rvalue
993 context::new_bitwise_xor (type result_type,
994 rvalue a, rvalue b,
995 location loc)
997 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
998 result_type, a, b, loc);
1000 inline rvalue
1001 context::new_bitwise_or (type result_type,
1002 rvalue a, rvalue b,
1003 location loc)
1005 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
1006 result_type, a, b, loc);
1008 inline rvalue
1009 context::new_logical_and (type result_type,
1010 rvalue a, rvalue b,
1011 location loc)
1013 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
1014 result_type, a, b, loc);
1016 inline rvalue
1017 context::new_logical_or (type result_type,
1018 rvalue a, rvalue b,
1019 location loc)
1021 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
1022 result_type, a, b, loc);
1025 inline rvalue
1026 context::new_comparison (enum gcc_jit_comparison op,
1027 rvalue a, rvalue b,
1028 location loc)
1030 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
1031 loc.get_inner_location (),
1033 a.get_inner_rvalue (),
1034 b.get_inner_rvalue ()));
1036 inline rvalue
1037 context::new_eq (rvalue a, rvalue b,
1038 location loc)
1040 return new_comparison (GCC_JIT_COMPARISON_EQ,
1041 a, b, loc);
1043 inline rvalue
1044 context::new_ne (rvalue a, rvalue b,
1045 location loc)
1047 return new_comparison (GCC_JIT_COMPARISON_NE,
1048 a, b, loc);
1050 inline rvalue
1051 context::new_lt (rvalue a, rvalue b,
1052 location loc)
1054 return new_comparison (GCC_JIT_COMPARISON_LT,
1055 a, b, loc);
1057 inline rvalue
1058 context::new_le (rvalue a, rvalue b,
1059 location loc)
1061 return new_comparison (GCC_JIT_COMPARISON_LE,
1062 a, b, loc);
1064 inline rvalue
1065 context::new_gt (rvalue a, rvalue b,
1066 location loc)
1068 return new_comparison (GCC_JIT_COMPARISON_GT,
1069 a, b, loc);
1071 inline rvalue
1072 context::new_ge (rvalue a, rvalue b,
1073 location loc)
1075 return new_comparison (GCC_JIT_COMPARISON_GE,
1076 a, b, loc);
1079 inline rvalue
1080 context::new_call (function func,
1081 std::vector<rvalue> &args,
1082 location loc)
1084 /* Treat std::vector as an array, relying on it not being resized: */
1085 rvalue *as_array_of_wrappers = &args[0];
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);
1097 inline rvalue
1098 context::new_call (function func,
1099 location loc)
1101 std::vector<rvalue> args;
1102 return new_call (func, args, loc);
1105 inline rvalue
1106 context::new_call (function func,
1107 rvalue arg0,
1108 location loc)
1110 std::vector<rvalue> args(1);
1111 args[0] = arg0;
1112 return new_call (func, args, loc);
1114 inline rvalue
1115 context::new_call (function func,
1116 rvalue arg0, rvalue arg1,
1117 location loc)
1119 std::vector<rvalue> args(2);
1120 args[0] = arg0;
1121 args[1] = arg1;
1122 return new_call (func, args, loc);
1124 inline rvalue
1125 context::new_call (function func,
1126 rvalue arg0, rvalue arg1, rvalue arg2,
1127 location loc)
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);
1135 inline rvalue
1136 context::new_call (function func,
1137 rvalue arg0, rvalue arg1, rvalue arg2,
1138 rvalue arg3,
1139 location loc)
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);
1148 inline rvalue
1149 context::new_call (function func,
1150 rvalue arg0, rvalue arg1, rvalue arg2,
1151 rvalue arg3, rvalue arg4,
1152 location loc)
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);
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)
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);
1178 inline rvalue
1179 context::new_cast (rvalue expr,
1180 type type_,
1181 location loc)
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 ()));
1189 inline lvalue
1190 context::new_array_access (rvalue ptr,
1191 rvalue index,
1192 location loc)
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 ()));
1200 inline case_
1201 context::new_case (rvalue min_value,
1202 rvalue max_value,
1203 block dest_block)
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 ()));
1211 // class object
1212 inline context
1213 object::get_context () const
1215 return context (gcc_jit_object_get_context (m_inner_obj));
1218 inline std::string
1219 object::get_debug_string () const
1221 return gcc_jit_object_get_debug_string (m_inner_obj);
1224 inline object::object () : m_inner_obj (NULL) {}
1225 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1227 if (!obj)
1228 throw error ();
1231 inline gcc_jit_object *
1232 object::get_inner_object () const
1234 return m_inner_obj;
1237 inline std::ostream&
1238 operator << (std::ostream& stream, const object &obj)
1240 return stream << obj.get_debug_string ();
1243 // class location
1244 inline location::location () : object () {}
1245 inline location::location (gcc_jit_location *loc)
1246 : object (gcc_jit_location_as_object (loc))
1249 inline gcc_jit_location *
1250 location::get_inner_location () const
1252 /* Manual downcast: */
1253 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1256 // class field
1257 inline field::field () : object () {}
1258 inline field::field (gcc_jit_field *inner)
1259 : object (gcc_jit_field_as_object (inner))
1262 inline gcc_jit_field *
1263 field::get_inner_field () const
1265 /* Manual downcast: */
1266 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1269 // class type
1270 inline type::type () : object () {}
1271 inline type::type (gcc_jit_type *inner)
1272 : object (gcc_jit_type_as_object (inner))
1275 inline gcc_jit_type *
1276 type::get_inner_type () const
1278 /* Manual downcast: */
1279 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1282 inline type
1283 type::get_pointer ()
1285 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1288 inline type
1289 type::get_volatile ()
1291 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1294 inline rvalue
1295 type::zero ()
1297 return get_context ().new_rvalue (*this, 0);
1300 inline rvalue
1301 type::one ()
1303 return get_context ().new_rvalue (*this, 1);
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))
1313 inline gcc_jit_struct *
1314 struct_::get_inner_struct () const
1316 /* Manual downcast: */
1317 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1320 // class function
1321 inline function::function () : object () {}
1322 inline function::function (gcc_jit_function *inner)
1323 : object (gcc_jit_function_as_object (inner))
1326 inline gcc_jit_function *
1327 function::get_inner_function () const
1329 /* Manual downcast: */
1330 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1333 inline void
1334 function::dump_to_dot (const std::string &path)
1336 gcc_jit_function_dump_to_dot (get_inner_function (),
1337 path.c_str ());
1340 inline param
1341 function::get_param (int index) const
1343 return param (gcc_jit_function_get_param (get_inner_function (),
1344 index));
1347 inline block
1348 function::new_block ()
1350 return block (gcc_jit_function_new_block (get_inner_function (),
1351 NULL));
1354 inline block
1355 function::new_block (const std::string &name)
1357 return block (gcc_jit_function_new_block (get_inner_function (),
1358 name.c_str ()));
1361 inline lvalue
1362 function::new_local (type type_,
1363 const std::string &name,
1364 location loc)
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 ()));
1372 inline function
1373 block::get_function () const
1375 return function (gcc_jit_block_get_function ( get_inner_block ()));
1378 inline void
1379 block::add_eval (rvalue rvalue,
1380 location loc)
1382 gcc_jit_block_add_eval (get_inner_block (),
1383 loc.get_inner_location (),
1384 rvalue.get_inner_rvalue ());
1387 inline void
1388 block::add_assignment (lvalue lvalue,
1389 rvalue rvalue,
1390 location loc)
1392 gcc_jit_block_add_assignment (get_inner_block (),
1393 loc.get_inner_location (),
1394 lvalue.get_inner_lvalue (),
1395 rvalue.get_inner_rvalue ());
1398 inline void
1399 block::add_assignment_op (lvalue lvalue,
1400 enum gcc_jit_binary_op op,
1401 rvalue rvalue,
1402 location loc)
1404 gcc_jit_block_add_assignment_op (get_inner_block (),
1405 loc.get_inner_location (),
1406 lvalue.get_inner_lvalue (),
1408 rvalue.get_inner_rvalue ());
1411 inline void
1412 block::add_comment (const std::string &text,
1413 location loc)
1415 gcc_jit_block_add_comment (get_inner_block (),
1416 loc.get_inner_location (),
1417 text.c_str ());
1420 inline void
1421 block::end_with_conditional (rvalue boolval,
1422 block on_true,
1423 block on_false,
1424 location loc)
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 ());
1433 inline void
1434 block::end_with_jump (block target,
1435 location loc)
1437 gcc_jit_block_end_with_jump (get_inner_block (),
1438 loc.get_inner_location (),
1439 target.get_inner_block ());
1442 inline void
1443 block::end_with_return (rvalue rvalue,
1444 location loc)
1446 gcc_jit_block_end_with_return (get_inner_block (),
1447 loc.get_inner_location (),
1448 rvalue.get_inner_rvalue ());
1451 inline void
1452 block::end_with_return (location loc)
1454 gcc_jit_block_end_with_void_return (get_inner_block (),
1455 loc.get_inner_location ());
1458 inline void
1459 block::end_with_switch (rvalue expr,
1460 block default_block,
1461 std::vector <case_> cases,
1462 location loc)
1464 /* Treat std::vector as an array, relying on it not being resized: */
1465 case_ *as_array_of_wrappers = &cases[0];
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);
1479 inline rvalue
1480 block::add_call (function other,
1481 location loc)
1483 rvalue c = get_context ().new_call (other, loc);
1484 add_eval (c);
1485 return c;
1487 inline rvalue
1488 block::add_call (function other,
1489 rvalue arg0,
1490 location loc)
1492 rvalue c = get_context ().new_call (other, arg0, loc);
1493 add_eval (c);
1494 return c;
1496 inline rvalue
1497 block::add_call (function other,
1498 rvalue arg0, rvalue arg1,
1499 location loc)
1501 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1502 add_eval (c);
1503 return c;
1505 inline rvalue
1506 block::add_call (function other,
1507 rvalue arg0, rvalue arg1, rvalue arg2,
1508 location loc)
1510 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1511 add_eval (c);
1512 return c;
1515 inline rvalue
1516 block::add_call (function other,
1517 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1518 location loc)
1520 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1521 add_eval (c);
1522 return c;
1525 inline rvalue
1526 function::operator() (location loc)
1528 return get_context ().new_call (*this, loc);
1530 inline rvalue
1531 function::operator() (rvalue arg0,
1532 location loc)
1534 return get_context ().new_call (*this,
1535 arg0,
1536 loc);
1538 inline rvalue
1539 function::operator() (rvalue arg0, rvalue arg1,
1540 location loc)
1542 return get_context ().new_call (*this,
1543 arg0, arg1,
1544 loc);
1546 inline rvalue
1547 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1548 location loc)
1550 return get_context ().new_call (*this,
1551 arg0, arg1, arg2,
1552 loc);
1555 // class block
1556 inline block::block () : object () {}
1557 inline block::block (gcc_jit_block *inner)
1558 : object (gcc_jit_block_as_object (inner))
1561 inline gcc_jit_block *
1562 block::get_inner_block () const
1564 /* Manual downcast: */
1565 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1568 // class rvalue
1569 inline rvalue::rvalue () : object () {}
1570 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1571 : object (gcc_jit_rvalue_as_object (inner))
1574 inline gcc_jit_rvalue *
1575 rvalue::get_inner_rvalue () const
1577 /* Manual downcast: */
1578 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1581 inline type
1582 rvalue::get_type ()
1584 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1587 inline rvalue
1588 rvalue::access_field (field field,
1589 location loc)
1591 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1592 loc.get_inner_location (),
1593 field.get_inner_field ()));
1596 inline lvalue
1597 rvalue::dereference_field (field field,
1598 location loc)
1600 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1601 loc.get_inner_location (),
1602 field.get_inner_field ()));
1605 inline lvalue
1606 rvalue::dereference (location loc)
1608 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1609 loc.get_inner_location ()));
1612 inline rvalue
1613 rvalue::cast_to (type type_,
1614 location loc)
1616 return get_context ().new_cast (*this, type_, loc);
1619 inline lvalue
1620 rvalue::operator[] (rvalue index)
1622 return get_context ().new_array_access (*this, index);
1625 inline lvalue
1626 rvalue::operator[] (int index)
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));
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))
1641 inline gcc_jit_lvalue *
1642 lvalue::get_inner_lvalue () const
1644 /* Manual downcast: */
1645 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1648 inline lvalue
1649 lvalue::access_field (field field, location loc)
1651 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1652 loc.get_inner_location (),
1653 field.get_inner_field ()));
1656 inline rvalue
1657 lvalue::get_address (location loc)
1659 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1660 loc.get_inner_location ()));
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))
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))
1676 inline gcc_jit_case *
1677 case_::get_inner_case () const
1679 /* Manual downcast: */
1680 return reinterpret_cast<gcc_jit_case *> (get_inner_object ());
1683 /* Overloaded operators. */
1684 // Unary operators
1685 inline rvalue operator- (rvalue a)
1687 return a.get_context ().new_minus (a.get_type (), a);
1689 inline rvalue operator~ (rvalue a)
1691 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1693 inline rvalue operator! (rvalue a)
1695 return a.get_context ().new_logical_negate (a.get_type (), a);
1698 // Binary operators
1699 inline rvalue operator+ (rvalue a, rvalue b)
1701 return a.get_context ().new_plus (a.get_type (), a, b);
1703 inline rvalue operator- (rvalue a, rvalue b)
1705 return a.get_context ().new_minus (a.get_type (), a, b);
1707 inline rvalue operator* (rvalue a, rvalue b)
1709 return a.get_context ().new_mult (a.get_type (), a, b);
1711 inline rvalue operator/ (rvalue a, rvalue b)
1713 return a.get_context ().new_divide (a.get_type (), a, b);
1715 inline rvalue operator% (rvalue a, rvalue b)
1717 return a.get_context ().new_modulo (a.get_type (), a, b);
1719 inline rvalue operator& (rvalue a, rvalue b)
1721 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1723 inline rvalue operator^ (rvalue a, rvalue b)
1725 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1727 inline rvalue operator| (rvalue a, rvalue b)
1729 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1731 inline rvalue operator&& (rvalue a, rvalue b)
1733 return a.get_context ().new_logical_and (a.get_type (), a, b);
1735 inline rvalue operator|| (rvalue a, rvalue b)
1737 return a.get_context ().new_logical_or (a.get_type (), a, b);
1740 /* Comparisons. */
1741 inline rvalue operator== (rvalue a, rvalue b)
1743 return a.get_context ().new_eq (a, b);
1745 inline rvalue operator!= (rvalue a, rvalue b)
1747 return a.get_context ().new_ne (a, b);
1749 inline rvalue operator< (rvalue a, rvalue b)
1751 return a.get_context ().new_lt (a, b);
1753 inline rvalue operator<= (rvalue a, rvalue b)
1755 return a.get_context ().new_le (a, b);
1757 inline rvalue operator> (rvalue a, rvalue b)
1759 return a.get_context ().new_gt (a, b);
1761 inline rvalue operator>= (rvalue a, rvalue b)
1763 return a.get_context ().new_ge (a, b);
1766 /* Dereferencing. */
1767 inline lvalue operator* (rvalue ptr)
1769 return ptr.dereference ();
1772 // class timer
1773 inline
1774 timer::timer ()
1776 m_inner_timer = gcc_jit_timer_new ();
1779 inline
1780 timer::timer (gcc_jit_timer *inner_timer)
1782 m_inner_timer = inner_timer;
1785 inline void
1786 timer::push (const char *item_name)
1788 gcc_jit_timer_push (m_inner_timer, item_name);
1792 inline void
1793 timer::pop (const char *item_name)
1795 gcc_jit_timer_pop (m_inner_timer, item_name);
1798 inline void
1799 timer::print (FILE *f_out) const
1801 gcc_jit_timer_print (m_inner_timer, f_out);
1804 inline gcc_jit_timer *
1805 timer::get_inner_timer () const
1807 return m_inner_timer;
1810 inline void
1811 timer::release ()
1813 gcc_jit_timer_release (m_inner_timer);
1814 m_inner_timer = NULL;
1817 // class auto_time
1819 inline
1820 auto_time::auto_time (timer t, const char *item_name)
1821 : m_timer (t),
1822 m_item_name (item_name)
1824 t.push (item_name);
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)
1832 m_timer.push (item_name);
1835 inline
1836 auto_time::~auto_time ()
1838 m_timer.pop (m_item_name);
1841 } // namespace gccjit
1843 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */