]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/jit/libgccjit++.h
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / jit / libgccjit++.h
1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2020 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 class case_;
49 class timer;
50 class auto_time;
51
52 namespace version {};
53
54 /* Errors within the API become C++ exceptions of this class. */
55 class error
56 {
57 };
58
59 class object
60 {
61 public:
62 context get_context () const;
63
64 std::string get_debug_string () const;
65
66 protected:
67 object ();
68 object (gcc_jit_object *obj);
69
70 gcc_jit_object *get_inner_object () const;
71
72 private:
73 gcc_jit_object *m_inner_obj;
74 };
75
76 inline std::ostream& operator << (std::ostream& stream, const object &obj);
77
78 /* Some client code will want to supply source code locations, others
79 won't. To avoid doubling the number of entrypoints, everything
80 accepting a location also has a default argument. To do this, the
81 other classes need to see that "location" has a default constructor,
82 hence we need to declare it first. */
83 class location : public object
84 {
85 public:
86 location ();
87 location (gcc_jit_location *loc);
88
89 gcc_jit_location *get_inner_location () const;
90 };
91
92 class context
93 {
94 public:
95 static context acquire ();
96 context ();
97 context (gcc_jit_context *ctxt);
98
99 gccjit::context new_child_context ();
100
101 gcc_jit_context *get_inner_context () { return m_inner_ctxt; }
102
103 void release ();
104
105 gcc_jit_result *compile ();
106
107 void compile_to_file (enum gcc_jit_output_kind output_kind,
108 const char *output_path);
109
110 void dump_to_file (const std::string &path,
111 bool update_locations);
112
113 void set_logfile (FILE *logfile,
114 int flags,
115 int verbosity);
116
117 void dump_reproducer_to_file (const char *path);
118
119 void set_str_option (enum gcc_jit_str_option opt,
120 const char *value);
121
122 void set_int_option (enum gcc_jit_int_option opt,
123 int value);
124
125 void set_bool_option (enum gcc_jit_bool_option opt,
126 int value);
127
128 void set_bool_allow_unreachable_blocks (int bool_value);
129 void set_bool_use_external_driver (int bool_value);
130
131 void add_command_line_option (const char *optname);
132 void add_driver_option (const char *optname);
133
134 void set_timer (gccjit::timer t);
135 gccjit::timer get_timer () const;
136
137 location
138 new_location (const std::string &filename,
139 int line,
140 int column);
141
142 type get_type (enum gcc_jit_types kind);
143 type get_int_type (size_t num_bytes, int is_signed);
144
145 /* A way to map a specific int type, using the compiler to
146 get the details automatically e.g.:
147 gccjit::type type = get_int_type <my_int_type_t> (); */
148 template <typename T>
149 type get_int_type ();
150
151 type new_array_type (type element_type, int num_elements,
152 location loc = location ());
153
154 field new_field (type type_, const std::string &name,
155 location loc = location ());
156
157 field new_bitfield (type type_, int width, const std::string &name,
158 location loc = location ());
159
160 struct_ new_struct_type (const std::string &name,
161 std::vector<field> &fields,
162 location loc = location ());
163
164 struct_ new_opaque_struct_type (const std::string &name,
165 location loc = location ());
166
167 param new_param (type type_,
168 const std::string &name,
169 location loc = location ());
170
171 function new_function (enum gcc_jit_function_kind kind,
172 type return_type,
173 const std::string &name,
174 std::vector<param> &params,
175 int is_variadic,
176 location loc = location ());
177
178 function get_builtin_function (const std::string &name);
179
180 lvalue new_global (enum gcc_jit_global_kind kind,
181 type type_,
182 const std::string &name,
183 location loc = location ());
184
185 rvalue new_rvalue (type numeric_type,
186 int value) const;
187 rvalue new_rvalue (type numeric_type,
188 long value) const;
189 rvalue zero (type numeric_type) const;
190 rvalue one (type numeric_type) const;
191 rvalue new_rvalue (type numeric_type,
192 double value) const;
193 rvalue new_rvalue (type pointer_type,
194 void *value) const;
195 rvalue new_rvalue (const std::string &value) const;
196 rvalue new_rvalue (type vector_type,
197 std::vector<rvalue> elements) const;
198
199 /* Generic unary operations... */
200 rvalue new_unary_op (enum gcc_jit_unary_op op,
201 type result_type,
202 rvalue a,
203 location loc = location ());
204
205 /* ...and shorter ways to spell the various specific kinds of
206 unary op. */
207 rvalue new_minus (type result_type,
208 rvalue a,
209 location loc = location ());
210 rvalue new_bitwise_negate (type result_type,
211 rvalue a,
212 location loc = location ());
213 rvalue new_logical_negate (type result_type,
214 rvalue a,
215 location loc = location ());
216
217 /* Generic binary operations... */
218 rvalue new_binary_op (enum gcc_jit_binary_op op,
219 type result_type,
220 rvalue a, rvalue b,
221 location loc = location ());
222
223 /* ...and shorter ways to spell the various specific kinds of
224 binary op. */
225 rvalue new_plus (type result_type,
226 rvalue a, rvalue b,
227 location loc = location ());
228 rvalue new_minus (type result_type,
229 rvalue a, rvalue b,
230 location loc = location ());
231 rvalue new_mult (type result_type,
232 rvalue a, rvalue b,
233 location loc = location ());
234 rvalue new_divide (type result_type,
235 rvalue a, rvalue b,
236 location loc = location ());
237 rvalue new_modulo (type result_type,
238 rvalue a, rvalue b,
239 location loc = location ());
240 rvalue new_bitwise_and (type result_type,
241 rvalue a, rvalue b,
242 location loc = location ());
243 rvalue new_bitwise_xor (type result_type,
244 rvalue a, rvalue b,
245 location loc = location ());
246 rvalue new_bitwise_or (type result_type,
247 rvalue a, rvalue b,
248 location loc = location ());
249 rvalue new_logical_and (type result_type,
250 rvalue a, rvalue b,
251 location loc = location ());
252 rvalue new_logical_or (type result_type,
253 rvalue a, rvalue b,
254 location loc = location ());
255
256 /* Generic comparisons... */
257 rvalue new_comparison (enum gcc_jit_comparison op,
258 rvalue a, rvalue b,
259 location loc = location ());
260 /* ...and shorter ways to spell the various specific kinds of
261 comparison. */
262 rvalue new_eq (rvalue a, rvalue b,
263 location loc = location ());
264 rvalue new_ne (rvalue a, rvalue b,
265 location loc = location ());
266 rvalue new_lt (rvalue a, rvalue b,
267 location loc = location ());
268 rvalue new_le (rvalue a, rvalue b,
269 location loc = location ());
270 rvalue new_gt (rvalue a, rvalue b,
271 location loc = location ());
272 rvalue new_ge (rvalue a, rvalue b,
273 location loc = location ());
274
275 /* The most general way of creating a function call. */
276 rvalue new_call (function func,
277 std::vector<rvalue> &args,
278 location loc = location ());
279
280 /* In addition, we provide a series of overloaded "new_call" methods
281 for specific numbers of args (from 0 - 6), to avoid the need for
282 client code to manually build a vector. */
283 rvalue new_call (function func,
284 location loc = location ());
285 rvalue new_call (function func,
286 rvalue arg0,
287 location loc = location ());
288 rvalue new_call (function func,
289 rvalue arg0, rvalue arg1,
290 location loc = location ());
291 rvalue new_call (function func,
292 rvalue arg0, rvalue arg1, rvalue arg2,
293 location loc = location ());
294 rvalue new_call (function func,
295 rvalue arg0, rvalue arg1, rvalue arg2,
296 rvalue arg3,
297 location loc = location ());
298 rvalue new_call (function func,
299 rvalue arg0, rvalue arg1, rvalue arg2,
300 rvalue arg3, rvalue arg4,
301 location loc = location ());
302 rvalue new_call (function func,
303 rvalue arg0, rvalue arg1, rvalue arg2,
304 rvalue arg3, rvalue arg4, rvalue arg5,
305 location loc = location ());
306
307 rvalue new_cast (rvalue expr,
308 type type_,
309 location loc = location ());
310
311 lvalue new_array_access (rvalue ptr,
312 rvalue index,
313 location loc = location ());
314
315 case_ new_case (rvalue min_value,
316 rvalue max_value,
317 block dest_block);
318
319 private:
320 gcc_jit_context *m_inner_ctxt;
321 };
322
323 class field : public object
324 {
325 public:
326 field ();
327 field (gcc_jit_field *inner);
328
329 gcc_jit_field *get_inner_field () const;
330 };
331
332 class type : public object
333 {
334 public:
335 type ();
336 type (gcc_jit_type *inner);
337
338 gcc_jit_type *get_inner_type () const;
339
340 type get_pointer ();
341 type get_const ();
342 type get_volatile ();
343 type get_aligned (size_t alignment_in_bytes);
344 type get_vector (size_t num_units);
345
346 // Shortcuts for getting values of numeric types:
347 rvalue zero ();
348 rvalue one ();
349 };
350
351 class struct_ : public type
352 {
353 public:
354 struct_ ();
355 struct_ (gcc_jit_struct *inner);
356
357 gcc_jit_struct *get_inner_struct () const;
358 };
359
360 class function : public object
361 {
362 public:
363 function ();
364 function (gcc_jit_function *func);
365
366 gcc_jit_function *get_inner_function () const;
367
368 void dump_to_dot (const std::string &path);
369
370 param get_param (int index) const;
371
372 block new_block ();
373 block new_block (const std::string &name);
374
375 lvalue new_local (type type_,
376 const std::string &name,
377 location loc = location ());
378
379 rvalue get_address (location loc = location ());
380
381 /* A series of overloaded operator () with various numbers of arguments
382 for a very terse way of creating a call to this function. The call
383 is created within the same context as the function itself, which may
384 not be what you want. */
385 rvalue operator() (location loc = location ());
386 rvalue operator() (rvalue arg0,
387 location loc = location ());
388 rvalue operator() (rvalue arg0, rvalue arg1,
389 location loc = location ());
390 rvalue operator() (rvalue arg0, rvalue arg1, rvalue arg2,
391 location loc = location ());
392 };
393
394 class block : public object
395 {
396 public:
397 block ();
398 block (gcc_jit_block *inner);
399
400 gcc_jit_block *get_inner_block () const;
401
402 function get_function () const;
403
404 void add_eval (rvalue rvalue,
405 location loc = location ());
406
407 void add_assignment (lvalue lvalue,
408 rvalue rvalue,
409 location loc = location ());
410
411 void add_assignment_op (lvalue lvalue,
412 enum gcc_jit_binary_op op,
413 rvalue rvalue,
414 location loc = location ());
415
416 /* A way to add a function call to the body of a function being
417 defined, with various numbers of args. */
418 rvalue add_call (function other,
419 location loc = location ());
420 rvalue add_call (function other,
421 rvalue arg0,
422 location loc = location ());
423 rvalue add_call (function other,
424 rvalue arg0, rvalue arg1,
425 location loc = location ());
426 rvalue add_call (function other,
427 rvalue arg0, rvalue arg1, rvalue arg2,
428 location loc = location ());
429 rvalue add_call (function other,
430 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
431 location loc = location ());
432
433 void add_comment (const std::string &text,
434 location loc = location ());
435
436 void end_with_conditional (rvalue boolval,
437 block on_true,
438 block on_false,
439 location loc = location ());
440
441 void end_with_jump (block target,
442 location loc = location ());
443
444 void end_with_return (rvalue rvalue,
445 location loc = location ());
446 void end_with_return (location loc = location ());
447
448 void end_with_switch (rvalue expr,
449 block default_block,
450 std::vector <case_> cases,
451 location loc = location ());
452 };
453
454 class rvalue : public object
455 {
456 public:
457 rvalue ();
458 rvalue (gcc_jit_rvalue *inner);
459 gcc_jit_rvalue *get_inner_rvalue () const;
460
461 type get_type ();
462
463 rvalue access_field (field field,
464 location loc = location ());
465
466 lvalue dereference_field (field field,
467 location loc = location ());
468
469 lvalue dereference (location loc = location ());
470
471 rvalue cast_to (type type_,
472 location loc = location ());
473
474 /* Array access. */
475 lvalue operator[] (rvalue index);
476 lvalue operator[] (int index);
477 };
478
479 class lvalue : public rvalue
480 {
481 public:
482 lvalue ();
483 lvalue (gcc_jit_lvalue *inner);
484
485 gcc_jit_lvalue *get_inner_lvalue () const;
486
487 lvalue access_field (field field,
488 location loc = location ());
489
490 rvalue get_address (location loc = location ());
491 };
492
493 class param : public lvalue
494 {
495 public:
496 param ();
497 param (gcc_jit_param *inner);
498
499 gcc_jit_param *get_inner_param () const;
500 };
501
502 class case_ : public object
503 {
504 public:
505 case_ ();
506 case_ (gcc_jit_case *inner);
507
508 gcc_jit_case *get_inner_case () const;
509 };
510
511 /* Overloaded operators, for those who want the most terse API
512 (at the possible risk of being a little too magical).
513
514 In each case, the first parameter is used to determine which context
515 owns the resulting expression, and, where appropriate, what the
516 latter's type is. */
517
518 /* Unary operators. */
519 rvalue operator- (rvalue a); // unary minus
520 rvalue operator~ (rvalue a); // unary bitwise negate
521 rvalue operator! (rvalue a); // unary logical negate
522
523 /* Binary operators. */
524 rvalue operator+ (rvalue a, rvalue b);
525 rvalue operator- (rvalue a, rvalue b);
526 rvalue operator* (rvalue a, rvalue b);
527 rvalue operator/ (rvalue a, rvalue b);
528 rvalue operator% (rvalue a, rvalue b);
529 rvalue operator& (rvalue a, rvalue b); // bitwise and
530 rvalue operator^ (rvalue a, rvalue b); // bitwise_xor
531 rvalue operator| (rvalue a, rvalue b); // bitwise_or
532 rvalue operator&& (rvalue a, rvalue b); // logical_and
533 rvalue operator|| (rvalue a, rvalue b); // logical_or
534
535 /* Comparisons. */
536 rvalue operator== (rvalue a, rvalue b);
537 rvalue operator!= (rvalue a, rvalue b);
538 rvalue operator< (rvalue a, rvalue b);
539 rvalue operator<= (rvalue a, rvalue b);
540 rvalue operator> (rvalue a, rvalue b);
541 rvalue operator>= (rvalue a, rvalue b);
542
543 /* Dereferencing. */
544 lvalue operator* (rvalue ptr);
545
546 class timer
547 {
548 public:
549 timer ();
550 timer (gcc_jit_timer *inner_timer);
551
552 void push (const char *item_name);
553 void pop (const char *item_name);
554 void print (FILE *f_out) const;
555
556 void release ();
557
558 gcc_jit_timer *get_inner_timer () const;
559
560 private:
561 gcc_jit_timer *m_inner_timer;
562 };
563
564 class auto_time
565 {
566 public:
567 auto_time (timer t, const char *item_name);
568 auto_time (context ctxt, const char *item_name);
569 ~auto_time ();
570
571 private:
572 timer m_timer;
573 const char *m_item_name;
574 };
575 }
576
577 /****************************************************************************
578 Implementation of the API
579 ****************************************************************************/
580 namespace gccjit {
581
582 // class context
583 inline context context::acquire ()
584 {
585 return context (gcc_jit_context_acquire ());
586 }
587 inline context::context () : m_inner_ctxt (NULL) {}
588 inline context::context (gcc_jit_context *inner) : m_inner_ctxt (inner)
589 {
590 if (!inner)
591 throw error ();
592 }
593
594 inline gccjit::context
595 context::new_child_context ()
596 {
597 return context (gcc_jit_context_new_child_context (m_inner_ctxt));
598 }
599
600 inline void
601 context::release ()
602 {
603 gcc_jit_context_release (m_inner_ctxt);
604 m_inner_ctxt = NULL;
605 }
606
607 inline gcc_jit_result *
608 context::compile ()
609 {
610 gcc_jit_result *result = gcc_jit_context_compile (m_inner_ctxt);
611 if (!result)
612 throw error ();
613 return result;
614 }
615
616 inline void
617 context::compile_to_file (enum gcc_jit_output_kind output_kind,
618 const char *output_path)
619 {
620 gcc_jit_context_compile_to_file (m_inner_ctxt,
621 output_kind,
622 output_path);
623 }
624
625 inline void
626 context::dump_to_file (const std::string &path,
627 bool update_locations)
628 {
629 gcc_jit_context_dump_to_file (m_inner_ctxt,
630 path.c_str (),
631 update_locations);
632 }
633
634 inline void
635 context::set_logfile (FILE *logfile,
636 int flags,
637 int verbosity)
638 {
639 gcc_jit_context_set_logfile (m_inner_ctxt,
640 logfile,
641 flags,
642 verbosity);
643 }
644
645 inline void
646 context::dump_reproducer_to_file (const char *path)
647 {
648 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt,
649 path);
650 }
651
652 inline void
653 context::set_str_option (enum gcc_jit_str_option opt,
654 const char *value)
655 {
656 gcc_jit_context_set_str_option (m_inner_ctxt, opt, value);
657
658 }
659
660 inline void
661 context::set_int_option (enum gcc_jit_int_option opt,
662 int value)
663 {
664 gcc_jit_context_set_int_option (m_inner_ctxt, opt, value);
665
666 }
667
668 inline void
669 context::set_bool_option (enum gcc_jit_bool_option opt,
670 int value)
671 {
672 gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
673 }
674
675 inline void
676 context::set_bool_allow_unreachable_blocks (int bool_value)
677 {
678 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
679 bool_value);
680 }
681
682 inline void
683 context::set_bool_use_external_driver (int bool_value)
684 {
685 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt,
686 bool_value);
687 }
688
689 inline void
690 context::add_command_line_option (const char *optname)
691 {
692 gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
693 }
694
695 inline void
696 context::add_driver_option (const char *optname)
697 {
698 gcc_jit_context_add_driver_option (m_inner_ctxt, optname);
699 }
700
701 inline void
702 context::set_timer (gccjit::timer t)
703 {
704 gcc_jit_context_set_timer (m_inner_ctxt, t.get_inner_timer ());
705 }
706
707 inline gccjit::timer
708 context::get_timer () const
709 {
710 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt));
711 }
712
713
714 inline location
715 context::new_location (const std::string &filename,
716 int line,
717 int column)
718 {
719 return location (gcc_jit_context_new_location (m_inner_ctxt,
720 filename.c_str (),
721 line,
722 column));
723 }
724
725 inline type
726 context::get_type (enum gcc_jit_types kind)
727 {
728 return type (gcc_jit_context_get_type (m_inner_ctxt, kind));
729 }
730
731 inline type
732 context::get_int_type (size_t num_bytes, int is_signed)
733 {
734 return type (gcc_jit_context_get_int_type (m_inner_ctxt,
735 num_bytes,
736 is_signed));
737 }
738
739 template <typename T>
740 inline type
741 context::get_int_type ()
742 {
743 return get_int_type (sizeof (T), std::numeric_limits<T>::is_signed);
744 }
745
746 inline type
747 context::new_array_type (type element_type, int num_elements, location loc)
748 {
749 return type (gcc_jit_context_new_array_type (
750 m_inner_ctxt,
751 loc.get_inner_location (),
752 element_type.get_inner_type (),
753 num_elements));
754 }
755
756 inline field
757 context::new_field (type type_, const std::string &name, location loc)
758 {
759 return field (gcc_jit_context_new_field (m_inner_ctxt,
760 loc.get_inner_location (),
761 type_.get_inner_type (),
762 name.c_str ()));
763 }
764
765 inline field
766 context::new_bitfield (type type_, int width, const std::string &name,
767 location loc)
768 {
769 return field (gcc_jit_context_new_bitfield (m_inner_ctxt,
770 loc.get_inner_location (),
771 type_.get_inner_type (),
772 width,
773 name.c_str ()));
774 }
775
776 inline struct_
777 context::new_struct_type (const std::string &name,
778 std::vector<field> &fields,
779 location loc)
780 {
781 /* Treat std::vector as an array, relying on it not being resized: */
782 field *as_array_of_wrappers = &fields[0];
783
784 /* Treat the array as being of the underlying pointers, relying on
785 the wrapper type being such a pointer internally. */
786 gcc_jit_field **as_array_of_ptrs =
787 reinterpret_cast<gcc_jit_field **> (as_array_of_wrappers);
788
789 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt,
790 loc.get_inner_location (),
791 name.c_str (),
792 fields.size (),
793 as_array_of_ptrs));
794 }
795
796 inline struct_
797 context::new_opaque_struct_type (const std::string &name,
798 location loc)
799 {
800 return struct_ (gcc_jit_context_new_opaque_struct (
801 m_inner_ctxt,
802 loc.get_inner_location (),
803 name.c_str ()));
804 }
805
806 inline param
807 context::new_param (type type_,
808 const std::string &name,
809 location loc)
810 {
811 return param (gcc_jit_context_new_param (m_inner_ctxt,
812 loc.get_inner_location (),
813 type_.get_inner_type (),
814 name.c_str ()));
815 }
816
817 inline function
818 context::new_function (enum gcc_jit_function_kind kind,
819 type return_type,
820 const std::string &name,
821 std::vector<param> &params,
822 int is_variadic,
823 location loc)
824 {
825 /* Treat std::vector as an array, relying on it not being resized: */
826 param *as_array_of_wrappers = &params[0];
827
828 /* Treat the array as being of the underlying pointers, relying on
829 the wrapper type being such a pointer internally. */
830 gcc_jit_param **as_array_of_ptrs =
831 reinterpret_cast<gcc_jit_param **> (as_array_of_wrappers);
832
833 return function (gcc_jit_context_new_function (m_inner_ctxt,
834 loc.get_inner_location (),
835 kind,
836 return_type.get_inner_type (),
837 name.c_str (),
838 params.size (),
839 as_array_of_ptrs,
840 is_variadic));
841 }
842
843 inline function
844 context::get_builtin_function (const std::string &name)
845 {
846 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt,
847 name.c_str ()));
848 }
849
850 inline lvalue
851 context::new_global (enum gcc_jit_global_kind kind,
852 type type_,
853 const std::string &name,
854 location loc)
855 {
856 return lvalue (gcc_jit_context_new_global (m_inner_ctxt,
857 loc.get_inner_location (),
858 kind,
859 type_.get_inner_type (),
860 name.c_str ()));
861 }
862
863 inline rvalue
864 context::new_rvalue (type numeric_type,
865 int value) const
866 {
867 return rvalue (
868 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt,
869 numeric_type.get_inner_type (),
870 value));
871 }
872
873 inline rvalue
874 context::new_rvalue (type numeric_type,
875 long value) const
876 {
877 return rvalue (
878 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt,
879 numeric_type.get_inner_type (),
880 value));
881 }
882
883 inline rvalue
884 context::zero (type numeric_type) const
885 {
886 return rvalue (gcc_jit_context_zero (m_inner_ctxt,
887 numeric_type.get_inner_type ()));
888 }
889
890 inline rvalue
891 context::one (type numeric_type) const
892 {
893 return rvalue (gcc_jit_context_one (m_inner_ctxt,
894 numeric_type.get_inner_type ()));
895 }
896
897 inline rvalue
898 context::new_rvalue (type numeric_type,
899 double value) const
900 {
901 return rvalue (
902 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt,
903 numeric_type.get_inner_type (),
904 value));
905 }
906
907 inline rvalue
908 context::new_rvalue (type pointer_type,
909 void *value) const
910 {
911 return rvalue (
912 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt,
913 pointer_type.get_inner_type (),
914 value));
915 }
916
917 inline rvalue
918 context::new_rvalue (const std::string &value) const
919 {
920 return rvalue (
921 gcc_jit_context_new_string_literal (m_inner_ctxt, value.c_str ()));
922 }
923
924 inline rvalue
925 context::new_rvalue (type vector_type,
926 std::vector<rvalue> elements) const
927 {
928 /* Treat std::vector as an array, relying on it not being resized: */
929 rvalue *as_array_of_wrappers = &elements[0];
930
931 /* Treat the array as being of the underlying pointers, relying on
932 the wrapper type being such a pointer internally. */
933 gcc_jit_rvalue **as_array_of_ptrs =
934 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
935
936 return rvalue (
937 gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt,
938 NULL,
939 vector_type.get_inner_type (),
940 elements.size (),
941 as_array_of_ptrs));
942 }
943
944 inline rvalue
945 context::new_unary_op (enum gcc_jit_unary_op op,
946 type result_type,
947 rvalue a,
948 location loc)
949 {
950 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt,
951 loc.get_inner_location (),
952 op,
953 result_type.get_inner_type (),
954 a.get_inner_rvalue ()));
955 }
956 inline rvalue
957 context::new_minus (type result_type,
958 rvalue a,
959 location loc)
960 {
961 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS,
962 result_type, a, loc));
963 }
964 inline rvalue
965 context::new_bitwise_negate (type result_type,
966 rvalue a,
967 location loc)
968 {
969 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE,
970 result_type, a, loc));
971 }
972 inline rvalue
973 context::new_logical_negate (type result_type,
974 rvalue a,
975 location loc)
976 {
977 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
978 result_type, a, loc));
979 }
980
981 inline rvalue
982 context::new_binary_op (enum gcc_jit_binary_op op,
983 type result_type,
984 rvalue a, rvalue b,
985 location loc)
986 {
987 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt,
988 loc.get_inner_location (),
989 op,
990 result_type.get_inner_type (),
991 a.get_inner_rvalue (),
992 b.get_inner_rvalue ()));
993 }
994 inline rvalue
995 context::new_plus (type result_type,
996 rvalue a, rvalue b,
997 location loc)
998 {
999 return new_binary_op (GCC_JIT_BINARY_OP_PLUS,
1000 result_type, a, b, loc);
1001 }
1002 inline rvalue
1003 context::new_minus (type result_type,
1004 rvalue a, rvalue b,
1005 location loc)
1006 {
1007 return new_binary_op (GCC_JIT_BINARY_OP_MINUS,
1008 result_type, a, b, loc);
1009 }
1010 inline rvalue
1011 context::new_mult (type result_type,
1012 rvalue a, rvalue b,
1013 location loc)
1014 {
1015 return new_binary_op (GCC_JIT_BINARY_OP_MULT,
1016 result_type, a, b, loc);
1017 }
1018 inline rvalue
1019 context::new_divide (type result_type,
1020 rvalue a, rvalue b,
1021 location loc)
1022 {
1023 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE,
1024 result_type, a, b, loc);
1025 }
1026 inline rvalue
1027 context::new_modulo (type result_type,
1028 rvalue a, rvalue b,
1029 location loc)
1030 {
1031 return new_binary_op (GCC_JIT_BINARY_OP_MODULO,
1032 result_type, a, b, loc);
1033 }
1034 inline rvalue
1035 context::new_bitwise_and (type result_type,
1036 rvalue a, rvalue b,
1037 location loc)
1038 {
1039 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND,
1040 result_type, a, b, loc);
1041 }
1042 inline rvalue
1043 context::new_bitwise_xor (type result_type,
1044 rvalue a, rvalue b,
1045 location loc)
1046 {
1047 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR,
1048 result_type, a, b, loc);
1049 }
1050 inline rvalue
1051 context::new_bitwise_or (type result_type,
1052 rvalue a, rvalue b,
1053 location loc)
1054 {
1055 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR,
1056 result_type, a, b, loc);
1057 }
1058 inline rvalue
1059 context::new_logical_and (type result_type,
1060 rvalue a, rvalue b,
1061 location loc)
1062 {
1063 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND,
1064 result_type, a, b, loc);
1065 }
1066 inline rvalue
1067 context::new_logical_or (type result_type,
1068 rvalue a, rvalue b,
1069 location loc)
1070 {
1071 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR,
1072 result_type, a, b, loc);
1073 }
1074
1075 inline rvalue
1076 context::new_comparison (enum gcc_jit_comparison op,
1077 rvalue a, rvalue b,
1078 location loc)
1079 {
1080 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt,
1081 loc.get_inner_location (),
1082 op,
1083 a.get_inner_rvalue (),
1084 b.get_inner_rvalue ()));
1085 }
1086 inline rvalue
1087 context::new_eq (rvalue a, rvalue b,
1088 location loc)
1089 {
1090 return new_comparison (GCC_JIT_COMPARISON_EQ,
1091 a, b, loc);
1092 }
1093 inline rvalue
1094 context::new_ne (rvalue a, rvalue b,
1095 location loc)
1096 {
1097 return new_comparison (GCC_JIT_COMPARISON_NE,
1098 a, b, loc);
1099 }
1100 inline rvalue
1101 context::new_lt (rvalue a, rvalue b,
1102 location loc)
1103 {
1104 return new_comparison (GCC_JIT_COMPARISON_LT,
1105 a, b, loc);
1106 }
1107 inline rvalue
1108 context::new_le (rvalue a, rvalue b,
1109 location loc)
1110 {
1111 return new_comparison (GCC_JIT_COMPARISON_LE,
1112 a, b, loc);
1113 }
1114 inline rvalue
1115 context::new_gt (rvalue a, rvalue b,
1116 location loc)
1117 {
1118 return new_comparison (GCC_JIT_COMPARISON_GT,
1119 a, b, loc);
1120 }
1121 inline rvalue
1122 context::new_ge (rvalue a, rvalue b,
1123 location loc)
1124 {
1125 return new_comparison (GCC_JIT_COMPARISON_GE,
1126 a, b, loc);
1127 }
1128
1129 inline rvalue
1130 context::new_call (function func,
1131 std::vector<rvalue> &args,
1132 location loc)
1133 {
1134 /* Treat std::vector as an array, relying on it not being resized: */
1135 rvalue *as_array_of_wrappers = &args[0];
1136
1137 /* Treat the array as being of the underlying pointers, relying on
1138 the wrapper type being such a pointer internally. */
1139 gcc_jit_rvalue **as_array_of_ptrs =
1140 reinterpret_cast<gcc_jit_rvalue **> (as_array_of_wrappers);
1141 return gcc_jit_context_new_call (m_inner_ctxt,
1142 loc.get_inner_location (),
1143 func.get_inner_function (),
1144 args.size (),
1145 as_array_of_ptrs);
1146 }
1147 inline rvalue
1148 context::new_call (function func,
1149 location loc)
1150 {
1151 std::vector<rvalue> args;
1152 return new_call (func, args, loc);
1153 }
1154
1155 inline rvalue
1156 context::new_call (function func,
1157 rvalue arg0,
1158 location loc)
1159 {
1160 std::vector<rvalue> args(1);
1161 args[0] = arg0;
1162 return new_call (func, args, loc);
1163 }
1164 inline rvalue
1165 context::new_call (function func,
1166 rvalue arg0, rvalue arg1,
1167 location loc)
1168 {
1169 std::vector<rvalue> args(2);
1170 args[0] = arg0;
1171 args[1] = arg1;
1172 return new_call (func, args, loc);
1173 }
1174 inline rvalue
1175 context::new_call (function func,
1176 rvalue arg0, rvalue arg1, rvalue arg2,
1177 location loc)
1178 {
1179 std::vector<rvalue> args(3);
1180 args[0] = arg0;
1181 args[1] = arg1;
1182 args[2] = arg2;
1183 return new_call (func, args, loc);
1184 }
1185 inline rvalue
1186 context::new_call (function func,
1187 rvalue arg0, rvalue arg1, rvalue arg2,
1188 rvalue arg3,
1189 location loc)
1190 {
1191 std::vector<rvalue> args(4);
1192 args[0] = arg0;
1193 args[1] = arg1;
1194 args[2] = arg2;
1195 args[3] = arg3;
1196 return new_call (func, args, loc);
1197 }
1198 inline rvalue
1199 context::new_call (function func,
1200 rvalue arg0, rvalue arg1, rvalue arg2,
1201 rvalue arg3, rvalue arg4,
1202 location loc)
1203 {
1204 std::vector<rvalue> args(5);
1205 args[0] = arg0;
1206 args[1] = arg1;
1207 args[2] = arg2;
1208 args[3] = arg3;
1209 args[4] = arg4;
1210 return new_call (func, args, loc);
1211 }
1212 inline rvalue
1213 context::new_call (function func,
1214 rvalue arg0, rvalue arg1, rvalue arg2,
1215 rvalue arg3, rvalue arg4, rvalue arg5,
1216 location loc)
1217 {
1218 std::vector<rvalue> args(6);
1219 args[0] = arg0;
1220 args[1] = arg1;
1221 args[2] = arg2;
1222 args[3] = arg3;
1223 args[4] = arg4;
1224 args[5] = arg5;
1225 return new_call (func, args, loc);
1226 }
1227
1228 inline rvalue
1229 context::new_cast (rvalue expr,
1230 type type_,
1231 location loc)
1232 {
1233 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt,
1234 loc.get_inner_location (),
1235 expr.get_inner_rvalue (),
1236 type_.get_inner_type ()));
1237 }
1238
1239 inline lvalue
1240 context::new_array_access (rvalue ptr,
1241 rvalue index,
1242 location loc)
1243 {
1244 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt,
1245 loc.get_inner_location (),
1246 ptr.get_inner_rvalue (),
1247 index.get_inner_rvalue ()));
1248 }
1249
1250 inline case_
1251 context::new_case (rvalue min_value,
1252 rvalue max_value,
1253 block dest_block)
1254 {
1255 return case_ (gcc_jit_context_new_case (m_inner_ctxt,
1256 min_value.get_inner_rvalue (),
1257 max_value.get_inner_rvalue (),
1258 dest_block.get_inner_block ()));
1259 }
1260
1261 // class object
1262 inline context
1263 object::get_context () const
1264 {
1265 return context (gcc_jit_object_get_context (m_inner_obj));
1266 }
1267
1268 inline std::string
1269 object::get_debug_string () const
1270 {
1271 return gcc_jit_object_get_debug_string (m_inner_obj);
1272 }
1273
1274 inline object::object () : m_inner_obj (NULL) {}
1275 inline object::object (gcc_jit_object *obj) : m_inner_obj (obj)
1276 {
1277 if (!obj)
1278 throw error ();
1279 }
1280
1281 inline gcc_jit_object *
1282 object::get_inner_object () const
1283 {
1284 return m_inner_obj;
1285 }
1286
1287 inline std::ostream&
1288 operator << (std::ostream& stream, const object &obj)
1289 {
1290 return stream << obj.get_debug_string ();
1291 }
1292
1293 // class location
1294 inline location::location () : object () {}
1295 inline location::location (gcc_jit_location *loc)
1296 : object (gcc_jit_location_as_object (loc))
1297 {}
1298
1299 inline gcc_jit_location *
1300 location::get_inner_location () const
1301 {
1302 /* Manual downcast: */
1303 return reinterpret_cast<gcc_jit_location *> (get_inner_object ());
1304 }
1305
1306 // class field
1307 inline field::field () : object () {}
1308 inline field::field (gcc_jit_field *inner)
1309 : object (gcc_jit_field_as_object (inner))
1310 {}
1311
1312 inline gcc_jit_field *
1313 field::get_inner_field () const
1314 {
1315 /* Manual downcast: */
1316 return reinterpret_cast<gcc_jit_field *> (get_inner_object ());
1317 }
1318
1319 // class type
1320 inline type::type () : object () {}
1321 inline type::type (gcc_jit_type *inner)
1322 : object (gcc_jit_type_as_object (inner))
1323 {}
1324
1325 inline gcc_jit_type *
1326 type::get_inner_type () const
1327 {
1328 /* Manual downcast: */
1329 return reinterpret_cast<gcc_jit_type *> (get_inner_object ());
1330 }
1331
1332 inline type
1333 type::get_pointer ()
1334 {
1335 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1336 }
1337
1338 inline type
1339 type::get_const ()
1340 {
1341 return type (gcc_jit_type_get_const (get_inner_type ()));
1342 }
1343
1344 inline type
1345 type::get_volatile ()
1346 {
1347 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1348 }
1349
1350 inline type
1351 type::get_aligned (size_t alignment_in_bytes)
1352 {
1353 return type (gcc_jit_type_get_aligned (get_inner_type (),
1354 alignment_in_bytes));
1355 }
1356
1357 inline type
1358 type::get_vector (size_t num_units)
1359 {
1360 return type (gcc_jit_type_get_vector (get_inner_type (),
1361 num_units));
1362 }
1363
1364 inline rvalue
1365 type::zero ()
1366 {
1367 return get_context ().new_rvalue (*this, 0);
1368 }
1369
1370 inline rvalue
1371 type::one ()
1372 {
1373 return get_context ().new_rvalue (*this, 1);
1374 }
1375
1376 // class struct_
1377 inline struct_::struct_ () : type (NULL) {}
1378 inline struct_::struct_ (gcc_jit_struct *inner) :
1379 type (gcc_jit_struct_as_type (inner))
1380 {
1381 }
1382
1383 inline gcc_jit_struct *
1384 struct_::get_inner_struct () const
1385 {
1386 /* Manual downcast: */
1387 return reinterpret_cast<gcc_jit_struct *> (get_inner_object ());
1388 }
1389
1390 // class function
1391 inline function::function () : object () {}
1392 inline function::function (gcc_jit_function *inner)
1393 : object (gcc_jit_function_as_object (inner))
1394 {}
1395
1396 inline gcc_jit_function *
1397 function::get_inner_function () const
1398 {
1399 /* Manual downcast: */
1400 return reinterpret_cast<gcc_jit_function *> (get_inner_object ());
1401 }
1402
1403 inline void
1404 function::dump_to_dot (const std::string &path)
1405 {
1406 gcc_jit_function_dump_to_dot (get_inner_function (),
1407 path.c_str ());
1408 }
1409
1410 inline param
1411 function::get_param (int index) const
1412 {
1413 return param (gcc_jit_function_get_param (get_inner_function (),
1414 index));
1415 }
1416
1417 inline block
1418 function::new_block ()
1419 {
1420 return block (gcc_jit_function_new_block (get_inner_function (),
1421 NULL));
1422 }
1423
1424 inline block
1425 function::new_block (const std::string &name)
1426 {
1427 return block (gcc_jit_function_new_block (get_inner_function (),
1428 name.c_str ()));
1429 }
1430
1431 inline lvalue
1432 function::new_local (type type_,
1433 const std::string &name,
1434 location loc)
1435 {
1436 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1437 loc.get_inner_location (),
1438 type_.get_inner_type (),
1439 name.c_str ()));
1440 }
1441
1442 inline rvalue
1443 function::get_address (location loc)
1444 {
1445 return rvalue (gcc_jit_function_get_address (get_inner_function (),
1446 loc.get_inner_location ()));
1447 }
1448
1449 inline function
1450 block::get_function () const
1451 {
1452 return function (gcc_jit_block_get_function ( get_inner_block ()));
1453 }
1454
1455 inline void
1456 block::add_eval (rvalue rvalue,
1457 location loc)
1458 {
1459 gcc_jit_block_add_eval (get_inner_block (),
1460 loc.get_inner_location (),
1461 rvalue.get_inner_rvalue ());
1462 }
1463
1464 inline void
1465 block::add_assignment (lvalue lvalue,
1466 rvalue rvalue,
1467 location loc)
1468 {
1469 gcc_jit_block_add_assignment (get_inner_block (),
1470 loc.get_inner_location (),
1471 lvalue.get_inner_lvalue (),
1472 rvalue.get_inner_rvalue ());
1473 }
1474
1475 inline void
1476 block::add_assignment_op (lvalue lvalue,
1477 enum gcc_jit_binary_op op,
1478 rvalue rvalue,
1479 location loc)
1480 {
1481 gcc_jit_block_add_assignment_op (get_inner_block (),
1482 loc.get_inner_location (),
1483 lvalue.get_inner_lvalue (),
1484 op,
1485 rvalue.get_inner_rvalue ());
1486 }
1487
1488 inline void
1489 block::add_comment (const std::string &text,
1490 location loc)
1491 {
1492 gcc_jit_block_add_comment (get_inner_block (),
1493 loc.get_inner_location (),
1494 text.c_str ());
1495 }
1496
1497 inline void
1498 block::end_with_conditional (rvalue boolval,
1499 block on_true,
1500 block on_false,
1501 location loc)
1502 {
1503 gcc_jit_block_end_with_conditional (get_inner_block (),
1504 loc.get_inner_location (),
1505 boolval.get_inner_rvalue (),
1506 on_true.get_inner_block (),
1507 on_false.get_inner_block ());
1508 }
1509
1510 inline void
1511 block::end_with_jump (block target,
1512 location loc)
1513 {
1514 gcc_jit_block_end_with_jump (get_inner_block (),
1515 loc.get_inner_location (),
1516 target.get_inner_block ());
1517 }
1518
1519 inline void
1520 block::end_with_return (rvalue rvalue,
1521 location loc)
1522 {
1523 gcc_jit_block_end_with_return (get_inner_block (),
1524 loc.get_inner_location (),
1525 rvalue.get_inner_rvalue ());
1526 }
1527
1528 inline void
1529 block::end_with_return (location loc)
1530 {
1531 gcc_jit_block_end_with_void_return (get_inner_block (),
1532 loc.get_inner_location ());
1533 }
1534
1535 inline void
1536 block::end_with_switch (rvalue expr,
1537 block default_block,
1538 std::vector <case_> cases,
1539 location loc)
1540 {
1541 /* Treat std::vector as an array, relying on it not being resized: */
1542 case_ *as_array_of_wrappers = &cases[0];
1543
1544 /* Treat the array as being of the underlying pointers, relying on
1545 the wrapper type being such a pointer internally. */
1546 gcc_jit_case **as_array_of_ptrs =
1547 reinterpret_cast<gcc_jit_case **> (as_array_of_wrappers);
1548 gcc_jit_block_end_with_switch (get_inner_block (),
1549 loc.get_inner_location (),
1550 expr.get_inner_rvalue (),
1551 default_block.get_inner_block (),
1552 cases.size (),
1553 as_array_of_ptrs);
1554 }
1555
1556 inline rvalue
1557 block::add_call (function other,
1558 location loc)
1559 {
1560 rvalue c = get_context ().new_call (other, loc);
1561 add_eval (c);
1562 return c;
1563 }
1564 inline rvalue
1565 block::add_call (function other,
1566 rvalue arg0,
1567 location loc)
1568 {
1569 rvalue c = get_context ().new_call (other, arg0, loc);
1570 add_eval (c);
1571 return c;
1572 }
1573 inline rvalue
1574 block::add_call (function other,
1575 rvalue arg0, rvalue arg1,
1576 location loc)
1577 {
1578 rvalue c = get_context ().new_call (other, arg0, arg1, loc);
1579 add_eval (c);
1580 return c;
1581 }
1582 inline rvalue
1583 block::add_call (function other,
1584 rvalue arg0, rvalue arg1, rvalue arg2,
1585 location loc)
1586 {
1587 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, loc);
1588 add_eval (c);
1589 return c;
1590 }
1591
1592 inline rvalue
1593 block::add_call (function other,
1594 rvalue arg0, rvalue arg1, rvalue arg2, rvalue arg3,
1595 location loc)
1596 {
1597 rvalue c = get_context ().new_call (other, arg0, arg1, arg2, arg3, loc);
1598 add_eval (c);
1599 return c;
1600 }
1601
1602 inline rvalue
1603 function::operator() (location loc)
1604 {
1605 return get_context ().new_call (*this, loc);
1606 }
1607 inline rvalue
1608 function::operator() (rvalue arg0,
1609 location loc)
1610 {
1611 return get_context ().new_call (*this,
1612 arg0,
1613 loc);
1614 }
1615 inline rvalue
1616 function::operator() (rvalue arg0, rvalue arg1,
1617 location loc)
1618 {
1619 return get_context ().new_call (*this,
1620 arg0, arg1,
1621 loc);
1622 }
1623 inline rvalue
1624 function::operator() (rvalue arg0, rvalue arg1, rvalue arg2,
1625 location loc)
1626 {
1627 return get_context ().new_call (*this,
1628 arg0, arg1, arg2,
1629 loc);
1630 }
1631
1632 // class block
1633 inline block::block () : object () {}
1634 inline block::block (gcc_jit_block *inner)
1635 : object (gcc_jit_block_as_object (inner))
1636 {}
1637
1638 inline gcc_jit_block *
1639 block::get_inner_block () const
1640 {
1641 /* Manual downcast: */
1642 return reinterpret_cast<gcc_jit_block *> (get_inner_object ());
1643 }
1644
1645 // class rvalue
1646 inline rvalue::rvalue () : object () {}
1647 inline rvalue::rvalue (gcc_jit_rvalue *inner)
1648 : object (gcc_jit_rvalue_as_object (inner))
1649 {}
1650
1651 inline gcc_jit_rvalue *
1652 rvalue::get_inner_rvalue () const
1653 {
1654 /* Manual downcast: */
1655 return reinterpret_cast<gcc_jit_rvalue *> (get_inner_object ());
1656 }
1657
1658 inline type
1659 rvalue::get_type ()
1660 {
1661 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1662 }
1663
1664 inline rvalue
1665 rvalue::access_field (field field,
1666 location loc)
1667 {
1668 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1669 loc.get_inner_location (),
1670 field.get_inner_field ()));
1671 }
1672
1673 inline lvalue
1674 rvalue::dereference_field (field field,
1675 location loc)
1676 {
1677 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1678 loc.get_inner_location (),
1679 field.get_inner_field ()));
1680 }
1681
1682 inline lvalue
1683 rvalue::dereference (location loc)
1684 {
1685 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1686 loc.get_inner_location ()));
1687 }
1688
1689 inline rvalue
1690 rvalue::cast_to (type type_,
1691 location loc)
1692 {
1693 return get_context ().new_cast (*this, type_, loc);
1694 }
1695
1696 inline lvalue
1697 rvalue::operator[] (rvalue index)
1698 {
1699 return get_context ().new_array_access (*this, index);
1700 }
1701
1702 inline lvalue
1703 rvalue::operator[] (int index)
1704 {
1705 context ctxt = get_context ();
1706 type int_t = ctxt.get_int_type <int> ();
1707 return ctxt.new_array_access (*this,
1708 ctxt.new_rvalue (int_t,
1709 index));
1710 }
1711
1712 // class lvalue : public rvalue
1713 inline lvalue::lvalue () : rvalue () {}
1714 inline lvalue::lvalue (gcc_jit_lvalue *inner)
1715 : rvalue (gcc_jit_lvalue_as_rvalue (inner))
1716 {}
1717
1718 inline gcc_jit_lvalue *
1719 lvalue::get_inner_lvalue () const
1720 {
1721 /* Manual downcast: */
1722 return reinterpret_cast<gcc_jit_lvalue *> (get_inner_object ());
1723 }
1724
1725 inline lvalue
1726 lvalue::access_field (field field, location loc)
1727 {
1728 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1729 loc.get_inner_location (),
1730 field.get_inner_field ()));
1731 }
1732
1733 inline rvalue
1734 lvalue::get_address (location loc)
1735 {
1736 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1737 loc.get_inner_location ()));
1738 }
1739
1740 // class param : public lvalue
1741 inline param::param () : lvalue () {}
1742 inline param::param (gcc_jit_param *inner)
1743 : lvalue (gcc_jit_param_as_lvalue (inner))
1744 {}
1745
1746 // class case_ : public object
1747 inline case_::case_ () : object () {}
1748 inline case_::case_ (gcc_jit_case *inner)
1749 : object (gcc_jit_case_as_object (inner))
1750 {
1751 }
1752
1753 inline gcc_jit_case *
1754 case_::get_inner_case () const
1755 {
1756 /* Manual downcast: */
1757 return reinterpret_cast<gcc_jit_case *> (get_inner_object ());
1758 }
1759
1760 /* Overloaded operators. */
1761 // Unary operators
1762 inline rvalue operator- (rvalue a)
1763 {
1764 return a.get_context ().new_minus (a.get_type (), a);
1765 }
1766 inline rvalue operator~ (rvalue a)
1767 {
1768 return a.get_context ().new_bitwise_negate (a.get_type (), a);
1769 }
1770 inline rvalue operator! (rvalue a)
1771 {
1772 return a.get_context ().new_logical_negate (a.get_type (), a);
1773 }
1774
1775 // Binary operators
1776 inline rvalue operator+ (rvalue a, rvalue b)
1777 {
1778 return a.get_context ().new_plus (a.get_type (), a, b);
1779 }
1780 inline rvalue operator- (rvalue a, rvalue b)
1781 {
1782 return a.get_context ().new_minus (a.get_type (), a, b);
1783 }
1784 inline rvalue operator* (rvalue a, rvalue b)
1785 {
1786 return a.get_context ().new_mult (a.get_type (), a, b);
1787 }
1788 inline rvalue operator/ (rvalue a, rvalue b)
1789 {
1790 return a.get_context ().new_divide (a.get_type (), a, b);
1791 }
1792 inline rvalue operator% (rvalue a, rvalue b)
1793 {
1794 return a.get_context ().new_modulo (a.get_type (), a, b);
1795 }
1796 inline rvalue operator& (rvalue a, rvalue b)
1797 {
1798 return a.get_context ().new_bitwise_and (a.get_type (), a, b);
1799 }
1800 inline rvalue operator^ (rvalue a, rvalue b)
1801 {
1802 return a.get_context ().new_bitwise_xor (a.get_type (), a, b);
1803 }
1804 inline rvalue operator| (rvalue a, rvalue b)
1805 {
1806 return a.get_context ().new_bitwise_or (a.get_type (), a, b);
1807 }
1808 inline rvalue operator&& (rvalue a, rvalue b)
1809 {
1810 return a.get_context ().new_logical_and (a.get_type (), a, b);
1811 }
1812 inline rvalue operator|| (rvalue a, rvalue b)
1813 {
1814 return a.get_context ().new_logical_or (a.get_type (), a, b);
1815 }
1816
1817 /* Comparisons. */
1818 inline rvalue operator== (rvalue a, rvalue b)
1819 {
1820 return a.get_context ().new_eq (a, b);
1821 }
1822 inline rvalue operator!= (rvalue a, rvalue b)
1823 {
1824 return a.get_context ().new_ne (a, b);
1825 }
1826 inline rvalue operator< (rvalue a, rvalue b)
1827 {
1828 return a.get_context ().new_lt (a, b);
1829 }
1830 inline rvalue operator<= (rvalue a, rvalue b)
1831 {
1832 return a.get_context ().new_le (a, b);
1833 }
1834 inline rvalue operator> (rvalue a, rvalue b)
1835 {
1836 return a.get_context ().new_gt (a, b);
1837 }
1838 inline rvalue operator>= (rvalue a, rvalue b)
1839 {
1840 return a.get_context ().new_ge (a, b);
1841 }
1842
1843 /* Dereferencing. */
1844 inline lvalue operator* (rvalue ptr)
1845 {
1846 return ptr.dereference ();
1847 }
1848
1849 // class timer
1850 inline
1851 timer::timer ()
1852 {
1853 m_inner_timer = gcc_jit_timer_new ();
1854 }
1855
1856 inline
1857 timer::timer (gcc_jit_timer *inner_timer)
1858 {
1859 m_inner_timer = inner_timer;
1860 }
1861
1862 inline void
1863 timer::push (const char *item_name)
1864 {
1865 gcc_jit_timer_push (m_inner_timer, item_name);
1866
1867 }
1868
1869 inline void
1870 timer::pop (const char *item_name)
1871 {
1872 gcc_jit_timer_pop (m_inner_timer, item_name);
1873 }
1874
1875 inline void
1876 timer::print (FILE *f_out) const
1877 {
1878 gcc_jit_timer_print (m_inner_timer, f_out);
1879 }
1880
1881 inline gcc_jit_timer *
1882 timer::get_inner_timer () const
1883 {
1884 return m_inner_timer;
1885 }
1886
1887 inline void
1888 timer::release ()
1889 {
1890 gcc_jit_timer_release (m_inner_timer);
1891 m_inner_timer = NULL;
1892 }
1893
1894 // class auto_time
1895
1896 inline
1897 auto_time::auto_time (timer t, const char *item_name)
1898 : m_timer (t),
1899 m_item_name (item_name)
1900 {
1901 t.push (item_name);
1902 }
1903
1904 inline
1905 auto_time::auto_time (context ctxt, const char *item_name)
1906 : m_timer (ctxt.get_timer ()),
1907 m_item_name (item_name)
1908 {
1909 m_timer.push (item_name);
1910 }
1911
1912 inline
1913 auto_time::~auto_time ()
1914 {
1915 m_timer.pop (m_item_name);
1916 }
1917
1918 namespace version
1919 {
1920 inline int
1921 major_v ()
1922 {
1923 return gcc_jit_version_major ();
1924 }
1925
1926 inline int
1927 minor_v ()
1928 {
1929 return gcc_jit_version_minor ();
1930 }
1931
1932 inline int
1933 patchlevel_v ()
1934 {
1935 return gcc_jit_version_patchlevel ();
1936 }
1937 } // namespace version
1938 } // namespace gccjit
1939
1940 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */