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