PR jit/66546: Add gcc_jit_context_set_bool_allow_unreachable_blocks
[official-gcc.git] / gcc / jit / libgccjit++.h
blobcbdc96fbd4727e43199a7e48ff41cf58fa930488
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)
9 any later version.
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"
25 #include <limits>
26 #include <ostream>
27 #include <vector>
29 /****************************************************************************
30 C++ API
31 ****************************************************************************/
33 namespace gccjit
35 /* Indentation indicates inheritance. */
36 class context;
37 class error;
38 class object;
39 class location;
40 class field;
41 class type;
42 class struct_;
43 class function;
44 class block;
45 class rvalue;
46 class lvalue;
47 class param;
49 /* Errors within the API become C++ exceptions of this class. */
50 class error
54 class object
56 public:
57 context get_context () const;
59 std::string get_debug_string () const;
61 protected:
62 object ();
63 object (gcc_jit_object *obj);
65 gcc_jit_object *get_inner_object () const;
67 private:
68 gcc_jit_object *m_inner_obj;
71 inline std::ostream& operator << (std::ostream& stream, const object &obj);
73 /* Some client code will want to supply source code locations, others
74 won't. To avoid doubling the number of entrypoints, everything
75 accepting a location also has a default argument. To do this, the
76 other classes need to see that "location" has a default constructor,
77 hence we need to declare it first. */
78 class location : public object
80 public:
81 location ();
82 location (gcc_jit_location *loc);
84 gcc_jit_location *get_inner_location () const;
87 class context
89 public:
90 static context acquire ();
91 context ();
92 context (gcc_jit_context *ctxt);
94 gccjit::context new_child_context ();
96 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
98 void release ();
100 gcc_jit_result *compile ();
102 void compile_to_file (enum gcc_jit_output_kind output_kind,
103 const char *output_path);
105 void dump_to_file (const std::string &path,
106 bool update_locations);
108 void set_logfile (FILE *logfile,
109 int flags,
110 int verbosity);
112 void dump_reproducer_to_file (const char *path);
114 void set_str_option (enum gcc_jit_str_option opt,
115 const char *value);
117 void set_int_option (enum gcc_jit_int_option opt,
118 int value);
120 void set_bool_option (enum gcc_jit_bool_option opt,
121 int value);
123 void set_bool_allow_unreachable_blocks (int bool_value);
125 void add_command_line_option (const char *optname);
127 location
128 new_location (const std::string &filename,
129 int line,
130 int column);
132 type get_type (enum gcc_jit_types kind);
133 type get_int_type (size_t num_bytes, int is_signed);
135 /* A way to map a specific int type, using the compiler to
136 get the details automatically e.g.:
137 gccjit::type type = get_int_type <my_int_type_t> (); */
138 template <typename T>
139 type get_int_type ();
141 type new_array_type (type element_type, int num_elements,
142 location loc = location ());
144 field new_field (type type_, const std::string &name,
145 location loc = location ());
147 struct_ new_struct_type (const std::string &name,
148 std::vector<field> &fields,
149 location loc = location ());
151 struct_ new_opaque_struct_type (const std::string &name,
152 location loc = location ());
154 param new_param (type type_,
155 const std::string &name,
156 location loc = location ());
158 function new_function (enum gcc_jit_function_kind kind,
159 type return_type,
160 const std::string &name,
161 std::vector<param> &params,
162 int is_variadic,
163 location loc = location ());
165 function get_builtin_function (const std::string &name);
167 lvalue new_global (enum gcc_jit_global_kind kind,
168 type type_,
169 const std::string &name,
170 location loc = location ());
172 rvalue new_rvalue (type numeric_type,
173 int value) const;
174 rvalue new_rvalue (type numeric_type,
175 long value) const;
176 rvalue zero (type numeric_type) const;
177 rvalue one (type numeric_type) const;
178 rvalue new_rvalue (type numeric_type,
179 double value) const;
180 rvalue new_rvalue (type pointer_type,
181 void *value) const;
182 rvalue new_rvalue (const std::string &value) const;
184 /* Generic unary operations... */
185 rvalue new_unary_op (enum gcc_jit_unary_op op,
186 type result_type,
187 rvalue a,
188 location loc = location ());
190 /* ...and shorter ways to spell the various specific kinds of
191 unary op. */
192 rvalue new_minus (type result_type,
193 rvalue a,
194 location loc = location ());
195 rvalue new_bitwise_negate (type result_type,
196 rvalue a,
197 location loc = location ());
198 rvalue new_logical_negate (type result_type,
199 rvalue a,
200 location loc = location ());
202 /* Generic binary operations... */
203 rvalue new_binary_op (enum gcc_jit_binary_op op,
204 type result_type,
205 rvalue a, rvalue b,
206 location loc = location ());
208 /* ...and shorter ways to spell the various specific kinds of
209 binary op. */
210 rvalue new_plus (type result_type,
211 rvalue a, rvalue b,
212 location loc = location ());
213 rvalue new_minus (type result_type,
214 rvalue a, rvalue b,
215 location loc = location ());
216 rvalue new_mult (type result_type,
217 rvalue a, rvalue b,
218 location loc = location ());
219 rvalue new_divide (type result_type,
220 rvalue a, rvalue b,
221 location loc = location ());
222 rvalue new_modulo (type result_type,
223 rvalue a, rvalue b,
224 location loc = location ());
225 rvalue new_bitwise_and (type result_type,
226 rvalue a, rvalue b,
227 location loc = location ());
228 rvalue new_bitwise_xor (type result_type,
229 rvalue a, rvalue b,
230 location loc = location ());
231 rvalue new_bitwise_or (type result_type,
232 rvalue a, rvalue b,
233 location loc = location ());
234 rvalue new_logical_and (type result_type,
235 rvalue a, rvalue b,
236 location loc = location ());
237 rvalue new_logical_or (type result_type,
238 rvalue a, rvalue b,
239 location loc = location ());
241 /* Generic comparisons... */
242 rvalue new_comparison (enum gcc_jit_comparison op,
243 rvalue a, rvalue b,
244 location loc = location ());
245 /* ...and shorter ways to spell the various specific kinds of
246 comparison. */
247 rvalue new_eq (rvalue a, rvalue b,
248 location loc = location ());
249 rvalue new_ne (rvalue a, rvalue b,
250 location loc = location ());
251 rvalue new_lt (rvalue a, rvalue b,
252 location loc = location ());
253 rvalue new_le (rvalue a, rvalue b,
254 location loc = location ());
255 rvalue new_gt (rvalue a, rvalue b,
256 location loc = location ());
257 rvalue new_ge (rvalue a, rvalue b,
258 location loc = location ());
260 /* The most general way of creating a function call. */
261 rvalue new_call (function func,
262 std::vector<rvalue> &args,
263 location loc = location ());
265 /* In addition, we provide a series of overloaded "new_call" methods
266 for specific numbers of args (from 0 - 6), to avoid the need for
267 client code to manually build a vector. */
268 rvalue new_call (function func,
269 location loc = location ());
270 rvalue new_call (function func,
271 rvalue arg0,
272 location loc = location ());
273 rvalue new_call (function func,
274 rvalue arg0, rvalue arg1,
275 location loc = location ());
276 rvalue new_call (function func,
277 rvalue arg0, rvalue arg1, rvalue arg2,
278 location loc = location ());
279 rvalue new_call (function func,
280 rvalue arg0, rvalue arg1, rvalue arg2,
281 rvalue arg3,
282 location loc = location ());
283 rvalue new_call (function func,
284 rvalue arg0, rvalue arg1, rvalue arg2,
285 rvalue arg3, rvalue arg4,
286 location loc = location ());
287 rvalue new_call (function func,
288 rvalue arg0, rvalue arg1, rvalue arg2,
289 rvalue arg3, rvalue arg4, rvalue arg5,
290 location loc = location ());
292 rvalue new_cast (rvalue expr,
293 type type_,
294 location loc = location ());
296 lvalue new_array_access (rvalue ptr,
297 rvalue index,
298 location loc = location ());
300 private:
301 gcc_jit_context *m_inner_ctxt;
304 class field : public object
306 public:
307 field ();
308 field (gcc_jit_field *inner);
310 gcc_jit_field *get_inner_field () const;
313 class type : public object
315 public:
316 type ();
317 type (gcc_jit_type *inner);
319 gcc_jit_type *get_inner_type () const;
321 type get_pointer ();
322 type get_volatile ();
324 // Shortcuts for getting values of numeric types:
325 rvalue zero ();
326 rvalue one ();
329 class struct_ : public type
331 public:
332 struct_ ();
333 struct_ (gcc_jit_struct *inner);
335 gcc_jit_struct *get_inner_struct () const;
338 class function : public object
340 public:
341 function ();
342 function (gcc_jit_function *func);
344 gcc_jit_function *get_inner_function () const;
346 void dump_to_dot (const std::string &path);
348 param get_param (int index) const;
350 block new_block ();
351 block new_block (const std::string &name);
353 lvalue new_local (type type_,
354 const std::string &name,
355 location loc = location ());
357 /* A series of overloaded operator () with various numbers of arguments
358 for a very terse way of creating a call to this function. The call
359 is created within the same context as the function itself, which may
360 not be what you want. */
361 rvalue operator() (location loc = location ());
362 rvalue operator() (rvalue arg0,
363 location loc = location ());
364 rvalue operator() (rvalue arg0, rvalue arg1,
365 location loc = location ());
366 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
367 location loc = location ());
370 class block : public object
372 public:
373 block ();
374 block (gcc_jit_block *inner);
376 gcc_jit_block *get_inner_block () const;
378 function get_function () const;
380 void add_eval (rvalue rvalue,
381 location loc = location ());
383 void add_assignment (lvalue lvalue,
384 rvalue rvalue,
385 location loc = location ());
387 void add_assignment_op (lvalue lvalue,
388 enum gcc_jit_binary_op op,
389 rvalue rvalue,
390 location loc = location ());
392 /* A way to add a function call to the body of a function being
393 defined, with various numbers of args. */
394 rvalue add_call (function other,
395 location loc = location ());
396 rvalue add_call (function other,
397 rvalue arg0,
398 location loc = location ());
399 rvalue add_call (function other,
400 rvalue arg0, rvalue arg1,
401 location loc = location ());
402 rvalue add_call (function other,
403 rvalue arg0, rvalue arg1, rvalue arg2,
404 location loc = location ());
405 rvalue add_call (function other,
406 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
407 location loc = location ());
409 void add_comment (const std::string &text,
410 location loc = location ());
412 void end_with_conditional (rvalue boolval,
413 block on_true,
414 block on_false,
415 location loc = location ());
417 void end_with_jump (block target,
418 location loc = location ());
420 void end_with_return (rvalue rvalue,
421 location loc = location ());
422 void end_with_return (location loc = location ());
426 class rvalue : public object
428 public:
429 rvalue ();
430 rvalue (gcc_jit_rvalue *inner);
431 gcc_jit_rvalue *get_inner_rvalue () const;
433 type get_type ();
435 rvalue access_field (field field,
436 location loc = location ());
438 lvalue dereference_field (field field,
439 location loc = location ());
441 lvalue dereference (location loc = location ());
443 rvalue cast_to (type type_,
444 location loc = location ());
446 /* Array access. */
447 lvalue operator[] (rvalue index);
448 lvalue operator[] (int index);
451 class lvalue : public rvalue
453 public:
454 lvalue ();
455 lvalue (gcc_jit_lvalue *inner);
457 gcc_jit_lvalue *get_inner_lvalue () const;
459 lvalue access_field (field field,
460 location loc = location ());
462 rvalue get_address (location loc = location ());
465 class param : public lvalue
467 public:
468 param ();
469 param (gcc_jit_param *inner);
471 gcc_jit_param *get_inner_param () const;
475 /* Overloaded operators, for those who want the most terse API
476 (at the possible risk of being a little too magical).
478 In each case, the first parameter is used to determine which context
479 owns the resulting expression, and, where appropriate, what the
480 latter's type is. */
482 /* Unary operators. */
483 rvalue operator- (rvalue a); // unary minus
484 rvalue operator~ (rvalue a); // unary bitwise negate
485 rvalue operator! (rvalue a); // unary logical negate
487 /* Binary operators. */
488 rvalue operator+ (rvalue a, rvalue b);
489 rvalue operator- (rvalue a, rvalue b);
490 rvalue operator* (rvalue a, rvalue b);
491 rvalue operator/ (rvalue a, rvalue b);
492 rvalue operator% (rvalue a, rvalue b);
493 rvalue operator& (rvalue a, rvalue b); // bitwise and
494 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
495 rvalue operator| (rvalue a, rvalue b); // bitwise_or
496 rvalue operator&& (rvalue a, rvalue b); // logical_and
497 rvalue operator|| (rvalue a, rvalue b); // logical_or
499 /* Comparisons. */
500 rvalue operator== (rvalue a, rvalue b);
501 rvalue operator!= (rvalue a, rvalue b);
502 rvalue operator< (rvalue a, rvalue b);
503 rvalue operator<= (rvalue a, rvalue b);
504 rvalue operator> (rvalue a, rvalue b);
505 rvalue operator>= (rvalue a, rvalue b);
507 /* Dereferencing. */
508 lvalue operator* (rvalue ptr);
511 /****************************************************************************
512 Implementation of the API
513 ****************************************************************************/
514 namespace gccjit {
516 // class context
517 inline context context::acquire ()
519 return context (gcc_jit_context_acquire ());
521 inline context::context () : m_inner_ctxt (NULL) {}
522 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
524 if (!inner)
525 throw error ();
528 inline gccjit::context
529 context::new_child_context ()
531 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
534 inline void
535 context::release ()
537 gcc_jit_context_release (m_inner_ctxt);
538 m_inner_ctxt = NULL;
541 inline gcc_jit_result *
542 context::compile ()
544 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
545 if (!result)
546 throw error ();
547 return result;
550 inline void
551 context::compile_to_file (enum gcc_jit_output_kind output_kind,
552 const char *output_path)
554 gcc_jit_context_compile_to_file (m_inner_ctxt,
555 output_kind,
556 output_path);
559 inline void
560 context::dump_to_file (const std::string &path,
561 bool update_locations)
563 gcc_jit_context_dump_to_file (m_inner_ctxt,
564 path.c_str (),
565 update_locations);
568 inline void
569 context::set_logfile (FILE *logfile,
570 int flags,
571 int verbosity)
573 gcc_jit_context_set_logfile (m_inner_ctxt,
574 logfile,
575 flags,
576 verbosity);
579 inline void
580 context::dump_reproducer_to_file (const char *path)
582 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
583 path);
586 inline void
587 context::set_str_option (enum gcc_jit_str_option opt,
588 const char *value)
590 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
594 inline void
595 context::set_int_option (enum gcc_jit_int_option opt,
596 int value)
598 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
602 inline void
603 context::set_bool_option (enum gcc_jit_bool_option opt,
604 int value)
606 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
609 inline void
610 context::set_bool_allow_unreachable_blocks (int bool_value)
612 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
613 bool_value);
616 inline void
617 context::add_command_line_option (const char *optname)
619 gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
622 inline location
623 context::new_location (const std::string &filename,
624 int line,
625 int column)
627 return location (gcc_jit_context_new_location (m_inner_ctxt,
628 filename.c_str (),
629 line,
630 column));
633 inline type
634 context::get_type (enum gcc_jit_types kind)
636 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
639 inline type
640 context::get_int_type (size_t num_bytes, int is_signed)
642 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
643 num_bytes,
644 is_signed));
647 template <typename T>
648 inline type
649 context::get_int_type ()
651 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
654 inline type
655 context::new_array_type (type element_type, int num_elements, location loc)
657 return type (gcc_jit_context_new_array_type (
658 m_inner_ctxt,
659 loc.get_inner_location (),
660 element_type.get_inner_type (),
661 num_elements));
664 inline field
665 context::new_field (type type_, const std::string &name, location loc)
667 return field (gcc_jit_context_new_field (m_inner_ctxt,
668 loc.get_inner_location (),
669 type_.get_inner_type (),
670 name.c_str ()));
673 inline struct_
674 context::new_struct_type (const std::string &name,
675 std::vector<field> &fields,
676 location loc)
678 /* Treat std::vector as an array, relying on it not being resized: */
679 field *as_array_of_wrappers = &fields[0];
681 /* Treat the array as being of the underlying pointers, relying on
682 the wrapper type being such a pointer internally. */
683 gcc_jit_field **as_array_of_ptrs =
684 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
686 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
687 loc.get_inner_location (),
688 name.c_str (),
689 fields.size (),
690 as_array_of_ptrs));
693 inline struct_
694 context::new_opaque_struct_type (const std::string &name,
695 location loc)
697 return struct_ (gcc_jit_context_new_opaque_struct (
698 m_inner_ctxt,
699 loc.get_inner_location (),
700 name.c_str ()));
703 inline param
704 context::new_param (type type_,
705 const std::string &name,
706 location loc)
708 return param (gcc_jit_context_new_param (m_inner_ctxt,
709 loc.get_inner_location (),
710 type_.get_inner_type (),
711 name.c_str ()));
714 inline function
715 context::new_function (enum gcc_jit_function_kind kind,
716 type return_type,
717 const std::string &name,
718 std::vector<param> &params,
719 int is_variadic,
720 location loc)
722 /* Treat std::vector as an array, relying on it not being resized: */
723 param *as_array_of_wrappers = &params[0];
725 /* Treat the array as being of the underlying pointers, relying on
726 the wrapper type being such a pointer internally. */
727 gcc_jit_param **as_array_of_ptrs =
728 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
730 return function (gcc_jit_context_new_function (m_inner_ctxt,
731 loc.get_inner_location (),
732 kind,
733 return_type.get_inner_type (),
734 name.c_str (),
735 params.size (),
736 as_array_of_ptrs,
737 is_variadic));
740 inline function
741 context::get_builtin_function (const std::string &name)
743 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
744 name.c_str ()));
747 inline lvalue
748 context::new_global (enum gcc_jit_global_kind kind,
749 type type_,
750 const std::string &name,
751 location loc)
753 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
754 loc.get_inner_location (),
755 kind,
756 type_.get_inner_type (),
757 name.c_str ()));
760 inline rvalue
761 context::new_rvalue (type numeric_type,
762 int value) const
764 return rvalue (
765 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
766 numeric_type.get_inner_type (),
767 value));
770 inline rvalue
771 context::new_rvalue (type numeric_type,
772 long value) const
774 return rvalue (
775 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
776 numeric_type.get_inner_type (),
777 value));
780 inline rvalue
781 context::zero (type numeric_type) const
783 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
784 numeric_type.get_inner_type ()));
787 inline rvalue
788 context::one (type numeric_type) const
790 return rvalue (gcc_jit_context_one (m_inner_ctxt,
791 numeric_type.get_inner_type ()));
794 inline rvalue
795 context::new_rvalue (type numeric_type,
796 double value) const
798 return rvalue (
799 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
800 numeric_type.get_inner_type (),
801 value));
804 inline rvalue
805 context::new_rvalue (type pointer_type,
806 void *value) const
808 return rvalue (
809 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
810 pointer_type.get_inner_type (),
811 value));
814 inline rvalue
815 context::new_rvalue (const std::string &value) const
817 return rvalue (
818 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
821 inline rvalue
822 context::new_unary_op (enum gcc_jit_unary_op op,
823 type result_type,
824 rvalue a,
825 location loc)
827 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
828 loc.get_inner_location (),
830 result_type.get_inner_type (),
831 a.get_inner_rvalue ()));
833 inline rvalue
834 context::new_minus (type result_type,
835 rvalue a,
836 location loc)
838 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
839 result_type, a, loc));
841 inline rvalue
842 context::new_bitwise_negate (type result_type,
843 rvalue a,
844 location loc)
846 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
847 result_type, a, loc));
849 inline rvalue
850 context::new_logical_negate (type result_type,
851 rvalue a,
852 location loc)
854 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
855 result_type, a, loc));
858 inline rvalue
859 context::new_binary_op (enum gcc_jit_binary_op op,
860 type result_type,
861 rvalue a, rvalue b,
862 location loc)
864 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
865 loc.get_inner_location (),
867 result_type.get_inner_type (),
868 a.get_inner_rvalue (),
869 b.get_inner_rvalue ()));
871 inline rvalue
872 context::new_plus (type result_type,
873 rvalue a, rvalue b,
874 location loc)
876 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
877 result_type, a, b, loc);
879 inline rvalue
880 context::new_minus (type result_type,
881 rvalue a, rvalue b,
882 location loc)
884 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
885 result_type, a, b, loc);
887 inline rvalue
888 context::new_mult (type result_type,
889 rvalue a, rvalue b,
890 location loc)
892 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
893 result_type, a, b, loc);
895 inline rvalue
896 context::new_divide (type result_type,
897 rvalue a, rvalue b,
898 location loc)
900 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
901 result_type, a, b, loc);
903 inline rvalue
904 context::new_modulo (type result_type,
905 rvalue a, rvalue b,
906 location loc)
908 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
909 result_type, a, b, loc);
911 inline rvalue
912 context::new_bitwise_and (type result_type,
913 rvalue a, rvalue b,
914 location loc)
916 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
917 result_type, a, b, loc);
919 inline rvalue
920 context::new_bitwise_xor (type result_type,
921 rvalue a, rvalue b,
922 location loc)
924 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
925 result_type, a, b, loc);
927 inline rvalue
928 context::new_bitwise_or (type result_type,
929 rvalue a, rvalue b,
930 location loc)
932 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
933 result_type, a, b, loc);
935 inline rvalue
936 context::new_logical_and (type result_type,
937 rvalue a, rvalue b,
938 location loc)
940 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
941 result_type, a, b, loc);
943 inline rvalue
944 context::new_logical_or (type result_type,
945 rvalue a, rvalue b,
946 location loc)
948 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
949 result_type, a, b, loc);
952 inline rvalue
953 context::new_comparison (enum gcc_jit_comparison op,
954 rvalue a, rvalue b,
955 location loc)
957 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
958 loc.get_inner_location (),
960 a.get_inner_rvalue (),
961 b.get_inner_rvalue ()));
963 inline rvalue
964 context::new_eq (rvalue a, rvalue b,
965 location loc)
967 return new_comparison (GCC_JIT_COMPARISON_EQ,
968 a, b, loc);
970 inline rvalue
971 context::new_ne (rvalue a, rvalue b,
972 location loc)
974 return new_comparison (GCC_JIT_COMPARISON_NE,
975 a, b, loc);
977 inline rvalue
978 context::new_lt (rvalue a, rvalue b,
979 location loc)
981 return new_comparison (GCC_JIT_COMPARISON_LT,
982 a, b, loc);
984 inline rvalue
985 context::new_le (rvalue a, rvalue b,
986 location loc)
988 return new_comparison (GCC_JIT_COMPARISON_LE,
989 a, b, loc);
991 inline rvalue
992 context::new_gt (rvalue a, rvalue b,
993 location loc)
995 return new_comparison (GCC_JIT_COMPARISON_GT,
996 a, b, loc);
998 inline rvalue
999 context::new_ge (rvalue a, rvalue b,
1000 location loc)
1002 return new_comparison (GCC_JIT_COMPARISON_GE,
1003 a, b, loc);
1006 inline rvalue
1007 context::new_call (function func,
1008 std::vector<rvalue> &args,
1009 location loc)
1011 /* Treat std::vector as an array, relying on it not being resized: */
1012 rvalue *as_array_of_wrappers = &args[0];
1014 /* Treat the array as being of the underlying pointers, relying on
1015 the wrapper type being such a pointer internally. */
1016 gcc_jit_rvalue **as_array_of_ptrs =
1017 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
1018 return gcc_jit_context_new_call (m_inner_ctxt,
1019 loc.get_inner_location (),
1020 func.get_inner_function (),
1021 args.size (),
1022 as_array_of_ptrs);
1024 inline rvalue
1025 context::new_call (function func,
1026 location loc)
1028 std::vector<rvalue> args;
1029 return new_call (func, args, loc);
1032 inline rvalue
1033 context::new_call (function func,
1034 rvalue arg0,
1035 location loc)
1037 std::vector<rvalue> args(1);
1038 args[0] = arg0;
1039 return new_call (func, args, loc);
1041 inline rvalue
1042 context::new_call (function func,
1043 rvalue arg0, rvalue arg1,
1044 location loc)
1046 std::vector<rvalue> args(2);
1047 args[0] = arg0;
1048 args[1] = arg1;
1049 return new_call (func, args, loc);
1051 inline rvalue
1052 context::new_call (function func,
1053 rvalue arg0, rvalue arg1, rvalue arg2,
1054 location loc)
1056 std::vector<rvalue> args(3);
1057 args[0] = arg0;
1058 args[1] = arg1;
1059 args[2] = arg2;
1060 return new_call (func, args, loc);
1062 inline rvalue
1063 context::new_call (function func,
1064 rvalue arg0, rvalue arg1, rvalue arg2,
1065 rvalue arg3,
1066 location loc)
1068 std::vector<rvalue> args(4);
1069 args[0] = arg0;
1070 args[1] = arg1;
1071 args[2] = arg2;
1072 args[3] = arg3;
1073 return new_call (func, args, loc);
1075 inline rvalue
1076 context::new_call (function func,
1077 rvalue arg0, rvalue arg1, rvalue arg2,
1078 rvalue arg3, rvalue arg4,
1079 location loc)
1081 std::vector<rvalue> args(5);
1082 args[0] = arg0;
1083 args[1] = arg1;
1084 args[2] = arg2;
1085 args[3] = arg3;
1086 args[4] = arg4;
1087 return new_call (func, args, loc);
1089 inline rvalue
1090 context::new_call (function func,
1091 rvalue arg0, rvalue arg1, rvalue arg2,
1092 rvalue arg3, rvalue arg4, rvalue arg5,
1093 location loc)
1095 std::vector<rvalue> args(6);
1096 args[0] = arg0;
1097 args[1] = arg1;
1098 args[2] = arg2;
1099 args[3] = arg3;
1100 args[4] = arg4;
1101 args[5] = arg5;
1102 return new_call (func, args, loc);
1105 inline rvalue
1106 context::new_cast (rvalue expr,
1107 type type_,
1108 location loc)
1110 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1111 loc.get_inner_location (),
1112 expr.get_inner_rvalue (),
1113 type_.get_inner_type ()));
1116 inline lvalue
1117 context::new_array_access (rvalue ptr,
1118 rvalue index,
1119 location loc)
1121 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1122 loc.get_inner_location (),
1123 ptr.get_inner_rvalue (),
1124 index.get_inner_rvalue ()));
1127 // class object
1128 inline context
1129 object::get_context () const
1131 return context (gcc_jit_object_get_context (m_inner_obj));
1134 inline std::string
1135 object::get_debug_string () const
1137 return gcc_jit_object_get_debug_string (m_inner_obj);
1140 inline object::object () : m_inner_obj (NULL) {}
1141 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1143 if (!obj)
1144 throw error ();
1147 inline gcc_jit_object *
1148 object::get_inner_object () const
1150 return m_inner_obj;
1153 inline std::ostream&
1154 operator << (std::ostream& stream, const object &obj)
1156 return stream << obj.get_debug_string ();
1159 // class location
1160 inline location::location () : object () {}
1161 inline location::location (gcc_jit_location *loc)
1162 : object (gcc_jit_location_as_object (loc))
1165 inline gcc_jit_location *
1166 location::get_inner_location () const
1168 /* Manual downcast: */
1169 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1172 // class field
1173 inline field::field () : object () {}
1174 inline field::field (gcc_jit_field *inner)
1175 : object (gcc_jit_field_as_object (inner))
1178 inline gcc_jit_field *
1179 field::get_inner_field () const
1181 /* Manual downcast: */
1182 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1185 // class type
1186 inline type::type () : object () {}
1187 inline type::type (gcc_jit_type *inner)
1188 : object (gcc_jit_type_as_object (inner))
1191 inline gcc_jit_type *
1192 type::get_inner_type () const
1194 /* Manual downcast: */
1195 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1198 inline type
1199 type::get_pointer ()
1201 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1204 inline type
1205 type::get_volatile ()
1207 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1210 inline rvalue
1211 type::zero ()
1213 return get_context ().new_rvalue (*this, 0);
1216 inline rvalue
1217 type::one ()
1219 return get_context ().new_rvalue (*this, 1);
1222 // class struct_
1223 inline struct_::struct_ () : type (NULL) {}
1224 inline struct_::struct_ (gcc_jit_struct *inner) :
1225 type (gcc_jit_struct_as_type (inner))
1229 inline gcc_jit_struct *
1230 struct_::get_inner_struct () const
1232 /* Manual downcast: */
1233 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1236 // class function
1237 inline function::function () : object () {}
1238 inline function::function (gcc_jit_function *inner)
1239 : object (gcc_jit_function_as_object (inner))
1242 inline gcc_jit_function *
1243 function::get_inner_function () const
1245 /* Manual downcast: */
1246 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1249 inline void
1250 function::dump_to_dot (const std::string &path)
1252 gcc_jit_function_dump_to_dot (get_inner_function (),
1253 path.c_str ());
1256 inline param
1257 function::get_param (int index) const
1259 return param (gcc_jit_function_get_param (get_inner_function (),
1260 index));
1263 inline block
1264 function::new_block ()
1266 return block (gcc_jit_function_new_block (get_inner_function (),
1267 NULL));
1270 inline block
1271 function::new_block (const std::string &name)
1273 return block (gcc_jit_function_new_block (get_inner_function (),
1274 name.c_str ()));
1277 inline lvalue
1278 function::new_local (type type_,
1279 const std::string &name,
1280 location loc)
1282 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1283 loc.get_inner_location (),
1284 type_.get_inner_type (),
1285 name.c_str ()));
1288 inline function
1289 block::get_function () const
1291 return function (gcc_jit_block_get_function ( get_inner_block ()));
1294 inline void
1295 block::add_eval (rvalue rvalue,
1296 location loc)
1298 gcc_jit_block_add_eval (get_inner_block (),
1299 loc.get_inner_location (),
1300 rvalue.get_inner_rvalue ());
1303 inline void
1304 block::add_assignment (lvalue lvalue,
1305 rvalue rvalue,
1306 location loc)
1308 gcc_jit_block_add_assignment (get_inner_block (),
1309 loc.get_inner_location (),
1310 lvalue.get_inner_lvalue (),
1311 rvalue.get_inner_rvalue ());
1314 inline void
1315 block::add_assignment_op (lvalue lvalue,
1316 enum gcc_jit_binary_op op,
1317 rvalue rvalue,
1318 location loc)
1320 gcc_jit_block_add_assignment_op (get_inner_block (),
1321 loc.get_inner_location (),
1322 lvalue.get_inner_lvalue (),
1324 rvalue.get_inner_rvalue ());
1327 inline void
1328 block::add_comment (const std::string &text,
1329 location loc)
1331 gcc_jit_block_add_comment (get_inner_block (),
1332 loc.get_inner_location (),
1333 text.c_str ());
1336 inline void
1337 block::end_with_conditional (rvalue boolval,
1338 block on_true,
1339 block on_false,
1340 location loc)
1342 gcc_jit_block_end_with_conditional (get_inner_block (),
1343 loc.get_inner_location (),
1344 boolval.get_inner_rvalue (),
1345 on_true.get_inner_block (),
1346 on_false.get_inner_block ());
1349 inline void
1350 block::end_with_jump (block target,
1351 location loc)
1353 gcc_jit_block_end_with_jump (get_inner_block (),
1354 loc.get_inner_location (),
1355 target.get_inner_block ());
1358 inline void
1359 block::end_with_return (rvalue rvalue,
1360 location loc)
1362 gcc_jit_block_end_with_return (get_inner_block (),
1363 loc.get_inner_location (),
1364 rvalue.get_inner_rvalue ());
1367 inline void
1368 block::end_with_return (location loc)
1370 gcc_jit_block_end_with_void_return (get_inner_block (),
1371 loc.get_inner_location ());
1374 inline rvalue
1375 block::add_call (function other,
1376 location loc)
1378 rvalue c = get_context ().new_call (other, loc);
1379 add_eval (c);
1380 return c;
1382 inline rvalue
1383 block::add_call (function other,
1384 rvalue arg0,
1385 location loc)
1387 rvalue c = get_context ().new_call (other, arg0, loc);
1388 add_eval (c);
1389 return c;
1391 inline rvalue
1392 block::add_call (function other,
1393 rvalue arg0, rvalue arg1,
1394 location loc)
1396 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1397 add_eval (c);
1398 return c;
1400 inline rvalue
1401 block::add_call (function other,
1402 rvalue arg0, rvalue arg1, rvalue arg2,
1403 location loc)
1405 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1406 add_eval (c);
1407 return c;
1410 inline rvalue
1411 block::add_call (function other,
1412 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1413 location loc)
1415 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1416 add_eval (c);
1417 return c;
1420 inline rvalue
1421 function::operator() (location loc)
1423 return get_context ().new_call (*this, loc);
1425 inline rvalue
1426 function::operator() (rvalue arg0,
1427 location loc)
1429 return get_context ().new_call (*this,
1430 arg0,
1431 loc);
1433 inline rvalue
1434 function::operator() (rvalue arg0, rvalue arg1,
1435 location loc)
1437 return get_context ().new_call (*this,
1438 arg0, arg1,
1439 loc);
1441 inline rvalue
1442 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1443 location loc)
1445 return get_context ().new_call (*this,
1446 arg0, arg1, arg2,
1447 loc);
1450 // class block
1451 inline block::block () : object () {}
1452 inline block::block (gcc_jit_block *inner)
1453 : object (gcc_jit_block_as_object (inner))
1456 inline gcc_jit_block *
1457 block::get_inner_block () const
1459 /* Manual downcast: */
1460 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1463 // class rvalue
1464 inline rvalue::rvalue () : object () {}
1465 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1466 : object (gcc_jit_rvalue_as_object (inner))
1469 inline gcc_jit_rvalue *
1470 rvalue::get_inner_rvalue () const
1472 /* Manual downcast: */
1473 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1476 inline type
1477 rvalue::get_type ()
1479 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1482 inline rvalue
1483 rvalue::access_field (field field,
1484 location loc)
1486 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1487 loc.get_inner_location (),
1488 field.get_inner_field ()));
1491 inline lvalue
1492 rvalue::dereference_field (field field,
1493 location loc)
1495 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1496 loc.get_inner_location (),
1497 field.get_inner_field ()));
1500 inline lvalue
1501 rvalue::dereference (location loc)
1503 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1504 loc.get_inner_location ()));
1507 inline rvalue
1508 rvalue::cast_to (type type_,
1509 location loc)
1511 return get_context ().new_cast (*this, type_, loc);
1514 inline lvalue
1515 rvalue::operator[] (rvalue index)
1517 return get_context ().new_array_access (*this, index);
1520 inline lvalue
1521 rvalue::operator[] (int index)
1523 context ctxt = get_context ();
1524 type int_t = ctxt.get_int_type <int> ();
1525 return ctxt.new_array_access (*this,
1526 ctxt.new_rvalue (int_t,
1527 index));
1530 // class lvalue : public rvalue
1531 inline lvalue::lvalue () : rvalue () {}
1532 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1533 : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1536 inline gcc_jit_lvalue *
1537 lvalue::get_inner_lvalue () const
1539 /* Manual downcast: */
1540 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1543 inline lvalue
1544 lvalue::access_field (field field, location loc)
1546 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1547 loc.get_inner_location (),
1548 field.get_inner_field ()));
1551 inline rvalue
1552 lvalue::get_address (location loc)
1554 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1555 loc.get_inner_location ()));
1558 // class param : public lvalue
1559 inline param::param () : lvalue () {}
1560 inline param::param (gcc_jit_param *inner)
1561 : lvalue (gcc_jit_param_as_lvalue (inner))
1564 /* Overloaded operators. */
1565 // Unary operators
1566 inline rvalue operator- (rvalue a)
1568 return a.get_context ().new_minus (a.get_type (), a);
1570 inline rvalue operator~ (rvalue a)
1572 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1574 inline rvalue operator! (rvalue a)
1576 return a.get_context ().new_logical_negate (a.get_type (), a);
1579 // Binary operators
1580 inline rvalue operator+ (rvalue a, rvalue b)
1582 return a.get_context ().new_plus (a.get_type (), a, b);
1584 inline rvalue operator- (rvalue a, rvalue b)
1586 return a.get_context ().new_minus (a.get_type (), a, b);
1588 inline rvalue operator* (rvalue a, rvalue b)
1590 return a.get_context ().new_mult (a.get_type (), a, b);
1592 inline rvalue operator/ (rvalue a, rvalue b)
1594 return a.get_context ().new_divide (a.get_type (), a, b);
1596 inline rvalue operator% (rvalue a, rvalue b)
1598 return a.get_context ().new_modulo (a.get_type (), a, b);
1600 inline rvalue operator& (rvalue a, rvalue b)
1602 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1604 inline rvalue operator^ (rvalue a, rvalue b)
1606 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1608 inline rvalue operator| (rvalue a, rvalue b)
1610 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1612 inline rvalue operator&& (rvalue a, rvalue b)
1614 return a.get_context ().new_logical_and (a.get_type (), a, b);
1616 inline rvalue operator|| (rvalue a, rvalue b)
1618 return a.get_context ().new_logical_or (a.get_type (), a, b);
1621 /* Comparisons. */
1622 inline rvalue operator== (rvalue a, rvalue b)
1624 return a.get_context ().new_eq (a, b);
1626 inline rvalue operator!= (rvalue a, rvalue b)
1628 return a.get_context ().new_ne (a, b);
1630 inline rvalue operator< (rvalue a, rvalue b)
1632 return a.get_context ().new_lt (a, b);
1634 inline rvalue operator<= (rvalue a, rvalue b)
1636 return a.get_context ().new_le (a, b);
1638 inline rvalue operator> (rvalue a, rvalue b)
1640 return a.get_context ().new_gt (a, b);
1642 inline rvalue operator>= (rvalue a, rvalue b)
1644 return a.get_context ().new_ge (a, b);
1647 /* Dereferencing. */
1648 inline lvalue operator* (rvalue ptr)
1650 return ptr.dereference ();
1653 } // namespace gccjit
1655 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */