7f6718bf7797d5d44319ab2ef274849130558d48
[gcc.git] / gcc / jit / libgccjit++.h
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
20 #ifndef LIBGCCJIT_PLUS_PLUS_H
21 #define LIBGCCJIT_PLUS_PLUS_H
22
23 #include "libgccjit.h"
24
25 #include <limits>
26 #include <ostream>
27 #include <vector>
28
29 /****************************************************************************
30 C++ API
31 ****************************************************************************/
32
33 namespace gccjit
34 {
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
49 /* Errors within the API become C++ exceptions of this class. */
50 class error
51 {
52 };
53
54 class object
55 {
56 public:
57 context get_context () const;
58
59 std::string get_debug_string () const;
60
61 protected:
62 object ();
63 object (gcc_jit_object *obj);
64
65 gcc_jit_object *get_inner_object () const;
66
67 private:
68 gcc_jit_object *m_inner_obj;
69 };
70
71 inline std::ostream& operator << (std::ostream& stream, const object &obj);
72
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
79 {
80 public:
81 location ();
82 location (gcc_jit_location *loc);
83
84 gcc_jit_location *get_inner_location () const;
85 };
86
87 class context
88 {
89 public:
90 static context acquire ();
91 context ();
92 context (gcc_jit_context *ctxt);
93
94 gccjit::context new_child_context ();
95
96 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
97
98 void release ();
99
100 gcc_jit_result *compile ();
101
102 void dump_to_file (const std::string &path,
103 bool update_locations);
104
105 void set_int_option (enum gcc_jit_int_option opt,
106 int value);
107
108 void set_bool_option (enum gcc_jit_bool_option opt,
109 int value);
110
111 location
112 new_location (const std::string &filename,
113 int line,
114 int column);
115
116 type get_type (enum gcc_jit_types kind);
117 type get_int_type (size_t num_bytes, int is_signed);
118
119 /* A way to map a specific int type, using the compiler to
120 get the details automatically e.g.:
121 gccjit::type type = get_int_type <my_int_type_t> (); */
122 template <typename T>
123 type get_int_type ();
124
125 type new_array_type (type element_type, int num_elements,
126 location loc = location ());
127
128 field new_field (type type_, const std::string &name,
129 location loc = location ());
130
131 struct_ new_struct_type (const std::string &name,
132 std::vector<field> &fields,
133 location loc = location ());
134
135 struct_ new_opaque_struct_type (const std::string &name,
136 location loc = location ());
137
138 param new_param (type type_,
139 const std::string &name,
140 location loc = location ());
141
142 function new_function (enum gcc_jit_function_kind kind,
143 type return_type,
144 const std::string &name,
145 std::vector<param> &params,
146 int is_variadic,
147 location loc = location ());
148
149 function get_builtin_function (const std::string &name);
150
151 lvalue new_global (type type_,
152 const std::string &name,
153 location loc = location ());
154
155 rvalue new_rvalue (type numeric_type,
156 int value) const;
157 rvalue zero (type numeric_type) const;
158 rvalue one (type numeric_type) const;
159 rvalue new_rvalue (type numeric_type,
160 double value) const;
161 rvalue new_rvalue (type pointer_type,
162 void *value) const;
163 rvalue new_rvalue (const std::string &value) const;
164
165 /* Generic unary operations... */
166 rvalue new_unary_op (enum gcc_jit_unary_op op,
167 type result_type,
168 rvalue a,
169 location loc = location ());
170
171 /* ...and shorter ways to spell the various specific kinds of
172 unary op. */
173 rvalue new_minus (type result_type,
174 rvalue a,
175 location loc = location ());
176 rvalue new_bitwise_negate (type result_type,
177 rvalue a,
178 location loc = location ());
179 rvalue new_logical_negate (type result_type,
180 rvalue a,
181 location loc = location ());
182
183 /* Generic binary operations... */
184 rvalue new_binary_op (enum gcc_jit_binary_op op,
185 type result_type,
186 rvalue a, rvalue b,
187 location loc = location ());
188
189 /* ...and shorter ways to spell the various specific kinds of
190 binary op. */
191 rvalue new_plus (type result_type,
192 rvalue a, rvalue b,
193 location loc = location ());
194 rvalue new_minus (type result_type,
195 rvalue a, rvalue b,
196 location loc = location ());
197 rvalue new_mult (type result_type,
198 rvalue a, rvalue b,
199 location loc = location ());
200 rvalue new_divide (type result_type,
201 rvalue a, rvalue b,
202 location loc = location ());
203 rvalue new_modulo (type result_type,
204 rvalue a, rvalue b,
205 location loc = location ());
206 rvalue new_bitwise_and (type result_type,
207 rvalue a, rvalue b,
208 location loc = location ());
209 rvalue new_bitwise_xor (type result_type,
210 rvalue a, rvalue b,
211 location loc = location ());
212 rvalue new_bitwise_or (type result_type,
213 rvalue a, rvalue b,
214 location loc = location ());
215 rvalue new_logical_and (type result_type,
216 rvalue a, rvalue b,
217 location loc = location ());
218 rvalue new_logical_or (type result_type,
219 rvalue a, rvalue b,
220 location loc = location ());
221
222 /* Generic comparisons... */
223 rvalue new_comparison (enum gcc_jit_comparison op,
224 rvalue a, rvalue b,
225 location loc = location ());
226 /* ...and shorter ways to spell the various specific kinds of
227 comparison. */
228 rvalue new_eq (rvalue a, rvalue b,
229 location loc = location ());
230 rvalue new_ne (rvalue a, rvalue b,
231 location loc = location ());
232 rvalue new_lt (rvalue a, rvalue b,
233 location loc = location ());
234 rvalue new_le (rvalue a, rvalue b,
235 location loc = location ());
236 rvalue new_gt (rvalue a, rvalue b,
237 location loc = location ());
238 rvalue new_ge (rvalue a, rvalue b,
239 location loc = location ());
240
241 /* The most general way of creating a function call. */
242 rvalue new_call (function func,
243 std::vector<rvalue> &args,
244 location loc = location ());
245
246 /* In addition, we provide a series of overloaded "new_call" methods
247 for specific numbers of args (from 0 - 6), to avoid the need for
248 client code to manually build a vector. */
249 rvalue new_call (function func,
250 location loc = location ());
251 rvalue new_call (function func,
252 rvalue arg0,
253 location loc = location ());
254 rvalue new_call (function func,
255 rvalue arg0, rvalue arg1,
256 location loc = location ());
257 rvalue new_call (function func,
258 rvalue arg0, rvalue arg1, rvalue arg2,
259 location loc = location ());
260 rvalue new_call (function func,
261 rvalue arg0, rvalue arg1, rvalue arg2,
262 rvalue arg3,
263 location loc = location ());
264 rvalue new_call (function func,
265 rvalue arg0, rvalue arg1, rvalue arg2,
266 rvalue arg3, rvalue arg4,
267 location loc = location ());
268 rvalue new_call (function func,
269 rvalue arg0, rvalue arg1, rvalue arg2,
270 rvalue arg3, rvalue arg4, rvalue arg5,
271 location loc = location ());
272
273 rvalue new_cast (rvalue expr,
274 type type_,
275 location loc = location ());
276
277 lvalue new_array_access (rvalue ptr,
278 rvalue index,
279 location loc = location ());
280
281 private:
282 gcc_jit_context *m_inner_ctxt;
283 };
284
285 class field : public object
286 {
287 public:
288 field ();
289 field (gcc_jit_field *inner);
290
291 gcc_jit_field *get_inner_field () const;
292 };
293
294 class type : public object
295 {
296 public:
297 type ();
298 type (gcc_jit_type *inner);
299
300 gcc_jit_type *get_inner_type () const;
301
302 type get_pointer ();
303 type get_volatile ();
304
305 // Shortcuts for getting values of numeric types:
306 rvalue zero ();
307 rvalue one ();
308 };
309
310 class struct_ : public type
311 {
312 public:
313 struct_ ();
314 struct_ (gcc_jit_struct *inner);
315
316 gcc_jit_struct *get_inner_struct () const;
317 };
318
319 class function : public object
320 {
321 public:
322 function ();
323 function (gcc_jit_function *func);
324
325 gcc_jit_function *get_inner_function () const;
326
327 void dump_to_dot (const std::string &path);
328
329 param get_param (int index) const;
330
331 block new_block ();
332 block new_block (const std::string &name);
333
334 lvalue new_local (type type_,
335 const std::string &name,
336 location loc = location ());
337
338 /* A series of overloaded operator () with various numbers of arguments
339 for a very terse way of creating a call to this function. The call
340 is created within the same context as the function itself, which may
341 not be what you want. */
342 rvalue operator() (location loc = location ());
343 rvalue operator() (rvalue arg0,
344 location loc = location ());
345 rvalue operator() (rvalue arg0, rvalue arg1,
346 location loc = location ());
347 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
348 location loc = location ());
349 };
350
351 class block : public object
352 {
353 public:
354 block ();
355 block (gcc_jit_block *inner);
356
357 gcc_jit_block *get_inner_block () const;
358
359 function get_function () const;
360
361 void add_eval (rvalue rvalue,
362 location loc = location ());
363
364 void add_assignment (lvalue lvalue,
365 rvalue rvalue,
366 location loc = location ());
367
368 void add_assignment_op (lvalue lvalue,
369 enum gcc_jit_binary_op op,
370 rvalue rvalue,
371 location loc = location ());
372
373 /* A way to add a function call to the body of a function being
374 defined, with various numbers of args. */
375 rvalue add_call (function other,
376 location loc = location ());
377 rvalue add_call (function other,
378 rvalue arg0,
379 location loc = location ());
380 rvalue add_call (function other,
381 rvalue arg0, rvalue arg1,
382 location loc = location ());
383 rvalue add_call (function other,
384 rvalue arg0, rvalue arg1, rvalue arg2,
385 location loc = location ());
386 rvalue add_call (function other,
387 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
388 location loc = location ());
389
390 void add_comment (const std::string &text,
391 location loc = location ());
392
393 void end_with_conditional (rvalue boolval,
394 block on_true,
395 block on_false,
396 location loc = location ());
397
398 void end_with_jump (block target,
399 location loc = location ());
400
401 void end_with_return (rvalue rvalue,
402 location loc = location ());
403 void end_with_return (location loc = location ());
404
405 };
406
407 class rvalue : public object
408 {
409 public:
410 rvalue ();
411 rvalue (gcc_jit_rvalue *inner);
412 gcc_jit_rvalue *get_inner_rvalue () const;
413
414 type get_type ();
415
416 rvalue access_field (field field,
417 location loc = location ());
418
419 lvalue dereference_field (field field,
420 location loc = location ());
421
422 lvalue dereference (location loc = location ());
423
424 rvalue cast_to (type type_,
425 location loc = location ());
426
427 /* Array access. */
428 lvalue operator[] (rvalue index);
429 lvalue operator[] (int index);
430 };
431
432 class lvalue : public rvalue
433 {
434 public:
435 lvalue ();
436 lvalue (gcc_jit_lvalue *inner);
437
438 gcc_jit_lvalue *get_inner_lvalue () const;
439
440 lvalue access_field (field field,
441 location loc = location ());
442
443 rvalue get_address (location loc = location ());
444 };
445
446 class param : public lvalue
447 {
448 public:
449 param ();
450 param (gcc_jit_param *inner);
451
452 gcc_jit_param *get_inner_param () const;
453 };
454
455
456 /* Overloaded operators, for those who want the most terse API
457 (at the possible risk of being a little too magical).
458
459 In each case, the first parameter is used to determine which context
460 owns the resulting expression, and, where appropriate, what the
461 latter's type is. */
462
463 /* Unary operators. */
464 rvalue operator- (rvalue a); // unary minus
465 rvalue operator~ (rvalue a); // unary bitwise negate
466 rvalue operator! (rvalue a); // unary logical negate
467
468 /* Binary operators. */
469 rvalue operator+ (rvalue a, rvalue b);
470 rvalue operator- (rvalue a, rvalue b);
471 rvalue operator* (rvalue a, rvalue b);
472 rvalue operator/ (rvalue a, rvalue b);
473 rvalue operator% (rvalue a, rvalue b);
474 rvalue operator& (rvalue a, rvalue b); // bitwise and
475 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
476 rvalue operator| (rvalue a, rvalue b); // bitwise_or
477 rvalue operator&& (rvalue a, rvalue b); // logical_and
478 rvalue operator|| (rvalue a, rvalue b); // logical_or
479
480 /* Comparisons. */
481 rvalue operator== (rvalue a, rvalue b);
482 rvalue operator!= (rvalue a, rvalue b);
483 rvalue operator< (rvalue a, rvalue b);
484 rvalue operator<= (rvalue a, rvalue b);
485 rvalue operator> (rvalue a, rvalue b);
486 rvalue operator>= (rvalue a, rvalue b);
487
488 /* Dereferencing. */
489 lvalue operator* (rvalue ptr);
490 }
491
492 /****************************************************************************
493 Implementation of the API
494 ****************************************************************************/
495 namespace gccjit {
496
497 // class context
498 inline context context::acquire ()
499 {
500 return context (gcc_jit_context_acquire ());
501 }
502 inline context::context () : m_inner_ctxt (NULL) {}
503 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
504 {
505 if (!inner)
506 throw error ();
507 }
508
509 inline gccjit::context
510 context::new_child_context ()
511 {
512 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
513 }
514
515 inline void
516 context::release ()
517 {
518 gcc_jit_context_release (m_inner_ctxt);
519 m_inner_ctxt = NULL;
520 }
521
522 inline gcc_jit_result *
523 context::compile ()
524 {
525 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
526 if (!result)
527 throw error ();
528 return result;
529 }
530
531 inline void
532 context::dump_to_file (const std::string &path,
533 bool update_locations)
534 {
535 gcc_jit_context_dump_to_file (m_inner_ctxt,
536 path.c_str (),
537 update_locations);
538 }
539
540 inline void
541 context::set_int_option (enum gcc_jit_int_option opt,
542 int value)
543 {
544 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
545
546 }
547
548 inline void
549 context::set_bool_option (enum gcc_jit_bool_option opt,
550 int value)
551 {
552 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
553
554 }
555
556 inline location
557 context::new_location (const std::string &filename,
558 int line,
559 int column)
560 {
561 return location (gcc_jit_context_new_location (m_inner_ctxt,
562 filename.c_str (),
563 line,
564 column));
565 }
566
567 inline type
568 context::get_type (enum gcc_jit_types kind)
569 {
570 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
571 }
572
573 inline type
574 context::get_int_type (size_t num_bytes, int is_signed)
575 {
576 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
577 num_bytes,
578 is_signed));
579 }
580
581 template <typename T>
582 inline type
583 context::get_int_type ()
584 {
585 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
586 }
587
588 inline type
589 context::new_array_type (type element_type, int num_elements, location loc)
590 {
591 return type (gcc_jit_context_new_array_type (
592 m_inner_ctxt,
593 loc.get_inner_location (),
594 element_type.get_inner_type (),
595 num_elements));
596 }
597
598 inline field
599 context::new_field (type type_, const std::string &name, location loc)
600 {
601 return field (gcc_jit_context_new_field (m_inner_ctxt,
602 loc.get_inner_location (),
603 type_.get_inner_type (),
604 name.c_str ()));
605 }
606
607 inline struct_
608 context::new_struct_type (const std::string &name,
609 std::vector<field> &fields,
610 location loc)
611 {
612 /* Treat std::vector as an array, relying on it not being resized: */
613 field *as_array_of_wrappers = &fields[0];
614
615 /* Treat the array as being of the underlying pointers, relying on
616 the wrapper type being such a pointer internally. */
617 gcc_jit_field **as_array_of_ptrs =
618 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
619
620 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
621 loc.get_inner_location (),
622 name.c_str (),
623 fields.size (),
624 as_array_of_ptrs));
625 }
626
627 inline struct_
628 context::new_opaque_struct_type (const std::string &name,
629 location loc)
630 {
631 return struct_ (gcc_jit_context_new_opaque_struct (
632 m_inner_ctxt,
633 loc.get_inner_location (),
634 name.c_str ()));
635 }
636
637 inline param
638 context::new_param (type type_,
639 const std::string &name,
640 location loc)
641 {
642 return param (gcc_jit_context_new_param (m_inner_ctxt,
643 loc.get_inner_location (),
644 type_.get_inner_type (),
645 name.c_str ()));
646 }
647
648 inline function
649 context::new_function (enum gcc_jit_function_kind kind,
650 type return_type,
651 const std::string &name,
652 std::vector<param> &params,
653 int is_variadic,
654 location loc)
655 {
656 /* Treat std::vector as an array, relying on it not being resized: */
657 param *as_array_of_wrappers = &params[0];
658
659 /* Treat the array as being of the underlying pointers, relying on
660 the wrapper type being such a pointer internally. */
661 gcc_jit_param **as_array_of_ptrs =
662 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
663
664 return function (gcc_jit_context_new_function (m_inner_ctxt,
665 loc.get_inner_location (),
666 kind,
667 return_type.get_inner_type (),
668 name.c_str (),
669 params.size (),
670 as_array_of_ptrs,
671 is_variadic));
672 }
673
674 inline function
675 context::get_builtin_function (const std::string &name)
676 {
677 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
678 name.c_str ()));
679 }
680
681 inline lvalue
682 context::new_global (type type_,
683 const std::string &name,
684 location loc)
685 {
686 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
687 loc.get_inner_location (),
688 type_.get_inner_type (),
689 name.c_str ()));
690 }
691
692 inline rvalue
693 context::new_rvalue (type numeric_type,
694 int value) const
695 {
696 return rvalue (
697 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
698 numeric_type.get_inner_type (),
699 value));
700 }
701
702 inline rvalue
703 context::zero (type numeric_type) const
704 {
705 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
706 numeric_type.get_inner_type ()));
707 }
708
709 inline rvalue
710 context::one (type numeric_type) const
711 {
712 return rvalue (gcc_jit_context_one (m_inner_ctxt,
713 numeric_type.get_inner_type ()));
714 }
715
716 inline rvalue
717 context::new_rvalue (type numeric_type,
718 double value) const
719 {
720 return rvalue (
721 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
722 numeric_type.get_inner_type (),
723 value));
724 }
725
726 inline rvalue
727 context::new_rvalue (type pointer_type,
728 void *value) const
729 {
730 return rvalue (
731 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
732 pointer_type.get_inner_type (),
733 value));
734 }
735
736 inline rvalue
737 context::new_rvalue (const std::string &value) const
738 {
739 return rvalue (
740 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
741 }
742
743 inline rvalue
744 context::new_unary_op (enum gcc_jit_unary_op op,
745 type result_type,
746 rvalue a,
747 location loc)
748 {
749 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
750 loc.get_inner_location (),
751 op,
752 result_type.get_inner_type (),
753 a.get_inner_rvalue ()));
754 }
755 inline rvalue
756 context::new_minus (type result_type,
757 rvalue a,
758 location loc)
759 {
760 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
761 result_type, a, loc));
762 }
763 inline rvalue
764 context::new_bitwise_negate (type result_type,
765 rvalue a,
766 location loc)
767 {
768 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
769 result_type, a, loc));
770 }
771 inline rvalue
772 context::new_logical_negate (type result_type,
773 rvalue a,
774 location loc)
775 {
776 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
777 result_type, a, loc));
778 }
779
780 inline rvalue
781 context::new_binary_op (enum gcc_jit_binary_op op,
782 type result_type,
783 rvalue a, rvalue b,
784 location loc)
785 {
786 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
787 loc.get_inner_location (),
788 op,
789 result_type.get_inner_type (),
790 a.get_inner_rvalue (),
791 b.get_inner_rvalue ()));
792 }
793 inline rvalue
794 context::new_plus (type result_type,
795 rvalue a, rvalue b,
796 location loc)
797 {
798 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
799 result_type, a, b, loc);
800 }
801 inline rvalue
802 context::new_minus (type result_type,
803 rvalue a, rvalue b,
804 location loc)
805 {
806 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
807 result_type, a, b, loc);
808 }
809 inline rvalue
810 context::new_mult (type result_type,
811 rvalue a, rvalue b,
812 location loc)
813 {
814 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
815 result_type, a, b, loc);
816 }
817 inline rvalue
818 context::new_divide (type result_type,
819 rvalue a, rvalue b,
820 location loc)
821 {
822 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
823 result_type, a, b, loc);
824 }
825 inline rvalue
826 context::new_modulo (type result_type,
827 rvalue a, rvalue b,
828 location loc)
829 {
830 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
831 result_type, a, b, loc);
832 }
833 inline rvalue
834 context::new_bitwise_and (type result_type,
835 rvalue a, rvalue b,
836 location loc)
837 {
838 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
839 result_type, a, b, loc);
840 }
841 inline rvalue
842 context::new_bitwise_xor (type result_type,
843 rvalue a, rvalue b,
844 location loc)
845 {
846 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
847 result_type, a, b, loc);
848 }
849 inline rvalue
850 context::new_bitwise_or (type result_type,
851 rvalue a, rvalue b,
852 location loc)
853 {
854 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
855 result_type, a, b, loc);
856 }
857 inline rvalue
858 context::new_logical_and (type result_type,
859 rvalue a, rvalue b,
860 location loc)
861 {
862 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
863 result_type, a, b, loc);
864 }
865 inline rvalue
866 context::new_logical_or (type result_type,
867 rvalue a, rvalue b,
868 location loc)
869 {
870 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
871 result_type, a, b, loc);
872 }
873
874 inline rvalue
875 context::new_comparison (enum gcc_jit_comparison op,
876 rvalue a, rvalue b,
877 location loc)
878 {
879 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
880 loc.get_inner_location (),
881 op,
882 a.get_inner_rvalue (),
883 b.get_inner_rvalue ()));
884 }
885 inline rvalue
886 context::new_eq (rvalue a, rvalue b,
887 location loc)
888 {
889 return new_comparison (GCC_JIT_COMPARISON_EQ,
890 a, b, loc);
891 }
892 inline rvalue
893 context::new_ne (rvalue a, rvalue b,
894 location loc)
895 {
896 return new_comparison (GCC_JIT_COMPARISON_NE,
897 a, b, loc);
898 }
899 inline rvalue
900 context::new_lt (rvalue a, rvalue b,
901 location loc)
902 {
903 return new_comparison (GCC_JIT_COMPARISON_LT,
904 a, b, loc);
905 }
906 inline rvalue
907 context::new_le (rvalue a, rvalue b,
908 location loc)
909 {
910 return new_comparison (GCC_JIT_COMPARISON_LE,
911 a, b, loc);
912 }
913 inline rvalue
914 context::new_gt (rvalue a, rvalue b,
915 location loc)
916 {
917 return new_comparison (GCC_JIT_COMPARISON_GT,
918 a, b, loc);
919 }
920 inline rvalue
921 context::new_ge (rvalue a, rvalue b,
922 location loc)
923 {
924 return new_comparison (GCC_JIT_COMPARISON_GE,
925 a, b, loc);
926 }
927
928 inline rvalue
929 context::new_call (function func,
930 std::vector<rvalue> &args,
931 location loc)
932 {
933 /* Treat std::vector as an array, relying on it not being resized: */
934 rvalue *as_array_of_wrappers = &args[0];
935
936 /* Treat the array as being of the underlying pointers, relying on
937 the wrapper type being such a pointer internally. */
938 gcc_jit_rvalue **as_array_of_ptrs =
939 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
940 return gcc_jit_context_new_call (m_inner_ctxt,
941 loc.get_inner_location (),
942 func.get_inner_function (),
943 args.size (),
944 as_array_of_ptrs);
945 }
946 inline rvalue
947 context::new_call (function func,
948 location loc)
949 {
950 std::vector<rvalue> args;
951 return new_call (func, args, loc);
952 }
953
954 inline rvalue
955 context::new_call (function func,
956 rvalue arg0,
957 location loc)
958 {
959 std::vector<rvalue> args(1);
960 args[0] = arg0;
961 return new_call (func, args, loc);
962 }
963 inline rvalue
964 context::new_call (function func,
965 rvalue arg0, rvalue arg1,
966 location loc)
967 {
968 std::vector<rvalue> args(2);
969 args[0] = arg0;
970 args[1] = arg1;
971 return new_call (func, args, loc);
972 }
973 inline rvalue
974 context::new_call (function func,
975 rvalue arg0, rvalue arg1, rvalue arg2,
976 location loc)
977 {
978 std::vector<rvalue> args(3);
979 args[0] = arg0;
980 args[1] = arg1;
981 args[2] = arg2;
982 return new_call (func, args, loc);
983 }
984 inline rvalue
985 context::new_call (function func,
986 rvalue arg0, rvalue arg1, rvalue arg2,
987 rvalue arg3,
988 location loc)
989 {
990 std::vector<rvalue> args(4);
991 args[0] = arg0;
992 args[1] = arg1;
993 args[2] = arg2;
994 args[3] = arg3;
995 return new_call (func, args, loc);
996 }
997 inline rvalue
998 context::new_call (function func,
999 rvalue arg0, rvalue arg1, rvalue arg2,
1000 rvalue arg3, rvalue arg4,
1001 location loc)
1002 {
1003 std::vector<rvalue> args(5);
1004 args[0] = arg0;
1005 args[1] = arg1;
1006 args[2] = arg2;
1007 args[3] = arg3;
1008 args[4] = arg4;
1009 return new_call (func, args, loc);
1010 }
1011 inline rvalue
1012 context::new_call (function func,
1013 rvalue arg0, rvalue arg1, rvalue arg2,
1014 rvalue arg3, rvalue arg4, rvalue arg5,
1015 location loc)
1016 {
1017 std::vector<rvalue> args(6);
1018 args[0] = arg0;
1019 args[1] = arg1;
1020 args[2] = arg2;
1021 args[3] = arg3;
1022 args[4] = arg4;
1023 args[5] = arg5;
1024 return new_call (func, args, loc);
1025 }
1026
1027 inline rvalue
1028 context::new_cast (rvalue expr,
1029 type type_,
1030 location loc)
1031 {
1032 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1033 loc.get_inner_location (),
1034 expr.get_inner_rvalue (),
1035 type_.get_inner_type ()));
1036 }
1037
1038 inline lvalue
1039 context::new_array_access (rvalue ptr,
1040 rvalue index,
1041 location loc)
1042 {
1043 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1044 loc.get_inner_location (),
1045 ptr.get_inner_rvalue (),
1046 index.get_inner_rvalue ()));
1047 }
1048
1049 // class object
1050 inline context
1051 object::get_context () const
1052 {
1053 return context (gcc_jit_object_get_context (m_inner_obj));
1054 }
1055
1056 inline std::string
1057 object::get_debug_string () const
1058 {
1059 return gcc_jit_object_get_debug_string (m_inner_obj);
1060 }
1061
1062 inline object::object () : m_inner_obj (NULL) {}
1063 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1064 {
1065 if (!obj)
1066 throw error ();
1067 }
1068
1069 inline gcc_jit_object *
1070 object::get_inner_object () const
1071 {
1072 return m_inner_obj;
1073 }
1074
1075 inline std::ostream&
1076 operator << (std::ostream& stream, const object &obj)
1077 {
1078 return stream << obj.get_debug_string ();
1079 }
1080
1081 // class location
1082 inline location::location () : object () {}
1083 inline location::location (gcc_jit_location *loc)
1084 : object (gcc_jit_location_as_object (loc))
1085 {}
1086
1087 inline gcc_jit_location *
1088 location::get_inner_location () const
1089 {
1090 /* Manual downcast: */
1091 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1092 }
1093
1094 // class field
1095 inline field::field () : object () {}
1096 inline field::field (gcc_jit_field *inner)
1097 : object (gcc_jit_field_as_object (inner))
1098 {}
1099
1100 inline gcc_jit_field *
1101 field::get_inner_field () const
1102 {
1103 /* Manual downcast: */
1104 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1105 }
1106
1107 // class type
1108 inline type::type () : object () {}
1109 inline type::type (gcc_jit_type *inner)
1110 : object (gcc_jit_type_as_object (inner))
1111 {}
1112
1113 inline gcc_jit_type *
1114 type::get_inner_type () const
1115 {
1116 /* Manual downcast: */
1117 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1118 }
1119
1120 inline type
1121 type::get_pointer ()
1122 {
1123 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1124 }
1125
1126 inline type
1127 type::get_volatile ()
1128 {
1129 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1130 }
1131
1132 inline rvalue
1133 type::zero ()
1134 {
1135 return get_context ().new_rvalue (*this, 0);
1136 }
1137
1138 inline rvalue
1139 type::one ()
1140 {
1141 return get_context ().new_rvalue (*this, 1);
1142 }
1143
1144 // class struct_
1145 inline struct_::struct_ () : type (NULL) {}
1146 inline struct_::struct_ (gcc_jit_struct *inner) :
1147 type (gcc_jit_struct_as_type (inner))
1148 {
1149 }
1150
1151 inline gcc_jit_struct *
1152 struct_::get_inner_struct () const
1153 {
1154 /* Manual downcast: */
1155 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1156 }
1157
1158 // class function
1159 inline function::function () : object () {}
1160 inline function::function (gcc_jit_function *inner)
1161 : object (gcc_jit_function_as_object (inner))
1162 {}
1163
1164 inline gcc_jit_function *
1165 function::get_inner_function () const
1166 {
1167 /* Manual downcast: */
1168 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1169 }
1170
1171 inline void
1172 function::dump_to_dot (const std::string &path)
1173 {
1174 gcc_jit_function_dump_to_dot (get_inner_function (),
1175 path.c_str ());
1176 }
1177
1178 inline param
1179 function::get_param (int index) const
1180 {
1181 return param (gcc_jit_function_get_param (get_inner_function (),
1182 index));
1183 }
1184
1185 inline block
1186 function::new_block ()
1187 {
1188 return block (gcc_jit_function_new_block (get_inner_function (),
1189 NULL));
1190 }
1191
1192 inline block
1193 function::new_block (const std::string &name)
1194 {
1195 return block (gcc_jit_function_new_block (get_inner_function (),
1196 name.c_str ()));
1197 }
1198
1199 inline lvalue
1200 function::new_local (type type_,
1201 const std::string &name,
1202 location loc)
1203 {
1204 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1205 loc.get_inner_location (),
1206 type_.get_inner_type (),
1207 name.c_str ()));
1208 }
1209
1210 inline function
1211 block::get_function () const
1212 {
1213 return function (gcc_jit_block_get_function ( get_inner_block ()));
1214 }
1215
1216 inline void
1217 block::add_eval (rvalue rvalue,
1218 location loc)
1219 {
1220 gcc_jit_block_add_eval (get_inner_block (),
1221 loc.get_inner_location (),
1222 rvalue.get_inner_rvalue ());
1223 }
1224
1225 inline void
1226 block::add_assignment (lvalue lvalue,
1227 rvalue rvalue,
1228 location loc)
1229 {
1230 gcc_jit_block_add_assignment (get_inner_block (),
1231 loc.get_inner_location (),
1232 lvalue.get_inner_lvalue (),
1233 rvalue.get_inner_rvalue ());
1234 }
1235
1236 inline void
1237 block::add_assignment_op (lvalue lvalue,
1238 enum gcc_jit_binary_op op,
1239 rvalue rvalue,
1240 location loc)
1241 {
1242 gcc_jit_block_add_assignment_op (get_inner_block (),
1243 loc.get_inner_location (),
1244 lvalue.get_inner_lvalue (),
1245 op,
1246 rvalue.get_inner_rvalue ());
1247 }
1248
1249 inline void
1250 block::add_comment (const std::string &text,
1251 location loc)
1252 {
1253 gcc_jit_block_add_comment (get_inner_block (),
1254 loc.get_inner_location (),
1255 text.c_str ());
1256 }
1257
1258 inline void
1259 block::end_with_conditional (rvalue boolval,
1260 block on_true,
1261 block on_false,
1262 location loc)
1263 {
1264 gcc_jit_block_end_with_conditional (get_inner_block (),
1265 loc.get_inner_location (),
1266 boolval.get_inner_rvalue (),
1267 on_true.get_inner_block (),
1268 on_false.get_inner_block ());
1269 }
1270
1271 inline void
1272 block::end_with_jump (block target,
1273 location loc)
1274 {
1275 gcc_jit_block_end_with_jump (get_inner_block (),
1276 loc.get_inner_location (),
1277 target.get_inner_block ());
1278 }
1279
1280 inline void
1281 block::end_with_return (rvalue rvalue,
1282 location loc)
1283 {
1284 gcc_jit_block_end_with_return (get_inner_block (),
1285 loc.get_inner_location (),
1286 rvalue.get_inner_rvalue ());
1287 }
1288
1289 inline void
1290 block::end_with_return (location loc)
1291 {
1292 gcc_jit_block_end_with_void_return (get_inner_block (),
1293 loc.get_inner_location ());
1294 }
1295
1296 inline rvalue
1297 block::add_call (function other,
1298 location loc)
1299 {
1300 rvalue c = get_context ().new_call (other, loc);
1301 add_eval (c);
1302 return c;
1303 }
1304 inline rvalue
1305 block::add_call (function other,
1306 rvalue arg0,
1307 location loc)
1308 {
1309 rvalue c = get_context ().new_call (other, arg0, loc);
1310 add_eval (c);
1311 return c;
1312 }
1313 inline rvalue
1314 block::add_call (function other,
1315 rvalue arg0, rvalue arg1,
1316 location loc)
1317 {
1318 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1319 add_eval (c);
1320 return c;
1321 }
1322 inline rvalue
1323 block::add_call (function other,
1324 rvalue arg0, rvalue arg1, rvalue arg2,
1325 location loc)
1326 {
1327 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1328 add_eval (c);
1329 return c;
1330 }
1331
1332 inline rvalue
1333 block::add_call (function other,
1334 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1335 location loc)
1336 {
1337 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1338 add_eval (c);
1339 return c;
1340 }
1341
1342 inline rvalue
1343 function::operator() (location loc)
1344 {
1345 return get_context ().new_call (*this, loc);
1346 }
1347 inline rvalue
1348 function::operator() (rvalue arg0,
1349 location loc)
1350 {
1351 return get_context ().new_call (*this,
1352 arg0,
1353 loc);
1354 }
1355 inline rvalue
1356 function::operator() (rvalue arg0, rvalue arg1,
1357 location loc)
1358 {
1359 return get_context ().new_call (*this,
1360 arg0, arg1,
1361 loc);
1362 }
1363 inline rvalue
1364 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1365 location loc)
1366 {
1367 return get_context ().new_call (*this,
1368 arg0, arg1, arg2,
1369 loc);
1370 }
1371
1372 // class block
1373 inline block::block () : object () {}
1374 inline block::block (gcc_jit_block *inner)
1375 : object (gcc_jit_block_as_object (inner))
1376 {}
1377
1378 inline gcc_jit_block *
1379 block::get_inner_block () const
1380 {
1381 /* Manual downcast: */
1382 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1383 }
1384
1385 // class rvalue
1386 inline rvalue::rvalue () : object () {}
1387 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1388 : object (gcc_jit_rvalue_as_object (inner))
1389 {}
1390
1391 inline gcc_jit_rvalue *
1392 rvalue::get_inner_rvalue () const
1393 {
1394 /* Manual downcast: */
1395 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1396 }
1397
1398 inline type
1399 rvalue::get_type ()
1400 {
1401 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1402 }
1403
1404 inline rvalue
1405 rvalue::access_field (field field,
1406 location loc)
1407 {
1408 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1409 loc.get_inner_location (),
1410 field.get_inner_field ()));
1411 }
1412
1413 inline lvalue
1414 rvalue::dereference_field (field field,
1415 location loc)
1416 {
1417 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1418 loc.get_inner_location (),
1419 field.get_inner_field ()));
1420 }
1421
1422 inline lvalue
1423 rvalue::dereference (location loc)
1424 {
1425 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1426 loc.get_inner_location ()));
1427 }
1428
1429 inline rvalue
1430 rvalue::cast_to (type type_,
1431 location loc)
1432 {
1433 return get_context ().new_cast (*this, type_, loc);
1434 }
1435
1436 inline lvalue
1437 rvalue::operator[] (rvalue index)
1438 {
1439 return get_context ().new_array_access (*this, index);
1440 }
1441
1442 inline lvalue
1443 rvalue::operator[] (int index)
1444 {
1445 context ctxt = get_context ();
1446 type int_t = ctxt.get_int_type <int> ();
1447 return ctxt.new_array_access (*this,
1448 ctxt.new_rvalue (int_t,
1449 index));
1450 }
1451
1452 // class lvalue : public rvalue
1453 inline lvalue::lvalue () : rvalue () {}
1454 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1455 : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1456 {}
1457
1458 inline gcc_jit_lvalue *
1459 lvalue::get_inner_lvalue () const
1460 {
1461 /* Manual downcast: */
1462 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1463 }
1464
1465 inline lvalue
1466 lvalue::access_field (field field, location loc)
1467 {
1468 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1469 loc.get_inner_location (),
1470 field.get_inner_field ()));
1471 }
1472
1473 inline rvalue
1474 lvalue::get_address (location loc)
1475 {
1476 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1477 loc.get_inner_location ()));
1478 }
1479
1480 // class param : public lvalue
1481 inline param::param () : lvalue () {}
1482 inline param::param (gcc_jit_param *inner)
1483 : lvalue (gcc_jit_param_as_lvalue (inner))
1484 {}
1485
1486 /* Overloaded operators. */
1487 // Unary operators
1488 inline rvalue operator- (rvalue a)
1489 {
1490 return a.get_context ().new_minus (a.get_type (), a);
1491 }
1492 inline rvalue operator~ (rvalue a)
1493 {
1494 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1495 }
1496 inline rvalue operator! (rvalue a)
1497 {
1498 return a.get_context ().new_logical_negate (a.get_type (), a);
1499 }
1500
1501 // Binary operators
1502 inline rvalue operator+ (rvalue a, rvalue b)
1503 {
1504 return a.get_context ().new_plus (a.get_type (), a, b);
1505 }
1506 inline rvalue operator- (rvalue a, rvalue b)
1507 {
1508 return a.get_context ().new_minus (a.get_type (), a, b);
1509 }
1510 inline rvalue operator* (rvalue a, rvalue b)
1511 {
1512 return a.get_context ().new_mult (a.get_type (), a, b);
1513 }
1514 inline rvalue operator/ (rvalue a, rvalue b)
1515 {
1516 return a.get_context ().new_divide (a.get_type (), a, b);
1517 }
1518 inline rvalue operator% (rvalue a, rvalue b)
1519 {
1520 return a.get_context ().new_modulo (a.get_type (), a, b);
1521 }
1522 inline rvalue operator& (rvalue a, rvalue b)
1523 {
1524 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1525 }
1526 inline rvalue operator^ (rvalue a, rvalue b)
1527 {
1528 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1529 }
1530 inline rvalue operator| (rvalue a, rvalue b)
1531 {
1532 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1533 }
1534 inline rvalue operator&& (rvalue a, rvalue b)
1535 {
1536 return a.get_context ().new_logical_and (a.get_type (), a, b);
1537 }
1538 inline rvalue operator|| (rvalue a, rvalue b)
1539 {
1540 return a.get_context ().new_logical_or (a.get_type (), a, b);
1541 }
1542
1543 /* Comparisons. */
1544 inline rvalue operator== (rvalue a, rvalue b)
1545 {
1546 return a.get_context ().new_eq (a, b);
1547 }
1548 inline rvalue operator!= (rvalue a, rvalue b)
1549 {
1550 return a.get_context ().new_ne (a, b);
1551 }
1552 inline rvalue operator< (rvalue a, rvalue b)
1553 {
1554 return a.get_context ().new_lt (a, b);
1555 }
1556 inline rvalue operator<= (rvalue a, rvalue b)
1557 {
1558 return a.get_context ().new_le (a, b);
1559 }
1560 inline rvalue operator> (rvalue a, rvalue b)
1561 {
1562 return a.get_context ().new_gt (a, b);
1563 }
1564 inline rvalue operator>= (rvalue a, rvalue b)
1565 {
1566 return a.get_context ().new_ge (a, b);
1567 }
1568
1569 /* Dereferencing. */
1570 inline lvalue operator* (rvalue ptr)
1571 {
1572 return ptr.dereference ();
1573 }
1574
1575 } // namespace gccjit
1576
1577 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */