2014-11-20 Robert Dewar <dewar@adacore.com>
[official-gcc.git] / gcc / jit / libgccjit++.h
blob67ed5d5ee1ee721929c49728b5e985241cade032
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014 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 class context;
36 class location;
37 class field;
38 class type;
39 class struct_;
40 class param;
41 class function;
42 class block;
43 class rvalue;
44 class lvalue;
46 /* Errors within the API become C++ exceptions of this class. */
47 class error
51 class object
53 public:
54 context get_context () const;
56 std::string get_debug_string () const;
58 protected:
59 object ();
60 object (gcc_jit_object *obj);
62 gcc_jit_object *get_inner_object () const;
64 private:
65 gcc_jit_object *m_inner_obj;
68 inline std::ostream& operator << (std::ostream& stream, const object &obj);
70 /* Some client code will want to supply source code locations, others
71 won't. To avoid doubling the number of entrypoints, everything
72 accepting a location also has a default argument. To do this, the
73 other classes need to see that "location" has a default constructor,
74 hence we need to declare it first. */
75 class location : public object
77 public:
78 location ();
79 location (gcc_jit_location *loc);
81 gcc_jit_location *get_inner_location () const;
84 class context
86 public:
87 static context acquire ();
88 context ();
89 context (gcc_jit_context *ctxt);
91 gccjit::context new_child_context ();
93 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
95 void release ();
97 gcc_jit_result *compile ();
99 void dump_to_file (const std::string &path,
100 bool update_locations);
102 void set_int_option (enum gcc_jit_int_option opt,
103 int value);
105 void set_bool_option (enum gcc_jit_bool_option opt,
106 int value);
108 location
109 new_location (const std::string &filename,
110 int line,
111 int column);
113 type get_type (enum gcc_jit_types kind);
114 type get_int_type (size_t num_bytes, int is_signed);
116 /* A way to map a specific int type, using the compiler to
117 get the details automatically e.g.:
118 gccjit::type type = get_int_type <my_int_type_t> (); */
119 template <typename T>
120 type get_int_type ();
122 type new_array_type (type element_type, int num_elements,
123 location loc = location ());
125 field new_field (type type_, const std::string &name,
126 location loc = location ());
128 struct_ new_struct_type (const std::string &name,
129 std::vector<field> &fields,
130 location loc = location ());
132 struct_ new_opaque_struct_type (const std::string &name,
133 location loc = location ());
135 param new_param (type type_,
136 const std::string &name,
137 location loc = location ());
139 function new_function (enum gcc_jit_function_kind kind,
140 type return_type,
141 const std::string &name,
142 std::vector<param> &params,
143 int is_variadic,
144 location loc = location ());
146 function get_builtin_function (const std::string &name);
148 lvalue new_global (type type_,
149 const std::string &name,
150 location loc = location ());
152 rvalue new_rvalue (type numeric_type,
153 int value) const;
154 rvalue zero (type numeric_type) const;
155 rvalue one (type numeric_type) const;
156 rvalue new_rvalue (type numeric_type,
157 double value) const;
158 rvalue new_rvalue (type pointer_type,
159 void *value) const;
160 rvalue new_rvalue (const std::string &value) const;
162 /* Generic unary operations... */
163 rvalue new_unary_op (enum gcc_jit_unary_op op,
164 type result_type,
165 rvalue a,
166 location loc = location ());
168 /* ...and shorter ways to spell the various specific kinds of
169 unary op. */
170 rvalue new_minus (type result_type,
171 rvalue a,
172 location loc = location ());
173 rvalue new_bitwise_negate (type result_type,
174 rvalue a,
175 location loc = location ());
176 rvalue new_logical_negate (type result_type,
177 rvalue a,
178 location loc = location ());
180 /* Generic binary operations... */
181 rvalue new_binary_op (enum gcc_jit_binary_op op,
182 type result_type,
183 rvalue a, rvalue b,
184 location loc = location ());
186 /* ...and shorter ways to spell the various specific kinds of
187 binary op. */
188 rvalue new_plus (type result_type,
189 rvalue a, rvalue b,
190 location loc = location ());
191 rvalue new_minus (type result_type,
192 rvalue a, rvalue b,
193 location loc = location ());
194 rvalue new_mult (type result_type,
195 rvalue a, rvalue b,
196 location loc = location ());
197 rvalue new_divide (type result_type,
198 rvalue a, rvalue b,
199 location loc = location ());
200 rvalue new_modulo (type result_type,
201 rvalue a, rvalue b,
202 location loc = location ());
203 rvalue new_bitwise_and (type result_type,
204 rvalue a, rvalue b,
205 location loc = location ());
206 rvalue new_bitwise_xor (type result_type,
207 rvalue a, rvalue b,
208 location loc = location ());
209 rvalue new_bitwise_or (type result_type,
210 rvalue a, rvalue b,
211 location loc = location ());
212 rvalue new_logical_and (type result_type,
213 rvalue a, rvalue b,
214 location loc = location ());
215 rvalue new_logical_or (type result_type,
216 rvalue a, rvalue b,
217 location loc = location ());
219 /* Generic comparisons... */
220 rvalue new_comparison (enum gcc_jit_comparison op,
221 rvalue a, rvalue b,
222 location loc = location ());
223 /* ...and shorter ways to spell the various specific kinds of
224 comparison. */
225 rvalue new_eq (rvalue a, rvalue b,
226 location loc = location ());
227 rvalue new_ne (rvalue a, rvalue b,
228 location loc = location ());
229 rvalue new_lt (rvalue a, rvalue b,
230 location loc = location ());
231 rvalue new_le (rvalue a, rvalue b,
232 location loc = location ());
233 rvalue new_gt (rvalue a, rvalue b,
234 location loc = location ());
235 rvalue new_ge (rvalue a, rvalue b,
236 location loc = location ());
238 /* The most general way of creating a function call. */
239 rvalue new_call (function func,
240 std::vector<rvalue> &args,
241 location loc = location ());
243 /* In addition, we provide a series of overloaded "new_call" methods
244 for specific numbers of args (from 0 - 6), to avoid the need for
245 client code to manually build a vector. */
246 rvalue new_call (function func,
247 location loc = location ());
248 rvalue new_call (function func,
249 rvalue arg0,
250 location loc = location ());
251 rvalue new_call (function func,
252 rvalue arg0, rvalue arg1,
253 location loc = location ());
254 rvalue new_call (function func,
255 rvalue arg0, rvalue arg1, rvalue arg2,
256 location loc = location ());
257 rvalue new_call (function func,
258 rvalue arg0, rvalue arg1, rvalue arg2,
259 rvalue arg3,
260 location loc = location ());
261 rvalue new_call (function func,
262 rvalue arg0, rvalue arg1, rvalue arg2,
263 rvalue arg3, rvalue arg4,
264 location loc = location ());
265 rvalue new_call (function func,
266 rvalue arg0, rvalue arg1, rvalue arg2,
267 rvalue arg3, rvalue arg4, rvalue arg5,
268 location loc = location ());
270 rvalue new_cast (rvalue expr,
271 type type_,
272 location loc = location ());
274 lvalue new_array_access (rvalue ptr,
275 rvalue index,
276 location loc = location ());
278 private:
279 gcc_jit_context *m_inner_ctxt;
282 class field : public object
284 public:
285 field ();
286 field (gcc_jit_field *inner);
288 gcc_jit_field *get_inner_field () const;
291 class type : public object
293 public:
294 type ();
295 type (gcc_jit_type *inner);
297 gcc_jit_type *get_inner_type () const;
299 type get_pointer ();
300 type get_volatile ();
302 // Shortcuts for getting values of numeric types:
303 rvalue zero ();
304 rvalue one ();
307 class struct_ : public type
309 public:
310 struct_ ();
311 struct_ (gcc_jit_struct *inner);
313 gcc_jit_struct *get_inner_struct () const;
316 class function : public object
318 public:
319 function ();
320 function (gcc_jit_function *func);
322 gcc_jit_function *get_inner_function () const;
324 void dump_to_dot (const std::string &path);
326 param get_param (int index) const;
328 block new_block ();
329 block new_block (const std::string &name);
331 lvalue new_local (type type_,
332 const std::string &name,
333 location loc = location ());
335 /* A series of overloaded operator () with various numbers of arguments
336 for a very terse way of creating a call to this function. The call
337 is created within the same context as the function itself, which may
338 not be what you want. */
339 rvalue operator() (location loc = location ());
340 rvalue operator() (rvalue arg0,
341 location loc = location ());
342 rvalue operator() (rvalue arg0, rvalue arg1,
343 location loc = location ());
344 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
345 location loc = location ());
348 class block : public object
350 public:
351 block ();
352 block (gcc_jit_block *inner);
354 gcc_jit_block *get_inner_block () const;
356 function get_function () const;
358 void add_eval (rvalue rvalue,
359 location loc = location ());
361 void add_assignment (lvalue lvalue,
362 rvalue rvalue,
363 location loc = location ());
365 void add_assignment_op (lvalue lvalue,
366 enum gcc_jit_binary_op op,
367 rvalue rvalue,
368 location loc = location ());
370 /* A way to add a function call to the body of a function being
371 defined, with various numbers of args. */
372 rvalue add_call (function other,
373 location loc = location ());
374 rvalue add_call (function other,
375 rvalue arg0,
376 location loc = location ());
377 rvalue add_call (function other,
378 rvalue arg0, rvalue arg1,
379 location loc = location ());
380 rvalue add_call (function other,
381 rvalue arg0, rvalue arg1, rvalue arg2,
382 location loc = location ());
383 rvalue add_call (function other,
384 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
385 location loc = location ());
387 void add_comment (const std::string &text,
388 location loc = location ());
390 void end_with_conditional (rvalue boolval,
391 block on_true,
392 block on_false,
393 location loc = location ());
395 void end_with_jump (block target,
396 location loc = location ());
398 void end_with_return (rvalue rvalue,
399 location loc = location ());
400 void end_with_return (location loc = location ());
404 class rvalue : public object
406 public:
407 rvalue ();
408 rvalue (gcc_jit_rvalue *inner);
409 gcc_jit_rvalue *get_inner_rvalue () const;
411 type get_type ();
413 rvalue access_field (field field,
414 location loc = location ());
416 lvalue dereference_field (field field,
417 location loc = location ());
419 lvalue dereference (location loc = location ());
421 rvalue cast_to (type type_,
422 location loc = location ());
424 /* Array access. */
425 lvalue operator[] (rvalue index);
426 lvalue operator[] (int index);
429 class lvalue : public rvalue
431 public:
432 lvalue ();
433 lvalue (gcc_jit_lvalue *inner);
435 gcc_jit_lvalue *get_inner_lvalue () const;
437 lvalue access_field (field field,
438 location loc = location ());
440 rvalue get_address (location loc = location ());
443 class param : public lvalue
445 public:
446 param ();
447 param (gcc_jit_param *inner);
449 gcc_jit_param *get_inner_param () const;
453 /* Overloaded operators, for those who want the most terse API
454 (at the possible risk of being a little too magical).
456 In each case, the first parameter is used to determine which context
457 owns the resulting expression, and, where appropriate, what the
458 latter's type is. */
460 /* Unary operators. */
461 rvalue operator- (rvalue a); // unary minus
462 rvalue operator~ (rvalue a); // unary bitwise negate
463 rvalue operator! (rvalue a); // unary logical negate
465 /* Binary operators. */
466 rvalue operator+ (rvalue a, rvalue b);
467 rvalue operator- (rvalue a, rvalue b);
468 rvalue operator* (rvalue a, rvalue b);
469 rvalue operator/ (rvalue a, rvalue b);
470 rvalue operator% (rvalue a, rvalue b);
471 rvalue operator& (rvalue a, rvalue b); // bitwise and
472 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
473 rvalue operator| (rvalue a, rvalue b); // bitwise_or
474 rvalue operator&& (rvalue a, rvalue b); // logical_and
475 rvalue operator|| (rvalue a, rvalue b); // logical_or
477 /* Comparisons. */
478 rvalue operator== (rvalue a, rvalue b);
479 rvalue operator!= (rvalue a, rvalue b);
480 rvalue operator< (rvalue a, rvalue b);
481 rvalue operator<= (rvalue a, rvalue b);
482 rvalue operator> (rvalue a, rvalue b);
483 rvalue operator>= (rvalue a, rvalue b);
485 /* Dereferencing. */
486 lvalue operator* (rvalue ptr);
489 /****************************************************************************
490 Implementation of the API
491 ****************************************************************************/
492 namespace gccjit {
494 // class context
495 inline context context::acquire ()
497 return context (gcc_jit_context_acquire ());
499 inline context::context () : m_inner_ctxt (NULL) {}
500 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
502 if (!inner)
503 throw error ();
506 inline gccjit::context
507 context::new_child_context ()
509 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
512 inline void
513 context::release ()
515 gcc_jit_context_release (m_inner_ctxt);
516 m_inner_ctxt = NULL;
519 inline gcc_jit_result *
520 context::compile ()
522 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
523 if (!result)
524 throw error ();
525 return result;
528 inline void
529 context::dump_to_file (const std::string &path,
530 bool update_locations)
532 gcc_jit_context_dump_to_file (m_inner_ctxt,
533 path.c_str (),
534 update_locations);
537 inline void
538 context::set_int_option (enum gcc_jit_int_option opt,
539 int value)
541 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
545 inline void
546 context::set_bool_option (enum gcc_jit_bool_option opt,
547 int value)
549 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
553 inline location
554 context::new_location (const std::string &filename,
555 int line,
556 int column)
558 return location (gcc_jit_context_new_location (m_inner_ctxt,
559 filename.c_str (),
560 line,
561 column));
564 inline type
565 context::get_type (enum gcc_jit_types kind)
567 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
570 inline type
571 context::get_int_type (size_t num_bytes, int is_signed)
573 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
574 num_bytes,
575 is_signed));
578 template <typename T>
579 inline type
580 context::get_int_type ()
582 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
585 inline type
586 context::new_array_type (type element_type, int num_elements, location loc)
588 return type (gcc_jit_context_new_array_type (
589 m_inner_ctxt,
590 loc.get_inner_location (),
591 element_type.get_inner_type (),
592 num_elements));
595 inline field
596 context::new_field (type type_, const std::string &name, location loc)
598 return field (gcc_jit_context_new_field (m_inner_ctxt,
599 loc.get_inner_location (),
600 type_.get_inner_type (),
601 name.c_str ()));
604 inline struct_
605 context::new_struct_type (const std::string &name,
606 std::vector<field> &fields,
607 location loc)
609 /* Treat std::vector as an array, relying on it not being resized: */
610 field *as_array_of_wrappers = &fields[0];
612 /* Treat the array as being of the underlying pointers, relying on
613 the wrapper type being such a pointer internally. */
614 gcc_jit_field **as_array_of_ptrs =
615 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
617 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
618 loc.get_inner_location (),
619 name.c_str (),
620 fields.size (),
621 as_array_of_ptrs));
624 inline struct_
625 context::new_opaque_struct_type (const std::string &name,
626 location loc)
628 return struct_ (gcc_jit_context_new_opaque_struct (
629 m_inner_ctxt,
630 loc.get_inner_location (),
631 name.c_str ()));
634 inline param
635 context::new_param (type type_,
636 const std::string &name,
637 location loc)
639 return param (gcc_jit_context_new_param (m_inner_ctxt,
640 loc.get_inner_location (),
641 type_.get_inner_type (),
642 name.c_str ()));
645 inline function
646 context::new_function (enum gcc_jit_function_kind kind,
647 type return_type,
648 const std::string &name,
649 std::vector<param> &params,
650 int is_variadic,
651 location loc)
653 /* Treat std::vector as an array, relying on it not being resized: */
654 param *as_array_of_wrappers = &params[0];
656 /* Treat the array as being of the underlying pointers, relying on
657 the wrapper type being such a pointer internally. */
658 gcc_jit_param **as_array_of_ptrs =
659 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
661 return function (gcc_jit_context_new_function (m_inner_ctxt,
662 loc.get_inner_location (),
663 kind,
664 return_type.get_inner_type (),
665 name.c_str (),
666 params.size (),
667 as_array_of_ptrs,
668 is_variadic));
671 inline function
672 context::get_builtin_function (const std::string &name)
674 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
675 name.c_str ()));
678 inline lvalue
679 context::new_global (type type_,
680 const std::string &name,
681 location loc)
683 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
684 loc.get_inner_location (),
685 type_.get_inner_type (),
686 name.c_str ()));
689 inline rvalue
690 context::new_rvalue (type numeric_type,
691 int value) const
693 return rvalue (
694 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
695 numeric_type.get_inner_type (),
696 value));
699 inline rvalue
700 context::zero (type numeric_type) const
702 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
703 numeric_type.get_inner_type ()));
706 inline rvalue
707 context::one (type numeric_type) const
709 return rvalue (gcc_jit_context_one (m_inner_ctxt,
710 numeric_type.get_inner_type ()));
713 inline rvalue
714 context::new_rvalue (type numeric_type,
715 double value) const
717 return rvalue (
718 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
719 numeric_type.get_inner_type (),
720 value));
723 inline rvalue
724 context::new_rvalue (type pointer_type,
725 void *value) const
727 return rvalue (
728 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
729 pointer_type.get_inner_type (),
730 value));
733 inline rvalue
734 context::new_rvalue (const std::string &value) const
736 return rvalue (
737 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
740 inline rvalue
741 context::new_unary_op (enum gcc_jit_unary_op op,
742 type result_type,
743 rvalue a,
744 location loc)
746 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
747 loc.get_inner_location (),
749 result_type.get_inner_type (),
750 a.get_inner_rvalue ()));
752 inline rvalue
753 context::new_minus (type result_type,
754 rvalue a,
755 location loc)
757 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
758 result_type, a, loc));
760 inline rvalue
761 context::new_bitwise_negate (type result_type,
762 rvalue a,
763 location loc)
765 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
766 result_type, a, loc));
768 inline rvalue
769 context::new_logical_negate (type result_type,
770 rvalue a,
771 location loc)
773 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
774 result_type, a, loc));
777 inline rvalue
778 context::new_binary_op (enum gcc_jit_binary_op op,
779 type result_type,
780 rvalue a, rvalue b,
781 location loc)
783 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
784 loc.get_inner_location (),
786 result_type.get_inner_type (),
787 a.get_inner_rvalue (),
788 b.get_inner_rvalue ()));
790 inline rvalue
791 context::new_plus (type result_type,
792 rvalue a, rvalue b,
793 location loc)
795 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
796 result_type, a, b, loc);
798 inline rvalue
799 context::new_minus (type result_type,
800 rvalue a, rvalue b,
801 location loc)
803 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
804 result_type, a, b, loc);
806 inline rvalue
807 context::new_mult (type result_type,
808 rvalue a, rvalue b,
809 location loc)
811 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
812 result_type, a, b, loc);
814 inline rvalue
815 context::new_divide (type result_type,
816 rvalue a, rvalue b,
817 location loc)
819 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
820 result_type, a, b, loc);
822 inline rvalue
823 context::new_modulo (type result_type,
824 rvalue a, rvalue b,
825 location loc)
827 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
828 result_type, a, b, loc);
830 inline rvalue
831 context::new_bitwise_and (type result_type,
832 rvalue a, rvalue b,
833 location loc)
835 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
836 result_type, a, b, loc);
838 inline rvalue
839 context::new_bitwise_xor (type result_type,
840 rvalue a, rvalue b,
841 location loc)
843 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
844 result_type, a, b, loc);
846 inline rvalue
847 context::new_bitwise_or (type result_type,
848 rvalue a, rvalue b,
849 location loc)
851 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
852 result_type, a, b, loc);
854 inline rvalue
855 context::new_logical_and (type result_type,
856 rvalue a, rvalue b,
857 location loc)
859 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
860 result_type, a, b, loc);
862 inline rvalue
863 context::new_logical_or (type result_type,
864 rvalue a, rvalue b,
865 location loc)
867 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
868 result_type, a, b, loc);
871 inline rvalue
872 context::new_comparison (enum gcc_jit_comparison op,
873 rvalue a, rvalue b,
874 location loc)
876 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
877 loc.get_inner_location (),
879 a.get_inner_rvalue (),
880 b.get_inner_rvalue ()));
882 inline rvalue
883 context::new_eq (rvalue a, rvalue b,
884 location loc)
886 return new_comparison (GCC_JIT_COMPARISON_EQ,
887 a, b, loc);
889 inline rvalue
890 context::new_ne (rvalue a, rvalue b,
891 location loc)
893 return new_comparison (GCC_JIT_COMPARISON_NE,
894 a, b, loc);
896 inline rvalue
897 context::new_lt (rvalue a, rvalue b,
898 location loc)
900 return new_comparison (GCC_JIT_COMPARISON_LT,
901 a, b, loc);
903 inline rvalue
904 context::new_le (rvalue a, rvalue b,
905 location loc)
907 return new_comparison (GCC_JIT_COMPARISON_LE,
908 a, b, loc);
910 inline rvalue
911 context::new_gt (rvalue a, rvalue b,
912 location loc)
914 return new_comparison (GCC_JIT_COMPARISON_GT,
915 a, b, loc);
917 inline rvalue
918 context::new_ge (rvalue a, rvalue b,
919 location loc)
921 return new_comparison (GCC_JIT_COMPARISON_GE,
922 a, b, loc);
925 inline rvalue
926 context::new_call (function func,
927 std::vector<rvalue> &args,
928 location loc)
930 /* Treat std::vector as an array, relying on it not being resized: */
931 rvalue *as_array_of_wrappers = &args[0];
933 /* Treat the array as being of the underlying pointers, relying on
934 the wrapper type being such a pointer internally. */
935 gcc_jit_rvalue **as_array_of_ptrs =
936 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
937 return gcc_jit_context_new_call (m_inner_ctxt,
938 loc.get_inner_location (),
939 func.get_inner_function (),
940 args.size (),
941 as_array_of_ptrs);
943 inline rvalue
944 context::new_call (function func,
945 location loc)
947 std::vector<rvalue> args;
948 return new_call (func, args, loc);
951 inline rvalue
952 context::new_call (function func,
953 rvalue arg0,
954 location loc)
956 std::vector<rvalue> args(1);
957 args[0] = arg0;
958 return new_call (func, args, loc);
960 inline rvalue
961 context::new_call (function func,
962 rvalue arg0, rvalue arg1,
963 location loc)
965 std::vector<rvalue> args(2);
966 args[0] = arg0;
967 args[1] = arg1;
968 return new_call (func, args, loc);
970 inline rvalue
971 context::new_call (function func,
972 rvalue arg0, rvalue arg1, rvalue arg2,
973 location loc)
975 std::vector<rvalue> args(3);
976 args[0] = arg0;
977 args[1] = arg1;
978 args[2] = arg2;
979 return new_call (func, args, loc);
981 inline rvalue
982 context::new_call (function func,
983 rvalue arg0, rvalue arg1, rvalue arg2,
984 rvalue arg3,
985 location loc)
987 std::vector<rvalue> args(4);
988 args[0] = arg0;
989 args[1] = arg1;
990 args[2] = arg2;
991 args[3] = arg3;
992 return new_call (func, args, loc);
994 inline rvalue
995 context::new_call (function func,
996 rvalue arg0, rvalue arg1, rvalue arg2,
997 rvalue arg3, rvalue arg4,
998 location loc)
1000 std::vector<rvalue> args(5);
1001 args[0] = arg0;
1002 args[1] = arg1;
1003 args[2] = arg2;
1004 args[3] = arg3;
1005 args[4] = arg4;
1006 return new_call (func, args, loc);
1008 inline rvalue
1009 context::new_call (function func,
1010 rvalue arg0, rvalue arg1, rvalue arg2,
1011 rvalue arg3, rvalue arg4, rvalue arg5,
1012 location loc)
1014 std::vector<rvalue> args(6);
1015 args[0] = arg0;
1016 args[1] = arg1;
1017 args[2] = arg2;
1018 args[3] = arg3;
1019 args[4] = arg4;
1020 args[5] = arg5;
1021 return new_call (func, args, loc);
1024 inline rvalue
1025 context::new_cast (rvalue expr,
1026 type type_,
1027 location loc)
1029 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1030 loc.get_inner_location (),
1031 expr.get_inner_rvalue (),
1032 type_.get_inner_type ()));
1035 inline lvalue
1036 context::new_array_access (rvalue ptr,
1037 rvalue index,
1038 location loc)
1040 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1041 loc.get_inner_location (),
1042 ptr.get_inner_rvalue (),
1043 index.get_inner_rvalue ()));
1046 // class object
1047 inline context
1048 object::get_context () const
1050 return context (gcc_jit_object_get_context (m_inner_obj));
1053 inline std::string
1054 object::get_debug_string () const
1056 return gcc_jit_object_get_debug_string (m_inner_obj);
1059 inline object::object () : m_inner_obj (NULL) {}
1060 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1062 if (!obj)
1063 throw error ();
1066 inline gcc_jit_object *
1067 object::get_inner_object () const
1069 return m_inner_obj;
1072 inline std::ostream&
1073 operator << (std::ostream& stream, const object &obj)
1075 return stream << obj.get_debug_string ();
1078 // class location
1079 inline location::location () : object () {}
1080 inline location::location (gcc_jit_location *loc)
1081 : object (gcc_jit_location_as_object (loc))
1084 inline gcc_jit_location *
1085 location::get_inner_location () const
1087 /* Manual downcast: */
1088 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1091 // class field
1092 inline field::field () : object () {}
1093 inline field::field (gcc_jit_field *inner)
1094 : object (gcc_jit_field_as_object (inner))
1097 inline gcc_jit_field *
1098 field::get_inner_field () const
1100 /* Manual downcast: */
1101 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1104 // class type
1105 inline type::type () : object () {}
1106 inline type::type (gcc_jit_type *inner)
1107 : object (gcc_jit_type_as_object (inner))
1110 inline gcc_jit_type *
1111 type::get_inner_type () const
1113 /* Manual downcast: */
1114 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1117 inline type
1118 type::get_pointer ()
1120 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1123 inline type
1124 type::get_volatile ()
1126 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1129 inline rvalue
1130 type::zero ()
1132 return get_context ().new_rvalue (*this, 0);
1135 inline rvalue
1136 type::one ()
1138 return get_context ().new_rvalue (*this, 1);
1141 // class struct_
1142 inline struct_::struct_ () : type (NULL) {}
1143 inline struct_::struct_ (gcc_jit_struct *inner) :
1144 type (gcc_jit_struct_as_type (inner))
1148 inline gcc_jit_struct *
1149 struct_::get_inner_struct () const
1151 /* Manual downcast: */
1152 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1155 // class function
1156 inline function::function () : object () {}
1157 inline function::function (gcc_jit_function *inner)
1158 : object (gcc_jit_function_as_object (inner))
1161 inline gcc_jit_function *
1162 function::get_inner_function () const
1164 /* Manual downcast: */
1165 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1168 inline void
1169 function::dump_to_dot (const std::string &path)
1171 gcc_jit_function_dump_to_dot (get_inner_function (),
1172 path.c_str ());
1175 inline param
1176 function::get_param (int index) const
1178 return param (gcc_jit_function_get_param (get_inner_function (),
1179 index));
1182 inline block
1183 function::new_block ()
1185 return block (gcc_jit_function_new_block (get_inner_function (),
1186 NULL));
1189 inline block
1190 function::new_block (const std::string &name)
1192 return block (gcc_jit_function_new_block (get_inner_function (),
1193 name.c_str ()));
1196 inline lvalue
1197 function::new_local (type type_,
1198 const std::string &name,
1199 location loc)
1201 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1202 loc.get_inner_location (),
1203 type_.get_inner_type (),
1204 name.c_str ()));
1207 inline function
1208 block::get_function () const
1210 return function (gcc_jit_block_get_function ( get_inner_block ()));
1213 inline void
1214 block::add_eval (rvalue rvalue,
1215 location loc)
1217 gcc_jit_block_add_eval (get_inner_block (),
1218 loc.get_inner_location (),
1219 rvalue.get_inner_rvalue ());
1222 inline void
1223 block::add_assignment (lvalue lvalue,
1224 rvalue rvalue,
1225 location loc)
1227 gcc_jit_block_add_assignment (get_inner_block (),
1228 loc.get_inner_location (),
1229 lvalue.get_inner_lvalue (),
1230 rvalue.get_inner_rvalue ());
1233 inline void
1234 block::add_assignment_op (lvalue lvalue,
1235 enum gcc_jit_binary_op op,
1236 rvalue rvalue,
1237 location loc)
1239 gcc_jit_block_add_assignment_op (get_inner_block (),
1240 loc.get_inner_location (),
1241 lvalue.get_inner_lvalue (),
1243 rvalue.get_inner_rvalue ());
1246 inline void
1247 block::add_comment (const std::string &text,
1248 location loc)
1250 gcc_jit_block_add_comment (get_inner_block (),
1251 loc.get_inner_location (),
1252 text.c_str ());
1255 inline void
1256 block::end_with_conditional (rvalue boolval,
1257 block on_true,
1258 block on_false,
1259 location loc)
1261 gcc_jit_block_end_with_conditional (get_inner_block (),
1262 loc.get_inner_location (),
1263 boolval.get_inner_rvalue (),
1264 on_true.get_inner_block (),
1265 on_false.get_inner_block ());
1268 inline void
1269 block::end_with_jump (block target,
1270 location loc)
1272 gcc_jit_block_end_with_jump (get_inner_block (),
1273 loc.get_inner_location (),
1274 target.get_inner_block ());
1277 inline void
1278 block::end_with_return (rvalue rvalue,
1279 location loc)
1281 gcc_jit_block_end_with_return (get_inner_block (),
1282 loc.get_inner_location (),
1283 rvalue.get_inner_rvalue ());
1286 inline void
1287 block::end_with_return (location loc)
1289 gcc_jit_block_end_with_void_return (get_inner_block (),
1290 loc.get_inner_location ());
1293 inline rvalue
1294 block::add_call (function other,
1295 location loc)
1297 rvalue c = get_context ().new_call (other, loc);
1298 add_eval (c);
1299 return c;
1301 inline rvalue
1302 block::add_call (function other,
1303 rvalue arg0,
1304 location loc)
1306 rvalue c = get_context ().new_call (other, arg0, loc);
1307 add_eval (c);
1308 return c;
1310 inline rvalue
1311 block::add_call (function other,
1312 rvalue arg0, rvalue arg1,
1313 location loc)
1315 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1316 add_eval (c);
1317 return c;
1319 inline rvalue
1320 block::add_call (function other,
1321 rvalue arg0, rvalue arg1, rvalue arg2,
1322 location loc)
1324 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1325 add_eval (c);
1326 return c;
1329 inline rvalue
1330 block::add_call (function other,
1331 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1332 location loc)
1334 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1335 add_eval (c);
1336 return c;
1339 inline rvalue
1340 function::operator() (location loc)
1342 return get_context ().new_call (*this, loc);
1344 inline rvalue
1345 function::operator() (rvalue arg0,
1346 location loc)
1348 return get_context ().new_call (*this,
1349 arg0,
1350 loc);
1352 inline rvalue
1353 function::operator() (rvalue arg0, rvalue arg1,
1354 location loc)
1356 return get_context ().new_call (*this,
1357 arg0, arg1,
1358 loc);
1360 inline rvalue
1361 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1362 location loc)
1364 return get_context ().new_call (*this,
1365 arg0, arg1, arg2,
1366 loc);
1369 // class block
1370 inline block::block () : object () {}
1371 inline block::block (gcc_jit_block *inner)
1372 : object (gcc_jit_block_as_object (inner))
1375 inline gcc_jit_block *
1376 block::get_inner_block () const
1378 /* Manual downcast: */
1379 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1382 // class rvalue
1383 inline rvalue::rvalue () : object () {}
1384 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1385 : object (gcc_jit_rvalue_as_object (inner))
1388 inline gcc_jit_rvalue *
1389 rvalue::get_inner_rvalue () const
1391 /* Manual downcast: */
1392 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1395 inline type
1396 rvalue::get_type ()
1398 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1401 inline rvalue
1402 rvalue::access_field (field field,
1403 location loc)
1405 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1406 loc.get_inner_location (),
1407 field.get_inner_field ()));
1410 inline lvalue
1411 rvalue::dereference_field (field field,
1412 location loc)
1414 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1415 loc.get_inner_location (),
1416 field.get_inner_field ()));
1419 inline lvalue
1420 rvalue::dereference (location loc)
1422 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1423 loc.get_inner_location ()));
1426 inline rvalue
1427 rvalue::cast_to (type type_,
1428 location loc)
1430 return get_context ().new_cast (*this, type_, loc);
1433 inline lvalue
1434 rvalue::operator[] (rvalue index)
1436 return get_context ().new_array_access (*this, index);
1439 inline lvalue
1440 rvalue::operator[] (int index)
1442 context ctxt = get_context ();
1443 type int_t = ctxt.get_int_type <int> ();
1444 return ctxt.new_array_access (*this,
1445 ctxt.new_rvalue (int_t,
1446 index));
1449 // class lvalue : public rvalue
1450 inline lvalue::lvalue () : rvalue () {}
1451 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1452 : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1455 inline gcc_jit_lvalue *
1456 lvalue::get_inner_lvalue () const
1458 /* Manual downcast: */
1459 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1462 inline lvalue
1463 lvalue::access_field (field field, location loc)
1465 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1466 loc.get_inner_location (),
1467 field.get_inner_field ()));
1470 inline rvalue
1471 lvalue::get_address (location loc)
1473 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1474 loc.get_inner_location ()));
1477 // class param : public lvalue
1478 inline param::param () : lvalue () {}
1479 inline param::param (gcc_jit_param *inner)
1480 : lvalue (gcc_jit_param_as_lvalue (inner))
1483 /* Overloaded operators. */
1484 // Unary operators
1485 inline rvalue operator- (rvalue a)
1487 return a.get_context ().new_minus (a.get_type (), a);
1489 inline rvalue operator~ (rvalue a)
1491 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1493 inline rvalue operator! (rvalue a)
1495 return a.get_context ().new_logical_negate (a.get_type (), a);
1498 // Binary operators
1499 inline rvalue operator+ (rvalue a, rvalue b)
1501 return a.get_context ().new_plus (a.get_type (), a, b);
1503 inline rvalue operator- (rvalue a, rvalue b)
1505 return a.get_context ().new_minus (a.get_type (), a, b);
1507 inline rvalue operator* (rvalue a, rvalue b)
1509 return a.get_context ().new_mult (a.get_type (), a, b);
1511 inline rvalue operator/ (rvalue a, rvalue b)
1513 return a.get_context ().new_divide (a.get_type (), a, b);
1515 inline rvalue operator% (rvalue a, rvalue b)
1517 return a.get_context ().new_modulo (a.get_type (), a, b);
1519 inline rvalue operator& (rvalue a, rvalue b)
1521 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1523 inline rvalue operator^ (rvalue a, rvalue b)
1525 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1527 inline rvalue operator| (rvalue a, rvalue b)
1529 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1531 inline rvalue operator&& (rvalue a, rvalue b)
1533 return a.get_context ().new_logical_and (a.get_type (), a, b);
1535 inline rvalue operator|| (rvalue a, rvalue b)
1537 return a.get_context ().new_logical_or (a.get_type (), a, b);
1540 /* Comparisons. */
1541 inline rvalue operator== (rvalue a, rvalue b)
1543 return a.get_context ().new_eq (a, b);
1545 inline rvalue operator!= (rvalue a, rvalue b)
1547 return a.get_context ().new_ne (a, b);
1549 inline rvalue operator< (rvalue a, rvalue b)
1551 return a.get_context ().new_lt (a, b);
1553 inline rvalue operator<= (rvalue a, rvalue b)
1555 return a.get_context ().new_le (a, b);
1557 inline rvalue operator> (rvalue a, rvalue b)
1559 return a.get_context ().new_gt (a, b);
1561 inline rvalue operator>= (rvalue a, rvalue b)
1563 return a.get_context ().new_ge (a, b);
1566 /* Dereferencing. */
1567 inline lvalue operator* (rvalue ptr)
1569 return ptr.dereference ();
1572 } // namespace gccjit
1574 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */