ipa-cp.c (ipcp_cloning_candidate_p): Use opt_for_fn.
[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 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;
45
46 /* Errors within the API become C++ exceptions of this class. */
47 class error
48 {
49 };
50
51 class object
52 {
53 public:
54 context get_context () const;
55
56 std::string get_debug_string () const;
57
58 protected:
59 object ();
60 object (gcc_jit_object *obj);
61
62 gcc_jit_object *get_inner_object () const;
63
64 private:
65 gcc_jit_object *m_inner_obj;
66 };
67
68 inline std::ostream& operator << (std::ostream& stream, const object &obj);
69
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
76 {
77 public:
78 location ();
79 location (gcc_jit_location *loc);
80
81 gcc_jit_location *get_inner_location () const;
82 };
83
84 class context
85 {
86 public:
87 static context acquire ();
88 context ();
89 context (gcc_jit_context *ctxt);
90
91 gccjit::context new_child_context ();
92
93 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
94
95 void release ();
96
97 gcc_jit_result *compile ();
98
99 void dump_to_file (const std::string &path,
100 bool update_locations);
101
102 void set_int_option (enum gcc_jit_int_option opt,
103 int value);
104
105 void set_bool_option (enum gcc_jit_bool_option opt,
106 int value);
107
108 location
109 new_location (const std::string &filename,
110 int line,
111 int column);
112
113 type get_type (enum gcc_jit_types kind);
114 type get_int_type (size_t num_bytes, int is_signed);
115
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 ();
121
122 type new_array_type (type element_type, int num_elements,
123 location loc = location ());
124
125 field new_field (type type_, const std::string &name,
126 location loc = location ());
127
128 struct_ new_struct_type (const std::string &name,
129 std::vector<field> &fields,
130 location loc = location ());
131
132 struct_ new_opaque_struct_type (const std::string &name,
133 location loc = location ());
134
135 param new_param (type type_,
136 const std::string &name,
137 location loc = location ());
138
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 ());
145
146 function get_builtin_function (const std::string &name);
147
148 lvalue new_global (type type_,
149 const std::string &name,
150 location loc = location ());
151
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;
161
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 ());
167
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 ());
179
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 ());
185
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 ());
218
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 ());
237
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 ());
242
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 ());
269
270 rvalue new_cast (rvalue expr,
271 type type_,
272 location loc = location ());
273
274 lvalue new_array_access (rvalue ptr,
275 rvalue index,
276 location loc = location ());
277
278 private:
279 gcc_jit_context *m_inner_ctxt;
280 };
281
282 class field : public object
283 {
284 public:
285 field ();
286 field (gcc_jit_field *inner);
287
288 gcc_jit_field *get_inner_field () const;
289 };
290
291 class type : public object
292 {
293 public:
294 type ();
295 type (gcc_jit_type *inner);
296
297 gcc_jit_type *get_inner_type () const;
298
299 type get_pointer ();
300 type get_volatile ();
301
302 // Shortcuts for getting values of numeric types:
303 rvalue zero ();
304 rvalue one ();
305 };
306
307 class struct_ : public type
308 {
309 public:
310 struct_ ();
311 struct_ (gcc_jit_struct *inner);
312
313 gcc_jit_struct *get_inner_struct () const;
314 };
315
316 class function : public object
317 {
318 public:
319 function ();
320 function (gcc_jit_function *func);
321
322 gcc_jit_function *get_inner_function () const;
323
324 void dump_to_dot (const std::string &path);
325
326 param get_param (int index) const;
327
328 block new_block ();
329 block new_block (const std::string &name);
330
331 lvalue new_local (type type_,
332 const std::string &name,
333 location loc = location ());
334
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 ());
346 };
347
348 class block : public object
349 {
350 public:
351 block ();
352 block (gcc_jit_block *inner);
353
354 gcc_jit_block *get_inner_block () const;
355
356 function get_function () const;
357
358 void add_eval (rvalue rvalue,
359 location loc = location ());
360
361 void add_assignment (lvalue lvalue,
362 rvalue rvalue,
363 location loc = location ());
364
365 void add_assignment_op (lvalue lvalue,
366 enum gcc_jit_binary_op op,
367 rvalue rvalue,
368 location loc = location ());
369
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 ());
386
387 void add_comment (const std::string &text,
388 location loc = location ());
389
390 void end_with_conditional (rvalue boolval,
391 block on_true,
392 block on_false,
393 location loc = location ());
394
395 void end_with_jump (block target,
396 location loc = location ());
397
398 void end_with_return (rvalue rvalue,
399 location loc = location ());
400 void end_with_return (location loc = location ());
401
402 };
403
404 class rvalue : public object
405 {
406 public:
407 rvalue ();
408 rvalue (gcc_jit_rvalue *inner);
409 gcc_jit_rvalue *get_inner_rvalue () const;
410
411 type get_type ();
412
413 rvalue access_field (field field,
414 location loc = location ());
415
416 lvalue dereference_field (field field,
417 location loc = location ());
418
419 lvalue dereference (location loc = location ());
420
421 rvalue cast_to (type type_,
422 location loc = location ());
423
424 /* Array access. */
425 lvalue operator[] (rvalue index);
426 lvalue operator[] (int index);
427 };
428
429 class lvalue : public rvalue
430 {
431 public:
432 lvalue ();
433 lvalue (gcc_jit_lvalue *inner);
434
435 gcc_jit_lvalue *get_inner_lvalue () const;
436
437 lvalue access_field (field field,
438 location loc = location ());
439
440 rvalue get_address (location loc = location ());
441 };
442
443 class param : public lvalue
444 {
445 public:
446 param ();
447 param (gcc_jit_param *inner);
448
449 gcc_jit_param *get_inner_param () const;
450 };
451
452
453 /* Overloaded operators, for those who want the most terse API
454 (at the possible risk of being a little too magical).
455
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. */
459
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
464
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
476
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);
484
485 /* Dereferencing. */
486 lvalue operator* (rvalue ptr);
487 }
488
489 /****************************************************************************
490 Implementation of the API
491 ****************************************************************************/
492 namespace gccjit {
493
494 // class context
495 inline context context::acquire ()
496 {
497 return context (gcc_jit_context_acquire ());
498 }
499 inline context::context () : m_inner_ctxt (NULL) {}
500 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
501 {
502 if (!inner)
503 throw error ();
504 }
505
506 inline gccjit::context
507 context::new_child_context ()
508 {
509 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
510 }
511
512 inline void
513 context::release ()
514 {
515 gcc_jit_context_release (m_inner_ctxt);
516 m_inner_ctxt = NULL;
517 }
518
519 inline gcc_jit_result *
520 context::compile ()
521 {
522 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
523 if (!result)
524 throw error ();
525 return result;
526 }
527
528 inline void
529 context::dump_to_file (const std::string &path,
530 bool update_locations)
531 {
532 gcc_jit_context_dump_to_file (m_inner_ctxt,
533 path.c_str (),
534 update_locations);
535 }
536
537 inline void
538 context::set_int_option (enum gcc_jit_int_option opt,
539 int value)
540 {
541 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
542
543 }
544
545 inline void
546 context::set_bool_option (enum gcc_jit_bool_option opt,
547 int value)
548 {
549 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
550
551 }
552
553 inline location
554 context::new_location (const std::string &filename,
555 int line,
556 int column)
557 {
558 return location (gcc_jit_context_new_location (m_inner_ctxt,
559 filename.c_str (),
560 line,
561 column));
562 }
563
564 inline type
565 context::get_type (enum gcc_jit_types kind)
566 {
567 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
568 }
569
570 inline type
571 context::get_int_type (size_t num_bytes, int is_signed)
572 {
573 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
574 num_bytes,
575 is_signed));
576 }
577
578 template <typename T>
579 inline type
580 context::get_int_type ()
581 {
582 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
583 }
584
585 inline type
586 context::new_array_type (type element_type, int num_elements, location loc)
587 {
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));
593 }
594
595 inline field
596 context::new_field (type type_, const std::string &name, location loc)
597 {
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 ()));
602 }
603
604 inline struct_
605 context::new_struct_type (const std::string &name,
606 std::vector<field> &fields,
607 location loc)
608 {
609 /* Treat std::vector as an array, relying on it not being resized: */
610 field *as_array_of_wrappers = &fields[0];
611
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);
616
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));
622 }
623
624 inline struct_
625 context::new_opaque_struct_type (const std::string &name,
626 location loc)
627 {
628 return struct_ (gcc_jit_context_new_opaque_struct (
629 m_inner_ctxt,
630 loc.get_inner_location (),
631 name.c_str ()));
632 }
633
634 inline param
635 context::new_param (type type_,
636 const std::string &name,
637 location loc)
638 {
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 ()));
643 }
644
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)
652 {
653 /* Treat std::vector as an array, relying on it not being resized: */
654 param *as_array_of_wrappers = &params[0];
655
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);
660
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));
669 }
670
671 inline function
672 context::get_builtin_function (const std::string &name)
673 {
674 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
675 name.c_str ()));
676 }
677
678 inline lvalue
679 context::new_global (type type_,
680 const std::string &name,
681 location loc)
682 {
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 ()));
687 }
688
689 inline rvalue
690 context::new_rvalue (type numeric_type,
691 int value) const
692 {
693 return rvalue (
694 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
695 numeric_type.get_inner_type (),
696 value));
697 }
698
699 inline rvalue
700 context::zero (type numeric_type) const
701 {
702 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
703 numeric_type.get_inner_type ()));
704 }
705
706 inline rvalue
707 context::one (type numeric_type) const
708 {
709 return rvalue (gcc_jit_context_one (m_inner_ctxt,
710 numeric_type.get_inner_type ()));
711 }
712
713 inline rvalue
714 context::new_rvalue (type numeric_type,
715 double value) const
716 {
717 return rvalue (
718 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
719 numeric_type.get_inner_type (),
720 value));
721 }
722
723 inline rvalue
724 context::new_rvalue (type pointer_type,
725 void *value) const
726 {
727 return rvalue (
728 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
729 pointer_type.get_inner_type (),
730 value));
731 }
732
733 inline rvalue
734 context::new_rvalue (const std::string &value) const
735 {
736 return rvalue (
737 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
738 }
739
740 inline rvalue
741 context::new_unary_op (enum gcc_jit_unary_op op,
742 type result_type,
743 rvalue a,
744 location loc)
745 {
746 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
747 loc.get_inner_location (),
748 op,
749 result_type.get_inner_type (),
750 a.get_inner_rvalue ()));
751 }
752 inline rvalue
753 context::new_minus (type result_type,
754 rvalue a,
755 location loc)
756 {
757 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
758 result_type, a, loc));
759 }
760 inline rvalue
761 context::new_bitwise_negate (type result_type,
762 rvalue a,
763 location loc)
764 {
765 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
766 result_type, a, loc));
767 }
768 inline rvalue
769 context::new_logical_negate (type result_type,
770 rvalue a,
771 location loc)
772 {
773 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
774 result_type, a, loc));
775 }
776
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)
782 {
783 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
784 loc.get_inner_location (),
785 op,
786 result_type.get_inner_type (),
787 a.get_inner_rvalue (),
788 b.get_inner_rvalue ()));
789 }
790 inline rvalue
791 context::new_plus (type result_type,
792 rvalue a, rvalue b,
793 location loc)
794 {
795 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
796 result_type, a, b, loc);
797 }
798 inline rvalue
799 context::new_minus (type result_type,
800 rvalue a, rvalue b,
801 location loc)
802 {
803 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
804 result_type, a, b, loc);
805 }
806 inline rvalue
807 context::new_mult (type result_type,
808 rvalue a, rvalue b,
809 location loc)
810 {
811 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
812 result_type, a, b, loc);
813 }
814 inline rvalue
815 context::new_divide (type result_type,
816 rvalue a, rvalue b,
817 location loc)
818 {
819 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
820 result_type, a, b, loc);
821 }
822 inline rvalue
823 context::new_modulo (type result_type,
824 rvalue a, rvalue b,
825 location loc)
826 {
827 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
828 result_type, a, b, loc);
829 }
830 inline rvalue
831 context::new_bitwise_and (type result_type,
832 rvalue a, rvalue b,
833 location loc)
834 {
835 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
836 result_type, a, b, loc);
837 }
838 inline rvalue
839 context::new_bitwise_xor (type result_type,
840 rvalue a, rvalue b,
841 location loc)
842 {
843 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
844 result_type, a, b, loc);
845 }
846 inline rvalue
847 context::new_bitwise_or (type result_type,
848 rvalue a, rvalue b,
849 location loc)
850 {
851 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
852 result_type, a, b, loc);
853 }
854 inline rvalue
855 context::new_logical_and (type result_type,
856 rvalue a, rvalue b,
857 location loc)
858 {
859 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
860 result_type, a, b, loc);
861 }
862 inline rvalue
863 context::new_logical_or (type result_type,
864 rvalue a, rvalue b,
865 location loc)
866 {
867 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
868 result_type, a, b, loc);
869 }
870
871 inline rvalue
872 context::new_comparison (enum gcc_jit_comparison op,
873 rvalue a, rvalue b,
874 location loc)
875 {
876 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
877 loc.get_inner_location (),
878 op,
879 a.get_inner_rvalue (),
880 b.get_inner_rvalue ()));
881 }
882 inline rvalue
883 context::new_eq (rvalue a, rvalue b,
884 location loc)
885 {
886 return new_comparison (GCC_JIT_COMPARISON_EQ,
887 a, b, loc);
888 }
889 inline rvalue
890 context::new_ne (rvalue a, rvalue b,
891 location loc)
892 {
893 return new_comparison (GCC_JIT_COMPARISON_NE,
894 a, b, loc);
895 }
896 inline rvalue
897 context::new_lt (rvalue a, rvalue b,
898 location loc)
899 {
900 return new_comparison (GCC_JIT_COMPARISON_LT,
901 a, b, loc);
902 }
903 inline rvalue
904 context::new_le (rvalue a, rvalue b,
905 location loc)
906 {
907 return new_comparison (GCC_JIT_COMPARISON_LE,
908 a, b, loc);
909 }
910 inline rvalue
911 context::new_gt (rvalue a, rvalue b,
912 location loc)
913 {
914 return new_comparison (GCC_JIT_COMPARISON_GT,
915 a, b, loc);
916 }
917 inline rvalue
918 context::new_ge (rvalue a, rvalue b,
919 location loc)
920 {
921 return new_comparison (GCC_JIT_COMPARISON_GE,
922 a, b, loc);
923 }
924
925 inline rvalue
926 context::new_call (function func,
927 std::vector<rvalue> &args,
928 location loc)
929 {
930 /* Treat std::vector as an array, relying on it not being resized: */
931 rvalue *as_array_of_wrappers = &args[0];
932
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);
942 }
943 inline rvalue
944 context::new_call (function func,
945 location loc)
946 {
947 std::vector<rvalue> args;
948 return new_call (func, args, loc);
949 }
950
951 inline rvalue
952 context::new_call (function func,
953 rvalue arg0,
954 location loc)
955 {
956 std::vector<rvalue> args(1);
957 args[0] = arg0;
958 return new_call (func, args, loc);
959 }
960 inline rvalue
961 context::new_call (function func,
962 rvalue arg0, rvalue arg1,
963 location loc)
964 {
965 std::vector<rvalue> args(2);
966 args[0] = arg0;
967 args[1] = arg1;
968 return new_call (func, args, loc);
969 }
970 inline rvalue
971 context::new_call (function func,
972 rvalue arg0, rvalue arg1, rvalue arg2,
973 location loc)
974 {
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);
980 }
981 inline rvalue
982 context::new_call (function func,
983 rvalue arg0, rvalue arg1, rvalue arg2,
984 rvalue arg3,
985 location loc)
986 {
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);
993 }
994 inline rvalue
995 context::new_call (function func,
996 rvalue arg0, rvalue arg1, rvalue arg2,
997 rvalue arg3, rvalue arg4,
998 location loc)
999 {
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);
1007 }
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)
1013 {
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);
1022 }
1023
1024 inline rvalue
1025 context::new_cast (rvalue expr,
1026 type type_,
1027 location loc)
1028 {
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 ()));
1033 }
1034
1035 inline lvalue
1036 context::new_array_access (rvalue ptr,
1037 rvalue index,
1038 location loc)
1039 {
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 ()));
1044 }
1045
1046 // class object
1047 inline context
1048 object::get_context () const
1049 {
1050 return context (gcc_jit_object_get_context (m_inner_obj));
1051 }
1052
1053 inline std::string
1054 object::get_debug_string () const
1055 {
1056 return gcc_jit_object_get_debug_string (m_inner_obj);
1057 }
1058
1059 inline object::object () : m_inner_obj (NULL) {}
1060 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1061 {
1062 if (!obj)
1063 throw error ();
1064 }
1065
1066 inline gcc_jit_object *
1067 object::get_inner_object () const
1068 {
1069 return m_inner_obj;
1070 }
1071
1072 inline std::ostream&
1073 operator << (std::ostream& stream, const object &obj)
1074 {
1075 return stream << obj.get_debug_string ();
1076 }
1077
1078 // class location
1079 inline location::location () : object () {}
1080 inline location::location (gcc_jit_location *loc)
1081 : object (gcc_jit_location_as_object (loc))
1082 {}
1083
1084 inline gcc_jit_location *
1085 location::get_inner_location () const
1086 {
1087 /* Manual downcast: */
1088 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1089 }
1090
1091 // class field
1092 inline field::field () : object () {}
1093 inline field::field (gcc_jit_field *inner)
1094 : object (gcc_jit_field_as_object (inner))
1095 {}
1096
1097 inline gcc_jit_field *
1098 field::get_inner_field () const
1099 {
1100 /* Manual downcast: */
1101 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1102 }
1103
1104 // class type
1105 inline type::type () : object () {}
1106 inline type::type (gcc_jit_type *inner)
1107 : object (gcc_jit_type_as_object (inner))
1108 {}
1109
1110 inline gcc_jit_type *
1111 type::get_inner_type () const
1112 {
1113 /* Manual downcast: */
1114 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1115 }
1116
1117 inline type
1118 type::get_pointer ()
1119 {
1120 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1121 }
1122
1123 inline type
1124 type::get_volatile ()
1125 {
1126 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1127 }
1128
1129 inline rvalue
1130 type::zero ()
1131 {
1132 return get_context ().new_rvalue (*this, 0);
1133 }
1134
1135 inline rvalue
1136 type::one ()
1137 {
1138 return get_context ().new_rvalue (*this, 1);
1139 }
1140
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))
1145 {
1146 }
1147
1148 inline gcc_jit_struct *
1149 struct_::get_inner_struct () const
1150 {
1151 /* Manual downcast: */
1152 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1153 }
1154
1155 // class function
1156 inline function::function () : object () {}
1157 inline function::function (gcc_jit_function *inner)
1158 : object (gcc_jit_function_as_object (inner))
1159 {}
1160
1161 inline gcc_jit_function *
1162 function::get_inner_function () const
1163 {
1164 /* Manual downcast: */
1165 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1166 }
1167
1168 inline void
1169 function::dump_to_dot (const std::string &path)
1170 {
1171 gcc_jit_function_dump_to_dot (get_inner_function (),
1172 path.c_str ());
1173 }
1174
1175 inline param
1176 function::get_param (int index) const
1177 {
1178 return param (gcc_jit_function_get_param (get_inner_function (),
1179 index));
1180 }
1181
1182 inline block
1183 function::new_block ()
1184 {
1185 return block (gcc_jit_function_new_block (get_inner_function (),
1186 NULL));
1187 }
1188
1189 inline block
1190 function::new_block (const std::string &name)
1191 {
1192 return block (gcc_jit_function_new_block (get_inner_function (),
1193 name.c_str ()));
1194 }
1195
1196 inline lvalue
1197 function::new_local (type type_,
1198 const std::string &name,
1199 location loc)
1200 {
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 ()));
1205 }
1206
1207 inline function
1208 block::get_function () const
1209 {
1210 return function (gcc_jit_block_get_function ( get_inner_block ()));
1211 }
1212
1213 inline void
1214 block::add_eval (rvalue rvalue,
1215 location loc)
1216 {
1217 gcc_jit_block_add_eval (get_inner_block (),
1218 loc.get_inner_location (),
1219 rvalue.get_inner_rvalue ());
1220 }
1221
1222 inline void
1223 block::add_assignment (lvalue lvalue,
1224 rvalue rvalue,
1225 location loc)
1226 {
1227 gcc_jit_block_add_assignment (get_inner_block (),
1228 loc.get_inner_location (),
1229 lvalue.get_inner_lvalue (),
1230 rvalue.get_inner_rvalue ());
1231 }
1232
1233 inline void
1234 block::add_assignment_op (lvalue lvalue,
1235 enum gcc_jit_binary_op op,
1236 rvalue rvalue,
1237 location loc)
1238 {
1239 gcc_jit_block_add_assignment_op (get_inner_block (),
1240 loc.get_inner_location (),
1241 lvalue.get_inner_lvalue (),
1242 op,
1243 rvalue.get_inner_rvalue ());
1244 }
1245
1246 inline void
1247 block::add_comment (const std::string &text,
1248 location loc)
1249 {
1250 gcc_jit_block_add_comment (get_inner_block (),
1251 loc.get_inner_location (),
1252 text.c_str ());
1253 }
1254
1255 inline void
1256 block::end_with_conditional (rvalue boolval,
1257 block on_true,
1258 block on_false,
1259 location loc)
1260 {
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 ());
1266 }
1267
1268 inline void
1269 block::end_with_jump (block target,
1270 location loc)
1271 {
1272 gcc_jit_block_end_with_jump (get_inner_block (),
1273 loc.get_inner_location (),
1274 target.get_inner_block ());
1275 }
1276
1277 inline void
1278 block::end_with_return (rvalue rvalue,
1279 location loc)
1280 {
1281 gcc_jit_block_end_with_return (get_inner_block (),
1282 loc.get_inner_location (),
1283 rvalue.get_inner_rvalue ());
1284 }
1285
1286 inline void
1287 block::end_with_return (location loc)
1288 {
1289 gcc_jit_block_end_with_void_return (get_inner_block (),
1290 loc.get_inner_location ());
1291 }
1292
1293 inline rvalue
1294 block::add_call (function other,
1295 location loc)
1296 {
1297 rvalue c = get_context ().new_call (other, loc);
1298 add_eval (c);
1299 return c;
1300 }
1301 inline rvalue
1302 block::add_call (function other,
1303 rvalue arg0,
1304 location loc)
1305 {
1306 rvalue c = get_context ().new_call (other, arg0, loc);
1307 add_eval (c);
1308 return c;
1309 }
1310 inline rvalue
1311 block::add_call (function other,
1312 rvalue arg0, rvalue arg1,
1313 location loc)
1314 {
1315 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1316 add_eval (c);
1317 return c;
1318 }
1319 inline rvalue
1320 block::add_call (function other,
1321 rvalue arg0, rvalue arg1, rvalue arg2,
1322 location loc)
1323 {
1324 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1325 add_eval (c);
1326 return c;
1327 }
1328
1329 inline rvalue
1330 block::add_call (function other,
1331 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1332 location loc)
1333 {
1334 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1335 add_eval (c);
1336 return c;
1337 }
1338
1339 inline rvalue
1340 function::operator() (location loc)
1341 {
1342 return get_context ().new_call (*this, loc);
1343 }
1344 inline rvalue
1345 function::operator() (rvalue arg0,
1346 location loc)
1347 {
1348 return get_context ().new_call (*this,
1349 arg0,
1350 loc);
1351 }
1352 inline rvalue
1353 function::operator() (rvalue arg0, rvalue arg1,
1354 location loc)
1355 {
1356 return get_context ().new_call (*this,
1357 arg0, arg1,
1358 loc);
1359 }
1360 inline rvalue
1361 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1362 location loc)
1363 {
1364 return get_context ().new_call (*this,
1365 arg0, arg1, arg2,
1366 loc);
1367 }
1368
1369 // class block
1370 inline block::block () : object () {}
1371 inline block::block (gcc_jit_block *inner)
1372 : object (gcc_jit_block_as_object (inner))
1373 {}
1374
1375 inline gcc_jit_block *
1376 block::get_inner_block () const
1377 {
1378 /* Manual downcast: */
1379 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1380 }
1381
1382 // class rvalue
1383 inline rvalue::rvalue () : object () {}
1384 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1385 : object (gcc_jit_rvalue_as_object (inner))
1386 {}
1387
1388 inline gcc_jit_rvalue *
1389 rvalue::get_inner_rvalue () const
1390 {
1391 /* Manual downcast: */
1392 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1393 }
1394
1395 inline type
1396 rvalue::get_type ()
1397 {
1398 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1399 }
1400
1401 inline rvalue
1402 rvalue::access_field (field field,
1403 location loc)
1404 {
1405 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1406 loc.get_inner_location (),
1407 field.get_inner_field ()));
1408 }
1409
1410 inline lvalue
1411 rvalue::dereference_field (field field,
1412 location loc)
1413 {
1414 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1415 loc.get_inner_location (),
1416 field.get_inner_field ()));
1417 }
1418
1419 inline lvalue
1420 rvalue::dereference (location loc)
1421 {
1422 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1423 loc.get_inner_location ()));
1424 }
1425
1426 inline rvalue
1427 rvalue::cast_to (type type_,
1428 location loc)
1429 {
1430 return get_context ().new_cast (*this, type_, loc);
1431 }
1432
1433 inline lvalue
1434 rvalue::operator[] (rvalue index)
1435 {
1436 return get_context ().new_array_access (*this, index);
1437 }
1438
1439 inline lvalue
1440 rvalue::operator[] (int index)
1441 {
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));
1447 }
1448
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))
1453 {}
1454
1455 inline gcc_jit_lvalue *
1456 lvalue::get_inner_lvalue () const
1457 {
1458 /* Manual downcast: */
1459 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1460 }
1461
1462 inline lvalue
1463 lvalue::access_field (field field, location loc)
1464 {
1465 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1466 loc.get_inner_location (),
1467 field.get_inner_field ()));
1468 }
1469
1470 inline rvalue
1471 lvalue::get_address (location loc)
1472 {
1473 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1474 loc.get_inner_location ()));
1475 }
1476
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))
1481 {}
1482
1483 /* Overloaded operators. */
1484 // Unary operators
1485 inline rvalue operator- (rvalue a)
1486 {
1487 return a.get_context ().new_minus (a.get_type (), a);
1488 }
1489 inline rvalue operator~ (rvalue a)
1490 {
1491 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1492 }
1493 inline rvalue operator! (rvalue a)
1494 {
1495 return a.get_context ().new_logical_negate (a.get_type (), a);
1496 }
1497
1498 // Binary operators
1499 inline rvalue operator+ (rvalue a, rvalue b)
1500 {
1501 return a.get_context ().new_plus (a.get_type (), a, b);
1502 }
1503 inline rvalue operator- (rvalue a, rvalue b)
1504 {
1505 return a.get_context ().new_minus (a.get_type (), a, b);
1506 }
1507 inline rvalue operator* (rvalue a, rvalue b)
1508 {
1509 return a.get_context ().new_mult (a.get_type (), a, b);
1510 }
1511 inline rvalue operator/ (rvalue a, rvalue b)
1512 {
1513 return a.get_context ().new_divide (a.get_type (), a, b);
1514 }
1515 inline rvalue operator% (rvalue a, rvalue b)
1516 {
1517 return a.get_context ().new_modulo (a.get_type (), a, b);
1518 }
1519 inline rvalue operator& (rvalue a, rvalue b)
1520 {
1521 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1522 }
1523 inline rvalue operator^ (rvalue a, rvalue b)
1524 {
1525 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1526 }
1527 inline rvalue operator| (rvalue a, rvalue b)
1528 {
1529 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1530 }
1531 inline rvalue operator&& (rvalue a, rvalue b)
1532 {
1533 return a.get_context ().new_logical_and (a.get_type (), a, b);
1534 }
1535 inline rvalue operator|| (rvalue a, rvalue b)
1536 {
1537 return a.get_context ().new_logical_or (a.get_type (), a, b);
1538 }
1539
1540 /* Comparisons. */
1541 inline rvalue operator== (rvalue a, rvalue b)
1542 {
1543 return a.get_context ().new_eq (a, b);
1544 }
1545 inline rvalue operator!= (rvalue a, rvalue b)
1546 {
1547 return a.get_context ().new_ne (a, b);
1548 }
1549 inline rvalue operator< (rvalue a, rvalue b)
1550 {
1551 return a.get_context ().new_lt (a, b);
1552 }
1553 inline rvalue operator<= (rvalue a, rvalue b)
1554 {
1555 return a.get_context ().new_le (a, b);
1556 }
1557 inline rvalue operator> (rvalue a, rvalue b)
1558 {
1559 return a.get_context ().new_gt (a, b);
1560 }
1561 inline rvalue operator>= (rvalue a, rvalue b)
1562 {
1563 return a.get_context ().new_ge (a, b);
1564 }
1565
1566 /* Dereferencing. */
1567 inline lvalue operator* (rvalue ptr)
1568 {
1569 return ptr.dereference ();
1570 }
1571
1572 } // namespace gccjit
1573
1574 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */