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