1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2020 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)
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"
29 /****************************************************************************
31 ****************************************************************************/
35 /* Indentation indicates inheritance. */
54 /* Errors within the API become C++ exceptions of this class. */
62 context
get_context () const;
64 std::string
get_debug_string () const;
68 object (gcc_jit_object
*obj
);
70 gcc_jit_object
*get_inner_object () const;
73 gcc_jit_object
*m_inner_obj
;
76 inline std::ostream
& operator << (std::ostream
& stream
, const object
&obj
);
78 /* Some client code will want to supply source code locations, others
79 won't. To avoid doubling the number of entrypoints, everything
80 accepting a location also has a default argument. To do this, the
81 other classes need to see that "location" has a default constructor,
82 hence we need to declare it first. */
83 class location
: public object
87 location (gcc_jit_location
*loc
);
89 gcc_jit_location
*get_inner_location () const;
95 static context
acquire ();
97 context (gcc_jit_context
*ctxt
);
99 gccjit::context
new_child_context ();
101 gcc_jit_context
*get_inner_context () { return m_inner_ctxt
; }
105 gcc_jit_result
*compile ();
107 void compile_to_file (enum gcc_jit_output_kind output_kind
,
108 const char *output_path
);
110 void dump_to_file (const std::string
&path
,
111 bool update_locations
);
113 void set_logfile (FILE *logfile
,
117 void dump_reproducer_to_file (const char *path
);
119 void set_str_option (enum gcc_jit_str_option opt
,
122 void set_int_option (enum gcc_jit_int_option opt
,
125 void set_bool_option (enum gcc_jit_bool_option opt
,
128 void set_bool_allow_unreachable_blocks (int bool_value
);
129 void set_bool_use_external_driver (int bool_value
);
131 void add_command_line_option (const char *optname
);
132 void add_driver_option (const char *optname
);
134 void set_timer (gccjit::timer t
);
135 gccjit::timer
get_timer () const;
138 new_location (const std::string
&filename
,
142 type
get_type (enum gcc_jit_types kind
);
143 type
get_int_type (size_t num_bytes
, int is_signed
);
145 /* A way to map a specific int type, using the compiler to
146 get the details automatically e.g.:
147 gccjit::type type = get_int_type <my_int_type_t> (); */
148 template <typename T
>
149 type
get_int_type ();
151 type
new_array_type (type element_type
, int num_elements
,
152 location loc
= location ());
154 field
new_field (type type_
, const std::string
&name
,
155 location loc
= location ());
157 field
new_bitfield (type type_
, int width
, const std::string
&name
,
158 location loc
= location ());
160 struct_
new_struct_type (const std::string
&name
,
161 std::vector
<field
> &fields
,
162 location loc
= location ());
164 struct_
new_opaque_struct_type (const std::string
&name
,
165 location loc
= location ());
167 param
new_param (type type_
,
168 const std::string
&name
,
169 location loc
= location ());
171 function
new_function (enum gcc_jit_function_kind kind
,
173 const std::string
&name
,
174 std::vector
<param
> ¶ms
,
176 location loc
= location ());
178 function
get_builtin_function (const std::string
&name
);
180 lvalue
new_global (enum gcc_jit_global_kind kind
,
182 const std::string
&name
,
183 location loc
= location ());
185 rvalue
new_rvalue (type numeric_type
,
187 rvalue
new_rvalue (type numeric_type
,
189 rvalue
zero (type numeric_type
) const;
190 rvalue
one (type numeric_type
) const;
191 rvalue
new_rvalue (type numeric_type
,
193 rvalue
new_rvalue (type pointer_type
,
195 rvalue
new_rvalue (const std::string
&value
) const;
196 rvalue
new_rvalue (type vector_type
,
197 std::vector
<rvalue
> elements
) const;
199 /* Generic unary operations... */
200 rvalue
new_unary_op (enum gcc_jit_unary_op op
,
203 location loc
= location ());
205 /* ...and shorter ways to spell the various specific kinds of
207 rvalue
new_minus (type result_type
,
209 location loc
= location ());
210 rvalue
new_bitwise_negate (type result_type
,
212 location loc
= location ());
213 rvalue
new_logical_negate (type result_type
,
215 location loc
= location ());
217 /* Generic binary operations... */
218 rvalue
new_binary_op (enum gcc_jit_binary_op op
,
221 location loc
= location ());
223 /* ...and shorter ways to spell the various specific kinds of
225 rvalue
new_plus (type result_type
,
227 location loc
= location ());
228 rvalue
new_minus (type result_type
,
230 location loc
= location ());
231 rvalue
new_mult (type result_type
,
233 location loc
= location ());
234 rvalue
new_divide (type result_type
,
236 location loc
= location ());
237 rvalue
new_modulo (type result_type
,
239 location loc
= location ());
240 rvalue
new_bitwise_and (type result_type
,
242 location loc
= location ());
243 rvalue
new_bitwise_xor (type result_type
,
245 location loc
= location ());
246 rvalue
new_bitwise_or (type result_type
,
248 location loc
= location ());
249 rvalue
new_logical_and (type result_type
,
251 location loc
= location ());
252 rvalue
new_logical_or (type result_type
,
254 location loc
= location ());
256 /* Generic comparisons... */
257 rvalue
new_comparison (enum gcc_jit_comparison op
,
259 location loc
= location ());
260 /* ...and shorter ways to spell the various specific kinds of
262 rvalue
new_eq (rvalue a
, rvalue b
,
263 location loc
= location ());
264 rvalue
new_ne (rvalue a
, rvalue b
,
265 location loc
= location ());
266 rvalue
new_lt (rvalue a
, rvalue b
,
267 location loc
= location ());
268 rvalue
new_le (rvalue a
, rvalue b
,
269 location loc
= location ());
270 rvalue
new_gt (rvalue a
, rvalue b
,
271 location loc
= location ());
272 rvalue
new_ge (rvalue a
, rvalue b
,
273 location loc
= location ());
275 /* The most general way of creating a function call. */
276 rvalue
new_call (function func
,
277 std::vector
<rvalue
> &args
,
278 location loc
= location ());
280 /* In addition, we provide a series of overloaded "new_call" methods
281 for specific numbers of args (from 0 - 6), to avoid the need for
282 client code to manually build a vector. */
283 rvalue
new_call (function func
,
284 location loc
= location ());
285 rvalue
new_call (function func
,
287 location loc
= location ());
288 rvalue
new_call (function func
,
289 rvalue arg0
, rvalue arg1
,
290 location loc
= location ());
291 rvalue
new_call (function func
,
292 rvalue arg0
, rvalue arg1
, rvalue arg2
,
293 location loc
= location ());
294 rvalue
new_call (function func
,
295 rvalue arg0
, rvalue arg1
, rvalue arg2
,
297 location loc
= location ());
298 rvalue
new_call (function func
,
299 rvalue arg0
, rvalue arg1
, rvalue arg2
,
300 rvalue arg3
, rvalue arg4
,
301 location loc
= location ());
302 rvalue
new_call (function func
,
303 rvalue arg0
, rvalue arg1
, rvalue arg2
,
304 rvalue arg3
, rvalue arg4
, rvalue arg5
,
305 location loc
= location ());
307 rvalue
new_cast (rvalue expr
,
309 location loc
= location ());
311 lvalue
new_array_access (rvalue ptr
,
313 location loc
= location ());
315 case_
new_case (rvalue min_value
,
320 gcc_jit_context
*m_inner_ctxt
;
323 class field
: public object
327 field (gcc_jit_field
*inner
);
329 gcc_jit_field
*get_inner_field () const;
332 class type
: public object
336 type (gcc_jit_type
*inner
);
338 gcc_jit_type
*get_inner_type () const;
342 type
get_volatile ();
343 type
get_aligned (size_t alignment_in_bytes
);
344 type
get_vector (size_t num_units
);
346 // Shortcuts for getting values of numeric types:
351 class struct_
: public type
355 struct_ (gcc_jit_struct
*inner
);
357 gcc_jit_struct
*get_inner_struct () const;
360 class function
: public object
364 function (gcc_jit_function
*func
);
366 gcc_jit_function
*get_inner_function () const;
368 void dump_to_dot (const std::string
&path
);
370 param
get_param (int index
) const;
373 block
new_block (const std::string
&name
);
375 lvalue
new_local (type type_
,
376 const std::string
&name
,
377 location loc
= location ());
379 rvalue
get_address (location loc
= location ());
381 /* A series of overloaded operator () with various numbers of arguments
382 for a very terse way of creating a call to this function. The call
383 is created within the same context as the function itself, which may
384 not be what you want. */
385 rvalue
operator() (location loc
= location ());
386 rvalue
operator() (rvalue arg0
,
387 location loc
= location ());
388 rvalue
operator() (rvalue arg0
, rvalue arg1
,
389 location loc
= location ());
390 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
391 location loc
= location ());
394 class block
: public object
398 block (gcc_jit_block
*inner
);
400 gcc_jit_block
*get_inner_block () const;
402 function
get_function () const;
404 void add_eval (rvalue rvalue
,
405 location loc
= location ());
407 void add_assignment (lvalue lvalue
,
409 location loc
= location ());
411 void add_assignment_op (lvalue lvalue
,
412 enum gcc_jit_binary_op op
,
414 location loc
= location ());
416 /* A way to add a function call to the body of a function being
417 defined, with various numbers of args. */
418 rvalue
add_call (function other
,
419 location loc
= location ());
420 rvalue
add_call (function other
,
422 location loc
= location ());
423 rvalue
add_call (function other
,
424 rvalue arg0
, rvalue arg1
,
425 location loc
= location ());
426 rvalue
add_call (function other
,
427 rvalue arg0
, rvalue arg1
, rvalue arg2
,
428 location loc
= location ());
429 rvalue
add_call (function other
,
430 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
431 location loc
= location ());
433 void add_comment (const std::string
&text
,
434 location loc
= location ());
436 void end_with_conditional (rvalue boolval
,
439 location loc
= location ());
441 void end_with_jump (block target
,
442 location loc
= location ());
444 void end_with_return (rvalue rvalue
,
445 location loc
= location ());
446 void end_with_return (location loc
= location ());
448 void end_with_switch (rvalue expr
,
450 std::vector
<case_
> cases
,
451 location loc
= location ());
454 class rvalue
: public object
458 rvalue (gcc_jit_rvalue
*inner
);
459 gcc_jit_rvalue
*get_inner_rvalue () const;
463 rvalue
access_field (field field
,
464 location loc
= location ());
466 lvalue
dereference_field (field field
,
467 location loc
= location ());
469 lvalue
dereference (location loc
= location ());
471 rvalue
cast_to (type type_
,
472 location loc
= location ());
475 lvalue
operator[] (rvalue index
);
476 lvalue
operator[] (int index
);
479 class lvalue
: public rvalue
483 lvalue (gcc_jit_lvalue
*inner
);
485 gcc_jit_lvalue
*get_inner_lvalue () const;
487 lvalue
access_field (field field
,
488 location loc
= location ());
490 rvalue
get_address (location loc
= location ());
493 class param
: public lvalue
497 param (gcc_jit_param
*inner
);
499 gcc_jit_param
*get_inner_param () const;
502 class case_
: public object
506 case_ (gcc_jit_case
*inner
);
508 gcc_jit_case
*get_inner_case () const;
511 /* Overloaded operators, for those who want the most terse API
512 (at the possible risk of being a little too magical).
514 In each case, the first parameter is used to determine which context
515 owns the resulting expression, and, where appropriate, what the
518 /* Unary operators. */
519 rvalue
operator- (rvalue a
); // unary minus
520 rvalue
operator~ (rvalue a
); // unary bitwise negate
521 rvalue
operator! (rvalue a
); // unary logical negate
523 /* Binary operators. */
524 rvalue
operator+ (rvalue a
, rvalue b
);
525 rvalue
operator- (rvalue a
, rvalue b
);
526 rvalue
operator* (rvalue a
, rvalue b
);
527 rvalue
operator/ (rvalue a
, rvalue b
);
528 rvalue
operator% (rvalue a
, rvalue b
);
529 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
530 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
531 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
532 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
533 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
536 rvalue
operator== (rvalue a
, rvalue b
);
537 rvalue
operator!= (rvalue a
, rvalue b
);
538 rvalue
operator< (rvalue a
, rvalue b
);
539 rvalue
operator<= (rvalue a
, rvalue b
);
540 rvalue
operator> (rvalue a
, rvalue b
);
541 rvalue
operator>= (rvalue a
, rvalue b
);
544 lvalue
operator* (rvalue ptr
);
550 timer (gcc_jit_timer
*inner_timer
);
552 void push (const char *item_name
);
553 void pop (const char *item_name
);
554 void print (FILE *f_out
) const;
558 gcc_jit_timer
*get_inner_timer () const;
561 gcc_jit_timer
*m_inner_timer
;
567 auto_time (timer t
, const char *item_name
);
568 auto_time (context ctxt
, const char *item_name
);
573 const char *m_item_name
;
577 /****************************************************************************
578 Implementation of the API
579 ****************************************************************************/
583 inline context
context::acquire ()
585 return context (gcc_jit_context_acquire ());
587 inline context::context () : m_inner_ctxt (NULL
) {}
588 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
594 inline gccjit::context
595 context::new_child_context ()
597 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
603 gcc_jit_context_release (m_inner_ctxt
);
607 inline gcc_jit_result
*
610 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
617 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
618 const char *output_path
)
620 gcc_jit_context_compile_to_file (m_inner_ctxt
,
626 context::dump_to_file (const std::string
&path
,
627 bool update_locations
)
629 gcc_jit_context_dump_to_file (m_inner_ctxt
,
635 context::set_logfile (FILE *logfile
,
639 gcc_jit_context_set_logfile (m_inner_ctxt
,
646 context::dump_reproducer_to_file (const char *path
)
648 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
653 context::set_str_option (enum gcc_jit_str_option opt
,
656 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
661 context::set_int_option (enum gcc_jit_int_option opt
,
664 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
669 context::set_bool_option (enum gcc_jit_bool_option opt
,
672 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
676 context::set_bool_allow_unreachable_blocks (int bool_value
)
678 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
683 context::set_bool_use_external_driver (int bool_value
)
685 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
690 context::add_command_line_option (const char *optname
)
692 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
696 context::add_driver_option (const char *optname
)
698 gcc_jit_context_add_driver_option (m_inner_ctxt
, optname
);
702 context::set_timer (gccjit::timer t
)
704 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
708 context::get_timer () const
710 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
715 context::new_location (const std::string
&filename
,
719 return location (gcc_jit_context_new_location (m_inner_ctxt
,
726 context::get_type (enum gcc_jit_types kind
)
728 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
732 context::get_int_type (size_t num_bytes
, int is_signed
)
734 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
739 template <typename T
>
741 context::get_int_type ()
743 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
747 context::new_array_type (type element_type
, int num_elements
, location loc
)
749 return type (gcc_jit_context_new_array_type (
751 loc
.get_inner_location (),
752 element_type
.get_inner_type (),
757 context::new_field (type type_
, const std::string
&name
, location loc
)
759 return field (gcc_jit_context_new_field (m_inner_ctxt
,
760 loc
.get_inner_location (),
761 type_
.get_inner_type (),
766 context::new_bitfield (type type_
, int width
, const std::string
&name
,
769 return field (gcc_jit_context_new_bitfield (m_inner_ctxt
,
770 loc
.get_inner_location (),
771 type_
.get_inner_type (),
777 context::new_struct_type (const std::string
&name
,
778 std::vector
<field
> &fields
,
781 /* Treat std::vector as an array, relying on it not being resized: */
782 field
*as_array_of_wrappers
= &fields
[0];
784 /* Treat the array as being of the underlying pointers, relying on
785 the wrapper type being such a pointer internally. */
786 gcc_jit_field
**as_array_of_ptrs
=
787 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
789 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
790 loc
.get_inner_location (),
797 context::new_opaque_struct_type (const std::string
&name
,
800 return struct_ (gcc_jit_context_new_opaque_struct (
802 loc
.get_inner_location (),
807 context::new_param (type type_
,
808 const std::string
&name
,
811 return param (gcc_jit_context_new_param (m_inner_ctxt
,
812 loc
.get_inner_location (),
813 type_
.get_inner_type (),
818 context::new_function (enum gcc_jit_function_kind kind
,
820 const std::string
&name
,
821 std::vector
<param
> ¶ms
,
825 /* Treat std::vector as an array, relying on it not being resized: */
826 param
*as_array_of_wrappers
= ¶ms
[0];
828 /* Treat the array as being of the underlying pointers, relying on
829 the wrapper type being such a pointer internally. */
830 gcc_jit_param
**as_array_of_ptrs
=
831 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
833 return function (gcc_jit_context_new_function (m_inner_ctxt
,
834 loc
.get_inner_location (),
836 return_type
.get_inner_type (),
844 context::get_builtin_function (const std::string
&name
)
846 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
851 context::new_global (enum gcc_jit_global_kind kind
,
853 const std::string
&name
,
856 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
857 loc
.get_inner_location (),
859 type_
.get_inner_type (),
864 context::new_rvalue (type numeric_type
,
868 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
869 numeric_type
.get_inner_type (),
874 context::new_rvalue (type numeric_type
,
878 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
879 numeric_type
.get_inner_type (),
884 context::zero (type numeric_type
) const
886 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
887 numeric_type
.get_inner_type ()));
891 context::one (type numeric_type
) const
893 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
894 numeric_type
.get_inner_type ()));
898 context::new_rvalue (type numeric_type
,
902 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
903 numeric_type
.get_inner_type (),
908 context::new_rvalue (type pointer_type
,
912 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
913 pointer_type
.get_inner_type (),
918 context::new_rvalue (const std::string
&value
) const
921 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
925 context::new_rvalue (type vector_type
,
926 std::vector
<rvalue
> elements
) const
928 /* Treat std::vector as an array, relying on it not being resized: */
929 rvalue
*as_array_of_wrappers
= &elements
[0];
931 /* Treat the array as being of the underlying pointers, relying on
932 the wrapper type being such a pointer internally. */
933 gcc_jit_rvalue
**as_array_of_ptrs
=
934 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
937 gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt
,
939 vector_type
.get_inner_type (),
945 context::new_unary_op (enum gcc_jit_unary_op op
,
950 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
951 loc
.get_inner_location (),
953 result_type
.get_inner_type (),
954 a
.get_inner_rvalue ()));
957 context::new_minus (type result_type
,
961 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
962 result_type
, a
, loc
));
965 context::new_bitwise_negate (type result_type
,
969 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
970 result_type
, a
, loc
));
973 context::new_logical_negate (type result_type
,
977 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
978 result_type
, a
, loc
));
982 context::new_binary_op (enum gcc_jit_binary_op op
,
987 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
988 loc
.get_inner_location (),
990 result_type
.get_inner_type (),
991 a
.get_inner_rvalue (),
992 b
.get_inner_rvalue ()));
995 context::new_plus (type result_type
,
999 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
1000 result_type
, a
, b
, loc
);
1003 context::new_minus (type result_type
,
1007 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
1008 result_type
, a
, b
, loc
);
1011 context::new_mult (type result_type
,
1015 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
1016 result_type
, a
, b
, loc
);
1019 context::new_divide (type result_type
,
1023 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
1024 result_type
, a
, b
, loc
);
1027 context::new_modulo (type result_type
,
1031 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
1032 result_type
, a
, b
, loc
);
1035 context::new_bitwise_and (type result_type
,
1039 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
1040 result_type
, a
, b
, loc
);
1043 context::new_bitwise_xor (type result_type
,
1047 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
1048 result_type
, a
, b
, loc
);
1051 context::new_bitwise_or (type result_type
,
1055 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1056 result_type
, a
, b
, loc
);
1059 context::new_logical_and (type result_type
,
1063 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1064 result_type
, a
, b
, loc
);
1067 context::new_logical_or (type result_type
,
1071 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1072 result_type
, a
, b
, loc
);
1076 context::new_comparison (enum gcc_jit_comparison op
,
1080 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1081 loc
.get_inner_location (),
1083 a
.get_inner_rvalue (),
1084 b
.get_inner_rvalue ()));
1087 context::new_eq (rvalue a
, rvalue b
,
1090 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1094 context::new_ne (rvalue a
, rvalue b
,
1097 return new_comparison (GCC_JIT_COMPARISON_NE
,
1101 context::new_lt (rvalue a
, rvalue b
,
1104 return new_comparison (GCC_JIT_COMPARISON_LT
,
1108 context::new_le (rvalue a
, rvalue b
,
1111 return new_comparison (GCC_JIT_COMPARISON_LE
,
1115 context::new_gt (rvalue a
, rvalue b
,
1118 return new_comparison (GCC_JIT_COMPARISON_GT
,
1122 context::new_ge (rvalue a
, rvalue b
,
1125 return new_comparison (GCC_JIT_COMPARISON_GE
,
1130 context::new_call (function func
,
1131 std::vector
<rvalue
> &args
,
1134 /* Treat std::vector as an array, relying on it not being resized: */
1135 rvalue
*as_array_of_wrappers
= &args
[0];
1137 /* Treat the array as being of the underlying pointers, relying on
1138 the wrapper type being such a pointer internally. */
1139 gcc_jit_rvalue
**as_array_of_ptrs
=
1140 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1141 return gcc_jit_context_new_call (m_inner_ctxt
,
1142 loc
.get_inner_location (),
1143 func
.get_inner_function (),
1148 context::new_call (function func
,
1151 std::vector
<rvalue
> args
;
1152 return new_call (func
, args
, loc
);
1156 context::new_call (function func
,
1160 std::vector
<rvalue
> args(1);
1162 return new_call (func
, args
, loc
);
1165 context::new_call (function func
,
1166 rvalue arg0
, rvalue arg1
,
1169 std::vector
<rvalue
> args(2);
1172 return new_call (func
, args
, loc
);
1175 context::new_call (function func
,
1176 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1179 std::vector
<rvalue
> args(3);
1183 return new_call (func
, args
, loc
);
1186 context::new_call (function func
,
1187 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1191 std::vector
<rvalue
> args(4);
1196 return new_call (func
, args
, loc
);
1199 context::new_call (function func
,
1200 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1201 rvalue arg3
, rvalue arg4
,
1204 std::vector
<rvalue
> args(5);
1210 return new_call (func
, args
, loc
);
1213 context::new_call (function func
,
1214 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1215 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1218 std::vector
<rvalue
> args(6);
1225 return new_call (func
, args
, loc
);
1229 context::new_cast (rvalue expr
,
1233 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1234 loc
.get_inner_location (),
1235 expr
.get_inner_rvalue (),
1236 type_
.get_inner_type ()));
1240 context::new_array_access (rvalue ptr
,
1244 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1245 loc
.get_inner_location (),
1246 ptr
.get_inner_rvalue (),
1247 index
.get_inner_rvalue ()));
1251 context::new_case (rvalue min_value
,
1255 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1256 min_value
.get_inner_rvalue (),
1257 max_value
.get_inner_rvalue (),
1258 dest_block
.get_inner_block ()));
1263 object::get_context () const
1265 return context (gcc_jit_object_get_context (m_inner_obj
));
1269 object::get_debug_string () const
1271 return gcc_jit_object_get_debug_string (m_inner_obj
);
1274 inline object::object () : m_inner_obj (NULL
) {}
1275 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1281 inline gcc_jit_object
*
1282 object::get_inner_object () const
1287 inline std::ostream
&
1288 operator << (std::ostream
& stream
, const object
&obj
)
1290 return stream
<< obj
.get_debug_string ();
1294 inline location::location () : object () {}
1295 inline location::location (gcc_jit_location
*loc
)
1296 : object (gcc_jit_location_as_object (loc
))
1299 inline gcc_jit_location
*
1300 location::get_inner_location () const
1302 /* Manual downcast: */
1303 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1307 inline field::field () : object () {}
1308 inline field::field (gcc_jit_field
*inner
)
1309 : object (gcc_jit_field_as_object (inner
))
1312 inline gcc_jit_field
*
1313 field::get_inner_field () const
1315 /* Manual downcast: */
1316 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1320 inline type::type () : object () {}
1321 inline type::type (gcc_jit_type
*inner
)
1322 : object (gcc_jit_type_as_object (inner
))
1325 inline gcc_jit_type
*
1326 type::get_inner_type () const
1328 /* Manual downcast: */
1329 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1333 type::get_pointer ()
1335 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1341 return type (gcc_jit_type_get_const (get_inner_type ()));
1345 type::get_volatile ()
1347 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1351 type::get_aligned (size_t alignment_in_bytes
)
1353 return type (gcc_jit_type_get_aligned (get_inner_type (),
1354 alignment_in_bytes
));
1358 type::get_vector (size_t num_units
)
1360 return type (gcc_jit_type_get_vector (get_inner_type (),
1367 return get_context ().new_rvalue (*this, 0);
1373 return get_context ().new_rvalue (*this, 1);
1377 inline struct_::struct_ () : type (NULL
) {}
1378 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1379 type (gcc_jit_struct_as_type (inner
))
1383 inline gcc_jit_struct
*
1384 struct_::get_inner_struct () const
1386 /* Manual downcast: */
1387 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1391 inline function::function () : object () {}
1392 inline function::function (gcc_jit_function
*inner
)
1393 : object (gcc_jit_function_as_object (inner
))
1396 inline gcc_jit_function
*
1397 function::get_inner_function () const
1399 /* Manual downcast: */
1400 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1404 function::dump_to_dot (const std::string
&path
)
1406 gcc_jit_function_dump_to_dot (get_inner_function (),
1411 function::get_param (int index
) const
1413 return param (gcc_jit_function_get_param (get_inner_function (),
1418 function::new_block ()
1420 return block (gcc_jit_function_new_block (get_inner_function (),
1425 function::new_block (const std::string
&name
)
1427 return block (gcc_jit_function_new_block (get_inner_function (),
1432 function::new_local (type type_
,
1433 const std::string
&name
,
1436 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1437 loc
.get_inner_location (),
1438 type_
.get_inner_type (),
1443 function::get_address (location loc
)
1445 return rvalue (gcc_jit_function_get_address (get_inner_function (),
1446 loc
.get_inner_location ()));
1450 block::get_function () const
1452 return function (gcc_jit_block_get_function ( get_inner_block ()));
1456 block::add_eval (rvalue rvalue
,
1459 gcc_jit_block_add_eval (get_inner_block (),
1460 loc
.get_inner_location (),
1461 rvalue
.get_inner_rvalue ());
1465 block::add_assignment (lvalue lvalue
,
1469 gcc_jit_block_add_assignment (get_inner_block (),
1470 loc
.get_inner_location (),
1471 lvalue
.get_inner_lvalue (),
1472 rvalue
.get_inner_rvalue ());
1476 block::add_assignment_op (lvalue lvalue
,
1477 enum gcc_jit_binary_op op
,
1481 gcc_jit_block_add_assignment_op (get_inner_block (),
1482 loc
.get_inner_location (),
1483 lvalue
.get_inner_lvalue (),
1485 rvalue
.get_inner_rvalue ());
1489 block::add_comment (const std::string
&text
,
1492 gcc_jit_block_add_comment (get_inner_block (),
1493 loc
.get_inner_location (),
1498 block::end_with_conditional (rvalue boolval
,
1503 gcc_jit_block_end_with_conditional (get_inner_block (),
1504 loc
.get_inner_location (),
1505 boolval
.get_inner_rvalue (),
1506 on_true
.get_inner_block (),
1507 on_false
.get_inner_block ());
1511 block::end_with_jump (block target
,
1514 gcc_jit_block_end_with_jump (get_inner_block (),
1515 loc
.get_inner_location (),
1516 target
.get_inner_block ());
1520 block::end_with_return (rvalue rvalue
,
1523 gcc_jit_block_end_with_return (get_inner_block (),
1524 loc
.get_inner_location (),
1525 rvalue
.get_inner_rvalue ());
1529 block::end_with_return (location loc
)
1531 gcc_jit_block_end_with_void_return (get_inner_block (),
1532 loc
.get_inner_location ());
1536 block::end_with_switch (rvalue expr
,
1537 block default_block
,
1538 std::vector
<case_
> cases
,
1541 /* Treat std::vector as an array, relying on it not being resized: */
1542 case_
*as_array_of_wrappers
= &cases
[0];
1544 /* Treat the array as being of the underlying pointers, relying on
1545 the wrapper type being such a pointer internally. */
1546 gcc_jit_case
**as_array_of_ptrs
=
1547 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1548 gcc_jit_block_end_with_switch (get_inner_block (),
1549 loc
.get_inner_location (),
1550 expr
.get_inner_rvalue (),
1551 default_block
.get_inner_block (),
1557 block::add_call (function other
,
1560 rvalue c
= get_context ().new_call (other
, loc
);
1565 block::add_call (function other
,
1569 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1574 block::add_call (function other
,
1575 rvalue arg0
, rvalue arg1
,
1578 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1583 block::add_call (function other
,
1584 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1587 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1593 block::add_call (function other
,
1594 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1597 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1603 function::operator() (location loc
)
1605 return get_context ().new_call (*this, loc
);
1608 function::operator() (rvalue arg0
,
1611 return get_context ().new_call (*this,
1616 function::operator() (rvalue arg0
, rvalue arg1
,
1619 return get_context ().new_call (*this,
1624 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1627 return get_context ().new_call (*this,
1633 inline block::block () : object () {}
1634 inline block::block (gcc_jit_block
*inner
)
1635 : object (gcc_jit_block_as_object (inner
))
1638 inline gcc_jit_block
*
1639 block::get_inner_block () const
1641 /* Manual downcast: */
1642 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1646 inline rvalue::rvalue () : object () {}
1647 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1648 : object (gcc_jit_rvalue_as_object (inner
))
1651 inline gcc_jit_rvalue
*
1652 rvalue::get_inner_rvalue () const
1654 /* Manual downcast: */
1655 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1661 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1665 rvalue::access_field (field field
,
1668 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1669 loc
.get_inner_location (),
1670 field
.get_inner_field ()));
1674 rvalue::dereference_field (field field
,
1677 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1678 loc
.get_inner_location (),
1679 field
.get_inner_field ()));
1683 rvalue::dereference (location loc
)
1685 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1686 loc
.get_inner_location ()));
1690 rvalue::cast_to (type type_
,
1693 return get_context ().new_cast (*this, type_
, loc
);
1697 rvalue::operator[] (rvalue index
)
1699 return get_context ().new_array_access (*this, index
);
1703 rvalue::operator[] (int index
)
1705 context ctxt
= get_context ();
1706 type int_t
= ctxt
.get_int_type
<int> ();
1707 return ctxt
.new_array_access (*this,
1708 ctxt
.new_rvalue (int_t
,
1712 // class lvalue : public rvalue
1713 inline lvalue::lvalue () : rvalue () {}
1714 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1715 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1718 inline gcc_jit_lvalue
*
1719 lvalue::get_inner_lvalue () const
1721 /* Manual downcast: */
1722 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1726 lvalue::access_field (field field
, location loc
)
1728 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1729 loc
.get_inner_location (),
1730 field
.get_inner_field ()));
1734 lvalue::get_address (location loc
)
1736 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1737 loc
.get_inner_location ()));
1740 // class param : public lvalue
1741 inline param::param () : lvalue () {}
1742 inline param::param (gcc_jit_param
*inner
)
1743 : lvalue (gcc_jit_param_as_lvalue (inner
))
1746 // class case_ : public object
1747 inline case_::case_ () : object () {}
1748 inline case_::case_ (gcc_jit_case
*inner
)
1749 : object (gcc_jit_case_as_object (inner
))
1753 inline gcc_jit_case
*
1754 case_::get_inner_case () const
1756 /* Manual downcast: */
1757 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1760 /* Overloaded operators. */
1762 inline rvalue
operator- (rvalue a
)
1764 return a
.get_context ().new_minus (a
.get_type (), a
);
1766 inline rvalue
operator~ (rvalue a
)
1768 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1770 inline rvalue
operator! (rvalue a
)
1772 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1776 inline rvalue
operator+ (rvalue a
, rvalue b
)
1778 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1780 inline rvalue
operator- (rvalue a
, rvalue b
)
1782 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1784 inline rvalue
operator* (rvalue a
, rvalue b
)
1786 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1788 inline rvalue
operator/ (rvalue a
, rvalue b
)
1790 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1792 inline rvalue
operator% (rvalue a
, rvalue b
)
1794 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1796 inline rvalue
operator& (rvalue a
, rvalue b
)
1798 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1800 inline rvalue
operator^ (rvalue a
, rvalue b
)
1802 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1804 inline rvalue
operator| (rvalue a
, rvalue b
)
1806 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1808 inline rvalue
operator&& (rvalue a
, rvalue b
)
1810 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1812 inline rvalue
operator|| (rvalue a
, rvalue b
)
1814 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1818 inline rvalue
operator== (rvalue a
, rvalue b
)
1820 return a
.get_context ().new_eq (a
, b
);
1822 inline rvalue
operator!= (rvalue a
, rvalue b
)
1824 return a
.get_context ().new_ne (a
, b
);
1826 inline rvalue
operator< (rvalue a
, rvalue b
)
1828 return a
.get_context ().new_lt (a
, b
);
1830 inline rvalue
operator<= (rvalue a
, rvalue b
)
1832 return a
.get_context ().new_le (a
, b
);
1834 inline rvalue
operator> (rvalue a
, rvalue b
)
1836 return a
.get_context ().new_gt (a
, b
);
1838 inline rvalue
operator>= (rvalue a
, rvalue b
)
1840 return a
.get_context ().new_ge (a
, b
);
1843 /* Dereferencing. */
1844 inline lvalue
operator* (rvalue ptr
)
1846 return ptr
.dereference ();
1853 m_inner_timer
= gcc_jit_timer_new ();
1857 timer::timer (gcc_jit_timer
*inner_timer
)
1859 m_inner_timer
= inner_timer
;
1863 timer::push (const char *item_name
)
1865 gcc_jit_timer_push (m_inner_timer
, item_name
);
1870 timer::pop (const char *item_name
)
1872 gcc_jit_timer_pop (m_inner_timer
, item_name
);
1876 timer::print (FILE *f_out
) const
1878 gcc_jit_timer_print (m_inner_timer
, f_out
);
1881 inline gcc_jit_timer
*
1882 timer::get_inner_timer () const
1884 return m_inner_timer
;
1890 gcc_jit_timer_release (m_inner_timer
);
1891 m_inner_timer
= NULL
;
1897 auto_time::auto_time (timer t
, const char *item_name
)
1899 m_item_name (item_name
)
1905 auto_time::auto_time (context ctxt
, const char *item_name
)
1906 : m_timer (ctxt
.get_timer ()),
1907 m_item_name (item_name
)
1909 m_timer
.push (item_name
);
1913 auto_time::~auto_time ()
1915 m_timer
.pop (m_item_name
);
1923 return gcc_jit_version_major ();
1929 return gcc_jit_version_minor ();
1935 return gcc_jit_version_patchlevel ();
1937 } // namespace version
1938 } // namespace gccjit
1940 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */