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;
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;
334 type
get_volatile ();
335 type
get_aligned (size_t alignment_in_bytes
);
337 // Shortcuts for getting values of numeric types:
342 class struct_
: public type
346 struct_ (gcc_jit_struct
*inner
);
348 gcc_jit_struct
*get_inner_struct () const;
351 class function
: public object
355 function (gcc_jit_function
*func
);
357 gcc_jit_function
*get_inner_function () const;
359 void dump_to_dot (const std::string
&path
);
361 param
get_param (int index
) const;
364 block
new_block (const std::string
&name
);
366 lvalue
new_local (type type_
,
367 const std::string
&name
,
368 location loc
= location ());
370 /* A series of overloaded operator () with various numbers of arguments
371 for a very terse way of creating a call to this function. The call
372 is created within the same context as the function itself, which may
373 not be what you want. */
374 rvalue
operator() (location loc
= location ());
375 rvalue
operator() (rvalue arg0
,
376 location loc
= location ());
377 rvalue
operator() (rvalue arg0
, rvalue arg1
,
378 location loc
= location ());
379 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
380 location loc
= location ());
383 class block
: public object
387 block (gcc_jit_block
*inner
);
389 gcc_jit_block
*get_inner_block () const;
391 function
get_function () const;
393 void add_eval (rvalue rvalue
,
394 location loc
= location ());
396 void add_assignment (lvalue lvalue
,
398 location loc
= location ());
400 void add_assignment_op (lvalue lvalue
,
401 enum gcc_jit_binary_op op
,
403 location loc
= location ());
405 /* A way to add a function call to the body of a function being
406 defined, with various numbers of args. */
407 rvalue
add_call (function other
,
408 location loc
= location ());
409 rvalue
add_call (function other
,
411 location loc
= location ());
412 rvalue
add_call (function other
,
413 rvalue arg0
, rvalue arg1
,
414 location loc
= location ());
415 rvalue
add_call (function other
,
416 rvalue arg0
, rvalue arg1
, rvalue arg2
,
417 location loc
= location ());
418 rvalue
add_call (function other
,
419 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
420 location loc
= location ());
422 void add_comment (const std::string
&text
,
423 location loc
= location ());
425 void end_with_conditional (rvalue boolval
,
428 location loc
= location ());
430 void end_with_jump (block target
,
431 location loc
= location ());
433 void end_with_return (rvalue rvalue
,
434 location loc
= location ());
435 void end_with_return (location loc
= location ());
437 void end_with_switch (rvalue expr
,
439 std::vector
<case_
> cases
,
440 location loc
= location ());
443 class rvalue
: public object
447 rvalue (gcc_jit_rvalue
*inner
);
448 gcc_jit_rvalue
*get_inner_rvalue () const;
452 rvalue
access_field (field field
,
453 location loc
= location ());
455 lvalue
dereference_field (field field
,
456 location loc
= location ());
458 lvalue
dereference (location loc
= location ());
460 rvalue
cast_to (type type_
,
461 location loc
= location ());
464 lvalue
operator[] (rvalue index
);
465 lvalue
operator[] (int index
);
468 class lvalue
: public rvalue
472 lvalue (gcc_jit_lvalue
*inner
);
474 gcc_jit_lvalue
*get_inner_lvalue () const;
476 lvalue
access_field (field field
,
477 location loc
= location ());
479 rvalue
get_address (location loc
= location ());
482 class param
: public lvalue
486 param (gcc_jit_param
*inner
);
488 gcc_jit_param
*get_inner_param () const;
491 class case_
: public object
495 case_ (gcc_jit_case
*inner
);
497 gcc_jit_case
*get_inner_case () const;
500 /* Overloaded operators, for those who want the most terse API
501 (at the possible risk of being a little too magical).
503 In each case, the first parameter is used to determine which context
504 owns the resulting expression, and, where appropriate, what the
507 /* Unary operators. */
508 rvalue
operator- (rvalue a
); // unary minus
509 rvalue
operator~ (rvalue a
); // unary bitwise negate
510 rvalue
operator! (rvalue a
); // unary logical negate
512 /* Binary operators. */
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
);
517 rvalue
operator% (rvalue a
, rvalue b
);
518 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
519 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
520 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
521 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
522 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
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
);
533 lvalue
operator* (rvalue ptr
);
539 timer (gcc_jit_timer
*inner_timer
);
541 void push (const char *item_name
);
542 void pop (const char *item_name
);
543 void print (FILE *f_out
) const;
547 gcc_jit_timer
*get_inner_timer () const;
550 gcc_jit_timer
*m_inner_timer
;
556 auto_time (timer t
, const char *item_name
);
557 auto_time (context ctxt
, const char *item_name
);
562 const char *m_item_name
;
566 /****************************************************************************
567 Implementation of the API
568 ****************************************************************************/
572 inline context
context::acquire ()
574 return context (gcc_jit_context_acquire ());
576 inline context::context () : m_inner_ctxt (NULL
) {}
577 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
583 inline gccjit::context
584 context::new_child_context ()
586 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
592 gcc_jit_context_release (m_inner_ctxt
);
596 inline gcc_jit_result
*
599 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
606 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
607 const char *output_path
)
609 gcc_jit_context_compile_to_file (m_inner_ctxt
,
615 context::dump_to_file (const std::string
&path
,
616 bool update_locations
)
618 gcc_jit_context_dump_to_file (m_inner_ctxt
,
624 context::set_logfile (FILE *logfile
,
628 gcc_jit_context_set_logfile (m_inner_ctxt
,
635 context::dump_reproducer_to_file (const char *path
)
637 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
642 context::set_str_option (enum gcc_jit_str_option opt
,
645 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
650 context::set_int_option (enum gcc_jit_int_option opt
,
653 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
658 context::set_bool_option (enum gcc_jit_bool_option opt
,
661 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
665 context::set_bool_allow_unreachable_blocks (int bool_value
)
667 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
672 context::set_bool_use_external_driver (int bool_value
)
674 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
679 context::add_command_line_option (const char *optname
)
681 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
685 context::set_timer (gccjit::timer t
)
687 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
691 context::get_timer () const
693 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
698 context::new_location (const std::string
&filename
,
702 return location (gcc_jit_context_new_location (m_inner_ctxt
,
709 context::get_type (enum gcc_jit_types kind
)
711 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
715 context::get_int_type (size_t num_bytes
, int is_signed
)
717 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
722 template <typename T
>
724 context::get_int_type ()
726 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
730 context::new_array_type (type element_type
, int num_elements
, location loc
)
732 return type (gcc_jit_context_new_array_type (
734 loc
.get_inner_location (),
735 element_type
.get_inner_type (),
740 context::new_field (type type_
, const std::string
&name
, location loc
)
742 return field (gcc_jit_context_new_field (m_inner_ctxt
,
743 loc
.get_inner_location (),
744 type_
.get_inner_type (),
749 context::new_struct_type (const std::string
&name
,
750 std::vector
<field
> &fields
,
753 /* Treat std::vector as an array, relying on it not being resized: */
754 field
*as_array_of_wrappers
= &fields
[0];
756 /* Treat the array as being of the underlying pointers, relying on
757 the wrapper type being such a pointer internally. */
758 gcc_jit_field
**as_array_of_ptrs
=
759 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
761 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
762 loc
.get_inner_location (),
769 context::new_opaque_struct_type (const std::string
&name
,
772 return struct_ (gcc_jit_context_new_opaque_struct (
774 loc
.get_inner_location (),
779 context::new_param (type type_
,
780 const std::string
&name
,
783 return param (gcc_jit_context_new_param (m_inner_ctxt
,
784 loc
.get_inner_location (),
785 type_
.get_inner_type (),
790 context::new_function (enum gcc_jit_function_kind kind
,
792 const std::string
&name
,
793 std::vector
<param
> ¶ms
,
797 /* Treat std::vector as an array, relying on it not being resized: */
798 param
*as_array_of_wrappers
= ¶ms
[0];
800 /* Treat the array as being of the underlying pointers, relying on
801 the wrapper type being such a pointer internally. */
802 gcc_jit_param
**as_array_of_ptrs
=
803 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
805 return function (gcc_jit_context_new_function (m_inner_ctxt
,
806 loc
.get_inner_location (),
808 return_type
.get_inner_type (),
816 context::get_builtin_function (const std::string
&name
)
818 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
823 context::new_global (enum gcc_jit_global_kind kind
,
825 const std::string
&name
,
828 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
829 loc
.get_inner_location (),
831 type_
.get_inner_type (),
836 context::new_rvalue (type numeric_type
,
840 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
841 numeric_type
.get_inner_type (),
846 context::new_rvalue (type numeric_type
,
850 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
851 numeric_type
.get_inner_type (),
856 context::zero (type numeric_type
) const
858 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
859 numeric_type
.get_inner_type ()));
863 context::one (type numeric_type
) const
865 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
866 numeric_type
.get_inner_type ()));
870 context::new_rvalue (type numeric_type
,
874 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
875 numeric_type
.get_inner_type (),
880 context::new_rvalue (type pointer_type
,
884 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
885 pointer_type
.get_inner_type (),
890 context::new_rvalue (const std::string
&value
) const
893 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
897 context::new_unary_op (enum gcc_jit_unary_op op
,
902 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
903 loc
.get_inner_location (),
905 result_type
.get_inner_type (),
906 a
.get_inner_rvalue ()));
909 context::new_minus (type result_type
,
913 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
914 result_type
, a
, loc
));
917 context::new_bitwise_negate (type result_type
,
921 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
922 result_type
, a
, loc
));
925 context::new_logical_negate (type result_type
,
929 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
930 result_type
, a
, loc
));
934 context::new_binary_op (enum gcc_jit_binary_op op
,
939 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
940 loc
.get_inner_location (),
942 result_type
.get_inner_type (),
943 a
.get_inner_rvalue (),
944 b
.get_inner_rvalue ()));
947 context::new_plus (type result_type
,
951 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
952 result_type
, a
, b
, loc
);
955 context::new_minus (type result_type
,
959 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
960 result_type
, a
, b
, loc
);
963 context::new_mult (type result_type
,
967 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
968 result_type
, a
, b
, loc
);
971 context::new_divide (type result_type
,
975 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
976 result_type
, a
, b
, loc
);
979 context::new_modulo (type result_type
,
983 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
984 result_type
, a
, b
, loc
);
987 context::new_bitwise_and (type result_type
,
991 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
992 result_type
, a
, b
, loc
);
995 context::new_bitwise_xor (type result_type
,
999 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
1000 result_type
, a
, b
, loc
);
1003 context::new_bitwise_or (type result_type
,
1007 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1008 result_type
, a
, b
, loc
);
1011 context::new_logical_and (type result_type
,
1015 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1016 result_type
, a
, b
, loc
);
1019 context::new_logical_or (type result_type
,
1023 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1024 result_type
, a
, b
, loc
);
1028 context::new_comparison (enum gcc_jit_comparison op
,
1032 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1033 loc
.get_inner_location (),
1035 a
.get_inner_rvalue (),
1036 b
.get_inner_rvalue ()));
1039 context::new_eq (rvalue a
, rvalue b
,
1042 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1046 context::new_ne (rvalue a
, rvalue b
,
1049 return new_comparison (GCC_JIT_COMPARISON_NE
,
1053 context::new_lt (rvalue a
, rvalue b
,
1056 return new_comparison (GCC_JIT_COMPARISON_LT
,
1060 context::new_le (rvalue a
, rvalue b
,
1063 return new_comparison (GCC_JIT_COMPARISON_LE
,
1067 context::new_gt (rvalue a
, rvalue b
,
1070 return new_comparison (GCC_JIT_COMPARISON_GT
,
1074 context::new_ge (rvalue a
, rvalue b
,
1077 return new_comparison (GCC_JIT_COMPARISON_GE
,
1082 context::new_call (function func
,
1083 std::vector
<rvalue
> &args
,
1086 /* Treat std::vector as an array, relying on it not being resized: */
1087 rvalue
*as_array_of_wrappers
= &args
[0];
1089 /* Treat the array as being of the underlying pointers, relying on
1090 the wrapper type being such a pointer internally. */
1091 gcc_jit_rvalue
**as_array_of_ptrs
=
1092 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1093 return gcc_jit_context_new_call (m_inner_ctxt
,
1094 loc
.get_inner_location (),
1095 func
.get_inner_function (),
1100 context::new_call (function func
,
1103 std::vector
<rvalue
> args
;
1104 return new_call (func
, args
, loc
);
1108 context::new_call (function func
,
1112 std::vector
<rvalue
> args(1);
1114 return new_call (func
, args
, loc
);
1117 context::new_call (function func
,
1118 rvalue arg0
, rvalue arg1
,
1121 std::vector
<rvalue
> args(2);
1124 return new_call (func
, args
, loc
);
1127 context::new_call (function func
,
1128 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1131 std::vector
<rvalue
> args(3);
1135 return new_call (func
, args
, loc
);
1138 context::new_call (function func
,
1139 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1143 std::vector
<rvalue
> args(4);
1148 return new_call (func
, args
, loc
);
1151 context::new_call (function func
,
1152 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1153 rvalue arg3
, rvalue arg4
,
1156 std::vector
<rvalue
> args(5);
1162 return new_call (func
, args
, loc
);
1165 context::new_call (function func
,
1166 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1167 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1170 std::vector
<rvalue
> args(6);
1177 return new_call (func
, args
, loc
);
1181 context::new_cast (rvalue expr
,
1185 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1186 loc
.get_inner_location (),
1187 expr
.get_inner_rvalue (),
1188 type_
.get_inner_type ()));
1192 context::new_array_access (rvalue ptr
,
1196 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1197 loc
.get_inner_location (),
1198 ptr
.get_inner_rvalue (),
1199 index
.get_inner_rvalue ()));
1203 context::new_case (rvalue min_value
,
1207 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1208 min_value
.get_inner_rvalue (),
1209 max_value
.get_inner_rvalue (),
1210 dest_block
.get_inner_block ()));
1215 object::get_context () const
1217 return context (gcc_jit_object_get_context (m_inner_obj
));
1221 object::get_debug_string () const
1223 return gcc_jit_object_get_debug_string (m_inner_obj
);
1226 inline object::object () : m_inner_obj (NULL
) {}
1227 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1233 inline gcc_jit_object
*
1234 object::get_inner_object () const
1239 inline std::ostream
&
1240 operator << (std::ostream
& stream
, const object
&obj
)
1242 return stream
<< obj
.get_debug_string ();
1246 inline location::location () : object () {}
1247 inline location::location (gcc_jit_location
*loc
)
1248 : object (gcc_jit_location_as_object (loc
))
1251 inline gcc_jit_location
*
1252 location::get_inner_location () const
1254 /* Manual downcast: */
1255 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1259 inline field::field () : object () {}
1260 inline field::field (gcc_jit_field
*inner
)
1261 : object (gcc_jit_field_as_object (inner
))
1264 inline gcc_jit_field
*
1265 field::get_inner_field () const
1267 /* Manual downcast: */
1268 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1272 inline type::type () : object () {}
1273 inline type::type (gcc_jit_type
*inner
)
1274 : object (gcc_jit_type_as_object (inner
))
1277 inline gcc_jit_type
*
1278 type::get_inner_type () const
1280 /* Manual downcast: */
1281 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1285 type::get_pointer ()
1287 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1293 return type (gcc_jit_type_get_const (get_inner_type ()));
1297 type::get_volatile ()
1299 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1303 type::get_aligned (size_t alignment_in_bytes
)
1305 return type (gcc_jit_type_get_aligned (get_inner_type (),
1306 alignment_in_bytes
));
1312 return get_context ().new_rvalue (*this, 0);
1318 return get_context ().new_rvalue (*this, 1);
1322 inline struct_::struct_ () : type (NULL
) {}
1323 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1324 type (gcc_jit_struct_as_type (inner
))
1328 inline gcc_jit_struct
*
1329 struct_::get_inner_struct () const
1331 /* Manual downcast: */
1332 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1336 inline function::function () : object () {}
1337 inline function::function (gcc_jit_function
*inner
)
1338 : object (gcc_jit_function_as_object (inner
))
1341 inline gcc_jit_function
*
1342 function::get_inner_function () const
1344 /* Manual downcast: */
1345 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1349 function::dump_to_dot (const std::string
&path
)
1351 gcc_jit_function_dump_to_dot (get_inner_function (),
1356 function::get_param (int index
) const
1358 return param (gcc_jit_function_get_param (get_inner_function (),
1363 function::new_block ()
1365 return block (gcc_jit_function_new_block (get_inner_function (),
1370 function::new_block (const std::string
&name
)
1372 return block (gcc_jit_function_new_block (get_inner_function (),
1377 function::new_local (type type_
,
1378 const std::string
&name
,
1381 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1382 loc
.get_inner_location (),
1383 type_
.get_inner_type (),
1388 block::get_function () const
1390 return function (gcc_jit_block_get_function ( get_inner_block ()));
1394 block::add_eval (rvalue rvalue
,
1397 gcc_jit_block_add_eval (get_inner_block (),
1398 loc
.get_inner_location (),
1399 rvalue
.get_inner_rvalue ());
1403 block::add_assignment (lvalue lvalue
,
1407 gcc_jit_block_add_assignment (get_inner_block (),
1408 loc
.get_inner_location (),
1409 lvalue
.get_inner_lvalue (),
1410 rvalue
.get_inner_rvalue ());
1414 block::add_assignment_op (lvalue lvalue
,
1415 enum gcc_jit_binary_op op
,
1419 gcc_jit_block_add_assignment_op (get_inner_block (),
1420 loc
.get_inner_location (),
1421 lvalue
.get_inner_lvalue (),
1423 rvalue
.get_inner_rvalue ());
1427 block::add_comment (const std::string
&text
,
1430 gcc_jit_block_add_comment (get_inner_block (),
1431 loc
.get_inner_location (),
1436 block::end_with_conditional (rvalue boolval
,
1441 gcc_jit_block_end_with_conditional (get_inner_block (),
1442 loc
.get_inner_location (),
1443 boolval
.get_inner_rvalue (),
1444 on_true
.get_inner_block (),
1445 on_false
.get_inner_block ());
1449 block::end_with_jump (block target
,
1452 gcc_jit_block_end_with_jump (get_inner_block (),
1453 loc
.get_inner_location (),
1454 target
.get_inner_block ());
1458 block::end_with_return (rvalue rvalue
,
1461 gcc_jit_block_end_with_return (get_inner_block (),
1462 loc
.get_inner_location (),
1463 rvalue
.get_inner_rvalue ());
1467 block::end_with_return (location loc
)
1469 gcc_jit_block_end_with_void_return (get_inner_block (),
1470 loc
.get_inner_location ());
1474 block::end_with_switch (rvalue expr
,
1475 block default_block
,
1476 std::vector
<case_
> cases
,
1479 /* Treat std::vector as an array, relying on it not being resized: */
1480 case_
*as_array_of_wrappers
= &cases
[0];
1482 /* Treat the array as being of the underlying pointers, relying on
1483 the wrapper type being such a pointer internally. */
1484 gcc_jit_case
**as_array_of_ptrs
=
1485 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1486 gcc_jit_block_end_with_switch (get_inner_block (),
1487 loc
.get_inner_location (),
1488 expr
.get_inner_rvalue (),
1489 default_block
.get_inner_block (),
1495 block::add_call (function other
,
1498 rvalue c
= get_context ().new_call (other
, loc
);
1503 block::add_call (function other
,
1507 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1512 block::add_call (function other
,
1513 rvalue arg0
, rvalue arg1
,
1516 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1521 block::add_call (function other
,
1522 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1525 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1531 block::add_call (function other
,
1532 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1535 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1541 function::operator() (location loc
)
1543 return get_context ().new_call (*this, loc
);
1546 function::operator() (rvalue arg0
,
1549 return get_context ().new_call (*this,
1554 function::operator() (rvalue arg0
, rvalue arg1
,
1557 return get_context ().new_call (*this,
1562 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1565 return get_context ().new_call (*this,
1571 inline block::block () : object () {}
1572 inline block::block (gcc_jit_block
*inner
)
1573 : object (gcc_jit_block_as_object (inner
))
1576 inline gcc_jit_block
*
1577 block::get_inner_block () const
1579 /* Manual downcast: */
1580 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1584 inline rvalue::rvalue () : object () {}
1585 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1586 : object (gcc_jit_rvalue_as_object (inner
))
1589 inline gcc_jit_rvalue
*
1590 rvalue::get_inner_rvalue () const
1592 /* Manual downcast: */
1593 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1599 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1603 rvalue::access_field (field field
,
1606 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1607 loc
.get_inner_location (),
1608 field
.get_inner_field ()));
1612 rvalue::dereference_field (field field
,
1615 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1616 loc
.get_inner_location (),
1617 field
.get_inner_field ()));
1621 rvalue::dereference (location loc
)
1623 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1624 loc
.get_inner_location ()));
1628 rvalue::cast_to (type type_
,
1631 return get_context ().new_cast (*this, type_
, loc
);
1635 rvalue::operator[] (rvalue index
)
1637 return get_context ().new_array_access (*this, index
);
1641 rvalue::operator[] (int index
)
1643 context ctxt
= get_context ();
1644 type int_t
= ctxt
.get_int_type
<int> ();
1645 return ctxt
.new_array_access (*this,
1646 ctxt
.new_rvalue (int_t
,
1650 // class lvalue : public rvalue
1651 inline lvalue::lvalue () : rvalue () {}
1652 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1653 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1656 inline gcc_jit_lvalue
*
1657 lvalue::get_inner_lvalue () const
1659 /* Manual downcast: */
1660 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1664 lvalue::access_field (field field
, location loc
)
1666 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1667 loc
.get_inner_location (),
1668 field
.get_inner_field ()));
1672 lvalue::get_address (location loc
)
1674 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1675 loc
.get_inner_location ()));
1678 // class param : public lvalue
1679 inline param::param () : lvalue () {}
1680 inline param::param (gcc_jit_param
*inner
)
1681 : lvalue (gcc_jit_param_as_lvalue (inner
))
1684 // class case_ : public object
1685 inline case_::case_ () : object () {}
1686 inline case_::case_ (gcc_jit_case
*inner
)
1687 : object (gcc_jit_case_as_object (inner
))
1691 inline gcc_jit_case
*
1692 case_::get_inner_case () const
1694 /* Manual downcast: */
1695 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1698 /* Overloaded operators. */
1700 inline rvalue
operator- (rvalue a
)
1702 return a
.get_context ().new_minus (a
.get_type (), a
);
1704 inline rvalue
operator~ (rvalue a
)
1706 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1708 inline rvalue
operator! (rvalue a
)
1710 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1714 inline rvalue
operator+ (rvalue a
, rvalue b
)
1716 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1718 inline rvalue
operator- (rvalue a
, rvalue b
)
1720 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1722 inline rvalue
operator* (rvalue a
, rvalue b
)
1724 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1726 inline rvalue
operator/ (rvalue a
, rvalue b
)
1728 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1730 inline rvalue
operator% (rvalue a
, rvalue b
)
1732 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1734 inline rvalue
operator& (rvalue a
, rvalue b
)
1736 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1738 inline rvalue
operator^ (rvalue a
, rvalue b
)
1740 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1742 inline rvalue
operator| (rvalue a
, rvalue b
)
1744 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1746 inline rvalue
operator&& (rvalue a
, rvalue b
)
1748 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1750 inline rvalue
operator|| (rvalue a
, rvalue b
)
1752 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1756 inline rvalue
operator== (rvalue a
, rvalue b
)
1758 return a
.get_context ().new_eq (a
, b
);
1760 inline rvalue
operator!= (rvalue a
, rvalue b
)
1762 return a
.get_context ().new_ne (a
, b
);
1764 inline rvalue
operator< (rvalue a
, rvalue b
)
1766 return a
.get_context ().new_lt (a
, b
);
1768 inline rvalue
operator<= (rvalue a
, rvalue b
)
1770 return a
.get_context ().new_le (a
, b
);
1772 inline rvalue
operator> (rvalue a
, rvalue b
)
1774 return a
.get_context ().new_gt (a
, b
);
1776 inline rvalue
operator>= (rvalue a
, rvalue b
)
1778 return a
.get_context ().new_ge (a
, b
);
1781 /* Dereferencing. */
1782 inline lvalue
operator* (rvalue ptr
)
1784 return ptr
.dereference ();
1791 m_inner_timer
= gcc_jit_timer_new ();
1795 timer::timer (gcc_jit_timer
*inner_timer
)
1797 m_inner_timer
= inner_timer
;
1801 timer::push (const char *item_name
)
1803 gcc_jit_timer_push (m_inner_timer
, item_name
);
1808 timer::pop (const char *item_name
)
1810 gcc_jit_timer_pop (m_inner_timer
, item_name
);
1814 timer::print (FILE *f_out
) const
1816 gcc_jit_timer_print (m_inner_timer
, f_out
);
1819 inline gcc_jit_timer
*
1820 timer::get_inner_timer () const
1822 return m_inner_timer
;
1828 gcc_jit_timer_release (m_inner_timer
);
1829 m_inner_timer
= NULL
;
1835 auto_time::auto_time (timer t
, const char *item_name
)
1837 m_item_name (item_name
)
1843 auto_time::auto_time (context ctxt
, const char *item_name
)
1844 : m_timer (ctxt
.get_timer ()),
1845 m_item_name (item_name
)
1847 m_timer
.push (item_name
);
1851 auto_time::~auto_time ()
1853 m_timer
.pop (m_item_name
);
1856 } // namespace gccjit
1858 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */