re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
[gcc.git] / gcc / jit / libgccjit++.h
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2015 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 compile_to_file (enum gcc_jit_output_kind output_kind,
103 const char *output_path);
104
105 void dump_to_file (const std::string &path,
106 bool update_locations);
107
108 void set_logfile (FILE *logfile,
109 int flags,
110 int verbosity);
111
112 void dump_reproducer_to_file (const char *path);
113
114 void set_str_option (enum gcc_jit_str_option opt,
115 const char *value);
116
117 void set_int_option (enum gcc_jit_int_option opt,
118 int value);
119
120 void set_bool_option (enum gcc_jit_bool_option opt,
121 int value);
122
123 location
124 new_location (const std::string &filename,
125 int line,
126 int column);
127
128 type get_type (enum gcc_jit_types kind);
129 type get_int_type (size_t num_bytes, int is_signed);
130
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 ();
136
137 type new_array_type (type element_type, int num_elements,
138 location loc = location ());
139
140 field new_field (type type_, const std::string &name,
141 location loc = location ());
142
143 struct_ new_struct_type (const std::string &name,
144 std::vector<field> &fields,
145 location loc = location ());
146
147 struct_ new_opaque_struct_type (const std::string &name,
148 location loc = location ());
149
150 param new_param (type type_,
151 const std::string &name,
152 location loc = location ());
153
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 ());
160
161 function get_builtin_function (const std::string &name);
162
163 lvalue new_global (enum gcc_jit_global_kind kind,
164 type type_,
165 const std::string &name,
166 location loc = location ());
167
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;
179
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 ());
185
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 ());
197
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 ());
203
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 ());
236
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 ());
255
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 ());
260
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 ());
287
288 rvalue new_cast (rvalue expr,
289 type type_,
290 location loc = location ());
291
292 lvalue new_array_access (rvalue ptr,
293 rvalue index,
294 location loc = location ());
295
296 private:
297 gcc_jit_context *m_inner_ctxt;
298 };
299
300 class field : public object
301 {
302 public:
303 field ();
304 field (gcc_jit_field *inner);
305
306 gcc_jit_field *get_inner_field () const;
307 };
308
309 class type : public object
310 {
311 public:
312 type ();
313 type (gcc_jit_type *inner);
314
315 gcc_jit_type *get_inner_type () const;
316
317 type get_pointer ();
318 type get_volatile ();
319
320 // Shortcuts for getting values of numeric types:
321 rvalue zero ();
322 rvalue one ();
323 };
324
325 class struct_ : public type
326 {
327 public:
328 struct_ ();
329 struct_ (gcc_jit_struct *inner);
330
331 gcc_jit_struct *get_inner_struct () const;
332 };
333
334 class function : public object
335 {
336 public:
337 function ();
338 function (gcc_jit_function *func);
339
340 gcc_jit_function *get_inner_function () const;
341
342 void dump_to_dot (const std::string &path);
343
344 param get_param (int index) const;
345
346 block new_block ();
347 block new_block (const std::string &name);
348
349 lvalue new_local (type type_,
350 const std::string &name,
351 location loc = location ());
352
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 ());
364 };
365
366 class block : public object
367 {
368 public:
369 block ();
370 block (gcc_jit_block *inner);
371
372 gcc_jit_block *get_inner_block () const;
373
374 function get_function () const;
375
376 void add_eval (rvalue rvalue,
377 location loc = location ());
378
379 void add_assignment (lvalue lvalue,
380 rvalue rvalue,
381 location loc = location ());
382
383 void add_assignment_op (lvalue lvalue,
384 enum gcc_jit_binary_op op,
385 rvalue rvalue,
386 location loc = location ());
387
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 ());
404
405 void add_comment (const std::string &text,
406 location loc = location ());
407
408 void end_with_conditional (rvalue boolval,
409 block on_true,
410 block on_false,
411 location loc = location ());
412
413 void end_with_jump (block target,
414 location loc = location ());
415
416 void end_with_return (rvalue rvalue,
417 location loc = location ());
418 void end_with_return (location loc = location ());
419
420 };
421
422 class rvalue : public object
423 {
424 public:
425 rvalue ();
426 rvalue (gcc_jit_rvalue *inner);
427 gcc_jit_rvalue *get_inner_rvalue () const;
428
429 type get_type ();
430
431 rvalue access_field (field field,
432 location loc = location ());
433
434 lvalue dereference_field (field field,
435 location loc = location ());
436
437 lvalue dereference (location loc = location ());
438
439 rvalue cast_to (type type_,
440 location loc = location ());
441
442 /* Array access. */
443 lvalue operator[] (rvalue index);
444 lvalue operator[] (int index);
445 };
446
447 class lvalue : public rvalue
448 {
449 public:
450 lvalue ();
451 lvalue (gcc_jit_lvalue *inner);
452
453 gcc_jit_lvalue *get_inner_lvalue () const;
454
455 lvalue access_field (field field,
456 location loc = location ());
457
458 rvalue get_address (location loc = location ());
459 };
460
461 class param : public lvalue
462 {
463 public:
464 param ();
465 param (gcc_jit_param *inner);
466
467 gcc_jit_param *get_inner_param () const;
468 };
469
470
471 /* Overloaded operators, for those who want the most terse API
472 (at the possible risk of being a little too magical).
473
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. */
477
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
482
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
494
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);
502
503 /* Dereferencing. */
504 lvalue operator* (rvalue ptr);
505 }
506
507 /****************************************************************************
508 Implementation of the API
509 ****************************************************************************/
510 namespace gccjit {
511
512 // class context
513 inline context context::acquire ()
514 {
515 return context (gcc_jit_context_acquire ());
516 }
517 inline context::context () : m_inner_ctxt (NULL) {}
518 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
519 {
520 if (!inner)
521 throw error ();
522 }
523
524 inline gccjit::context
525 context::new_child_context ()
526 {
527 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
528 }
529
530 inline void
531 context::release ()
532 {
533 gcc_jit_context_release (m_inner_ctxt);
534 m_inner_ctxt = NULL;
535 }
536
537 inline gcc_jit_result *
538 context::compile ()
539 {
540 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
541 if (!result)
542 throw error ();
543 return result;
544 }
545
546 inline void
547 context::compile_to_file (enum gcc_jit_output_kind output_kind,
548 const char *output_path)
549 {
550 gcc_jit_context_compile_to_file (m_inner_ctxt,
551 output_kind,
552 output_path);
553 }
554
555 inline void
556 context::dump_to_file (const std::string &path,
557 bool update_locations)
558 {
559 gcc_jit_context_dump_to_file (m_inner_ctxt,
560 path.c_str (),
561 update_locations);
562 }
563
564 inline void
565 context::set_logfile (FILE *logfile,
566 int flags,
567 int verbosity)
568 {
569 gcc_jit_context_set_logfile (m_inner_ctxt,
570 logfile,
571 flags,
572 verbosity);
573 }
574
575 inline void
576 context::dump_reproducer_to_file (const char *path)
577 {
578 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
579 path);
580 }
581
582 inline void
583 context::set_str_option (enum gcc_jit_str_option opt,
584 const char *value)
585 {
586 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
587
588 }
589
590 inline void
591 context::set_int_option (enum gcc_jit_int_option opt,
592 int value)
593 {
594 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
595
596 }
597
598 inline void
599 context::set_bool_option (enum gcc_jit_bool_option opt,
600 int value)
601 {
602 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
603
604 }
605
606 inline location
607 context::new_location (const std::string &filename,
608 int line,
609 int column)
610 {
611 return location (gcc_jit_context_new_location (m_inner_ctxt,
612 filename.c_str (),
613 line,
614 column));
615 }
616
617 inline type
618 context::get_type (enum gcc_jit_types kind)
619 {
620 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
621 }
622
623 inline type
624 context::get_int_type (size_t num_bytes, int is_signed)
625 {
626 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
627 num_bytes,
628 is_signed));
629 }
630
631 template <typename T>
632 inline type
633 context::get_int_type ()
634 {
635 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
636 }
637
638 inline type
639 context::new_array_type (type element_type, int num_elements, location loc)
640 {
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));
646 }
647
648 inline field
649 context::new_field (type type_, const std::string &name, location loc)
650 {
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 ()));
655 }
656
657 inline struct_
658 context::new_struct_type (const std::string &name,
659 std::vector<field> &fields,
660 location loc)
661 {
662 /* Treat std::vector as an array, relying on it not being resized: */
663 field *as_array_of_wrappers = &fields[0];
664
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);
669
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));
675 }
676
677 inline struct_
678 context::new_opaque_struct_type (const std::string &name,
679 location loc)
680 {
681 return struct_ (gcc_jit_context_new_opaque_struct (
682 m_inner_ctxt,
683 loc.get_inner_location (),
684 name.c_str ()));
685 }
686
687 inline param
688 context::new_param (type type_,
689 const std::string &name,
690 location loc)
691 {
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 ()));
696 }
697
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)
705 {
706 /* Treat std::vector as an array, relying on it not being resized: */
707 param *as_array_of_wrappers = &params[0];
708
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);
713
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));
722 }
723
724 inline function
725 context::get_builtin_function (const std::string &name)
726 {
727 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
728 name.c_str ()));
729 }
730
731 inline lvalue
732 context::new_global (enum gcc_jit_global_kind kind,
733 type type_,
734 const std::string &name,
735 location loc)
736 {
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 ()));
742 }
743
744 inline rvalue
745 context::new_rvalue (type numeric_type,
746 int value) const
747 {
748 return rvalue (
749 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
750 numeric_type.get_inner_type (),
751 value));
752 }
753
754 inline rvalue
755 context::new_rvalue (type numeric_type,
756 long value) const
757 {
758 return rvalue (
759 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
760 numeric_type.get_inner_type (),
761 value));
762 }
763
764 inline rvalue
765 context::zero (type numeric_type) const
766 {
767 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
768 numeric_type.get_inner_type ()));
769 }
770
771 inline rvalue
772 context::one (type numeric_type) const
773 {
774 return rvalue (gcc_jit_context_one (m_inner_ctxt,
775 numeric_type.get_inner_type ()));
776 }
777
778 inline rvalue
779 context::new_rvalue (type numeric_type,
780 double value) const
781 {
782 return rvalue (
783 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
784 numeric_type.get_inner_type (),
785 value));
786 }
787
788 inline rvalue
789 context::new_rvalue (type pointer_type,
790 void *value) const
791 {
792 return rvalue (
793 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
794 pointer_type.get_inner_type (),
795 value));
796 }
797
798 inline rvalue
799 context::new_rvalue (const std::string &value) const
800 {
801 return rvalue (
802 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
803 }
804
805 inline rvalue
806 context::new_unary_op (enum gcc_jit_unary_op op,
807 type result_type,
808 rvalue a,
809 location loc)
810 {
811 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
812 loc.get_inner_location (),
813 op,
814 result_type.get_inner_type (),
815 a.get_inner_rvalue ()));
816 }
817 inline rvalue
818 context::new_minus (type result_type,
819 rvalue a,
820 location loc)
821 {
822 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
823 result_type, a, loc));
824 }
825 inline rvalue
826 context::new_bitwise_negate (type result_type,
827 rvalue a,
828 location loc)
829 {
830 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
831 result_type, a, loc));
832 }
833 inline rvalue
834 context::new_logical_negate (type result_type,
835 rvalue a,
836 location loc)
837 {
838 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
839 result_type, a, loc));
840 }
841
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)
847 {
848 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
849 loc.get_inner_location (),
850 op,
851 result_type.get_inner_type (),
852 a.get_inner_rvalue (),
853 b.get_inner_rvalue ()));
854 }
855 inline rvalue
856 context::new_plus (type result_type,
857 rvalue a, rvalue b,
858 location loc)
859 {
860 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
861 result_type, a, b, loc);
862 }
863 inline rvalue
864 context::new_minus (type result_type,
865 rvalue a, rvalue b,
866 location loc)
867 {
868 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
869 result_type, a, b, loc);
870 }
871 inline rvalue
872 context::new_mult (type result_type,
873 rvalue a, rvalue b,
874 location loc)
875 {
876 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
877 result_type, a, b, loc);
878 }
879 inline rvalue
880 context::new_divide (type result_type,
881 rvalue a, rvalue b,
882 location loc)
883 {
884 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
885 result_type, a, b, loc);
886 }
887 inline rvalue
888 context::new_modulo (type result_type,
889 rvalue a, rvalue b,
890 location loc)
891 {
892 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
893 result_type, a, b, loc);
894 }
895 inline rvalue
896 context::new_bitwise_and (type result_type,
897 rvalue a, rvalue b,
898 location loc)
899 {
900 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
901 result_type, a, b, loc);
902 }
903 inline rvalue
904 context::new_bitwise_xor (type result_type,
905 rvalue a, rvalue b,
906 location loc)
907 {
908 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
909 result_type, a, b, loc);
910 }
911 inline rvalue
912 context::new_bitwise_or (type result_type,
913 rvalue a, rvalue b,
914 location loc)
915 {
916 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
917 result_type, a, b, loc);
918 }
919 inline rvalue
920 context::new_logical_and (type result_type,
921 rvalue a, rvalue b,
922 location loc)
923 {
924 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
925 result_type, a, b, loc);
926 }
927 inline rvalue
928 context::new_logical_or (type result_type,
929 rvalue a, rvalue b,
930 location loc)
931 {
932 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
933 result_type, a, b, loc);
934 }
935
936 inline rvalue
937 context::new_comparison (enum gcc_jit_comparison op,
938 rvalue a, rvalue b,
939 location loc)
940 {
941 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
942 loc.get_inner_location (),
943 op,
944 a.get_inner_rvalue (),
945 b.get_inner_rvalue ()));
946 }
947 inline rvalue
948 context::new_eq (rvalue a, rvalue b,
949 location loc)
950 {
951 return new_comparison (GCC_JIT_COMPARISON_EQ,
952 a, b, loc);
953 }
954 inline rvalue
955 context::new_ne (rvalue a, rvalue b,
956 location loc)
957 {
958 return new_comparison (GCC_JIT_COMPARISON_NE,
959 a, b, loc);
960 }
961 inline rvalue
962 context::new_lt (rvalue a, rvalue b,
963 location loc)
964 {
965 return new_comparison (GCC_JIT_COMPARISON_LT,
966 a, b, loc);
967 }
968 inline rvalue
969 context::new_le (rvalue a, rvalue b,
970 location loc)
971 {
972 return new_comparison (GCC_JIT_COMPARISON_LE,
973 a, b, loc);
974 }
975 inline rvalue
976 context::new_gt (rvalue a, rvalue b,
977 location loc)
978 {
979 return new_comparison (GCC_JIT_COMPARISON_GT,
980 a, b, loc);
981 }
982 inline rvalue
983 context::new_ge (rvalue a, rvalue b,
984 location loc)
985 {
986 return new_comparison (GCC_JIT_COMPARISON_GE,
987 a, b, loc);
988 }
989
990 inline rvalue
991 context::new_call (function func,
992 std::vector<rvalue> &args,
993 location loc)
994 {
995 /* Treat std::vector as an array, relying on it not being resized: */
996 rvalue *as_array_of_wrappers = &args[0];
997
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);
1007 }
1008 inline rvalue
1009 context::new_call (function func,
1010 location loc)
1011 {
1012 std::vector<rvalue> args;
1013 return new_call (func, args, loc);
1014 }
1015
1016 inline rvalue
1017 context::new_call (function func,
1018 rvalue arg0,
1019 location loc)
1020 {
1021 std::vector<rvalue> args(1);
1022 args[0] = arg0;
1023 return new_call (func, args, loc);
1024 }
1025 inline rvalue
1026 context::new_call (function func,
1027 rvalue arg0, rvalue arg1,
1028 location loc)
1029 {
1030 std::vector<rvalue> args(2);
1031 args[0] = arg0;
1032 args[1] = arg1;
1033 return new_call (func, args, loc);
1034 }
1035 inline rvalue
1036 context::new_call (function func,
1037 rvalue arg0, rvalue arg1, rvalue arg2,
1038 location loc)
1039 {
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);
1045 }
1046 inline rvalue
1047 context::new_call (function func,
1048 rvalue arg0, rvalue arg1, rvalue arg2,
1049 rvalue arg3,
1050 location loc)
1051 {
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);
1058 }
1059 inline rvalue
1060 context::new_call (function func,
1061 rvalue arg0, rvalue arg1, rvalue arg2,
1062 rvalue arg3, rvalue arg4,
1063 location loc)
1064 {
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);
1072 }
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)
1078 {
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);
1087 }
1088
1089 inline rvalue
1090 context::new_cast (rvalue expr,
1091 type type_,
1092 location loc)
1093 {
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 ()));
1098 }
1099
1100 inline lvalue
1101 context::new_array_access (rvalue ptr,
1102 rvalue index,
1103 location loc)
1104 {
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 ()));
1109 }
1110
1111 // class object
1112 inline context
1113 object::get_context () const
1114 {
1115 return context (gcc_jit_object_get_context (m_inner_obj));
1116 }
1117
1118 inline std::string
1119 object::get_debug_string () const
1120 {
1121 return gcc_jit_object_get_debug_string (m_inner_obj);
1122 }
1123
1124 inline object::object () : m_inner_obj (NULL) {}
1125 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1126 {
1127 if (!obj)
1128 throw error ();
1129 }
1130
1131 inline gcc_jit_object *
1132 object::get_inner_object () const
1133 {
1134 return m_inner_obj;
1135 }
1136
1137 inline std::ostream&
1138 operator << (std::ostream& stream, const object &obj)
1139 {
1140 return stream << obj.get_debug_string ();
1141 }
1142
1143 // class location
1144 inline location::location () : object () {}
1145 inline location::location (gcc_jit_location *loc)
1146 : object (gcc_jit_location_as_object (loc))
1147 {}
1148
1149 inline gcc_jit_location *
1150 location::get_inner_location () const
1151 {
1152 /* Manual downcast: */
1153 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1154 }
1155
1156 // class field
1157 inline field::field () : object () {}
1158 inline field::field (gcc_jit_field *inner)
1159 : object (gcc_jit_field_as_object (inner))
1160 {}
1161
1162 inline gcc_jit_field *
1163 field::get_inner_field () const
1164 {
1165 /* Manual downcast: */
1166 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1167 }
1168
1169 // class type
1170 inline type::type () : object () {}
1171 inline type::type (gcc_jit_type *inner)
1172 : object (gcc_jit_type_as_object (inner))
1173 {}
1174
1175 inline gcc_jit_type *
1176 type::get_inner_type () const
1177 {
1178 /* Manual downcast: */
1179 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1180 }
1181
1182 inline type
1183 type::get_pointer ()
1184 {
1185 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1186 }
1187
1188 inline type
1189 type::get_volatile ()
1190 {
1191 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1192 }
1193
1194 inline rvalue
1195 type::zero ()
1196 {
1197 return get_context ().new_rvalue (*this, 0);
1198 }
1199
1200 inline rvalue
1201 type::one ()
1202 {
1203 return get_context ().new_rvalue (*this, 1);
1204 }
1205
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))
1210 {
1211 }
1212
1213 inline gcc_jit_struct *
1214 struct_::get_inner_struct () const
1215 {
1216 /* Manual downcast: */
1217 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1218 }
1219
1220 // class function
1221 inline function::function () : object () {}
1222 inline function::function (gcc_jit_function *inner)
1223 : object (gcc_jit_function_as_object (inner))
1224 {}
1225
1226 inline gcc_jit_function *
1227 function::get_inner_function () const
1228 {
1229 /* Manual downcast: */
1230 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1231 }
1232
1233 inline void
1234 function::dump_to_dot (const std::string &path)
1235 {
1236 gcc_jit_function_dump_to_dot (get_inner_function (),
1237 path.c_str ());
1238 }
1239
1240 inline param
1241 function::get_param (int index) const
1242 {
1243 return param (gcc_jit_function_get_param (get_inner_function (),
1244 index));
1245 }
1246
1247 inline block
1248 function::new_block ()
1249 {
1250 return block (gcc_jit_function_new_block (get_inner_function (),
1251 NULL));
1252 }
1253
1254 inline block
1255 function::new_block (const std::string &name)
1256 {
1257 return block (gcc_jit_function_new_block (get_inner_function (),
1258 name.c_str ()));
1259 }
1260
1261 inline lvalue
1262 function::new_local (type type_,
1263 const std::string &name,
1264 location loc)
1265 {
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 ()));
1270 }
1271
1272 inline function
1273 block::get_function () const
1274 {
1275 return function (gcc_jit_block_get_function ( get_inner_block ()));
1276 }
1277
1278 inline void
1279 block::add_eval (rvalue rvalue,
1280 location loc)
1281 {
1282 gcc_jit_block_add_eval (get_inner_block (),
1283 loc.get_inner_location (),
1284 rvalue.get_inner_rvalue ());
1285 }
1286
1287 inline void
1288 block::add_assignment (lvalue lvalue,
1289 rvalue rvalue,
1290 location loc)
1291 {
1292 gcc_jit_block_add_assignment (get_inner_block (),
1293 loc.get_inner_location (),
1294 lvalue.get_inner_lvalue (),
1295 rvalue.get_inner_rvalue ());
1296 }
1297
1298 inline void
1299 block::add_assignment_op (lvalue lvalue,
1300 enum gcc_jit_binary_op op,
1301 rvalue rvalue,
1302 location loc)
1303 {
1304 gcc_jit_block_add_assignment_op (get_inner_block (),
1305 loc.get_inner_location (),
1306 lvalue.get_inner_lvalue (),
1307 op,
1308 rvalue.get_inner_rvalue ());
1309 }
1310
1311 inline void
1312 block::add_comment (const std::string &text,
1313 location loc)
1314 {
1315 gcc_jit_block_add_comment (get_inner_block (),
1316 loc.get_inner_location (),
1317 text.c_str ());
1318 }
1319
1320 inline void
1321 block::end_with_conditional (rvalue boolval,
1322 block on_true,
1323 block on_false,
1324 location loc)
1325 {
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 ());
1331 }
1332
1333 inline void
1334 block::end_with_jump (block target,
1335 location loc)
1336 {
1337 gcc_jit_block_end_with_jump (get_inner_block (),
1338 loc.get_inner_location (),
1339 target.get_inner_block ());
1340 }
1341
1342 inline void
1343 block::end_with_return (rvalue rvalue,
1344 location loc)
1345 {
1346 gcc_jit_block_end_with_return (get_inner_block (),
1347 loc.get_inner_location (),
1348 rvalue.get_inner_rvalue ());
1349 }
1350
1351 inline void
1352 block::end_with_return (location loc)
1353 {
1354 gcc_jit_block_end_with_void_return (get_inner_block (),
1355 loc.get_inner_location ());
1356 }
1357
1358 inline rvalue
1359 block::add_call (function other,
1360 location loc)
1361 {
1362 rvalue c = get_context ().new_call (other, loc);
1363 add_eval (c);
1364 return c;
1365 }
1366 inline rvalue
1367 block::add_call (function other,
1368 rvalue arg0,
1369 location loc)
1370 {
1371 rvalue c = get_context ().new_call (other, arg0, loc);
1372 add_eval (c);
1373 return c;
1374 }
1375 inline rvalue
1376 block::add_call (function other,
1377 rvalue arg0, rvalue arg1,
1378 location loc)
1379 {
1380 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1381 add_eval (c);
1382 return c;
1383 }
1384 inline rvalue
1385 block::add_call (function other,
1386 rvalue arg0, rvalue arg1, rvalue arg2,
1387 location loc)
1388 {
1389 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1390 add_eval (c);
1391 return c;
1392 }
1393
1394 inline rvalue
1395 block::add_call (function other,
1396 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1397 location loc)
1398 {
1399 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1400 add_eval (c);
1401 return c;
1402 }
1403
1404 inline rvalue
1405 function::operator() (location loc)
1406 {
1407 return get_context ().new_call (*this, loc);
1408 }
1409 inline rvalue
1410 function::operator() (rvalue arg0,
1411 location loc)
1412 {
1413 return get_context ().new_call (*this,
1414 arg0,
1415 loc);
1416 }
1417 inline rvalue
1418 function::operator() (rvalue arg0, rvalue arg1,
1419 location loc)
1420 {
1421 return get_context ().new_call (*this,
1422 arg0, arg1,
1423 loc);
1424 }
1425 inline rvalue
1426 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1427 location loc)
1428 {
1429 return get_context ().new_call (*this,
1430 arg0, arg1, arg2,
1431 loc);
1432 }
1433
1434 // class block
1435 inline block::block () : object () {}
1436 inline block::block (gcc_jit_block *inner)
1437 : object (gcc_jit_block_as_object (inner))
1438 {}
1439
1440 inline gcc_jit_block *
1441 block::get_inner_block () const
1442 {
1443 /* Manual downcast: */
1444 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1445 }
1446
1447 // class rvalue
1448 inline rvalue::rvalue () : object () {}
1449 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1450 : object (gcc_jit_rvalue_as_object (inner))
1451 {}
1452
1453 inline gcc_jit_rvalue *
1454 rvalue::get_inner_rvalue () const
1455 {
1456 /* Manual downcast: */
1457 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1458 }
1459
1460 inline type
1461 rvalue::get_type ()
1462 {
1463 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1464 }
1465
1466 inline rvalue
1467 rvalue::access_field (field field,
1468 location loc)
1469 {
1470 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1471 loc.get_inner_location (),
1472 field.get_inner_field ()));
1473 }
1474
1475 inline lvalue
1476 rvalue::dereference_field (field field,
1477 location loc)
1478 {
1479 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1480 loc.get_inner_location (),
1481 field.get_inner_field ()));
1482 }
1483
1484 inline lvalue
1485 rvalue::dereference (location loc)
1486 {
1487 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1488 loc.get_inner_location ()));
1489 }
1490
1491 inline rvalue
1492 rvalue::cast_to (type type_,
1493 location loc)
1494 {
1495 return get_context ().new_cast (*this, type_, loc);
1496 }
1497
1498 inline lvalue
1499 rvalue::operator[] (rvalue index)
1500 {
1501 return get_context ().new_array_access (*this, index);
1502 }
1503
1504 inline lvalue
1505 rvalue::operator[] (int index)
1506 {
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));
1512 }
1513
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))
1518 {}
1519
1520 inline gcc_jit_lvalue *
1521 lvalue::get_inner_lvalue () const
1522 {
1523 /* Manual downcast: */
1524 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1525 }
1526
1527 inline lvalue
1528 lvalue::access_field (field field, location loc)
1529 {
1530 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1531 loc.get_inner_location (),
1532 field.get_inner_field ()));
1533 }
1534
1535 inline rvalue
1536 lvalue::get_address (location loc)
1537 {
1538 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1539 loc.get_inner_location ()));
1540 }
1541
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))
1546 {}
1547
1548 /* Overloaded operators. */
1549 // Unary operators
1550 inline rvalue operator- (rvalue a)
1551 {
1552 return a.get_context ().new_minus (a.get_type (), a);
1553 }
1554 inline rvalue operator~ (rvalue a)
1555 {
1556 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1557 }
1558 inline rvalue operator! (rvalue a)
1559 {
1560 return a.get_context ().new_logical_negate (a.get_type (), a);
1561 }
1562
1563 // Binary operators
1564 inline rvalue operator+ (rvalue a, rvalue b)
1565 {
1566 return a.get_context ().new_plus (a.get_type (), a, b);
1567 }
1568 inline rvalue operator- (rvalue a, rvalue b)
1569 {
1570 return a.get_context ().new_minus (a.get_type (), a, b);
1571 }
1572 inline rvalue operator* (rvalue a, rvalue b)
1573 {
1574 return a.get_context ().new_mult (a.get_type (), a, b);
1575 }
1576 inline rvalue operator/ (rvalue a, rvalue b)
1577 {
1578 return a.get_context ().new_divide (a.get_type (), a, b);
1579 }
1580 inline rvalue operator% (rvalue a, rvalue b)
1581 {
1582 return a.get_context ().new_modulo (a.get_type (), a, b);
1583 }
1584 inline rvalue operator& (rvalue a, rvalue b)
1585 {
1586 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1587 }
1588 inline rvalue operator^ (rvalue a, rvalue b)
1589 {
1590 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1591 }
1592 inline rvalue operator| (rvalue a, rvalue b)
1593 {
1594 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1595 }
1596 inline rvalue operator&& (rvalue a, rvalue b)
1597 {
1598 return a.get_context ().new_logical_and (a.get_type (), a, b);
1599 }
1600 inline rvalue operator|| (rvalue a, rvalue b)
1601 {
1602 return a.get_context ().new_logical_or (a.get_type (), a, b);
1603 }
1604
1605 /* Comparisons. */
1606 inline rvalue operator== (rvalue a, rvalue b)
1607 {
1608 return a.get_context ().new_eq (a, b);
1609 }
1610 inline rvalue operator!= (rvalue a, rvalue b)
1611 {
1612 return a.get_context ().new_ne (a, b);
1613 }
1614 inline rvalue operator< (rvalue a, rvalue b)
1615 {
1616 return a.get_context ().new_lt (a, b);
1617 }
1618 inline rvalue operator<= (rvalue a, rvalue b)
1619 {
1620 return a.get_context ().new_le (a, b);
1621 }
1622 inline rvalue operator> (rvalue a, rvalue b)
1623 {
1624 return a.get_context ().new_gt (a, b);
1625 }
1626 inline rvalue operator>= (rvalue a, rvalue b)
1627 {
1628 return a.get_context ().new_ge (a, b);
1629 }
1630
1631 /* Dereferencing. */
1632 inline lvalue operator* (rvalue ptr)
1633 {
1634 return ptr.dereference ();
1635 }
1636
1637 } // namespace gccjit
1638
1639 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */