jit: New API entrypoint: gcc_jit_context_get_last_error
[official-gcc.git] / gcc / jit / jit-recording.c
bloba9ff3002e32bfb97f20f19a4e26760e02759041a
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
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.
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.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "opts.h"
26 #include "tree.h"
27 #include "pretty-print.h"
29 #include <pthread.h>
31 #include "jit-common.h"
32 #include "jit-builtins.h"
33 #include "jit-logging.h"
34 #include "jit-recording.h"
35 #include "jit-playback.h"
37 namespace gcc {
38 namespace jit {
40 // class dump
42 dump::dump (recording::context &ctxt,
43 const char *filename,
44 bool update_locations)
45 : m_ctxt (ctxt),
46 m_filename (filename),
47 m_update_locations (update_locations),
48 m_line (0),
49 m_column (0)
51 m_file = fopen (filename, "w");
52 if (!m_file)
53 ctxt.add_error (NULL,
54 "error opening dump file %s for writing: %s",
55 filename,
56 xstrerror (errno));
59 dump::~dump ()
61 if (m_file)
63 int err = fclose (m_file);
64 if (err)
65 m_ctxt.add_error (NULL,
66 "error closing dump file %s: %s",
67 m_filename,
68 xstrerror (errno));
72 /* Write the given message to the dump, using printf-formatting
73 conventions, updating the line/column within the dump.
75 Emit an error on the context if a failure occurs. */
77 void
78 dump::write (const char *fmt, ...)
80 va_list ap;
81 char *buf = NULL;
83 /* If there was an error opening the file, we've already reported it.
84 Don't attempt further work. */
85 if (!m_file)
86 return;
88 va_start (ap, fmt);
89 vasprintf (&buf, fmt, ap);
90 va_end (ap);
92 if (!buf)
94 m_ctxt.add_error (NULL, "malloc failure writing to dumpfile %s",
95 m_filename);
96 return;
99 if (fwrite (buf, strlen (buf), 1, m_file) != 1)
100 m_ctxt.add_error (NULL, "error writing to dump file %s",
101 m_filename);
103 /* Update line/column: */
104 for (const char *ptr = buf; *ptr; ptr++)
106 if ('\n' == *ptr)
108 m_line++;
109 m_column = 0;
111 else
112 m_column++;
115 free (buf);
118 /* Construct a gcc::jit::recording::location instance for the current
119 location within the dump. */
121 recording::location *
122 dump::make_location () const
124 return m_ctxt.new_location (m_filename, m_line, m_column);
127 /**********************************************************************
128 Recording.
129 **********************************************************************/
131 /* Get the playback::location for the given recording::location,
132 handling a NULL input with a NULL output. */
134 playback::location *
135 recording::playback_location (replayer *r, recording::location *loc)
137 if (loc)
138 return loc->playback_location (r);
139 else
140 return NULL;
143 /* Get a const char * for the given recording::string
144 handling a NULL input with a NULL output. */
146 const char *
147 recording::playback_string (recording::string *str)
149 if (str)
150 return str->c_str ();
151 else
152 return NULL;
155 /* Get the playback::block for the given recording::block,
156 handling a NULL input with a NULL output. */
158 playback::block *
159 recording::playback_block (recording::block *b)
161 if (b)
162 return b->playback_block ();
163 else
164 return NULL;
167 /* Methods of cc::jit::recording::context. */
169 /* The constructor for gcc::jit::recording::context, used by
170 gcc_jit_context_acquire and gcc_jit_context_new_child_context. */
172 recording::context::context (context *parent_ctxt)
173 : log_user (NULL),
174 m_parent_ctxt (parent_ctxt),
175 m_error_count (0),
176 m_first_error_str (NULL),
177 m_owns_first_error_str (false),
178 m_last_error_str (NULL),
179 m_owns_last_error_str (false),
180 m_mementos (),
181 m_compound_types (),
182 m_functions (),
183 m_FILE_type (NULL),
184 m_builtins_manager(NULL)
186 if (parent_ctxt)
188 /* Inherit options from parent. */
189 for (unsigned i = 0;
190 i < sizeof (m_str_options) / sizeof (m_str_options[0]);
191 i++)
193 const char *parent_opt = parent_ctxt->m_str_options[i];
194 m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL;
196 memcpy (m_int_options,
197 parent_ctxt->m_int_options,
198 sizeof (m_int_options));
199 memcpy (m_bool_options,
200 parent_ctxt->m_bool_options,
201 sizeof (m_bool_options));
202 set_logger (parent_ctxt->get_logger ());
204 else
206 memset (m_str_options, 0, sizeof (m_str_options));
207 memset (m_int_options, 0, sizeof (m_int_options));
208 memset (m_bool_options, 0, sizeof (m_bool_options));
211 memset (m_basic_types, 0, sizeof (m_basic_types));
214 /* The destructor for gcc::jit::recording::context, implicitly used by
215 gcc_jit_context_release. */
217 recording::context::~context ()
219 JIT_LOG_SCOPE (get_logger ());
220 int i;
221 memento *m;
222 FOR_EACH_VEC_ELT (m_mementos, i, m)
224 delete m;
227 for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
228 free (m_str_options[i]);
230 if (m_builtins_manager)
231 delete m_builtins_manager;
233 if (m_owns_first_error_str)
234 free (m_first_error_str);
236 if (m_owns_last_error_str)
237 if (m_last_error_str != m_first_error_str)
238 free (m_last_error_str);
241 /* Add the given mememto to the list of those tracked by this
242 gcc::jit::recording::context, so that e.g. it can be deleted
243 when this context is released. */
245 void
246 recording::context::record (memento *m)
248 gcc_assert (m);
250 m_mementos.safe_push (m);
253 /* Replay this context (and any parents) into the given replayer. */
255 void
256 recording::context::replay_into (replayer *r)
258 JIT_LOG_SCOPE (get_logger ());
259 int i;
260 memento *m;
262 /* If we have a parent context, we must replay it. This will
263 recursively walk backwards up the historical tree, then replay things
264 forwards "in historical order", starting with the ultimate parent
265 context, until we reach the "this" context.
267 Note that we fully replay the parent, then fully replay the child,
268 which means that inter-context references can only exist from child
269 to parent, not the other way around.
271 All of this replaying is suboptimal - it would be better to do the
272 work for the parent context *once*, rather than replaying the parent
273 every time we replay each child. However, fixing this requires deep
274 surgery to lifetime-management: we'd need every context family tree
275 to have its own GC heap, and to initialize the GCC code to use that
276 heap (with a mutex on such a heap). */
277 if (m_parent_ctxt)
278 m_parent_ctxt->replay_into (r);
280 if (r->errors_occurred ())
281 return;
283 /* Replay this context's saved operations into r. */
284 FOR_EACH_VEC_ELT (m_mementos, i, m)
286 /* Disabled low-level debugging, here if we need it: print what
287 we're replaying.
288 Note that the calls to get_debug_string might lead to more
289 mementos being created for the strings.
290 This can also be used to exercise the debug_string
291 machinery. */
292 if (0)
293 printf ("context %p replaying (%p): %s\n",
294 (void *)this, (void *)m, m->get_debug_string ());
296 m->replay_into (r);
298 if (r->errors_occurred ())
299 return;
303 /* During a playback, we associate objects from the recording with
304 their counterparts during this playback.
306 For simplicity, we store this within the recording objects.
308 The following method cleans away these associations, to ensure that
309 we never have out-of-date associations lingering on subsequent
310 playbacks (the objects pointed to are GC-managed, but the
311 recording objects don't own refs to them). */
313 void
314 recording::context::disassociate_from_playback ()
316 JIT_LOG_SCOPE (get_logger ());
317 int i;
318 memento *m;
320 if (m_parent_ctxt)
321 m_parent_ctxt->disassociate_from_playback ();
323 FOR_EACH_VEC_ELT (m_mementos, i, m)
325 m->set_playback_obj (NULL);
329 /* Create a recording::string instance and add it to this context's list
330 of mementos.
332 This creates a fresh copy of the given 0-terminated buffer. */
334 recording::string *
335 recording::context::new_string (const char *text)
337 if (!text)
338 return NULL;
340 recording::string *result = new string (this, text);
341 record (result);
342 return result;
345 /* Create a recording::location instance and add it to this context's
346 list of mementos.
348 Implements the post-error-checking part of
349 gcc_jit_context_new_location. */
351 recording::location *
352 recording::context::new_location (const char *filename,
353 int line,
354 int column)
356 recording::location *result =
357 new recording::location (this,
358 new_string (filename),
359 line, column);
360 record (result);
361 return result;
364 /* If we haven't seen this enum value yet, create a recording::type
365 instance and add it to this context's list of mementos.
367 If we have seen it before, reuse our cached value, so that repeated
368 calls on the context give the same object.
370 If we have a parent context, the cache is within the ultimate
371 ancestor context.
373 Implements the post-error-checking part of
374 gcc_jit_context_get_type. */
376 recording::type *
377 recording::context::get_type (enum gcc_jit_types kind)
379 if (!m_basic_types[kind])
381 if (m_parent_ctxt)
382 m_basic_types[kind] = m_parent_ctxt->get_type (kind);
383 else
385 recording::type *result = new memento_of_get_type (this, kind);
386 record (result);
387 m_basic_types[kind] = result;
391 return m_basic_types[kind];
394 /* Get a recording::type instance for the given size and signedness.
395 This is implemented in terms of recording::context::get_type
396 above.
398 Implements the post-error-checking part of
399 gcc_jit_context_get_int_type. */
401 recording::type *
402 recording::context::get_int_type (int num_bytes, int is_signed)
404 /* We can't use a switch here since some of the values are macros affected
405 by options; e.g. i386.h has
406 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
407 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
408 are in bits, rather than bytes.
410 const int num_bits = num_bytes * 8;
411 if (num_bits == INT_TYPE_SIZE)
412 return get_type (is_signed
413 ? GCC_JIT_TYPE_INT
414 : GCC_JIT_TYPE_UNSIGNED_INT);
415 if (num_bits == CHAR_TYPE_SIZE)
416 return get_type (is_signed
417 ? GCC_JIT_TYPE_SIGNED_CHAR
418 : GCC_JIT_TYPE_UNSIGNED_CHAR);
419 if (num_bits == SHORT_TYPE_SIZE)
420 return get_type (is_signed
421 ? GCC_JIT_TYPE_SHORT
422 : GCC_JIT_TYPE_UNSIGNED_SHORT);
423 if (num_bits == LONG_TYPE_SIZE)
424 return get_type (is_signed
425 ? GCC_JIT_TYPE_LONG
426 : GCC_JIT_TYPE_UNSIGNED_LONG);
427 if (num_bits == LONG_LONG_TYPE_SIZE)
428 return get_type (is_signed
429 ? GCC_JIT_TYPE_LONG_LONG
430 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
432 /* Some other size, not corresponding to the C int types. */
433 /* To be written: support arbitrary other sizes, sharing by
434 memoizing at the recording::context level? */
435 gcc_unreachable ();
438 /* Create a recording::type instance and add it to this context's list
439 of mementos.
441 Implements the post-error-checking part of
442 gcc_jit_context_new_array_type. */
444 recording::type *
445 recording::context::new_array_type (recording::location *loc,
446 recording::type *element_type,
447 int num_elements)
449 if (struct_ *s = element_type->dyn_cast_struct ())
450 if (!s->get_fields ())
452 add_error (NULL,
453 "cannot create an array of type %s"
454 " until the fields have been set",
455 s->get_name ()->c_str ());
456 return NULL;
458 recording::type *result =
459 new recording::array_type (this, loc, element_type, num_elements);
460 record (result);
461 return result;
464 /* Create a recording::field instance and add it to this context's list
465 of mementos.
467 Implements the post-error-checking part of
468 gcc_jit_context_new_field. */
470 recording::field *
471 recording::context::new_field (recording::location *loc,
472 recording::type *type,
473 const char *name)
475 recording::field *result =
476 new recording::field (this, loc, type, new_string (name));
477 record (result);
478 return result;
481 /* Create a recording::struct_ instance and add it to this context's
482 list of mementos and list of compound types.
484 Implements the post-error-checking part of
485 gcc_jit_context_new_struct_type. */
487 recording::struct_ *
488 recording::context::new_struct_type (recording::location *loc,
489 const char *name)
491 recording::struct_ *result = new struct_ (this, loc, new_string (name));
492 record (result);
493 m_compound_types.safe_push (result);
494 return result;
497 /* Create a recording::union_ instance and add it to this context's
498 list of mementos and list of compound types.
500 Implements the first post-error-checking part of
501 gcc_jit_context_new_union_type. */
503 recording::union_ *
504 recording::context::new_union_type (recording::location *loc,
505 const char *name)
507 recording::union_ *result = new union_ (this, loc, new_string (name));
508 record (result);
509 m_compound_types.safe_push (result);
510 return result;
513 /* Create a recording::function_type instance and add it to this context's
514 list of mementos.
516 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
518 recording::function_type *
519 recording::context::new_function_type (recording::type *return_type,
520 int num_params,
521 recording::type **param_types,
522 int is_variadic)
524 recording::function_type *fn_type
525 = new function_type (this,
526 return_type,
527 num_params,
528 param_types,
529 is_variadic);
530 record (fn_type);
531 return fn_type;
534 /* Create a recording::type instance and add it to this context's list
535 of mementos.
537 Implements the post-error-checking part of
538 gcc_jit_context_new_function_ptr_type. */
540 recording::type *
541 recording::context::new_function_ptr_type (recording::location *, /* unused loc */
542 recording::type *return_type,
543 int num_params,
544 recording::type **param_types,
545 int is_variadic)
547 recording::function_type *fn_type
548 = new_function_type (return_type,
549 num_params,
550 param_types,
551 is_variadic);
553 /* Return a pointer-type to the the function type. */
554 return fn_type->get_pointer ();
557 /* Create a recording::param instance and add it to this context's list
558 of mementos.
560 Implements the post-error-checking part of
561 gcc_jit_context_new_param. */
563 recording::param *
564 recording::context::new_param (recording::location *loc,
565 recording::type *type,
566 const char *name)
568 recording::param *result = new recording::param (this, loc, type, new_string (name));
569 record (result);
570 return result;
573 /* Create a recording::function instance and add it to this context's list
574 of mementos and list of functions.
576 Implements the post-error-checking part of
577 gcc_jit_context_new_function. */
579 recording::function *
580 recording::context::new_function (recording::location *loc,
581 enum gcc_jit_function_kind kind,
582 recording::type *return_type,
583 const char *name,
584 int num_params,
585 recording::param **params,
586 int is_variadic,
587 enum built_in_function builtin_id)
589 recording::function *result =
590 new recording::function (this,
591 loc, kind, return_type,
592 new_string (name),
593 num_params, params, is_variadic,
594 builtin_id);
595 record (result);
596 m_functions.safe_push (result);
598 return result;
601 /* Locate the builtins_manager (if any) for this family of contexts,
602 creating it if it doesn't exist already.
604 All of the recording contexts in a family share one builtins_manager:
605 if we have a child context, follow the parent links to get the
606 ultimate ancestor context, and look for it/store it there. */
608 builtins_manager *
609 recording::context::get_builtins_manager ()
611 if (m_parent_ctxt)
612 return m_parent_ctxt->get_builtins_manager ();
614 if (!m_builtins_manager)
615 m_builtins_manager = new builtins_manager (this);
617 return m_builtins_manager;
620 /* Get a recording::function instance, which is lazily-created and added
621 to the context's lists of mementos.
623 Implements the post-error-checking part of
624 gcc_jit_context_get_builtin_function. */
626 recording::function *
627 recording::context::get_builtin_function (const char *name)
629 builtins_manager *bm = get_builtins_manager ();
630 return bm->get_builtin_function (name);
633 /* Create a recording::global instance and add it to this context's list
634 of mementos.
636 Implements the post-error-checking part of
637 gcc_jit_context_new_global. */
639 recording::lvalue *
640 recording::context::new_global (recording::location *loc,
641 recording::type *type,
642 const char *name)
644 recording::lvalue *result =
645 new recording::global (this, loc, type, new_string (name));
646 record (result);
647 return result;
650 /* Create a recording::memento_of_new_rvalue_from_int instance and add
651 it to this context's list of mementos.
653 Implements the post-error-checking part of
654 gcc_jit_context_new_rvalue_from_int. */
656 recording::rvalue *
657 recording::context::new_rvalue_from_int (recording::type *type,
658 int value)
660 recording::rvalue *result =
661 new memento_of_new_rvalue_from_int (this, NULL, type, value);
662 record (result);
663 return result;
666 /* Create a recording::memento_of_new_rvalue_from_double instance and
667 add it to this context's list of mementos.
669 Implements the post-error-checking part of
670 gcc_jit_context_new_rvalue_from_double. */
672 recording::rvalue *
673 recording::context::new_rvalue_from_double (recording::type *type,
674 double value)
676 recording::rvalue *result =
677 new memento_of_new_rvalue_from_double (this, NULL, type, value);
678 record (result);
679 return result;
682 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
683 it to this context's list of mementos.
685 Implements the post-error-checking part of
686 gcc_jit_context_new_rvalue_from_ptr. */
688 recording::rvalue *
689 recording::context::new_rvalue_from_ptr (recording::type *type,
690 void *value)
692 recording::rvalue *result =
693 new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
694 record (result);
695 return result;
698 /* Create a recording::memento_of_new_string_literal instance and add it
699 to this context's list of mementos.
701 Implements the post-error-checking part of
702 gcc_jit_context_new_string_literal. */
704 recording::rvalue *
705 recording::context::new_string_literal (const char *value)
707 recording::rvalue *result =
708 new memento_of_new_string_literal (this, NULL, new_string (value));
709 record (result);
710 return result;
713 /* Create a recording::unary_op instance and add it to this context's
714 list of mementos.
716 Implements the post-error-checking part of
717 gcc_jit_context_new_unary_op. */
719 recording::rvalue *
720 recording::context::new_unary_op (recording::location *loc,
721 enum gcc_jit_unary_op op,
722 recording::type *result_type,
723 recording::rvalue *a)
725 recording::rvalue *result =
726 new unary_op (this, loc, op, result_type, a);
727 record (result);
728 return result;
731 /* Create a recording::binary_op instance and add it to this context's
732 list of mementos.
734 Implements the post-error-checking part of
735 gcc_jit_context_new_binary_op. */
737 recording::rvalue *
738 recording::context::new_binary_op (recording::location *loc,
739 enum gcc_jit_binary_op op,
740 recording::type *result_type,
741 recording::rvalue *a,
742 recording::rvalue *b)
744 recording::rvalue *result =
745 new binary_op (this, loc, op, result_type, a, b);
746 record (result);
747 return result;
750 /* Create a recording::comparison instance and add it to this context's
751 list of mementos.
753 Implements the post-error-checking part of
754 gcc_jit_context_new_comparison. */
756 recording::rvalue *
757 recording::context::new_comparison (recording::location *loc,
758 enum gcc_jit_comparison op,
759 recording::rvalue *a,
760 recording::rvalue *b)
762 recording::rvalue *result = new comparison (this, loc, op, a, b);
763 record (result);
764 return result;
767 /* Create a recording::cast instance and add it to this context's list
768 of mementos.
770 Implements the post-error-checking part of
771 gcc_jit_context_new_cast. */
773 recording::rvalue *
774 recording::context::new_cast (recording::location *loc,
775 recording::rvalue *expr,
776 recording::type *type_)
778 recording::rvalue *result = new cast (this, loc, expr, type_);
779 record (result);
780 return result;
783 /* Create a recording::call instance and add it to this context's list
784 of mementos.
786 Implements the post-error-checking part of
787 gcc_jit_context_new_call. */
789 recording::rvalue *
790 recording::context::new_call (recording::location *loc,
791 function *func,
792 int numargs , recording::rvalue **args)
794 recording::rvalue *result = new call (this, loc, func, numargs, args);
795 record (result);
796 return result;
799 /* Create a recording::call_through_ptr instance and add it to this
800 context's list of mementos.
802 Implements the post-error-checking part of
803 gcc_jit_context_new_call_through_ptr. */
805 recording::rvalue *
806 recording::context::new_call_through_ptr (recording::location *loc,
807 recording::rvalue *fn_ptr,
808 int numargs,
809 recording::rvalue **args)
811 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
812 record (result);
813 return result;
816 /* Create a recording::array_access instance and add it to this context's list
817 of mementos.
819 Implements the post-error-checking part of
820 gcc_jit_context_new_array_access. */
822 recording::lvalue *
823 recording::context::new_array_access (recording::location *loc,
824 recording::rvalue *ptr,
825 recording::rvalue *index)
827 recording::lvalue *result = new array_access (this, loc, ptr, index);
828 record (result);
829 return result;
832 /* Set the given string option for this context, or add an error if
833 it's not recognized.
835 Implements the post-error-checking part of
836 gcc_jit_context_set_str_option. */
838 void
839 recording::context::set_str_option (enum gcc_jit_str_option opt,
840 const char *value)
842 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
844 add_error (NULL,
845 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
846 return;
848 free (m_str_options[opt]);
849 m_str_options[opt] = value ? xstrdup (value) : NULL;
852 /* Set the given integer option for this context, or add an error if
853 it's not recognized.
855 Implements the post-error-checking part of
856 gcc_jit_context_set_int_option. */
858 void
859 recording::context::set_int_option (enum gcc_jit_int_option opt,
860 int value)
862 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
864 add_error (NULL,
865 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
866 return;
868 m_int_options[opt] = value;
871 /* Set the given boolean option for this context, or add an error if
872 it's not recognized.
874 Implements the post-error-checking part of
875 gcc_jit_context_set_bool_option. */
877 void
878 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
879 int value)
881 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
883 add_error (NULL,
884 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
885 return;
887 m_bool_options[opt] = value ? true : false;
890 /* Add the given dumpname/out_ptr pair to this context's list of requested
891 dumps.
893 Implements the post-error-checking part of
894 gcc_jit_context_enable_dump. */
896 void
897 recording::context::enable_dump (const char *dumpname,
898 char **out_ptr)
900 requested_dump d;
901 gcc_assert (dumpname);
902 gcc_assert (out_ptr);
904 d.m_dumpname = dumpname;
905 d.m_out_ptr = out_ptr;
906 *out_ptr = NULL;
907 m_requested_dumps.safe_push (d);
910 /* Validate this context, and if it passes, compile it within a
911 mutex.
913 Implements the post-error-checking part of
914 gcc_jit_context_compile. */
916 result *
917 recording::context::compile ()
919 JIT_LOG_SCOPE (get_logger ());
921 validate ();
923 if (errors_occurred ())
924 return NULL;
926 /* Set up a playback context. */
927 ::gcc::jit::playback::context replayer (this);
929 /* Use it. */
930 result *result_obj = replayer.compile ();
932 return result_obj;
935 /* Format the given error using printf's conventions, print
936 it to stderr, and add it to the context. */
938 void
939 recording::context::add_error (location *loc, const char *fmt, ...)
941 va_list ap;
942 va_start (ap, fmt);
943 add_error_va (loc, fmt, ap);
944 va_end (ap);
947 /* Format the given error using printf's conventions, print
948 it to stderr, and add it to the context. */
950 void
951 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
953 char *malloced_msg;
954 const char *errmsg;
955 bool has_ownership;
957 JIT_LOG_SCOPE (get_logger ());
959 vasprintf (&malloced_msg, fmt, ap);
960 if (malloced_msg)
962 errmsg = malloced_msg;
963 has_ownership = true;
965 else
967 errmsg = "out of memory generating error message";
968 has_ownership = false;
970 if (get_logger ())
971 get_logger ()->log ("error %i: %s", m_error_count, errmsg);
973 const char *ctxt_progname =
974 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
975 if (!ctxt_progname)
976 ctxt_progname = "libgccjit.so";
978 if (loc)
979 fprintf (stderr, "%s: %s: error: %s\n",
980 ctxt_progname,
981 loc->get_debug_string (),
982 errmsg);
983 else
984 fprintf (stderr, "%s: error: %s\n",
985 ctxt_progname,
986 errmsg);
988 if (!m_error_count)
990 m_first_error_str = const_cast <char *> (errmsg);
991 m_owns_first_error_str = has_ownership;
994 if (m_owns_last_error_str)
995 if (m_last_error_str != m_first_error_str)
996 free (m_last_error_str);
997 m_last_error_str = const_cast <char *> (errmsg);
998 m_owns_last_error_str = has_ownership;
1000 m_error_count++;
1003 /* Get the message for the first error that occurred on this context, or
1004 NULL if no errors have occurred on it.
1006 Implements the post-error-checking part of
1007 gcc_jit_context_get_first_error. */
1009 const char *
1010 recording::context::get_first_error () const
1012 return m_first_error_str;
1015 /* Get the message for the last error that occurred on this context, or
1016 NULL if no errors have occurred on it.
1018 Implements the post-error-checking part of
1019 gcc_jit_context_get_last_error. */
1021 const char *
1022 recording::context::get_last_error () const
1024 return m_last_error_str;
1027 /* Lazily generate and record a recording::type representing an opaque
1028 struct named "FILE".
1030 For use if client code tries to dereference the result of
1031 get_type (GCC_JIT_TYPE_FILE_PTR). */
1033 recording::type *
1034 recording::context::get_opaque_FILE_type ()
1036 if (!m_FILE_type)
1037 m_FILE_type = new_struct_type (NULL, "FILE");
1038 return m_FILE_type;
1041 /* Dump a C-like representation of the given context to the given path.
1042 If UPDATE_LOCATIONS is true, update the locations within the
1043 context's mementos to point to the dumpfile.
1045 Implements the post-error-checking part of
1046 gcc_jit_context_dump_to_file. */
1048 void
1049 recording::context::dump_to_file (const char *path, bool update_locations)
1051 int i;
1052 dump d (*this, path, update_locations);
1054 /* Forward declaration of structs and unions. */
1055 compound_type *st;
1056 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1058 d.write ("%s;\n\n", st->get_debug_string ());
1061 /* Content of structs, where set. */
1062 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1063 if (st->get_fields ())
1065 st->get_fields ()->write_to_dump (d);
1066 d.write ("\n");
1069 function *fn;
1070 FOR_EACH_VEC_ELT (m_functions, i, fn)
1072 fn->write_to_dump (d);
1076 /* Copy the requested dumps within this context and all ancestors into
1077 OUT. */
1079 void
1080 recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
1082 if (m_parent_ctxt)
1083 m_parent_ctxt->get_all_requested_dumps (out);
1085 out->reserve (m_requested_dumps.length ());
1086 out->splice (m_requested_dumps);
1089 /* This is a pre-compilation check for the context (and any parents).
1091 Detect errors within the context, adding errors if any are found. */
1093 void
1094 recording::context::validate ()
1096 JIT_LOG_SCOPE (get_logger ());
1098 if (m_parent_ctxt)
1099 m_parent_ctxt->validate ();
1101 int i;
1102 function *fn;
1103 FOR_EACH_VEC_ELT (m_functions, i, fn)
1104 fn->validate ();
1107 /* The implementation of class gcc::jit::recording::memento. */
1109 /* Get a (const char *) debug description of the given memento, by
1110 calling the pure-virtual make_debug_string hook, caching the
1111 result.
1113 It is intended that this should only be called in debugging and
1114 error-handling paths, so this doesn't need to be particularly
1115 optimized. */
1117 const char *
1118 recording::memento::get_debug_string ()
1120 if (!m_debug_string)
1121 m_debug_string = make_debug_string ();
1122 return m_debug_string->c_str ();
1125 /* Default implementation of recording::memento::write_to_dump, writing
1126 an indented form of the memento's debug string to the dump. */
1128 void
1129 recording::memento::write_to_dump (dump &d)
1131 d.write(" %s\n", get_debug_string ());
1134 /* The implementation of class gcc::jit::recording::string. */
1136 /* Constructor for gcc::jit::recording::string::string, allocating a
1137 copy of the given text using new char[]. */
1139 recording::string::string (context *ctxt, const char *text)
1140 : memento (ctxt)
1142 m_len = strlen (text);
1143 m_buffer = new char[m_len + 1];
1144 strcpy (m_buffer, text);
1147 /* Destructor for gcc::jit::recording::string::string. */
1149 recording::string::~string ()
1151 delete[] m_buffer;
1154 /* Function for making gcc::jit::recording::string instances on a
1155 context via printf-style formatting.
1157 It is intended that this should only be called in debugging and
1158 error-handling paths, so this doesn't need to be particularly
1159 optimized, hence the double-copy of the string is acceptable. */
1161 recording::string *
1162 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1164 va_list ap;
1165 char *buf = NULL;
1166 recording::string *result;
1168 va_start (ap, fmt);
1169 vasprintf (&buf, fmt, ap);
1170 va_end (ap);
1172 if (!buf)
1174 ctxt->add_error (NULL, "malloc failure");
1175 return NULL;
1178 result = ctxt->new_string (buf);
1179 free (buf);
1180 return result;
1183 /* Implementation of recording::memento::make_debug_string for strings,
1184 wrapping the given string in quotes and escaping as necessary. */
1186 recording::string *
1187 recording::string::make_debug_string ()
1189 /* Hack to avoid infinite recursion into strings when logging all
1190 mementos: don't re-escape strings: */
1191 if (m_buffer[0] == '"')
1192 return this;
1194 /* Wrap in quotes and do escaping etc */
1196 size_t sz = (1 /* opening quote */
1197 + (m_len * 2) /* each char might get escaped */
1198 + 1 /* closing quote */
1199 + 1); /* nil termintator */
1200 char *tmp = new char[sz];
1201 size_t len = 0;
1203 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1204 APPEND('"'); /* opening quote */
1205 for (size_t i = 0; i < m_len ; i++)
1207 char ch = m_buffer[i];
1208 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1209 APPEND('\\');
1210 APPEND(ch);
1212 APPEND('"'); /* closing quote */
1213 #undef APPEND
1214 tmp[len] = '\0'; /* nil termintator */
1216 string *result = m_ctxt->new_string (tmp);
1218 delete[] tmp;
1219 return result;
1222 /* The implementation of class gcc::jit::recording::location. */
1224 /* Implementation of recording::memento::replay_into for locations.
1226 Create a new playback::location and store it into the
1227 recording::location's m_playback_obj field. */
1229 void
1230 recording::location::replay_into (replayer *r)
1232 m_playback_obj = r->new_location (this,
1233 m_filename->c_str (),
1234 m_line,
1235 m_column);
1238 /* Implementation of recording::memento::make_debug_string for locations,
1239 turning them into the usual form:
1240 FILENAME:LINE:COLUMN
1241 like we do when emitting diagnostics. */
1243 recording::string *
1244 recording::location::make_debug_string ()
1246 return string::from_printf (m_ctxt,
1247 "%s:%i:%i",
1248 m_filename->c_str (), m_line, m_column);
1251 /* The implementation of class gcc::jit::recording::type. */
1253 /* Given a type T, get the type T*.
1255 If this doesn't already exist, generate a new memento_of_get_pointer
1256 instance and add it to this type's context's list of mementos.
1258 Otherwise, use the cached type.
1260 Implements the post-error-checking part of
1261 gcc_jit_type_get_pointer. */
1263 recording::type *
1264 recording::type::get_pointer ()
1266 if (!m_pointer_to_this_type)
1268 m_pointer_to_this_type = new memento_of_get_pointer (this);
1269 m_ctxt->record (m_pointer_to_this_type);
1271 return m_pointer_to_this_type;
1274 /* Given a type T, get the type const T.
1276 Implements the post-error-checking part of
1277 gcc_jit_type_get_const. */
1279 recording::type *
1280 recording::type::get_const ()
1282 recording::type *result = new memento_of_get_const (this);
1283 m_ctxt->record (result);
1284 return result;
1287 /* Given a type T, get the type volatile T.
1289 Implements the post-error-checking part of
1290 gcc_jit_type_get_volatile. */
1292 recording::type *
1293 recording::type::get_volatile ()
1295 recording::type *result = new memento_of_get_volatile (this);
1296 m_ctxt->record (result);
1297 return result;
1300 /* Implementation of pure virtual hook recording::type::dereference for
1301 recording::memento_of_get_type. */
1303 recording::type *
1304 recording::memento_of_get_type::dereference ()
1306 switch (m_kind)
1308 default: gcc_unreachable ();
1310 case GCC_JIT_TYPE_VOID:
1311 return NULL;
1313 case GCC_JIT_TYPE_VOID_PTR:
1314 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1316 case GCC_JIT_TYPE_BOOL:
1317 case GCC_JIT_TYPE_CHAR:
1318 case GCC_JIT_TYPE_SIGNED_CHAR:
1319 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1320 case GCC_JIT_TYPE_SHORT:
1321 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1322 case GCC_JIT_TYPE_INT:
1323 case GCC_JIT_TYPE_UNSIGNED_INT:
1324 case GCC_JIT_TYPE_LONG:
1325 case GCC_JIT_TYPE_UNSIGNED_LONG:
1326 case GCC_JIT_TYPE_LONG_LONG:
1327 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1328 case GCC_JIT_TYPE_FLOAT:
1329 case GCC_JIT_TYPE_DOUBLE:
1330 case GCC_JIT_TYPE_LONG_DOUBLE:
1331 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1332 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1333 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1334 /* Not a pointer: */
1335 return NULL;
1337 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1338 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1340 case GCC_JIT_TYPE_SIZE_T:
1341 /* Not a pointer: */
1342 return NULL;
1344 case GCC_JIT_TYPE_FILE_PTR:
1345 /* Give the client code back an opaque "struct FILE". */
1346 return m_ctxt->get_opaque_FILE_type ();
1350 /* Implementation of pure virtual hook recording::type::is_int for
1351 recording::memento_of_get_type. */
1353 bool
1354 recording::memento_of_get_type::is_int () const
1356 switch (m_kind)
1358 default: gcc_unreachable ();
1360 case GCC_JIT_TYPE_VOID:
1361 return false;
1363 case GCC_JIT_TYPE_VOID_PTR:
1364 return false;
1366 case GCC_JIT_TYPE_BOOL:
1367 return false;
1369 case GCC_JIT_TYPE_CHAR:
1370 case GCC_JIT_TYPE_SIGNED_CHAR:
1371 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1372 case GCC_JIT_TYPE_SHORT:
1373 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1374 case GCC_JIT_TYPE_INT:
1375 case GCC_JIT_TYPE_UNSIGNED_INT:
1376 case GCC_JIT_TYPE_LONG:
1377 case GCC_JIT_TYPE_UNSIGNED_LONG:
1378 case GCC_JIT_TYPE_LONG_LONG:
1379 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1380 return true;
1382 case GCC_JIT_TYPE_FLOAT:
1383 case GCC_JIT_TYPE_DOUBLE:
1384 case GCC_JIT_TYPE_LONG_DOUBLE:
1385 return false;
1387 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1388 return false;
1390 case GCC_JIT_TYPE_SIZE_T:
1391 return true;
1393 case GCC_JIT_TYPE_FILE_PTR:
1394 return false;
1396 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1397 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1398 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1399 return false;
1403 /* Implementation of pure virtual hook recording::type::is_float for
1404 recording::memento_of_get_type. */
1406 bool
1407 recording::memento_of_get_type::is_float () const
1409 switch (m_kind)
1411 default: gcc_unreachable ();
1413 case GCC_JIT_TYPE_VOID:
1414 return false;
1416 case GCC_JIT_TYPE_VOID_PTR:
1417 return false;
1419 case GCC_JIT_TYPE_BOOL:
1420 return false;
1422 case GCC_JIT_TYPE_CHAR:
1423 case GCC_JIT_TYPE_SIGNED_CHAR:
1424 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1425 case GCC_JIT_TYPE_SHORT:
1426 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1427 case GCC_JIT_TYPE_INT:
1428 case GCC_JIT_TYPE_UNSIGNED_INT:
1429 case GCC_JIT_TYPE_LONG:
1430 case GCC_JIT_TYPE_UNSIGNED_LONG:
1431 case GCC_JIT_TYPE_LONG_LONG:
1432 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1433 return false;
1435 case GCC_JIT_TYPE_FLOAT:
1436 case GCC_JIT_TYPE_DOUBLE:
1437 case GCC_JIT_TYPE_LONG_DOUBLE:
1438 return true;
1440 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1441 return false;
1443 case GCC_JIT_TYPE_SIZE_T:
1444 return false;
1446 case GCC_JIT_TYPE_FILE_PTR:
1447 return false;
1449 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1450 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1451 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1452 return true;
1456 /* Implementation of pure virtual hook recording::type::is_bool for
1457 recording::memento_of_get_type. */
1459 bool
1460 recording::memento_of_get_type::is_bool () const
1462 switch (m_kind)
1464 default: gcc_unreachable ();
1466 case GCC_JIT_TYPE_VOID:
1467 return false;
1469 case GCC_JIT_TYPE_VOID_PTR:
1470 return false;
1472 case GCC_JIT_TYPE_BOOL:
1473 return true;
1475 case GCC_JIT_TYPE_CHAR:
1476 case GCC_JIT_TYPE_SIGNED_CHAR:
1477 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1478 case GCC_JIT_TYPE_SHORT:
1479 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1480 case GCC_JIT_TYPE_INT:
1481 case GCC_JIT_TYPE_UNSIGNED_INT:
1482 case GCC_JIT_TYPE_LONG:
1483 case GCC_JIT_TYPE_UNSIGNED_LONG:
1484 case GCC_JIT_TYPE_LONG_LONG:
1485 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1486 return false;
1488 case GCC_JIT_TYPE_FLOAT:
1489 case GCC_JIT_TYPE_DOUBLE:
1490 case GCC_JIT_TYPE_LONG_DOUBLE:
1491 return false;
1493 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1494 return false;
1496 case GCC_JIT_TYPE_SIZE_T:
1497 return false;
1499 case GCC_JIT_TYPE_FILE_PTR:
1500 return false;
1502 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1503 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1504 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1505 return false;
1509 /* Implementation of pure virtual hook recording::memento::replay_into
1510 for recording::memento_of_get_type. */
1512 void
1513 recording::memento_of_get_type::replay_into (replayer *r)
1515 set_playback_obj (r->get_type (m_kind));
1518 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1520 /* Descriptive strings for each of enum gcc_jit_types. */
1522 static const char * const get_type_strings[] = {
1523 "void", /* GCC_JIT_TYPE_VOID */
1524 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1526 "bool", /* GCC_JIT_TYPE_BOOL */
1528 "char", /* GCC_JIT_TYPE_CHAR */
1529 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1530 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1532 "short", /* GCC_JIT_TYPE_SHORT */
1533 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1535 "int", /* GCC_JIT_TYPE_INT */
1536 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1538 "long", /* GCC_JIT_TYPE_LONG */
1539 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1541 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1542 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1544 "float", /* GCC_JIT_TYPE_FLOAT */
1545 "double", /* GCC_JIT_TYPE_DOUBLE */
1546 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1548 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1550 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1552 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1554 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1555 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1556 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1560 /* Implementation of recording::memento::make_debug_string for
1561 results of get_type, using a simple table of type names. */
1563 recording::string *
1564 recording::memento_of_get_type::make_debug_string ()
1566 return m_ctxt->new_string (get_type_strings[m_kind]);
1569 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1571 /* Override of default implementation of
1572 recording::type::accepts_writes_from for get_pointer.
1574 Require a pointer type, and allowing writes to
1575 (const T *) from a (T*), but not the other way around. */
1577 bool
1578 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1580 /* Must be a pointer type: */
1581 type *rtype_points_to = rtype->is_pointer ();
1582 if (!rtype_points_to)
1583 return false;
1585 /* It's OK to assign to a (const T *) from a (T *). */
1586 return m_other_type->unqualified ()
1587 ->accepts_writes_from (rtype_points_to);
1590 /* Implementation of pure virtual hook recording::memento::replay_into
1591 for recording::memento_of_get_pointer. */
1593 void
1594 recording::memento_of_get_pointer::replay_into (replayer *)
1596 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1599 /* Implementation of recording::memento::make_debug_string for
1600 results of get_pointer, adding " *" to the underlying type,
1601 with special-casing to handle function pointer types. */
1603 recording::string *
1604 recording::memento_of_get_pointer::make_debug_string ()
1606 /* Special-case function pointer types, to put the "*" in parens between
1607 the return type and the params (for one level of dereferencing, at
1608 least). */
1609 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1610 return fn_type->make_debug_string_with_ptr ();
1612 return string::from_printf (m_ctxt,
1613 "%s *", m_other_type->get_debug_string ());
1616 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1618 /* Implementation of pure virtual hook recording::memento::replay_into
1619 for recording::memento_of_get_const. */
1621 void
1622 recording::memento_of_get_const::replay_into (replayer *)
1624 set_playback_obj (m_other_type->playback_type ()->get_const ());
1627 /* Implementation of recording::memento::make_debug_string for
1628 results of get_const, prepending "const ". */
1630 recording::string *
1631 recording::memento_of_get_const::make_debug_string ()
1633 return string::from_printf (m_ctxt,
1634 "const %s", m_other_type->get_debug_string ());
1637 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1639 /* Implementation of pure virtual hook recording::memento::replay_into
1640 for recording::memento_of_get_volatile. */
1642 void
1643 recording::memento_of_get_volatile::replay_into (replayer *)
1645 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1648 /* Implementation of recording::memento::make_debug_string for
1649 results of get_volatile, prepending "volatile ". */
1651 recording::string *
1652 recording::memento_of_get_volatile::make_debug_string ()
1654 return string::from_printf (m_ctxt,
1655 "volatile %s", m_other_type->get_debug_string ());
1658 /* The implementation of class gcc::jit::recording::array_type */
1660 /* Implementation of pure virtual hook recording::type::dereference for
1661 recording::array_type. */
1663 recording::type *
1664 recording::array_type::dereference ()
1666 return m_element_type;
1669 /* Implementation of pure virtual hook recording::memento::replay_into
1670 for recording::array_type. */
1672 void
1673 recording::array_type::replay_into (replayer *r)
1675 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1676 m_element_type->playback_type (),
1677 m_num_elements));
1680 /* Implementation of recording::memento::make_debug_string for
1681 results of new_array_type. */
1683 recording::string *
1684 recording::array_type::make_debug_string ()
1686 return string::from_printf (m_ctxt,
1687 "%s[%d]",
1688 m_element_type->get_debug_string (),
1689 m_num_elements);
1692 /* The implementation of class gcc::jit::recording::function_type */
1694 /* Constructor for gcc::jit::recording::function_type. */
1696 recording::function_type::function_type (context *ctxt,
1697 type *return_type,
1698 int num_params,
1699 type **param_types,
1700 int is_variadic)
1701 : type (ctxt),
1702 m_return_type (return_type),
1703 m_param_types (),
1704 m_is_variadic (is_variadic)
1706 for (int i = 0; i< num_params; i++)
1707 m_param_types.safe_push (param_types[i]);
1710 /* Implementation of pure virtual hook recording::type::dereference for
1711 recording::function_type. */
1713 recording::type *
1714 recording::function_type::dereference ()
1716 return NULL;
1719 /* Implementation of pure virtual hook recording::memento::replay_into
1720 for recording::function_type. */
1722 void
1723 recording::function_type::replay_into (replayer *r)
1725 /* Convert m_param_types to a vec of playback type. */
1726 auto_vec <playback::type *> param_types;
1727 int i;
1728 recording::type *type;
1729 param_types.create (m_param_types.length ());
1730 FOR_EACH_VEC_ELT (m_param_types, i, type)
1731 param_types.safe_push (type->playback_type ());
1733 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1734 &param_types,
1735 m_is_variadic));
1738 /* Special-casing for make_debug_string for get_pointer results for
1739 handling (one level) of pointers to functions. */
1741 recording::string *
1742 recording::function_type::make_debug_string_with_ptr ()
1744 return make_debug_string_with ("(*) ");
1747 /* Implementation of recording::memento::make_debug_string for
1748 results of new_function_type. */
1750 recording::string *
1751 recording::function_type::make_debug_string ()
1753 return make_debug_string_with ("");
1756 /* Build a debug string representation of the form:
1758 RESULT_TYPE INSERT (PARAM_TYPES)
1760 for use when handling 0 and 1 level of indirection to this
1761 function type. */
1763 recording::string *
1764 recording::function_type::make_debug_string_with (const char *insert)
1766 /* First, build a buffer for the arguments. */
1767 /* Calculate length of said buffer. */
1768 size_t sz = 1; /* nil terminator */
1769 for (unsigned i = 0; i< m_param_types.length (); i++)
1771 sz += strlen (m_param_types[i]->get_debug_string ());
1772 sz += 2; /* ", " separator */
1774 if (m_is_variadic)
1775 sz += 5; /* ", ..." separator and ellipsis */
1777 /* Now allocate and populate the buffer. */
1778 char *argbuf = new char[sz];
1779 size_t len = 0;
1781 for (unsigned i = 0; i< m_param_types.length (); i++)
1783 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1784 len += strlen (m_param_types[i]->get_debug_string ());
1785 if (i + 1 < m_param_types.length ())
1787 strcpy (argbuf + len, ", ");
1788 len += 2;
1791 if (m_is_variadic)
1793 if (m_param_types.length ())
1795 strcpy (argbuf + len, ", ");
1796 len += 2;
1798 strcpy (argbuf + len, "...");
1799 len += 3;
1801 argbuf[len] = '\0';
1803 /* ...and use it to get the string for the call as a whole. */
1804 string *result = string::from_printf (m_ctxt,
1805 "%s %s(%s)",
1806 m_return_type->get_debug_string (),
1807 insert,
1808 argbuf);
1810 delete[] argbuf;
1812 return result;
1815 /* The implementation of class gcc::jit::recording::field. */
1817 /* Implementation of pure virtual hook recording::memento::replay_into
1818 for recording::field. */
1820 void
1821 recording::field::replay_into (replayer *r)
1823 set_playback_obj (r->new_field (playback_location (r, m_loc),
1824 m_type->playback_type (),
1825 playback_string (m_name)));
1828 /* Override the default implementation of
1829 recording::memento::write_to_dump. Dump each field
1830 by dumping a line of the form:
1831 TYPE NAME;
1832 so that we can build up a struct/union field-byfield. */
1834 void
1835 recording::field::write_to_dump (dump &d)
1837 d.write (" %s %s;\n",
1838 m_type->get_debug_string (),
1839 m_name->c_str ());
1842 /* Implementation of recording::memento::make_debug_string for
1843 results of new_field. */
1845 recording::string *
1846 recording::field::make_debug_string ()
1848 return m_name;
1851 /* The implementation of class gcc::jit::recording::compound_type */
1853 /* The constructor for gcc::jit::recording::compound_type. */
1855 recording::compound_type::compound_type (context *ctxt,
1856 location *loc,
1857 string *name)
1858 : type (ctxt),
1859 m_loc (loc),
1860 m_name (name),
1861 m_fields (NULL)
1865 /* Set the fields of a compound type.
1867 Implements the post-error-checking part of
1868 gcc_jit_struct_set_fields, and is also used by
1869 gcc_jit_context_new_union_type. */
1871 void
1872 recording::compound_type::set_fields (location *loc,
1873 int num_fields,
1874 field **field_array)
1876 m_loc = loc;
1877 gcc_assert (NULL == m_fields);
1879 m_fields = new fields (this, num_fields, field_array);
1880 m_ctxt->record (m_fields);
1883 /* Implementation of pure virtual hook recording::type::dereference for
1884 recording::compound_type. */
1886 recording::type *
1887 recording::compound_type::dereference ()
1889 return NULL; /* not a pointer */
1892 /* The implementation of class gcc::jit::recording::struct_. */
1894 /* The constructor for gcc::jit::recording::struct_. */
1896 recording::struct_::struct_ (context *ctxt,
1897 location *loc,
1898 string *name)
1899 : compound_type (ctxt, loc, name)
1903 /* Implementation of pure virtual hook recording::memento::replay_into
1904 for recording::struct_. */
1906 void
1907 recording::struct_::replay_into (replayer *r)
1909 set_playback_obj (
1910 r->new_compound_type (playback_location (r, get_loc ()),
1911 get_name ()->c_str (),
1912 true /* is_struct */));
1915 /* Implementation of recording::memento::make_debug_string for
1916 structs. */
1918 recording::string *
1919 recording::struct_::make_debug_string ()
1921 return string::from_printf (m_ctxt,
1922 "struct %s", get_name ()->c_str ());
1925 /* The implementation of class gcc::jit::recording::union_. */
1927 /* The constructor for gcc::jit::recording::union_. */
1929 recording::union_::union_ (context *ctxt,
1930 location *loc,
1931 string *name)
1932 : compound_type (ctxt, loc, name)
1936 /* Implementation of pure virtual hook recording::memento::replay_into
1937 for recording::union_. */
1939 void
1940 recording::union_::replay_into (replayer *r)
1942 set_playback_obj (
1943 r->new_compound_type (playback_location (r, get_loc ()),
1944 get_name ()->c_str (),
1945 false /* is_struct */));
1948 /* Implementation of recording::memento::make_debug_string for
1949 unions. */
1951 recording::string *
1952 recording::union_::make_debug_string ()
1954 return string::from_printf (m_ctxt,
1955 "union %s", get_name ()->c_str ());
1958 /* The implementation of class gcc::jit::recording::fields. */
1960 /* The constructor for gcc::jit::recording::fields. */
1962 recording::fields::fields (compound_type *struct_or_union,
1963 int num_fields,
1964 field **fields)
1965 : memento (struct_or_union->m_ctxt),
1966 m_struct_or_union (struct_or_union),
1967 m_fields ()
1969 for (int i = 0; i < num_fields; i++)
1971 gcc_assert (fields[i]->get_container () == NULL);
1972 fields[i]->set_container (m_struct_or_union);
1973 m_fields.safe_push (fields[i]);
1977 /* Implementation of pure virtual hook recording::memento::replay_into
1978 for recording::fields. */
1980 void
1981 recording::fields::replay_into (replayer *)
1983 auto_vec<playback::field *> playback_fields;
1984 playback_fields.create (m_fields.length ());
1985 for (unsigned i = 0; i < m_fields.length (); i++)
1986 playback_fields.safe_push (m_fields[i]->playback_field ());
1987 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1990 /* Override the default implementation of
1991 recording::memento::write_to_dump by writing a union/struct
1992 declaration of this form:
1994 struct/union NAME {
1995 TYPE_1 NAME_1;
1996 TYPE_2 NAME_2;
1997 ....
1998 TYPE_N NAME_N;
2001 to the dump. */
2003 void
2004 recording::fields::write_to_dump (dump &d)
2006 int i;
2007 field *f;
2009 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
2010 FOR_EACH_VEC_ELT (m_fields, i, f)
2011 f->write_to_dump (d);
2012 d.write ("};\n");
2015 /* Implementation of recording::memento::make_debug_string for
2016 field tables. */
2018 recording::string *
2019 recording::fields::make_debug_string ()
2021 return string::from_printf (m_ctxt,
2022 "fields");
2025 /* The implementation of class gcc::jit::recording::rvalue. */
2027 /* Create a recording::access_field_rvalue instance and add it to
2028 the rvalue's context's list of mementos.
2030 Implements the post-error-checking part of
2031 gcc_jit_rvalue_access_field. */
2033 recording::rvalue *
2034 recording::rvalue::access_field (recording::location *loc,
2035 field *field)
2037 recording::rvalue *result =
2038 new access_field_rvalue (m_ctxt, loc, this, field);
2039 m_ctxt->record (result);
2040 return result;
2043 /* Create a recording::dereference_field_rvalue instance and add it to
2044 the rvalue's context's list of mementos.
2046 Implements the post-error-checking part of
2047 gcc_jit_rvalue_dereference_field. */
2049 recording::lvalue *
2050 recording::rvalue::dereference_field (recording::location *loc,
2051 field *field)
2053 recording::lvalue *result =
2054 new dereference_field_rvalue (m_ctxt, loc, this, field);
2055 m_ctxt->record (result);
2056 return result;
2059 /* Create a recording::dereference_rvalue instance and add it to the
2060 rvalue's context's list of mementos.
2062 Implements the post-error-checking part of
2063 gcc_jit_rvalue_dereference. */
2065 recording::lvalue *
2066 recording::rvalue::dereference (recording::location *loc)
2068 recording::lvalue *result =
2069 new dereference_rvalue (m_ctxt, loc, this);
2070 m_ctxt->record (result);
2071 return result;
2074 /* The implementation of class gcc::jit::recording::lvalue. */
2076 /* Create a recording::new_access_field_of_lvalue instance and add it to
2077 the lvalue's context's list of mementos.
2079 Implements the post-error-checking part of
2080 gcc_jit_lvalue_access_field. */
2082 recording::lvalue *
2083 recording::lvalue::access_field (recording::location *loc,
2084 field *field)
2086 recording::lvalue *result =
2087 new access_field_of_lvalue (m_ctxt, loc, this, field);
2088 m_ctxt->record (result);
2089 return result;
2092 /* Create a recording::get_address_of_lvalue instance and add it to
2093 the lvalue's context's list of mementos.
2095 Implements the post-error-checking part of
2096 gcc_jit_lvalue_get_address. */
2098 recording::rvalue *
2099 recording::lvalue::get_address (recording::location *loc)
2101 recording::rvalue *result =
2102 new get_address_of_lvalue (m_ctxt, loc, this);
2103 m_ctxt->record (result);
2104 return result;
2107 /* The implementation of class gcc::jit::recording::param. */
2109 /* Implementation of pure virtual hook recording::memento::replay_into
2110 for recording::param. */
2112 void
2113 recording::param::replay_into (replayer *r)
2115 set_playback_obj (r->new_param (playback_location (r, m_loc),
2116 m_type->playback_type (),
2117 m_name->c_str ()));
2121 /* The implementation of class gcc::jit::recording::function. */
2123 /* gcc::jit::recording::function's constructor. */
2125 recording::function::function (context *ctxt,
2126 recording::location *loc,
2127 enum gcc_jit_function_kind kind,
2128 type *return_type,
2129 recording::string *name,
2130 int num_params,
2131 recording::param **params,
2132 int is_variadic,
2133 enum built_in_function builtin_id)
2134 : memento (ctxt),
2135 m_loc (loc),
2136 m_kind (kind),
2137 m_return_type (return_type),
2138 m_name (name),
2139 m_params (),
2140 m_is_variadic (is_variadic),
2141 m_builtin_id (builtin_id),
2142 m_locals (),
2143 m_blocks ()
2145 for (int i = 0; i< num_params; i++)
2146 m_params.safe_push (params[i]);
2149 /* Implementation of pure virtual hook recording::memento::replay_into
2150 for recording::function. */
2152 void
2153 recording::function::replay_into (replayer *r)
2155 /* Convert m_params to a vec of playback param. */
2156 auto_vec <playback::param *> params;
2157 int i;
2158 recording::param *param;
2159 params.create (m_params.length ());
2160 FOR_EACH_VEC_ELT (m_params, i, param)
2161 params.safe_push (param->playback_param ());
2163 set_playback_obj (r->new_function (playback_location (r, m_loc),
2164 m_kind,
2165 m_return_type->playback_type (),
2166 m_name->c_str (),
2167 &params,
2168 m_is_variadic,
2169 m_builtin_id));
2172 /* Create a recording::local instance and add it to
2173 the functions's context's list of mementos, and to the function's
2174 list of locals.
2176 Implements the post-error-checking part of
2177 gcc_jit_function_new_local. */
2179 recording::lvalue *
2180 recording::function::new_local (recording::location *loc,
2181 type *type,
2182 const char *name)
2184 local *result = new local (this, loc, type, new_string (name));
2185 m_ctxt->record (result);
2186 m_locals.safe_push (result);
2187 return result;
2190 /* Create a recording::block instance and add it to
2191 the functions's context's list of mementos, and to the function's
2192 list of blocks.
2194 Implements the post-error-checking part of
2195 gcc_jit_function_new_block. */
2197 recording::block*
2198 recording::function::new_block (const char *name)
2200 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2202 recording::block *result =
2203 new recording::block (this, m_blocks.length (), new_string (name));
2204 m_ctxt->record (result);
2205 m_blocks.safe_push (result);
2206 return result;
2209 /* Override the default implementation of
2210 recording::memento::write_to_dump by dumping a C-like
2211 representation of the function; either like a prototype
2212 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2213 all other kinds of function. */
2215 void
2216 recording::function::write_to_dump (dump &d)
2218 switch (m_kind)
2220 default: gcc_unreachable ();
2221 case GCC_JIT_FUNCTION_EXPORTED:
2222 case GCC_JIT_FUNCTION_IMPORTED:
2223 d.write ("extern ");
2224 break;
2225 case GCC_JIT_FUNCTION_INTERNAL:
2226 d.write ("static ");
2227 break;
2228 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2229 d.write ("static inline ");
2230 break;
2232 d.write ("%s\n", m_return_type->get_debug_string ());
2234 if (d.update_locations ())
2235 m_loc = d.make_location ();
2237 d.write ("%s (", get_debug_string ());
2239 int i;
2240 recording::param *param;
2241 FOR_EACH_VEC_ELT (m_params, i, param)
2243 if (i > 0)
2244 d.write (", ");
2245 d.write ("%s %s",
2246 param->get_type ()->get_debug_string (),
2247 param->get_debug_string ());
2249 d.write (")");
2250 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2252 d.write ("; /* (imported) */\n\n");
2254 else
2256 int i;
2257 local *var = NULL;
2258 block *b;
2259 d.write ("\n{\n");
2261 /* Write locals: */
2262 FOR_EACH_VEC_ELT (m_locals, i, var)
2263 var->write_to_dump (d);
2264 if (m_locals.length ())
2265 d.write ("\n");
2267 /* Write each block: */
2268 FOR_EACH_VEC_ELT (m_blocks, i, b)
2270 if (i > 0)
2271 d.write ("\n");
2272 b->write_to_dump (d);
2275 d.write ("}\n\n");
2279 /* Pre-compilation validation of a function, for those things we can't
2280 check until the context is (supposedly) fully-populated. */
2282 void
2283 recording::function::validate ()
2285 /* Complain about empty functions with non-void return type. */
2286 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2287 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2288 if (0 == m_blocks.length ())
2289 m_ctxt->add_error (m_loc,
2290 "function %s returns non-void (type: %s)"
2291 " but has no blocks",
2292 get_debug_string (),
2293 m_return_type->get_debug_string ());
2295 /* Check that all blocks are terminated. */
2296 int num_invalid_blocks = 0;
2298 int i;
2299 block *b;
2301 FOR_EACH_VEC_ELT (m_blocks, i, b)
2302 if (!b->validate ())
2303 num_invalid_blocks++;
2306 /* Check that all blocks are reachable. */
2307 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2309 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2310 flag, starting at the initial block. */
2311 auto_vec<block *> worklist (m_blocks.length ());
2312 worklist.safe_push (m_blocks[0]);
2313 while (worklist.length () > 0)
2315 block *b = worklist.pop ();
2316 b->m_is_reachable = true;
2318 /* Add successor blocks that aren't yet marked to the worklist. */
2319 /* We checked that each block has a terminating statement above . */
2320 block *next1, *next2;
2321 int n = b->get_successor_blocks (&next1, &next2);
2322 switch (n)
2324 default:
2325 gcc_unreachable ();
2326 case 2:
2327 if (!next2->m_is_reachable)
2328 worklist.safe_push (next2);
2329 /* fallthrough */
2330 case 1:
2331 if (!next1->m_is_reachable)
2332 worklist.safe_push (next1);
2333 break;
2334 case 0:
2335 break;
2339 /* Now complain about any blocks that haven't been marked. */
2341 int i;
2342 block *b;
2343 FOR_EACH_VEC_ELT (m_blocks, i, b)
2344 if (!b->m_is_reachable)
2345 m_ctxt->add_error (b->get_loc (),
2346 "unreachable block: %s",
2347 b->get_debug_string ());
2352 /* Implements the post-error-checking part of
2353 gcc_jit_function_dump_to_dot. */
2355 void
2356 recording::function::dump_to_dot (const char *path)
2358 FILE *fp = fopen (path, "w");
2359 if (!fp)
2360 return;
2362 pretty_printer the_pp;
2363 the_pp.buffer->stream = fp;
2365 pretty_printer *pp = &the_pp;
2367 pp_printf (pp,
2368 "digraph %s {\n", get_debug_string ());
2370 /* Blocks: */
2372 int i;
2373 block *b;
2374 FOR_EACH_VEC_ELT (m_blocks, i, b)
2375 b->dump_to_dot (pp);
2378 /* Edges: */
2380 int i;
2381 block *b;
2382 FOR_EACH_VEC_ELT (m_blocks, i, b)
2383 b->dump_edges_to_dot (pp);
2386 pp_printf (pp, "}\n");
2387 pp_flush (pp);
2388 fclose (fp);
2391 /* Implementation of recording::memento::make_debug_string for
2392 functions. */
2394 recording::string *
2395 recording::function::make_debug_string ()
2397 return m_name;
2400 /* The implementation of class gcc::jit::recording::block. */
2402 /* Create a recording::eval instance and add it to
2403 the block's context's list of mementos, and to the block's
2404 list of statements.
2406 Implements the post-error-checking part of
2407 gcc_jit_block_add_eval. */
2409 void
2410 recording::block::add_eval (recording::location *loc,
2411 recording::rvalue *rvalue)
2413 statement *result = new eval (this, loc, rvalue);
2414 m_ctxt->record (result);
2415 m_statements.safe_push (result);
2418 /* Create a recording::assignment instance and add it to
2419 the block's context's list of mementos, and to the block's
2420 list of statements.
2422 Implements the post-error-checking part of
2423 gcc_jit_block_add_assignment. */
2425 void
2426 recording::block::add_assignment (recording::location *loc,
2427 recording::lvalue *lvalue,
2428 recording::rvalue *rvalue)
2430 statement *result = new assignment (this, loc, lvalue, rvalue);
2431 m_ctxt->record (result);
2432 m_statements.safe_push (result);
2435 /* Create a recording::assignment_op instance and add it to
2436 the block's context's list of mementos, and to the block's
2437 list of statements.
2439 Implements the post-error-checking part of
2440 gcc_jit_block_add_assignment_op. */
2442 void
2443 recording::block::add_assignment_op (recording::location *loc,
2444 recording::lvalue *lvalue,
2445 enum gcc_jit_binary_op op,
2446 recording::rvalue *rvalue)
2448 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2449 m_ctxt->record (result);
2450 m_statements.safe_push (result);
2453 /* Create a recording::comment instance and add it to
2454 the block's context's list of mementos, and to the block's
2455 list of statements.
2457 Implements the post-error-checking part of
2458 gcc_jit_block_add_comment. */
2460 void
2461 recording::block::add_comment (recording::location *loc,
2462 const char *text)
2464 statement *result = new comment (this, loc, new_string (text));
2465 m_ctxt->record (result);
2466 m_statements.safe_push (result);
2469 /* Create a recording::end_with_conditional instance and add it to
2470 the block's context's list of mementos, and to the block's
2471 list of statements.
2473 Implements the post-error-checking part of
2474 gcc_jit_block_end_with_conditional. */
2476 void
2477 recording::block::end_with_conditional (recording::location *loc,
2478 recording::rvalue *boolval,
2479 recording::block *on_true,
2480 recording::block *on_false)
2482 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2483 m_ctxt->record (result);
2484 m_statements.safe_push (result);
2485 m_has_been_terminated = true;
2488 /* Create a recording::end_with_jump instance and add it to
2489 the block's context's list of mementos, and to the block's
2490 list of statements.
2492 Implements the post-error-checking part of
2493 gcc_jit_block_end_with_jump. */
2495 void
2496 recording::block::end_with_jump (recording::location *loc,
2497 recording::block *target)
2499 statement *result = new jump (this, loc, target);
2500 m_ctxt->record (result);
2501 m_statements.safe_push (result);
2502 m_has_been_terminated = true;
2505 /* Create a recording::end_with_return instance and add it to
2506 the block's context's list of mementos, and to the block's
2507 list of statements.
2509 Implements the post-error-checking parts of
2510 gcc_jit_block_end_with_return and
2511 gcc_jit_block_end_with_void_return. */
2513 void
2514 recording::block::end_with_return (recording::location *loc,
2515 recording::rvalue *rvalue)
2517 /* This is used by both gcc_jit_function_add_return and
2518 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2519 the former and NULL for the latter. */
2520 statement *result = new return_ (this, loc, rvalue);
2521 m_ctxt->record (result);
2522 m_statements.safe_push (result);
2523 m_has_been_terminated = true;
2526 /* Override the default implementation of
2527 recording::memento::write_to_dump for blocks by writing
2528 an unindented block name as a label, followed by the indented
2529 statements:
2531 BLOCK_NAME:
2532 STATEMENT_1;
2533 STATEMENT_2;
2535 STATEMENT_N; */
2537 void
2538 recording::block::write_to_dump (dump &d)
2540 d.write ("%s:\n", get_debug_string ());
2542 int i;
2543 statement *s;
2544 FOR_EACH_VEC_ELT (m_statements, i, s)
2545 s->write_to_dump (d);
2548 /* Validate a block by ensuring that it has been terminated. */
2550 bool
2551 recording::block::validate ()
2553 if (!has_been_terminated ())
2555 statement *stmt = get_last_statement ();
2556 location *loc = stmt ? stmt->get_loc () : NULL;
2557 m_func->get_context ()->add_error (loc,
2558 "unterminated block in %s: %s",
2559 m_func->get_debug_string (),
2560 get_debug_string ());
2561 return false;
2564 return true;
2567 /* Get the source-location of a block by using that of the first
2568 statement within it, if any. */
2570 recording::location *
2571 recording::block::get_loc () const
2573 recording::statement *stmt = get_first_statement ();
2574 if (stmt)
2575 return stmt->get_loc ();
2576 else
2577 return NULL;
2580 /* Get the first statement within a block, if any. */
2582 recording::statement *
2583 recording::block::get_first_statement () const
2585 if (m_statements.length ())
2586 return m_statements[0];
2587 else
2588 return NULL;
2591 /* Get the last statement within a block, if any. */
2593 recording::statement *
2594 recording::block::get_last_statement () const
2596 if (m_statements.length ())
2597 return m_statements[m_statements.length () - 1];
2598 else
2599 return NULL;
2602 /* Assuming that this block has been terminated, get the number of
2603 successor blocks, which will be 0, 1 or 2, for return, unconditional
2604 jump, and conditional jump respectively.
2605 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2606 is written to NEXT1, and the second (if any) to NEXT2.
2608 Used when validating functions, and when dumping dot representations
2609 of them. */
2612 recording::block::get_successor_blocks (block **next1, block **next2) const
2614 gcc_assert (m_has_been_terminated);
2615 gcc_assert (next1);
2616 gcc_assert (next2);
2617 statement *last_statement = get_last_statement ();
2618 gcc_assert (last_statement);
2619 return last_statement->get_successor_blocks (next1, next2);
2622 /* Implementation of pure virtual hook recording::memento::replay_into
2623 for recording::block. */
2625 void
2626 recording::block::replay_into (replayer *)
2628 set_playback_obj (m_func->playback_function ()
2629 ->new_block (playback_string (m_name)));
2632 /* Implementation of recording::memento::make_debug_string for
2633 blocks. */
2635 recording::string *
2636 recording::block::make_debug_string ()
2638 if (m_name)
2639 return m_name;
2640 else
2641 return string::from_printf (m_ctxt,
2642 "<UNNAMED BLOCK %p>",
2643 (void *)this);
2646 /* Dump a block in graphviz form into PP, capturing the block name (if
2647 any) and the statements. */
2649 void
2650 recording::block::dump_to_dot (pretty_printer *pp)
2652 pp_printf (pp,
2653 ("\tblock_%d "
2654 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2655 m_index);
2656 pp_write_text_to_stream (pp);
2657 if (m_name)
2659 pp_string (pp, m_name->c_str ());
2660 pp_string (pp, ":");
2661 pp_newline (pp);
2662 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2665 int i;
2666 statement *s;
2667 FOR_EACH_VEC_ELT (m_statements, i, s)
2669 pp_string (pp, s->get_debug_string ());
2670 pp_newline (pp);
2671 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2674 pp_printf (pp,
2675 "}\"];\n\n");
2676 pp_flush (pp);
2679 /* Dump the out-edges of the block in graphviz form into PP. */
2681 void
2682 recording::block::dump_edges_to_dot (pretty_printer *pp)
2684 block *next[2];
2685 int num_succs = get_successor_blocks (&next[0], &next[1]);
2686 for (int i = 0; i < num_succs; i++)
2687 pp_printf (pp,
2688 "\tblock_%d:s -> block_%d:n;\n",
2689 m_index, next[i]->m_index);
2692 /* The implementation of class gcc::jit::recording::global. */
2694 /* Implementation of pure virtual hook recording::memento::replay_into
2695 for recording::global. */
2697 void
2698 recording::global::replay_into (replayer *r)
2700 set_playback_obj (r->new_global (playback_location (r, m_loc),
2701 m_type->playback_type (),
2702 playback_string (m_name)));
2705 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2707 /* Implementation of pure virtual hook recording::memento::replay_into
2708 for recording::memento_of_new_rvalue_from_int. */
2710 void
2711 recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
2713 set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
2714 m_value));
2717 /* Implementation of recording::memento::make_debug_string for
2718 rvalue_from_int, rendering it as
2719 (TYPE)LITERAL
2720 e.g.
2721 "(int)42". */
2723 recording::string *
2724 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2726 return string::from_printf (m_ctxt,
2727 "(%s)%i",
2728 m_type->get_debug_string (),
2729 m_value);
2732 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2734 /* Implementation of pure virtual hook recording::memento::replay_into
2735 for recording::memento_of_new_rvalue_from_double. */
2737 void
2738 recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
2740 set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
2741 m_value));
2744 /* Implementation of recording::memento::make_debug_string for
2745 rvalue_from_double, rendering it as
2746 (TYPE)LITERAL
2747 e.g.
2748 "(float)42.0". */
2750 recording::string *
2751 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2753 return string::from_printf (m_ctxt,
2754 "(%s)%f",
2755 m_type->get_debug_string (),
2756 m_value);
2759 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2761 /* Implementation of pure virtual hook recording::memento::replay_into
2762 for recording::memento_of_new_rvalue_from_ptr. */
2764 void
2765 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
2767 set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
2768 m_value));
2771 /* Implementation of recording::memento::make_debug_string for
2772 rvalue_from_ptr, rendering it as
2773 (TYPE)HEX
2774 e.g.
2775 "(int *)0xdeadbeef"
2777 Zero is rendered as NULL e.g.
2778 "(int *)NULL". */
2780 recording::string *
2781 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2783 if (m_value != NULL)
2784 return string::from_printf (m_ctxt,
2785 "(%s)%p",
2786 m_type->get_debug_string (), m_value);
2787 else
2788 return string::from_printf (m_ctxt,
2789 "(%s)NULL",
2790 m_type->get_debug_string ());
2793 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2795 /* Implementation of pure virtual hook recording::memento::replay_into
2796 for recording::memento_of_new_string_literal. */
2798 void
2799 recording::memento_of_new_string_literal::replay_into (replayer *r)
2801 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2804 /* Implementation of recording::memento::make_debug_string for
2805 string literals. */
2807 recording::string *
2808 recording::memento_of_new_string_literal::make_debug_string ()
2810 return string::from_printf (m_ctxt,
2811 m_value->get_debug_string ());
2814 /* The implementation of class gcc::jit::recording::unary_op. */
2816 /* Implementation of pure virtual hook recording::memento::replay_into
2817 for recording::unary_op. */
2819 void
2820 recording::unary_op::replay_into (replayer *r)
2822 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2823 m_op,
2824 get_type ()->playback_type (),
2825 m_a->playback_rvalue ()));
2828 /* Implementation of recording::memento::make_debug_string for
2829 unary ops. */
2831 static const char * const unary_op_strings[] = {
2832 "-", /* GCC_JIT_UNARY_OP_MINUS */
2833 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2834 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2835 "abs ", /* GCC_JIT_UNARY_OP_ABS */
2838 recording::string *
2839 recording::unary_op::make_debug_string ()
2841 return string::from_printf (m_ctxt,
2842 "%s(%s)",
2843 unary_op_strings[m_op],
2844 m_a->get_debug_string ());
2847 /* The implementation of class gcc::jit::recording::binary_op. */
2849 /* Implementation of pure virtual hook recording::memento::replay_into
2850 for recording::binary_op. */
2852 void
2853 recording::binary_op::replay_into (replayer *r)
2855 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2856 m_op,
2857 get_type ()->playback_type (),
2858 m_a->playback_rvalue (),
2859 m_b->playback_rvalue ()));
2862 /* Implementation of recording::memento::make_debug_string for
2863 binary ops. */
2865 static const char * const binary_op_strings[] = {
2866 "+", /* GCC_JIT_BINARY_OP_PLUS */
2867 "-", /* GCC_JIT_BINARY_OP_MINUS */
2868 "*", /* GCC_JIT_BINARY_OP_MULT */
2869 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2870 "%", /* GCC_JIT_BINARY_OP_MODULO */
2871 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2872 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2873 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2874 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2875 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2876 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2877 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2880 recording::string *
2881 recording::binary_op::make_debug_string ()
2883 return string::from_printf (m_ctxt,
2884 "%s %s %s",
2885 m_a->get_debug_string (),
2886 binary_op_strings[m_op],
2887 m_b->get_debug_string ());
2890 /* The implementation of class gcc::jit::recording::comparison. */
2892 /* Implementation of recording::memento::make_debug_string for
2893 comparisons. */
2895 static const char * const comparison_strings[] =
2897 "==", /* GCC_JIT_COMPARISON_EQ */
2898 "!=", /* GCC_JIT_COMPARISON_NE */
2899 "<", /* GCC_JIT_COMPARISON_LT */
2900 "<=", /* GCC_JIT_COMPARISON_LE */
2901 ">", /* GCC_JIT_COMPARISON_GT */
2902 ">=", /* GCC_JIT_COMPARISON_GE */
2905 recording::string *
2906 recording::comparison::make_debug_string ()
2908 return string::from_printf (m_ctxt,
2909 "%s %s %s",
2910 m_a->get_debug_string (),
2911 comparison_strings[m_op],
2912 m_b->get_debug_string ());
2915 /* Implementation of pure virtual hook recording::memento::replay_into
2916 for recording::comparison. */
2918 void
2919 recording::comparison::replay_into (replayer *r)
2921 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2922 m_op,
2923 m_a->playback_rvalue (),
2924 m_b->playback_rvalue ()));
2927 /* Implementation of pure virtual hook recording::memento::replay_into
2928 for recording::cast. */
2930 void
2931 recording::cast::replay_into (replayer *r)
2933 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2934 m_rvalue->playback_rvalue (),
2935 get_type ()->playback_type ()));
2938 /* Implementation of recording::memento::make_debug_string for
2939 casts. */
2941 recording::string *
2942 recording::cast::make_debug_string ()
2944 return string::from_printf (m_ctxt,
2945 "(%s)%s",
2946 get_type ()->get_debug_string (),
2947 m_rvalue->get_debug_string ());
2950 /* The implementation of class gcc::jit::recording::call. */
2952 /* The constructor for gcc::jit::recording::call. */
2954 recording::call::call (recording::context *ctxt,
2955 recording::location *loc,
2956 recording::function *func,
2957 int numargs,
2958 rvalue **args)
2959 : rvalue (ctxt, loc, func->get_return_type ()),
2960 m_func (func),
2961 m_args ()
2963 for (int i = 0; i< numargs; i++)
2964 m_args.safe_push (args[i]);
2967 /* Implementation of pure virtual hook recording::memento::replay_into
2968 for recording::call. */
2970 void
2971 recording::call::replay_into (replayer *r)
2973 auto_vec<playback::rvalue *> playback_args;
2974 playback_args.create (m_args.length ());
2975 for (unsigned i = 0; i< m_args.length (); i++)
2976 playback_args.safe_push (m_args[i]->playback_rvalue ());
2978 set_playback_obj (r->new_call (playback_location (r, m_loc),
2979 m_func->playback_function (),
2980 &playback_args));
2983 /* Implementation of recording::memento::make_debug_string for
2984 function calls. */
2986 recording::string *
2987 recording::call::make_debug_string ()
2989 /* First, build a buffer for the arguments. */
2990 /* Calculate length of said buffer. */
2991 size_t sz = 1; /* nil terminator */
2992 for (unsigned i = 0; i< m_args.length (); i++)
2994 sz += strlen (m_args[i]->get_debug_string ());
2995 sz += 2; /* ", " separator */
2998 /* Now allocate and populate the buffer. */
2999 char *argbuf = new char[sz];
3000 size_t len = 0;
3002 for (unsigned i = 0; i< m_args.length (); i++)
3004 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3005 len += strlen (m_args[i]->get_debug_string ());
3006 if (i + 1 < m_args.length ())
3008 strcpy (argbuf + len, ", ");
3009 len += 2;
3012 argbuf[len] = '\0';
3014 /* ...and use it to get the string for the call as a whole. */
3015 string *result = string::from_printf (m_ctxt,
3016 "%s (%s)",
3017 m_func->get_debug_string (),
3018 argbuf);
3020 delete[] argbuf;
3022 return result;
3025 /* The implementation of class gcc::jit::recording::call_through_ptr. */
3027 /* The constructor for recording::call_through_ptr. */
3029 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
3030 recording::location *loc,
3031 recording::rvalue *fn_ptr,
3032 int numargs,
3033 rvalue **args)
3034 : rvalue (ctxt, loc,
3035 fn_ptr->get_type ()->dereference ()
3036 ->as_a_function_type ()->get_return_type ()),
3037 m_fn_ptr (fn_ptr),
3038 m_args ()
3040 for (int i = 0; i< numargs; i++)
3041 m_args.safe_push (args[i]);
3044 /* Implementation of pure virtual hook recording::memento::replay_into
3045 for recording::call_through_ptr. */
3047 void
3048 recording::call_through_ptr::replay_into (replayer *r)
3050 auto_vec<playback::rvalue *> playback_args;
3051 playback_args.create (m_args.length ());
3052 for (unsigned i = 0; i< m_args.length (); i++)
3053 playback_args.safe_push (m_args[i]->playback_rvalue ());
3055 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
3056 m_fn_ptr->playback_rvalue (),
3057 &playback_args));
3060 /* Implementation of recording::memento::make_debug_string for
3061 calls through function ptrs. */
3063 recording::string *
3064 recording::call_through_ptr::make_debug_string ()
3066 /* First, build a buffer for the arguments. */
3067 /* Calculate length of said buffer. */
3068 size_t sz = 1; /* nil terminator */
3069 for (unsigned i = 0; i< m_args.length (); i++)
3071 sz += strlen (m_args[i]->get_debug_string ());
3072 sz += 2; /* ", " separator */
3075 /* Now allocate and populate the buffer. */
3076 char *argbuf = new char[sz];
3077 size_t len = 0;
3079 for (unsigned i = 0; i< m_args.length (); i++)
3081 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3082 len += strlen (m_args[i]->get_debug_string ());
3083 if (i + 1 < m_args.length ())
3085 strcpy (argbuf + len, ", ");
3086 len += 2;
3089 argbuf[len] = '\0';
3091 /* ...and use it to get the string for the call as a whole. */
3092 string *result = string::from_printf (m_ctxt,
3093 "%s (%s)",
3094 m_fn_ptr->get_debug_string (),
3095 argbuf);
3097 delete[] argbuf;
3099 return result;
3102 /* The implementation of class gcc::jit::recording::array_access. */
3104 /* Implementation of pure virtual hook recording::memento::replay_into
3105 for recording::array_access. */
3107 void
3108 recording::array_access::replay_into (replayer *r)
3110 set_playback_obj (
3111 r->new_array_access (playback_location (r, m_loc),
3112 m_ptr->playback_rvalue (),
3113 m_index->playback_rvalue ()));
3116 /* Implementation of recording::memento::make_debug_string for
3117 array accesses. */
3119 recording::string *
3120 recording::array_access::make_debug_string ()
3122 return string::from_printf (m_ctxt,
3123 "%s[%s]",
3124 m_ptr->get_debug_string (),
3125 m_index->get_debug_string ());
3128 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3130 /* Implementation of pure virtual hook recording::memento::replay_into
3131 for recording::access_field_of_lvalue. */
3133 void
3134 recording::access_field_of_lvalue::replay_into (replayer *r)
3136 set_playback_obj (
3137 m_lvalue->playback_lvalue ()
3138 ->access_field (playback_location (r, m_loc),
3139 m_field->playback_field ()));
3143 /* Implementation of recording::memento::make_debug_string for
3144 accessing a field of an lvalue. */
3146 recording::string *
3147 recording::access_field_of_lvalue::make_debug_string ()
3149 return string::from_printf (m_ctxt,
3150 "%s.%s",
3151 m_lvalue->get_debug_string (),
3152 m_field->get_debug_string ());
3155 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3157 /* Implementation of pure virtual hook recording::memento::replay_into
3158 for recording::access_field_rvalue. */
3160 void
3161 recording::access_field_rvalue::replay_into (replayer *r)
3163 set_playback_obj (
3164 m_rvalue->playback_rvalue ()
3165 ->access_field (playback_location (r, m_loc),
3166 m_field->playback_field ()));
3169 /* Implementation of recording::memento::make_debug_string for
3170 accessing a field of an rvalue. */
3172 recording::string *
3173 recording::access_field_rvalue::make_debug_string ()
3175 return string::from_printf (m_ctxt,
3176 "%s.%s",
3177 m_rvalue->get_debug_string (),
3178 m_field->get_debug_string ());
3181 /* The implementation of class
3182 gcc::jit::recording::dereference_field_rvalue. */
3184 /* Implementation of pure virtual hook recording::memento::replay_into
3185 for recording::dereference_field_rvalue. */
3187 void
3188 recording::dereference_field_rvalue::replay_into (replayer *r)
3190 set_playback_obj (
3191 m_rvalue->playback_rvalue ()->
3192 dereference_field (playback_location (r, m_loc),
3193 m_field->playback_field ()));
3196 /* Implementation of recording::memento::make_debug_string for
3197 dereferencing a field of an rvalue. */
3199 recording::string *
3200 recording::dereference_field_rvalue::make_debug_string ()
3202 return string::from_printf (m_ctxt,
3203 "%s->%s",
3204 m_rvalue->get_debug_string (),
3205 m_field->get_debug_string ());
3208 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3210 /* Implementation of pure virtual hook recording::memento::replay_into
3211 for recording::dereference_rvalue. */
3213 void
3214 recording::dereference_rvalue::replay_into (replayer *r)
3216 set_playback_obj (
3217 m_rvalue->playback_rvalue ()->
3218 dereference (playback_location (r, m_loc)));
3221 /* Implementation of recording::memento::make_debug_string for
3222 dereferencing an rvalue. */
3224 recording::string *
3225 recording::dereference_rvalue::make_debug_string ()
3227 return string::from_printf (m_ctxt,
3228 "*%s",
3229 m_rvalue->get_debug_string ());
3232 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3234 /* Implementation of pure virtual hook recording::memento::replay_into
3235 for recording::get_address_of_lvalue. */
3237 void
3238 recording::get_address_of_lvalue::replay_into (replayer *r)
3240 set_playback_obj (
3241 m_lvalue->playback_lvalue ()->
3242 get_address (playback_location (r, m_loc)));
3245 /* Implementation of recording::memento::make_debug_string for
3246 getting the address of an lvalue. */
3248 recording::string *
3249 recording::get_address_of_lvalue::make_debug_string ()
3251 return string::from_printf (m_ctxt,
3252 "&%s",
3253 m_lvalue->get_debug_string ());
3256 /* The implementation of class gcc::jit::recording::local. */
3258 /* Implementation of pure virtual hook recording::memento::replay_into
3259 for recording::local. */
3261 void
3262 recording::local::replay_into (replayer *r)
3264 set_playback_obj (
3265 m_func->playback_function ()
3266 ->new_local (playback_location (r, m_loc),
3267 m_type->playback_type (),
3268 playback_string (m_name)));
3271 /* Override the default implementation of
3272 recording::memento::write_to_dump for locals by writing
3273 TYPE NAME;
3274 for use at the top of the function body as if it were a
3275 declaration. */
3277 void
3278 recording::local::write_to_dump (dump &d)
3280 if (d.update_locations ())
3281 m_loc = d.make_location ();
3282 d.write(" %s %s;\n",
3283 m_type->get_debug_string (),
3284 get_debug_string ());
3287 /* The implementation of class gcc::jit::recording::statement. */
3289 /* We poison the default implementation of
3290 gcc::jit::recording::statement::get_successor_blocks
3291 since this vfunc must only ever be called on terminator
3292 statements. */
3295 recording::statement::get_successor_blocks (block **/*out_next1*/,
3296 block **/*out_next2*/) const
3298 /* The base class implementation is for non-terminating statements,
3299 and thus should never be called. */
3300 gcc_unreachable ();
3301 return 0;
3304 /* Extend the default implementation of
3305 recording::memento::write_to_dump for statements by (if requested)
3306 updating the location of the statement to the current location in
3307 the dumpfile. */
3309 void
3310 recording::statement::write_to_dump (dump &d)
3312 memento::write_to_dump (d);
3313 if (d.update_locations ())
3314 m_loc = d.make_location ();
3317 /* The implementation of class gcc::jit::recording::eval. */
3319 /* Implementation of pure virtual hook recording::memento::replay_into
3320 for recording::eval. */
3322 void
3323 recording::eval::replay_into (replayer *r)
3325 playback_block (get_block ())
3326 ->add_eval (playback_location (r),
3327 m_rvalue->playback_rvalue ());
3330 /* Implementation of recording::memento::make_debug_string for
3331 an eval statement. */
3333 recording::string *
3334 recording::eval::make_debug_string ()
3336 return string::from_printf (m_ctxt,
3337 "(void)%s;",
3338 m_rvalue->get_debug_string ());
3341 /* The implementation of class gcc::jit::recording::assignment. */
3343 /* Implementation of pure virtual hook recording::memento::replay_into
3344 for recording::assignment. */
3346 void
3347 recording::assignment::replay_into (replayer *r)
3349 playback_block (get_block ())
3350 ->add_assignment (playback_location (r),
3351 m_lvalue->playback_lvalue (),
3352 m_rvalue->playback_rvalue ());
3355 /* Implementation of recording::memento::make_debug_string for
3356 an assignment statement. */
3358 recording::string *
3359 recording::assignment::make_debug_string ()
3361 return string::from_printf (m_ctxt,
3362 "%s = %s;",
3363 m_lvalue->get_debug_string (),
3364 m_rvalue->get_debug_string ());
3367 /* The implementation of class gcc::jit::recording::assignment_op. */
3369 /* Implementation of pure virtual hook recording::memento::replay_into
3370 for recording::assignment_op. */
3372 void
3373 recording::assignment_op::replay_into (replayer *r)
3375 playback::type *result_type =
3376 m_lvalue->playback_lvalue ()->get_type ();
3378 playback::rvalue *binary_op =
3379 r->new_binary_op (playback_location (r),
3380 m_op,
3381 result_type,
3382 m_lvalue->playback_rvalue (),
3383 m_rvalue->playback_rvalue ());
3385 playback_block (get_block ())
3386 ->add_assignment (playback_location (r),
3387 m_lvalue->playback_lvalue (),
3388 binary_op);
3391 /* Implementation of recording::memento::make_debug_string for
3392 an assignment_op statement. */
3394 recording::string *
3395 recording::assignment_op::make_debug_string ()
3397 return string::from_printf (m_ctxt,
3398 "%s %s= %s;",
3399 m_lvalue->get_debug_string (),
3400 binary_op_strings[m_op],
3401 m_rvalue->get_debug_string ());
3404 /* The implementation of class gcc::jit::recording::comment. */
3406 /* Implementation of pure virtual hook recording::memento::replay_into
3407 for recording::comment. */
3409 void
3410 recording::comment::replay_into (replayer *r)
3412 playback_block (get_block ())
3413 ->add_comment (playback_location (r),
3414 m_text->c_str ());
3417 /* Implementation of recording::memento::make_debug_string for
3418 a comment "statement". */
3420 recording::string *
3421 recording::comment::make_debug_string ()
3423 return string::from_printf (m_ctxt,
3424 "/* %s */",
3425 m_text->c_str ());
3428 /* The implementation of class gcc::jit::recording::conditional. */
3430 /* Implementation of pure virtual hook recording::memento::replay_into
3431 for recording::conditional. */
3433 void
3434 recording::conditional::replay_into (replayer *r)
3436 playback_block (get_block ())
3437 ->add_conditional (playback_location (r),
3438 m_boolval->playback_rvalue (),
3439 playback_block (m_on_true),
3440 playback_block (m_on_false));
3443 /* Override the poisoned default implementation of
3444 gcc::jit::recording::statement::get_successor_blocks
3446 A conditional jump has 2 successor blocks. */
3449 recording::conditional::get_successor_blocks (block **out_next1,
3450 block **out_next2) const
3452 *out_next1 = m_on_true;
3453 *out_next2 = m_on_false;
3454 return 2;
3457 /* Implementation of recording::memento::make_debug_string for
3458 a conditional jump statement. */
3460 recording::string *
3461 recording::conditional::make_debug_string ()
3463 if (m_on_false)
3464 return string::from_printf (m_ctxt,
3465 "if (%s) goto %s; else goto %s;",
3466 m_boolval->get_debug_string (),
3467 m_on_true->get_debug_string (),
3468 m_on_false->get_debug_string ());
3469 else
3470 return string::from_printf (m_ctxt,
3471 "if (%s) goto %s;",
3472 m_boolval->get_debug_string (),
3473 m_on_true->get_debug_string ());
3476 /* The implementation of class gcc::jit::recording::jump. */
3478 /* Implementation of pure virtual hook recording::memento::replay_into
3479 for recording::jump. */
3481 void
3482 recording::jump::replay_into (replayer *r)
3484 playback_block (get_block ())
3485 ->add_jump (playback_location (r),
3486 m_target->playback_block ());
3489 /* Override the poisoned default implementation of
3490 gcc::jit::recording::statement::get_successor_blocks
3492 An unconditional jump has 1 successor block. */
3495 recording::jump::get_successor_blocks (block **out_next1,
3496 block **/*out_next2*/) const
3498 *out_next1 = m_target;
3499 return 1;
3502 /* Implementation of recording::memento::make_debug_string for
3503 a unconditional jump statement. */
3505 recording::string *
3506 recording::jump::make_debug_string ()
3508 return string::from_printf (m_ctxt,
3509 "goto %s;",
3510 m_target->get_debug_string ());
3513 /* The implementation of class gcc::jit::recording::return_. */
3515 /* Implementation of pure virtual hook recording::memento::replay_into
3516 for recording::return_. */
3518 void
3519 recording::return_::replay_into (replayer *r)
3521 playback_block (get_block ())
3522 ->add_return (playback_location (r),
3523 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3526 /* Override the poisoned default implementation of
3527 gcc::jit::recording::statement::get_successor_blocks
3529 A return statement has no successor block. */
3532 recording::return_::get_successor_blocks (block **/*out_next1*/,
3533 block **/*out_next2*/) const
3535 return 0;
3538 /* Implementation of recording::memento::make_debug_string for
3539 a return statement (covers both those with and without rvalues). */
3541 recording::string *
3542 recording::return_::make_debug_string ()
3544 if (m_rvalue)
3545 return string::from_printf (m_ctxt,
3546 "return %s;",
3547 m_rvalue->get_debug_string ());
3548 else
3549 return string::from_printf (m_ctxt,
3550 "return;");
3553 } // namespace gcc::jit
3555 } // namespace gcc