1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2021 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #ifndef JIT_RECORDING_H
22 #define JIT_RECORDING_H
23
24 #include "jit-common.h"
25 #include "jit-logging.h"
26
27 class timer;
28
29 namespace gcc {
30
31 namespace jit {
32
33 extern const char * const unary_op_reproducer_strings[];
34 extern const char * const binary_op_reproducer_strings[];
35
36 class result;
37 class dump;
38 class reproducer;
39
40 /**********************************************************************
41 Recording.
42 **********************************************************************/
43
44 namespace recording {
45
46 playback::location *
47 playback_location (replayer *r, location *loc);
48
49 const char *
50 playback_string (string *str);
51
52 playback::block *
53 playback_block (block *b);
54
55 /* A recording of a call to gcc_jit_context_enable_dump. */
56 struct requested_dump
57 {
58 const char *m_dumpname;
59 char **m_out_ptr;
60 };
61
62 /* A JIT-compilation context. */
63 class context : public log_user
64 {
65 public:
66 context (context *parent_ctxt);
67 ~context ();
68
69 builtins_manager *
70 get_builtins_manager ();
71
72 void record (memento *m);
73 void replay_into (replayer *r);
74 void disassociate_from_playback ();
75
76 string *
77 new_string (const char *text, bool escaped = false);
78
79 location *
80 new_location (const char *filename,
81 int line,
82 int column,
83 bool created_by_user);
84
85 type *
86 get_type (enum gcc_jit_types type);
87
88 type *
89 get_int_type (int num_bytes, int is_signed);
90
91 type *
92 new_array_type (location *loc,
93 type *element_type,
94 int num_elements);
95
96 field *
97 new_field (location *loc,
98 type *type,
99 const char *name);
100
101 field *
102 new_bitfield (location *loc,
103 type *type,
104 int width,
105 const char *name);
106
107 struct_ *
108 new_struct_type (location *loc,
109 const char *name);
110
111 union_ *
112 new_union_type (location *loc,
113 const char *name);
114
115 function_type *
116 new_function_type (type *return_type,
117 int num_params,
118 type **param_types,
119 int is_variadic);
120
121 type *
122 new_function_ptr_type (location *loc,
123 type *return_type,
124 int num_params,
125 type **param_types,
126 int is_variadic);
127
128 param *
129 new_param (location *loc,
130 type *type,
131 const char *name);
132
133 function *
134 new_function (location *loc,
135 enum gcc_jit_function_kind kind,
136 type *return_type,
137 const char *name,
138 int num_params,
139 param **params,
140 int is_variadic,
141 enum built_in_function builtin_id);
142
143 function *
144 get_builtin_function (const char *name);
145
146 lvalue *
147 new_global (location *loc,
148 enum gcc_jit_global_kind kind,
149 type *type,
150 const char *name);
151
152 template <typename HOST_TYPE>
153 rvalue *
154 new_rvalue_from_const (type *type,
155 HOST_TYPE value);
156
157 rvalue *
158 new_string_literal (const char *value);
159
160 rvalue *
161 new_rvalue_from_vector (location *loc,
162 vector_type *type,
163 rvalue **elements);
164
165 rvalue *
166 new_unary_op (location *loc,
167 enum gcc_jit_unary_op op,
168 type *result_type,
169 rvalue *a);
170
171 rvalue *
172 new_binary_op (location *loc,
173 enum gcc_jit_binary_op op,
174 type *result_type,
175 rvalue *a, rvalue *b);
176
177 rvalue *
178 new_comparison (location *loc,
179 enum gcc_jit_comparison op,
180 rvalue *a, rvalue *b);
181
182 rvalue *
183 new_call (location *loc,
184 function *func,
185 int numargs, rvalue **args);
186
187 rvalue *
188 new_call_through_ptr (location *loc,
189 rvalue *fn_ptr,
190 int numargs, rvalue **args);
191
192 rvalue *
193 new_cast (location *loc,
194 rvalue *expr,
195 type *type_);
196
197 lvalue *
198 new_array_access (location *loc,
199 rvalue *ptr,
200 rvalue *index);
201
202 case_ *
203 new_case (rvalue *min_value,
204 rvalue *max_value,
205 block *block);
206
207 void
208 set_str_option (enum gcc_jit_str_option opt,
209 const char *value);
210
211 void
212 set_int_option (enum gcc_jit_int_option opt,
213 int value);
214
215 void
216 set_bool_option (enum gcc_jit_bool_option opt,
217 int value);
218
219 void
220 set_inner_bool_option (enum inner_bool_option inner_opt,
221 int value);
222
223 void
224 add_command_line_option (const char *optname);
225
226 void
227 append_command_line_options (vec <char *> *argvec);
228
229 void
230 add_driver_option (const char *optname);
231
232 void
233 append_driver_options (auto_string_vec *argvec);
234
235 void
236 enable_dump (const char *dumpname,
237 char **out_ptr);
238
239 const char *
get_str_option(enum gcc_jit_str_option opt)240 get_str_option (enum gcc_jit_str_option opt) const
241 {
242 return m_str_options[opt];
243 }
244
245 int
get_int_option(enum gcc_jit_int_option opt)246 get_int_option (enum gcc_jit_int_option opt) const
247 {
248 return m_int_options[opt];
249 }
250
251 int
get_bool_option(enum gcc_jit_bool_option opt)252 get_bool_option (enum gcc_jit_bool_option opt) const
253 {
254 return m_bool_options[opt];
255 }
256
257 int
get_inner_bool_option(enum inner_bool_option opt)258 get_inner_bool_option (enum inner_bool_option opt) const
259 {
260 return m_inner_bool_options[opt];
261 }
262
263 result *
264 compile ();
265
266 void
267 compile_to_file (enum gcc_jit_output_kind output_kind,
268 const char *output_path);
269
270 void
271 add_error (location *loc, const char *fmt, ...)
272 GNU_PRINTF(3, 4);
273
274 void
275 add_error_va (location *loc, const char *fmt, va_list ap)
276 GNU_PRINTF(3, 0);
277
278 const char *
279 get_first_error () const;
280
281 const char *
282 get_last_error () const;
283
errors_occurred()284 bool errors_occurred () const
285 {
286 if (m_parent_ctxt)
287 if (m_parent_ctxt->errors_occurred ())
288 return true;
289 return m_error_count;
290 }
291
292 type *get_opaque_FILE_type ();
293
294 void dump_to_file (const char *path, bool update_locations);
295
296 void dump_reproducer_to_file (const char *path);
297
298 void
299 get_all_requested_dumps (vec <recording::requested_dump> *out);
300
set_timer(timer * t)301 void set_timer (timer *t) { m_timer = t; }
get_timer()302 timer *get_timer () const { return m_timer; }
303
304 void add_top_level_asm (location *loc, const char *asm_stmts);
305
306 private:
307 void log_all_options () const;
308 void log_str_option (enum gcc_jit_str_option opt) const;
309 void log_int_option (enum gcc_jit_int_option opt) const;
310 void log_bool_option (enum gcc_jit_bool_option opt) const;
311 void log_inner_bool_option (enum inner_bool_option opt) const;
312
313 void validate ();
314
315 private:
316 context *m_parent_ctxt;
317
318 /* The ultimate ancestor of the contexts within a family tree of
319 contexts. This has itself as its own m_toplevel_ctxt. */
320 context *m_toplevel_ctxt;
321
322 timer *m_timer;
323
324 int m_error_count;
325
326 char *m_first_error_str;
327 bool m_owns_first_error_str;
328
329 char *m_last_error_str;
330 bool m_owns_last_error_str;
331
332 char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
333 int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
334 bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
335 bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
336 auto_vec <char *> m_command_line_options;
337 auto_vec <char *> m_driver_options;
338
339 /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
340 auto_vec<requested_dump> m_requested_dumps;
341
342 /* Recorded API usage. */
343 auto_vec<memento *> m_mementos;
344
345 /* Specific recordings, for use by dump_to_file. */
346 auto_vec<compound_type *> m_compound_types;
347 auto_vec<global *> m_globals;
348 auto_vec<function *> m_functions;
349 auto_vec<top_level_asm *> m_top_level_asms;
350
351 type *m_basic_types[NUM_GCC_JIT_TYPES];
352 type *m_FILE_type;
353
354 builtins_manager *m_builtins_manager; // lazily created
355 };
356
357
358 /* An object with lifetime managed by the context i.e.
359 it lives until the context is released, at which
360 point it itself is cleaned up. */
361
362 class memento
363 {
364 public:
~memento()365 virtual ~memento () {}
366
367 /* Hook for replaying this. */
368 virtual void replay_into (replayer *r) = 0;
369
set_playback_obj(void * obj)370 void set_playback_obj (void *obj) { m_playback_obj = obj; }
371
372
373 /* Get the context that owns this object.
374
375 Implements the post-error-checking part of
376 gcc_jit_object_get_context. */
get_context()377 context *get_context () { return m_ctxt; }
378
379 memento *
as_object()380 as_object () { return this; }
381
382 /* Debugging hook, for use in generating error messages etc.
383 Implements the post-error-checking part of
384 gcc_jit_object_get_debug_string. */
385 const char *
386 get_debug_string ();
387
388 virtual void write_to_dump (dump &d);
389 virtual void write_reproducer (reproducer &r) = 0;
dyn_cast_location()390 virtual location *dyn_cast_location () { return NULL; }
391
392 protected:
memento(context * ctxt)393 memento (context *ctxt)
394 : m_ctxt (ctxt),
395 m_playback_obj (NULL),
396 m_debug_string (NULL)
397 {
398 gcc_assert (ctxt);
399 }
400
new_string(const char * text)401 string *new_string (const char *text) { return m_ctxt->new_string (text); }
402
403 private:
404 virtual string * make_debug_string () = 0;
405
406 public:
407 context *m_ctxt;
408
409 protected:
410 void *m_playback_obj;
411
412 private:
413 string *m_debug_string;
414 };
415
416 /* or just use std::string? */
417 class string : public memento
418 {
419 public:
420 string (context *ctxt, const char *text, bool escaped);
421 ~string ();
422
c_str()423 const char *c_str () { return m_buffer; }
424
425 static string * from_printf (context *ctxt, const char *fmt, ...)
426 GNU_PRINTF(2, 3);
427
replay_into(replayer *)428 void replay_into (replayer *) FINAL OVERRIDE {}
429
430 private:
431 string * make_debug_string () FINAL OVERRIDE;
432 void write_reproducer (reproducer &r) FINAL OVERRIDE;
433
434 private:
435 size_t m_len;
436 char *m_buffer;
437
438 /* Flag to track if this string is the result of string::make_debug_string,
439 to avoid infinite recursion when logging all mementos: don't re-escape
440 such strings. */
441 bool m_escaped;
442 };
443
444 class location : public memento
445 {
446 public:
location(context * ctxt,string * filename,int line,int column,bool created_by_user)447 location (context *ctxt, string *filename, int line, int column,
448 bool created_by_user)
449 : memento (ctxt),
450 m_filename (filename),
451 m_line (line),
452 m_column (column),
453 m_created_by_user (created_by_user)
454 {}
455
456 void replay_into (replayer *r) FINAL OVERRIDE;
457
458 playback::location *
playback_location(replayer * r)459 playback_location (replayer *r)
460 {
461 /* Normally during playback, we can walk forwards through the list of
462 recording objects, playing them back. The ordering of recording
463 ensures that everything that a recording object refers to has
464 already been played back, so we can simply look up the relevant
465 m_playback_obj.
466
467 Locations are an exception, due to the "write_to_dump" method of
468 recording::statement. This method can set a new location on a
469 statement after the statement is created, and thus the location
470 appears in the context's memento list *after* the statement that
471 refers to it.
472
473 In such circumstances, the statement is replayed *before* the location,
474 when the latter doesn't yet have a playback object.
475
476 Hence we need to ensure that locations have playback objects. */
477 if (!m_playback_obj)
478 {
479 replay_into (r);
480 }
481 gcc_assert (m_playback_obj);
482 return static_cast <playback::location *> (m_playback_obj);
483 }
484
dyn_cast_location()485 location *dyn_cast_location () FINAL OVERRIDE { return this; }
created_by_user()486 bool created_by_user () const { return m_created_by_user; }
487
488 private:
489 string * make_debug_string () FINAL OVERRIDE;
490 void write_reproducer (reproducer &r) FINAL OVERRIDE;
491
492 private:
493 string *m_filename;
494 int m_line;
495 int m_column;
496 bool m_created_by_user;
497 };
498
499 class type : public memento
500 {
501 public:
502 type *get_pointer ();
503 type *get_const ();
504 type *get_volatile ();
505 type *get_aligned (size_t alignment_in_bytes);
506 type *get_vector (size_t num_units);
507
508 /* Get the type obtained when dereferencing this type.
509
510 This will return NULL if it's not valid to dereference this type.
511 The caller is responsible for setting an error. */
512 virtual type *dereference () = 0;
513 /* Get the type size in bytes.
514
515 This is implemented only for memento_of_get_type and
516 memento_of_get_pointer as it is used for initializing globals of
517 these types. */
get_size()518 virtual size_t get_size () { gcc_unreachable (); }
519
520 /* Dynamic casts. */
dyn_cast_function_type()521 virtual function_type *dyn_cast_function_type () { return NULL; }
as_a_function_type()522 virtual function_type *as_a_function_type() { gcc_unreachable (); return NULL; }
dyn_cast_struct()523 virtual struct_ *dyn_cast_struct () { return NULL; }
dyn_cast_vector_type()524 virtual vector_type *dyn_cast_vector_type () { return NULL; }
525
526 /* Is it typesafe to copy to this type from rtype? */
accepts_writes_from(type * rtype)527 virtual bool accepts_writes_from (type *rtype)
528 {
529 gcc_assert (rtype);
530 return this->unqualified ()->is_same_type_as (rtype->unqualified ());
531 }
532
is_same_type_as(type * other)533 virtual bool is_same_type_as (type *other)
534 {
535 return this == other;
536 }
537
538 /* Strip off "const" etc */
unqualified()539 virtual type *unqualified ()
540 {
541 return this;
542 }
543
544 virtual bool is_int () const = 0;
545 virtual bool is_float () const = 0;
546 virtual bool is_bool () const = 0;
547 virtual type *is_pointer () = 0;
548 virtual type *is_array () = 0;
is_void()549 virtual bool is_void () const { return false; }
has_known_size()550 virtual bool has_known_size () const { return true; }
551
is_numeric()552 bool is_numeric () const
553 {
554 return is_int () || is_float () || is_bool ();
555 }
556
557 playback::type *
playback_type()558 playback_type ()
559 {
560 return static_cast <playback::type *> (m_playback_obj);
561 }
562
563 virtual const char *access_as_type (reproducer &r);
564
565 protected:
type(context * ctxt)566 type (context *ctxt)
567 : memento (ctxt),
568 m_pointer_to_this_type (NULL)
569 {}
570
571 private:
572 type *m_pointer_to_this_type;
573 };
574
575 /* Result of "gcc_jit_context_get_type". */
576 class memento_of_get_type : public type
577 {
578 public:
memento_of_get_type(context * ctxt,enum gcc_jit_types kind)579 memento_of_get_type (context *ctxt,
580 enum gcc_jit_types kind)
581 : type (ctxt),
582 m_kind (kind) {}
583
584 type *dereference () FINAL OVERRIDE;
585
586 size_t get_size () FINAL OVERRIDE;
587
accepts_writes_from(type * rtype)588 bool accepts_writes_from (type *rtype) FINAL OVERRIDE
589 {
590 if (m_kind == GCC_JIT_TYPE_VOID_PTR)
591 if (rtype->is_pointer ())
592 {
593 /* LHS (this) is type (void *), and the RHS is a pointer:
594 accept it: */
595 return true;
596 }
597
598 return type::accepts_writes_from (rtype);
599 }
600
601 bool is_int () const FINAL OVERRIDE;
602 bool is_float () const FINAL OVERRIDE;
603 bool is_bool () const FINAL OVERRIDE;
is_pointer()604 type *is_pointer () FINAL OVERRIDE { return dereference (); }
is_array()605 type *is_array () FINAL OVERRIDE { return NULL; }
is_void()606 bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
607
608 public:
609 void replay_into (replayer *r) FINAL OVERRIDE;
610
611 private:
612 string * make_debug_string () FINAL OVERRIDE;
613 void write_reproducer (reproducer &r) FINAL OVERRIDE;
614
615 private:
616 enum gcc_jit_types m_kind;
617 };
618
619 /* Result of "gcc_jit_type_get_pointer". */
620 class memento_of_get_pointer : public type
621 {
622 public:
memento_of_get_pointer(type * other_type)623 memento_of_get_pointer (type *other_type)
624 : type (other_type->m_ctxt),
625 m_other_type (other_type) {}
626
dereference()627 type *dereference () FINAL OVERRIDE { return m_other_type; }
628
629 size_t get_size () FINAL OVERRIDE;
630
631 bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
632
633 void replay_into (replayer *r) FINAL OVERRIDE;
634
is_int()635 bool is_int () const FINAL OVERRIDE { return false; }
is_float()636 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()637 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()638 type *is_pointer () FINAL OVERRIDE { return m_other_type; }
is_array()639 type *is_array () FINAL OVERRIDE { return NULL; }
640
641 private:
642 string * make_debug_string () FINAL OVERRIDE;
643 void write_reproducer (reproducer &r) FINAL OVERRIDE;
644
645 private:
646 type *m_other_type;
647 };
648
649 /* A decorated version of a type, for get_const, get_volatile,
650 get_aligned, and get_vector. */
651
652 class decorated_type : public type
653 {
654 public:
decorated_type(type * other_type)655 decorated_type (type *other_type)
656 : type (other_type->m_ctxt),
657 m_other_type (other_type) {}
658
dereference()659 type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
660
is_int()661 bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
is_float()662 bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
is_bool()663 bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
is_pointer()664 type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
is_array()665 type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
666
667 protected:
668 type *m_other_type;
669 };
670
671 /* Result of "gcc_jit_type_get_const". */
672 class memento_of_get_const : public decorated_type
673 {
674 public:
memento_of_get_const(type * other_type)675 memento_of_get_const (type *other_type)
676 : decorated_type (other_type) {}
677
accepts_writes_from(type *)678 bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
679 {
680 /* Can't write to a "const". */
681 return false;
682 }
683
684 /* Strip off the "const", giving the underlying type. */
unqualified()685 type *unqualified () FINAL OVERRIDE { return m_other_type; }
686
687 void replay_into (replayer *) FINAL OVERRIDE;
688
689 private:
690 string * make_debug_string () FINAL OVERRIDE;
691 void write_reproducer (reproducer &r) FINAL OVERRIDE;
692 };
693
694 /* Result of "gcc_jit_type_get_volatile". */
695 class memento_of_get_volatile : public decorated_type
696 {
697 public:
memento_of_get_volatile(type * other_type)698 memento_of_get_volatile (type *other_type)
699 : decorated_type (other_type) {}
700
701 /* Strip off the "volatile", giving the underlying type. */
unqualified()702 type *unqualified () FINAL OVERRIDE { return m_other_type; }
703
704 void replay_into (replayer *) FINAL OVERRIDE;
705
706 private:
707 string * make_debug_string () FINAL OVERRIDE;
708 void write_reproducer (reproducer &r) FINAL OVERRIDE;
709 };
710
711 /* Result of "gcc_jit_type_get_aligned". */
712 class memento_of_get_aligned : public decorated_type
713 {
714 public:
memento_of_get_aligned(type * other_type,size_t alignment_in_bytes)715 memento_of_get_aligned (type *other_type, size_t alignment_in_bytes)
716 : decorated_type (other_type),
717 m_alignment_in_bytes (alignment_in_bytes) {}
718
719 /* Strip off the alignment, giving the underlying type. */
unqualified()720 type *unqualified () FINAL OVERRIDE { return m_other_type; }
721
722 void replay_into (replayer *) FINAL OVERRIDE;
723
724 private:
725 string * make_debug_string () FINAL OVERRIDE;
726 void write_reproducer (reproducer &r) FINAL OVERRIDE;
727
728 private:
729 size_t m_alignment_in_bytes;
730 };
731
732 /* Result of "gcc_jit_type_get_vector". */
733 class vector_type : public decorated_type
734 {
735 public:
vector_type(type * other_type,size_t num_units)736 vector_type (type *other_type, size_t num_units)
737 : decorated_type (other_type),
738 m_num_units (num_units) {}
739
get_num_units()740 size_t get_num_units () const { return m_num_units; }
741
dyn_cast_vector_type()742 vector_type *dyn_cast_vector_type () FINAL OVERRIDE { return this; }
743
get_element_type()744 type *get_element_type () { return m_other_type; }
745
746 void replay_into (replayer *) FINAL OVERRIDE;
747
748 private:
749 string * make_debug_string () FINAL OVERRIDE;
750 void write_reproducer (reproducer &r) FINAL OVERRIDE;
751
752 private:
753 size_t m_num_units;
754 };
755
756 class array_type : public type
757 {
758 public:
array_type(context * ctxt,location * loc,type * element_type,int num_elements)759 array_type (context *ctxt,
760 location *loc,
761 type *element_type,
762 int num_elements)
763 : type (ctxt),
764 m_loc (loc),
765 m_element_type (element_type),
766 m_num_elements (num_elements)
767 {}
768
769 type *dereference () FINAL OVERRIDE;
770
is_int()771 bool is_int () const FINAL OVERRIDE { return false; }
is_float()772 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()773 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()774 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()775 type *is_array () FINAL OVERRIDE { return m_element_type; }
num_elements()776 int num_elements () { return m_num_elements; }
777
778 void replay_into (replayer *) FINAL OVERRIDE;
779
780 private:
781 string * make_debug_string () FINAL OVERRIDE;
782 void write_reproducer (reproducer &r) FINAL OVERRIDE;
783
784 private:
785 location *m_loc;
786 type *m_element_type;
787 int m_num_elements;
788 };
789
790 class function_type : public type
791 {
792 public:
793 function_type (context *ctxt,
794 type *return_type,
795 int num_params,
796 type **param_types,
797 int is_variadic);
798
799 type *dereference () FINAL OVERRIDE;
dyn_cast_function_type()800 function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
as_a_function_type()801 function_type *as_a_function_type () FINAL OVERRIDE { return this; }
802
803 bool is_same_type_as (type *other) FINAL OVERRIDE;
804
is_int()805 bool is_int () const FINAL OVERRIDE { return false; }
is_float()806 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()807 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()808 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()809 type *is_array () FINAL OVERRIDE { return NULL; }
810
811 void replay_into (replayer *) FINAL OVERRIDE;
812
get_return_type()813 type * get_return_type () const { return m_return_type; }
get_param_types()814 const vec<type *> &get_param_types () const { return m_param_types; }
is_variadic()815 int is_variadic () const { return m_is_variadic; }
816
817 string * make_debug_string_with_ptr ();
818
819 void
820 write_deferred_reproducer (reproducer &r,
821 memento *ptr_type);
822
823 private:
824 string * make_debug_string () FINAL OVERRIDE;
825 string * make_debug_string_with (const char *);
826 void write_reproducer (reproducer &r) FINAL OVERRIDE;
827
828 private:
829 type *m_return_type;
830 auto_vec<type *> m_param_types;
831 int m_is_variadic;
832 };
833
834 class field : public memento
835 {
836 public:
field(context * ctxt,location * loc,type * type,string * name)837 field (context *ctxt,
838 location *loc,
839 type *type,
840 string *name)
841 : memento (ctxt),
842 m_loc (loc),
843 m_type (type),
844 m_name (name),
845 m_container (NULL)
846 {}
847
get_type()848 type * get_type () const { return m_type; }
849
get_container()850 compound_type * get_container () const { return m_container; }
set_container(compound_type * c)851 void set_container (compound_type *c) { m_container = c; }
852
853 void replay_into (replayer *) OVERRIDE;
854
855 void write_to_dump (dump &d) OVERRIDE;
856
857 playback::field *
playback_field()858 playback_field () const
859 {
860 return static_cast <playback::field *> (m_playback_obj);
861 }
862
863 private:
864 string * make_debug_string () OVERRIDE;
865 void write_reproducer (reproducer &r) OVERRIDE;
866
867 protected:
868 location *m_loc;
869 type *m_type;
870 string *m_name;
871 compound_type *m_container;
872 };
873
874
875 class bitfield : public field
876 {
877 public:
bitfield(context * ctxt,location * loc,type * type,int width,string * name)878 bitfield (context *ctxt,
879 location *loc,
880 type *type,
881 int width,
882 string *name)
883 : field (ctxt, loc, type, name),
884 m_width (width)
885 {}
886
887 void replay_into (replayer *) FINAL OVERRIDE;
888
889 void write_to_dump (dump &d) FINAL OVERRIDE;
890
891 private:
892 string * make_debug_string () FINAL OVERRIDE;
893 void write_reproducer (reproducer &r) FINAL OVERRIDE;
894
895 private:
896 int m_width;
897 };
898
899 /* Base class for struct_ and union_ */
900 class compound_type : public type
901 {
902 public:
903 compound_type (context *ctxt,
904 location *loc,
905 string *name);
906
get_name()907 string *get_name () const { return m_name; }
get_loc()908 location *get_loc () const { return m_loc; }
get_fields()909 fields * get_fields () { return m_fields; }
910
911 void
912 set_fields (location *loc,
913 int num_fields,
914 field **fields);
915
916 type *dereference () FINAL OVERRIDE;
917
is_int()918 bool is_int () const FINAL OVERRIDE { return false; }
is_float()919 bool is_float () const FINAL OVERRIDE { return false; }
is_bool()920 bool is_bool () const FINAL OVERRIDE { return false; }
is_pointer()921 type *is_pointer () FINAL OVERRIDE { return NULL; }
is_array()922 type *is_array () FINAL OVERRIDE { return NULL; }
923
has_known_size()924 bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
925
926 playback::compound_type *
playback_compound_type()927 playback_compound_type ()
928 {
929 return static_cast <playback::compound_type *> (m_playback_obj);
930 }
931
932 private:
933 location *m_loc;
934 string *m_name;
935 fields *m_fields;
936 };
937
938 class struct_ : public compound_type
939 {
940 public:
941 struct_ (context *ctxt,
942 location *loc,
943 string *name);
944
dyn_cast_struct()945 struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
946
947 type *
as_type()948 as_type () { return this; }
949
950 void replay_into (replayer *r) FINAL OVERRIDE;
951
952 const char *access_as_type (reproducer &r) FINAL OVERRIDE;
953
954 private:
955 string * make_debug_string () FINAL OVERRIDE;
956 void write_reproducer (reproducer &r) FINAL OVERRIDE;
957 };
958
959 // memento of struct_::set_fields
960 class fields : public memento
961 {
962 public:
963 fields (compound_type *struct_or_union,
964 int num_fields,
965 field **fields);
966
967 void replay_into (replayer *r) FINAL OVERRIDE;
968
969 void write_to_dump (dump &d) FINAL OVERRIDE;
970
length()971 int length () const { return m_fields.length (); }
get_field(int i)972 field *get_field (int i) const { return m_fields[i]; }
973
974 private:
975 string * make_debug_string () FINAL OVERRIDE;
976 void write_reproducer (reproducer &r) FINAL OVERRIDE;
977
978 private:
979 compound_type *m_struct_or_union;
980 auto_vec<field *> m_fields;
981 };
982
983 class union_ : public compound_type
984 {
985 public:
986 union_ (context *ctxt,
987 location *loc,
988 string *name);
989
990 void replay_into (replayer *r) FINAL OVERRIDE;
991
992 private:
993 string * make_debug_string () FINAL OVERRIDE;
994 void write_reproducer (reproducer &r) FINAL OVERRIDE;
995 };
996
997 /* An abstract base class for operations that visit all rvalues within an
998 expression tree.
999 Currently the only implementation is class rvalue_usage_validator within
1000 jit-recording.c. */
1001
1002 class rvalue_visitor
1003 {
1004 public:
~rvalue_visitor()1005 virtual ~rvalue_visitor () {}
1006 virtual void visit (rvalue *rvalue) = 0;
1007 };
1008
1009 /* When generating debug strings for rvalues we mimic C, so we need to
1010 mimic C's precedence levels when handling compound expressions.
1011 These are in order from strongest precedence to weakest. */
1012 enum precedence
1013 {
1014 PRECEDENCE_PRIMARY,
1015 PRECEDENCE_POSTFIX,
1016 PRECEDENCE_UNARY,
1017 PRECEDENCE_CAST,
1018 PRECEDENCE_MULTIPLICATIVE,
1019 PRECEDENCE_ADDITIVE,
1020 PRECEDENCE_SHIFT,
1021 PRECEDENCE_RELATIONAL,
1022 PRECEDENCE_EQUALITY,
1023 PRECEDENCE_BITWISE_AND,
1024 PRECEDENCE_BITWISE_XOR,
1025 PRECEDENCE_BITWISE_IOR,
1026 PRECEDENCE_LOGICAL_AND,
1027 PRECEDENCE_LOGICAL_OR
1028 };
1029
1030 class rvalue : public memento
1031 {
1032 public:
rvalue(context * ctxt,location * loc,type * type_)1033 rvalue (context *ctxt,
1034 location *loc,
1035 type *type_)
1036 : memento (ctxt),
1037 m_loc (loc),
1038 m_type (type_),
1039 m_scope (NULL),
1040 m_parenthesized_string (NULL)
1041 {
1042 gcc_assert (type_);
1043 }
1044
get_loc()1045 location * get_loc () const { return m_loc; }
1046
1047 /* Get the recording::type of this rvalue.
1048
1049 Implements the post-error-checking part of
1050 gcc_jit_rvalue_get_type. */
get_type()1051 type * get_type () const { return m_type; }
1052
1053 playback::rvalue *
playback_rvalue()1054 playback_rvalue () const
1055 {
1056 return static_cast <playback::rvalue *> (m_playback_obj);
1057 }
1058 rvalue *
1059 access_field (location *loc,
1060 field *field);
1061
1062 lvalue *
1063 dereference_field (location *loc,
1064 field *field);
1065
1066 lvalue *
1067 dereference (location *loc);
1068
1069 void
1070 verify_valid_within_stmt (const char *api_funcname, statement *s);
1071
1072 virtual void visit_children (rvalue_visitor *v) = 0;
1073
1074 void set_scope (function *scope);
get_scope()1075 function *get_scope () const { return m_scope; }
1076
1077 /* Dynamic casts. */
dyn_cast_param()1078 virtual param *dyn_cast_param () { return NULL; }
dyn_cast_base_call()1079 virtual base_call *dyn_cast_base_call () { return NULL; }
1080
1081 virtual const char *access_as_rvalue (reproducer &r);
1082
1083 /* Get the debug string, wrapped in parentheses. */
1084 const char *
1085 get_debug_string_parens (enum precedence outer_prec);
1086
is_constant()1087 virtual bool is_constant () const { return false; }
get_wide_int(wide_int *)1088 virtual bool get_wide_int (wide_int *) const { return false; }
1089
1090 private:
1091 virtual enum precedence get_precedence () const = 0;
1092
1093 protected:
1094 location *m_loc;
1095 type *m_type;
1096
1097 private:
1098 function *m_scope; /* NULL for globals, non-NULL for locals/params */
1099 string *m_parenthesized_string;
1100 };
1101
1102 class lvalue : public rvalue
1103 {
1104 public:
lvalue(context * ctxt,location * loc,type * type_)1105 lvalue (context *ctxt,
1106 location *loc,
1107 type *type_)
1108 : rvalue (ctxt, loc, type_)
1109 {}
1110
1111 playback::lvalue *
playback_lvalue()1112 playback_lvalue () const
1113 {
1114 return static_cast <playback::lvalue *> (m_playback_obj);
1115 }
1116
1117 lvalue *
1118 access_field (location *loc,
1119 field *field);
1120
1121 rvalue *
1122 get_address (location *loc);
1123
1124 rvalue *
as_rvalue()1125 as_rvalue () { return this; }
1126
1127 const char *access_as_rvalue (reproducer &r) OVERRIDE;
1128 virtual const char *access_as_lvalue (reproducer &r);
is_global()1129 virtual bool is_global () const { return false; }
1130 };
1131
1132 class param : public lvalue
1133 {
1134 public:
param(context * ctxt,location * loc,type * type,string * name)1135 param (context *ctxt,
1136 location *loc,
1137 type *type,
1138 string *name)
1139 : lvalue (ctxt, loc, type),
1140 m_name (name) {}
1141
1142 lvalue *
as_lvalue()1143 as_lvalue () { return this; }
1144
1145 void replay_into (replayer *r) FINAL OVERRIDE;
1146
visit_children(rvalue_visitor *)1147 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1148
1149 playback::param *
playback_param()1150 playback_param () const
1151 {
1152 return static_cast <playback::param *> (m_playback_obj);
1153 }
1154
dyn_cast_param()1155 param *dyn_cast_param () FINAL OVERRIDE { return this; }
1156
1157 const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
1158 const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
1159
1160 private:
make_debug_string()1161 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1162 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1163 enum precedence get_precedence () const FINAL OVERRIDE
1164 {
1165 return PRECEDENCE_PRIMARY;
1166 }
1167
1168 private:
1169 string *m_name;
1170 };
1171
1172 class function : public memento
1173 {
1174 public:
1175 function (context *ctxt,
1176 location *loc,
1177 enum gcc_jit_function_kind kind,
1178 type *return_type,
1179 string *name,
1180 int num_params,
1181 param **params,
1182 int is_variadic,
1183 enum built_in_function builtin_id);
1184
1185 void replay_into (replayer *r) FINAL OVERRIDE;
1186
1187 playback::function *
playback_function()1188 playback_function () const
1189 {
1190 return static_cast <playback::function *> (m_playback_obj);
1191 }
1192
get_kind()1193 enum gcc_jit_function_kind get_kind () const { return m_kind; }
1194
1195 lvalue *
1196 new_local (location *loc,
1197 type *type,
1198 const char *name);
1199
1200 block*
1201 new_block (const char *name);
1202
get_loc()1203 location *get_loc () const { return m_loc; }
get_return_type()1204 type *get_return_type () const { return m_return_type; }
get_name()1205 string * get_name () const { return m_name; }
get_params()1206 const vec<param *> &get_params () const { return m_params; }
1207
1208 /* Get the given param by index.
1209 Implements the post-error-checking part of
1210 gcc_jit_function_get_param. */
get_param(int i)1211 param *get_param (int i) const { return m_params[i]; }
1212
is_variadic()1213 bool is_variadic () const { return m_is_variadic; }
1214
1215 void write_to_dump (dump &d) FINAL OVERRIDE;
1216
1217 void validate ();
1218
1219 void dump_to_dot (const char *path);
1220
1221 rvalue *get_address (location *loc);
1222
1223 private:
1224 string * make_debug_string () FINAL OVERRIDE;
1225 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1226
1227 private:
1228 location *m_loc;
1229 enum gcc_jit_function_kind m_kind;
1230 type *m_return_type;
1231 string *m_name;
1232 auto_vec<param *> m_params;
1233 int m_is_variadic;
1234 enum built_in_function m_builtin_id;
1235 auto_vec<local *> m_locals;
1236 auto_vec<block *> m_blocks;
1237 type *m_fn_ptr_type;
1238 };
1239
1240 class block : public memento
1241 {
1242 public:
block(function * func,int index,string * name)1243 block (function *func, int index, string *name)
1244 : memento (func->m_ctxt),
1245 m_func (func),
1246 m_index (index),
1247 m_name (name),
1248 m_statements (),
1249 m_has_been_terminated (false),
1250 m_is_reachable (false)
1251 {
1252 }
1253
1254 /* Get the recording::function containing this block.
1255 Implements the post-error-checking part of
1256 gcc_jit_block_get_function. */
get_function()1257 function *get_function () { return m_func; }
1258
has_been_terminated()1259 bool has_been_terminated () { return m_has_been_terminated; }
is_reachable()1260 bool is_reachable () { return m_is_reachable; }
1261
1262 statement *
1263 add_eval (location *loc,
1264 rvalue *rvalue);
1265
1266 statement *
1267 add_assignment (location *loc,
1268 lvalue *lvalue,
1269 rvalue *rvalue);
1270
1271 statement *
1272 add_assignment_op (location *loc,
1273 lvalue *lvalue,
1274 enum gcc_jit_binary_op op,
1275 rvalue *rvalue);
1276
1277 statement *
1278 add_comment (location *loc,
1279 const char *text);
1280
1281 extended_asm *
1282 add_extended_asm (location *loc,
1283 const char *asm_template);
1284
1285 statement *
1286 end_with_conditional (location *loc,
1287 rvalue *boolval,
1288 block *on_true,
1289 block *on_false);
1290
1291 statement *
1292 end_with_jump (location *loc,
1293 block *target);
1294
1295 statement *
1296 end_with_return (location *loc,
1297 rvalue *rvalue);
1298
1299 statement *
1300 end_with_switch (location *loc,
1301 rvalue *expr,
1302 block *default_block,
1303 int num_cases,
1304 case_ **cases);
1305
1306 extended_asm *
1307 end_with_extended_asm_goto (location *loc,
1308 const char *asm_template,
1309 int num_goto_blocks,
1310 block **goto_blocks,
1311 block *fallthrough_block);
1312
1313 playback::block *
playback_block()1314 playback_block () const
1315 {
1316 return static_cast <playback::block *> (m_playback_obj);
1317 }
1318
1319 void write_to_dump (dump &d) FINAL OVERRIDE;
1320
1321 bool validate ();
1322
1323 location *get_loc () const;
1324
1325 statement *get_first_statement () const;
1326 statement *get_last_statement () const;
1327
1328 vec <block *> get_successor_blocks () const;
1329
1330 private:
1331 string * make_debug_string () FINAL OVERRIDE;
1332 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1333
1334 void replay_into (replayer *r) FINAL OVERRIDE;
1335
1336 void dump_to_dot (pretty_printer *pp);
1337 void dump_edges_to_dot (pretty_printer *pp);
1338
1339 private:
1340 function *m_func;
1341 int m_index;
1342 string *m_name;
1343 auto_vec<statement *> m_statements;
1344 bool m_has_been_terminated;
1345 bool m_is_reachable;
1346
1347 friend class function;
1348 };
1349
1350 class global : public lvalue
1351 {
1352 public:
global(context * ctxt,location * loc,enum gcc_jit_global_kind kind,type * type,string * name)1353 global (context *ctxt,
1354 location *loc,
1355 enum gcc_jit_global_kind kind,
1356 type *type,
1357 string *name)
1358 : lvalue (ctxt, loc, type),
1359 m_kind (kind),
1360 m_name (name)
1361 {
1362 m_initializer = NULL;
1363 m_initializer_num_bytes = 0;
1364 }
~global()1365 ~global ()
1366 {
1367 free (m_initializer);
1368 }
1369
1370 void replay_into (replayer *) FINAL OVERRIDE;
1371
visit_children(rvalue_visitor *)1372 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1373
1374 void write_to_dump (dump &d) FINAL OVERRIDE;
1375
is_global()1376 bool is_global () const FINAL OVERRIDE { return true; }
1377
1378 void
set_initializer(const void * initializer,size_t num_bytes)1379 set_initializer (const void *initializer,
1380 size_t num_bytes)
1381 {
1382 if (m_initializer)
1383 free (m_initializer);
1384 m_initializer = xmalloc (num_bytes);
1385 memcpy (m_initializer, initializer, num_bytes);
1386 m_initializer_num_bytes = num_bytes;
1387 }
1388
1389 private:
make_debug_string()1390 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1391 template <typename T>
1392 void write_initializer_reproducer (const char *id, reproducer &r);
1393 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1394 enum precedence get_precedence () const FINAL OVERRIDE
1395 {
1396 return PRECEDENCE_PRIMARY;
1397 }
1398
1399 private:
1400 enum gcc_jit_global_kind m_kind;
1401 string *m_name;
1402 void *m_initializer;
1403 size_t m_initializer_num_bytes;
1404 };
1405
1406 template <typename HOST_TYPE>
1407 class memento_of_new_rvalue_from_const : public rvalue
1408 {
1409 public:
memento_of_new_rvalue_from_const(context * ctxt,location * loc,type * type,HOST_TYPE value)1410 memento_of_new_rvalue_from_const (context *ctxt,
1411 location *loc,
1412 type *type,
1413 HOST_TYPE value)
1414 : rvalue (ctxt, loc, type),
1415 m_value (value) {}
1416
1417 void replay_into (replayer *r) FINAL OVERRIDE;
1418
visit_children(rvalue_visitor *)1419 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1420
is_constant()1421 bool is_constant () const FINAL OVERRIDE { return true; }
1422
1423 bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
1424
1425 private:
1426 string * make_debug_string () FINAL OVERRIDE;
1427 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1428 enum precedence get_precedence () const FINAL OVERRIDE
1429 {
1430 return PRECEDENCE_PRIMARY;
1431 }
1432
1433 private:
1434 HOST_TYPE m_value;
1435 };
1436
1437 class memento_of_new_string_literal : public rvalue
1438 {
1439 public:
memento_of_new_string_literal(context * ctxt,location * loc,string * value)1440 memento_of_new_string_literal (context *ctxt,
1441 location *loc,
1442 string *value)
1443 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
1444 m_value (value) {}
1445
1446 void replay_into (replayer *r) FINAL OVERRIDE;
1447
visit_children(rvalue_visitor *)1448 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1449
1450 private:
1451 string * make_debug_string () FINAL OVERRIDE;
1452 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1453 enum precedence get_precedence () const FINAL OVERRIDE
1454 {
1455 return PRECEDENCE_PRIMARY;
1456 }
1457
1458 private:
1459 string *m_value;
1460 };
1461
1462 class memento_of_new_rvalue_from_vector : public rvalue
1463 {
1464 public:
1465 memento_of_new_rvalue_from_vector (context *ctxt,
1466 location *loc,
1467 vector_type *type,
1468 rvalue **elements);
1469
1470 void replay_into (replayer *r) FINAL OVERRIDE;
1471
1472 void visit_children (rvalue_visitor *) FINAL OVERRIDE;
1473
1474 private:
1475 string * make_debug_string () FINAL OVERRIDE;
1476 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1477 enum precedence get_precedence () const FINAL OVERRIDE
1478 {
1479 return PRECEDENCE_PRIMARY;
1480 }
1481
1482 private:
1483 vector_type *m_vector_type;
1484 auto_vec<rvalue *> m_elements;
1485 };
1486
1487 class unary_op : public rvalue
1488 {
1489 public:
unary_op(context * ctxt,location * loc,enum gcc_jit_unary_op op,type * result_type,rvalue * a)1490 unary_op (context *ctxt,
1491 location *loc,
1492 enum gcc_jit_unary_op op,
1493 type *result_type,
1494 rvalue *a)
1495 : rvalue (ctxt, loc, result_type),
1496 m_op (op),
1497 m_a (a)
1498 {}
1499
1500 void replay_into (replayer *r) FINAL OVERRIDE;
1501
1502 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1503
1504 private:
1505 string * make_debug_string () FINAL OVERRIDE;
1506 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1507 enum precedence get_precedence () const FINAL OVERRIDE
1508 {
1509 return PRECEDENCE_UNARY;
1510 }
1511
1512 private:
1513 enum gcc_jit_unary_op m_op;
1514 rvalue *m_a;
1515 };
1516
1517 class binary_op : public rvalue
1518 {
1519 public:
binary_op(context * ctxt,location * loc,enum gcc_jit_binary_op op,type * result_type,rvalue * a,rvalue * b)1520 binary_op (context *ctxt,
1521 location *loc,
1522 enum gcc_jit_binary_op op,
1523 type *result_type,
1524 rvalue *a, rvalue *b)
1525 : rvalue (ctxt, loc, result_type),
1526 m_op (op),
1527 m_a (a),
1528 m_b (b) {}
1529
1530 void replay_into (replayer *r) FINAL OVERRIDE;
1531
1532 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1533
1534 private:
1535 string * make_debug_string () FINAL OVERRIDE;
1536 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1537 enum precedence get_precedence () const FINAL OVERRIDE;
1538
1539 private:
1540 enum gcc_jit_binary_op m_op;
1541 rvalue *m_a;
1542 rvalue *m_b;
1543 };
1544
1545 class comparison : public rvalue
1546 {
1547 public:
comparison(context * ctxt,location * loc,enum gcc_jit_comparison op,rvalue * a,rvalue * b)1548 comparison (context *ctxt,
1549 location *loc,
1550 enum gcc_jit_comparison op,
1551 rvalue *a, rvalue *b)
1552 : rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_BOOL)),
1553 m_op (op),
1554 m_a (a),
1555 m_b (b)
1556 {}
1557
1558 void replay_into (replayer *r) FINAL OVERRIDE;
1559
1560 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1561
1562 private:
1563 string * make_debug_string () FINAL OVERRIDE;
1564 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1565 enum precedence get_precedence () const FINAL OVERRIDE;
1566
1567 private:
1568 enum gcc_jit_comparison m_op;
1569 rvalue *m_a;
1570 rvalue *m_b;
1571 };
1572
1573 class cast : public rvalue
1574 {
1575 public:
cast(context * ctxt,location * loc,rvalue * a,type * type_)1576 cast (context *ctxt,
1577 location *loc,
1578 rvalue *a,
1579 type *type_)
1580 : rvalue (ctxt, loc, type_),
1581 m_rvalue (a)
1582 {}
1583
1584 void replay_into (replayer *r) FINAL OVERRIDE;
1585
1586 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1587
1588 private:
1589 string * make_debug_string () FINAL OVERRIDE;
1590 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1591 enum precedence get_precedence () const FINAL OVERRIDE
1592 {
1593 return PRECEDENCE_CAST;
1594 }
1595
1596 private:
1597 rvalue *m_rvalue;
1598 };
1599
1600 class base_call : public rvalue
1601 {
1602 public:
1603 base_call (context *ctxt,
1604 location *loc,
1605 type *type_,
1606 int numargs,
1607 rvalue **args);
1608
get_precedence()1609 enum precedence get_precedence () const FINAL OVERRIDE
1610 {
1611 return PRECEDENCE_POSTFIX;
1612 }
1613
dyn_cast_base_call()1614 base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
1615
set_require_tail_call(bool require_tail_call)1616 void set_require_tail_call (bool require_tail_call)
1617 {
1618 m_require_tail_call = require_tail_call;
1619 }
1620
1621 protected:
1622 void write_reproducer_tail_call (reproducer &r, const char *id);
1623
1624 protected:
1625 auto_vec<rvalue *> m_args;
1626 bool m_require_tail_call;
1627 };
1628
1629 class call : public base_call
1630 {
1631 public:
1632 call (context *ctxt,
1633 location *loc,
1634 function *func,
1635 int numargs,
1636 rvalue **args);
1637
1638 void replay_into (replayer *r) FINAL OVERRIDE;
1639
1640 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1641
1642 private:
1643 string * make_debug_string () FINAL OVERRIDE;
1644 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1645
1646 private:
1647 function *m_func;
1648 };
1649
1650 class call_through_ptr : public base_call
1651 {
1652 public:
1653 call_through_ptr (context *ctxt,
1654 location *loc,
1655 rvalue *fn_ptr,
1656 int numargs,
1657 rvalue **args);
1658
1659 void replay_into (replayer *r) FINAL OVERRIDE;
1660
1661 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1662
1663 private:
1664 string * make_debug_string () FINAL OVERRIDE;
1665 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1666
1667 private:
1668 rvalue *m_fn_ptr;
1669 };
1670
1671 class array_access : public lvalue
1672 {
1673 public:
array_access(context * ctxt,location * loc,rvalue * ptr,rvalue * index)1674 array_access (context *ctxt,
1675 location *loc,
1676 rvalue *ptr,
1677 rvalue *index)
1678 : lvalue (ctxt, loc, ptr->get_type ()->dereference ()),
1679 m_ptr (ptr),
1680 m_index (index)
1681 {}
1682
1683 void replay_into (replayer *r) FINAL OVERRIDE;
1684
1685 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1686
1687 private:
1688 string * make_debug_string () FINAL OVERRIDE;
1689 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1690 enum precedence get_precedence () const FINAL OVERRIDE
1691 {
1692 return PRECEDENCE_POSTFIX;
1693 }
1694
1695 private:
1696 rvalue *m_ptr;
1697 rvalue *m_index;
1698 };
1699
1700 class access_field_of_lvalue : public lvalue
1701 {
1702 public:
access_field_of_lvalue(context * ctxt,location * loc,lvalue * val,field * field)1703 access_field_of_lvalue (context *ctxt,
1704 location *loc,
1705 lvalue *val,
1706 field *field)
1707 : lvalue (ctxt, loc, field->get_type ()),
1708 m_lvalue (val),
1709 m_field (field)
1710 {}
1711
1712 void replay_into (replayer *r) FINAL OVERRIDE;
1713
1714 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1715
1716 private:
1717 string * make_debug_string () FINAL OVERRIDE;
1718 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1719 enum precedence get_precedence () const FINAL OVERRIDE
1720 {
1721 return PRECEDENCE_POSTFIX;
1722 }
1723
1724 private:
1725 lvalue *m_lvalue;
1726 field *m_field;
1727 };
1728
1729 class access_field_rvalue : public rvalue
1730 {
1731 public:
access_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1732 access_field_rvalue (context *ctxt,
1733 location *loc,
1734 rvalue *val,
1735 field *field)
1736 : rvalue (ctxt, loc, field->get_type ()),
1737 m_rvalue (val),
1738 m_field (field)
1739 {}
1740
1741 void replay_into (replayer *r) FINAL OVERRIDE;
1742
1743 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1744
1745 private:
1746 string * make_debug_string () FINAL OVERRIDE;
1747 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1748 enum precedence get_precedence () const FINAL OVERRIDE
1749 {
1750 return PRECEDENCE_POSTFIX;
1751 }
1752
1753 private:
1754 rvalue *m_rvalue;
1755 field *m_field;
1756 };
1757
1758 class dereference_field_rvalue : public lvalue
1759 {
1760 public:
dereference_field_rvalue(context * ctxt,location * loc,rvalue * val,field * field)1761 dereference_field_rvalue (context *ctxt,
1762 location *loc,
1763 rvalue *val,
1764 field *field)
1765 : lvalue (ctxt, loc, field->get_type ()),
1766 m_rvalue (val),
1767 m_field (field)
1768 {}
1769
1770 void replay_into (replayer *r) FINAL OVERRIDE;
1771
1772 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1773
1774 private:
1775 string * make_debug_string () FINAL OVERRIDE;
1776 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1777 enum precedence get_precedence () const FINAL OVERRIDE
1778 {
1779 return PRECEDENCE_POSTFIX;
1780 }
1781
1782 private:
1783 rvalue *m_rvalue;
1784 field *m_field;
1785 };
1786
1787 class dereference_rvalue : public lvalue
1788 {
1789 public:
dereference_rvalue(context * ctxt,location * loc,rvalue * val)1790 dereference_rvalue (context *ctxt,
1791 location *loc,
1792 rvalue *val)
1793 : lvalue (ctxt, loc, val->get_type ()->dereference ()),
1794 m_rvalue (val) {}
1795
1796 void replay_into (replayer *r) FINAL OVERRIDE;
1797
1798 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1799
1800 private:
1801 string * make_debug_string () FINAL OVERRIDE;
1802 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1803 enum precedence get_precedence () const FINAL OVERRIDE
1804 {
1805 return PRECEDENCE_UNARY;
1806 }
1807
1808 private:
1809 rvalue *m_rvalue;
1810 };
1811
1812 class get_address_of_lvalue : public rvalue
1813 {
1814 public:
get_address_of_lvalue(context * ctxt,location * loc,lvalue * val)1815 get_address_of_lvalue (context *ctxt,
1816 location *loc,
1817 lvalue *val)
1818 : rvalue (ctxt, loc, val->get_type ()->get_pointer ()),
1819 m_lvalue (val)
1820 {}
1821
1822 void replay_into (replayer *r) FINAL OVERRIDE;
1823
1824 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1825
1826 private:
1827 string * make_debug_string () FINAL OVERRIDE;
1828 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1829 enum precedence get_precedence () const FINAL OVERRIDE
1830 {
1831 return PRECEDENCE_UNARY;
1832 }
1833
1834 private:
1835 lvalue *m_lvalue;
1836 };
1837
1838 class function_pointer : public rvalue
1839 {
1840 public:
function_pointer(context * ctxt,location * loc,function * fn,type * type)1841 function_pointer (context *ctxt,
1842 location *loc,
1843 function *fn,
1844 type *type)
1845 : rvalue (ctxt, loc, type),
1846 m_fn (fn) {}
1847
1848 void replay_into (replayer *r) FINAL OVERRIDE;
1849
1850 void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
1851
1852 private:
1853 string * make_debug_string () FINAL OVERRIDE;
1854 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1855 enum precedence get_precedence () const FINAL OVERRIDE
1856 {
1857 return PRECEDENCE_UNARY;
1858 }
1859
1860 private:
1861 function *m_fn;
1862 };
1863
1864 class local : public lvalue
1865 {
1866 public:
local(function * func,location * loc,type * type_,string * name)1867 local (function *func, location *loc, type *type_, string *name)
1868 : lvalue (func->m_ctxt, loc, type_),
1869 m_func (func),
1870 m_name (name)
1871 {
1872 set_scope (func);
1873 }
1874
1875 void replay_into (replayer *r) FINAL OVERRIDE;
1876
visit_children(rvalue_visitor *)1877 void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
1878
1879 void write_to_dump (dump &d) FINAL OVERRIDE;
1880
1881 private:
make_debug_string()1882 string * make_debug_string () FINAL OVERRIDE { return m_name; }
1883 void write_reproducer (reproducer &r) FINAL OVERRIDE;
get_precedence()1884 enum precedence get_precedence () const FINAL OVERRIDE
1885 {
1886 return PRECEDENCE_PRIMARY;
1887 }
1888
1889 private:
1890 function *m_func;
1891 string *m_name;
1892 };
1893
1894 class statement : public memento
1895 {
1896 public:
1897 virtual vec <block *> get_successor_blocks () const;
1898
1899 void write_to_dump (dump &d) FINAL OVERRIDE;
1900
get_block()1901 block *get_block () const { return m_block; }
get_loc()1902 location *get_loc () const { return m_loc; }
1903
1904 protected:
statement(block * b,location * loc)1905 statement (block *b, location *loc)
1906 : memento (b->m_ctxt),
1907 m_block (b),
1908 m_loc (loc) {}
1909
1910 playback::location *
playback_location(replayer * r)1911 playback_location (replayer *r) const
1912 {
1913 return ::gcc::jit::recording::playback_location (r, m_loc);
1914 }
1915
1916 private:
1917 block *m_block;
1918 location *m_loc;
1919 };
1920
1921 class eval : public statement
1922 {
1923 public:
eval(block * b,location * loc,rvalue * rvalue)1924 eval (block *b,
1925 location *loc,
1926 rvalue *rvalue)
1927 : statement (b, loc),
1928 m_rvalue (rvalue) {}
1929
1930 void replay_into (replayer *r) FINAL OVERRIDE;
1931
1932 private:
1933 string * make_debug_string () FINAL OVERRIDE;
1934 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1935
1936 private:
1937 rvalue *m_rvalue;
1938 };
1939
1940 class assignment : public statement
1941 {
1942 public:
assignment(block * b,location * loc,lvalue * lvalue,rvalue * rvalue)1943 assignment (block *b,
1944 location *loc,
1945 lvalue *lvalue,
1946 rvalue *rvalue)
1947 : statement (b, loc),
1948 m_lvalue (lvalue),
1949 m_rvalue (rvalue) {}
1950
1951 void replay_into (replayer *r) FINAL OVERRIDE;
1952
1953 private:
1954 string * make_debug_string () FINAL OVERRIDE;
1955 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1956
1957 private:
1958 lvalue *m_lvalue;
1959 rvalue *m_rvalue;
1960 };
1961
1962 class assignment_op : public statement
1963 {
1964 public:
assignment_op(block * b,location * loc,lvalue * lvalue,enum gcc_jit_binary_op op,rvalue * rvalue)1965 assignment_op (block *b,
1966 location *loc,
1967 lvalue *lvalue,
1968 enum gcc_jit_binary_op op,
1969 rvalue *rvalue)
1970 : statement (b, loc),
1971 m_lvalue (lvalue),
1972 m_op (op),
1973 m_rvalue (rvalue) {}
1974
1975 void replay_into (replayer *r) FINAL OVERRIDE;
1976
1977 private:
1978 string * make_debug_string () FINAL OVERRIDE;
1979 void write_reproducer (reproducer &r) FINAL OVERRIDE;
1980
1981 private:
1982 lvalue *m_lvalue;
1983 enum gcc_jit_binary_op m_op;
1984 rvalue *m_rvalue;
1985 };
1986
1987 class comment : public statement
1988 {
1989 public:
comment(block * b,location * loc,string * text)1990 comment (block *b,
1991 location *loc,
1992 string *text)
1993 : statement (b, loc),
1994 m_text (text) {}
1995
1996 void replay_into (replayer *r) FINAL OVERRIDE;
1997
1998 private:
1999 string * make_debug_string () FINAL OVERRIDE;
2000 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2001
2002 private:
2003 string *m_text;
2004 };
2005
2006 class conditional : public statement
2007 {
2008 public:
conditional(block * b,location * loc,rvalue * boolval,block * on_true,block * on_false)2009 conditional (block *b,
2010 location *loc,
2011 rvalue *boolval,
2012 block *on_true,
2013 block *on_false)
2014 : statement (b, loc),
2015 m_boolval (boolval),
2016 m_on_true (on_true),
2017 m_on_false (on_false) {}
2018
2019 void replay_into (replayer *r) FINAL OVERRIDE;
2020
2021 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2022
2023 private:
2024 string * make_debug_string () FINAL OVERRIDE;
2025 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2026
2027 private:
2028 rvalue *m_boolval;
2029 block *m_on_true;
2030 block *m_on_false;
2031 };
2032
2033 class jump : public statement
2034 {
2035 public:
jump(block * b,location * loc,block * target)2036 jump (block *b,
2037 location *loc,
2038 block *target)
2039 : statement (b, loc),
2040 m_target (target) {}
2041
2042 void replay_into (replayer *r) FINAL OVERRIDE;
2043
2044 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2045
2046 private:
2047 string * make_debug_string () FINAL OVERRIDE;
2048 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2049
2050 private:
2051 block *m_target;
2052 };
2053
2054 class return_ : public statement
2055 {
2056 public:
return_(block * b,location * loc,rvalue * rvalue)2057 return_ (block *b,
2058 location *loc,
2059 rvalue *rvalue)
2060 : statement (b, loc),
2061 m_rvalue (rvalue) {}
2062
2063 void replay_into (replayer *r) FINAL OVERRIDE;
2064
2065 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2066
2067 private:
2068 string * make_debug_string () FINAL OVERRIDE;
2069 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2070
2071 private:
2072 rvalue *m_rvalue;
2073 };
2074
2075 class case_ : public memento
2076 {
2077 public:
case_(context * ctxt,rvalue * min_value,rvalue * max_value,block * dest_block)2078 case_ (context *ctxt,
2079 rvalue *min_value,
2080 rvalue *max_value,
2081 block *dest_block)
2082 : memento (ctxt),
2083 m_min_value (min_value),
2084 m_max_value (max_value),
2085 m_dest_block (dest_block)
2086 {}
2087
get_min_value()2088 rvalue *get_min_value () const { return m_min_value; }
get_max_value()2089 rvalue *get_max_value () const { return m_max_value; }
get_dest_block()2090 block *get_dest_block () const { return m_dest_block; }
2091
replay_into(replayer *)2092 void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
2093
2094 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2095
2096 private:
2097 string * make_debug_string () FINAL OVERRIDE;
2098
2099 private:
2100 rvalue *m_min_value;
2101 rvalue *m_max_value;
2102 block *m_dest_block;
2103 };
2104
2105 class switch_ : public statement
2106 {
2107 public:
2108 switch_ (block *b,
2109 location *loc,
2110 rvalue *expr,
2111 block *default_block,
2112 int num_cases,
2113 case_ **cases);
2114
2115 void replay_into (replayer *r) FINAL OVERRIDE;
2116
2117 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2118
2119 private:
2120 string * make_debug_string () FINAL OVERRIDE;
2121 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2122
2123 private:
2124 rvalue *m_expr;
2125 block *m_default_block;
2126 auto_vec <case_ *> m_cases;
2127 };
2128
2129 class asm_operand : public memento
2130 {
2131 public:
2132 asm_operand (extended_asm *ext_asm,
2133 string *asm_symbolic_name,
2134 string *constraint);
2135
get_symbolic_name()2136 const char *get_symbolic_name () const
2137 {
2138 if (m_asm_symbolic_name)
2139 return m_asm_symbolic_name->c_str ();
2140 else
2141 return NULL;
2142 }
2143
get_constraint()2144 const char *get_constraint () const
2145 {
2146 return m_constraint->c_str ();
2147 }
2148
2149 virtual void print (pretty_printer *pp) const;
2150
2151 private:
2152 string * make_debug_string () FINAL OVERRIDE;
2153
2154 protected:
2155 extended_asm *m_ext_asm;
2156 string *m_asm_symbolic_name;
2157 string *m_constraint;
2158 };
2159
2160 class output_asm_operand : public asm_operand
2161 {
2162 public:
output_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,lvalue * dest)2163 output_asm_operand (extended_asm *ext_asm,
2164 string *asm_symbolic_name,
2165 string *constraint,
2166 lvalue *dest)
2167 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2168 m_dest (dest)
2169 {}
2170
get_lvalue()2171 lvalue *get_lvalue () const { return m_dest; }
2172
replay_into(replayer *)2173 void replay_into (replayer *) FINAL OVERRIDE {}
2174
2175 void print (pretty_printer *pp) const FINAL OVERRIDE;
2176
2177 private:
2178 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2179
2180 private:
2181 lvalue *m_dest;
2182 };
2183
2184 class input_asm_operand : public asm_operand
2185 {
2186 public:
input_asm_operand(extended_asm * ext_asm,string * asm_symbolic_name,string * constraint,rvalue * src)2187 input_asm_operand (extended_asm *ext_asm,
2188 string *asm_symbolic_name,
2189 string *constraint,
2190 rvalue *src)
2191 : asm_operand (ext_asm, asm_symbolic_name, constraint),
2192 m_src (src)
2193 {}
2194
get_rvalue()2195 rvalue *get_rvalue () const { return m_src; }
2196
replay_into(replayer *)2197 void replay_into (replayer *) FINAL OVERRIDE {}
2198
2199 void print (pretty_printer *pp) const FINAL OVERRIDE;
2200
2201 private:
2202 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2203
2204 private:
2205 rvalue *m_src;
2206 };
2207
2208 /* Abstract base class for extended_asm statements. */
2209
2210 class extended_asm : public statement
2211 {
2212 public:
extended_asm(block * b,location * loc,string * asm_template)2213 extended_asm (block *b,
2214 location *loc,
2215 string *asm_template)
2216 : statement (b, loc),
2217 m_asm_template (asm_template),
2218 m_is_volatile (false),
2219 m_is_inline (false)
2220 {}
2221
set_volatile_flag(bool flag)2222 void set_volatile_flag (bool flag) { m_is_volatile = flag; }
set_inline_flag(bool flag)2223 void set_inline_flag (bool flag) { m_is_inline = flag; }
2224
2225 void add_output_operand (const char *asm_symbolic_name,
2226 const char *constraint,
2227 lvalue *dest);
2228 void add_input_operand (const char *asm_symbolic_name,
2229 const char *constraint,
2230 rvalue *src);
2231 void add_clobber (const char *victim);
2232
2233 void replay_into (replayer *r) OVERRIDE;
2234
get_asm_template()2235 string *get_asm_template () const { return m_asm_template; }
2236
2237 virtual bool is_goto () const = 0;
2238 virtual void maybe_print_gotos (pretty_printer *) const = 0;
2239
2240 protected:
2241 void write_flags (reproducer &r);
2242 void write_clobbers (reproducer &r);
2243
2244 private:
2245 string * make_debug_string () FINAL OVERRIDE;
2246 virtual void maybe_populate_playback_blocks
2247 (auto_vec <playback::block *> *out) = 0;
2248
2249 protected:
2250 string *m_asm_template;
2251 bool m_is_volatile;
2252 bool m_is_inline;
2253 auto_vec<output_asm_operand *> m_output_ops;
2254 auto_vec<input_asm_operand *> m_input_ops;
2255 auto_vec<string *> m_clobbers;
2256 };
2257
2258 /* An extended_asm that's not a goto, as created by
2259 gcc_jit_block_add_extended_asm. */
2260
2261 class extended_asm_simple : public extended_asm
2262 {
2263 public:
extended_asm_simple(block * b,location * loc,string * asm_template)2264 extended_asm_simple (block *b,
2265 location *loc,
2266 string *asm_template)
2267 : extended_asm (b, loc, asm_template)
2268 {}
2269
2270 void write_reproducer (reproducer &r) OVERRIDE;
is_goto()2271 bool is_goto () const FINAL OVERRIDE { return false; }
maybe_print_gotos(pretty_printer *)2272 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE {}
2273
2274 private:
maybe_populate_playback_blocks(auto_vec<playback::block * > *)2275 void maybe_populate_playback_blocks
2276 (auto_vec <playback::block *> *) FINAL OVERRIDE
2277 {}
2278 };
2279
2280 /* An extended_asm that's a asm goto, as created by
2281 gcc_jit_block_end_with_extended_asm_goto. */
2282
2283 class extended_asm_goto : public extended_asm
2284 {
2285 public:
2286 extended_asm_goto (block *b,
2287 location *loc,
2288 string *asm_template,
2289 int num_goto_blocks,
2290 block **goto_blocks,
2291 block *fallthrough_block);
2292
2293 void replay_into (replayer *r) FINAL OVERRIDE;
2294 void write_reproducer (reproducer &r) OVERRIDE;
2295
2296 vec <block *> get_successor_blocks () const FINAL OVERRIDE;
2297
is_goto()2298 bool is_goto () const FINAL OVERRIDE { return true; }
2299 void maybe_print_gotos (pretty_printer *) const FINAL OVERRIDE;
2300
2301 private:
2302 void maybe_populate_playback_blocks
2303 (auto_vec <playback::block *> *out) FINAL OVERRIDE;
2304
2305 private:
2306 auto_vec <block *> m_goto_blocks;
2307 block *m_fallthrough_block;
2308 };
2309
2310 /* A group of top-level asm statements, as created by
2311 gcc_jit_context_add_top_level_asm. */
2312
2313 class top_level_asm : public memento
2314 {
2315 public:
2316 top_level_asm (context *ctxt, location *loc, string *asm_stmts);
2317
2318 void write_to_dump (dump &d) FINAL OVERRIDE;
2319
2320 private:
2321 void replay_into (replayer *r) FINAL OVERRIDE;
2322 string * make_debug_string () FINAL OVERRIDE;
2323 void write_reproducer (reproducer &r) FINAL OVERRIDE;
2324
2325 private:
2326 location *m_loc;
2327 string *m_asm_stmts;
2328 };
2329
2330 } // namespace gcc::jit::recording
2331
2332 /* Create a recording::memento_of_new_rvalue_from_const instance and add
2333 it to this context's list of mementos.
2334
2335 Implements the post-error-checking part of
2336 gcc_jit_context_new_rvalue_from_{int|long|double|ptr}. */
2337
2338 template <typename HOST_TYPE>
2339 recording::rvalue *
new_rvalue_from_const(recording::type * type,HOST_TYPE value)2340 recording::context::new_rvalue_from_const (recording::type *type,
2341 HOST_TYPE value)
2342 {
2343 recording::rvalue *result =
2344 new memento_of_new_rvalue_from_const <HOST_TYPE> (this, NULL, type, value);
2345 record (result);
2346 return result;
2347 }
2348
2349 } // namespace gcc::jit
2350
2351 } // namespace gcc
2352
2353 #endif /* JIT_RECORDING_H */
2354