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