jit: add switch statements
[official-gcc.git] / gcc / jit / libgccjit++.h
blob01579bd7312c0601342fa654bb636819720bd15a
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;
48 class case_;
50 /* Errors within the API become C++ exceptions of this class. */
51 class error
55 class object
57 public:
58 context get_context () const;
60 std::string get_debug_string () const;
62 protected:
63 object ();
64 object (gcc_jit_object *obj);
66 gcc_jit_object *get_inner_object () const;
68 private:
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
81 public:
82 location ();
83 location (gcc_jit_location *loc);
85 gcc_jit_location *get_inner_location () const;
88 class context
90 public:
91 static context acquire ();
92 context ();
93 context (gcc_jit_context *ctxt);
95 gccjit::context new_child_context ();
97 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
99 void release ();
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,
110 int flags,
111 int verbosity);
113 void dump_reproducer_to_file (const char *path);
115 void set_str_option (enum gcc_jit_str_option opt,
116 const char *value);
118 void set_int_option (enum gcc_jit_int_option opt,
119 int value);
121 void set_bool_option (enum gcc_jit_bool_option opt,
122 int value);
124 void set_bool_allow_unreachable_blocks (int bool_value);
126 void add_command_line_option (const char *optname);
128 location
129 new_location (const std::string &filename,
130 int line,
131 int column);
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,
160 type return_type,
161 const std::string &name,
162 std::vector<param> &params,
163 int is_variadic,
164 location loc = location ());
166 function get_builtin_function (const std::string &name);
168 lvalue new_global (enum gcc_jit_global_kind kind,
169 type type_,
170 const std::string &name,
171 location loc = location ());
173 rvalue new_rvalue (type numeric_type,
174 int value) const;
175 rvalue new_rvalue (type numeric_type,
176 long value) const;
177 rvalue zero (type numeric_type) const;
178 rvalue one (type numeric_type) const;
179 rvalue new_rvalue (type numeric_type,
180 double value) const;
181 rvalue new_rvalue (type pointer_type,
182 void *value) const;
183 rvalue new_rvalue (const std::string &value) const;
185 /* Generic unary operations... */
186 rvalue new_unary_op (enum gcc_jit_unary_op op,
187 type result_type,
188 rvalue a,
189 location loc = location ());
191 /* ...and shorter ways to spell the various specific kinds of
192 unary op. */
193 rvalue new_minus (type result_type,
194 rvalue a,
195 location loc = location ());
196 rvalue new_bitwise_negate (type result_type,
197 rvalue a,
198 location loc = location ());
199 rvalue new_logical_negate (type result_type,
200 rvalue a,
201 location loc = location ());
203 /* Generic binary operations... */
204 rvalue new_binary_op (enum gcc_jit_binary_op op,
205 type result_type,
206 rvalue a, rvalue b,
207 location loc = location ());
209 /* ...and shorter ways to spell the various specific kinds of
210 binary op. */
211 rvalue new_plus (type result_type,
212 rvalue a, rvalue b,
213 location loc = location ());
214 rvalue new_minus (type result_type,
215 rvalue a, rvalue b,
216 location loc = location ());
217 rvalue new_mult (type result_type,
218 rvalue a, rvalue b,
219 location loc = location ());
220 rvalue new_divide (type result_type,
221 rvalue a, rvalue b,
222 location loc = location ());
223 rvalue new_modulo (type result_type,
224 rvalue a, rvalue b,
225 location loc = location ());
226 rvalue new_bitwise_and (type result_type,
227 rvalue a, rvalue b,
228 location loc = location ());
229 rvalue new_bitwise_xor (type result_type,
230 rvalue a, rvalue b,
231 location loc = location ());
232 rvalue new_bitwise_or (type result_type,
233 rvalue a, rvalue b,
234 location loc = location ());
235 rvalue new_logical_and (type result_type,
236 rvalue a, rvalue b,
237 location loc = location ());
238 rvalue new_logical_or (type result_type,
239 rvalue a, rvalue b,
240 location loc = location ());
242 /* Generic comparisons... */
243 rvalue new_comparison (enum gcc_jit_comparison op,
244 rvalue a, rvalue b,
245 location loc = location ());
246 /* ...and shorter ways to spell the various specific kinds of
247 comparison. */
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,
272 rvalue arg0,
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,
282 rvalue arg3,
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,
294 type type_,
295 location loc = location ());
297 lvalue new_array_access (rvalue ptr,
298 rvalue index,
299 location loc = location ());
301 case_ new_case (rvalue min_value,
302 rvalue max_value,
303 block dest_block);
305 private:
306 gcc_jit_context *m_inner_ctxt;
309 class field : public object
311 public:
312 field ();
313 field (gcc_jit_field *inner);
315 gcc_jit_field *get_inner_field () const;
318 class type : public object
320 public:
321 type ();
322 type (gcc_jit_type *inner);
324 gcc_jit_type *get_inner_type () const;
326 type get_pointer ();
327 type get_volatile ();
329 // Shortcuts for getting values of numeric types:
330 rvalue zero ();
331 rvalue one ();
334 class struct_ : public type
336 public:
337 struct_ ();
338 struct_ (gcc_jit_struct *inner);
340 gcc_jit_struct *get_inner_struct () const;
343 class function : public object
345 public:
346 function ();
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;
355 block new_block ();
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
377 public:
378 block ();
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,
389 rvalue rvalue,
390 location loc = location ());
392 void add_assignment_op (lvalue lvalue,
393 enum gcc_jit_binary_op op,
394 rvalue rvalue,
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,
402 rvalue arg0,
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,
418 block on_true,
419 block on_false,
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,
430 block default_block,
431 std::vector <case_> cases,
432 location loc = location ());
435 class rvalue : public object
437 public:
438 rvalue ();
439 rvalue (gcc_jit_rvalue *inner);
440 gcc_jit_rvalue *get_inner_rvalue () const;
442 type get_type ();
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 ());
455 /* Array access. */
456 lvalue operator[] (rvalue index);
457 lvalue operator[] (int index);
460 class lvalue : public rvalue
462 public:
463 lvalue ();
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
476 public:
477 param ();
478 param (gcc_jit_param *inner);
480 gcc_jit_param *get_inner_param () const;
483 class case_ : public object
485 public:
486 case_ ();
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
497 latter's type is. */
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
516 /* Comparisons. */
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);
524 /* Dereferencing. */
525 lvalue operator* (rvalue ptr);
528 /****************************************************************************
529 Implementation of the API
530 ****************************************************************************/
531 namespace gccjit {
533 // class context
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)
541 if (!inner)
542 throw error ();
545 inline gccjit::context
546 context::new_child_context ()
548 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
551 inline void
552 context::release ()
554 gcc_jit_context_release (m_inner_ctxt);
555 m_inner_ctxt = NULL;
558 inline gcc_jit_result *
559 context::compile ()
561 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
562 if (!result)
563 throw error ();
564 return result;
567 inline void
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,
572 output_kind,
573 output_path);
576 inline void
577 context::dump_to_file (const std::string &path,
578 bool update_locations)
580 gcc_jit_context_dump_to_file (m_inner_ctxt,
581 path.c_str (),
582 update_locations);
585 inline void
586 context::set_logfile (FILE *logfile,
587 int flags,
588 int verbosity)
590 gcc_jit_context_set_logfile (m_inner_ctxt,
591 logfile,
592 flags,
593 verbosity);
596 inline void
597 context::dump_reproducer_to_file (const char *path)
599 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
600 path);
603 inline void
604 context::set_str_option (enum gcc_jit_str_option opt,
605 const char *value)
607 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
611 inline void
612 context::set_int_option (enum gcc_jit_int_option opt,
613 int value)
615 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
619 inline void
620 context::set_bool_option (enum gcc_jit_bool_option opt,
621 int value)
623 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
626 inline void
627 context::set_bool_allow_unreachable_blocks (int bool_value)
629 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
630 bool_value);
633 inline void
634 context::add_command_line_option (const char *optname)
636 gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
639 inline location
640 context::new_location (const std::string &filename,
641 int line,
642 int column)
644 return location (gcc_jit_context_new_location (m_inner_ctxt,
645 filename.c_str (),
646 line,
647 column));
650 inline type
651 context::get_type (enum gcc_jit_types kind)
653 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
656 inline type
657 context::get_int_type (size_t num_bytes, int is_signed)
659 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
660 num_bytes,
661 is_signed));
664 template <typename T>
665 inline type
666 context::get_int_type ()
668 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
671 inline type
672 context::new_array_type (type element_type, int num_elements, location loc)
674 return type (gcc_jit_context_new_array_type (
675 m_inner_ctxt,
676 loc.get_inner_location (),
677 element_type.get_inner_type (),
678 num_elements));
681 inline field
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 (),
687 name.c_str ()));
690 inline struct_
691 context::new_struct_type (const std::string &name,
692 std::vector<field> &fields,
693 location loc)
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 (),
705 name.c_str (),
706 fields.size (),
707 as_array_of_ptrs));
710 inline struct_
711 context::new_opaque_struct_type (const std::string &name,
712 location loc)
714 return struct_ (gcc_jit_context_new_opaque_struct (
715 m_inner_ctxt,
716 loc.get_inner_location (),
717 name.c_str ()));
720 inline param
721 context::new_param (type type_,
722 const std::string &name,
723 location loc)
725 return param (gcc_jit_context_new_param (m_inner_ctxt,
726 loc.get_inner_location (),
727 type_.get_inner_type (),
728 name.c_str ()));
731 inline function
732 context::new_function (enum gcc_jit_function_kind kind,
733 type return_type,
734 const std::string &name,
735 std::vector<param> &params,
736 int is_variadic,
737 location loc)
739 /* Treat std::vector as an array, relying on it not being resized: */
740 param *as_array_of_wrappers = &params[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 (),
749 kind,
750 return_type.get_inner_type (),
751 name.c_str (),
752 params.size (),
753 as_array_of_ptrs,
754 is_variadic));
757 inline function
758 context::get_builtin_function (const std::string &name)
760 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
761 name.c_str ()));
764 inline lvalue
765 context::new_global (enum gcc_jit_global_kind kind,
766 type type_,
767 const std::string &name,
768 location loc)
770 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
771 loc.get_inner_location (),
772 kind,
773 type_.get_inner_type (),
774 name.c_str ()));
777 inline rvalue
778 context::new_rvalue (type numeric_type,
779 int value) const
781 return rvalue (
782 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
783 numeric_type.get_inner_type (),
784 value));
787 inline rvalue
788 context::new_rvalue (type numeric_type,
789 long value) const
791 return rvalue (
792 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
793 numeric_type.get_inner_type (),
794 value));
797 inline rvalue
798 context::zero (type numeric_type) const
800 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
801 numeric_type.get_inner_type ()));
804 inline rvalue
805 context::one (type numeric_type) const
807 return rvalue (gcc_jit_context_one (m_inner_ctxt,
808 numeric_type.get_inner_type ()));
811 inline rvalue
812 context::new_rvalue (type numeric_type,
813 double value) const
815 return rvalue (
816 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
817 numeric_type.get_inner_type (),
818 value));
821 inline rvalue
822 context::new_rvalue (type pointer_type,
823 void *value) const
825 return rvalue (
826 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
827 pointer_type.get_inner_type (),
828 value));
831 inline rvalue
832 context::new_rvalue (const std::string &value) const
834 return rvalue (
835 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
838 inline rvalue
839 context::new_unary_op (enum gcc_jit_unary_op op,
840 type result_type,
841 rvalue a,
842 location loc)
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 ()));
850 inline rvalue
851 context::new_minus (type result_type,
852 rvalue a,
853 location loc)
855 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
856 result_type, a, loc));
858 inline rvalue
859 context::new_bitwise_negate (type result_type,
860 rvalue a,
861 location loc)
863 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
864 result_type, a, loc));
866 inline rvalue
867 context::new_logical_negate (type result_type,
868 rvalue a,
869 location loc)
871 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
872 result_type, a, loc));
875 inline rvalue
876 context::new_binary_op (enum gcc_jit_binary_op op,
877 type result_type,
878 rvalue a, rvalue b,
879 location loc)
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 ()));
888 inline rvalue
889 context::new_plus (type result_type,
890 rvalue a, rvalue b,
891 location loc)
893 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
894 result_type, a, b, loc);
896 inline rvalue
897 context::new_minus (type result_type,
898 rvalue a, rvalue b,
899 location loc)
901 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
902 result_type, a, b, loc);
904 inline rvalue
905 context::new_mult (type result_type,
906 rvalue a, rvalue b,
907 location loc)
909 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
910 result_type, a, b, loc);
912 inline rvalue
913 context::new_divide (type result_type,
914 rvalue a, rvalue b,
915 location loc)
917 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
918 result_type, a, b, loc);
920 inline rvalue
921 context::new_modulo (type result_type,
922 rvalue a, rvalue b,
923 location loc)
925 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
926 result_type, a, b, loc);
928 inline rvalue
929 context::new_bitwise_and (type result_type,
930 rvalue a, rvalue b,
931 location loc)
933 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
934 result_type, a, b, loc);
936 inline rvalue
937 context::new_bitwise_xor (type result_type,
938 rvalue a, rvalue b,
939 location loc)
941 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
942 result_type, a, b, loc);
944 inline rvalue
945 context::new_bitwise_or (type result_type,
946 rvalue a, rvalue b,
947 location loc)
949 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
950 result_type, a, b, loc);
952 inline rvalue
953 context::new_logical_and (type result_type,
954 rvalue a, rvalue b,
955 location loc)
957 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
958 result_type, a, b, loc);
960 inline rvalue
961 context::new_logical_or (type result_type,
962 rvalue a, rvalue b,
963 location loc)
965 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
966 result_type, a, b, loc);
969 inline rvalue
970 context::new_comparison (enum gcc_jit_comparison op,
971 rvalue a, rvalue b,
972 location loc)
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 ()));
980 inline rvalue
981 context::new_eq (rvalue a, rvalue b,
982 location loc)
984 return new_comparison (GCC_JIT_COMPARISON_EQ,
985 a, b, loc);
987 inline rvalue
988 context::new_ne (rvalue a, rvalue b,
989 location loc)
991 return new_comparison (GCC_JIT_COMPARISON_NE,
992 a, b, loc);
994 inline rvalue
995 context::new_lt (rvalue a, rvalue b,
996 location loc)
998 return new_comparison (GCC_JIT_COMPARISON_LT,
999 a, b, loc);
1001 inline rvalue
1002 context::new_le (rvalue a, rvalue b,
1003 location loc)
1005 return new_comparison (GCC_JIT_COMPARISON_LE,
1006 a, b, loc);
1008 inline rvalue
1009 context::new_gt (rvalue a, rvalue b,
1010 location loc)
1012 return new_comparison (GCC_JIT_COMPARISON_GT,
1013 a, b, loc);
1015 inline rvalue
1016 context::new_ge (rvalue a, rvalue b,
1017 location loc)
1019 return new_comparison (GCC_JIT_COMPARISON_GE,
1020 a, b, loc);
1023 inline rvalue
1024 context::new_call (function func,
1025 std::vector<rvalue> &args,
1026 location loc)
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 (),
1038 args.size (),
1039 as_array_of_ptrs);
1041 inline rvalue
1042 context::new_call (function func,
1043 location loc)
1045 std::vector<rvalue> args;
1046 return new_call (func, args, loc);
1049 inline rvalue
1050 context::new_call (function func,
1051 rvalue arg0,
1052 location loc)
1054 std::vector<rvalue> args(1);
1055 args[0] = arg0;
1056 return new_call (func, args, loc);
1058 inline rvalue
1059 context::new_call (function func,
1060 rvalue arg0, rvalue arg1,
1061 location loc)
1063 std::vector<rvalue> args(2);
1064 args[0] = arg0;
1065 args[1] = arg1;
1066 return new_call (func, args, loc);
1068 inline rvalue
1069 context::new_call (function func,
1070 rvalue arg0, rvalue arg1, rvalue arg2,
1071 location loc)
1073 std::vector<rvalue> args(3);
1074 args[0] = arg0;
1075 args[1] = arg1;
1076 args[2] = arg2;
1077 return new_call (func, args, loc);
1079 inline rvalue
1080 context::new_call (function func,
1081 rvalue arg0, rvalue arg1, rvalue arg2,
1082 rvalue arg3,
1083 location loc)
1085 std::vector<rvalue> args(4);
1086 args[0] = arg0;
1087 args[1] = arg1;
1088 args[2] = arg2;
1089 args[3] = arg3;
1090 return new_call (func, args, loc);
1092 inline rvalue
1093 context::new_call (function func,
1094 rvalue arg0, rvalue arg1, rvalue arg2,
1095 rvalue arg3, rvalue arg4,
1096 location loc)
1098 std::vector<rvalue> args(5);
1099 args[0] = arg0;
1100 args[1] = arg1;
1101 args[2] = arg2;
1102 args[3] = arg3;
1103 args[4] = arg4;
1104 return new_call (func, args, loc);
1106 inline rvalue
1107 context::new_call (function func,
1108 rvalue arg0, rvalue arg1, rvalue arg2,
1109 rvalue arg3, rvalue arg4, rvalue arg5,
1110 location loc)
1112 std::vector<rvalue> args(6);
1113 args[0] = arg0;
1114 args[1] = arg1;
1115 args[2] = arg2;
1116 args[3] = arg3;
1117 args[4] = arg4;
1118 args[5] = arg5;
1119 return new_call (func, args, loc);
1122 inline rvalue
1123 context::new_cast (rvalue expr,
1124 type type_,
1125 location loc)
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 ()));
1133 inline lvalue
1134 context::new_array_access (rvalue ptr,
1135 rvalue index,
1136 location loc)
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 ()));
1144 inline case_
1145 context::new_case (rvalue min_value,
1146 rvalue max_value,
1147 block dest_block)
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 ()));
1155 // class object
1156 inline context
1157 object::get_context () const
1159 return context (gcc_jit_object_get_context (m_inner_obj));
1162 inline std::string
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)
1171 if (!obj)
1172 throw error ();
1175 inline gcc_jit_object *
1176 object::get_inner_object () const
1178 return m_inner_obj;
1181 inline std::ostream&
1182 operator << (std::ostream& stream, const object &obj)
1184 return stream << obj.get_debug_string ();
1187 // class location
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 ());
1200 // class field
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 ());
1213 // class type
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 ());
1226 inline type
1227 type::get_pointer ()
1229 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1232 inline type
1233 type::get_volatile ()
1235 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1238 inline rvalue
1239 type::zero ()
1241 return get_context ().new_rvalue (*this, 0);
1244 inline rvalue
1245 type::one ()
1247 return get_context ().new_rvalue (*this, 1);
1250 // class struct_
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 ());
1264 // class function
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 ());
1277 inline void
1278 function::dump_to_dot (const std::string &path)
1280 gcc_jit_function_dump_to_dot (get_inner_function (),
1281 path.c_str ());
1284 inline param
1285 function::get_param (int index) const
1287 return param (gcc_jit_function_get_param (get_inner_function (),
1288 index));
1291 inline block
1292 function::new_block ()
1294 return block (gcc_jit_function_new_block (get_inner_function (),
1295 NULL));
1298 inline block
1299 function::new_block (const std::string &name)
1301 return block (gcc_jit_function_new_block (get_inner_function (),
1302 name.c_str ()));
1305 inline lvalue
1306 function::new_local (type type_,
1307 const std::string &name,
1308 location loc)
1310 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1311 loc.get_inner_location (),
1312 type_.get_inner_type (),
1313 name.c_str ()));
1316 inline function
1317 block::get_function () const
1319 return function (gcc_jit_block_get_function ( get_inner_block ()));
1322 inline void
1323 block::add_eval (rvalue rvalue,
1324 location loc)
1326 gcc_jit_block_add_eval (get_inner_block (),
1327 loc.get_inner_location (),
1328 rvalue.get_inner_rvalue ());
1331 inline void
1332 block::add_assignment (lvalue lvalue,
1333 rvalue rvalue,
1334 location loc)
1336 gcc_jit_block_add_assignment (get_inner_block (),
1337 loc.get_inner_location (),
1338 lvalue.get_inner_lvalue (),
1339 rvalue.get_inner_rvalue ());
1342 inline void
1343 block::add_assignment_op (lvalue lvalue,
1344 enum gcc_jit_binary_op op,
1345 rvalue rvalue,
1346 location loc)
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 ());
1355 inline void
1356 block::add_comment (const std::string &text,
1357 location loc)
1359 gcc_jit_block_add_comment (get_inner_block (),
1360 loc.get_inner_location (),
1361 text.c_str ());
1364 inline void
1365 block::end_with_conditional (rvalue boolval,
1366 block on_true,
1367 block on_false,
1368 location loc)
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 ());
1377 inline void
1378 block::end_with_jump (block target,
1379 location loc)
1381 gcc_jit_block_end_with_jump (get_inner_block (),
1382 loc.get_inner_location (),
1383 target.get_inner_block ());
1386 inline void
1387 block::end_with_return (rvalue rvalue,
1388 location loc)
1390 gcc_jit_block_end_with_return (get_inner_block (),
1391 loc.get_inner_location (),
1392 rvalue.get_inner_rvalue ());
1395 inline void
1396 block::end_with_return (location loc)
1398 gcc_jit_block_end_with_void_return (get_inner_block (),
1399 loc.get_inner_location ());
1402 inline void
1403 block::end_with_switch (rvalue expr,
1404 block default_block,
1405 std::vector <case_> cases,
1406 location loc)
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 (),
1419 cases.size (),
1420 as_array_of_ptrs);
1423 inline rvalue
1424 block::add_call (function other,
1425 location loc)
1427 rvalue c = get_context ().new_call (other, loc);
1428 add_eval (c);
1429 return c;
1431 inline rvalue
1432 block::add_call (function other,
1433 rvalue arg0,
1434 location loc)
1436 rvalue c = get_context ().new_call (other, arg0, loc);
1437 add_eval (c);
1438 return c;
1440 inline rvalue
1441 block::add_call (function other,
1442 rvalue arg0, rvalue arg1,
1443 location loc)
1445 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1446 add_eval (c);
1447 return c;
1449 inline rvalue
1450 block::add_call (function other,
1451 rvalue arg0, rvalue arg1, rvalue arg2,
1452 location loc)
1454 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1455 add_eval (c);
1456 return c;
1459 inline rvalue
1460 block::add_call (function other,
1461 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1462 location loc)
1464 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1465 add_eval (c);
1466 return c;
1469 inline rvalue
1470 function::operator() (location loc)
1472 return get_context ().new_call (*this, loc);
1474 inline rvalue
1475 function::operator() (rvalue arg0,
1476 location loc)
1478 return get_context ().new_call (*this,
1479 arg0,
1480 loc);
1482 inline rvalue
1483 function::operator() (rvalue arg0, rvalue arg1,
1484 location loc)
1486 return get_context ().new_call (*this,
1487 arg0, arg1,
1488 loc);
1490 inline rvalue
1491 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1492 location loc)
1494 return get_context ().new_call (*this,
1495 arg0, arg1, arg2,
1496 loc);
1499 // class block
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 ());
1512 // class rvalue
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 ());
1525 inline type
1526 rvalue::get_type ()
1528 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1531 inline rvalue
1532 rvalue::access_field (field field,
1533 location loc)
1535 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1536 loc.get_inner_location (),
1537 field.get_inner_field ()));
1540 inline lvalue
1541 rvalue::dereference_field (field field,
1542 location loc)
1544 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1545 loc.get_inner_location (),
1546 field.get_inner_field ()));
1549 inline lvalue
1550 rvalue::dereference (location loc)
1552 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1553 loc.get_inner_location ()));
1556 inline rvalue
1557 rvalue::cast_to (type type_,
1558 location loc)
1560 return get_context ().new_cast (*this, type_, loc);
1563 inline lvalue
1564 rvalue::operator[] (rvalue index)
1566 return get_context ().new_array_access (*this, index);
1569 inline lvalue
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,
1576 index));
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 ());
1592 inline lvalue
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 ()));
1600 inline rvalue
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. */
1628 // Unary 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);
1642 // Binary operators
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);
1684 /* Comparisons. */
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 */