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