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)
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. */
52 /* Errors within the API become C++ exceptions of this class. */
60 context
get_context () const;
62 std::string
get_debug_string () const;
66 object (gcc_jit_object
*obj
);
68 gcc_jit_object
*get_inner_object () const;
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
85 location (gcc_jit_location
*loc
);
87 gcc_jit_location
*get_inner_location () const;
93 static context
acquire ();
95 context (gcc_jit_context
*ctxt
);
97 gccjit::context
new_child_context ();
99 gcc_jit_context
*get_inner_context () { return m_inner_ctxt
; }
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
,
115 void dump_reproducer_to_file (const char *path
);
117 void set_str_option (enum gcc_jit_str_option opt
,
120 void set_int_option (enum gcc_jit_int_option opt
,
123 void set_bool_option (enum gcc_jit_bool_option opt
,
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;
135 new_location (const std::string
&filename
,
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
,
167 const std::string
&name
,
168 std::vector
<param
> ¶ms
,
170 location loc
= location ());
172 function
get_builtin_function (const std::string
&name
);
174 lvalue
new_global (enum gcc_jit_global_kind kind
,
176 const std::string
&name
,
177 location loc
= location ());
179 rvalue
new_rvalue (type numeric_type
,
181 rvalue
new_rvalue (type numeric_type
,
183 rvalue
zero (type numeric_type
) const;
184 rvalue
one (type numeric_type
) const;
185 rvalue
new_rvalue (type numeric_type
,
187 rvalue
new_rvalue (type pointer_type
,
189 rvalue
new_rvalue (const std::string
&value
) const;
190 rvalue
new_rvalue (type vector_type
,
191 std::vector
<rvalue
> elements
) const;
193 /* Generic unary operations... */
194 rvalue
new_unary_op (enum gcc_jit_unary_op op
,
197 location loc
= location ());
199 /* ...and shorter ways to spell the various specific kinds of
201 rvalue
new_minus (type result_type
,
203 location loc
= location ());
204 rvalue
new_bitwise_negate (type result_type
,
206 location loc
= location ());
207 rvalue
new_logical_negate (type result_type
,
209 location loc
= location ());
211 /* Generic binary operations... */
212 rvalue
new_binary_op (enum gcc_jit_binary_op op
,
215 location loc
= location ());
217 /* ...and shorter ways to spell the various specific kinds of
219 rvalue
new_plus (type result_type
,
221 location loc
= location ());
222 rvalue
new_minus (type result_type
,
224 location loc
= location ());
225 rvalue
new_mult (type result_type
,
227 location loc
= location ());
228 rvalue
new_divide (type result_type
,
230 location loc
= location ());
231 rvalue
new_modulo (type result_type
,
233 location loc
= location ());
234 rvalue
new_bitwise_and (type result_type
,
236 location loc
= location ());
237 rvalue
new_bitwise_xor (type result_type
,
239 location loc
= location ());
240 rvalue
new_bitwise_or (type result_type
,
242 location loc
= location ());
243 rvalue
new_logical_and (type result_type
,
245 location loc
= location ());
246 rvalue
new_logical_or (type result_type
,
248 location loc
= location ());
250 /* Generic comparisons... */
251 rvalue
new_comparison (enum gcc_jit_comparison op
,
253 location loc
= location ());
254 /* ...and shorter ways to spell the various specific kinds of
256 rvalue
new_eq (rvalue a
, rvalue b
,
257 location loc
= location ());
258 rvalue
new_ne (rvalue a
, rvalue b
,
259 location loc
= location ());
260 rvalue
new_lt (rvalue a
, rvalue b
,
261 location loc
= location ());
262 rvalue
new_le (rvalue a
, rvalue b
,
263 location loc
= location ());
264 rvalue
new_gt (rvalue a
, rvalue b
,
265 location loc
= location ());
266 rvalue
new_ge (rvalue a
, rvalue b
,
267 location loc
= location ());
269 /* The most general way of creating a function call. */
270 rvalue
new_call (function func
,
271 std::vector
<rvalue
> &args
,
272 location loc
= location ());
274 /* In addition, we provide a series of overloaded "new_call" methods
275 for specific numbers of args (from 0 - 6), to avoid the need for
276 client code to manually build a vector. */
277 rvalue
new_call (function func
,
278 location loc
= location ());
279 rvalue
new_call (function func
,
281 location loc
= location ());
282 rvalue
new_call (function func
,
283 rvalue arg0
, rvalue arg1
,
284 location loc
= location ());
285 rvalue
new_call (function func
,
286 rvalue arg0
, rvalue arg1
, rvalue arg2
,
287 location loc
= location ());
288 rvalue
new_call (function func
,
289 rvalue arg0
, rvalue arg1
, rvalue arg2
,
291 location loc
= location ());
292 rvalue
new_call (function func
,
293 rvalue arg0
, rvalue arg1
, rvalue arg2
,
294 rvalue arg3
, rvalue arg4
,
295 location loc
= location ());
296 rvalue
new_call (function func
,
297 rvalue arg0
, rvalue arg1
, rvalue arg2
,
298 rvalue arg3
, rvalue arg4
, rvalue arg5
,
299 location loc
= location ());
301 rvalue
new_cast (rvalue expr
,
303 location loc
= location ());
305 lvalue
new_array_access (rvalue ptr
,
307 location loc
= location ());
309 case_
new_case (rvalue min_value
,
314 gcc_jit_context
*m_inner_ctxt
;
317 class field
: public object
321 field (gcc_jit_field
*inner
);
323 gcc_jit_field
*get_inner_field () const;
326 class type
: public object
330 type (gcc_jit_type
*inner
);
332 gcc_jit_type
*get_inner_type () const;
336 type
get_volatile ();
337 type
get_aligned (size_t alignment_in_bytes
);
338 type
get_vector (size_t num_units
);
340 // Shortcuts for getting values of numeric types:
345 class struct_
: public type
349 struct_ (gcc_jit_struct
*inner
);
351 gcc_jit_struct
*get_inner_struct () const;
354 class function
: public object
358 function (gcc_jit_function
*func
);
360 gcc_jit_function
*get_inner_function () const;
362 void dump_to_dot (const std::string
&path
);
364 param
get_param (int index
) const;
367 block
new_block (const std::string
&name
);
369 lvalue
new_local (type type_
,
370 const std::string
&name
,
371 location loc
= location ());
373 rvalue
get_address (location loc
= location ());
375 /* A series of overloaded operator () with various numbers of arguments
376 for a very terse way of creating a call to this function. The call
377 is created within the same context as the function itself, which may
378 not be what you want. */
379 rvalue
operator() (location loc
= location ());
380 rvalue
operator() (rvalue arg0
,
381 location loc
= location ());
382 rvalue
operator() (rvalue arg0
, rvalue arg1
,
383 location loc
= location ());
384 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
385 location loc
= location ());
388 class block
: public object
392 block (gcc_jit_block
*inner
);
394 gcc_jit_block
*get_inner_block () const;
396 function
get_function () const;
398 void add_eval (rvalue rvalue
,
399 location loc
= location ());
401 void add_assignment (lvalue lvalue
,
403 location loc
= location ());
405 void add_assignment_op (lvalue lvalue
,
406 enum gcc_jit_binary_op op
,
408 location loc
= location ());
410 /* A way to add a function call to the body of a function being
411 defined, with various numbers of args. */
412 rvalue
add_call (function other
,
413 location loc
= location ());
414 rvalue
add_call (function other
,
416 location loc
= location ());
417 rvalue
add_call (function other
,
418 rvalue arg0
, rvalue arg1
,
419 location loc
= location ());
420 rvalue
add_call (function other
,
421 rvalue arg0
, rvalue arg1
, rvalue arg2
,
422 location loc
= location ());
423 rvalue
add_call (function other
,
424 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
425 location loc
= location ());
427 void add_comment (const std::string
&text
,
428 location loc
= location ());
430 void end_with_conditional (rvalue boolval
,
433 location loc
= location ());
435 void end_with_jump (block target
,
436 location loc
= location ());
438 void end_with_return (rvalue rvalue
,
439 location loc
= location ());
440 void end_with_return (location loc
= location ());
442 void end_with_switch (rvalue expr
,
444 std::vector
<case_
> cases
,
445 location loc
= location ());
448 class rvalue
: public object
452 rvalue (gcc_jit_rvalue
*inner
);
453 gcc_jit_rvalue
*get_inner_rvalue () const;
457 rvalue
access_field (field field
,
458 location loc
= location ());
460 lvalue
dereference_field (field field
,
461 location loc
= location ());
463 lvalue
dereference (location loc
= location ());
465 rvalue
cast_to (type type_
,
466 location loc
= location ());
469 lvalue
operator[] (rvalue index
);
470 lvalue
operator[] (int index
);
473 class lvalue
: public rvalue
477 lvalue (gcc_jit_lvalue
*inner
);
479 gcc_jit_lvalue
*get_inner_lvalue () const;
481 lvalue
access_field (field field
,
482 location loc
= location ());
484 rvalue
get_address (location loc
= location ());
487 class param
: public lvalue
491 param (gcc_jit_param
*inner
);
493 gcc_jit_param
*get_inner_param () const;
496 class case_
: public object
500 case_ (gcc_jit_case
*inner
);
502 gcc_jit_case
*get_inner_case () const;
505 /* Overloaded operators, for those who want the most terse API
506 (at the possible risk of being a little too magical).
508 In each case, the first parameter is used to determine which context
509 owns the resulting expression, and, where appropriate, what the
512 /* Unary operators. */
513 rvalue
operator- (rvalue a
); // unary minus
514 rvalue
operator~ (rvalue a
); // unary bitwise negate
515 rvalue
operator! (rvalue a
); // unary logical negate
517 /* Binary operators. */
518 rvalue
operator+ (rvalue a
, rvalue b
);
519 rvalue
operator- (rvalue a
, rvalue b
);
520 rvalue
operator* (rvalue a
, rvalue b
);
521 rvalue
operator/ (rvalue a
, rvalue b
);
522 rvalue
operator% (rvalue a
, rvalue b
);
523 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
524 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
525 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
526 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
527 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
530 rvalue
operator== (rvalue a
, rvalue b
);
531 rvalue
operator!= (rvalue a
, rvalue b
);
532 rvalue
operator< (rvalue a
, rvalue b
);
533 rvalue
operator<= (rvalue a
, rvalue b
);
534 rvalue
operator> (rvalue a
, rvalue b
);
535 rvalue
operator>= (rvalue a
, rvalue b
);
538 lvalue
operator* (rvalue ptr
);
544 timer (gcc_jit_timer
*inner_timer
);
546 void push (const char *item_name
);
547 void pop (const char *item_name
);
548 void print (FILE *f_out
) const;
552 gcc_jit_timer
*get_inner_timer () const;
555 gcc_jit_timer
*m_inner_timer
;
561 auto_time (timer t
, const char *item_name
);
562 auto_time (context ctxt
, const char *item_name
);
567 const char *m_item_name
;
571 /****************************************************************************
572 Implementation of the API
573 ****************************************************************************/
577 inline context
context::acquire ()
579 return context (gcc_jit_context_acquire ());
581 inline context::context () : m_inner_ctxt (NULL
) {}
582 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
588 inline gccjit::context
589 context::new_child_context ()
591 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
597 gcc_jit_context_release (m_inner_ctxt
);
601 inline gcc_jit_result
*
604 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
611 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
612 const char *output_path
)
614 gcc_jit_context_compile_to_file (m_inner_ctxt
,
620 context::dump_to_file (const std::string
&path
,
621 bool update_locations
)
623 gcc_jit_context_dump_to_file (m_inner_ctxt
,
629 context::set_logfile (FILE *logfile
,
633 gcc_jit_context_set_logfile (m_inner_ctxt
,
640 context::dump_reproducer_to_file (const char *path
)
642 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
647 context::set_str_option (enum gcc_jit_str_option opt
,
650 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
655 context::set_int_option (enum gcc_jit_int_option opt
,
658 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
663 context::set_bool_option (enum gcc_jit_bool_option opt
,
666 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
670 context::set_bool_allow_unreachable_blocks (int bool_value
)
672 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
677 context::set_bool_use_external_driver (int bool_value
)
679 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
684 context::add_command_line_option (const char *optname
)
686 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
690 context::set_timer (gccjit::timer t
)
692 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
696 context::get_timer () const
698 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
703 context::new_location (const std::string
&filename
,
707 return location (gcc_jit_context_new_location (m_inner_ctxt
,
714 context::get_type (enum gcc_jit_types kind
)
716 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
720 context::get_int_type (size_t num_bytes
, int is_signed
)
722 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
727 template <typename T
>
729 context::get_int_type ()
731 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
735 context::new_array_type (type element_type
, int num_elements
, location loc
)
737 return type (gcc_jit_context_new_array_type (
739 loc
.get_inner_location (),
740 element_type
.get_inner_type (),
745 context::new_field (type type_
, const std::string
&name
, location loc
)
747 return field (gcc_jit_context_new_field (m_inner_ctxt
,
748 loc
.get_inner_location (),
749 type_
.get_inner_type (),
754 context::new_struct_type (const std::string
&name
,
755 std::vector
<field
> &fields
,
758 /* Treat std::vector as an array, relying on it not being resized: */
759 field
*as_array_of_wrappers
= &fields
[0];
761 /* Treat the array as being of the underlying pointers, relying on
762 the wrapper type being such a pointer internally. */
763 gcc_jit_field
**as_array_of_ptrs
=
764 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
766 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
767 loc
.get_inner_location (),
774 context::new_opaque_struct_type (const std::string
&name
,
777 return struct_ (gcc_jit_context_new_opaque_struct (
779 loc
.get_inner_location (),
784 context::new_param (type type_
,
785 const std::string
&name
,
788 return param (gcc_jit_context_new_param (m_inner_ctxt
,
789 loc
.get_inner_location (),
790 type_
.get_inner_type (),
795 context::new_function (enum gcc_jit_function_kind kind
,
797 const std::string
&name
,
798 std::vector
<param
> ¶ms
,
802 /* Treat std::vector as an array, relying on it not being resized: */
803 param
*as_array_of_wrappers
= ¶ms
[0];
805 /* Treat the array as being of the underlying pointers, relying on
806 the wrapper type being such a pointer internally. */
807 gcc_jit_param
**as_array_of_ptrs
=
808 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
810 return function (gcc_jit_context_new_function (m_inner_ctxt
,
811 loc
.get_inner_location (),
813 return_type
.get_inner_type (),
821 context::get_builtin_function (const std::string
&name
)
823 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
828 context::new_global (enum gcc_jit_global_kind kind
,
830 const std::string
&name
,
833 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
834 loc
.get_inner_location (),
836 type_
.get_inner_type (),
841 context::new_rvalue (type numeric_type
,
845 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
846 numeric_type
.get_inner_type (),
851 context::new_rvalue (type numeric_type
,
855 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
856 numeric_type
.get_inner_type (),
861 context::zero (type numeric_type
) const
863 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
864 numeric_type
.get_inner_type ()));
868 context::one (type numeric_type
) const
870 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
871 numeric_type
.get_inner_type ()));
875 context::new_rvalue (type numeric_type
,
879 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
880 numeric_type
.get_inner_type (),
885 context::new_rvalue (type pointer_type
,
889 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
890 pointer_type
.get_inner_type (),
895 context::new_rvalue (const std::string
&value
) const
898 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
902 context::new_rvalue (type vector_type
,
903 std::vector
<rvalue
> elements
) const
905 /* Treat std::vector as an array, relying on it not being resized: */
906 rvalue
*as_array_of_wrappers
= &elements
[0];
908 /* Treat the array as being of the underlying pointers, relying on
909 the wrapper type being such a pointer internally. */
910 gcc_jit_rvalue
**as_array_of_ptrs
=
911 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
914 gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt
,
916 vector_type
.get_inner_type (),
922 context::new_unary_op (enum gcc_jit_unary_op op
,
927 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
928 loc
.get_inner_location (),
930 result_type
.get_inner_type (),
931 a
.get_inner_rvalue ()));
934 context::new_minus (type result_type
,
938 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
939 result_type
, a
, loc
));
942 context::new_bitwise_negate (type result_type
,
946 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
947 result_type
, a
, loc
));
950 context::new_logical_negate (type result_type
,
954 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
955 result_type
, a
, loc
));
959 context::new_binary_op (enum gcc_jit_binary_op op
,
964 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
965 loc
.get_inner_location (),
967 result_type
.get_inner_type (),
968 a
.get_inner_rvalue (),
969 b
.get_inner_rvalue ()));
972 context::new_plus (type result_type
,
976 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
977 result_type
, a
, b
, loc
);
980 context::new_minus (type result_type
,
984 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
985 result_type
, a
, b
, loc
);
988 context::new_mult (type result_type
,
992 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
993 result_type
, a
, b
, loc
);
996 context::new_divide (type result_type
,
1000 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
1001 result_type
, a
, b
, loc
);
1004 context::new_modulo (type result_type
,
1008 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
1009 result_type
, a
, b
, loc
);
1012 context::new_bitwise_and (type result_type
,
1016 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
1017 result_type
, a
, b
, loc
);
1020 context::new_bitwise_xor (type result_type
,
1024 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
1025 result_type
, a
, b
, loc
);
1028 context::new_bitwise_or (type result_type
,
1032 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1033 result_type
, a
, b
, loc
);
1036 context::new_logical_and (type result_type
,
1040 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1041 result_type
, a
, b
, loc
);
1044 context::new_logical_or (type result_type
,
1048 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1049 result_type
, a
, b
, loc
);
1053 context::new_comparison (enum gcc_jit_comparison op
,
1057 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1058 loc
.get_inner_location (),
1060 a
.get_inner_rvalue (),
1061 b
.get_inner_rvalue ()));
1064 context::new_eq (rvalue a
, rvalue b
,
1067 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1071 context::new_ne (rvalue a
, rvalue b
,
1074 return new_comparison (GCC_JIT_COMPARISON_NE
,
1078 context::new_lt (rvalue a
, rvalue b
,
1081 return new_comparison (GCC_JIT_COMPARISON_LT
,
1085 context::new_le (rvalue a
, rvalue b
,
1088 return new_comparison (GCC_JIT_COMPARISON_LE
,
1092 context::new_gt (rvalue a
, rvalue b
,
1095 return new_comparison (GCC_JIT_COMPARISON_GT
,
1099 context::new_ge (rvalue a
, rvalue b
,
1102 return new_comparison (GCC_JIT_COMPARISON_GE
,
1107 context::new_call (function func
,
1108 std::vector
<rvalue
> &args
,
1111 /* Treat std::vector as an array, relying on it not being resized: */
1112 rvalue
*as_array_of_wrappers
= &args
[0];
1114 /* Treat the array as being of the underlying pointers, relying on
1115 the wrapper type being such a pointer internally. */
1116 gcc_jit_rvalue
**as_array_of_ptrs
=
1117 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1118 return gcc_jit_context_new_call (m_inner_ctxt
,
1119 loc
.get_inner_location (),
1120 func
.get_inner_function (),
1125 context::new_call (function func
,
1128 std::vector
<rvalue
> args
;
1129 return new_call (func
, args
, loc
);
1133 context::new_call (function func
,
1137 std::vector
<rvalue
> args(1);
1139 return new_call (func
, args
, loc
);
1142 context::new_call (function func
,
1143 rvalue arg0
, rvalue arg1
,
1146 std::vector
<rvalue
> args(2);
1149 return new_call (func
, args
, loc
);
1152 context::new_call (function func
,
1153 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1156 std::vector
<rvalue
> args(3);
1160 return new_call (func
, args
, loc
);
1163 context::new_call (function func
,
1164 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1168 std::vector
<rvalue
> args(4);
1173 return new_call (func
, args
, loc
);
1176 context::new_call (function func
,
1177 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1178 rvalue arg3
, rvalue arg4
,
1181 std::vector
<rvalue
> args(5);
1187 return new_call (func
, args
, loc
);
1190 context::new_call (function func
,
1191 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1192 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1195 std::vector
<rvalue
> args(6);
1202 return new_call (func
, args
, loc
);
1206 context::new_cast (rvalue expr
,
1210 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1211 loc
.get_inner_location (),
1212 expr
.get_inner_rvalue (),
1213 type_
.get_inner_type ()));
1217 context::new_array_access (rvalue ptr
,
1221 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1222 loc
.get_inner_location (),
1223 ptr
.get_inner_rvalue (),
1224 index
.get_inner_rvalue ()));
1228 context::new_case (rvalue min_value
,
1232 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1233 min_value
.get_inner_rvalue (),
1234 max_value
.get_inner_rvalue (),
1235 dest_block
.get_inner_block ()));
1240 object::get_context () const
1242 return context (gcc_jit_object_get_context (m_inner_obj
));
1246 object::get_debug_string () const
1248 return gcc_jit_object_get_debug_string (m_inner_obj
);
1251 inline object::object () : m_inner_obj (NULL
) {}
1252 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1258 inline gcc_jit_object
*
1259 object::get_inner_object () const
1264 inline std::ostream
&
1265 operator << (std::ostream
& stream
, const object
&obj
)
1267 return stream
<< obj
.get_debug_string ();
1271 inline location::location () : object () {}
1272 inline location::location (gcc_jit_location
*loc
)
1273 : object (gcc_jit_location_as_object (loc
))
1276 inline gcc_jit_location
*
1277 location::get_inner_location () const
1279 /* Manual downcast: */
1280 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1284 inline field::field () : object () {}
1285 inline field::field (gcc_jit_field
*inner
)
1286 : object (gcc_jit_field_as_object (inner
))
1289 inline gcc_jit_field
*
1290 field::get_inner_field () const
1292 /* Manual downcast: */
1293 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1297 inline type::type () : object () {}
1298 inline type::type (gcc_jit_type
*inner
)
1299 : object (gcc_jit_type_as_object (inner
))
1302 inline gcc_jit_type
*
1303 type::get_inner_type () const
1305 /* Manual downcast: */
1306 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1310 type::get_pointer ()
1312 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1318 return type (gcc_jit_type_get_const (get_inner_type ()));
1322 type::get_volatile ()
1324 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1328 type::get_aligned (size_t alignment_in_bytes
)
1330 return type (gcc_jit_type_get_aligned (get_inner_type (),
1331 alignment_in_bytes
));
1335 type::get_vector (size_t num_units
)
1337 return type (gcc_jit_type_get_vector (get_inner_type (),
1344 return get_context ().new_rvalue (*this, 0);
1350 return get_context ().new_rvalue (*this, 1);
1354 inline struct_::struct_ () : type (NULL
) {}
1355 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1356 type (gcc_jit_struct_as_type (inner
))
1360 inline gcc_jit_struct
*
1361 struct_::get_inner_struct () const
1363 /* Manual downcast: */
1364 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1368 inline function::function () : object () {}
1369 inline function::function (gcc_jit_function
*inner
)
1370 : object (gcc_jit_function_as_object (inner
))
1373 inline gcc_jit_function
*
1374 function::get_inner_function () const
1376 /* Manual downcast: */
1377 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1381 function::dump_to_dot (const std::string
&path
)
1383 gcc_jit_function_dump_to_dot (get_inner_function (),
1388 function::get_param (int index
) const
1390 return param (gcc_jit_function_get_param (get_inner_function (),
1395 function::new_block ()
1397 return block (gcc_jit_function_new_block (get_inner_function (),
1402 function::new_block (const std::string
&name
)
1404 return block (gcc_jit_function_new_block (get_inner_function (),
1409 function::new_local (type type_
,
1410 const std::string
&name
,
1413 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1414 loc
.get_inner_location (),
1415 type_
.get_inner_type (),
1420 function::get_address (location loc
)
1422 return rvalue (gcc_jit_function_get_address (get_inner_function (),
1423 loc
.get_inner_location ()));
1427 block::get_function () const
1429 return function (gcc_jit_block_get_function ( get_inner_block ()));
1433 block::add_eval (rvalue rvalue
,
1436 gcc_jit_block_add_eval (get_inner_block (),
1437 loc
.get_inner_location (),
1438 rvalue
.get_inner_rvalue ());
1442 block::add_assignment (lvalue lvalue
,
1446 gcc_jit_block_add_assignment (get_inner_block (),
1447 loc
.get_inner_location (),
1448 lvalue
.get_inner_lvalue (),
1449 rvalue
.get_inner_rvalue ());
1453 block::add_assignment_op (lvalue lvalue
,
1454 enum gcc_jit_binary_op op
,
1458 gcc_jit_block_add_assignment_op (get_inner_block (),
1459 loc
.get_inner_location (),
1460 lvalue
.get_inner_lvalue (),
1462 rvalue
.get_inner_rvalue ());
1466 block::add_comment (const std::string
&text
,
1469 gcc_jit_block_add_comment (get_inner_block (),
1470 loc
.get_inner_location (),
1475 block::end_with_conditional (rvalue boolval
,
1480 gcc_jit_block_end_with_conditional (get_inner_block (),
1481 loc
.get_inner_location (),
1482 boolval
.get_inner_rvalue (),
1483 on_true
.get_inner_block (),
1484 on_false
.get_inner_block ());
1488 block::end_with_jump (block target
,
1491 gcc_jit_block_end_with_jump (get_inner_block (),
1492 loc
.get_inner_location (),
1493 target
.get_inner_block ());
1497 block::end_with_return (rvalue rvalue
,
1500 gcc_jit_block_end_with_return (get_inner_block (),
1501 loc
.get_inner_location (),
1502 rvalue
.get_inner_rvalue ());
1506 block::end_with_return (location loc
)
1508 gcc_jit_block_end_with_void_return (get_inner_block (),
1509 loc
.get_inner_location ());
1513 block::end_with_switch (rvalue expr
,
1514 block default_block
,
1515 std::vector
<case_
> cases
,
1518 /* Treat std::vector as an array, relying on it not being resized: */
1519 case_
*as_array_of_wrappers
= &cases
[0];
1521 /* Treat the array as being of the underlying pointers, relying on
1522 the wrapper type being such a pointer internally. */
1523 gcc_jit_case
**as_array_of_ptrs
=
1524 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1525 gcc_jit_block_end_with_switch (get_inner_block (),
1526 loc
.get_inner_location (),
1527 expr
.get_inner_rvalue (),
1528 default_block
.get_inner_block (),
1534 block::add_call (function other
,
1537 rvalue c
= get_context ().new_call (other
, loc
);
1542 block::add_call (function other
,
1546 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1551 block::add_call (function other
,
1552 rvalue arg0
, rvalue arg1
,
1555 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1560 block::add_call (function other
,
1561 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1564 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1570 block::add_call (function other
,
1571 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1574 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1580 function::operator() (location loc
)
1582 return get_context ().new_call (*this, loc
);
1585 function::operator() (rvalue arg0
,
1588 return get_context ().new_call (*this,
1593 function::operator() (rvalue arg0
, rvalue arg1
,
1596 return get_context ().new_call (*this,
1601 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1604 return get_context ().new_call (*this,
1610 inline block::block () : object () {}
1611 inline block::block (gcc_jit_block
*inner
)
1612 : object (gcc_jit_block_as_object (inner
))
1615 inline gcc_jit_block
*
1616 block::get_inner_block () const
1618 /* Manual downcast: */
1619 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1623 inline rvalue::rvalue () : object () {}
1624 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1625 : object (gcc_jit_rvalue_as_object (inner
))
1628 inline gcc_jit_rvalue
*
1629 rvalue::get_inner_rvalue () const
1631 /* Manual downcast: */
1632 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1638 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1642 rvalue::access_field (field field
,
1645 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1646 loc
.get_inner_location (),
1647 field
.get_inner_field ()));
1651 rvalue::dereference_field (field field
,
1654 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1655 loc
.get_inner_location (),
1656 field
.get_inner_field ()));
1660 rvalue::dereference (location loc
)
1662 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1663 loc
.get_inner_location ()));
1667 rvalue::cast_to (type type_
,
1670 return get_context ().new_cast (*this, type_
, loc
);
1674 rvalue::operator[] (rvalue index
)
1676 return get_context ().new_array_access (*this, index
);
1680 rvalue::operator[] (int index
)
1682 context ctxt
= get_context ();
1683 type int_t
= ctxt
.get_int_type
<int> ();
1684 return ctxt
.new_array_access (*this,
1685 ctxt
.new_rvalue (int_t
,
1689 // class lvalue : public rvalue
1690 inline lvalue::lvalue () : rvalue () {}
1691 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1692 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1695 inline gcc_jit_lvalue
*
1696 lvalue::get_inner_lvalue () const
1698 /* Manual downcast: */
1699 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1703 lvalue::access_field (field field
, location loc
)
1705 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1706 loc
.get_inner_location (),
1707 field
.get_inner_field ()));
1711 lvalue::get_address (location loc
)
1713 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1714 loc
.get_inner_location ()));
1717 // class param : public lvalue
1718 inline param::param () : lvalue () {}
1719 inline param::param (gcc_jit_param
*inner
)
1720 : lvalue (gcc_jit_param_as_lvalue (inner
))
1723 // class case_ : public object
1724 inline case_::case_ () : object () {}
1725 inline case_::case_ (gcc_jit_case
*inner
)
1726 : object (gcc_jit_case_as_object (inner
))
1730 inline gcc_jit_case
*
1731 case_::get_inner_case () const
1733 /* Manual downcast: */
1734 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1737 /* Overloaded operators. */
1739 inline rvalue
operator- (rvalue a
)
1741 return a
.get_context ().new_minus (a
.get_type (), a
);
1743 inline rvalue
operator~ (rvalue a
)
1745 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1747 inline rvalue
operator! (rvalue a
)
1749 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1753 inline rvalue
operator+ (rvalue a
, rvalue b
)
1755 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1757 inline rvalue
operator- (rvalue a
, rvalue b
)
1759 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1761 inline rvalue
operator* (rvalue a
, rvalue b
)
1763 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1765 inline rvalue
operator/ (rvalue a
, rvalue b
)
1767 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1769 inline rvalue
operator% (rvalue a
, rvalue b
)
1771 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1773 inline rvalue
operator& (rvalue a
, rvalue b
)
1775 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1777 inline rvalue
operator^ (rvalue a
, rvalue b
)
1779 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1781 inline rvalue
operator| (rvalue a
, rvalue b
)
1783 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1785 inline rvalue
operator&& (rvalue a
, rvalue b
)
1787 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1789 inline rvalue
operator|| (rvalue a
, rvalue b
)
1791 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1795 inline rvalue
operator== (rvalue a
, rvalue b
)
1797 return a
.get_context ().new_eq (a
, b
);
1799 inline rvalue
operator!= (rvalue a
, rvalue b
)
1801 return a
.get_context ().new_ne (a
, b
);
1803 inline rvalue
operator< (rvalue a
, rvalue b
)
1805 return a
.get_context ().new_lt (a
, b
);
1807 inline rvalue
operator<= (rvalue a
, rvalue b
)
1809 return a
.get_context ().new_le (a
, b
);
1811 inline rvalue
operator> (rvalue a
, rvalue b
)
1813 return a
.get_context ().new_gt (a
, b
);
1815 inline rvalue
operator>= (rvalue a
, rvalue b
)
1817 return a
.get_context ().new_ge (a
, b
);
1820 /* Dereferencing. */
1821 inline lvalue
operator* (rvalue ptr
)
1823 return ptr
.dereference ();
1830 m_inner_timer
= gcc_jit_timer_new ();
1834 timer::timer (gcc_jit_timer
*inner_timer
)
1836 m_inner_timer
= inner_timer
;
1840 timer::push (const char *item_name
)
1842 gcc_jit_timer_push (m_inner_timer
, item_name
);
1847 timer::pop (const char *item_name
)
1849 gcc_jit_timer_pop (m_inner_timer
, item_name
);
1853 timer::print (FILE *f_out
) const
1855 gcc_jit_timer_print (m_inner_timer
, f_out
);
1858 inline gcc_jit_timer
*
1859 timer::get_inner_timer () const
1861 return m_inner_timer
;
1867 gcc_jit_timer_release (m_inner_timer
);
1868 m_inner_timer
= NULL
;
1874 auto_time::auto_time (timer t
, const char *item_name
)
1876 m_item_name (item_name
)
1882 auto_time::auto_time (context ctxt
, const char *item_name
)
1883 : m_timer (ctxt
.get_timer ()),
1884 m_item_name (item_name
)
1886 m_timer
.push (item_name
);
1890 auto_time::~auto_time ()
1892 m_timer
.pop (m_item_name
);
1895 } // namespace gccjit
1897 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */