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 ());
491 lvalue
set_initializer (const void *blob
, size_t num_bytes
);
494 class param
: public lvalue
498 param (gcc_jit_param
*inner
);
500 gcc_jit_param
*get_inner_param () const;
503 class case_
: public object
507 case_ (gcc_jit_case
*inner
);
509 gcc_jit_case
*get_inner_case () const;
512 /* Overloaded operators, for those who want the most terse API
513 (at the possible risk of being a little too magical).
515 In each case, the first parameter is used to determine which context
516 owns the resulting expression, and, where appropriate, what the
519 /* Unary operators. */
520 rvalue
operator- (rvalue a
); // unary minus
521 rvalue
operator~ (rvalue a
); // unary bitwise negate
522 rvalue
operator! (rvalue a
); // unary logical negate
524 /* Binary operators. */
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
);
530 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
531 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
532 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
533 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
534 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
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
);
542 rvalue
operator>= (rvalue a
, rvalue b
);
545 lvalue
operator* (rvalue ptr
);
551 timer (gcc_jit_timer
*inner_timer
);
553 void push (const char *item_name
);
554 void pop (const char *item_name
);
555 void print (FILE *f_out
) const;
559 gcc_jit_timer
*get_inner_timer () const;
562 gcc_jit_timer
*m_inner_timer
;
568 auto_time (timer t
, const char *item_name
);
569 auto_time (context ctxt
, const char *item_name
);
574 const char *m_item_name
;
578 /****************************************************************************
579 Implementation of the API
580 ****************************************************************************/
584 inline context
context::acquire ()
586 return context (gcc_jit_context_acquire ());
588 inline context::context () : m_inner_ctxt (NULL
) {}
589 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
595 inline gccjit::context
596 context::new_child_context ()
598 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
604 gcc_jit_context_release (m_inner_ctxt
);
608 inline gcc_jit_result
*
611 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
618 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
619 const char *output_path
)
621 gcc_jit_context_compile_to_file (m_inner_ctxt
,
627 context::dump_to_file (const std::string
&path
,
628 bool update_locations
)
630 gcc_jit_context_dump_to_file (m_inner_ctxt
,
636 context::set_logfile (FILE *logfile
,
640 gcc_jit_context_set_logfile (m_inner_ctxt
,
647 context::dump_reproducer_to_file (const char *path
)
649 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
654 context::set_str_option (enum gcc_jit_str_option opt
,
657 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
662 context::set_int_option (enum gcc_jit_int_option opt
,
665 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
670 context::set_bool_option (enum gcc_jit_bool_option opt
,
673 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
677 context::set_bool_allow_unreachable_blocks (int bool_value
)
679 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
684 context::set_bool_use_external_driver (int bool_value
)
686 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
691 context::add_command_line_option (const char *optname
)
693 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
697 context::add_driver_option (const char *optname
)
699 gcc_jit_context_add_driver_option (m_inner_ctxt
, optname
);
703 context::set_timer (gccjit::timer t
)
705 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
709 context::get_timer () const
711 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
716 context::new_location (const std::string
&filename
,
720 return location (gcc_jit_context_new_location (m_inner_ctxt
,
727 context::get_type (enum gcc_jit_types kind
)
729 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
733 context::get_int_type (size_t num_bytes
, int is_signed
)
735 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
740 template <typename T
>
742 context::get_int_type ()
744 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
748 context::new_array_type (type element_type
, int num_elements
, location loc
)
750 return type (gcc_jit_context_new_array_type (
752 loc
.get_inner_location (),
753 element_type
.get_inner_type (),
758 context::new_field (type type_
, const std::string
&name
, location loc
)
760 return field (gcc_jit_context_new_field (m_inner_ctxt
,
761 loc
.get_inner_location (),
762 type_
.get_inner_type (),
767 context::new_bitfield (type type_
, int width
, const std::string
&name
,
770 return field (gcc_jit_context_new_bitfield (m_inner_ctxt
,
771 loc
.get_inner_location (),
772 type_
.get_inner_type (),
778 context::new_struct_type (const std::string
&name
,
779 std::vector
<field
> &fields
,
782 /* Treat std::vector as an array, relying on it not being resized: */
783 field
*as_array_of_wrappers
= &fields
[0];
785 /* Treat the array as being of the underlying pointers, relying on
786 the wrapper type being such a pointer internally. */
787 gcc_jit_field
**as_array_of_ptrs
=
788 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
790 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
791 loc
.get_inner_location (),
798 context::new_opaque_struct_type (const std::string
&name
,
801 return struct_ (gcc_jit_context_new_opaque_struct (
803 loc
.get_inner_location (),
808 context::new_param (type type_
,
809 const std::string
&name
,
812 return param (gcc_jit_context_new_param (m_inner_ctxt
,
813 loc
.get_inner_location (),
814 type_
.get_inner_type (),
819 context::new_function (enum gcc_jit_function_kind kind
,
821 const std::string
&name
,
822 std::vector
<param
> ¶ms
,
826 /* Treat std::vector as an array, relying on it not being resized: */
827 param
*as_array_of_wrappers
= ¶ms
[0];
829 /* Treat the array as being of the underlying pointers, relying on
830 the wrapper type being such a pointer internally. */
831 gcc_jit_param
**as_array_of_ptrs
=
832 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
834 return function (gcc_jit_context_new_function (m_inner_ctxt
,
835 loc
.get_inner_location (),
837 return_type
.get_inner_type (),
845 context::get_builtin_function (const std::string
&name
)
847 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
852 context::new_global (enum gcc_jit_global_kind kind
,
854 const std::string
&name
,
857 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
858 loc
.get_inner_location (),
860 type_
.get_inner_type (),
865 context::new_rvalue (type numeric_type
,
869 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
870 numeric_type
.get_inner_type (),
875 context::new_rvalue (type numeric_type
,
879 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
880 numeric_type
.get_inner_type (),
885 context::zero (type numeric_type
) const
887 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
888 numeric_type
.get_inner_type ()));
892 context::one (type numeric_type
) const
894 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
895 numeric_type
.get_inner_type ()));
899 context::new_rvalue (type numeric_type
,
903 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
904 numeric_type
.get_inner_type (),
909 context::new_rvalue (type pointer_type
,
913 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
914 pointer_type
.get_inner_type (),
919 context::new_rvalue (const std::string
&value
) const
922 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
926 context::new_rvalue (type vector_type
,
927 std::vector
<rvalue
> elements
) const
929 /* Treat std::vector as an array, relying on it not being resized: */
930 rvalue
*as_array_of_wrappers
= &elements
[0];
932 /* Treat the array as being of the underlying pointers, relying on
933 the wrapper type being such a pointer internally. */
934 gcc_jit_rvalue
**as_array_of_ptrs
=
935 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
938 gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt
,
940 vector_type
.get_inner_type (),
946 context::new_unary_op (enum gcc_jit_unary_op op
,
951 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
952 loc
.get_inner_location (),
954 result_type
.get_inner_type (),
955 a
.get_inner_rvalue ()));
958 context::new_minus (type result_type
,
962 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
963 result_type
, a
, loc
));
966 context::new_bitwise_negate (type result_type
,
970 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
971 result_type
, a
, loc
));
974 context::new_logical_negate (type result_type
,
978 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
979 result_type
, a
, loc
));
983 context::new_binary_op (enum gcc_jit_binary_op op
,
988 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
989 loc
.get_inner_location (),
991 result_type
.get_inner_type (),
992 a
.get_inner_rvalue (),
993 b
.get_inner_rvalue ()));
996 context::new_plus (type result_type
,
1000 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
1001 result_type
, a
, b
, loc
);
1004 context::new_minus (type result_type
,
1008 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
1009 result_type
, a
, b
, loc
);
1012 context::new_mult (type result_type
,
1016 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
1017 result_type
, a
, b
, loc
);
1020 context::new_divide (type result_type
,
1024 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
1025 result_type
, a
, b
, loc
);
1028 context::new_modulo (type result_type
,
1032 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
1033 result_type
, a
, b
, loc
);
1036 context::new_bitwise_and (type result_type
,
1040 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
1041 result_type
, a
, b
, loc
);
1044 context::new_bitwise_xor (type result_type
,
1048 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
1049 result_type
, a
, b
, loc
);
1052 context::new_bitwise_or (type result_type
,
1056 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1057 result_type
, a
, b
, loc
);
1060 context::new_logical_and (type result_type
,
1064 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1065 result_type
, a
, b
, loc
);
1068 context::new_logical_or (type result_type
,
1072 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1073 result_type
, a
, b
, loc
);
1077 context::new_comparison (enum gcc_jit_comparison op
,
1081 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1082 loc
.get_inner_location (),
1084 a
.get_inner_rvalue (),
1085 b
.get_inner_rvalue ()));
1088 context::new_eq (rvalue a
, rvalue b
,
1091 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1095 context::new_ne (rvalue a
, rvalue b
,
1098 return new_comparison (GCC_JIT_COMPARISON_NE
,
1102 context::new_lt (rvalue a
, rvalue b
,
1105 return new_comparison (GCC_JIT_COMPARISON_LT
,
1109 context::new_le (rvalue a
, rvalue b
,
1112 return new_comparison (GCC_JIT_COMPARISON_LE
,
1116 context::new_gt (rvalue a
, rvalue b
,
1119 return new_comparison (GCC_JIT_COMPARISON_GT
,
1123 context::new_ge (rvalue a
, rvalue b
,
1126 return new_comparison (GCC_JIT_COMPARISON_GE
,
1131 context::new_call (function func
,
1132 std::vector
<rvalue
> &args
,
1135 /* Treat std::vector as an array, relying on it not being resized: */
1136 rvalue
*as_array_of_wrappers
= &args
[0];
1138 /* Treat the array as being of the underlying pointers, relying on
1139 the wrapper type being such a pointer internally. */
1140 gcc_jit_rvalue
**as_array_of_ptrs
=
1141 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1142 return gcc_jit_context_new_call (m_inner_ctxt
,
1143 loc
.get_inner_location (),
1144 func
.get_inner_function (),
1149 context::new_call (function func
,
1152 std::vector
<rvalue
> args
;
1153 return new_call (func
, args
, loc
);
1157 context::new_call (function func
,
1161 std::vector
<rvalue
> args(1);
1163 return new_call (func
, args
, loc
);
1166 context::new_call (function func
,
1167 rvalue arg0
, rvalue arg1
,
1170 std::vector
<rvalue
> args(2);
1173 return new_call (func
, args
, loc
);
1176 context::new_call (function func
,
1177 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1180 std::vector
<rvalue
> args(3);
1184 return new_call (func
, args
, loc
);
1187 context::new_call (function func
,
1188 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1192 std::vector
<rvalue
> args(4);
1197 return new_call (func
, args
, loc
);
1200 context::new_call (function func
,
1201 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1202 rvalue arg3
, rvalue arg4
,
1205 std::vector
<rvalue
> args(5);
1211 return new_call (func
, args
, loc
);
1214 context::new_call (function func
,
1215 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1216 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1219 std::vector
<rvalue
> args(6);
1226 return new_call (func
, args
, loc
);
1230 context::new_cast (rvalue expr
,
1234 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1235 loc
.get_inner_location (),
1236 expr
.get_inner_rvalue (),
1237 type_
.get_inner_type ()));
1241 context::new_array_access (rvalue ptr
,
1245 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1246 loc
.get_inner_location (),
1247 ptr
.get_inner_rvalue (),
1248 index
.get_inner_rvalue ()));
1252 context::new_case (rvalue min_value
,
1256 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1257 min_value
.get_inner_rvalue (),
1258 max_value
.get_inner_rvalue (),
1259 dest_block
.get_inner_block ()));
1264 object::get_context () const
1266 return context (gcc_jit_object_get_context (m_inner_obj
));
1270 object::get_debug_string () const
1272 return gcc_jit_object_get_debug_string (m_inner_obj
);
1275 inline object::object () : m_inner_obj (NULL
) {}
1276 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1282 inline gcc_jit_object
*
1283 object::get_inner_object () const
1288 inline std::ostream
&
1289 operator << (std::ostream
& stream
, const object
&obj
)
1291 return stream
<< obj
.get_debug_string ();
1295 inline location::location () : object () {}
1296 inline location::location (gcc_jit_location
*loc
)
1297 : object (gcc_jit_location_as_object (loc
))
1300 inline gcc_jit_location
*
1301 location::get_inner_location () const
1303 /* Manual downcast: */
1304 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1308 inline field::field () : object () {}
1309 inline field::field (gcc_jit_field
*inner
)
1310 : object (gcc_jit_field_as_object (inner
))
1313 inline gcc_jit_field
*
1314 field::get_inner_field () const
1316 /* Manual downcast: */
1317 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1321 inline type::type () : object () {}
1322 inline type::type (gcc_jit_type
*inner
)
1323 : object (gcc_jit_type_as_object (inner
))
1326 inline gcc_jit_type
*
1327 type::get_inner_type () const
1329 /* Manual downcast: */
1330 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1334 type::get_pointer ()
1336 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1342 return type (gcc_jit_type_get_const (get_inner_type ()));
1346 type::get_volatile ()
1348 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1352 type::get_aligned (size_t alignment_in_bytes
)
1354 return type (gcc_jit_type_get_aligned (get_inner_type (),
1355 alignment_in_bytes
));
1359 type::get_vector (size_t num_units
)
1361 return type (gcc_jit_type_get_vector (get_inner_type (),
1368 return get_context ().new_rvalue (*this, 0);
1374 return get_context ().new_rvalue (*this, 1);
1378 inline struct_::struct_ () : type (NULL
) {}
1379 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1380 type (gcc_jit_struct_as_type (inner
))
1384 inline gcc_jit_struct
*
1385 struct_::get_inner_struct () const
1387 /* Manual downcast: */
1388 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1392 inline function::function () : object () {}
1393 inline function::function (gcc_jit_function
*inner
)
1394 : object (gcc_jit_function_as_object (inner
))
1397 inline gcc_jit_function
*
1398 function::get_inner_function () const
1400 /* Manual downcast: */
1401 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1405 function::dump_to_dot (const std::string
&path
)
1407 gcc_jit_function_dump_to_dot (get_inner_function (),
1412 function::get_param (int index
) const
1414 return param (gcc_jit_function_get_param (get_inner_function (),
1419 function::new_block ()
1421 return block (gcc_jit_function_new_block (get_inner_function (),
1426 function::new_block (const std::string
&name
)
1428 return block (gcc_jit_function_new_block (get_inner_function (),
1433 function::new_local (type type_
,
1434 const std::string
&name
,
1437 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1438 loc
.get_inner_location (),
1439 type_
.get_inner_type (),
1444 function::get_address (location loc
)
1446 return rvalue (gcc_jit_function_get_address (get_inner_function (),
1447 loc
.get_inner_location ()));
1451 block::get_function () const
1453 return function (gcc_jit_block_get_function ( get_inner_block ()));
1457 block::add_eval (rvalue rvalue
,
1460 gcc_jit_block_add_eval (get_inner_block (),
1461 loc
.get_inner_location (),
1462 rvalue
.get_inner_rvalue ());
1466 block::add_assignment (lvalue lvalue
,
1470 gcc_jit_block_add_assignment (get_inner_block (),
1471 loc
.get_inner_location (),
1472 lvalue
.get_inner_lvalue (),
1473 rvalue
.get_inner_rvalue ());
1477 block::add_assignment_op (lvalue lvalue
,
1478 enum gcc_jit_binary_op op
,
1482 gcc_jit_block_add_assignment_op (get_inner_block (),
1483 loc
.get_inner_location (),
1484 lvalue
.get_inner_lvalue (),
1486 rvalue
.get_inner_rvalue ());
1490 block::add_comment (const std::string
&text
,
1493 gcc_jit_block_add_comment (get_inner_block (),
1494 loc
.get_inner_location (),
1499 block::end_with_conditional (rvalue boolval
,
1504 gcc_jit_block_end_with_conditional (get_inner_block (),
1505 loc
.get_inner_location (),
1506 boolval
.get_inner_rvalue (),
1507 on_true
.get_inner_block (),
1508 on_false
.get_inner_block ());
1512 block::end_with_jump (block target
,
1515 gcc_jit_block_end_with_jump (get_inner_block (),
1516 loc
.get_inner_location (),
1517 target
.get_inner_block ());
1521 block::end_with_return (rvalue rvalue
,
1524 gcc_jit_block_end_with_return (get_inner_block (),
1525 loc
.get_inner_location (),
1526 rvalue
.get_inner_rvalue ());
1530 block::end_with_return (location loc
)
1532 gcc_jit_block_end_with_void_return (get_inner_block (),
1533 loc
.get_inner_location ());
1537 block::end_with_switch (rvalue expr
,
1538 block default_block
,
1539 std::vector
<case_
> cases
,
1542 /* Treat std::vector as an array, relying on it not being resized: */
1543 case_
*as_array_of_wrappers
= &cases
[0];
1545 /* Treat the array as being of the underlying pointers, relying on
1546 the wrapper type being such a pointer internally. */
1547 gcc_jit_case
**as_array_of_ptrs
=
1548 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1549 gcc_jit_block_end_with_switch (get_inner_block (),
1550 loc
.get_inner_location (),
1551 expr
.get_inner_rvalue (),
1552 default_block
.get_inner_block (),
1558 block::add_call (function other
,
1561 rvalue c
= get_context ().new_call (other
, loc
);
1566 block::add_call (function other
,
1570 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1575 block::add_call (function other
,
1576 rvalue arg0
, rvalue arg1
,
1579 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1584 block::add_call (function other
,
1585 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1588 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1594 block::add_call (function other
,
1595 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1598 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1604 function::operator() (location loc
)
1606 return get_context ().new_call (*this, loc
);
1609 function::operator() (rvalue arg0
,
1612 return get_context ().new_call (*this,
1617 function::operator() (rvalue arg0
, rvalue arg1
,
1620 return get_context ().new_call (*this,
1625 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1628 return get_context ().new_call (*this,
1634 inline block::block () : object () {}
1635 inline block::block (gcc_jit_block
*inner
)
1636 : object (gcc_jit_block_as_object (inner
))
1639 inline gcc_jit_block
*
1640 block::get_inner_block () const
1642 /* Manual downcast: */
1643 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1647 inline rvalue::rvalue () : object () {}
1648 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1649 : object (gcc_jit_rvalue_as_object (inner
))
1652 inline gcc_jit_rvalue
*
1653 rvalue::get_inner_rvalue () const
1655 /* Manual downcast: */
1656 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1662 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1666 rvalue::access_field (field field
,
1669 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1670 loc
.get_inner_location (),
1671 field
.get_inner_field ()));
1675 rvalue::dereference_field (field field
,
1678 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1679 loc
.get_inner_location (),
1680 field
.get_inner_field ()));
1684 rvalue::dereference (location loc
)
1686 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1687 loc
.get_inner_location ()));
1691 rvalue::cast_to (type type_
,
1694 return get_context ().new_cast (*this, type_
, loc
);
1698 rvalue::operator[] (rvalue index
)
1700 return get_context ().new_array_access (*this, index
);
1704 rvalue::operator[] (int index
)
1706 context ctxt
= get_context ();
1707 type int_t
= ctxt
.get_int_type
<int> ();
1708 return ctxt
.new_array_access (*this,
1709 ctxt
.new_rvalue (int_t
,
1713 // class lvalue : public rvalue
1714 inline lvalue::lvalue () : rvalue () {}
1715 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1716 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1719 inline gcc_jit_lvalue
*
1720 lvalue::get_inner_lvalue () const
1722 /* Manual downcast: */
1723 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1727 lvalue::access_field (field field
, location loc
)
1729 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1730 loc
.get_inner_location (),
1731 field
.get_inner_field ()));
1735 lvalue::get_address (location loc
)
1737 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1738 loc
.get_inner_location ()));
1742 lvalue::set_initializer (const void *blob
, size_t num_bytes
)
1744 gcc_jit_global_set_initializer (get_inner_lvalue (),
1750 // class param : public lvalue
1751 inline param::param () : lvalue () {}
1752 inline param::param (gcc_jit_param
*inner
)
1753 : lvalue (gcc_jit_param_as_lvalue (inner
))
1756 // class case_ : public object
1757 inline case_::case_ () : object () {}
1758 inline case_::case_ (gcc_jit_case
*inner
)
1759 : object (gcc_jit_case_as_object (inner
))
1763 inline gcc_jit_case
*
1764 case_::get_inner_case () const
1766 /* Manual downcast: */
1767 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1770 /* Overloaded operators. */
1772 inline rvalue
operator- (rvalue a
)
1774 return a
.get_context ().new_minus (a
.get_type (), a
);
1776 inline rvalue
operator~ (rvalue a
)
1778 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1780 inline rvalue
operator! (rvalue a
)
1782 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1786 inline rvalue
operator+ (rvalue a
, rvalue b
)
1788 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1790 inline rvalue
operator- (rvalue a
, rvalue b
)
1792 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1794 inline rvalue
operator* (rvalue a
, rvalue b
)
1796 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1798 inline rvalue
operator/ (rvalue a
, rvalue b
)
1800 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1802 inline rvalue
operator% (rvalue a
, rvalue b
)
1804 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1806 inline rvalue
operator& (rvalue a
, rvalue b
)
1808 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1810 inline rvalue
operator^ (rvalue a
, rvalue b
)
1812 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1814 inline rvalue
operator| (rvalue a
, rvalue b
)
1816 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1818 inline rvalue
operator&& (rvalue a
, rvalue b
)
1820 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1822 inline rvalue
operator|| (rvalue a
, rvalue b
)
1824 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1828 inline rvalue
operator== (rvalue a
, rvalue b
)
1830 return a
.get_context ().new_eq (a
, b
);
1832 inline rvalue
operator!= (rvalue a
, rvalue b
)
1834 return a
.get_context ().new_ne (a
, b
);
1836 inline rvalue
operator< (rvalue a
, rvalue b
)
1838 return a
.get_context ().new_lt (a
, b
);
1840 inline rvalue
operator<= (rvalue a
, rvalue b
)
1842 return a
.get_context ().new_le (a
, b
);
1844 inline rvalue
operator> (rvalue a
, rvalue b
)
1846 return a
.get_context ().new_gt (a
, b
);
1848 inline rvalue
operator>= (rvalue a
, rvalue b
)
1850 return a
.get_context ().new_ge (a
, b
);
1853 /* Dereferencing. */
1854 inline lvalue
operator* (rvalue ptr
)
1856 return ptr
.dereference ();
1863 m_inner_timer
= gcc_jit_timer_new ();
1867 timer::timer (gcc_jit_timer
*inner_timer
)
1869 m_inner_timer
= inner_timer
;
1873 timer::push (const char *item_name
)
1875 gcc_jit_timer_push (m_inner_timer
, item_name
);
1880 timer::pop (const char *item_name
)
1882 gcc_jit_timer_pop (m_inner_timer
, item_name
);
1886 timer::print (FILE *f_out
) const
1888 gcc_jit_timer_print (m_inner_timer
, f_out
);
1891 inline gcc_jit_timer
*
1892 timer::get_inner_timer () const
1894 return m_inner_timer
;
1900 gcc_jit_timer_release (m_inner_timer
);
1901 m_inner_timer
= NULL
;
1907 auto_time::auto_time (timer t
, const char *item_name
)
1909 m_item_name (item_name
)
1915 auto_time::auto_time (context ctxt
, const char *item_name
)
1916 : m_timer (ctxt
.get_timer ()),
1917 m_item_name (item_name
)
1919 m_timer
.push (item_name
);
1923 auto_time::~auto_time ()
1925 m_timer
.pop (m_item_name
);
1933 return gcc_jit_version_major ();
1939 return gcc_jit_version_minor ();
1945 return gcc_jit_version_patchlevel ();
1947 } // namespace version
1948 } // namespace gccjit
1950 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */