New jit API entrypoint: gcc_jit_context_new_rvalue_from_long
[official-gcc.git] / gcc / jit / jit-recording.c
blob63dab380db13c691735808421d08da6ed3a03c58
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_string_literal instance and add it
651 to this context's list of mementos.
653 Implements the post-error-checking part of
654 gcc_jit_context_new_string_literal. */
656 recording::rvalue *
657 recording::context::new_string_literal (const char *value)
659 recording::rvalue *result =
660 new memento_of_new_string_literal (this, NULL, new_string (value));
661 record (result);
662 return result;
665 /* Create a recording::unary_op instance and add it to this context's
666 list of mementos.
668 Implements the post-error-checking part of
669 gcc_jit_context_new_unary_op. */
671 recording::rvalue *
672 recording::context::new_unary_op (recording::location *loc,
673 enum gcc_jit_unary_op op,
674 recording::type *result_type,
675 recording::rvalue *a)
677 recording::rvalue *result =
678 new unary_op (this, loc, op, result_type, a);
679 record (result);
680 return result;
683 /* Create a recording::binary_op instance and add it to this context's
684 list of mementos.
686 Implements the post-error-checking part of
687 gcc_jit_context_new_binary_op. */
689 recording::rvalue *
690 recording::context::new_binary_op (recording::location *loc,
691 enum gcc_jit_binary_op op,
692 recording::type *result_type,
693 recording::rvalue *a,
694 recording::rvalue *b)
696 recording::rvalue *result =
697 new binary_op (this, loc, op, result_type, a, b);
698 record (result);
699 return result;
702 /* Create a recording::comparison instance and add it to this context's
703 list of mementos.
705 Implements the post-error-checking part of
706 gcc_jit_context_new_comparison. */
708 recording::rvalue *
709 recording::context::new_comparison (recording::location *loc,
710 enum gcc_jit_comparison op,
711 recording::rvalue *a,
712 recording::rvalue *b)
714 recording::rvalue *result = new comparison (this, loc, op, a, b);
715 record (result);
716 return result;
719 /* Create a recording::cast instance and add it to this context's list
720 of mementos.
722 Implements the post-error-checking part of
723 gcc_jit_context_new_cast. */
725 recording::rvalue *
726 recording::context::new_cast (recording::location *loc,
727 recording::rvalue *expr,
728 recording::type *type_)
730 recording::rvalue *result = new cast (this, loc, expr, type_);
731 record (result);
732 return result;
735 /* Create a recording::call instance and add it to this context's list
736 of mementos.
738 Implements the post-error-checking part of
739 gcc_jit_context_new_call. */
741 recording::rvalue *
742 recording::context::new_call (recording::location *loc,
743 function *func,
744 int numargs , recording::rvalue **args)
746 recording::rvalue *result = new call (this, loc, func, numargs, args);
747 record (result);
748 return result;
751 /* Create a recording::call_through_ptr instance and add it to this
752 context's list of mementos.
754 Implements the post-error-checking part of
755 gcc_jit_context_new_call_through_ptr. */
757 recording::rvalue *
758 recording::context::new_call_through_ptr (recording::location *loc,
759 recording::rvalue *fn_ptr,
760 int numargs,
761 recording::rvalue **args)
763 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
764 record (result);
765 return result;
768 /* Create a recording::array_access instance and add it to this context's list
769 of mementos.
771 Implements the post-error-checking part of
772 gcc_jit_context_new_array_access. */
774 recording::lvalue *
775 recording::context::new_array_access (recording::location *loc,
776 recording::rvalue *ptr,
777 recording::rvalue *index)
779 recording::lvalue *result = new array_access (this, loc, ptr, index);
780 record (result);
781 return result;
784 /* Set the given string option for this context, or add an error if
785 it's not recognized.
787 Implements the post-error-checking part of
788 gcc_jit_context_set_str_option. */
790 void
791 recording::context::set_str_option (enum gcc_jit_str_option opt,
792 const char *value)
794 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
796 add_error (NULL,
797 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
798 return;
800 free (m_str_options[opt]);
801 m_str_options[opt] = value ? xstrdup (value) : NULL;
804 /* Set the given integer option for this context, or add an error if
805 it's not recognized.
807 Implements the post-error-checking part of
808 gcc_jit_context_set_int_option. */
810 void
811 recording::context::set_int_option (enum gcc_jit_int_option opt,
812 int value)
814 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
816 add_error (NULL,
817 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
818 return;
820 m_int_options[opt] = value;
823 /* Set the given boolean option for this context, or add an error if
824 it's not recognized.
826 Implements the post-error-checking part of
827 gcc_jit_context_set_bool_option. */
829 void
830 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
831 int value)
833 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
835 add_error (NULL,
836 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
837 return;
839 m_bool_options[opt] = value ? true : false;
842 /* Add the given dumpname/out_ptr pair to this context's list of requested
843 dumps.
845 Implements the post-error-checking part of
846 gcc_jit_context_enable_dump. */
848 void
849 recording::context::enable_dump (const char *dumpname,
850 char **out_ptr)
852 requested_dump d;
853 gcc_assert (dumpname);
854 gcc_assert (out_ptr);
856 d.m_dumpname = dumpname;
857 d.m_out_ptr = out_ptr;
858 *out_ptr = NULL;
859 m_requested_dumps.safe_push (d);
862 /* Validate this context, and if it passes, compile it within a
863 mutex.
865 Implements the post-error-checking part of
866 gcc_jit_context_compile. */
868 result *
869 recording::context::compile ()
871 JIT_LOG_SCOPE (get_logger ());
873 validate ();
875 if (errors_occurred ())
876 return NULL;
878 /* Set up a playback context. */
879 ::gcc::jit::playback::context replayer (this);
881 /* Use it. */
882 result *result_obj = replayer.compile ();
884 return result_obj;
887 /* Format the given error using printf's conventions, print
888 it to stderr, and add it to the context. */
890 void
891 recording::context::add_error (location *loc, const char *fmt, ...)
893 va_list ap;
894 va_start (ap, fmt);
895 add_error_va (loc, fmt, ap);
896 va_end (ap);
899 /* Format the given error using printf's conventions, print
900 it to stderr, and add it to the context. */
902 void
903 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
905 char *malloced_msg;
906 const char *errmsg;
907 bool has_ownership;
909 JIT_LOG_SCOPE (get_logger ());
911 vasprintf (&malloced_msg, fmt, ap);
912 if (malloced_msg)
914 errmsg = malloced_msg;
915 has_ownership = true;
917 else
919 errmsg = "out of memory generating error message";
920 has_ownership = false;
922 if (get_logger ())
923 get_logger ()->log ("error %i: %s", m_error_count, errmsg);
925 const char *ctxt_progname =
926 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
927 if (!ctxt_progname)
928 ctxt_progname = "libgccjit.so";
930 if (loc)
931 fprintf (stderr, "%s: %s: error: %s\n",
932 ctxt_progname,
933 loc->get_debug_string (),
934 errmsg);
935 else
936 fprintf (stderr, "%s: error: %s\n",
937 ctxt_progname,
938 errmsg);
940 if (!m_error_count)
942 m_first_error_str = const_cast <char *> (errmsg);
943 m_owns_first_error_str = has_ownership;
946 if (m_owns_last_error_str)
947 if (m_last_error_str != m_first_error_str)
948 free (m_last_error_str);
949 m_last_error_str = const_cast <char *> (errmsg);
950 m_owns_last_error_str = has_ownership;
952 m_error_count++;
955 /* Get the message for the first error that occurred on this context, or
956 NULL if no errors have occurred on it.
958 Implements the post-error-checking part of
959 gcc_jit_context_get_first_error. */
961 const char *
962 recording::context::get_first_error () const
964 return m_first_error_str;
967 /* Get the message for the last error that occurred on this context, or
968 NULL if no errors have occurred on it.
970 Implements the post-error-checking part of
971 gcc_jit_context_get_last_error. */
973 const char *
974 recording::context::get_last_error () const
976 return m_last_error_str;
979 /* Lazily generate and record a recording::type representing an opaque
980 struct named "FILE".
982 For use if client code tries to dereference the result of
983 get_type (GCC_JIT_TYPE_FILE_PTR). */
985 recording::type *
986 recording::context::get_opaque_FILE_type ()
988 if (!m_FILE_type)
989 m_FILE_type = new_struct_type (NULL, "FILE");
990 return m_FILE_type;
993 /* Dump a C-like representation of the given context to the given path.
994 If UPDATE_LOCATIONS is true, update the locations within the
995 context's mementos to point to the dumpfile.
997 Implements the post-error-checking part of
998 gcc_jit_context_dump_to_file. */
1000 void
1001 recording::context::dump_to_file (const char *path, bool update_locations)
1003 int i;
1004 dump d (*this, path, update_locations);
1006 /* Forward declaration of structs and unions. */
1007 compound_type *st;
1008 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1010 d.write ("%s;\n\n", st->get_debug_string ());
1013 /* Content of structs, where set. */
1014 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1015 if (st->get_fields ())
1017 st->get_fields ()->write_to_dump (d);
1018 d.write ("\n");
1021 function *fn;
1022 FOR_EACH_VEC_ELT (m_functions, i, fn)
1024 fn->write_to_dump (d);
1028 /* Copy the requested dumps within this context and all ancestors into
1029 OUT. */
1031 void
1032 recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
1034 if (m_parent_ctxt)
1035 m_parent_ctxt->get_all_requested_dumps (out);
1037 out->reserve (m_requested_dumps.length ());
1038 out->splice (m_requested_dumps);
1041 /* This is a pre-compilation check for the context (and any parents).
1043 Detect errors within the context, adding errors if any are found. */
1045 void
1046 recording::context::validate ()
1048 JIT_LOG_SCOPE (get_logger ());
1050 if (m_parent_ctxt)
1051 m_parent_ctxt->validate ();
1053 int i;
1054 function *fn;
1055 FOR_EACH_VEC_ELT (m_functions, i, fn)
1056 fn->validate ();
1059 /* The implementation of class gcc::jit::recording::memento. */
1061 /* Get a (const char *) debug description of the given memento, by
1062 calling the pure-virtual make_debug_string hook, caching the
1063 result.
1065 It is intended that this should only be called in debugging and
1066 error-handling paths, so this doesn't need to be particularly
1067 optimized. */
1069 const char *
1070 recording::memento::get_debug_string ()
1072 if (!m_debug_string)
1073 m_debug_string = make_debug_string ();
1074 return m_debug_string->c_str ();
1077 /* Default implementation of recording::memento::write_to_dump, writing
1078 an indented form of the memento's debug string to the dump. */
1080 void
1081 recording::memento::write_to_dump (dump &d)
1083 d.write(" %s\n", get_debug_string ());
1086 /* The implementation of class gcc::jit::recording::string. */
1088 /* Constructor for gcc::jit::recording::string::string, allocating a
1089 copy of the given text using new char[]. */
1091 recording::string::string (context *ctxt, const char *text)
1092 : memento (ctxt)
1094 m_len = strlen (text);
1095 m_buffer = new char[m_len + 1];
1096 strcpy (m_buffer, text);
1099 /* Destructor for gcc::jit::recording::string::string. */
1101 recording::string::~string ()
1103 delete[] m_buffer;
1106 /* Function for making gcc::jit::recording::string instances on a
1107 context via printf-style formatting.
1109 It is intended that this should only be called in debugging and
1110 error-handling paths, so this doesn't need to be particularly
1111 optimized, hence the double-copy of the string is acceptable. */
1113 recording::string *
1114 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1116 va_list ap;
1117 char *buf = NULL;
1118 recording::string *result;
1120 va_start (ap, fmt);
1121 vasprintf (&buf, fmt, ap);
1122 va_end (ap);
1124 if (!buf)
1126 ctxt->add_error (NULL, "malloc failure");
1127 return NULL;
1130 result = ctxt->new_string (buf);
1131 free (buf);
1132 return result;
1135 /* Implementation of recording::memento::make_debug_string for strings,
1136 wrapping the given string in quotes and escaping as necessary. */
1138 recording::string *
1139 recording::string::make_debug_string ()
1141 /* Hack to avoid infinite recursion into strings when logging all
1142 mementos: don't re-escape strings: */
1143 if (m_buffer[0] == '"')
1144 return this;
1146 /* Wrap in quotes and do escaping etc */
1148 size_t sz = (1 /* opening quote */
1149 + (m_len * 2) /* each char might get escaped */
1150 + 1 /* closing quote */
1151 + 1); /* nil termintator */
1152 char *tmp = new char[sz];
1153 size_t len = 0;
1155 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1156 APPEND('"'); /* opening quote */
1157 for (size_t i = 0; i < m_len ; i++)
1159 char ch = m_buffer[i];
1160 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1161 APPEND('\\');
1162 APPEND(ch);
1164 APPEND('"'); /* closing quote */
1165 #undef APPEND
1166 tmp[len] = '\0'; /* nil termintator */
1168 string *result = m_ctxt->new_string (tmp);
1170 delete[] tmp;
1171 return result;
1174 /* The implementation of class gcc::jit::recording::location. */
1176 /* Implementation of recording::memento::replay_into for locations.
1178 Create a new playback::location and store it into the
1179 recording::location's m_playback_obj field. */
1181 void
1182 recording::location::replay_into (replayer *r)
1184 m_playback_obj = r->new_location (this,
1185 m_filename->c_str (),
1186 m_line,
1187 m_column);
1190 /* Implementation of recording::memento::make_debug_string for locations,
1191 turning them into the usual form:
1192 FILENAME:LINE:COLUMN
1193 like we do when emitting diagnostics. */
1195 recording::string *
1196 recording::location::make_debug_string ()
1198 return string::from_printf (m_ctxt,
1199 "%s:%i:%i",
1200 m_filename->c_str (), m_line, m_column);
1203 /* The implementation of class gcc::jit::recording::type. */
1205 /* Given a type T, get the type T*.
1207 If this doesn't already exist, generate a new memento_of_get_pointer
1208 instance and add it to this type's context's list of mementos.
1210 Otherwise, use the cached type.
1212 Implements the post-error-checking part of
1213 gcc_jit_type_get_pointer. */
1215 recording::type *
1216 recording::type::get_pointer ()
1218 if (!m_pointer_to_this_type)
1220 m_pointer_to_this_type = new memento_of_get_pointer (this);
1221 m_ctxt->record (m_pointer_to_this_type);
1223 return m_pointer_to_this_type;
1226 /* Given a type T, get the type const T.
1228 Implements the post-error-checking part of
1229 gcc_jit_type_get_const. */
1231 recording::type *
1232 recording::type::get_const ()
1234 recording::type *result = new memento_of_get_const (this);
1235 m_ctxt->record (result);
1236 return result;
1239 /* Given a type T, get the type volatile T.
1241 Implements the post-error-checking part of
1242 gcc_jit_type_get_volatile. */
1244 recording::type *
1245 recording::type::get_volatile ()
1247 recording::type *result = new memento_of_get_volatile (this);
1248 m_ctxt->record (result);
1249 return result;
1252 /* Implementation of pure virtual hook recording::type::dereference for
1253 recording::memento_of_get_type. */
1255 recording::type *
1256 recording::memento_of_get_type::dereference ()
1258 switch (m_kind)
1260 default: gcc_unreachable ();
1262 case GCC_JIT_TYPE_VOID:
1263 return NULL;
1265 case GCC_JIT_TYPE_VOID_PTR:
1266 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1268 case GCC_JIT_TYPE_BOOL:
1269 case GCC_JIT_TYPE_CHAR:
1270 case GCC_JIT_TYPE_SIGNED_CHAR:
1271 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1272 case GCC_JIT_TYPE_SHORT:
1273 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1274 case GCC_JIT_TYPE_INT:
1275 case GCC_JIT_TYPE_UNSIGNED_INT:
1276 case GCC_JIT_TYPE_LONG:
1277 case GCC_JIT_TYPE_UNSIGNED_LONG:
1278 case GCC_JIT_TYPE_LONG_LONG:
1279 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1280 case GCC_JIT_TYPE_FLOAT:
1281 case GCC_JIT_TYPE_DOUBLE:
1282 case GCC_JIT_TYPE_LONG_DOUBLE:
1283 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1284 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1285 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1286 /* Not a pointer: */
1287 return NULL;
1289 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1290 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1292 case GCC_JIT_TYPE_SIZE_T:
1293 /* Not a pointer: */
1294 return NULL;
1296 case GCC_JIT_TYPE_FILE_PTR:
1297 /* Give the client code back an opaque "struct FILE". */
1298 return m_ctxt->get_opaque_FILE_type ();
1302 /* Implementation of pure virtual hook recording::type::is_int for
1303 recording::memento_of_get_type. */
1305 bool
1306 recording::memento_of_get_type::is_int () const
1308 switch (m_kind)
1310 default: gcc_unreachable ();
1312 case GCC_JIT_TYPE_VOID:
1313 return false;
1315 case GCC_JIT_TYPE_VOID_PTR:
1316 return false;
1318 case GCC_JIT_TYPE_BOOL:
1319 return false;
1321 case GCC_JIT_TYPE_CHAR:
1322 case GCC_JIT_TYPE_SIGNED_CHAR:
1323 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1324 case GCC_JIT_TYPE_SHORT:
1325 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1326 case GCC_JIT_TYPE_INT:
1327 case GCC_JIT_TYPE_UNSIGNED_INT:
1328 case GCC_JIT_TYPE_LONG:
1329 case GCC_JIT_TYPE_UNSIGNED_LONG:
1330 case GCC_JIT_TYPE_LONG_LONG:
1331 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1332 return true;
1334 case GCC_JIT_TYPE_FLOAT:
1335 case GCC_JIT_TYPE_DOUBLE:
1336 case GCC_JIT_TYPE_LONG_DOUBLE:
1337 return false;
1339 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1340 return false;
1342 case GCC_JIT_TYPE_SIZE_T:
1343 return true;
1345 case GCC_JIT_TYPE_FILE_PTR:
1346 return false;
1348 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1349 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1350 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1351 return false;
1355 /* Implementation of pure virtual hook recording::type::is_float for
1356 recording::memento_of_get_type. */
1358 bool
1359 recording::memento_of_get_type::is_float () const
1361 switch (m_kind)
1363 default: gcc_unreachable ();
1365 case GCC_JIT_TYPE_VOID:
1366 return false;
1368 case GCC_JIT_TYPE_VOID_PTR:
1369 return false;
1371 case GCC_JIT_TYPE_BOOL:
1372 return false;
1374 case GCC_JIT_TYPE_CHAR:
1375 case GCC_JIT_TYPE_SIGNED_CHAR:
1376 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1377 case GCC_JIT_TYPE_SHORT:
1378 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1379 case GCC_JIT_TYPE_INT:
1380 case GCC_JIT_TYPE_UNSIGNED_INT:
1381 case GCC_JIT_TYPE_LONG:
1382 case GCC_JIT_TYPE_UNSIGNED_LONG:
1383 case GCC_JIT_TYPE_LONG_LONG:
1384 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1385 return false;
1387 case GCC_JIT_TYPE_FLOAT:
1388 case GCC_JIT_TYPE_DOUBLE:
1389 case GCC_JIT_TYPE_LONG_DOUBLE:
1390 return true;
1392 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1393 return false;
1395 case GCC_JIT_TYPE_SIZE_T:
1396 return false;
1398 case GCC_JIT_TYPE_FILE_PTR:
1399 return false;
1401 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1402 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1403 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1404 return true;
1408 /* Implementation of pure virtual hook recording::type::is_bool for
1409 recording::memento_of_get_type. */
1411 bool
1412 recording::memento_of_get_type::is_bool () const
1414 switch (m_kind)
1416 default: gcc_unreachable ();
1418 case GCC_JIT_TYPE_VOID:
1419 return false;
1421 case GCC_JIT_TYPE_VOID_PTR:
1422 return false;
1424 case GCC_JIT_TYPE_BOOL:
1425 return true;
1427 case GCC_JIT_TYPE_CHAR:
1428 case GCC_JIT_TYPE_SIGNED_CHAR:
1429 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1430 case GCC_JIT_TYPE_SHORT:
1431 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1432 case GCC_JIT_TYPE_INT:
1433 case GCC_JIT_TYPE_UNSIGNED_INT:
1434 case GCC_JIT_TYPE_LONG:
1435 case GCC_JIT_TYPE_UNSIGNED_LONG:
1436 case GCC_JIT_TYPE_LONG_LONG:
1437 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1438 return false;
1440 case GCC_JIT_TYPE_FLOAT:
1441 case GCC_JIT_TYPE_DOUBLE:
1442 case GCC_JIT_TYPE_LONG_DOUBLE:
1443 return false;
1445 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1446 return false;
1448 case GCC_JIT_TYPE_SIZE_T:
1449 return false;
1451 case GCC_JIT_TYPE_FILE_PTR:
1452 return false;
1454 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1455 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1456 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1457 return false;
1461 /* Implementation of pure virtual hook recording::memento::replay_into
1462 for recording::memento_of_get_type. */
1464 void
1465 recording::memento_of_get_type::replay_into (replayer *r)
1467 set_playback_obj (r->get_type (m_kind));
1470 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1472 /* Descriptive strings for each of enum gcc_jit_types. */
1474 static const char * const get_type_strings[] = {
1475 "void", /* GCC_JIT_TYPE_VOID */
1476 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1478 "bool", /* GCC_JIT_TYPE_BOOL */
1480 "char", /* GCC_JIT_TYPE_CHAR */
1481 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1482 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1484 "short", /* GCC_JIT_TYPE_SHORT */
1485 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1487 "int", /* GCC_JIT_TYPE_INT */
1488 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1490 "long", /* GCC_JIT_TYPE_LONG */
1491 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1493 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1494 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1496 "float", /* GCC_JIT_TYPE_FLOAT */
1497 "double", /* GCC_JIT_TYPE_DOUBLE */
1498 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1500 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1502 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1504 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1506 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1507 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1508 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1512 /* Implementation of recording::memento::make_debug_string for
1513 results of get_type, using a simple table of type names. */
1515 recording::string *
1516 recording::memento_of_get_type::make_debug_string ()
1518 return m_ctxt->new_string (get_type_strings[m_kind]);
1521 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1523 /* Override of default implementation of
1524 recording::type::accepts_writes_from for get_pointer.
1526 Require a pointer type, and allowing writes to
1527 (const T *) from a (T*), but not the other way around. */
1529 bool
1530 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1532 /* Must be a pointer type: */
1533 type *rtype_points_to = rtype->is_pointer ();
1534 if (!rtype_points_to)
1535 return false;
1537 /* It's OK to assign to a (const T *) from a (T *). */
1538 return m_other_type->unqualified ()
1539 ->accepts_writes_from (rtype_points_to);
1542 /* Implementation of pure virtual hook recording::memento::replay_into
1543 for recording::memento_of_get_pointer. */
1545 void
1546 recording::memento_of_get_pointer::replay_into (replayer *)
1548 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1551 /* Implementation of recording::memento::make_debug_string for
1552 results of get_pointer, adding " *" to the underlying type,
1553 with special-casing to handle function pointer types. */
1555 recording::string *
1556 recording::memento_of_get_pointer::make_debug_string ()
1558 /* Special-case function pointer types, to put the "*" in parens between
1559 the return type and the params (for one level of dereferencing, at
1560 least). */
1561 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1562 return fn_type->make_debug_string_with_ptr ();
1564 return string::from_printf (m_ctxt,
1565 "%s *", m_other_type->get_debug_string ());
1568 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1570 /* Implementation of pure virtual hook recording::memento::replay_into
1571 for recording::memento_of_get_const. */
1573 void
1574 recording::memento_of_get_const::replay_into (replayer *)
1576 set_playback_obj (m_other_type->playback_type ()->get_const ());
1579 /* Implementation of recording::memento::make_debug_string for
1580 results of get_const, prepending "const ". */
1582 recording::string *
1583 recording::memento_of_get_const::make_debug_string ()
1585 return string::from_printf (m_ctxt,
1586 "const %s", m_other_type->get_debug_string ());
1589 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1591 /* Implementation of pure virtual hook recording::memento::replay_into
1592 for recording::memento_of_get_volatile. */
1594 void
1595 recording::memento_of_get_volatile::replay_into (replayer *)
1597 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1600 /* Implementation of recording::memento::make_debug_string for
1601 results of get_volatile, prepending "volatile ". */
1603 recording::string *
1604 recording::memento_of_get_volatile::make_debug_string ()
1606 return string::from_printf (m_ctxt,
1607 "volatile %s", m_other_type->get_debug_string ());
1610 /* The implementation of class gcc::jit::recording::array_type */
1612 /* Implementation of pure virtual hook recording::type::dereference for
1613 recording::array_type. */
1615 recording::type *
1616 recording::array_type::dereference ()
1618 return m_element_type;
1621 /* Implementation of pure virtual hook recording::memento::replay_into
1622 for recording::array_type. */
1624 void
1625 recording::array_type::replay_into (replayer *r)
1627 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1628 m_element_type->playback_type (),
1629 m_num_elements));
1632 /* Implementation of recording::memento::make_debug_string for
1633 results of new_array_type. */
1635 recording::string *
1636 recording::array_type::make_debug_string ()
1638 return string::from_printf (m_ctxt,
1639 "%s[%d]",
1640 m_element_type->get_debug_string (),
1641 m_num_elements);
1644 /* The implementation of class gcc::jit::recording::function_type */
1646 /* Constructor for gcc::jit::recording::function_type. */
1648 recording::function_type::function_type (context *ctxt,
1649 type *return_type,
1650 int num_params,
1651 type **param_types,
1652 int is_variadic)
1653 : type (ctxt),
1654 m_return_type (return_type),
1655 m_param_types (),
1656 m_is_variadic (is_variadic)
1658 for (int i = 0; i< num_params; i++)
1659 m_param_types.safe_push (param_types[i]);
1662 /* Implementation of pure virtual hook recording::type::dereference for
1663 recording::function_type. */
1665 recording::type *
1666 recording::function_type::dereference ()
1668 return NULL;
1671 /* Implementation of pure virtual hook recording::memento::replay_into
1672 for recording::function_type. */
1674 void
1675 recording::function_type::replay_into (replayer *r)
1677 /* Convert m_param_types to a vec of playback type. */
1678 auto_vec <playback::type *> param_types;
1679 int i;
1680 recording::type *type;
1681 param_types.create (m_param_types.length ());
1682 FOR_EACH_VEC_ELT (m_param_types, i, type)
1683 param_types.safe_push (type->playback_type ());
1685 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1686 &param_types,
1687 m_is_variadic));
1690 /* Special-casing for make_debug_string for get_pointer results for
1691 handling (one level) of pointers to functions. */
1693 recording::string *
1694 recording::function_type::make_debug_string_with_ptr ()
1696 return make_debug_string_with ("(*) ");
1699 /* Implementation of recording::memento::make_debug_string for
1700 results of new_function_type. */
1702 recording::string *
1703 recording::function_type::make_debug_string ()
1705 return make_debug_string_with ("");
1708 /* Build a debug string representation of the form:
1710 RESULT_TYPE INSERT (PARAM_TYPES)
1712 for use when handling 0 and 1 level of indirection to this
1713 function type. */
1715 recording::string *
1716 recording::function_type::make_debug_string_with (const char *insert)
1718 /* First, build a buffer for the arguments. */
1719 /* Calculate length of said buffer. */
1720 size_t sz = 1; /* nil terminator */
1721 for (unsigned i = 0; i< m_param_types.length (); i++)
1723 sz += strlen (m_param_types[i]->get_debug_string ());
1724 sz += 2; /* ", " separator */
1726 if (m_is_variadic)
1727 sz += 5; /* ", ..." separator and ellipsis */
1729 /* Now allocate and populate the buffer. */
1730 char *argbuf = new char[sz];
1731 size_t len = 0;
1733 for (unsigned i = 0; i< m_param_types.length (); i++)
1735 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1736 len += strlen (m_param_types[i]->get_debug_string ());
1737 if (i + 1 < m_param_types.length ())
1739 strcpy (argbuf + len, ", ");
1740 len += 2;
1743 if (m_is_variadic)
1745 if (m_param_types.length ())
1747 strcpy (argbuf + len, ", ");
1748 len += 2;
1750 strcpy (argbuf + len, "...");
1751 len += 3;
1753 argbuf[len] = '\0';
1755 /* ...and use it to get the string for the call as a whole. */
1756 string *result = string::from_printf (m_ctxt,
1757 "%s %s(%s)",
1758 m_return_type->get_debug_string (),
1759 insert,
1760 argbuf);
1762 delete[] argbuf;
1764 return result;
1767 /* The implementation of class gcc::jit::recording::field. */
1769 /* Implementation of pure virtual hook recording::memento::replay_into
1770 for recording::field. */
1772 void
1773 recording::field::replay_into (replayer *r)
1775 set_playback_obj (r->new_field (playback_location (r, m_loc),
1776 m_type->playback_type (),
1777 playback_string (m_name)));
1780 /* Override the default implementation of
1781 recording::memento::write_to_dump. Dump each field
1782 by dumping a line of the form:
1783 TYPE NAME;
1784 so that we can build up a struct/union field-byfield. */
1786 void
1787 recording::field::write_to_dump (dump &d)
1789 d.write (" %s %s;\n",
1790 m_type->get_debug_string (),
1791 m_name->c_str ());
1794 /* Implementation of recording::memento::make_debug_string for
1795 results of new_field. */
1797 recording::string *
1798 recording::field::make_debug_string ()
1800 return m_name;
1803 /* The implementation of class gcc::jit::recording::compound_type */
1805 /* The constructor for gcc::jit::recording::compound_type. */
1807 recording::compound_type::compound_type (context *ctxt,
1808 location *loc,
1809 string *name)
1810 : type (ctxt),
1811 m_loc (loc),
1812 m_name (name),
1813 m_fields (NULL)
1817 /* Set the fields of a compound type.
1819 Implements the post-error-checking part of
1820 gcc_jit_struct_set_fields, and is also used by
1821 gcc_jit_context_new_union_type. */
1823 void
1824 recording::compound_type::set_fields (location *loc,
1825 int num_fields,
1826 field **field_array)
1828 m_loc = loc;
1829 gcc_assert (NULL == m_fields);
1831 m_fields = new fields (this, num_fields, field_array);
1832 m_ctxt->record (m_fields);
1835 /* Implementation of pure virtual hook recording::type::dereference for
1836 recording::compound_type. */
1838 recording::type *
1839 recording::compound_type::dereference ()
1841 return NULL; /* not a pointer */
1844 /* The implementation of class gcc::jit::recording::struct_. */
1846 /* The constructor for gcc::jit::recording::struct_. */
1848 recording::struct_::struct_ (context *ctxt,
1849 location *loc,
1850 string *name)
1851 : compound_type (ctxt, loc, name)
1855 /* Implementation of pure virtual hook recording::memento::replay_into
1856 for recording::struct_. */
1858 void
1859 recording::struct_::replay_into (replayer *r)
1861 set_playback_obj (
1862 r->new_compound_type (playback_location (r, get_loc ()),
1863 get_name ()->c_str (),
1864 true /* is_struct */));
1867 /* Implementation of recording::memento::make_debug_string for
1868 structs. */
1870 recording::string *
1871 recording::struct_::make_debug_string ()
1873 return string::from_printf (m_ctxt,
1874 "struct %s", get_name ()->c_str ());
1877 /* The implementation of class gcc::jit::recording::union_. */
1879 /* The constructor for gcc::jit::recording::union_. */
1881 recording::union_::union_ (context *ctxt,
1882 location *loc,
1883 string *name)
1884 : compound_type (ctxt, loc, name)
1888 /* Implementation of pure virtual hook recording::memento::replay_into
1889 for recording::union_. */
1891 void
1892 recording::union_::replay_into (replayer *r)
1894 set_playback_obj (
1895 r->new_compound_type (playback_location (r, get_loc ()),
1896 get_name ()->c_str (),
1897 false /* is_struct */));
1900 /* Implementation of recording::memento::make_debug_string for
1901 unions. */
1903 recording::string *
1904 recording::union_::make_debug_string ()
1906 return string::from_printf (m_ctxt,
1907 "union %s", get_name ()->c_str ());
1910 /* The implementation of class gcc::jit::recording::fields. */
1912 /* The constructor for gcc::jit::recording::fields. */
1914 recording::fields::fields (compound_type *struct_or_union,
1915 int num_fields,
1916 field **fields)
1917 : memento (struct_or_union->m_ctxt),
1918 m_struct_or_union (struct_or_union),
1919 m_fields ()
1921 for (int i = 0; i < num_fields; i++)
1923 gcc_assert (fields[i]->get_container () == NULL);
1924 fields[i]->set_container (m_struct_or_union);
1925 m_fields.safe_push (fields[i]);
1929 /* Implementation of pure virtual hook recording::memento::replay_into
1930 for recording::fields. */
1932 void
1933 recording::fields::replay_into (replayer *)
1935 auto_vec<playback::field *> playback_fields;
1936 playback_fields.create (m_fields.length ());
1937 for (unsigned i = 0; i < m_fields.length (); i++)
1938 playback_fields.safe_push (m_fields[i]->playback_field ());
1939 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1942 /* Override the default implementation of
1943 recording::memento::write_to_dump by writing a union/struct
1944 declaration of this form:
1946 struct/union NAME {
1947 TYPE_1 NAME_1;
1948 TYPE_2 NAME_2;
1949 ....
1950 TYPE_N NAME_N;
1953 to the dump. */
1955 void
1956 recording::fields::write_to_dump (dump &d)
1958 int i;
1959 field *f;
1961 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
1962 FOR_EACH_VEC_ELT (m_fields, i, f)
1963 f->write_to_dump (d);
1964 d.write ("};\n");
1967 /* Implementation of recording::memento::make_debug_string for
1968 field tables. */
1970 recording::string *
1971 recording::fields::make_debug_string ()
1973 return string::from_printf (m_ctxt,
1974 "fields");
1977 /* The implementation of class gcc::jit::recording::rvalue. */
1979 /* Create a recording::access_field_rvalue instance and add it to
1980 the rvalue's context's list of mementos.
1982 Implements the post-error-checking part of
1983 gcc_jit_rvalue_access_field. */
1985 recording::rvalue *
1986 recording::rvalue::access_field (recording::location *loc,
1987 field *field)
1989 recording::rvalue *result =
1990 new access_field_rvalue (m_ctxt, loc, this, field);
1991 m_ctxt->record (result);
1992 return result;
1995 /* Create a recording::dereference_field_rvalue instance and add it to
1996 the rvalue's context's list of mementos.
1998 Implements the post-error-checking part of
1999 gcc_jit_rvalue_dereference_field. */
2001 recording::lvalue *
2002 recording::rvalue::dereference_field (recording::location *loc,
2003 field *field)
2005 recording::lvalue *result =
2006 new dereference_field_rvalue (m_ctxt, loc, this, field);
2007 m_ctxt->record (result);
2008 return result;
2011 /* Create a recording::dereference_rvalue instance and add it to the
2012 rvalue's context's list of mementos.
2014 Implements the post-error-checking part of
2015 gcc_jit_rvalue_dereference. */
2017 recording::lvalue *
2018 recording::rvalue::dereference (recording::location *loc)
2020 recording::lvalue *result =
2021 new dereference_rvalue (m_ctxt, loc, this);
2022 m_ctxt->record (result);
2023 return result;
2026 /* The implementation of class gcc::jit::recording::lvalue. */
2028 /* Create a recording::new_access_field_of_lvalue instance and add it to
2029 the lvalue's context's list of mementos.
2031 Implements the post-error-checking part of
2032 gcc_jit_lvalue_access_field. */
2034 recording::lvalue *
2035 recording::lvalue::access_field (recording::location *loc,
2036 field *field)
2038 recording::lvalue *result =
2039 new access_field_of_lvalue (m_ctxt, loc, this, field);
2040 m_ctxt->record (result);
2041 return result;
2044 /* Create a recording::get_address_of_lvalue instance and add it to
2045 the lvalue's context's list of mementos.
2047 Implements the post-error-checking part of
2048 gcc_jit_lvalue_get_address. */
2050 recording::rvalue *
2051 recording::lvalue::get_address (recording::location *loc)
2053 recording::rvalue *result =
2054 new get_address_of_lvalue (m_ctxt, loc, this);
2055 m_ctxt->record (result);
2056 return result;
2059 /* The implementation of class gcc::jit::recording::param. */
2061 /* Implementation of pure virtual hook recording::memento::replay_into
2062 for recording::param. */
2064 void
2065 recording::param::replay_into (replayer *r)
2067 set_playback_obj (r->new_param (playback_location (r, m_loc),
2068 m_type->playback_type (),
2069 m_name->c_str ()));
2073 /* The implementation of class gcc::jit::recording::function. */
2075 /* gcc::jit::recording::function's constructor. */
2077 recording::function::function (context *ctxt,
2078 recording::location *loc,
2079 enum gcc_jit_function_kind kind,
2080 type *return_type,
2081 recording::string *name,
2082 int num_params,
2083 recording::param **params,
2084 int is_variadic,
2085 enum built_in_function builtin_id)
2086 : memento (ctxt),
2087 m_loc (loc),
2088 m_kind (kind),
2089 m_return_type (return_type),
2090 m_name (name),
2091 m_params (),
2092 m_is_variadic (is_variadic),
2093 m_builtin_id (builtin_id),
2094 m_locals (),
2095 m_blocks ()
2097 for (int i = 0; i< num_params; i++)
2098 m_params.safe_push (params[i]);
2101 /* Implementation of pure virtual hook recording::memento::replay_into
2102 for recording::function. */
2104 void
2105 recording::function::replay_into (replayer *r)
2107 /* Convert m_params to a vec of playback param. */
2108 auto_vec <playback::param *> params;
2109 int i;
2110 recording::param *param;
2111 params.create (m_params.length ());
2112 FOR_EACH_VEC_ELT (m_params, i, param)
2113 params.safe_push (param->playback_param ());
2115 set_playback_obj (r->new_function (playback_location (r, m_loc),
2116 m_kind,
2117 m_return_type->playback_type (),
2118 m_name->c_str (),
2119 &params,
2120 m_is_variadic,
2121 m_builtin_id));
2124 /* Create a recording::local instance and add it to
2125 the functions's context's list of mementos, and to the function's
2126 list of locals.
2128 Implements the post-error-checking part of
2129 gcc_jit_function_new_local. */
2131 recording::lvalue *
2132 recording::function::new_local (recording::location *loc,
2133 type *type,
2134 const char *name)
2136 local *result = new local (this, loc, type, new_string (name));
2137 m_ctxt->record (result);
2138 m_locals.safe_push (result);
2139 return result;
2142 /* Create a recording::block instance and add it to
2143 the functions's context's list of mementos, and to the function's
2144 list of blocks.
2146 Implements the post-error-checking part of
2147 gcc_jit_function_new_block. */
2149 recording::block*
2150 recording::function::new_block (const char *name)
2152 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2154 recording::block *result =
2155 new recording::block (this, m_blocks.length (), new_string (name));
2156 m_ctxt->record (result);
2157 m_blocks.safe_push (result);
2158 return result;
2161 /* Override the default implementation of
2162 recording::memento::write_to_dump by dumping a C-like
2163 representation of the function; either like a prototype
2164 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2165 all other kinds of function. */
2167 void
2168 recording::function::write_to_dump (dump &d)
2170 switch (m_kind)
2172 default: gcc_unreachable ();
2173 case GCC_JIT_FUNCTION_EXPORTED:
2174 case GCC_JIT_FUNCTION_IMPORTED:
2175 d.write ("extern ");
2176 break;
2177 case GCC_JIT_FUNCTION_INTERNAL:
2178 d.write ("static ");
2179 break;
2180 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2181 d.write ("static inline ");
2182 break;
2184 d.write ("%s\n", m_return_type->get_debug_string ());
2186 if (d.update_locations ())
2187 m_loc = d.make_location ();
2189 d.write ("%s (", get_debug_string ());
2191 int i;
2192 recording::param *param;
2193 FOR_EACH_VEC_ELT (m_params, i, param)
2195 if (i > 0)
2196 d.write (", ");
2197 d.write ("%s %s",
2198 param->get_type ()->get_debug_string (),
2199 param->get_debug_string ());
2201 d.write (")");
2202 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2204 d.write ("; /* (imported) */\n\n");
2206 else
2208 int i;
2209 local *var = NULL;
2210 block *b;
2211 d.write ("\n{\n");
2213 /* Write locals: */
2214 FOR_EACH_VEC_ELT (m_locals, i, var)
2215 var->write_to_dump (d);
2216 if (m_locals.length ())
2217 d.write ("\n");
2219 /* Write each block: */
2220 FOR_EACH_VEC_ELT (m_blocks, i, b)
2222 if (i > 0)
2223 d.write ("\n");
2224 b->write_to_dump (d);
2227 d.write ("}\n\n");
2231 /* Pre-compilation validation of a function, for those things we can't
2232 check until the context is (supposedly) fully-populated. */
2234 void
2235 recording::function::validate ()
2237 /* Complain about empty functions with non-void return type. */
2238 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2239 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2240 if (0 == m_blocks.length ())
2241 m_ctxt->add_error (m_loc,
2242 "function %s returns non-void (type: %s)"
2243 " but has no blocks",
2244 get_debug_string (),
2245 m_return_type->get_debug_string ());
2247 /* Check that all blocks are terminated. */
2248 int num_invalid_blocks = 0;
2250 int i;
2251 block *b;
2253 FOR_EACH_VEC_ELT (m_blocks, i, b)
2254 if (!b->validate ())
2255 num_invalid_blocks++;
2258 /* Check that all blocks are reachable. */
2259 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2261 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2262 flag, starting at the initial block. */
2263 auto_vec<block *> worklist (m_blocks.length ());
2264 worklist.safe_push (m_blocks[0]);
2265 while (worklist.length () > 0)
2267 block *b = worklist.pop ();
2268 b->m_is_reachable = true;
2270 /* Add successor blocks that aren't yet marked to the worklist. */
2271 /* We checked that each block has a terminating statement above . */
2272 block *next1, *next2;
2273 int n = b->get_successor_blocks (&next1, &next2);
2274 switch (n)
2276 default:
2277 gcc_unreachable ();
2278 case 2:
2279 if (!next2->m_is_reachable)
2280 worklist.safe_push (next2);
2281 /* fallthrough */
2282 case 1:
2283 if (!next1->m_is_reachable)
2284 worklist.safe_push (next1);
2285 break;
2286 case 0:
2287 break;
2291 /* Now complain about any blocks that haven't been marked. */
2293 int i;
2294 block *b;
2295 FOR_EACH_VEC_ELT (m_blocks, i, b)
2296 if (!b->m_is_reachable)
2297 m_ctxt->add_error (b->get_loc (),
2298 "unreachable block: %s",
2299 b->get_debug_string ());
2304 /* Implements the post-error-checking part of
2305 gcc_jit_function_dump_to_dot. */
2307 void
2308 recording::function::dump_to_dot (const char *path)
2310 FILE *fp = fopen (path, "w");
2311 if (!fp)
2312 return;
2314 pretty_printer the_pp;
2315 the_pp.buffer->stream = fp;
2317 pretty_printer *pp = &the_pp;
2319 pp_printf (pp,
2320 "digraph %s {\n", get_debug_string ());
2322 /* Blocks: */
2324 int i;
2325 block *b;
2326 FOR_EACH_VEC_ELT (m_blocks, i, b)
2327 b->dump_to_dot (pp);
2330 /* Edges: */
2332 int i;
2333 block *b;
2334 FOR_EACH_VEC_ELT (m_blocks, i, b)
2335 b->dump_edges_to_dot (pp);
2338 pp_printf (pp, "}\n");
2339 pp_flush (pp);
2340 fclose (fp);
2343 /* Implementation of recording::memento::make_debug_string for
2344 functions. */
2346 recording::string *
2347 recording::function::make_debug_string ()
2349 return m_name;
2352 /* The implementation of class gcc::jit::recording::block. */
2354 /* Create a recording::eval instance and add it to
2355 the block's context's list of mementos, and to the block's
2356 list of statements.
2358 Implements the post-error-checking part of
2359 gcc_jit_block_add_eval. */
2361 void
2362 recording::block::add_eval (recording::location *loc,
2363 recording::rvalue *rvalue)
2365 statement *result = new eval (this, loc, rvalue);
2366 m_ctxt->record (result);
2367 m_statements.safe_push (result);
2370 /* Create a recording::assignment instance and add it to
2371 the block's context's list of mementos, and to the block's
2372 list of statements.
2374 Implements the post-error-checking part of
2375 gcc_jit_block_add_assignment. */
2377 void
2378 recording::block::add_assignment (recording::location *loc,
2379 recording::lvalue *lvalue,
2380 recording::rvalue *rvalue)
2382 statement *result = new assignment (this, loc, lvalue, rvalue);
2383 m_ctxt->record (result);
2384 m_statements.safe_push (result);
2387 /* Create a recording::assignment_op instance and add it to
2388 the block's context's list of mementos, and to the block's
2389 list of statements.
2391 Implements the post-error-checking part of
2392 gcc_jit_block_add_assignment_op. */
2394 void
2395 recording::block::add_assignment_op (recording::location *loc,
2396 recording::lvalue *lvalue,
2397 enum gcc_jit_binary_op op,
2398 recording::rvalue *rvalue)
2400 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2401 m_ctxt->record (result);
2402 m_statements.safe_push (result);
2405 /* Create a recording::comment instance and add it to
2406 the block's context's list of mementos, and to the block's
2407 list of statements.
2409 Implements the post-error-checking part of
2410 gcc_jit_block_add_comment. */
2412 void
2413 recording::block::add_comment (recording::location *loc,
2414 const char *text)
2416 statement *result = new comment (this, loc, new_string (text));
2417 m_ctxt->record (result);
2418 m_statements.safe_push (result);
2421 /* Create a recording::end_with_conditional instance and add it to
2422 the block's context's list of mementos, and to the block's
2423 list of statements.
2425 Implements the post-error-checking part of
2426 gcc_jit_block_end_with_conditional. */
2428 void
2429 recording::block::end_with_conditional (recording::location *loc,
2430 recording::rvalue *boolval,
2431 recording::block *on_true,
2432 recording::block *on_false)
2434 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2435 m_ctxt->record (result);
2436 m_statements.safe_push (result);
2437 m_has_been_terminated = true;
2440 /* Create a recording::end_with_jump instance and add it to
2441 the block's context's list of mementos, and to the block's
2442 list of statements.
2444 Implements the post-error-checking part of
2445 gcc_jit_block_end_with_jump. */
2447 void
2448 recording::block::end_with_jump (recording::location *loc,
2449 recording::block *target)
2451 statement *result = new jump (this, loc, target);
2452 m_ctxt->record (result);
2453 m_statements.safe_push (result);
2454 m_has_been_terminated = true;
2457 /* Create a recording::end_with_return instance and add it to
2458 the block's context's list of mementos, and to the block's
2459 list of statements.
2461 Implements the post-error-checking parts of
2462 gcc_jit_block_end_with_return and
2463 gcc_jit_block_end_with_void_return. */
2465 void
2466 recording::block::end_with_return (recording::location *loc,
2467 recording::rvalue *rvalue)
2469 /* This is used by both gcc_jit_function_add_return and
2470 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2471 the former and NULL for the latter. */
2472 statement *result = new return_ (this, loc, rvalue);
2473 m_ctxt->record (result);
2474 m_statements.safe_push (result);
2475 m_has_been_terminated = true;
2478 /* Override the default implementation of
2479 recording::memento::write_to_dump for blocks by writing
2480 an unindented block name as a label, followed by the indented
2481 statements:
2483 BLOCK_NAME:
2484 STATEMENT_1;
2485 STATEMENT_2;
2487 STATEMENT_N; */
2489 void
2490 recording::block::write_to_dump (dump &d)
2492 d.write ("%s:\n", get_debug_string ());
2494 int i;
2495 statement *s;
2496 FOR_EACH_VEC_ELT (m_statements, i, s)
2497 s->write_to_dump (d);
2500 /* Validate a block by ensuring that it has been terminated. */
2502 bool
2503 recording::block::validate ()
2505 if (!has_been_terminated ())
2507 statement *stmt = get_last_statement ();
2508 location *loc = stmt ? stmt->get_loc () : NULL;
2509 m_func->get_context ()->add_error (loc,
2510 "unterminated block in %s: %s",
2511 m_func->get_debug_string (),
2512 get_debug_string ());
2513 return false;
2516 return true;
2519 /* Get the source-location of a block by using that of the first
2520 statement within it, if any. */
2522 recording::location *
2523 recording::block::get_loc () const
2525 recording::statement *stmt = get_first_statement ();
2526 if (stmt)
2527 return stmt->get_loc ();
2528 else
2529 return NULL;
2532 /* Get the first statement within a block, if any. */
2534 recording::statement *
2535 recording::block::get_first_statement () const
2537 if (m_statements.length ())
2538 return m_statements[0];
2539 else
2540 return NULL;
2543 /* Get the last statement within a block, if any. */
2545 recording::statement *
2546 recording::block::get_last_statement () const
2548 if (m_statements.length ())
2549 return m_statements[m_statements.length () - 1];
2550 else
2551 return NULL;
2554 /* Assuming that this block has been terminated, get the number of
2555 successor blocks, which will be 0, 1 or 2, for return, unconditional
2556 jump, and conditional jump respectively.
2557 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2558 is written to NEXT1, and the second (if any) to NEXT2.
2560 Used when validating functions, and when dumping dot representations
2561 of them. */
2564 recording::block::get_successor_blocks (block **next1, block **next2) const
2566 gcc_assert (m_has_been_terminated);
2567 gcc_assert (next1);
2568 gcc_assert (next2);
2569 statement *last_statement = get_last_statement ();
2570 gcc_assert (last_statement);
2571 return last_statement->get_successor_blocks (next1, next2);
2574 /* Implementation of pure virtual hook recording::memento::replay_into
2575 for recording::block. */
2577 void
2578 recording::block::replay_into (replayer *)
2580 set_playback_obj (m_func->playback_function ()
2581 ->new_block (playback_string (m_name)));
2584 /* Implementation of recording::memento::make_debug_string for
2585 blocks. */
2587 recording::string *
2588 recording::block::make_debug_string ()
2590 if (m_name)
2591 return m_name;
2592 else
2593 return string::from_printf (m_ctxt,
2594 "<UNNAMED BLOCK %p>",
2595 (void *)this);
2598 /* Dump a block in graphviz form into PP, capturing the block name (if
2599 any) and the statements. */
2601 void
2602 recording::block::dump_to_dot (pretty_printer *pp)
2604 pp_printf (pp,
2605 ("\tblock_%d "
2606 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2607 m_index);
2608 pp_write_text_to_stream (pp);
2609 if (m_name)
2611 pp_string (pp, m_name->c_str ());
2612 pp_string (pp, ":");
2613 pp_newline (pp);
2614 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2617 int i;
2618 statement *s;
2619 FOR_EACH_VEC_ELT (m_statements, i, s)
2621 pp_string (pp, s->get_debug_string ());
2622 pp_newline (pp);
2623 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2626 pp_printf (pp,
2627 "}\"];\n\n");
2628 pp_flush (pp);
2631 /* Dump the out-edges of the block in graphviz form into PP. */
2633 void
2634 recording::block::dump_edges_to_dot (pretty_printer *pp)
2636 block *next[2];
2637 int num_succs = get_successor_blocks (&next[0], &next[1]);
2638 for (int i = 0; i < num_succs; i++)
2639 pp_printf (pp,
2640 "\tblock_%d:s -> block_%d:n;\n",
2641 m_index, next[i]->m_index);
2644 /* The implementation of class gcc::jit::recording::global. */
2646 /* Implementation of pure virtual hook recording::memento::replay_into
2647 for recording::global. */
2649 void
2650 recording::global::replay_into (replayer *r)
2652 set_playback_obj (r->new_global (playback_location (r, m_loc),
2653 m_type->playback_type (),
2654 playback_string (m_name)));
2657 /* The implementation of the various const-handling classes:
2658 gcc::jit::recording::memento_of_new_rvalue_from_const <HOST_TYPE>. */
2660 /* Explicit specialization of the various mementos we're interested in. */
2661 template class recording::memento_of_new_rvalue_from_const <int>;
2662 template class recording::memento_of_new_rvalue_from_const <long>;
2663 template class recording::memento_of_new_rvalue_from_const <double>;
2664 template class recording::memento_of_new_rvalue_from_const <void *>;
2666 /* Implementation of the pure virtual hook recording::memento::replay_into
2667 for recording::memento_of_new_rvalue_from_const <HOST_TYPE>. */
2669 template <typename HOST_TYPE>
2670 void
2671 recording::
2672 memento_of_new_rvalue_from_const <HOST_TYPE>::replay_into (replayer *r)
2674 set_playback_obj
2675 (r->new_rvalue_from_const <HOST_TYPE> (m_type->playback_type (),
2676 m_value));
2679 /* The make_debug_string method varies between the various
2680 memento_of_new_rvalue_from_const <HOST_TYPE> classes, so we explicitly
2681 write specializations of it.
2683 I (dmalcolm) find the code to be clearer if the "recording" vs "playback"
2684 namespaces are written out explicitly, which is why most of this file
2685 doesn't abbreviate things by entering the "recording" namespace.
2687 However, these specializations are required to be in the same namespace
2688 as the template, hence we now have to enter the gcc::jit::recording
2689 namespace. */
2691 namespace recording
2694 /* The make_debug_string specialization for <int>, which renders it as
2695 (TARGET_TYPE)LITERAL
2696 e.g.
2697 "(int)42". */
2699 template <>
2700 string *
2701 memento_of_new_rvalue_from_const <int>::make_debug_string ()
2703 return string::from_printf (m_ctxt,
2704 "(%s)%i",
2705 m_type->get_debug_string (),
2706 m_value);
2709 /* The make_debug_string specialization for <long>, rendering it as
2710 (TARGET_TYPE)LITERAL
2711 e.g.
2712 "(long)42". */
2714 template <>
2715 string *
2716 memento_of_new_rvalue_from_const <long>::make_debug_string ()
2718 return string::from_printf (m_ctxt,
2719 "(%s)%li",
2720 m_type->get_debug_string (),
2721 m_value);
2724 /* The make_debug_string specialization for <double>, rendering it as
2725 (TARGET_TYPE)LITERAL
2726 e.g.
2727 "(float)42.0". */
2729 template <>
2730 string *
2731 memento_of_new_rvalue_from_const <double>::make_debug_string ()
2733 return string::from_printf (m_ctxt,
2734 "(%s)%f",
2735 m_type->get_debug_string (),
2736 m_value);
2739 /* The make_debug_string specialization for <void *>, rendering it as
2740 (TARGET_TYPE)HEX
2741 e.g.
2742 "(int *)0xdeadbeef"
2744 Zero is rendered as NULL e.g.
2745 "(int *)NULL". */
2747 template <>
2748 string *
2749 memento_of_new_rvalue_from_const <void *>::make_debug_string ()
2751 if (m_value != NULL)
2752 return string::from_printf (m_ctxt,
2753 "(%s)%p",
2754 m_type->get_debug_string (), m_value);
2755 else
2756 return string::from_printf (m_ctxt,
2757 "(%s)NULL",
2758 m_type->get_debug_string ());
2761 /* We're done specializing make_debug_string, so we can exit the
2762 gcc::jit::recording namespace. */
2764 } // namespace recording
2766 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2768 /* Implementation of pure virtual hook recording::memento::replay_into
2769 for recording::memento_of_new_string_literal. */
2771 void
2772 recording::memento_of_new_string_literal::replay_into (replayer *r)
2774 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2777 /* Implementation of recording::memento::make_debug_string for
2778 string literals. */
2780 recording::string *
2781 recording::memento_of_new_string_literal::make_debug_string ()
2783 return string::from_printf (m_ctxt,
2784 m_value->get_debug_string ());
2787 /* The implementation of class gcc::jit::recording::unary_op. */
2789 /* Implementation of pure virtual hook recording::memento::replay_into
2790 for recording::unary_op. */
2792 void
2793 recording::unary_op::replay_into (replayer *r)
2795 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2796 m_op,
2797 get_type ()->playback_type (),
2798 m_a->playback_rvalue ()));
2801 /* Implementation of recording::memento::make_debug_string for
2802 unary ops. */
2804 static const char * const unary_op_strings[] = {
2805 "-", /* GCC_JIT_UNARY_OP_MINUS */
2806 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2807 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2808 "abs ", /* GCC_JIT_UNARY_OP_ABS */
2811 recording::string *
2812 recording::unary_op::make_debug_string ()
2814 return string::from_printf (m_ctxt,
2815 "%s(%s)",
2816 unary_op_strings[m_op],
2817 m_a->get_debug_string ());
2820 /* The implementation of class gcc::jit::recording::binary_op. */
2822 /* Implementation of pure virtual hook recording::memento::replay_into
2823 for recording::binary_op. */
2825 void
2826 recording::binary_op::replay_into (replayer *r)
2828 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2829 m_op,
2830 get_type ()->playback_type (),
2831 m_a->playback_rvalue (),
2832 m_b->playback_rvalue ()));
2835 /* Implementation of recording::memento::make_debug_string for
2836 binary ops. */
2838 static const char * const binary_op_strings[] = {
2839 "+", /* GCC_JIT_BINARY_OP_PLUS */
2840 "-", /* GCC_JIT_BINARY_OP_MINUS */
2841 "*", /* GCC_JIT_BINARY_OP_MULT */
2842 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2843 "%", /* GCC_JIT_BINARY_OP_MODULO */
2844 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2845 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2846 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2847 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2848 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2849 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2850 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2853 recording::string *
2854 recording::binary_op::make_debug_string ()
2856 return string::from_printf (m_ctxt,
2857 "%s %s %s",
2858 m_a->get_debug_string (),
2859 binary_op_strings[m_op],
2860 m_b->get_debug_string ());
2863 /* The implementation of class gcc::jit::recording::comparison. */
2865 /* Implementation of recording::memento::make_debug_string for
2866 comparisons. */
2868 static const char * const comparison_strings[] =
2870 "==", /* GCC_JIT_COMPARISON_EQ */
2871 "!=", /* GCC_JIT_COMPARISON_NE */
2872 "<", /* GCC_JIT_COMPARISON_LT */
2873 "<=", /* GCC_JIT_COMPARISON_LE */
2874 ">", /* GCC_JIT_COMPARISON_GT */
2875 ">=", /* GCC_JIT_COMPARISON_GE */
2878 recording::string *
2879 recording::comparison::make_debug_string ()
2881 return string::from_printf (m_ctxt,
2882 "%s %s %s",
2883 m_a->get_debug_string (),
2884 comparison_strings[m_op],
2885 m_b->get_debug_string ());
2888 /* Implementation of pure virtual hook recording::memento::replay_into
2889 for recording::comparison. */
2891 void
2892 recording::comparison::replay_into (replayer *r)
2894 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2895 m_op,
2896 m_a->playback_rvalue (),
2897 m_b->playback_rvalue ()));
2900 /* Implementation of pure virtual hook recording::memento::replay_into
2901 for recording::cast. */
2903 void
2904 recording::cast::replay_into (replayer *r)
2906 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2907 m_rvalue->playback_rvalue (),
2908 get_type ()->playback_type ()));
2911 /* Implementation of recording::memento::make_debug_string for
2912 casts. */
2914 recording::string *
2915 recording::cast::make_debug_string ()
2917 return string::from_printf (m_ctxt,
2918 "(%s)%s",
2919 get_type ()->get_debug_string (),
2920 m_rvalue->get_debug_string ());
2923 /* The implementation of class gcc::jit::recording::call. */
2925 /* The constructor for gcc::jit::recording::call. */
2927 recording::call::call (recording::context *ctxt,
2928 recording::location *loc,
2929 recording::function *func,
2930 int numargs,
2931 rvalue **args)
2932 : rvalue (ctxt, loc, func->get_return_type ()),
2933 m_func (func),
2934 m_args ()
2936 for (int i = 0; i< numargs; i++)
2937 m_args.safe_push (args[i]);
2940 /* Implementation of pure virtual hook recording::memento::replay_into
2941 for recording::call. */
2943 void
2944 recording::call::replay_into (replayer *r)
2946 auto_vec<playback::rvalue *> playback_args;
2947 playback_args.create (m_args.length ());
2948 for (unsigned i = 0; i< m_args.length (); i++)
2949 playback_args.safe_push (m_args[i]->playback_rvalue ());
2951 set_playback_obj (r->new_call (playback_location (r, m_loc),
2952 m_func->playback_function (),
2953 &playback_args));
2956 /* Implementation of recording::memento::make_debug_string for
2957 function calls. */
2959 recording::string *
2960 recording::call::make_debug_string ()
2962 /* First, build a buffer for the arguments. */
2963 /* Calculate length of said buffer. */
2964 size_t sz = 1; /* nil terminator */
2965 for (unsigned i = 0; i< m_args.length (); i++)
2967 sz += strlen (m_args[i]->get_debug_string ());
2968 sz += 2; /* ", " separator */
2971 /* Now allocate and populate the buffer. */
2972 char *argbuf = new char[sz];
2973 size_t len = 0;
2975 for (unsigned i = 0; i< m_args.length (); i++)
2977 strcpy (argbuf + len, m_args[i]->get_debug_string ());
2978 len += strlen (m_args[i]->get_debug_string ());
2979 if (i + 1 < m_args.length ())
2981 strcpy (argbuf + len, ", ");
2982 len += 2;
2985 argbuf[len] = '\0';
2987 /* ...and use it to get the string for the call as a whole. */
2988 string *result = string::from_printf (m_ctxt,
2989 "%s (%s)",
2990 m_func->get_debug_string (),
2991 argbuf);
2993 delete[] argbuf;
2995 return result;
2998 /* The implementation of class gcc::jit::recording::call_through_ptr. */
3000 /* The constructor for recording::call_through_ptr. */
3002 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
3003 recording::location *loc,
3004 recording::rvalue *fn_ptr,
3005 int numargs,
3006 rvalue **args)
3007 : rvalue (ctxt, loc,
3008 fn_ptr->get_type ()->dereference ()
3009 ->as_a_function_type ()->get_return_type ()),
3010 m_fn_ptr (fn_ptr),
3011 m_args ()
3013 for (int i = 0; i< numargs; i++)
3014 m_args.safe_push (args[i]);
3017 /* Implementation of pure virtual hook recording::memento::replay_into
3018 for recording::call_through_ptr. */
3020 void
3021 recording::call_through_ptr::replay_into (replayer *r)
3023 auto_vec<playback::rvalue *> playback_args;
3024 playback_args.create (m_args.length ());
3025 for (unsigned i = 0; i< m_args.length (); i++)
3026 playback_args.safe_push (m_args[i]->playback_rvalue ());
3028 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
3029 m_fn_ptr->playback_rvalue (),
3030 &playback_args));
3033 /* Implementation of recording::memento::make_debug_string for
3034 calls through function ptrs. */
3036 recording::string *
3037 recording::call_through_ptr::make_debug_string ()
3039 /* First, build a buffer for the arguments. */
3040 /* Calculate length of said buffer. */
3041 size_t sz = 1; /* nil terminator */
3042 for (unsigned i = 0; i< m_args.length (); i++)
3044 sz += strlen (m_args[i]->get_debug_string ());
3045 sz += 2; /* ", " separator */
3048 /* Now allocate and populate the buffer. */
3049 char *argbuf = new char[sz];
3050 size_t len = 0;
3052 for (unsigned i = 0; i< m_args.length (); i++)
3054 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3055 len += strlen (m_args[i]->get_debug_string ());
3056 if (i + 1 < m_args.length ())
3058 strcpy (argbuf + len, ", ");
3059 len += 2;
3062 argbuf[len] = '\0';
3064 /* ...and use it to get the string for the call as a whole. */
3065 string *result = string::from_printf (m_ctxt,
3066 "%s (%s)",
3067 m_fn_ptr->get_debug_string (),
3068 argbuf);
3070 delete[] argbuf;
3072 return result;
3075 /* The implementation of class gcc::jit::recording::array_access. */
3077 /* Implementation of pure virtual hook recording::memento::replay_into
3078 for recording::array_access. */
3080 void
3081 recording::array_access::replay_into (replayer *r)
3083 set_playback_obj (
3084 r->new_array_access (playback_location (r, m_loc),
3085 m_ptr->playback_rvalue (),
3086 m_index->playback_rvalue ()));
3089 /* Implementation of recording::memento::make_debug_string for
3090 array accesses. */
3092 recording::string *
3093 recording::array_access::make_debug_string ()
3095 return string::from_printf (m_ctxt,
3096 "%s[%s]",
3097 m_ptr->get_debug_string (),
3098 m_index->get_debug_string ());
3101 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3103 /* Implementation of pure virtual hook recording::memento::replay_into
3104 for recording::access_field_of_lvalue. */
3106 void
3107 recording::access_field_of_lvalue::replay_into (replayer *r)
3109 set_playback_obj (
3110 m_lvalue->playback_lvalue ()
3111 ->access_field (playback_location (r, m_loc),
3112 m_field->playback_field ()));
3116 /* Implementation of recording::memento::make_debug_string for
3117 accessing a field of an lvalue. */
3119 recording::string *
3120 recording::access_field_of_lvalue::make_debug_string ()
3122 return string::from_printf (m_ctxt,
3123 "%s.%s",
3124 m_lvalue->get_debug_string (),
3125 m_field->get_debug_string ());
3128 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3130 /* Implementation of pure virtual hook recording::memento::replay_into
3131 for recording::access_field_rvalue. */
3133 void
3134 recording::access_field_rvalue::replay_into (replayer *r)
3136 set_playback_obj (
3137 m_rvalue->playback_rvalue ()
3138 ->access_field (playback_location (r, m_loc),
3139 m_field->playback_field ()));
3142 /* Implementation of recording::memento::make_debug_string for
3143 accessing a field of an rvalue. */
3145 recording::string *
3146 recording::access_field_rvalue::make_debug_string ()
3148 return string::from_printf (m_ctxt,
3149 "%s.%s",
3150 m_rvalue->get_debug_string (),
3151 m_field->get_debug_string ());
3154 /* The implementation of class
3155 gcc::jit::recording::dereference_field_rvalue. */
3157 /* Implementation of pure virtual hook recording::memento::replay_into
3158 for recording::dereference_field_rvalue. */
3160 void
3161 recording::dereference_field_rvalue::replay_into (replayer *r)
3163 set_playback_obj (
3164 m_rvalue->playback_rvalue ()->
3165 dereference_field (playback_location (r, m_loc),
3166 m_field->playback_field ()));
3169 /* Implementation of recording::memento::make_debug_string for
3170 dereferencing a field of an rvalue. */
3172 recording::string *
3173 recording::dereference_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 gcc::jit::recording::dereference_rvalue. */
3183 /* Implementation of pure virtual hook recording::memento::replay_into
3184 for recording::dereference_rvalue. */
3186 void
3187 recording::dereference_rvalue::replay_into (replayer *r)
3189 set_playback_obj (
3190 m_rvalue->playback_rvalue ()->
3191 dereference (playback_location (r, m_loc)));
3194 /* Implementation of recording::memento::make_debug_string for
3195 dereferencing an rvalue. */
3197 recording::string *
3198 recording::dereference_rvalue::make_debug_string ()
3200 return string::from_printf (m_ctxt,
3201 "*%s",
3202 m_rvalue->get_debug_string ());
3205 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3207 /* Implementation of pure virtual hook recording::memento::replay_into
3208 for recording::get_address_of_lvalue. */
3210 void
3211 recording::get_address_of_lvalue::replay_into (replayer *r)
3213 set_playback_obj (
3214 m_lvalue->playback_lvalue ()->
3215 get_address (playback_location (r, m_loc)));
3218 /* Implementation of recording::memento::make_debug_string for
3219 getting the address of an lvalue. */
3221 recording::string *
3222 recording::get_address_of_lvalue::make_debug_string ()
3224 return string::from_printf (m_ctxt,
3225 "&%s",
3226 m_lvalue->get_debug_string ());
3229 /* The implementation of class gcc::jit::recording::local. */
3231 /* Implementation of pure virtual hook recording::memento::replay_into
3232 for recording::local. */
3234 void
3235 recording::local::replay_into (replayer *r)
3237 set_playback_obj (
3238 m_func->playback_function ()
3239 ->new_local (playback_location (r, m_loc),
3240 m_type->playback_type (),
3241 playback_string (m_name)));
3244 /* Override the default implementation of
3245 recording::memento::write_to_dump for locals by writing
3246 TYPE NAME;
3247 for use at the top of the function body as if it were a
3248 declaration. */
3250 void
3251 recording::local::write_to_dump (dump &d)
3253 if (d.update_locations ())
3254 m_loc = d.make_location ();
3255 d.write(" %s %s;\n",
3256 m_type->get_debug_string (),
3257 get_debug_string ());
3260 /* The implementation of class gcc::jit::recording::statement. */
3262 /* We poison the default implementation of
3263 gcc::jit::recording::statement::get_successor_blocks
3264 since this vfunc must only ever be called on terminator
3265 statements. */
3268 recording::statement::get_successor_blocks (block **/*out_next1*/,
3269 block **/*out_next2*/) const
3271 /* The base class implementation is for non-terminating statements,
3272 and thus should never be called. */
3273 gcc_unreachable ();
3274 return 0;
3277 /* Extend the default implementation of
3278 recording::memento::write_to_dump for statements by (if requested)
3279 updating the location of the statement to the current location in
3280 the dumpfile. */
3282 void
3283 recording::statement::write_to_dump (dump &d)
3285 memento::write_to_dump (d);
3286 if (d.update_locations ())
3287 m_loc = d.make_location ();
3290 /* The implementation of class gcc::jit::recording::eval. */
3292 /* Implementation of pure virtual hook recording::memento::replay_into
3293 for recording::eval. */
3295 void
3296 recording::eval::replay_into (replayer *r)
3298 playback_block (get_block ())
3299 ->add_eval (playback_location (r),
3300 m_rvalue->playback_rvalue ());
3303 /* Implementation of recording::memento::make_debug_string for
3304 an eval statement. */
3306 recording::string *
3307 recording::eval::make_debug_string ()
3309 return string::from_printf (m_ctxt,
3310 "(void)%s;",
3311 m_rvalue->get_debug_string ());
3314 /* The implementation of class gcc::jit::recording::assignment. */
3316 /* Implementation of pure virtual hook recording::memento::replay_into
3317 for recording::assignment. */
3319 void
3320 recording::assignment::replay_into (replayer *r)
3322 playback_block (get_block ())
3323 ->add_assignment (playback_location (r),
3324 m_lvalue->playback_lvalue (),
3325 m_rvalue->playback_rvalue ());
3328 /* Implementation of recording::memento::make_debug_string for
3329 an assignment statement. */
3331 recording::string *
3332 recording::assignment::make_debug_string ()
3334 return string::from_printf (m_ctxt,
3335 "%s = %s;",
3336 m_lvalue->get_debug_string (),
3337 m_rvalue->get_debug_string ());
3340 /* The implementation of class gcc::jit::recording::assignment_op. */
3342 /* Implementation of pure virtual hook recording::memento::replay_into
3343 for recording::assignment_op. */
3345 void
3346 recording::assignment_op::replay_into (replayer *r)
3348 playback::type *result_type =
3349 m_lvalue->playback_lvalue ()->get_type ();
3351 playback::rvalue *binary_op =
3352 r->new_binary_op (playback_location (r),
3353 m_op,
3354 result_type,
3355 m_lvalue->playback_rvalue (),
3356 m_rvalue->playback_rvalue ());
3358 playback_block (get_block ())
3359 ->add_assignment (playback_location (r),
3360 m_lvalue->playback_lvalue (),
3361 binary_op);
3364 /* Implementation of recording::memento::make_debug_string for
3365 an assignment_op statement. */
3367 recording::string *
3368 recording::assignment_op::make_debug_string ()
3370 return string::from_printf (m_ctxt,
3371 "%s %s= %s;",
3372 m_lvalue->get_debug_string (),
3373 binary_op_strings[m_op],
3374 m_rvalue->get_debug_string ());
3377 /* The implementation of class gcc::jit::recording::comment. */
3379 /* Implementation of pure virtual hook recording::memento::replay_into
3380 for recording::comment. */
3382 void
3383 recording::comment::replay_into (replayer *r)
3385 playback_block (get_block ())
3386 ->add_comment (playback_location (r),
3387 m_text->c_str ());
3390 /* Implementation of recording::memento::make_debug_string for
3391 a comment "statement". */
3393 recording::string *
3394 recording::comment::make_debug_string ()
3396 return string::from_printf (m_ctxt,
3397 "/* %s */",
3398 m_text->c_str ());
3401 /* The implementation of class gcc::jit::recording::conditional. */
3403 /* Implementation of pure virtual hook recording::memento::replay_into
3404 for recording::conditional. */
3406 void
3407 recording::conditional::replay_into (replayer *r)
3409 playback_block (get_block ())
3410 ->add_conditional (playback_location (r),
3411 m_boolval->playback_rvalue (),
3412 playback_block (m_on_true),
3413 playback_block (m_on_false));
3416 /* Override the poisoned default implementation of
3417 gcc::jit::recording::statement::get_successor_blocks
3419 A conditional jump has 2 successor blocks. */
3422 recording::conditional::get_successor_blocks (block **out_next1,
3423 block **out_next2) const
3425 *out_next1 = m_on_true;
3426 *out_next2 = m_on_false;
3427 return 2;
3430 /* Implementation of recording::memento::make_debug_string for
3431 a conditional jump statement. */
3433 recording::string *
3434 recording::conditional::make_debug_string ()
3436 if (m_on_false)
3437 return string::from_printf (m_ctxt,
3438 "if (%s) goto %s; else goto %s;",
3439 m_boolval->get_debug_string (),
3440 m_on_true->get_debug_string (),
3441 m_on_false->get_debug_string ());
3442 else
3443 return string::from_printf (m_ctxt,
3444 "if (%s) goto %s;",
3445 m_boolval->get_debug_string (),
3446 m_on_true->get_debug_string ());
3449 /* The implementation of class gcc::jit::recording::jump. */
3451 /* Implementation of pure virtual hook recording::memento::replay_into
3452 for recording::jump. */
3454 void
3455 recording::jump::replay_into (replayer *r)
3457 playback_block (get_block ())
3458 ->add_jump (playback_location (r),
3459 m_target->playback_block ());
3462 /* Override the poisoned default implementation of
3463 gcc::jit::recording::statement::get_successor_blocks
3465 An unconditional jump has 1 successor block. */
3468 recording::jump::get_successor_blocks (block **out_next1,
3469 block **/*out_next2*/) const
3471 *out_next1 = m_target;
3472 return 1;
3475 /* Implementation of recording::memento::make_debug_string for
3476 a unconditional jump statement. */
3478 recording::string *
3479 recording::jump::make_debug_string ()
3481 return string::from_printf (m_ctxt,
3482 "goto %s;",
3483 m_target->get_debug_string ());
3486 /* The implementation of class gcc::jit::recording::return_. */
3488 /* Implementation of pure virtual hook recording::memento::replay_into
3489 for recording::return_. */
3491 void
3492 recording::return_::replay_into (replayer *r)
3494 playback_block (get_block ())
3495 ->add_return (playback_location (r),
3496 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3499 /* Override the poisoned default implementation of
3500 gcc::jit::recording::statement::get_successor_blocks
3502 A return statement has no successor block. */
3505 recording::return_::get_successor_blocks (block **/*out_next1*/,
3506 block **/*out_next2*/) const
3508 return 0;
3511 /* Implementation of recording::memento::make_debug_string for
3512 a return statement (covers both those with and without rvalues). */
3514 recording::string *
3515 recording::return_::make_debug_string ()
3517 if (m_rvalue)
3518 return string::from_printf (m_ctxt,
3519 "return %s;",
3520 m_rvalue->get_debug_string ());
3521 else
3522 return string::from_printf (m_ctxt,
3523 "return;");
3526 } // namespace gcc::jit
3528 } // namespace gcc