2015-03-02 Hristian Kirtchev <kirtchev@adacore.com>
[official-gcc.git] / gcc / jit / libgccjit++.h
blob62ef6a432efabf124cf21d7023231c5bdbeda1e3
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 location
124 new_location (const std::string &filename,
125 int line,
126 int column);
128 type get_type (enum gcc_jit_types kind);
129 type get_int_type (size_t num_bytes, int is_signed);
131 /* A way to map a specific int type, using the compiler to
132 get the details automatically e.g.:
133 gccjit::type type = get_int_type <my_int_type_t> (); */
134 template <typename T>
135 type get_int_type ();
137 type new_array_type (type element_type, int num_elements,
138 location loc = location ());
140 field new_field (type type_, const std::string &name,
141 location loc = location ());
143 struct_ new_struct_type (const std::string &name,
144 std::vector<field> &fields,
145 location loc = location ());
147 struct_ new_opaque_struct_type (const std::string &name,
148 location loc = location ());
150 param new_param (type type_,
151 const std::string &name,
152 location loc = location ());
154 function new_function (enum gcc_jit_function_kind kind,
155 type return_type,
156 const std::string &name,
157 std::vector<param> &params,
158 int is_variadic,
159 location loc = location ());
161 function get_builtin_function (const std::string &name);
163 lvalue new_global (enum gcc_jit_global_kind kind,
164 type type_,
165 const std::string &name,
166 location loc = location ());
168 rvalue new_rvalue (type numeric_type,
169 int value) const;
170 rvalue new_rvalue (type numeric_type,
171 long value) const;
172 rvalue zero (type numeric_type) const;
173 rvalue one (type numeric_type) const;
174 rvalue new_rvalue (type numeric_type,
175 double value) const;
176 rvalue new_rvalue (type pointer_type,
177 void *value) const;
178 rvalue new_rvalue (const std::string &value) const;
180 /* Generic unary operations... */
181 rvalue new_unary_op (enum gcc_jit_unary_op op,
182 type result_type,
183 rvalue a,
184 location loc = location ());
186 /* ...and shorter ways to spell the various specific kinds of
187 unary op. */
188 rvalue new_minus (type result_type,
189 rvalue a,
190 location loc = location ());
191 rvalue new_bitwise_negate (type result_type,
192 rvalue a,
193 location loc = location ());
194 rvalue new_logical_negate (type result_type,
195 rvalue a,
196 location loc = location ());
198 /* Generic binary operations... */
199 rvalue new_binary_op (enum gcc_jit_binary_op op,
200 type result_type,
201 rvalue a, rvalue b,
202 location loc = location ());
204 /* ...and shorter ways to spell the various specific kinds of
205 binary op. */
206 rvalue new_plus (type result_type,
207 rvalue a, rvalue b,
208 location loc = location ());
209 rvalue new_minus (type result_type,
210 rvalue a, rvalue b,
211 location loc = location ());
212 rvalue new_mult (type result_type,
213 rvalue a, rvalue b,
214 location loc = location ());
215 rvalue new_divide (type result_type,
216 rvalue a, rvalue b,
217 location loc = location ());
218 rvalue new_modulo (type result_type,
219 rvalue a, rvalue b,
220 location loc = location ());
221 rvalue new_bitwise_and (type result_type,
222 rvalue a, rvalue b,
223 location loc = location ());
224 rvalue new_bitwise_xor (type result_type,
225 rvalue a, rvalue b,
226 location loc = location ());
227 rvalue new_bitwise_or (type result_type,
228 rvalue a, rvalue b,
229 location loc = location ());
230 rvalue new_logical_and (type result_type,
231 rvalue a, rvalue b,
232 location loc = location ());
233 rvalue new_logical_or (type result_type,
234 rvalue a, rvalue b,
235 location loc = location ());
237 /* Generic comparisons... */
238 rvalue new_comparison (enum gcc_jit_comparison op,
239 rvalue a, rvalue b,
240 location loc = location ());
241 /* ...and shorter ways to spell the various specific kinds of
242 comparison. */
243 rvalue new_eq (rvalue a, rvalue b,
244 location loc = location ());
245 rvalue new_ne (rvalue a, rvalue b,
246 location loc = location ());
247 rvalue new_lt (rvalue a, rvalue b,
248 location loc = location ());
249 rvalue new_le (rvalue a, rvalue b,
250 location loc = location ());
251 rvalue new_gt (rvalue a, rvalue b,
252 location loc = location ());
253 rvalue new_ge (rvalue a, rvalue b,
254 location loc = location ());
256 /* The most general way of creating a function call. */
257 rvalue new_call (function func,
258 std::vector<rvalue> &args,
259 location loc = location ());
261 /* In addition, we provide a series of overloaded "new_call" methods
262 for specific numbers of args (from 0 - 6), to avoid the need for
263 client code to manually build a vector. */
264 rvalue new_call (function func,
265 location loc = location ());
266 rvalue new_call (function func,
267 rvalue arg0,
268 location loc = location ());
269 rvalue new_call (function func,
270 rvalue arg0, rvalue arg1,
271 location loc = location ());
272 rvalue new_call (function func,
273 rvalue arg0, rvalue arg1, rvalue arg2,
274 location loc = location ());
275 rvalue new_call (function func,
276 rvalue arg0, rvalue arg1, rvalue arg2,
277 rvalue arg3,
278 location loc = location ());
279 rvalue new_call (function func,
280 rvalue arg0, rvalue arg1, rvalue arg2,
281 rvalue arg3, rvalue arg4,
282 location loc = location ());
283 rvalue new_call (function func,
284 rvalue arg0, rvalue arg1, rvalue arg2,
285 rvalue arg3, rvalue arg4, rvalue arg5,
286 location loc = location ());
288 rvalue new_cast (rvalue expr,
289 type type_,
290 location loc = location ());
292 lvalue new_array_access (rvalue ptr,
293 rvalue index,
294 location loc = location ());
296 private:
297 gcc_jit_context *m_inner_ctxt;
300 class field : public object
302 public:
303 field ();
304 field (gcc_jit_field *inner);
306 gcc_jit_field *get_inner_field () const;
309 class type : public object
311 public:
312 type ();
313 type (gcc_jit_type *inner);
315 gcc_jit_type *get_inner_type () const;
317 type get_pointer ();
318 type get_volatile ();
320 // Shortcuts for getting values of numeric types:
321 rvalue zero ();
322 rvalue one ();
325 class struct_ : public type
327 public:
328 struct_ ();
329 struct_ (gcc_jit_struct *inner);
331 gcc_jit_struct *get_inner_struct () const;
334 class function : public object
336 public:
337 function ();
338 function (gcc_jit_function *func);
340 gcc_jit_function *get_inner_function () const;
342 void dump_to_dot (const std::string &path);
344 param get_param (int index) const;
346 block new_block ();
347 block new_block (const std::string &name);
349 lvalue new_local (type type_,
350 const std::string &name,
351 location loc = location ());
353 /* A series of overloaded operator () with various numbers of arguments
354 for a very terse way of creating a call to this function. The call
355 is created within the same context as the function itself, which may
356 not be what you want. */
357 rvalue operator() (location loc = location ());
358 rvalue operator() (rvalue arg0,
359 location loc = location ());
360 rvalue operator() (rvalue arg0, rvalue arg1,
361 location loc = location ());
362 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
363 location loc = location ());
366 class block : public object
368 public:
369 block ();
370 block (gcc_jit_block *inner);
372 gcc_jit_block *get_inner_block () const;
374 function get_function () const;
376 void add_eval (rvalue rvalue,
377 location loc = location ());
379 void add_assignment (lvalue lvalue,
380 rvalue rvalue,
381 location loc = location ());
383 void add_assignment_op (lvalue lvalue,
384 enum gcc_jit_binary_op op,
385 rvalue rvalue,
386 location loc = location ());
388 /* A way to add a function call to the body of a function being
389 defined, with various numbers of args. */
390 rvalue add_call (function other,
391 location loc = location ());
392 rvalue add_call (function other,
393 rvalue arg0,
394 location loc = location ());
395 rvalue add_call (function other,
396 rvalue arg0, rvalue arg1,
397 location loc = location ());
398 rvalue add_call (function other,
399 rvalue arg0, rvalue arg1, rvalue arg2,
400 location loc = location ());
401 rvalue add_call (function other,
402 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
403 location loc = location ());
405 void add_comment (const std::string &text,
406 location loc = location ());
408 void end_with_conditional (rvalue boolval,
409 block on_true,
410 block on_false,
411 location loc = location ());
413 void end_with_jump (block target,
414 location loc = location ());
416 void end_with_return (rvalue rvalue,
417 location loc = location ());
418 void end_with_return (location loc = location ());
422 class rvalue : public object
424 public:
425 rvalue ();
426 rvalue (gcc_jit_rvalue *inner);
427 gcc_jit_rvalue *get_inner_rvalue () const;
429 type get_type ();
431 rvalue access_field (field field,
432 location loc = location ());
434 lvalue dereference_field (field field,
435 location loc = location ());
437 lvalue dereference (location loc = location ());
439 rvalue cast_to (type type_,
440 location loc = location ());
442 /* Array access. */
443 lvalue operator[] (rvalue index);
444 lvalue operator[] (int index);
447 class lvalue : public rvalue
449 public:
450 lvalue ();
451 lvalue (gcc_jit_lvalue *inner);
453 gcc_jit_lvalue *get_inner_lvalue () const;
455 lvalue access_field (field field,
456 location loc = location ());
458 rvalue get_address (location loc = location ());
461 class param : public lvalue
463 public:
464 param ();
465 param (gcc_jit_param *inner);
467 gcc_jit_param *get_inner_param () const;
471 /* Overloaded operators, for those who want the most terse API
472 (at the possible risk of being a little too magical).
474 In each case, the first parameter is used to determine which context
475 owns the resulting expression, and, where appropriate, what the
476 latter's type is. */
478 /* Unary operators. */
479 rvalue operator- (rvalue a); // unary minus
480 rvalue operator~ (rvalue a); // unary bitwise negate
481 rvalue operator! (rvalue a); // unary logical negate
483 /* Binary operators. */
484 rvalue operator+ (rvalue a, rvalue b);
485 rvalue operator- (rvalue a, rvalue b);
486 rvalue operator* (rvalue a, rvalue b);
487 rvalue operator/ (rvalue a, rvalue b);
488 rvalue operator% (rvalue a, rvalue b);
489 rvalue operator& (rvalue a, rvalue b); // bitwise and
490 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
491 rvalue operator| (rvalue a, rvalue b); // bitwise_or
492 rvalue operator&& (rvalue a, rvalue b); // logical_and
493 rvalue operator|| (rvalue a, rvalue b); // logical_or
495 /* Comparisons. */
496 rvalue operator== (rvalue a, rvalue b);
497 rvalue operator!= (rvalue a, rvalue b);
498 rvalue operator< (rvalue a, rvalue b);
499 rvalue operator<= (rvalue a, rvalue b);
500 rvalue operator> (rvalue a, rvalue b);
501 rvalue operator>= (rvalue a, rvalue b);
503 /* Dereferencing. */
504 lvalue operator* (rvalue ptr);
507 /****************************************************************************
508 Implementation of the API
509 ****************************************************************************/
510 namespace gccjit {
512 // class context
513 inline context context::acquire ()
515 return context (gcc_jit_context_acquire ());
517 inline context::context () : m_inner_ctxt (NULL) {}
518 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
520 if (!inner)
521 throw error ();
524 inline gccjit::context
525 context::new_child_context ()
527 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
530 inline void
531 context::release ()
533 gcc_jit_context_release (m_inner_ctxt);
534 m_inner_ctxt = NULL;
537 inline gcc_jit_result *
538 context::compile ()
540 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
541 if (!result)
542 throw error ();
543 return result;
546 inline void
547 context::compile_to_file (enum gcc_jit_output_kind output_kind,
548 const char *output_path)
550 gcc_jit_context_compile_to_file (m_inner_ctxt,
551 output_kind,
552 output_path);
555 inline void
556 context::dump_to_file (const std::string &path,
557 bool update_locations)
559 gcc_jit_context_dump_to_file (m_inner_ctxt,
560 path.c_str (),
561 update_locations);
564 inline void
565 context::set_logfile (FILE *logfile,
566 int flags,
567 int verbosity)
569 gcc_jit_context_set_logfile (m_inner_ctxt,
570 logfile,
571 flags,
572 verbosity);
575 inline void
576 context::dump_reproducer_to_file (const char *path)
578 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
579 path);
582 inline void
583 context::set_str_option (enum gcc_jit_str_option opt,
584 const char *value)
586 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
590 inline void
591 context::set_int_option (enum gcc_jit_int_option opt,
592 int value)
594 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
598 inline void
599 context::set_bool_option (enum gcc_jit_bool_option opt,
600 int value)
602 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
606 inline location
607 context::new_location (const std::string &filename,
608 int line,
609 int column)
611 return location (gcc_jit_context_new_location (m_inner_ctxt,
612 filename.c_str (),
613 line,
614 column));
617 inline type
618 context::get_type (enum gcc_jit_types kind)
620 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
623 inline type
624 context::get_int_type (size_t num_bytes, int is_signed)
626 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
627 num_bytes,
628 is_signed));
631 template <typename T>
632 inline type
633 context::get_int_type ()
635 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
638 inline type
639 context::new_array_type (type element_type, int num_elements, location loc)
641 return type (gcc_jit_context_new_array_type (
642 m_inner_ctxt,
643 loc.get_inner_location (),
644 element_type.get_inner_type (),
645 num_elements));
648 inline field
649 context::new_field (type type_, const std::string &name, location loc)
651 return field (gcc_jit_context_new_field (m_inner_ctxt,
652 loc.get_inner_location (),
653 type_.get_inner_type (),
654 name.c_str ()));
657 inline struct_
658 context::new_struct_type (const std::string &name,
659 std::vector<field> &fields,
660 location loc)
662 /* Treat std::vector as an array, relying on it not being resized: */
663 field *as_array_of_wrappers = &fields[0];
665 /* Treat the array as being of the underlying pointers, relying on
666 the wrapper type being such a pointer internally. */
667 gcc_jit_field **as_array_of_ptrs =
668 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
670 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
671 loc.get_inner_location (),
672 name.c_str (),
673 fields.size (),
674 as_array_of_ptrs));
677 inline struct_
678 context::new_opaque_struct_type (const std::string &name,
679 location loc)
681 return struct_ (gcc_jit_context_new_opaque_struct (
682 m_inner_ctxt,
683 loc.get_inner_location (),
684 name.c_str ()));
687 inline param
688 context::new_param (type type_,
689 const std::string &name,
690 location loc)
692 return param (gcc_jit_context_new_param (m_inner_ctxt,
693 loc.get_inner_location (),
694 type_.get_inner_type (),
695 name.c_str ()));
698 inline function
699 context::new_function (enum gcc_jit_function_kind kind,
700 type return_type,
701 const std::string &name,
702 std::vector<param> &params,
703 int is_variadic,
704 location loc)
706 /* Treat std::vector as an array, relying on it not being resized: */
707 param *as_array_of_wrappers = &params[0];
709 /* Treat the array as being of the underlying pointers, relying on
710 the wrapper type being such a pointer internally. */
711 gcc_jit_param **as_array_of_ptrs =
712 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
714 return function (gcc_jit_context_new_function (m_inner_ctxt,
715 loc.get_inner_location (),
716 kind,
717 return_type.get_inner_type (),
718 name.c_str (),
719 params.size (),
720 as_array_of_ptrs,
721 is_variadic));
724 inline function
725 context::get_builtin_function (const std::string &name)
727 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
728 name.c_str ()));
731 inline lvalue
732 context::new_global (enum gcc_jit_global_kind kind,
733 type type_,
734 const std::string &name,
735 location loc)
737 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
738 loc.get_inner_location (),
739 kind,
740 type_.get_inner_type (),
741 name.c_str ()));
744 inline rvalue
745 context::new_rvalue (type numeric_type,
746 int value) const
748 return rvalue (
749 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
750 numeric_type.get_inner_type (),
751 value));
754 inline rvalue
755 context::new_rvalue (type numeric_type,
756 long value) const
758 return rvalue (
759 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
760 numeric_type.get_inner_type (),
761 value));
764 inline rvalue
765 context::zero (type numeric_type) const
767 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
768 numeric_type.get_inner_type ()));
771 inline rvalue
772 context::one (type numeric_type) const
774 return rvalue (gcc_jit_context_one (m_inner_ctxt,
775 numeric_type.get_inner_type ()));
778 inline rvalue
779 context::new_rvalue (type numeric_type,
780 double value) const
782 return rvalue (
783 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
784 numeric_type.get_inner_type (),
785 value));
788 inline rvalue
789 context::new_rvalue (type pointer_type,
790 void *value) const
792 return rvalue (
793 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
794 pointer_type.get_inner_type (),
795 value));
798 inline rvalue
799 context::new_rvalue (const std::string &value) const
801 return rvalue (
802 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
805 inline rvalue
806 context::new_unary_op (enum gcc_jit_unary_op op,
807 type result_type,
808 rvalue a,
809 location loc)
811 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
812 loc.get_inner_location (),
814 result_type.get_inner_type (),
815 a.get_inner_rvalue ()));
817 inline rvalue
818 context::new_minus (type result_type,
819 rvalue a,
820 location loc)
822 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
823 result_type, a, loc));
825 inline rvalue
826 context::new_bitwise_negate (type result_type,
827 rvalue a,
828 location loc)
830 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
831 result_type, a, loc));
833 inline rvalue
834 context::new_logical_negate (type result_type,
835 rvalue a,
836 location loc)
838 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
839 result_type, a, loc));
842 inline rvalue
843 context::new_binary_op (enum gcc_jit_binary_op op,
844 type result_type,
845 rvalue a, rvalue b,
846 location loc)
848 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
849 loc.get_inner_location (),
851 result_type.get_inner_type (),
852 a.get_inner_rvalue (),
853 b.get_inner_rvalue ()));
855 inline rvalue
856 context::new_plus (type result_type,
857 rvalue a, rvalue b,
858 location loc)
860 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
861 result_type, a, b, loc);
863 inline rvalue
864 context::new_minus (type result_type,
865 rvalue a, rvalue b,
866 location loc)
868 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
869 result_type, a, b, loc);
871 inline rvalue
872 context::new_mult (type result_type,
873 rvalue a, rvalue b,
874 location loc)
876 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
877 result_type, a, b, loc);
879 inline rvalue
880 context::new_divide (type result_type,
881 rvalue a, rvalue b,
882 location loc)
884 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
885 result_type, a, b, loc);
887 inline rvalue
888 context::new_modulo (type result_type,
889 rvalue a, rvalue b,
890 location loc)
892 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
893 result_type, a, b, loc);
895 inline rvalue
896 context::new_bitwise_and (type result_type,
897 rvalue a, rvalue b,
898 location loc)
900 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
901 result_type, a, b, loc);
903 inline rvalue
904 context::new_bitwise_xor (type result_type,
905 rvalue a, rvalue b,
906 location loc)
908 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
909 result_type, a, b, loc);
911 inline rvalue
912 context::new_bitwise_or (type result_type,
913 rvalue a, rvalue b,
914 location loc)
916 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
917 result_type, a, b, loc);
919 inline rvalue
920 context::new_logical_and (type result_type,
921 rvalue a, rvalue b,
922 location loc)
924 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
925 result_type, a, b, loc);
927 inline rvalue
928 context::new_logical_or (type result_type,
929 rvalue a, rvalue b,
930 location loc)
932 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
933 result_type, a, b, loc);
936 inline rvalue
937 context::new_comparison (enum gcc_jit_comparison op,
938 rvalue a, rvalue b,
939 location loc)
941 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
942 loc.get_inner_location (),
944 a.get_inner_rvalue (),
945 b.get_inner_rvalue ()));
947 inline rvalue
948 context::new_eq (rvalue a, rvalue b,
949 location loc)
951 return new_comparison (GCC_JIT_COMPARISON_EQ,
952 a, b, loc);
954 inline rvalue
955 context::new_ne (rvalue a, rvalue b,
956 location loc)
958 return new_comparison (GCC_JIT_COMPARISON_NE,
959 a, b, loc);
961 inline rvalue
962 context::new_lt (rvalue a, rvalue b,
963 location loc)
965 return new_comparison (GCC_JIT_COMPARISON_LT,
966 a, b, loc);
968 inline rvalue
969 context::new_le (rvalue a, rvalue b,
970 location loc)
972 return new_comparison (GCC_JIT_COMPARISON_LE,
973 a, b, loc);
975 inline rvalue
976 context::new_gt (rvalue a, rvalue b,
977 location loc)
979 return new_comparison (GCC_JIT_COMPARISON_GT,
980 a, b, loc);
982 inline rvalue
983 context::new_ge (rvalue a, rvalue b,
984 location loc)
986 return new_comparison (GCC_JIT_COMPARISON_GE,
987 a, b, loc);
990 inline rvalue
991 context::new_call (function func,
992 std::vector<rvalue> &args,
993 location loc)
995 /* Treat std::vector as an array, relying on it not being resized: */
996 rvalue *as_array_of_wrappers = &args[0];
998 /* Treat the array as being of the underlying pointers, relying on
999 the wrapper type being such a pointer internally. */
1000 gcc_jit_rvalue **as_array_of_ptrs =
1001 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
1002 return gcc_jit_context_new_call (m_inner_ctxt,
1003 loc.get_inner_location (),
1004 func.get_inner_function (),
1005 args.size (),
1006 as_array_of_ptrs);
1008 inline rvalue
1009 context::new_call (function func,
1010 location loc)
1012 std::vector<rvalue> args;
1013 return new_call (func, args, loc);
1016 inline rvalue
1017 context::new_call (function func,
1018 rvalue arg0,
1019 location loc)
1021 std::vector<rvalue> args(1);
1022 args[0] = arg0;
1023 return new_call (func, args, loc);
1025 inline rvalue
1026 context::new_call (function func,
1027 rvalue arg0, rvalue arg1,
1028 location loc)
1030 std::vector<rvalue> args(2);
1031 args[0] = arg0;
1032 args[1] = arg1;
1033 return new_call (func, args, loc);
1035 inline rvalue
1036 context::new_call (function func,
1037 rvalue arg0, rvalue arg1, rvalue arg2,
1038 location loc)
1040 std::vector<rvalue> args(3);
1041 args[0] = arg0;
1042 args[1] = arg1;
1043 args[2] = arg2;
1044 return new_call (func, args, loc);
1046 inline rvalue
1047 context::new_call (function func,
1048 rvalue arg0, rvalue arg1, rvalue arg2,
1049 rvalue arg3,
1050 location loc)
1052 std::vector<rvalue> args(4);
1053 args[0] = arg0;
1054 args[1] = arg1;
1055 args[2] = arg2;
1056 args[3] = arg3;
1057 return new_call (func, args, loc);
1059 inline rvalue
1060 context::new_call (function func,
1061 rvalue arg0, rvalue arg1, rvalue arg2,
1062 rvalue arg3, rvalue arg4,
1063 location loc)
1065 std::vector<rvalue> args(5);
1066 args[0] = arg0;
1067 args[1] = arg1;
1068 args[2] = arg2;
1069 args[3] = arg3;
1070 args[4] = arg4;
1071 return new_call (func, args, loc);
1073 inline rvalue
1074 context::new_call (function func,
1075 rvalue arg0, rvalue arg1, rvalue arg2,
1076 rvalue arg3, rvalue arg4, rvalue arg5,
1077 location loc)
1079 std::vector<rvalue> args(6);
1080 args[0] = arg0;
1081 args[1] = arg1;
1082 args[2] = arg2;
1083 args[3] = arg3;
1084 args[4] = arg4;
1085 args[5] = arg5;
1086 return new_call (func, args, loc);
1089 inline rvalue
1090 context::new_cast (rvalue expr,
1091 type type_,
1092 location loc)
1094 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1095 loc.get_inner_location (),
1096 expr.get_inner_rvalue (),
1097 type_.get_inner_type ()));
1100 inline lvalue
1101 context::new_array_access (rvalue ptr,
1102 rvalue index,
1103 location loc)
1105 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1106 loc.get_inner_location (),
1107 ptr.get_inner_rvalue (),
1108 index.get_inner_rvalue ()));
1111 // class object
1112 inline context
1113 object::get_context () const
1115 return context (gcc_jit_object_get_context (m_inner_obj));
1118 inline std::string
1119 object::get_debug_string () const
1121 return gcc_jit_object_get_debug_string (m_inner_obj);
1124 inline object::object () : m_inner_obj (NULL) {}
1125 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1127 if (!obj)
1128 throw error ();
1131 inline gcc_jit_object *
1132 object::get_inner_object () const
1134 return m_inner_obj;
1137 inline std::ostream&
1138 operator << (std::ostream& stream, const object &obj)
1140 return stream << obj.get_debug_string ();
1143 // class location
1144 inline location::location () : object () {}
1145 inline location::location (gcc_jit_location *loc)
1146 : object (gcc_jit_location_as_object (loc))
1149 inline gcc_jit_location *
1150 location::get_inner_location () const
1152 /* Manual downcast: */
1153 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1156 // class field
1157 inline field::field () : object () {}
1158 inline field::field (gcc_jit_field *inner)
1159 : object (gcc_jit_field_as_object (inner))
1162 inline gcc_jit_field *
1163 field::get_inner_field () const
1165 /* Manual downcast: */
1166 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1169 // class type
1170 inline type::type () : object () {}
1171 inline type::type (gcc_jit_type *inner)
1172 : object (gcc_jit_type_as_object (inner))
1175 inline gcc_jit_type *
1176 type::get_inner_type () const
1178 /* Manual downcast: */
1179 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1182 inline type
1183 type::get_pointer ()
1185 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1188 inline type
1189 type::get_volatile ()
1191 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1194 inline rvalue
1195 type::zero ()
1197 return get_context ().new_rvalue (*this, 0);
1200 inline rvalue
1201 type::one ()
1203 return get_context ().new_rvalue (*this, 1);
1206 // class struct_
1207 inline struct_::struct_ () : type (NULL) {}
1208 inline struct_::struct_ (gcc_jit_struct *inner) :
1209 type (gcc_jit_struct_as_type (inner))
1213 inline gcc_jit_struct *
1214 struct_::get_inner_struct () const
1216 /* Manual downcast: */
1217 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1220 // class function
1221 inline function::function () : object () {}
1222 inline function::function (gcc_jit_function *inner)
1223 : object (gcc_jit_function_as_object (inner))
1226 inline gcc_jit_function *
1227 function::get_inner_function () const
1229 /* Manual downcast: */
1230 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1233 inline void
1234 function::dump_to_dot (const std::string &path)
1236 gcc_jit_function_dump_to_dot (get_inner_function (),
1237 path.c_str ());
1240 inline param
1241 function::get_param (int index) const
1243 return param (gcc_jit_function_get_param (get_inner_function (),
1244 index));
1247 inline block
1248 function::new_block ()
1250 return block (gcc_jit_function_new_block (get_inner_function (),
1251 NULL));
1254 inline block
1255 function::new_block (const std::string &name)
1257 return block (gcc_jit_function_new_block (get_inner_function (),
1258 name.c_str ()));
1261 inline lvalue
1262 function::new_local (type type_,
1263 const std::string &name,
1264 location loc)
1266 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1267 loc.get_inner_location (),
1268 type_.get_inner_type (),
1269 name.c_str ()));
1272 inline function
1273 block::get_function () const
1275 return function (gcc_jit_block_get_function ( get_inner_block ()));
1278 inline void
1279 block::add_eval (rvalue rvalue,
1280 location loc)
1282 gcc_jit_block_add_eval (get_inner_block (),
1283 loc.get_inner_location (),
1284 rvalue.get_inner_rvalue ());
1287 inline void
1288 block::add_assignment (lvalue lvalue,
1289 rvalue rvalue,
1290 location loc)
1292 gcc_jit_block_add_assignment (get_inner_block (),
1293 loc.get_inner_location (),
1294 lvalue.get_inner_lvalue (),
1295 rvalue.get_inner_rvalue ());
1298 inline void
1299 block::add_assignment_op (lvalue lvalue,
1300 enum gcc_jit_binary_op op,
1301 rvalue rvalue,
1302 location loc)
1304 gcc_jit_block_add_assignment_op (get_inner_block (),
1305 loc.get_inner_location (),
1306 lvalue.get_inner_lvalue (),
1308 rvalue.get_inner_rvalue ());
1311 inline void
1312 block::add_comment (const std::string &text,
1313 location loc)
1315 gcc_jit_block_add_comment (get_inner_block (),
1316 loc.get_inner_location (),
1317 text.c_str ());
1320 inline void
1321 block::end_with_conditional (rvalue boolval,
1322 block on_true,
1323 block on_false,
1324 location loc)
1326 gcc_jit_block_end_with_conditional (get_inner_block (),
1327 loc.get_inner_location (),
1328 boolval.get_inner_rvalue (),
1329 on_true.get_inner_block (),
1330 on_false.get_inner_block ());
1333 inline void
1334 block::end_with_jump (block target,
1335 location loc)
1337 gcc_jit_block_end_with_jump (get_inner_block (),
1338 loc.get_inner_location (),
1339 target.get_inner_block ());
1342 inline void
1343 block::end_with_return (rvalue rvalue,
1344 location loc)
1346 gcc_jit_block_end_with_return (get_inner_block (),
1347 loc.get_inner_location (),
1348 rvalue.get_inner_rvalue ());
1351 inline void
1352 block::end_with_return (location loc)
1354 gcc_jit_block_end_with_void_return (get_inner_block (),
1355 loc.get_inner_location ());
1358 inline rvalue
1359 block::add_call (function other,
1360 location loc)
1362 rvalue c = get_context ().new_call (other, loc);
1363 add_eval (c);
1364 return c;
1366 inline rvalue
1367 block::add_call (function other,
1368 rvalue arg0,
1369 location loc)
1371 rvalue c = get_context ().new_call (other, arg0, loc);
1372 add_eval (c);
1373 return c;
1375 inline rvalue
1376 block::add_call (function other,
1377 rvalue arg0, rvalue arg1,
1378 location loc)
1380 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1381 add_eval (c);
1382 return c;
1384 inline rvalue
1385 block::add_call (function other,
1386 rvalue arg0, rvalue arg1, rvalue arg2,
1387 location loc)
1389 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1390 add_eval (c);
1391 return c;
1394 inline rvalue
1395 block::add_call (function other,
1396 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1397 location loc)
1399 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1400 add_eval (c);
1401 return c;
1404 inline rvalue
1405 function::operator() (location loc)
1407 return get_context ().new_call (*this, loc);
1409 inline rvalue
1410 function::operator() (rvalue arg0,
1411 location loc)
1413 return get_context ().new_call (*this,
1414 arg0,
1415 loc);
1417 inline rvalue
1418 function::operator() (rvalue arg0, rvalue arg1,
1419 location loc)
1421 return get_context ().new_call (*this,
1422 arg0, arg1,
1423 loc);
1425 inline rvalue
1426 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1427 location loc)
1429 return get_context ().new_call (*this,
1430 arg0, arg1, arg2,
1431 loc);
1434 // class block
1435 inline block::block () : object () {}
1436 inline block::block (gcc_jit_block *inner)
1437 : object (gcc_jit_block_as_object (inner))
1440 inline gcc_jit_block *
1441 block::get_inner_block () const
1443 /* Manual downcast: */
1444 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1447 // class rvalue
1448 inline rvalue::rvalue () : object () {}
1449 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1450 : object (gcc_jit_rvalue_as_object (inner))
1453 inline gcc_jit_rvalue *
1454 rvalue::get_inner_rvalue () const
1456 /* Manual downcast: */
1457 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1460 inline type
1461 rvalue::get_type ()
1463 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1466 inline rvalue
1467 rvalue::access_field (field field,
1468 location loc)
1470 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1471 loc.get_inner_location (),
1472 field.get_inner_field ()));
1475 inline lvalue
1476 rvalue::dereference_field (field field,
1477 location loc)
1479 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1480 loc.get_inner_location (),
1481 field.get_inner_field ()));
1484 inline lvalue
1485 rvalue::dereference (location loc)
1487 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1488 loc.get_inner_location ()));
1491 inline rvalue
1492 rvalue::cast_to (type type_,
1493 location loc)
1495 return get_context ().new_cast (*this, type_, loc);
1498 inline lvalue
1499 rvalue::operator[] (rvalue index)
1501 return get_context ().new_array_access (*this, index);
1504 inline lvalue
1505 rvalue::operator[] (int index)
1507 context ctxt = get_context ();
1508 type int_t = ctxt.get_int_type <int> ();
1509 return ctxt.new_array_access (*this,
1510 ctxt.new_rvalue (int_t,
1511 index));
1514 // class lvalue : public rvalue
1515 inline lvalue::lvalue () : rvalue () {}
1516 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1517 : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1520 inline gcc_jit_lvalue *
1521 lvalue::get_inner_lvalue () const
1523 /* Manual downcast: */
1524 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1527 inline lvalue
1528 lvalue::access_field (field field, location loc)
1530 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1531 loc.get_inner_location (),
1532 field.get_inner_field ()));
1535 inline rvalue
1536 lvalue::get_address (location loc)
1538 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1539 loc.get_inner_location ()));
1542 // class param : public lvalue
1543 inline param::param () : lvalue () {}
1544 inline param::param (gcc_jit_param *inner)
1545 : lvalue (gcc_jit_param_as_lvalue (inner))
1548 /* Overloaded operators. */
1549 // Unary operators
1550 inline rvalue operator- (rvalue a)
1552 return a.get_context ().new_minus (a.get_type (), a);
1554 inline rvalue operator~ (rvalue a)
1556 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1558 inline rvalue operator! (rvalue a)
1560 return a.get_context ().new_logical_negate (a.get_type (), a);
1563 // Binary operators
1564 inline rvalue operator+ (rvalue a, rvalue b)
1566 return a.get_context ().new_plus (a.get_type (), a, b);
1568 inline rvalue operator- (rvalue a, rvalue b)
1570 return a.get_context ().new_minus (a.get_type (), a, b);
1572 inline rvalue operator* (rvalue a, rvalue b)
1574 return a.get_context ().new_mult (a.get_type (), a, b);
1576 inline rvalue operator/ (rvalue a, rvalue b)
1578 return a.get_context ().new_divide (a.get_type (), a, b);
1580 inline rvalue operator% (rvalue a, rvalue b)
1582 return a.get_context ().new_modulo (a.get_type (), a, b);
1584 inline rvalue operator& (rvalue a, rvalue b)
1586 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1588 inline rvalue operator^ (rvalue a, rvalue b)
1590 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1592 inline rvalue operator| (rvalue a, rvalue b)
1594 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1596 inline rvalue operator&& (rvalue a, rvalue b)
1598 return a.get_context ().new_logical_and (a.get_type (), a, b);
1600 inline rvalue operator|| (rvalue a, rvalue b)
1602 return a.get_context ().new_logical_or (a.get_type (), a, b);
1605 /* Comparisons. */
1606 inline rvalue operator== (rvalue a, rvalue b)
1608 return a.get_context ().new_eq (a, b);
1610 inline rvalue operator!= (rvalue a, rvalue b)
1612 return a.get_context ().new_ne (a, b);
1614 inline rvalue operator< (rvalue a, rvalue b)
1616 return a.get_context ().new_lt (a, b);
1618 inline rvalue operator<= (rvalue a, rvalue b)
1620 return a.get_context ().new_le (a, b);
1622 inline rvalue operator> (rvalue a, rvalue b)
1624 return a.get_context ().new_gt (a, b);
1626 inline rvalue operator>= (rvalue a, rvalue b)
1628 return a.get_context ().new_ge (a, b);
1631 /* Dereferencing. */
1632 inline lvalue operator* (rvalue ptr)
1634 return ptr.dereference ();
1637 } // namespace gccjit
1639 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */