1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2015 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. */
50 /* Errors within the API become C++ exceptions of this class. */
58 context
get_context () const;
60 std::string
get_debug_string () const;
64 object (gcc_jit_object
*obj
);
66 gcc_jit_object
*get_inner_object () const;
69 gcc_jit_object
*m_inner_obj
;
72 inline std::ostream
& operator << (std::ostream
& stream
, const object
&obj
);
74 /* Some client code will want to supply source code locations, others
75 won't. To avoid doubling the number of entrypoints, everything
76 accepting a location also has a default argument. To do this, the
77 other classes need to see that "location" has a default constructor,
78 hence we need to declare it first. */
79 class location
: public object
83 location (gcc_jit_location
*loc
);
85 gcc_jit_location
*get_inner_location () const;
91 static context
acquire ();
93 context (gcc_jit_context
*ctxt
);
95 gccjit::context
new_child_context ();
97 gcc_jit_context
*get_inner_context () { return m_inner_ctxt
; }
101 gcc_jit_result
*compile ();
103 void compile_to_file (enum gcc_jit_output_kind output_kind
,
104 const char *output_path
);
106 void dump_to_file (const std::string
&path
,
107 bool update_locations
);
109 void set_logfile (FILE *logfile
,
113 void dump_reproducer_to_file (const char *path
);
115 void set_str_option (enum gcc_jit_str_option opt
,
118 void set_int_option (enum gcc_jit_int_option opt
,
121 void set_bool_option (enum gcc_jit_bool_option opt
,
124 void set_bool_allow_unreachable_blocks (int bool_value
);
126 void add_command_line_option (const char *optname
);
129 new_location (const std::string
&filename
,
133 type
get_type (enum gcc_jit_types kind
);
134 type
get_int_type (size_t num_bytes
, int is_signed
);
136 /* A way to map a specific int type, using the compiler to
137 get the details automatically e.g.:
138 gccjit::type type = get_int_type <my_int_type_t> (); */
139 template <typename T
>
140 type
get_int_type ();
142 type
new_array_type (type element_type
, int num_elements
,
143 location loc
= location ());
145 field
new_field (type type_
, const std::string
&name
,
146 location loc
= location ());
148 struct_
new_struct_type (const std::string
&name
,
149 std::vector
<field
> &fields
,
150 location loc
= location ());
152 struct_
new_opaque_struct_type (const std::string
&name
,
153 location loc
= location ());
155 param
new_param (type type_
,
156 const std::string
&name
,
157 location loc
= location ());
159 function
new_function (enum gcc_jit_function_kind kind
,
161 const std::string
&name
,
162 std::vector
<param
> ¶ms
,
164 location loc
= location ());
166 function
get_builtin_function (const std::string
&name
);
168 lvalue
new_global (enum gcc_jit_global_kind kind
,
170 const std::string
&name
,
171 location loc
= location ());
173 rvalue
new_rvalue (type numeric_type
,
175 rvalue
new_rvalue (type numeric_type
,
177 rvalue
zero (type numeric_type
) const;
178 rvalue
one (type numeric_type
) const;
179 rvalue
new_rvalue (type numeric_type
,
181 rvalue
new_rvalue (type pointer_type
,
183 rvalue
new_rvalue (const std::string
&value
) const;
185 /* Generic unary operations... */
186 rvalue
new_unary_op (enum gcc_jit_unary_op op
,
189 location loc
= location ());
191 /* ...and shorter ways to spell the various specific kinds of
193 rvalue
new_minus (type result_type
,
195 location loc
= location ());
196 rvalue
new_bitwise_negate (type result_type
,
198 location loc
= location ());
199 rvalue
new_logical_negate (type result_type
,
201 location loc
= location ());
203 /* Generic binary operations... */
204 rvalue
new_binary_op (enum gcc_jit_binary_op op
,
207 location loc
= location ());
209 /* ...and shorter ways to spell the various specific kinds of
211 rvalue
new_plus (type result_type
,
213 location loc
= location ());
214 rvalue
new_minus (type result_type
,
216 location loc
= location ());
217 rvalue
new_mult (type result_type
,
219 location loc
= location ());
220 rvalue
new_divide (type result_type
,
222 location loc
= location ());
223 rvalue
new_modulo (type result_type
,
225 location loc
= location ());
226 rvalue
new_bitwise_and (type result_type
,
228 location loc
= location ());
229 rvalue
new_bitwise_xor (type result_type
,
231 location loc
= location ());
232 rvalue
new_bitwise_or (type result_type
,
234 location loc
= location ());
235 rvalue
new_logical_and (type result_type
,
237 location loc
= location ());
238 rvalue
new_logical_or (type result_type
,
240 location loc
= location ());
242 /* Generic comparisons... */
243 rvalue
new_comparison (enum gcc_jit_comparison op
,
245 location loc
= location ());
246 /* ...and shorter ways to spell the various specific kinds of
248 rvalue
new_eq (rvalue a
, rvalue b
,
249 location loc
= location ());
250 rvalue
new_ne (rvalue a
, rvalue b
,
251 location loc
= location ());
252 rvalue
new_lt (rvalue a
, rvalue b
,
253 location loc
= location ());
254 rvalue
new_le (rvalue a
, rvalue b
,
255 location loc
= location ());
256 rvalue
new_gt (rvalue a
, rvalue b
,
257 location loc
= location ());
258 rvalue
new_ge (rvalue a
, rvalue b
,
259 location loc
= location ());
261 /* The most general way of creating a function call. */
262 rvalue
new_call (function func
,
263 std::vector
<rvalue
> &args
,
264 location loc
= location ());
266 /* In addition, we provide a series of overloaded "new_call" methods
267 for specific numbers of args (from 0 - 6), to avoid the need for
268 client code to manually build a vector. */
269 rvalue
new_call (function func
,
270 location loc
= location ());
271 rvalue
new_call (function func
,
273 location loc
= location ());
274 rvalue
new_call (function func
,
275 rvalue arg0
, rvalue arg1
,
276 location loc
= location ());
277 rvalue
new_call (function func
,
278 rvalue arg0
, rvalue arg1
, rvalue arg2
,
279 location loc
= location ());
280 rvalue
new_call (function func
,
281 rvalue arg0
, rvalue arg1
, rvalue arg2
,
283 location loc
= location ());
284 rvalue
new_call (function func
,
285 rvalue arg0
, rvalue arg1
, rvalue arg2
,
286 rvalue arg3
, rvalue arg4
,
287 location loc
= location ());
288 rvalue
new_call (function func
,
289 rvalue arg0
, rvalue arg1
, rvalue arg2
,
290 rvalue arg3
, rvalue arg4
, rvalue arg5
,
291 location loc
= location ());
293 rvalue
new_cast (rvalue expr
,
295 location loc
= location ());
297 lvalue
new_array_access (rvalue ptr
,
299 location loc
= location ());
301 case_
new_case (rvalue min_value
,
306 gcc_jit_context
*m_inner_ctxt
;
309 class field
: public object
313 field (gcc_jit_field
*inner
);
315 gcc_jit_field
*get_inner_field () const;
318 class type
: public object
322 type (gcc_jit_type
*inner
);
324 gcc_jit_type
*get_inner_type () const;
327 type
get_volatile ();
329 // Shortcuts for getting values of numeric types:
334 class struct_
: public type
338 struct_ (gcc_jit_struct
*inner
);
340 gcc_jit_struct
*get_inner_struct () const;
343 class function
: public object
347 function (gcc_jit_function
*func
);
349 gcc_jit_function
*get_inner_function () const;
351 void dump_to_dot (const std::string
&path
);
353 param
get_param (int index
) const;
356 block
new_block (const std::string
&name
);
358 lvalue
new_local (type type_
,
359 const std::string
&name
,
360 location loc
= location ());
362 /* A series of overloaded operator () with various numbers of arguments
363 for a very terse way of creating a call to this function. The call
364 is created within the same context as the function itself, which may
365 not be what you want. */
366 rvalue
operator() (location loc
= location ());
367 rvalue
operator() (rvalue arg0
,
368 location loc
= location ());
369 rvalue
operator() (rvalue arg0
, rvalue arg1
,
370 location loc
= location ());
371 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
372 location loc
= location ());
375 class block
: public object
379 block (gcc_jit_block
*inner
);
381 gcc_jit_block
*get_inner_block () const;
383 function
get_function () const;
385 void add_eval (rvalue rvalue
,
386 location loc
= location ());
388 void add_assignment (lvalue lvalue
,
390 location loc
= location ());
392 void add_assignment_op (lvalue lvalue
,
393 enum gcc_jit_binary_op op
,
395 location loc
= location ());
397 /* A way to add a function call to the body of a function being
398 defined, with various numbers of args. */
399 rvalue
add_call (function other
,
400 location loc
= location ());
401 rvalue
add_call (function other
,
403 location loc
= location ());
404 rvalue
add_call (function other
,
405 rvalue arg0
, rvalue arg1
,
406 location loc
= location ());
407 rvalue
add_call (function other
,
408 rvalue arg0
, rvalue arg1
, rvalue arg2
,
409 location loc
= location ());
410 rvalue
add_call (function other
,
411 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
412 location loc
= location ());
414 void add_comment (const std::string
&text
,
415 location loc
= location ());
417 void end_with_conditional (rvalue boolval
,
420 location loc
= location ());
422 void end_with_jump (block target
,
423 location loc
= location ());
425 void end_with_return (rvalue rvalue
,
426 location loc
= location ());
427 void end_with_return (location loc
= location ());
429 void end_with_switch (rvalue expr
,
431 std::vector
<case_
> cases
,
432 location loc
= location ());
435 class rvalue
: public object
439 rvalue (gcc_jit_rvalue
*inner
);
440 gcc_jit_rvalue
*get_inner_rvalue () const;
444 rvalue
access_field (field field
,
445 location loc
= location ());
447 lvalue
dereference_field (field field
,
448 location loc
= location ());
450 lvalue
dereference (location loc
= location ());
452 rvalue
cast_to (type type_
,
453 location loc
= location ());
456 lvalue
operator[] (rvalue index
);
457 lvalue
operator[] (int index
);
460 class lvalue
: public rvalue
464 lvalue (gcc_jit_lvalue
*inner
);
466 gcc_jit_lvalue
*get_inner_lvalue () const;
468 lvalue
access_field (field field
,
469 location loc
= location ());
471 rvalue
get_address (location loc
= location ());
474 class param
: public lvalue
478 param (gcc_jit_param
*inner
);
480 gcc_jit_param
*get_inner_param () const;
483 class case_
: public object
487 case_ (gcc_jit_case
*inner
);
489 gcc_jit_case
*get_inner_case () const;
492 /* Overloaded operators, for those who want the most terse API
493 (at the possible risk of being a little too magical).
495 In each case, the first parameter is used to determine which context
496 owns the resulting expression, and, where appropriate, what the
499 /* Unary operators. */
500 rvalue
operator- (rvalue a
); // unary minus
501 rvalue
operator~ (rvalue a
); // unary bitwise negate
502 rvalue
operator! (rvalue a
); // unary logical negate
504 /* Binary operators. */
505 rvalue
operator+ (rvalue a
, rvalue b
);
506 rvalue
operator- (rvalue a
, rvalue b
);
507 rvalue
operator* (rvalue a
, rvalue b
);
508 rvalue
operator/ (rvalue a
, rvalue b
);
509 rvalue
operator% (rvalue a
, rvalue b
);
510 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
511 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
512 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
513 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
514 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
517 rvalue
operator== (rvalue a
, rvalue b
);
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
);
525 lvalue
operator* (rvalue ptr
);
528 /****************************************************************************
529 Implementation of the API
530 ****************************************************************************/
534 inline context
context::acquire ()
536 return context (gcc_jit_context_acquire ());
538 inline context::context () : m_inner_ctxt (NULL
) {}
539 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
545 inline gccjit::context
546 context::new_child_context ()
548 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
554 gcc_jit_context_release (m_inner_ctxt
);
558 inline gcc_jit_result
*
561 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
568 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
569 const char *output_path
)
571 gcc_jit_context_compile_to_file (m_inner_ctxt
,
577 context::dump_to_file (const std::string
&path
,
578 bool update_locations
)
580 gcc_jit_context_dump_to_file (m_inner_ctxt
,
586 context::set_logfile (FILE *logfile
,
590 gcc_jit_context_set_logfile (m_inner_ctxt
,
597 context::dump_reproducer_to_file (const char *path
)
599 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
604 context::set_str_option (enum gcc_jit_str_option opt
,
607 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
612 context::set_int_option (enum gcc_jit_int_option opt
,
615 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
620 context::set_bool_option (enum gcc_jit_bool_option opt
,
623 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
627 context::set_bool_allow_unreachable_blocks (int bool_value
)
629 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
634 context::add_command_line_option (const char *optname
)
636 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
640 context::new_location (const std::string
&filename
,
644 return location (gcc_jit_context_new_location (m_inner_ctxt
,
651 context::get_type (enum gcc_jit_types kind
)
653 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
657 context::get_int_type (size_t num_bytes
, int is_signed
)
659 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
664 template <typename T
>
666 context::get_int_type ()
668 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
672 context::new_array_type (type element_type
, int num_elements
, location loc
)
674 return type (gcc_jit_context_new_array_type (
676 loc
.get_inner_location (),
677 element_type
.get_inner_type (),
682 context::new_field (type type_
, const std::string
&name
, location loc
)
684 return field (gcc_jit_context_new_field (m_inner_ctxt
,
685 loc
.get_inner_location (),
686 type_
.get_inner_type (),
691 context::new_struct_type (const std::string
&name
,
692 std::vector
<field
> &fields
,
695 /* Treat std::vector as an array, relying on it not being resized: */
696 field
*as_array_of_wrappers
= &fields
[0];
698 /* Treat the array as being of the underlying pointers, relying on
699 the wrapper type being such a pointer internally. */
700 gcc_jit_field
**as_array_of_ptrs
=
701 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
703 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
704 loc
.get_inner_location (),
711 context::new_opaque_struct_type (const std::string
&name
,
714 return struct_ (gcc_jit_context_new_opaque_struct (
716 loc
.get_inner_location (),
721 context::new_param (type type_
,
722 const std::string
&name
,
725 return param (gcc_jit_context_new_param (m_inner_ctxt
,
726 loc
.get_inner_location (),
727 type_
.get_inner_type (),
732 context::new_function (enum gcc_jit_function_kind kind
,
734 const std::string
&name
,
735 std::vector
<param
> ¶ms
,
739 /* Treat std::vector as an array, relying on it not being resized: */
740 param
*as_array_of_wrappers
= ¶ms
[0];
742 /* Treat the array as being of the underlying pointers, relying on
743 the wrapper type being such a pointer internally. */
744 gcc_jit_param
**as_array_of_ptrs
=
745 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
747 return function (gcc_jit_context_new_function (m_inner_ctxt
,
748 loc
.get_inner_location (),
750 return_type
.get_inner_type (),
758 context::get_builtin_function (const std::string
&name
)
760 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
765 context::new_global (enum gcc_jit_global_kind kind
,
767 const std::string
&name
,
770 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
771 loc
.get_inner_location (),
773 type_
.get_inner_type (),
778 context::new_rvalue (type numeric_type
,
782 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
783 numeric_type
.get_inner_type (),
788 context::new_rvalue (type numeric_type
,
792 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
793 numeric_type
.get_inner_type (),
798 context::zero (type numeric_type
) const
800 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
801 numeric_type
.get_inner_type ()));
805 context::one (type numeric_type
) const
807 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
808 numeric_type
.get_inner_type ()));
812 context::new_rvalue (type numeric_type
,
816 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
817 numeric_type
.get_inner_type (),
822 context::new_rvalue (type pointer_type
,
826 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
827 pointer_type
.get_inner_type (),
832 context::new_rvalue (const std::string
&value
) const
835 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
839 context::new_unary_op (enum gcc_jit_unary_op op
,
844 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
845 loc
.get_inner_location (),
847 result_type
.get_inner_type (),
848 a
.get_inner_rvalue ()));
851 context::new_minus (type result_type
,
855 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
856 result_type
, a
, loc
));
859 context::new_bitwise_negate (type result_type
,
863 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
864 result_type
, a
, loc
));
867 context::new_logical_negate (type result_type
,
871 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
872 result_type
, a
, loc
));
876 context::new_binary_op (enum gcc_jit_binary_op op
,
881 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
882 loc
.get_inner_location (),
884 result_type
.get_inner_type (),
885 a
.get_inner_rvalue (),
886 b
.get_inner_rvalue ()));
889 context::new_plus (type result_type
,
893 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
894 result_type
, a
, b
, loc
);
897 context::new_minus (type result_type
,
901 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
902 result_type
, a
, b
, loc
);
905 context::new_mult (type result_type
,
909 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
910 result_type
, a
, b
, loc
);
913 context::new_divide (type result_type
,
917 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
918 result_type
, a
, b
, loc
);
921 context::new_modulo (type result_type
,
925 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
926 result_type
, a
, b
, loc
);
929 context::new_bitwise_and (type result_type
,
933 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
934 result_type
, a
, b
, loc
);
937 context::new_bitwise_xor (type result_type
,
941 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
942 result_type
, a
, b
, loc
);
945 context::new_bitwise_or (type result_type
,
949 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
950 result_type
, a
, b
, loc
);
953 context::new_logical_and (type result_type
,
957 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
958 result_type
, a
, b
, loc
);
961 context::new_logical_or (type result_type
,
965 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
966 result_type
, a
, b
, loc
);
970 context::new_comparison (enum gcc_jit_comparison op
,
974 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
975 loc
.get_inner_location (),
977 a
.get_inner_rvalue (),
978 b
.get_inner_rvalue ()));
981 context::new_eq (rvalue a
, rvalue b
,
984 return new_comparison (GCC_JIT_COMPARISON_EQ
,
988 context::new_ne (rvalue a
, rvalue b
,
991 return new_comparison (GCC_JIT_COMPARISON_NE
,
995 context::new_lt (rvalue a
, rvalue b
,
998 return new_comparison (GCC_JIT_COMPARISON_LT
,
1002 context::new_le (rvalue a
, rvalue b
,
1005 return new_comparison (GCC_JIT_COMPARISON_LE
,
1009 context::new_gt (rvalue a
, rvalue b
,
1012 return new_comparison (GCC_JIT_COMPARISON_GT
,
1016 context::new_ge (rvalue a
, rvalue b
,
1019 return new_comparison (GCC_JIT_COMPARISON_GE
,
1024 context::new_call (function func
,
1025 std::vector
<rvalue
> &args
,
1028 /* Treat std::vector as an array, relying on it not being resized: */
1029 rvalue
*as_array_of_wrappers
= &args
[0];
1031 /* Treat the array as being of the underlying pointers, relying on
1032 the wrapper type being such a pointer internally. */
1033 gcc_jit_rvalue
**as_array_of_ptrs
=
1034 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1035 return gcc_jit_context_new_call (m_inner_ctxt
,
1036 loc
.get_inner_location (),
1037 func
.get_inner_function (),
1042 context::new_call (function func
,
1045 std::vector
<rvalue
> args
;
1046 return new_call (func
, args
, loc
);
1050 context::new_call (function func
,
1054 std::vector
<rvalue
> args(1);
1056 return new_call (func
, args
, loc
);
1059 context::new_call (function func
,
1060 rvalue arg0
, rvalue arg1
,
1063 std::vector
<rvalue
> args(2);
1066 return new_call (func
, args
, loc
);
1069 context::new_call (function func
,
1070 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1073 std::vector
<rvalue
> args(3);
1077 return new_call (func
, args
, loc
);
1080 context::new_call (function func
,
1081 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1085 std::vector
<rvalue
> args(4);
1090 return new_call (func
, args
, loc
);
1093 context::new_call (function func
,
1094 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1095 rvalue arg3
, rvalue arg4
,
1098 std::vector
<rvalue
> args(5);
1104 return new_call (func
, args
, loc
);
1107 context::new_call (function func
,
1108 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1109 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1112 std::vector
<rvalue
> args(6);
1119 return new_call (func
, args
, loc
);
1123 context::new_cast (rvalue expr
,
1127 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1128 loc
.get_inner_location (),
1129 expr
.get_inner_rvalue (),
1130 type_
.get_inner_type ()));
1134 context::new_array_access (rvalue ptr
,
1138 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1139 loc
.get_inner_location (),
1140 ptr
.get_inner_rvalue (),
1141 index
.get_inner_rvalue ()));
1145 context::new_case (rvalue min_value
,
1149 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1150 min_value
.get_inner_rvalue (),
1151 max_value
.get_inner_rvalue (),
1152 dest_block
.get_inner_block ()));
1157 object::get_context () const
1159 return context (gcc_jit_object_get_context (m_inner_obj
));
1163 object::get_debug_string () const
1165 return gcc_jit_object_get_debug_string (m_inner_obj
);
1168 inline object::object () : m_inner_obj (NULL
) {}
1169 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1175 inline gcc_jit_object
*
1176 object::get_inner_object () const
1181 inline std::ostream
&
1182 operator << (std::ostream
& stream
, const object
&obj
)
1184 return stream
<< obj
.get_debug_string ();
1188 inline location::location () : object () {}
1189 inline location::location (gcc_jit_location
*loc
)
1190 : object (gcc_jit_location_as_object (loc
))
1193 inline gcc_jit_location
*
1194 location::get_inner_location () const
1196 /* Manual downcast: */
1197 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1201 inline field::field () : object () {}
1202 inline field::field (gcc_jit_field
*inner
)
1203 : object (gcc_jit_field_as_object (inner
))
1206 inline gcc_jit_field
*
1207 field::get_inner_field () const
1209 /* Manual downcast: */
1210 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1214 inline type::type () : object () {}
1215 inline type::type (gcc_jit_type
*inner
)
1216 : object (gcc_jit_type_as_object (inner
))
1219 inline gcc_jit_type
*
1220 type::get_inner_type () const
1222 /* Manual downcast: */
1223 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1227 type::get_pointer ()
1229 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1233 type::get_volatile ()
1235 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1241 return get_context ().new_rvalue (*this, 0);
1247 return get_context ().new_rvalue (*this, 1);
1251 inline struct_::struct_ () : type (NULL
) {}
1252 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1253 type (gcc_jit_struct_as_type (inner
))
1257 inline gcc_jit_struct
*
1258 struct_::get_inner_struct () const
1260 /* Manual downcast: */
1261 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1265 inline function::function () : object () {}
1266 inline function::function (gcc_jit_function
*inner
)
1267 : object (gcc_jit_function_as_object (inner
))
1270 inline gcc_jit_function
*
1271 function::get_inner_function () const
1273 /* Manual downcast: */
1274 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1278 function::dump_to_dot (const std::string
&path
)
1280 gcc_jit_function_dump_to_dot (get_inner_function (),
1285 function::get_param (int index
) const
1287 return param (gcc_jit_function_get_param (get_inner_function (),
1292 function::new_block ()
1294 return block (gcc_jit_function_new_block (get_inner_function (),
1299 function::new_block (const std::string
&name
)
1301 return block (gcc_jit_function_new_block (get_inner_function (),
1306 function::new_local (type type_
,
1307 const std::string
&name
,
1310 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1311 loc
.get_inner_location (),
1312 type_
.get_inner_type (),
1317 block::get_function () const
1319 return function (gcc_jit_block_get_function ( get_inner_block ()));
1323 block::add_eval (rvalue rvalue
,
1326 gcc_jit_block_add_eval (get_inner_block (),
1327 loc
.get_inner_location (),
1328 rvalue
.get_inner_rvalue ());
1332 block::add_assignment (lvalue lvalue
,
1336 gcc_jit_block_add_assignment (get_inner_block (),
1337 loc
.get_inner_location (),
1338 lvalue
.get_inner_lvalue (),
1339 rvalue
.get_inner_rvalue ());
1343 block::add_assignment_op (lvalue lvalue
,
1344 enum gcc_jit_binary_op op
,
1348 gcc_jit_block_add_assignment_op (get_inner_block (),
1349 loc
.get_inner_location (),
1350 lvalue
.get_inner_lvalue (),
1352 rvalue
.get_inner_rvalue ());
1356 block::add_comment (const std::string
&text
,
1359 gcc_jit_block_add_comment (get_inner_block (),
1360 loc
.get_inner_location (),
1365 block::end_with_conditional (rvalue boolval
,
1370 gcc_jit_block_end_with_conditional (get_inner_block (),
1371 loc
.get_inner_location (),
1372 boolval
.get_inner_rvalue (),
1373 on_true
.get_inner_block (),
1374 on_false
.get_inner_block ());
1378 block::end_with_jump (block target
,
1381 gcc_jit_block_end_with_jump (get_inner_block (),
1382 loc
.get_inner_location (),
1383 target
.get_inner_block ());
1387 block::end_with_return (rvalue rvalue
,
1390 gcc_jit_block_end_with_return (get_inner_block (),
1391 loc
.get_inner_location (),
1392 rvalue
.get_inner_rvalue ());
1396 block::end_with_return (location loc
)
1398 gcc_jit_block_end_with_void_return (get_inner_block (),
1399 loc
.get_inner_location ());
1403 block::end_with_switch (rvalue expr
,
1404 block default_block
,
1405 std::vector
<case_
> cases
,
1408 /* Treat std::vector as an array, relying on it not being resized: */
1409 case_
*as_array_of_wrappers
= &cases
[0];
1411 /* Treat the array as being of the underlying pointers, relying on
1412 the wrapper type being such a pointer internally. */
1413 gcc_jit_case
**as_array_of_ptrs
=
1414 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1415 gcc_jit_block_end_with_switch (get_inner_block (),
1416 loc
.get_inner_location (),
1417 expr
.get_inner_rvalue (),
1418 default_block
.get_inner_block (),
1424 block::add_call (function other
,
1427 rvalue c
= get_context ().new_call (other
, loc
);
1432 block::add_call (function other
,
1436 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1441 block::add_call (function other
,
1442 rvalue arg0
, rvalue arg1
,
1445 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1450 block::add_call (function other
,
1451 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1454 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1460 block::add_call (function other
,
1461 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1464 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1470 function::operator() (location loc
)
1472 return get_context ().new_call (*this, loc
);
1475 function::operator() (rvalue arg0
,
1478 return get_context ().new_call (*this,
1483 function::operator() (rvalue arg0
, rvalue arg1
,
1486 return get_context ().new_call (*this,
1491 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1494 return get_context ().new_call (*this,
1500 inline block::block () : object () {}
1501 inline block::block (gcc_jit_block
*inner
)
1502 : object (gcc_jit_block_as_object (inner
))
1505 inline gcc_jit_block
*
1506 block::get_inner_block () const
1508 /* Manual downcast: */
1509 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1513 inline rvalue::rvalue () : object () {}
1514 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1515 : object (gcc_jit_rvalue_as_object (inner
))
1518 inline gcc_jit_rvalue
*
1519 rvalue::get_inner_rvalue () const
1521 /* Manual downcast: */
1522 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1528 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1532 rvalue::access_field (field field
,
1535 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1536 loc
.get_inner_location (),
1537 field
.get_inner_field ()));
1541 rvalue::dereference_field (field field
,
1544 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1545 loc
.get_inner_location (),
1546 field
.get_inner_field ()));
1550 rvalue::dereference (location loc
)
1552 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1553 loc
.get_inner_location ()));
1557 rvalue::cast_to (type type_
,
1560 return get_context ().new_cast (*this, type_
, loc
);
1564 rvalue::operator[] (rvalue index
)
1566 return get_context ().new_array_access (*this, index
);
1570 rvalue::operator[] (int index
)
1572 context ctxt
= get_context ();
1573 type int_t
= ctxt
.get_int_type
<int> ();
1574 return ctxt
.new_array_access (*this,
1575 ctxt
.new_rvalue (int_t
,
1579 // class lvalue : public rvalue
1580 inline lvalue::lvalue () : rvalue () {}
1581 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1582 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1585 inline gcc_jit_lvalue
*
1586 lvalue::get_inner_lvalue () const
1588 /* Manual downcast: */
1589 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1593 lvalue::access_field (field field
, location loc
)
1595 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1596 loc
.get_inner_location (),
1597 field
.get_inner_field ()));
1601 lvalue::get_address (location loc
)
1603 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1604 loc
.get_inner_location ()));
1607 // class param : public lvalue
1608 inline param::param () : lvalue () {}
1609 inline param::param (gcc_jit_param
*inner
)
1610 : lvalue (gcc_jit_param_as_lvalue (inner
))
1613 // class case_ : public object
1614 inline case_::case_ () : object () {}
1615 inline case_::case_ (gcc_jit_case
*inner
)
1616 : object (gcc_jit_case_as_object (inner
))
1620 inline gcc_jit_case
*
1621 case_::get_inner_case () const
1623 /* Manual downcast: */
1624 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1627 /* Overloaded operators. */
1629 inline rvalue
operator- (rvalue a
)
1631 return a
.get_context ().new_minus (a
.get_type (), a
);
1633 inline rvalue
operator~ (rvalue a
)
1635 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1637 inline rvalue
operator! (rvalue a
)
1639 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1643 inline rvalue
operator+ (rvalue a
, rvalue b
)
1645 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1647 inline rvalue
operator- (rvalue a
, rvalue b
)
1649 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1651 inline rvalue
operator* (rvalue a
, rvalue b
)
1653 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1655 inline rvalue
operator/ (rvalue a
, rvalue b
)
1657 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1659 inline rvalue
operator% (rvalue a
, rvalue b
)
1661 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1663 inline rvalue
operator& (rvalue a
, rvalue b
)
1665 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1667 inline rvalue
operator^ (rvalue a
, rvalue b
)
1669 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1671 inline rvalue
operator| (rvalue a
, rvalue b
)
1673 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1675 inline rvalue
operator&& (rvalue a
, rvalue b
)
1677 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1679 inline rvalue
operator|| (rvalue a
, rvalue b
)
1681 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1685 inline rvalue
operator== (rvalue a
, rvalue b
)
1687 return a
.get_context ().new_eq (a
, b
);
1689 inline rvalue
operator!= (rvalue a
, rvalue b
)
1691 return a
.get_context ().new_ne (a
, b
);
1693 inline rvalue
operator< (rvalue a
, rvalue b
)
1695 return a
.get_context ().new_lt (a
, b
);
1697 inline rvalue
operator<= (rvalue a
, rvalue b
)
1699 return a
.get_context ().new_le (a
, b
);
1701 inline rvalue
operator> (rvalue a
, rvalue b
)
1703 return a
.get_context ().new_gt (a
, b
);
1705 inline rvalue
operator>= (rvalue a
, rvalue b
)
1707 return a
.get_context ().new_ge (a
, b
);
1710 /* Dereferencing. */
1711 inline lvalue
operator* (rvalue ptr
)
1713 return ptr
.dereference ();
1716 } // namespace gccjit
1718 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */