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