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