comparison gcc/jit/jit-recording.h @ 111:04ced10e8804

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