1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2016 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;
191 /* Generic unary operations... */
192 rvalue
new_unary_op (enum gcc_jit_unary_op op
,
195 location loc
= location ());
197 /* ...and shorter ways to spell the various specific kinds of
199 rvalue
new_minus (type result_type
,
201 location loc
= location ());
202 rvalue
new_bitwise_negate (type result_type
,
204 location loc
= location ());
205 rvalue
new_logical_negate (type result_type
,
207 location loc
= location ());
209 /* Generic binary operations... */
210 rvalue
new_binary_op (enum gcc_jit_binary_op op
,
213 location loc
= location ());
215 /* ...and shorter ways to spell the various specific kinds of
217 rvalue
new_plus (type result_type
,
219 location loc
= location ());
220 rvalue
new_minus (type result_type
,
222 location loc
= location ());
223 rvalue
new_mult (type result_type
,
225 location loc
= location ());
226 rvalue
new_divide (type result_type
,
228 location loc
= location ());
229 rvalue
new_modulo (type result_type
,
231 location loc
= location ());
232 rvalue
new_bitwise_and (type result_type
,
234 location loc
= location ());
235 rvalue
new_bitwise_xor (type result_type
,
237 location loc
= location ());
238 rvalue
new_bitwise_or (type result_type
,
240 location loc
= location ());
241 rvalue
new_logical_and (type result_type
,
243 location loc
= location ());
244 rvalue
new_logical_or (type result_type
,
246 location loc
= location ());
248 /* Generic comparisons... */
249 rvalue
new_comparison (enum gcc_jit_comparison op
,
251 location loc
= location ());
252 /* ...and shorter ways to spell the various specific kinds of
254 rvalue
new_eq (rvalue a
, rvalue b
,
255 location loc
= location ());
256 rvalue
new_ne (rvalue a
, rvalue b
,
257 location loc
= location ());
258 rvalue
new_lt (rvalue a
, rvalue b
,
259 location loc
= location ());
260 rvalue
new_le (rvalue a
, rvalue b
,
261 location loc
= location ());
262 rvalue
new_gt (rvalue a
, rvalue b
,
263 location loc
= location ());
264 rvalue
new_ge (rvalue a
, rvalue b
,
265 location loc
= location ());
267 /* The most general way of creating a function call. */
268 rvalue
new_call (function func
,
269 std::vector
<rvalue
> &args
,
270 location loc
= location ());
272 /* In addition, we provide a series of overloaded "new_call" methods
273 for specific numbers of args (from 0 - 6), to avoid the need for
274 client code to manually build a vector. */
275 rvalue
new_call (function func
,
276 location loc
= location ());
277 rvalue
new_call (function func
,
279 location loc
= location ());
280 rvalue
new_call (function func
,
281 rvalue arg0
, rvalue arg1
,
282 location loc
= location ());
283 rvalue
new_call (function func
,
284 rvalue arg0
, rvalue arg1
, rvalue arg2
,
285 location loc
= location ());
286 rvalue
new_call (function func
,
287 rvalue arg0
, rvalue arg1
, rvalue arg2
,
289 location loc
= location ());
290 rvalue
new_call (function func
,
291 rvalue arg0
, rvalue arg1
, rvalue arg2
,
292 rvalue arg3
, rvalue arg4
,
293 location loc
= location ());
294 rvalue
new_call (function func
,
295 rvalue arg0
, rvalue arg1
, rvalue arg2
,
296 rvalue arg3
, rvalue arg4
, rvalue arg5
,
297 location loc
= location ());
299 rvalue
new_cast (rvalue expr
,
301 location loc
= location ());
303 lvalue
new_array_access (rvalue ptr
,
305 location loc
= location ());
307 case_
new_case (rvalue min_value
,
312 gcc_jit_context
*m_inner_ctxt
;
315 class field
: public object
319 field (gcc_jit_field
*inner
);
321 gcc_jit_field
*get_inner_field () const;
324 class type
: public object
328 type (gcc_jit_type
*inner
);
330 gcc_jit_type
*get_inner_type () const;
333 type
get_volatile ();
335 // Shortcuts for getting values of numeric types:
340 class struct_
: public type
344 struct_ (gcc_jit_struct
*inner
);
346 gcc_jit_struct
*get_inner_struct () const;
349 class function
: public object
353 function (gcc_jit_function
*func
);
355 gcc_jit_function
*get_inner_function () const;
357 void dump_to_dot (const std::string
&path
);
359 param
get_param (int index
) const;
362 block
new_block (const std::string
&name
);
364 lvalue
new_local (type type_
,
365 const std::string
&name
,
366 location loc
= location ());
368 /* A series of overloaded operator () with various numbers of arguments
369 for a very terse way of creating a call to this function. The call
370 is created within the same context as the function itself, which may
371 not be what you want. */
372 rvalue
operator() (location loc
= location ());
373 rvalue
operator() (rvalue arg0
,
374 location loc
= location ());
375 rvalue
operator() (rvalue arg0
, rvalue arg1
,
376 location loc
= location ());
377 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
378 location loc
= location ());
381 class block
: public object
385 block (gcc_jit_block
*inner
);
387 gcc_jit_block
*get_inner_block () const;
389 function
get_function () const;
391 void add_eval (rvalue rvalue
,
392 location loc
= location ());
394 void add_assignment (lvalue lvalue
,
396 location loc
= location ());
398 void add_assignment_op (lvalue lvalue
,
399 enum gcc_jit_binary_op op
,
401 location loc
= location ());
403 /* A way to add a function call to the body of a function being
404 defined, with various numbers of args. */
405 rvalue
add_call (function other
,
406 location loc
= location ());
407 rvalue
add_call (function other
,
409 location loc
= location ());
410 rvalue
add_call (function other
,
411 rvalue arg0
, rvalue arg1
,
412 location loc
= location ());
413 rvalue
add_call (function other
,
414 rvalue arg0
, rvalue arg1
, rvalue arg2
,
415 location loc
= location ());
416 rvalue
add_call (function other
,
417 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
418 location loc
= location ());
420 void add_comment (const std::string
&text
,
421 location loc
= location ());
423 void end_with_conditional (rvalue boolval
,
426 location loc
= location ());
428 void end_with_jump (block target
,
429 location loc
= location ());
431 void end_with_return (rvalue rvalue
,
432 location loc
= location ());
433 void end_with_return (location loc
= location ());
435 void end_with_switch (rvalue expr
,
437 std::vector
<case_
> cases
,
438 location loc
= location ());
441 class rvalue
: public object
445 rvalue (gcc_jit_rvalue
*inner
);
446 gcc_jit_rvalue
*get_inner_rvalue () const;
450 rvalue
access_field (field field
,
451 location loc
= location ());
453 lvalue
dereference_field (field field
,
454 location loc
= location ());
456 lvalue
dereference (location loc
= location ());
458 rvalue
cast_to (type type_
,
459 location loc
= location ());
462 lvalue
operator[] (rvalue index
);
463 lvalue
operator[] (int index
);
466 class lvalue
: public rvalue
470 lvalue (gcc_jit_lvalue
*inner
);
472 gcc_jit_lvalue
*get_inner_lvalue () const;
474 lvalue
access_field (field field
,
475 location loc
= location ());
477 rvalue
get_address (location loc
= location ());
480 class param
: public lvalue
484 param (gcc_jit_param
*inner
);
486 gcc_jit_param
*get_inner_param () const;
489 class case_
: public object
493 case_ (gcc_jit_case
*inner
);
495 gcc_jit_case
*get_inner_case () const;
498 /* Overloaded operators, for those who want the most terse API
499 (at the possible risk of being a little too magical).
501 In each case, the first parameter is used to determine which context
502 owns the resulting expression, and, where appropriate, what the
505 /* Unary operators. */
506 rvalue
operator- (rvalue a
); // unary minus
507 rvalue
operator~ (rvalue a
); // unary bitwise negate
508 rvalue
operator! (rvalue a
); // unary logical negate
510 /* Binary operators. */
511 rvalue
operator+ (rvalue a
, rvalue b
);
512 rvalue
operator- (rvalue a
, rvalue b
);
513 rvalue
operator* (rvalue a
, rvalue b
);
514 rvalue
operator/ (rvalue a
, rvalue b
);
515 rvalue
operator% (rvalue a
, rvalue b
);
516 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
517 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
518 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
519 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
520 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
523 rvalue
operator== (rvalue a
, rvalue b
);
524 rvalue
operator!= (rvalue a
, rvalue b
);
525 rvalue
operator< (rvalue a
, rvalue b
);
526 rvalue
operator<= (rvalue a
, rvalue b
);
527 rvalue
operator> (rvalue a
, rvalue b
);
528 rvalue
operator>= (rvalue a
, rvalue b
);
531 lvalue
operator* (rvalue ptr
);
537 timer (gcc_jit_timer
*inner_timer
);
539 void push (const char *item_name
);
540 void pop (const char *item_name
);
541 void print (FILE *f_out
) const;
545 gcc_jit_timer
*get_inner_timer () const;
548 gcc_jit_timer
*m_inner_timer
;
554 auto_time (timer t
, const char *item_name
);
555 auto_time (context ctxt
, const char *item_name
);
560 const char *m_item_name
;
564 /****************************************************************************
565 Implementation of the API
566 ****************************************************************************/
570 inline context
context::acquire ()
572 return context (gcc_jit_context_acquire ());
574 inline context::context () : m_inner_ctxt (NULL
) {}
575 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
581 inline gccjit::context
582 context::new_child_context ()
584 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
590 gcc_jit_context_release (m_inner_ctxt
);
594 inline gcc_jit_result
*
597 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
604 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
605 const char *output_path
)
607 gcc_jit_context_compile_to_file (m_inner_ctxt
,
613 context::dump_to_file (const std::string
&path
,
614 bool update_locations
)
616 gcc_jit_context_dump_to_file (m_inner_ctxt
,
622 context::set_logfile (FILE *logfile
,
626 gcc_jit_context_set_logfile (m_inner_ctxt
,
633 context::dump_reproducer_to_file (const char *path
)
635 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
640 context::set_str_option (enum gcc_jit_str_option opt
,
643 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
648 context::set_int_option (enum gcc_jit_int_option opt
,
651 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
656 context::set_bool_option (enum gcc_jit_bool_option opt
,
659 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
663 context::set_bool_allow_unreachable_blocks (int bool_value
)
665 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
670 context::set_bool_use_external_driver (int bool_value
)
672 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
677 context::add_command_line_option (const char *optname
)
679 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
683 context::set_timer (gccjit::timer t
)
685 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
689 context::get_timer () const
691 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
696 context::new_location (const std::string
&filename
,
700 return location (gcc_jit_context_new_location (m_inner_ctxt
,
707 context::get_type (enum gcc_jit_types kind
)
709 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
713 context::get_int_type (size_t num_bytes
, int is_signed
)
715 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
720 template <typename T
>
722 context::get_int_type ()
724 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
728 context::new_array_type (type element_type
, int num_elements
, location loc
)
730 return type (gcc_jit_context_new_array_type (
732 loc
.get_inner_location (),
733 element_type
.get_inner_type (),
738 context::new_field (type type_
, const std::string
&name
, location loc
)
740 return field (gcc_jit_context_new_field (m_inner_ctxt
,
741 loc
.get_inner_location (),
742 type_
.get_inner_type (),
747 context::new_struct_type (const std::string
&name
,
748 std::vector
<field
> &fields
,
751 /* Treat std::vector as an array, relying on it not being resized: */
752 field
*as_array_of_wrappers
= &fields
[0];
754 /* Treat the array as being of the underlying pointers, relying on
755 the wrapper type being such a pointer internally. */
756 gcc_jit_field
**as_array_of_ptrs
=
757 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
759 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
760 loc
.get_inner_location (),
767 context::new_opaque_struct_type (const std::string
&name
,
770 return struct_ (gcc_jit_context_new_opaque_struct (
772 loc
.get_inner_location (),
777 context::new_param (type type_
,
778 const std::string
&name
,
781 return param (gcc_jit_context_new_param (m_inner_ctxt
,
782 loc
.get_inner_location (),
783 type_
.get_inner_type (),
788 context::new_function (enum gcc_jit_function_kind kind
,
790 const std::string
&name
,
791 std::vector
<param
> ¶ms
,
795 /* Treat std::vector as an array, relying on it not being resized: */
796 param
*as_array_of_wrappers
= ¶ms
[0];
798 /* Treat the array as being of the underlying pointers, relying on
799 the wrapper type being such a pointer internally. */
800 gcc_jit_param
**as_array_of_ptrs
=
801 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
803 return function (gcc_jit_context_new_function (m_inner_ctxt
,
804 loc
.get_inner_location (),
806 return_type
.get_inner_type (),
814 context::get_builtin_function (const std::string
&name
)
816 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
821 context::new_global (enum gcc_jit_global_kind kind
,
823 const std::string
&name
,
826 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
827 loc
.get_inner_location (),
829 type_
.get_inner_type (),
834 context::new_rvalue (type numeric_type
,
838 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
839 numeric_type
.get_inner_type (),
844 context::new_rvalue (type numeric_type
,
848 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
849 numeric_type
.get_inner_type (),
854 context::zero (type numeric_type
) const
856 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
857 numeric_type
.get_inner_type ()));
861 context::one (type numeric_type
) const
863 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
864 numeric_type
.get_inner_type ()));
868 context::new_rvalue (type numeric_type
,
872 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
873 numeric_type
.get_inner_type (),
878 context::new_rvalue (type pointer_type
,
882 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
883 pointer_type
.get_inner_type (),
888 context::new_rvalue (const std::string
&value
) const
891 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
895 context::new_unary_op (enum gcc_jit_unary_op op
,
900 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
901 loc
.get_inner_location (),
903 result_type
.get_inner_type (),
904 a
.get_inner_rvalue ()));
907 context::new_minus (type result_type
,
911 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
912 result_type
, a
, loc
));
915 context::new_bitwise_negate (type result_type
,
919 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
920 result_type
, a
, loc
));
923 context::new_logical_negate (type result_type
,
927 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
928 result_type
, a
, loc
));
932 context::new_binary_op (enum gcc_jit_binary_op op
,
937 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
938 loc
.get_inner_location (),
940 result_type
.get_inner_type (),
941 a
.get_inner_rvalue (),
942 b
.get_inner_rvalue ()));
945 context::new_plus (type result_type
,
949 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
950 result_type
, a
, b
, loc
);
953 context::new_minus (type result_type
,
957 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
958 result_type
, a
, b
, loc
);
961 context::new_mult (type result_type
,
965 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
966 result_type
, a
, b
, loc
);
969 context::new_divide (type result_type
,
973 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
974 result_type
, a
, b
, loc
);
977 context::new_modulo (type result_type
,
981 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
982 result_type
, a
, b
, loc
);
985 context::new_bitwise_and (type result_type
,
989 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
990 result_type
, a
, b
, loc
);
993 context::new_bitwise_xor (type result_type
,
997 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
998 result_type
, a
, b
, loc
);
1001 context::new_bitwise_or (type result_type
,
1005 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1006 result_type
, a
, b
, loc
);
1009 context::new_logical_and (type result_type
,
1013 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1014 result_type
, a
, b
, loc
);
1017 context::new_logical_or (type result_type
,
1021 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1022 result_type
, a
, b
, loc
);
1026 context::new_comparison (enum gcc_jit_comparison op
,
1030 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1031 loc
.get_inner_location (),
1033 a
.get_inner_rvalue (),
1034 b
.get_inner_rvalue ()));
1037 context::new_eq (rvalue a
, rvalue b
,
1040 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1044 context::new_ne (rvalue a
, rvalue b
,
1047 return new_comparison (GCC_JIT_COMPARISON_NE
,
1051 context::new_lt (rvalue a
, rvalue b
,
1054 return new_comparison (GCC_JIT_COMPARISON_LT
,
1058 context::new_le (rvalue a
, rvalue b
,
1061 return new_comparison (GCC_JIT_COMPARISON_LE
,
1065 context::new_gt (rvalue a
, rvalue b
,
1068 return new_comparison (GCC_JIT_COMPARISON_GT
,
1072 context::new_ge (rvalue a
, rvalue b
,
1075 return new_comparison (GCC_JIT_COMPARISON_GE
,
1080 context::new_call (function func
,
1081 std::vector
<rvalue
> &args
,
1084 /* Treat std::vector as an array, relying on it not being resized: */
1085 rvalue
*as_array_of_wrappers
= &args
[0];
1087 /* Treat the array as being of the underlying pointers, relying on
1088 the wrapper type being such a pointer internally. */
1089 gcc_jit_rvalue
**as_array_of_ptrs
=
1090 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1091 return gcc_jit_context_new_call (m_inner_ctxt
,
1092 loc
.get_inner_location (),
1093 func
.get_inner_function (),
1098 context::new_call (function func
,
1101 std::vector
<rvalue
> args
;
1102 return new_call (func
, args
, loc
);
1106 context::new_call (function func
,
1110 std::vector
<rvalue
> args(1);
1112 return new_call (func
, args
, loc
);
1115 context::new_call (function func
,
1116 rvalue arg0
, rvalue arg1
,
1119 std::vector
<rvalue
> args(2);
1122 return new_call (func
, args
, loc
);
1125 context::new_call (function func
,
1126 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1129 std::vector
<rvalue
> args(3);
1133 return new_call (func
, args
, loc
);
1136 context::new_call (function func
,
1137 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1141 std::vector
<rvalue
> args(4);
1146 return new_call (func
, args
, loc
);
1149 context::new_call (function func
,
1150 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1151 rvalue arg3
, rvalue arg4
,
1154 std::vector
<rvalue
> args(5);
1160 return new_call (func
, args
, loc
);
1163 context::new_call (function func
,
1164 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1165 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1168 std::vector
<rvalue
> args(6);
1175 return new_call (func
, args
, loc
);
1179 context::new_cast (rvalue expr
,
1183 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1184 loc
.get_inner_location (),
1185 expr
.get_inner_rvalue (),
1186 type_
.get_inner_type ()));
1190 context::new_array_access (rvalue ptr
,
1194 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1195 loc
.get_inner_location (),
1196 ptr
.get_inner_rvalue (),
1197 index
.get_inner_rvalue ()));
1201 context::new_case (rvalue min_value
,
1205 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1206 min_value
.get_inner_rvalue (),
1207 max_value
.get_inner_rvalue (),
1208 dest_block
.get_inner_block ()));
1213 object::get_context () const
1215 return context (gcc_jit_object_get_context (m_inner_obj
));
1219 object::get_debug_string () const
1221 return gcc_jit_object_get_debug_string (m_inner_obj
);
1224 inline object::object () : m_inner_obj (NULL
) {}
1225 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1231 inline gcc_jit_object
*
1232 object::get_inner_object () const
1237 inline std::ostream
&
1238 operator << (std::ostream
& stream
, const object
&obj
)
1240 return stream
<< obj
.get_debug_string ();
1244 inline location::location () : object () {}
1245 inline location::location (gcc_jit_location
*loc
)
1246 : object (gcc_jit_location_as_object (loc
))
1249 inline gcc_jit_location
*
1250 location::get_inner_location () const
1252 /* Manual downcast: */
1253 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1257 inline field::field () : object () {}
1258 inline field::field (gcc_jit_field
*inner
)
1259 : object (gcc_jit_field_as_object (inner
))
1262 inline gcc_jit_field
*
1263 field::get_inner_field () const
1265 /* Manual downcast: */
1266 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1270 inline type::type () : object () {}
1271 inline type::type (gcc_jit_type
*inner
)
1272 : object (gcc_jit_type_as_object (inner
))
1275 inline gcc_jit_type
*
1276 type::get_inner_type () const
1278 /* Manual downcast: */
1279 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1283 type::get_pointer ()
1285 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1289 type::get_volatile ()
1291 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1297 return get_context ().new_rvalue (*this, 0);
1303 return get_context ().new_rvalue (*this, 1);
1307 inline struct_::struct_ () : type (NULL
) {}
1308 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1309 type (gcc_jit_struct_as_type (inner
))
1313 inline gcc_jit_struct
*
1314 struct_::get_inner_struct () const
1316 /* Manual downcast: */
1317 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1321 inline function::function () : object () {}
1322 inline function::function (gcc_jit_function
*inner
)
1323 : object (gcc_jit_function_as_object (inner
))
1326 inline gcc_jit_function
*
1327 function::get_inner_function () const
1329 /* Manual downcast: */
1330 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1334 function::dump_to_dot (const std::string
&path
)
1336 gcc_jit_function_dump_to_dot (get_inner_function (),
1341 function::get_param (int index
) const
1343 return param (gcc_jit_function_get_param (get_inner_function (),
1348 function::new_block ()
1350 return block (gcc_jit_function_new_block (get_inner_function (),
1355 function::new_block (const std::string
&name
)
1357 return block (gcc_jit_function_new_block (get_inner_function (),
1362 function::new_local (type type_
,
1363 const std::string
&name
,
1366 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1367 loc
.get_inner_location (),
1368 type_
.get_inner_type (),
1373 block::get_function () const
1375 return function (gcc_jit_block_get_function ( get_inner_block ()));
1379 block::add_eval (rvalue rvalue
,
1382 gcc_jit_block_add_eval (get_inner_block (),
1383 loc
.get_inner_location (),
1384 rvalue
.get_inner_rvalue ());
1388 block::add_assignment (lvalue lvalue
,
1392 gcc_jit_block_add_assignment (get_inner_block (),
1393 loc
.get_inner_location (),
1394 lvalue
.get_inner_lvalue (),
1395 rvalue
.get_inner_rvalue ());
1399 block::add_assignment_op (lvalue lvalue
,
1400 enum gcc_jit_binary_op op
,
1404 gcc_jit_block_add_assignment_op (get_inner_block (),
1405 loc
.get_inner_location (),
1406 lvalue
.get_inner_lvalue (),
1408 rvalue
.get_inner_rvalue ());
1412 block::add_comment (const std::string
&text
,
1415 gcc_jit_block_add_comment (get_inner_block (),
1416 loc
.get_inner_location (),
1421 block::end_with_conditional (rvalue boolval
,
1426 gcc_jit_block_end_with_conditional (get_inner_block (),
1427 loc
.get_inner_location (),
1428 boolval
.get_inner_rvalue (),
1429 on_true
.get_inner_block (),
1430 on_false
.get_inner_block ());
1434 block::end_with_jump (block target
,
1437 gcc_jit_block_end_with_jump (get_inner_block (),
1438 loc
.get_inner_location (),
1439 target
.get_inner_block ());
1443 block::end_with_return (rvalue rvalue
,
1446 gcc_jit_block_end_with_return (get_inner_block (),
1447 loc
.get_inner_location (),
1448 rvalue
.get_inner_rvalue ());
1452 block::end_with_return (location loc
)
1454 gcc_jit_block_end_with_void_return (get_inner_block (),
1455 loc
.get_inner_location ());
1459 block::end_with_switch (rvalue expr
,
1460 block default_block
,
1461 std::vector
<case_
> cases
,
1464 /* Treat std::vector as an array, relying on it not being resized: */
1465 case_
*as_array_of_wrappers
= &cases
[0];
1467 /* Treat the array as being of the underlying pointers, relying on
1468 the wrapper type being such a pointer internally. */
1469 gcc_jit_case
**as_array_of_ptrs
=
1470 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1471 gcc_jit_block_end_with_switch (get_inner_block (),
1472 loc
.get_inner_location (),
1473 expr
.get_inner_rvalue (),
1474 default_block
.get_inner_block (),
1480 block::add_call (function other
,
1483 rvalue c
= get_context ().new_call (other
, loc
);
1488 block::add_call (function other
,
1492 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1497 block::add_call (function other
,
1498 rvalue arg0
, rvalue arg1
,
1501 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1506 block::add_call (function other
,
1507 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1510 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1516 block::add_call (function other
,
1517 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1520 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1526 function::operator() (location loc
)
1528 return get_context ().new_call (*this, loc
);
1531 function::operator() (rvalue arg0
,
1534 return get_context ().new_call (*this,
1539 function::operator() (rvalue arg0
, rvalue arg1
,
1542 return get_context ().new_call (*this,
1547 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1550 return get_context ().new_call (*this,
1556 inline block::block () : object () {}
1557 inline block::block (gcc_jit_block
*inner
)
1558 : object (gcc_jit_block_as_object (inner
))
1561 inline gcc_jit_block
*
1562 block::get_inner_block () const
1564 /* Manual downcast: */
1565 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1569 inline rvalue::rvalue () : object () {}
1570 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1571 : object (gcc_jit_rvalue_as_object (inner
))
1574 inline gcc_jit_rvalue
*
1575 rvalue::get_inner_rvalue () const
1577 /* Manual downcast: */
1578 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1584 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1588 rvalue::access_field (field field
,
1591 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1592 loc
.get_inner_location (),
1593 field
.get_inner_field ()));
1597 rvalue::dereference_field (field field
,
1600 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1601 loc
.get_inner_location (),
1602 field
.get_inner_field ()));
1606 rvalue::dereference (location loc
)
1608 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1609 loc
.get_inner_location ()));
1613 rvalue::cast_to (type type_
,
1616 return get_context ().new_cast (*this, type_
, loc
);
1620 rvalue::operator[] (rvalue index
)
1622 return get_context ().new_array_access (*this, index
);
1626 rvalue::operator[] (int index
)
1628 context ctxt
= get_context ();
1629 type int_t
= ctxt
.get_int_type
<int> ();
1630 return ctxt
.new_array_access (*this,
1631 ctxt
.new_rvalue (int_t
,
1635 // class lvalue : public rvalue
1636 inline lvalue::lvalue () : rvalue () {}
1637 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1638 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1641 inline gcc_jit_lvalue
*
1642 lvalue::get_inner_lvalue () const
1644 /* Manual downcast: */
1645 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1649 lvalue::access_field (field field
, location loc
)
1651 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1652 loc
.get_inner_location (),
1653 field
.get_inner_field ()));
1657 lvalue::get_address (location loc
)
1659 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1660 loc
.get_inner_location ()));
1663 // class param : public lvalue
1664 inline param::param () : lvalue () {}
1665 inline param::param (gcc_jit_param
*inner
)
1666 : lvalue (gcc_jit_param_as_lvalue (inner
))
1669 // class case_ : public object
1670 inline case_::case_ () : object () {}
1671 inline case_::case_ (gcc_jit_case
*inner
)
1672 : object (gcc_jit_case_as_object (inner
))
1676 inline gcc_jit_case
*
1677 case_::get_inner_case () const
1679 /* Manual downcast: */
1680 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1683 /* Overloaded operators. */
1685 inline rvalue
operator- (rvalue a
)
1687 return a
.get_context ().new_minus (a
.get_type (), a
);
1689 inline rvalue
operator~ (rvalue a
)
1691 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1693 inline rvalue
operator! (rvalue a
)
1695 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1699 inline rvalue
operator+ (rvalue a
, rvalue b
)
1701 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1703 inline rvalue
operator- (rvalue a
, rvalue b
)
1705 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1707 inline rvalue
operator* (rvalue a
, rvalue b
)
1709 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1711 inline rvalue
operator/ (rvalue a
, rvalue b
)
1713 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1715 inline rvalue
operator% (rvalue a
, rvalue b
)
1717 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1719 inline rvalue
operator& (rvalue a
, rvalue b
)
1721 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1723 inline rvalue
operator^ (rvalue a
, rvalue b
)
1725 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1727 inline rvalue
operator| (rvalue a
, rvalue b
)
1729 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1731 inline rvalue
operator&& (rvalue a
, rvalue b
)
1733 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1735 inline rvalue
operator|| (rvalue a
, rvalue b
)
1737 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1741 inline rvalue
operator== (rvalue a
, rvalue b
)
1743 return a
.get_context ().new_eq (a
, b
);
1745 inline rvalue
operator!= (rvalue a
, rvalue b
)
1747 return a
.get_context ().new_ne (a
, b
);
1749 inline rvalue
operator< (rvalue a
, rvalue b
)
1751 return a
.get_context ().new_lt (a
, b
);
1753 inline rvalue
operator<= (rvalue a
, rvalue b
)
1755 return a
.get_context ().new_le (a
, b
);
1757 inline rvalue
operator> (rvalue a
, rvalue b
)
1759 return a
.get_context ().new_gt (a
, b
);
1761 inline rvalue
operator>= (rvalue a
, rvalue b
)
1763 return a
.get_context ().new_ge (a
, b
);
1766 /* Dereferencing. */
1767 inline lvalue
operator* (rvalue ptr
)
1769 return ptr
.dereference ();
1776 m_inner_timer
= gcc_jit_timer_new ();
1780 timer::timer (gcc_jit_timer
*inner_timer
)
1782 m_inner_timer
= inner_timer
;
1786 timer::push (const char *item_name
)
1788 gcc_jit_timer_push (m_inner_timer
, item_name
);
1793 timer::pop (const char *item_name
)
1795 gcc_jit_timer_pop (m_inner_timer
, item_name
);
1799 timer::print (FILE *f_out
) const
1801 gcc_jit_timer_print (m_inner_timer
, f_out
);
1804 inline gcc_jit_timer
*
1805 timer::get_inner_timer () const
1807 return m_inner_timer
;
1813 gcc_jit_timer_release (m_inner_timer
);
1814 m_inner_timer
= NULL
;
1820 auto_time::auto_time (timer t
, const char *item_name
)
1822 m_item_name (item_name
)
1828 auto_time::auto_time (context ctxt
, const char *item_name
)
1829 : m_timer (ctxt
.get_timer ()),
1830 m_item_name (item_name
)
1832 m_timer
.push (item_name
);
1836 auto_time::~auto_time ()
1838 m_timer
.pop (m_item_name
);
1841 } // namespace gccjit
1843 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */