Fix issue with string options and nested gcc_jit_contexts
[official-gcc.git] / gcc / jit / jit-recording.c
blob6613ed7af34f040ec68aab65d72842c0ce16d3b5
1 /* Internals of libgccjit: classes for recording calls made to the JIT API.
2 Copyright (C) 2013-2014 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-recording.h"
34 #include "jit-playback.h"
36 namespace gcc {
37 namespace jit {
39 // class dump
41 dump::dump (recording::context &ctxt,
42 const char *filename,
43 bool update_locations)
44 : m_ctxt (ctxt),
45 m_filename (filename),
46 m_update_locations (update_locations),
47 m_line (0),
48 m_column (0)
50 m_file = fopen (filename, "w");
51 if (!m_file)
52 ctxt.add_error (NULL,
53 "error opening dump file %s for writing: %s",
54 filename,
55 xstrerror (errno));
58 dump::~dump ()
60 if (m_file)
62 int err = fclose (m_file);
63 if (err)
64 m_ctxt.add_error (NULL,
65 "error closing dump file %s: %s",
66 m_filename,
67 xstrerror (errno));
71 /* Write the given message to the dump, using printf-formatting
72 conventions, updating the line/column within the dump.
74 Emit an error on the context if a failure occurs. */
76 void
77 dump::write (const char *fmt, ...)
79 va_list ap;
80 char *buf = NULL;
82 /* If there was an error opening the file, we've already reported it.
83 Don't attempt further work. */
84 if (!m_file)
85 return;
87 va_start (ap, fmt);
88 vasprintf (&buf, fmt, ap);
89 va_end (ap);
91 if (!buf)
93 m_ctxt.add_error (NULL, "malloc failure writing to dumpfile %s",
94 m_filename);
95 return;
98 if (fwrite (buf, strlen (buf), 1, m_file) != 1)
99 m_ctxt.add_error (NULL, "error writing to dump file %s",
100 m_filename);
102 /* Update line/column: */
103 for (const char *ptr = buf; *ptr; ptr++)
105 if ('\n' == *ptr)
107 m_line++;
108 m_column = 0;
110 else
111 m_column++;
114 free (buf);
117 /* Construct a gcc::jit::recording::location instance for the current
118 location within the dump. */
120 recording::location *
121 dump::make_location () const
123 return m_ctxt.new_location (m_filename, m_line, m_column);
126 /**********************************************************************
127 Recording.
128 **********************************************************************/
130 /* Get the playback::location for the given recording::location,
131 handling a NULL input with a NULL output. */
133 playback::location *
134 recording::playback_location (replayer *r, recording::location *loc)
136 if (loc)
137 return loc->playback_location (r);
138 else
139 return NULL;
142 /* Get a const char * for the given recording::string
143 handling a NULL input with a NULL output. */
145 const char *
146 recording::playback_string (recording::string *str)
148 if (str)
149 return str->c_str ();
150 else
151 return NULL;
154 /* Get the playback::block for the given recording::block,
155 handling a NULL input with a NULL output. */
157 playback::block *
158 recording::playback_block (recording::block *b)
160 if (b)
161 return b->playback_block ();
162 else
163 return NULL;
166 /* Methods of cc::jit::recording::context. */
168 /* The constructor for gcc::jit::recording::context, used by
169 gcc_jit_context_acquire and gcc_jit_context_new_child_context. */
171 recording::context::context (context *parent_ctxt)
172 : m_parent_ctxt (parent_ctxt),
173 m_error_count (0),
174 m_first_error_str (NULL),
175 m_owns_first_error_str (false),
176 m_mementos (),
177 m_compound_types (),
178 m_functions (),
179 m_FILE_type (NULL),
180 m_builtins_manager(NULL)
182 if (parent_ctxt)
184 /* Inherit options from parent. */
185 for (unsigned i = 0;
186 i < sizeof (m_str_options) / sizeof (m_str_options[0]);
187 i++)
189 const char *parent_opt = parent_ctxt->m_str_options[i];
190 m_str_options[i] = parent_opt ? xstrdup (parent_opt) : NULL;
192 memcpy (m_int_options,
193 parent_ctxt->m_int_options,
194 sizeof (m_int_options));
195 memcpy (m_bool_options,
196 parent_ctxt->m_bool_options,
197 sizeof (m_bool_options));
199 else
201 memset (m_str_options, 0, sizeof (m_str_options));
202 memset (m_int_options, 0, sizeof (m_int_options));
203 memset (m_bool_options, 0, sizeof (m_bool_options));
206 memset (m_basic_types, 0, sizeof (m_basic_types));
209 /* The destructor for gcc::jit::recording::context, implicitly used by
210 gcc_jit_context_release. */
212 recording::context::~context ()
214 int i;
215 memento *m;
216 FOR_EACH_VEC_ELT (m_mementos, i, m)
218 delete m;
221 for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
222 free (m_str_options[i]);
224 if (m_builtins_manager)
225 delete m_builtins_manager;
227 if (m_owns_first_error_str)
228 free (m_first_error_str);
231 /* Add the given mememto to the list of those tracked by this
232 gcc::jit::recording::context, so that e.g. it can be deleted
233 when this context is released. */
235 void
236 recording::context::record (memento *m)
238 gcc_assert (m);
240 m_mementos.safe_push (m);
243 /* Replay this context (and any parents) into the given replayer. */
245 void
246 recording::context::replay_into (replayer *r)
248 int i;
249 memento *m;
251 /* If we have a parent context, we must replay it. This will
252 recursively walk backwards up the historical tree, then replay things
253 forwards "in historical order", starting with the ultimate parent
254 context, until we reach the "this" context.
256 Note that we fully replay the parent, then fully replay the child,
257 which means that inter-context references can only exist from child
258 to parent, not the other way around.
260 All of this replaying is suboptimal - it would be better to do the
261 work for the parent context *once*, rather than replaying the parent
262 every time we replay each child. However, fixing this requires deep
263 surgery to lifetime-management: we'd need every context family tree
264 to have its own GC heap, and to initialize the GCC code to use that
265 heap (with a mutex on such a heap). */
266 if (m_parent_ctxt)
267 m_parent_ctxt->replay_into (r);
269 if (r->errors_occurred ())
270 return;
272 /* Replay this context's saved operations into r. */
273 FOR_EACH_VEC_ELT (m_mementos, i, m)
275 /* Disabled low-level debugging, here if we need it: print what
276 we're replaying.
277 Note that the calls to get_debug_string might lead to more
278 mementos being created for the strings.
279 This can also be used to exercise the debug_string
280 machinery. */
281 if (0)
282 printf ("context %p replaying (%p): %s\n",
283 (void *)this, (void *)m, m->get_debug_string ());
285 m->replay_into (r);
287 if (r->errors_occurred ())
288 return;
292 /* During a playback, we associate objects from the recording with
293 their counterparts during this playback.
295 For simplicity, we store this within the recording objects.
297 The following method cleans away these associations, to ensure that
298 we never have out-of-date associations lingering on subsequent
299 playbacks (the objects pointed to are GC-managed, but the
300 recording objects don't own refs to them). */
302 void
303 recording::context::disassociate_from_playback ()
305 int i;
306 memento *m;
308 if (m_parent_ctxt)
309 m_parent_ctxt->disassociate_from_playback ();
311 FOR_EACH_VEC_ELT (m_mementos, i, m)
313 m->set_playback_obj (NULL);
317 /* Create a recording::string instance and add it to this context's list
318 of mementos.
320 This creates a fresh copy of the given 0-terminated buffer. */
322 recording::string *
323 recording::context::new_string (const char *text)
325 if (!text)
326 return NULL;
328 recording::string *result = new string (this, text);
329 record (result);
330 return result;
333 /* Create a recording::location instance and add it to this context's
334 list of mementos.
336 Implements the post-error-checking part of
337 gcc_jit_context_new_location. */
339 recording::location *
340 recording::context::new_location (const char *filename,
341 int line,
342 int column)
344 recording::location *result =
345 new recording::location (this,
346 new_string (filename),
347 line, column);
348 record (result);
349 return result;
352 /* If we haven't seen this enum value yet, create a recording::type
353 instance and add it to this context's list of mementos.
355 If we have seen it before, reuse our cached value, so that repeated
356 calls on the context give the same object.
358 If we have a parent context, the cache is within the ultimate
359 ancestor context.
361 Implements the post-error-checking part of
362 gcc_jit_context_get_type. */
364 recording::type *
365 recording::context::get_type (enum gcc_jit_types kind)
367 if (!m_basic_types[kind])
369 if (m_parent_ctxt)
370 m_basic_types[kind] = m_parent_ctxt->get_type (kind);
371 else
373 recording::type *result = new memento_of_get_type (this, kind);
374 record (result);
375 m_basic_types[kind] = result;
379 return m_basic_types[kind];
382 /* Get a recording::type instance for the given size and signedness.
383 This is implemented in terms of recording::context::get_type
384 above.
386 Implements the post-error-checking part of
387 gcc_jit_context_get_int_type. */
389 recording::type *
390 recording::context::get_int_type (int num_bytes, int is_signed)
392 /* We can't use a switch here since some of the values are macros affected
393 by options; e.g. i386.h has
394 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
395 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
396 are in bits, rather than bytes.
398 const int num_bits = num_bytes * 8;
399 if (num_bits == INT_TYPE_SIZE)
400 return get_type (is_signed
401 ? GCC_JIT_TYPE_INT
402 : GCC_JIT_TYPE_UNSIGNED_INT);
403 if (num_bits == CHAR_TYPE_SIZE)
404 return get_type (is_signed
405 ? GCC_JIT_TYPE_SIGNED_CHAR
406 : GCC_JIT_TYPE_UNSIGNED_CHAR);
407 if (num_bits == SHORT_TYPE_SIZE)
408 return get_type (is_signed
409 ? GCC_JIT_TYPE_SHORT
410 : GCC_JIT_TYPE_UNSIGNED_SHORT);
411 if (num_bits == LONG_TYPE_SIZE)
412 return get_type (is_signed
413 ? GCC_JIT_TYPE_LONG
414 : GCC_JIT_TYPE_UNSIGNED_LONG);
415 if (num_bits == LONG_LONG_TYPE_SIZE)
416 return get_type (is_signed
417 ? GCC_JIT_TYPE_LONG_LONG
418 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
420 /* Some other size, not corresponding to the C int types. */
421 /* To be written: support arbitrary other sizes, sharing by
422 memoizing at the recording::context level? */
423 gcc_unreachable ();
426 /* Create a recording::type instance and add it to this context's list
427 of mementos.
429 Implements the post-error-checking part of
430 gcc_jit_context_new_array_type. */
432 recording::type *
433 recording::context::new_array_type (recording::location *loc,
434 recording::type *element_type,
435 int num_elements)
437 if (struct_ *s = element_type->dyn_cast_struct ())
438 if (!s->get_fields ())
440 add_error (NULL,
441 "cannot create an array of type %s"
442 " until the fields have been set",
443 s->get_name ()->c_str ());
444 return NULL;
446 recording::type *result =
447 new recording::array_type (this, loc, element_type, num_elements);
448 record (result);
449 return result;
452 /* Create a recording::field instance and add it to this context's list
453 of mementos.
455 Implements the post-error-checking part of
456 gcc_jit_context_new_field. */
458 recording::field *
459 recording::context::new_field (recording::location *loc,
460 recording::type *type,
461 const char *name)
463 recording::field *result =
464 new recording::field (this, loc, type, new_string (name));
465 record (result);
466 return result;
469 /* Create a recording::struct_ instance and add it to this context's
470 list of mementos and list of compound types.
472 Implements the post-error-checking part of
473 gcc_jit_context_new_struct_type. */
475 recording::struct_ *
476 recording::context::new_struct_type (recording::location *loc,
477 const char *name)
479 recording::struct_ *result = new struct_ (this, loc, new_string (name));
480 record (result);
481 m_compound_types.safe_push (result);
482 return result;
485 /* Create a recording::union_ instance and add it to this context's
486 list of mementos and list of compound types.
488 Implements the first post-error-checking part of
489 gcc_jit_context_new_union_type. */
491 recording::union_ *
492 recording::context::new_union_type (recording::location *loc,
493 const char *name)
495 recording::union_ *result = new union_ (this, loc, new_string (name));
496 record (result);
497 m_compound_types.safe_push (result);
498 return result;
501 /* Create a recording::function_type instance and add it to this context's
502 list of mementos.
504 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
506 recording::function_type *
507 recording::context::new_function_type (recording::type *return_type,
508 int num_params,
509 recording::type **param_types,
510 int is_variadic)
512 recording::function_type *fn_type
513 = new function_type (this,
514 return_type,
515 num_params,
516 param_types,
517 is_variadic);
518 record (fn_type);
519 return fn_type;
522 /* Create a recording::type instance and add it to this context's list
523 of mementos.
525 Implements the post-error-checking part of
526 gcc_jit_context_new_function_ptr_type. */
528 recording::type *
529 recording::context::new_function_ptr_type (recording::location *, /* unused loc */
530 recording::type *return_type,
531 int num_params,
532 recording::type **param_types,
533 int is_variadic)
535 recording::function_type *fn_type
536 = new_function_type (return_type,
537 num_params,
538 param_types,
539 is_variadic);
541 /* Return a pointer-type to the the function type. */
542 return fn_type->get_pointer ();
545 /* Create a recording::param instance and add it to this context's list
546 of mementos.
548 Implements the post-error-checking part of
549 gcc_jit_context_new_param. */
551 recording::param *
552 recording::context::new_param (recording::location *loc,
553 recording::type *type,
554 const char *name)
556 recording::param *result = new recording::param (this, loc, type, new_string (name));
557 record (result);
558 return result;
561 /* Create a recording::function instance and add it to this context's list
562 of mementos and list of functions.
564 Implements the post-error-checking part of
565 gcc_jit_context_new_function. */
567 recording::function *
568 recording::context::new_function (recording::location *loc,
569 enum gcc_jit_function_kind kind,
570 recording::type *return_type,
571 const char *name,
572 int num_params,
573 recording::param **params,
574 int is_variadic,
575 enum built_in_function builtin_id)
577 recording::function *result =
578 new recording::function (this,
579 loc, kind, return_type,
580 new_string (name),
581 num_params, params, is_variadic,
582 builtin_id);
583 record (result);
584 m_functions.safe_push (result);
586 return result;
589 /* Locate the builtins_manager (if any) for this family of contexts,
590 creating it if it doesn't exist already.
592 All of the recording contexts in a family share one builtins_manager:
593 if we have a child context, follow the parent links to get the
594 ultimate ancestor context, and look for it/store it there. */
596 builtins_manager *
597 recording::context::get_builtins_manager ()
599 if (m_parent_ctxt)
600 return m_parent_ctxt->get_builtins_manager ();
602 if (!m_builtins_manager)
603 m_builtins_manager = new builtins_manager (this);
605 return m_builtins_manager;
608 /* Get a recording::function instance, which is lazily-created and added
609 to the context's lists of mementos.
611 Implements the post-error-checking part of
612 gcc_jit_context_get_builtin_function. */
614 recording::function *
615 recording::context::get_builtin_function (const char *name)
617 builtins_manager *bm = get_builtins_manager ();
618 return bm->get_builtin_function (name);
621 /* Create a recording::global instance and add it to this context's list
622 of mementos.
624 Implements the post-error-checking part of
625 gcc_jit_context_new_global. */
627 recording::lvalue *
628 recording::context::new_global (recording::location *loc,
629 recording::type *type,
630 const char *name)
632 recording::lvalue *result =
633 new recording::global (this, loc, type, new_string (name));
634 record (result);
635 return result;
638 /* Create a recording::memento_of_new_rvalue_from_int instance and add
639 it to this context's list of mementos.
641 Implements the post-error-checking part of
642 gcc_jit_context_new_rvalue_from_int. */
644 recording::rvalue *
645 recording::context::new_rvalue_from_int (recording::type *type,
646 int value)
648 recording::rvalue *result =
649 new memento_of_new_rvalue_from_int (this, NULL, type, value);
650 record (result);
651 return result;
654 /* Create a recording::memento_of_new_rvalue_from_double instance and
655 add it to this context's list of mementos.
657 Implements the post-error-checking part of
658 gcc_jit_context_new_rvalue_from_double. */
660 recording::rvalue *
661 recording::context::new_rvalue_from_double (recording::type *type,
662 double value)
664 recording::rvalue *result =
665 new memento_of_new_rvalue_from_double (this, NULL, type, value);
666 record (result);
667 return result;
670 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
671 it to this context's list of mementos.
673 Implements the post-error-checking part of
674 gcc_jit_context_new_rvalue_from_ptr. */
676 recording::rvalue *
677 recording::context::new_rvalue_from_ptr (recording::type *type,
678 void *value)
680 recording::rvalue *result =
681 new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
682 record (result);
683 return result;
686 /* Create a recording::memento_of_new_string_literal instance and add it
687 to this context's list of mementos.
689 Implements the post-error-checking part of
690 gcc_jit_context_new_string_literal. */
692 recording::rvalue *
693 recording::context::new_string_literal (const char *value)
695 recording::rvalue *result =
696 new memento_of_new_string_literal (this, NULL, new_string (value));
697 record (result);
698 return result;
701 /* Create a recording::unary_op instance and add it to this context's
702 list of mementos.
704 Implements the post-error-checking part of
705 gcc_jit_context_new_unary_op. */
707 recording::rvalue *
708 recording::context::new_unary_op (recording::location *loc,
709 enum gcc_jit_unary_op op,
710 recording::type *result_type,
711 recording::rvalue *a)
713 recording::rvalue *result =
714 new unary_op (this, loc, op, result_type, a);
715 record (result);
716 return result;
719 /* Create a recording::binary_op instance and add it to this context's
720 list of mementos.
722 Implements the post-error-checking part of
723 gcc_jit_context_new_binary_op. */
725 recording::rvalue *
726 recording::context::new_binary_op (recording::location *loc,
727 enum gcc_jit_binary_op op,
728 recording::type *result_type,
729 recording::rvalue *a,
730 recording::rvalue *b)
732 recording::rvalue *result =
733 new binary_op (this, loc, op, result_type, a, b);
734 record (result);
735 return result;
738 /* Create a recording::comparison instance and add it to this context's
739 list of mementos.
741 Implements the post-error-checking part of
742 gcc_jit_context_new_comparison. */
744 recording::rvalue *
745 recording::context::new_comparison (recording::location *loc,
746 enum gcc_jit_comparison op,
747 recording::rvalue *a,
748 recording::rvalue *b)
750 recording::rvalue *result = new comparison (this, loc, op, a, b);
751 record (result);
752 return result;
755 /* Create a recording::cast instance and add it to this context's list
756 of mementos.
758 Implements the post-error-checking part of
759 gcc_jit_context_new_cast. */
761 recording::rvalue *
762 recording::context::new_cast (recording::location *loc,
763 recording::rvalue *expr,
764 recording::type *type_)
766 recording::rvalue *result = new cast (this, loc, expr, type_);
767 record (result);
768 return result;
771 /* Create a recording::call instance and add it to this context's list
772 of mementos.
774 Implements the post-error-checking part of
775 gcc_jit_context_new_call. */
777 recording::rvalue *
778 recording::context::new_call (recording::location *loc,
779 function *func,
780 int numargs , recording::rvalue **args)
782 recording::rvalue *result = new call (this, loc, func, numargs, args);
783 record (result);
784 return result;
787 /* Create a recording::call_through_ptr instance and add it to this
788 context's list of mementos.
790 Implements the post-error-checking part of
791 gcc_jit_context_new_call_through_ptr. */
793 recording::rvalue *
794 recording::context::new_call_through_ptr (recording::location *loc,
795 recording::rvalue *fn_ptr,
796 int numargs,
797 recording::rvalue **args)
799 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
800 record (result);
801 return result;
804 /* Create a recording::array_access instance and add it to this context's list
805 of mementos.
807 Implements the post-error-checking part of
808 gcc_jit_context_new_array_access. */
810 recording::lvalue *
811 recording::context::new_array_access (recording::location *loc,
812 recording::rvalue *ptr,
813 recording::rvalue *index)
815 recording::lvalue *result = new array_access (this, loc, ptr, index);
816 record (result);
817 return result;
820 /* Set the given string option for this context, or add an error if
821 it's not recognized.
823 Implements the post-error-checking part of
824 gcc_jit_context_set_str_option. */
826 void
827 recording::context::set_str_option (enum gcc_jit_str_option opt,
828 const char *value)
830 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
832 add_error (NULL,
833 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
834 return;
836 free (m_str_options[opt]);
837 m_str_options[opt] = value ? xstrdup (value) : NULL;
840 /* Set the given integer option for this context, or add an error if
841 it's not recognized.
843 Implements the post-error-checking part of
844 gcc_jit_context_set_int_option. */
846 void
847 recording::context::set_int_option (enum gcc_jit_int_option opt,
848 int value)
850 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
852 add_error (NULL,
853 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
854 return;
856 m_int_options[opt] = value;
859 /* Set the given boolean option for this context, or add an error if
860 it's not recognized.
862 Implements the post-error-checking part of
863 gcc_jit_context_set_bool_option. */
865 void
866 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
867 int value)
869 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
871 add_error (NULL,
872 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
873 return;
875 m_bool_options[opt] = value ? true : false;
878 /* Add the given dumpname/out_ptr pair to this context's list of requested
879 dumps.
881 Implements the post-error-checking part of
882 gcc_jit_context_enable_dump. */
884 void
885 recording::context::enable_dump (const char *dumpname,
886 char **out_ptr)
888 requested_dump d;
889 gcc_assert (dumpname);
890 gcc_assert (out_ptr);
892 d.m_dumpname = dumpname;
893 d.m_out_ptr = out_ptr;
894 *out_ptr = NULL;
895 m_requested_dumps.safe_push (d);
898 /* Validate this context, and if it passes, compile it within a
899 mutex.
901 Implements the post-error-checking part of
902 gcc_jit_context_compile. */
904 result *
905 recording::context::compile ()
907 validate ();
909 if (errors_occurred ())
910 return NULL;
912 /* Set up a playback context. */
913 ::gcc::jit::playback::context replayer (this);
915 /* Use it. */
916 result *result_obj = replayer.compile ();
918 return result_obj;
921 /* Format the given error using printf's conventions, print
922 it to stderr, and add it to the context. */
924 void
925 recording::context::add_error (location *loc, const char *fmt, ...)
927 va_list ap;
928 va_start (ap, fmt);
929 add_error_va (loc, fmt, ap);
930 va_end (ap);
933 /* Format the given error using printf's conventions, print
934 it to stderr, and add it to the context. */
936 void
937 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
939 char *malloced_msg;
940 const char *errmsg;
941 bool has_ownership;
943 vasprintf (&malloced_msg, fmt, ap);
944 if (malloced_msg)
946 errmsg = malloced_msg;
947 has_ownership = true;
949 else
951 errmsg = "out of memory generating error message";
952 has_ownership = false;
955 const char *ctxt_progname =
956 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
957 if (!ctxt_progname)
958 ctxt_progname = "libgccjit.so";
960 if (loc)
961 fprintf (stderr, "%s: %s: error: %s\n",
962 ctxt_progname,
963 loc->get_debug_string (),
964 errmsg);
965 else
966 fprintf (stderr, "%s: error: %s\n",
967 ctxt_progname,
968 errmsg);
970 if (!m_error_count)
972 m_first_error_str = const_cast <char *> (errmsg);
973 m_owns_first_error_str = has_ownership;
975 else
976 if (has_ownership)
977 free (malloced_msg);
979 m_error_count++;
982 /* Get the message for the first error that occurred on this context, or
983 NULL if no errors have occurred on it.
985 Implements the post-error-checking part of
986 gcc_jit_context_get_first_error. */
988 const char *
989 recording::context::get_first_error () const
991 return m_first_error_str;
994 /* Lazily generate and record a recording::type representing an opaque
995 struct named "FILE".
997 For use if client code tries to dereference the result of
998 get_type (GCC_JIT_TYPE_FILE_PTR). */
1000 recording::type *
1001 recording::context::get_opaque_FILE_type ()
1003 if (!m_FILE_type)
1004 m_FILE_type = new_struct_type (NULL, "FILE");
1005 return m_FILE_type;
1008 /* Dump a C-like representation of the given context to the given path.
1009 If UPDATE_LOCATIONS is true, update the locations within the
1010 context's mementos to point to the dumpfile.
1012 Implements the post-error-checking part of
1013 gcc_jit_context_dump_to_file. */
1015 void
1016 recording::context::dump_to_file (const char *path, bool update_locations)
1018 int i;
1019 dump d (*this, path, update_locations);
1021 /* Forward declaration of structs and unions. */
1022 compound_type *st;
1023 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1025 d.write ("%s;\n\n", st->get_debug_string ());
1028 /* Content of structs, where set. */
1029 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1030 if (st->get_fields ())
1032 st->get_fields ()->write_to_dump (d);
1033 d.write ("\n");
1036 function *fn;
1037 FOR_EACH_VEC_ELT (m_functions, i, fn)
1039 fn->write_to_dump (d);
1043 /* Copy the requested dumps within this context and all ancestors into
1044 OUT. */
1046 void
1047 recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
1049 if (m_parent_ctxt)
1050 m_parent_ctxt->get_all_requested_dumps (out);
1052 out->reserve (m_requested_dumps.length ());
1053 out->splice (m_requested_dumps);
1056 /* This is a pre-compilation check for the context (and any parents).
1058 Detect errors within the context, adding errors if any are found. */
1060 void
1061 recording::context::validate ()
1063 if (m_parent_ctxt)
1064 m_parent_ctxt->validate ();
1066 int i;
1067 function *fn;
1068 FOR_EACH_VEC_ELT (m_functions, i, fn)
1069 fn->validate ();
1072 /* The implementation of class gcc::jit::recording::memento. */
1074 /* Get a (const char *) debug description of the given memento, by
1075 calling the pure-virtual make_debug_string hook, caching the
1076 result.
1078 It is intended that this should only be called in debugging and
1079 error-handling paths, so this doesn't need to be particularly
1080 optimized. */
1082 const char *
1083 recording::memento::get_debug_string ()
1085 if (!m_debug_string)
1086 m_debug_string = make_debug_string ();
1087 return m_debug_string->c_str ();
1090 /* Default implementation of recording::memento::write_to_dump, writing
1091 an indented form of the memento's debug string to the dump. */
1093 void
1094 recording::memento::write_to_dump (dump &d)
1096 d.write(" %s\n", get_debug_string ());
1099 /* The implementation of class gcc::jit::recording::string. */
1101 /* Constructor for gcc::jit::recording::string::string, allocating a
1102 copy of the given text using new char[]. */
1104 recording::string::string (context *ctxt, const char *text)
1105 : memento (ctxt)
1107 m_len = strlen (text);
1108 m_buffer = new char[m_len + 1];
1109 strcpy (m_buffer, text);
1112 /* Destructor for gcc::jit::recording::string::string. */
1114 recording::string::~string ()
1116 delete[] m_buffer;
1119 /* Function for making gcc::jit::recording::string instances on a
1120 context via printf-style formatting.
1122 It is intended that this should only be called in debugging and
1123 error-handling paths, so this doesn't need to be particularly
1124 optimized, hence the double-copy of the string is acceptable. */
1126 recording::string *
1127 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1129 va_list ap;
1130 char *buf = NULL;
1131 recording::string *result;
1133 va_start (ap, fmt);
1134 vasprintf (&buf, fmt, ap);
1135 va_end (ap);
1137 if (!buf)
1139 ctxt->add_error (NULL, "malloc failure");
1140 return NULL;
1143 result = ctxt->new_string (buf);
1144 free (buf);
1145 return result;
1148 /* Implementation of recording::memento::make_debug_string for strings,
1149 wrapping the given string in quotes and escaping as necessary. */
1151 recording::string *
1152 recording::string::make_debug_string ()
1154 /* Hack to avoid infinite recursion into strings when logging all
1155 mementos: don't re-escape strings: */
1156 if (m_buffer[0] == '"')
1157 return this;
1159 /* Wrap in quotes and do escaping etc */
1161 size_t sz = (1 /* opening quote */
1162 + (m_len * 2) /* each char might get escaped */
1163 + 1 /* closing quote */
1164 + 1); /* nil termintator */
1165 char *tmp = new char[sz];
1166 size_t len = 0;
1168 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1169 APPEND('"'); /* opening quote */
1170 for (size_t i = 0; i < m_len ; i++)
1172 char ch = m_buffer[i];
1173 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1174 APPEND('\\');
1175 APPEND(ch);
1177 APPEND('"'); /* closing quote */
1178 #undef APPEND
1179 tmp[len] = '\0'; /* nil termintator */
1181 string *result = m_ctxt->new_string (tmp);
1183 delete[] tmp;
1184 return result;
1187 /* The implementation of class gcc::jit::recording::location. */
1189 /* Implementation of recording::memento::replay_into for locations.
1191 Create a new playback::location and store it into the
1192 recording::location's m_playback_obj field. */
1194 void
1195 recording::location::replay_into (replayer *r)
1197 m_playback_obj = r->new_location (this,
1198 m_filename->c_str (),
1199 m_line,
1200 m_column);
1203 /* Implementation of recording::memento::make_debug_string for locations,
1204 turning them into the usual form:
1205 FILENAME:LINE:COLUMN
1206 like we do when emitting diagnostics. */
1208 recording::string *
1209 recording::location::make_debug_string ()
1211 return string::from_printf (m_ctxt,
1212 "%s:%i:%i",
1213 m_filename->c_str (), m_line, m_column);
1216 /* The implementation of class gcc::jit::recording::type. */
1218 /* Given a type T, get the type T*.
1220 If this doesn't already exist, generate a new memento_of_get_pointer
1221 instance and add it to this type's context's list of mementos.
1223 Otherwise, use the cached type.
1225 Implements the post-error-checking part of
1226 gcc_jit_type_get_pointer. */
1228 recording::type *
1229 recording::type::get_pointer ()
1231 if (!m_pointer_to_this_type)
1233 m_pointer_to_this_type = new memento_of_get_pointer (this);
1234 m_ctxt->record (m_pointer_to_this_type);
1236 return m_pointer_to_this_type;
1239 /* Given a type T, get the type const T.
1241 Implements the post-error-checking part of
1242 gcc_jit_type_get_const. */
1244 recording::type *
1245 recording::type::get_const ()
1247 recording::type *result = new memento_of_get_const (this);
1248 m_ctxt->record (result);
1249 return result;
1252 /* Given a type T, get the type volatile T.
1254 Implements the post-error-checking part of
1255 gcc_jit_type_get_volatile. */
1257 recording::type *
1258 recording::type::get_volatile ()
1260 recording::type *result = new memento_of_get_volatile (this);
1261 m_ctxt->record (result);
1262 return result;
1265 /* Implementation of pure virtual hook recording::type::dereference for
1266 recording::memento_of_get_type. */
1268 recording::type *
1269 recording::memento_of_get_type::dereference ()
1271 switch (m_kind)
1273 default: gcc_unreachable ();
1275 case GCC_JIT_TYPE_VOID:
1276 return NULL;
1278 case GCC_JIT_TYPE_VOID_PTR:
1279 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1281 case GCC_JIT_TYPE_BOOL:
1282 case GCC_JIT_TYPE_CHAR:
1283 case GCC_JIT_TYPE_SIGNED_CHAR:
1284 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1285 case GCC_JIT_TYPE_SHORT:
1286 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1287 case GCC_JIT_TYPE_INT:
1288 case GCC_JIT_TYPE_UNSIGNED_INT:
1289 case GCC_JIT_TYPE_LONG:
1290 case GCC_JIT_TYPE_UNSIGNED_LONG:
1291 case GCC_JIT_TYPE_LONG_LONG:
1292 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1293 case GCC_JIT_TYPE_FLOAT:
1294 case GCC_JIT_TYPE_DOUBLE:
1295 case GCC_JIT_TYPE_LONG_DOUBLE:
1296 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1297 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1298 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1299 /* Not a pointer: */
1300 return NULL;
1302 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1303 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1305 case GCC_JIT_TYPE_SIZE_T:
1306 /* Not a pointer: */
1307 return NULL;
1309 case GCC_JIT_TYPE_FILE_PTR:
1310 /* Give the client code back an opaque "struct FILE". */
1311 return m_ctxt->get_opaque_FILE_type ();
1315 /* Implementation of pure virtual hook recording::type::is_int for
1316 recording::memento_of_get_type. */
1318 bool
1319 recording::memento_of_get_type::is_int () const
1321 switch (m_kind)
1323 default: gcc_unreachable ();
1325 case GCC_JIT_TYPE_VOID:
1326 return false;
1328 case GCC_JIT_TYPE_VOID_PTR:
1329 return false;
1331 case GCC_JIT_TYPE_BOOL:
1332 return false;
1334 case GCC_JIT_TYPE_CHAR:
1335 case GCC_JIT_TYPE_SIGNED_CHAR:
1336 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1337 case GCC_JIT_TYPE_SHORT:
1338 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1339 case GCC_JIT_TYPE_INT:
1340 case GCC_JIT_TYPE_UNSIGNED_INT:
1341 case GCC_JIT_TYPE_LONG:
1342 case GCC_JIT_TYPE_UNSIGNED_LONG:
1343 case GCC_JIT_TYPE_LONG_LONG:
1344 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1345 return true;
1347 case GCC_JIT_TYPE_FLOAT:
1348 case GCC_JIT_TYPE_DOUBLE:
1349 case GCC_JIT_TYPE_LONG_DOUBLE:
1350 return false;
1352 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1353 return false;
1355 case GCC_JIT_TYPE_SIZE_T:
1356 return true;
1358 case GCC_JIT_TYPE_FILE_PTR:
1359 return false;
1361 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1362 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1363 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1364 return false;
1368 /* Implementation of pure virtual hook recording::type::is_float for
1369 recording::memento_of_get_type. */
1371 bool
1372 recording::memento_of_get_type::is_float () const
1374 switch (m_kind)
1376 default: gcc_unreachable ();
1378 case GCC_JIT_TYPE_VOID:
1379 return false;
1381 case GCC_JIT_TYPE_VOID_PTR:
1382 return false;
1384 case GCC_JIT_TYPE_BOOL:
1385 return false;
1387 case GCC_JIT_TYPE_CHAR:
1388 case GCC_JIT_TYPE_SIGNED_CHAR:
1389 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1390 case GCC_JIT_TYPE_SHORT:
1391 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1392 case GCC_JIT_TYPE_INT:
1393 case GCC_JIT_TYPE_UNSIGNED_INT:
1394 case GCC_JIT_TYPE_LONG:
1395 case GCC_JIT_TYPE_UNSIGNED_LONG:
1396 case GCC_JIT_TYPE_LONG_LONG:
1397 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1398 return false;
1400 case GCC_JIT_TYPE_FLOAT:
1401 case GCC_JIT_TYPE_DOUBLE:
1402 case GCC_JIT_TYPE_LONG_DOUBLE:
1403 return true;
1405 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1406 return false;
1408 case GCC_JIT_TYPE_SIZE_T:
1409 return false;
1411 case GCC_JIT_TYPE_FILE_PTR:
1412 return false;
1414 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1415 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1416 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1417 return true;
1421 /* Implementation of pure virtual hook recording::type::is_bool for
1422 recording::memento_of_get_type. */
1424 bool
1425 recording::memento_of_get_type::is_bool () const
1427 switch (m_kind)
1429 default: gcc_unreachable ();
1431 case GCC_JIT_TYPE_VOID:
1432 return false;
1434 case GCC_JIT_TYPE_VOID_PTR:
1435 return false;
1437 case GCC_JIT_TYPE_BOOL:
1438 return true;
1440 case GCC_JIT_TYPE_CHAR:
1441 case GCC_JIT_TYPE_SIGNED_CHAR:
1442 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1443 case GCC_JIT_TYPE_SHORT:
1444 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1445 case GCC_JIT_TYPE_INT:
1446 case GCC_JIT_TYPE_UNSIGNED_INT:
1447 case GCC_JIT_TYPE_LONG:
1448 case GCC_JIT_TYPE_UNSIGNED_LONG:
1449 case GCC_JIT_TYPE_LONG_LONG:
1450 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1451 return false;
1453 case GCC_JIT_TYPE_FLOAT:
1454 case GCC_JIT_TYPE_DOUBLE:
1455 case GCC_JIT_TYPE_LONG_DOUBLE:
1456 return false;
1458 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1459 return false;
1461 case GCC_JIT_TYPE_SIZE_T:
1462 return false;
1464 case GCC_JIT_TYPE_FILE_PTR:
1465 return false;
1467 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1468 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1469 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1470 return false;
1474 /* Implementation of pure virtual hook recording::memento::replay_into
1475 for recording::memento_of_get_type. */
1477 void
1478 recording::memento_of_get_type::replay_into (replayer *r)
1480 set_playback_obj (r->get_type (m_kind));
1483 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1485 /* Descriptive strings for each of enum gcc_jit_types. */
1487 static const char * const get_type_strings[] = {
1488 "void", /* GCC_JIT_TYPE_VOID */
1489 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1491 "bool", /* GCC_JIT_TYPE_BOOL */
1493 "char", /* GCC_JIT_TYPE_CHAR */
1494 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1495 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1497 "short", /* GCC_JIT_TYPE_SHORT */
1498 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1500 "int", /* GCC_JIT_TYPE_INT */
1501 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1503 "long", /* GCC_JIT_TYPE_LONG */
1504 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1506 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1507 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1509 "float", /* GCC_JIT_TYPE_FLOAT */
1510 "double", /* GCC_JIT_TYPE_DOUBLE */
1511 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1513 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1515 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1517 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1519 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1520 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1521 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1525 /* Implementation of recording::memento::make_debug_string for
1526 results of get_type, using a simple table of type names. */
1528 recording::string *
1529 recording::memento_of_get_type::make_debug_string ()
1531 return m_ctxt->new_string (get_type_strings[m_kind]);
1534 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1536 /* Override of default implementation of
1537 recording::type::accepts_writes_from for get_pointer.
1539 Require a pointer type, and allowing writes to
1540 (const T *) from a (T*), but not the other way around. */
1542 bool
1543 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1545 /* Must be a pointer type: */
1546 type *rtype_points_to = rtype->is_pointer ();
1547 if (!rtype_points_to)
1548 return false;
1550 /* It's OK to assign to a (const T *) from a (T *). */
1551 return m_other_type->unqualified ()
1552 ->accepts_writes_from (rtype_points_to);
1555 /* Implementation of pure virtual hook recording::memento::replay_into
1556 for recording::memento_of_get_pointer. */
1558 void
1559 recording::memento_of_get_pointer::replay_into (replayer *)
1561 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1564 /* Implementation of recording::memento::make_debug_string for
1565 results of get_pointer, adding " *" to the underlying type,
1566 with special-casing to handle function pointer types. */
1568 recording::string *
1569 recording::memento_of_get_pointer::make_debug_string ()
1571 /* Special-case function pointer types, to put the "*" in parens between
1572 the return type and the params (for one level of dereferencing, at
1573 least). */
1574 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1575 return fn_type->make_debug_string_with_ptr ();
1577 return string::from_printf (m_ctxt,
1578 "%s *", m_other_type->get_debug_string ());
1581 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1583 /* Implementation of pure virtual hook recording::memento::replay_into
1584 for recording::memento_of_get_const. */
1586 void
1587 recording::memento_of_get_const::replay_into (replayer *)
1589 set_playback_obj (m_other_type->playback_type ()->get_const ());
1592 /* Implementation of recording::memento::make_debug_string for
1593 results of get_const, prepending "const ". */
1595 recording::string *
1596 recording::memento_of_get_const::make_debug_string ()
1598 return string::from_printf (m_ctxt,
1599 "const %s", m_other_type->get_debug_string ());
1602 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1604 /* Implementation of pure virtual hook recording::memento::replay_into
1605 for recording::memento_of_get_volatile. */
1607 void
1608 recording::memento_of_get_volatile::replay_into (replayer *)
1610 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1613 /* Implementation of recording::memento::make_debug_string for
1614 results of get_volatile, prepending "volatile ". */
1616 recording::string *
1617 recording::memento_of_get_volatile::make_debug_string ()
1619 return string::from_printf (m_ctxt,
1620 "volatile %s", m_other_type->get_debug_string ());
1623 /* The implementation of class gcc::jit::recording::array_type */
1625 /* Implementation of pure virtual hook recording::type::dereference for
1626 recording::array_type. */
1628 recording::type *
1629 recording::array_type::dereference ()
1631 return m_element_type;
1634 /* Implementation of pure virtual hook recording::memento::replay_into
1635 for recording::array_type. */
1637 void
1638 recording::array_type::replay_into (replayer *r)
1640 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1641 m_element_type->playback_type (),
1642 m_num_elements));
1645 /* Implementation of recording::memento::make_debug_string for
1646 results of new_array_type. */
1648 recording::string *
1649 recording::array_type::make_debug_string ()
1651 return string::from_printf (m_ctxt,
1652 "%s[%d]",
1653 m_element_type->get_debug_string (),
1654 m_num_elements);
1657 /* The implementation of class gcc::jit::recording::function_type */
1659 /* Constructor for gcc::jit::recording::function_type. */
1661 recording::function_type::function_type (context *ctxt,
1662 type *return_type,
1663 int num_params,
1664 type **param_types,
1665 int is_variadic)
1666 : type (ctxt),
1667 m_return_type (return_type),
1668 m_param_types (),
1669 m_is_variadic (is_variadic)
1671 for (int i = 0; i< num_params; i++)
1672 m_param_types.safe_push (param_types[i]);
1675 /* Implementation of pure virtual hook recording::type::dereference for
1676 recording::function_type. */
1678 recording::type *
1679 recording::function_type::dereference ()
1681 return NULL;
1684 /* Implementation of pure virtual hook recording::memento::replay_into
1685 for recording::function_type. */
1687 void
1688 recording::function_type::replay_into (replayer *r)
1690 /* Convert m_param_types to a vec of playback type. */
1691 auto_vec <playback::type *> param_types;
1692 int i;
1693 recording::type *type;
1694 param_types.create (m_param_types.length ());
1695 FOR_EACH_VEC_ELT (m_param_types, i, type)
1696 param_types.safe_push (type->playback_type ());
1698 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1699 &param_types,
1700 m_is_variadic));
1703 /* Special-casing for make_debug_string for get_pointer results for
1704 handling (one level) of pointers to functions. */
1706 recording::string *
1707 recording::function_type::make_debug_string_with_ptr ()
1709 return make_debug_string_with ("(*) ");
1712 /* Implementation of recording::memento::make_debug_string for
1713 results of new_function_type. */
1715 recording::string *
1716 recording::function_type::make_debug_string ()
1718 return make_debug_string_with ("");
1721 /* Build a debug string representation of the form:
1723 RESULT_TYPE INSERT (PARAM_TYPES)
1725 for use when handling 0 and 1 level of indirection to this
1726 function type. */
1728 recording::string *
1729 recording::function_type::make_debug_string_with (const char *insert)
1731 /* First, build a buffer for the arguments. */
1732 /* Calculate length of said buffer. */
1733 size_t sz = 1; /* nil terminator */
1734 for (unsigned i = 0; i< m_param_types.length (); i++)
1736 sz += strlen (m_param_types[i]->get_debug_string ());
1737 sz += 2; /* ", " separator */
1739 if (m_is_variadic)
1740 sz += 5; /* ", ..." separator and ellipsis */
1742 /* Now allocate and populate the buffer. */
1743 char *argbuf = new char[sz];
1744 size_t len = 0;
1746 for (unsigned i = 0; i< m_param_types.length (); i++)
1748 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1749 len += strlen (m_param_types[i]->get_debug_string ());
1750 if (i + 1 < m_param_types.length ())
1752 strcpy (argbuf + len, ", ");
1753 len += 2;
1756 if (m_is_variadic)
1758 if (m_param_types.length ())
1760 strcpy (argbuf + len, ", ");
1761 len += 2;
1763 strcpy (argbuf + len, "...");
1764 len += 3;
1766 argbuf[len] = '\0';
1768 /* ...and use it to get the string for the call as a whole. */
1769 string *result = string::from_printf (m_ctxt,
1770 "%s %s(%s)",
1771 m_return_type->get_debug_string (),
1772 insert,
1773 argbuf);
1775 delete[] argbuf;
1777 return result;
1780 /* The implementation of class gcc::jit::recording::field. */
1782 /* Implementation of pure virtual hook recording::memento::replay_into
1783 for recording::field. */
1785 void
1786 recording::field::replay_into (replayer *r)
1788 set_playback_obj (r->new_field (playback_location (r, m_loc),
1789 m_type->playback_type (),
1790 playback_string (m_name)));
1793 /* Override the default implementation of
1794 recording::memento::write_to_dump. Dump each field
1795 by dumping a line of the form:
1796 TYPE NAME;
1797 so that we can build up a struct/union field-byfield. */
1799 void
1800 recording::field::write_to_dump (dump &d)
1802 d.write (" %s %s;\n",
1803 m_type->get_debug_string (),
1804 m_name->c_str ());
1807 /* Implementation of recording::memento::make_debug_string for
1808 results of new_field. */
1810 recording::string *
1811 recording::field::make_debug_string ()
1813 return m_name;
1816 /* The implementation of class gcc::jit::recording::compound_type */
1818 /* The constructor for gcc::jit::recording::compound_type. */
1820 recording::compound_type::compound_type (context *ctxt,
1821 location *loc,
1822 string *name)
1823 : type (ctxt),
1824 m_loc (loc),
1825 m_name (name),
1826 m_fields (NULL)
1830 /* Set the fields of a compound type.
1832 Implements the post-error-checking part of
1833 gcc_jit_struct_set_fields, and is also used by
1834 gcc_jit_context_new_union_type. */
1836 void
1837 recording::compound_type::set_fields (location *loc,
1838 int num_fields,
1839 field **field_array)
1841 m_loc = loc;
1842 gcc_assert (NULL == m_fields);
1844 m_fields = new fields (this, num_fields, field_array);
1845 m_ctxt->record (m_fields);
1848 /* Implementation of pure virtual hook recording::type::dereference for
1849 recording::compound_type. */
1851 recording::type *
1852 recording::compound_type::dereference ()
1854 return NULL; /* not a pointer */
1857 /* The implementation of class gcc::jit::recording::struct_. */
1859 /* The constructor for gcc::jit::recording::struct_. */
1861 recording::struct_::struct_ (context *ctxt,
1862 location *loc,
1863 string *name)
1864 : compound_type (ctxt, loc, name)
1868 /* Implementation of pure virtual hook recording::memento::replay_into
1869 for recording::struct_. */
1871 void
1872 recording::struct_::replay_into (replayer *r)
1874 set_playback_obj (
1875 r->new_compound_type (playback_location (r, get_loc ()),
1876 get_name ()->c_str (),
1877 true /* is_struct */));
1880 /* Implementation of recording::memento::make_debug_string for
1881 structs. */
1883 recording::string *
1884 recording::struct_::make_debug_string ()
1886 return string::from_printf (m_ctxt,
1887 "struct %s", get_name ()->c_str ());
1890 /* The implementation of class gcc::jit::recording::union_. */
1892 /* The constructor for gcc::jit::recording::union_. */
1894 recording::union_::union_ (context *ctxt,
1895 location *loc,
1896 string *name)
1897 : compound_type (ctxt, loc, name)
1901 /* Implementation of pure virtual hook recording::memento::replay_into
1902 for recording::union_. */
1904 void
1905 recording::union_::replay_into (replayer *r)
1907 set_playback_obj (
1908 r->new_compound_type (playback_location (r, get_loc ()),
1909 get_name ()->c_str (),
1910 false /* is_struct */));
1913 /* Implementation of recording::memento::make_debug_string for
1914 unions. */
1916 recording::string *
1917 recording::union_::make_debug_string ()
1919 return string::from_printf (m_ctxt,
1920 "union %s", get_name ()->c_str ());
1923 /* The implementation of class gcc::jit::recording::fields. */
1925 /* The constructor for gcc::jit::recording::fields. */
1927 recording::fields::fields (compound_type *struct_or_union,
1928 int num_fields,
1929 field **fields)
1930 : memento (struct_or_union->m_ctxt),
1931 m_struct_or_union (struct_or_union),
1932 m_fields ()
1934 for (int i = 0; i < num_fields; i++)
1936 gcc_assert (fields[i]->get_container () == NULL);
1937 fields[i]->set_container (m_struct_or_union);
1938 m_fields.safe_push (fields[i]);
1942 /* Implementation of pure virtual hook recording::memento::replay_into
1943 for recording::fields. */
1945 void
1946 recording::fields::replay_into (replayer *)
1948 auto_vec<playback::field *> playback_fields;
1949 playback_fields.create (m_fields.length ());
1950 for (unsigned i = 0; i < m_fields.length (); i++)
1951 playback_fields.safe_push (m_fields[i]->playback_field ());
1952 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1955 /* Override the default implementation of
1956 recording::memento::write_to_dump by writing a union/struct
1957 declaration of this form:
1959 struct/union NAME {
1960 TYPE_1 NAME_1;
1961 TYPE_2 NAME_2;
1962 ....
1963 TYPE_N NAME_N;
1966 to the dump. */
1968 void
1969 recording::fields::write_to_dump (dump &d)
1971 int i;
1972 field *f;
1974 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
1975 FOR_EACH_VEC_ELT (m_fields, i, f)
1976 f->write_to_dump (d);
1977 d.write ("};\n");
1980 /* Implementation of recording::memento::make_debug_string for
1981 field tables. */
1983 recording::string *
1984 recording::fields::make_debug_string ()
1986 return string::from_printf (m_ctxt,
1987 "fields");
1990 /* The implementation of class gcc::jit::recording::rvalue. */
1992 /* Create a recording::access_field_rvalue instance and add it to
1993 the rvalue's context's list of mementos.
1995 Implements the post-error-checking part of
1996 gcc_jit_rvalue_access_field. */
1998 recording::rvalue *
1999 recording::rvalue::access_field (recording::location *loc,
2000 field *field)
2002 recording::rvalue *result =
2003 new access_field_rvalue (m_ctxt, loc, this, field);
2004 m_ctxt->record (result);
2005 return result;
2008 /* Create a recording::dereference_field_rvalue instance and add it to
2009 the rvalue's context's list of mementos.
2011 Implements the post-error-checking part of
2012 gcc_jit_rvalue_dereference_field. */
2014 recording::lvalue *
2015 recording::rvalue::dereference_field (recording::location *loc,
2016 field *field)
2018 recording::lvalue *result =
2019 new dereference_field_rvalue (m_ctxt, loc, this, field);
2020 m_ctxt->record (result);
2021 return result;
2024 /* Create a recording::dereference_rvalue instance and add it to the
2025 rvalue's context's list of mementos.
2027 Implements the post-error-checking part of
2028 gcc_jit_rvalue_dereference. */
2030 recording::lvalue *
2031 recording::rvalue::dereference (recording::location *loc)
2033 recording::lvalue *result =
2034 new dereference_rvalue (m_ctxt, loc, this);
2035 m_ctxt->record (result);
2036 return result;
2039 /* The implementation of class gcc::jit::recording::lvalue. */
2041 /* Create a recording::new_access_field_of_lvalue instance and add it to
2042 the lvalue's context's list of mementos.
2044 Implements the post-error-checking part of
2045 gcc_jit_lvalue_access_field. */
2047 recording::lvalue *
2048 recording::lvalue::access_field (recording::location *loc,
2049 field *field)
2051 recording::lvalue *result =
2052 new access_field_of_lvalue (m_ctxt, loc, this, field);
2053 m_ctxt->record (result);
2054 return result;
2057 /* Create a recording::get_address_of_lvalue instance and add it to
2058 the lvalue's context's list of mementos.
2060 Implements the post-error-checking part of
2061 gcc_jit_lvalue_get_address. */
2063 recording::rvalue *
2064 recording::lvalue::get_address (recording::location *loc)
2066 recording::rvalue *result =
2067 new get_address_of_lvalue (m_ctxt, loc, this);
2068 m_ctxt->record (result);
2069 return result;
2072 /* The implementation of class gcc::jit::recording::param. */
2074 /* Implementation of pure virtual hook recording::memento::replay_into
2075 for recording::param. */
2077 void
2078 recording::param::replay_into (replayer *r)
2080 set_playback_obj (r->new_param (playback_location (r, m_loc),
2081 m_type->playback_type (),
2082 m_name->c_str ()));
2086 /* The implementation of class gcc::jit::recording::function. */
2088 /* gcc::jit::recording::function's constructor. */
2090 recording::function::function (context *ctxt,
2091 recording::location *loc,
2092 enum gcc_jit_function_kind kind,
2093 type *return_type,
2094 recording::string *name,
2095 int num_params,
2096 recording::param **params,
2097 int is_variadic,
2098 enum built_in_function builtin_id)
2099 : memento (ctxt),
2100 m_loc (loc),
2101 m_kind (kind),
2102 m_return_type (return_type),
2103 m_name (name),
2104 m_params (),
2105 m_is_variadic (is_variadic),
2106 m_builtin_id (builtin_id),
2107 m_locals (),
2108 m_blocks ()
2110 for (int i = 0; i< num_params; i++)
2111 m_params.safe_push (params[i]);
2114 /* Implementation of pure virtual hook recording::memento::replay_into
2115 for recording::function. */
2117 void
2118 recording::function::replay_into (replayer *r)
2120 /* Convert m_params to a vec of playback param. */
2121 auto_vec <playback::param *> params;
2122 int i;
2123 recording::param *param;
2124 params.create (m_params.length ());
2125 FOR_EACH_VEC_ELT (m_params, i, param)
2126 params.safe_push (param->playback_param ());
2128 set_playback_obj (r->new_function (playback_location (r, m_loc),
2129 m_kind,
2130 m_return_type->playback_type (),
2131 m_name->c_str (),
2132 &params,
2133 m_is_variadic,
2134 m_builtin_id));
2137 /* Create a recording::local instance and add it to
2138 the functions's context's list of mementos, and to the function's
2139 list of locals.
2141 Implements the post-error-checking part of
2142 gcc_jit_function_new_local. */
2144 recording::lvalue *
2145 recording::function::new_local (recording::location *loc,
2146 type *type,
2147 const char *name)
2149 local *result = new local (this, loc, type, new_string (name));
2150 m_ctxt->record (result);
2151 m_locals.safe_push (result);
2152 return result;
2155 /* Create a recording::block instance and add it to
2156 the functions's context's list of mementos, and to the function's
2157 list of blocks.
2159 Implements the post-error-checking part of
2160 gcc_jit_function_new_block. */
2162 recording::block*
2163 recording::function::new_block (const char *name)
2165 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2167 recording::block *result =
2168 new recording::block (this, m_blocks.length (), new_string (name));
2169 m_ctxt->record (result);
2170 m_blocks.safe_push (result);
2171 return result;
2174 /* Override the default implementation of
2175 recording::memento::write_to_dump by dumping a C-like
2176 representation of the function; either like a prototype
2177 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2178 all other kinds of function. */
2180 void
2181 recording::function::write_to_dump (dump &d)
2183 switch (m_kind)
2185 default: gcc_unreachable ();
2186 case GCC_JIT_FUNCTION_EXPORTED:
2187 case GCC_JIT_FUNCTION_IMPORTED:
2188 d.write ("extern ");
2189 break;
2190 case GCC_JIT_FUNCTION_INTERNAL:
2191 d.write ("static ");
2192 break;
2193 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2194 d.write ("static inline ");
2195 break;
2197 d.write ("%s\n", m_return_type->get_debug_string ());
2199 if (d.update_locations ())
2200 m_loc = d.make_location ();
2202 d.write ("%s (", get_debug_string ());
2204 int i;
2205 recording::param *param;
2206 FOR_EACH_VEC_ELT (m_params, i, param)
2208 if (i > 0)
2209 d.write (", ");
2210 d.write ("%s %s",
2211 param->get_type ()->get_debug_string (),
2212 param->get_debug_string ());
2214 d.write (")");
2215 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2217 d.write ("; /* (imported) */\n\n");
2219 else
2221 int i;
2222 local *var = NULL;
2223 block *b;
2224 d.write ("\n{\n");
2226 /* Write locals: */
2227 FOR_EACH_VEC_ELT (m_locals, i, var)
2228 var->write_to_dump (d);
2229 if (m_locals.length ())
2230 d.write ("\n");
2232 /* Write each block: */
2233 FOR_EACH_VEC_ELT (m_blocks, i, b)
2235 if (i > 0)
2236 d.write ("\n");
2237 b->write_to_dump (d);
2240 d.write ("}\n\n");
2244 /* Pre-compilation validation of a function, for those things we can't
2245 check until the context is (supposedly) fully-populated. */
2247 void
2248 recording::function::validate ()
2250 /* Complain about empty functions with non-void return type. */
2251 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2252 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2253 if (0 == m_blocks.length ())
2254 m_ctxt->add_error (m_loc,
2255 "function %s returns non-void (type: %s)"
2256 " but has no blocks",
2257 get_debug_string (),
2258 m_return_type->get_debug_string ());
2260 /* Check that all blocks are terminated. */
2261 int num_invalid_blocks = 0;
2263 int i;
2264 block *b;
2266 FOR_EACH_VEC_ELT (m_blocks, i, b)
2267 if (!b->validate ())
2268 num_invalid_blocks++;
2271 /* Check that all blocks are reachable. */
2272 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2274 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2275 flag, starting at the initial block. */
2276 auto_vec<block *> worklist (m_blocks.length ());
2277 worklist.safe_push (m_blocks[0]);
2278 while (worklist.length () > 0)
2280 block *b = worklist.pop ();
2281 b->m_is_reachable = true;
2283 /* Add successor blocks that aren't yet marked to the worklist. */
2284 /* We checked that each block has a terminating statement above . */
2285 block *next1, *next2;
2286 int n = b->get_successor_blocks (&next1, &next2);
2287 switch (n)
2289 default:
2290 gcc_unreachable ();
2291 case 2:
2292 if (!next2->m_is_reachable)
2293 worklist.safe_push (next2);
2294 /* fallthrough */
2295 case 1:
2296 if (!next1->m_is_reachable)
2297 worklist.safe_push (next1);
2298 break;
2299 case 0:
2300 break;
2304 /* Now complain about any blocks that haven't been marked. */
2306 int i;
2307 block *b;
2308 FOR_EACH_VEC_ELT (m_blocks, i, b)
2309 if (!b->m_is_reachable)
2310 m_ctxt->add_error (b->get_loc (),
2311 "unreachable block: %s",
2312 b->get_debug_string ());
2317 /* Implements the post-error-checking part of
2318 gcc_jit_function_dump_to_dot. */
2320 void
2321 recording::function::dump_to_dot (const char *path)
2323 FILE *fp = fopen (path, "w");
2324 if (!fp)
2325 return;
2327 pretty_printer the_pp;
2328 the_pp.buffer->stream = fp;
2330 pretty_printer *pp = &the_pp;
2332 pp_printf (pp,
2333 "digraph %s {\n", get_debug_string ());
2335 /* Blocks: */
2337 int i;
2338 block *b;
2339 FOR_EACH_VEC_ELT (m_blocks, i, b)
2340 b->dump_to_dot (pp);
2343 /* Edges: */
2345 int i;
2346 block *b;
2347 FOR_EACH_VEC_ELT (m_blocks, i, b)
2348 b->dump_edges_to_dot (pp);
2351 pp_printf (pp, "}\n");
2352 pp_flush (pp);
2353 fclose (fp);
2356 /* Implementation of recording::memento::make_debug_string for
2357 functions. */
2359 recording::string *
2360 recording::function::make_debug_string ()
2362 return m_name;
2365 /* The implementation of class gcc::jit::recording::block. */
2367 /* Create a recording::eval instance and add it to
2368 the block's context's list of mementos, and to the block's
2369 list of statements.
2371 Implements the post-error-checking part of
2372 gcc_jit_block_add_eval. */
2374 void
2375 recording::block::add_eval (recording::location *loc,
2376 recording::rvalue *rvalue)
2378 statement *result = new eval (this, loc, rvalue);
2379 m_ctxt->record (result);
2380 m_statements.safe_push (result);
2383 /* Create a recording::assignment instance and add it to
2384 the block's context's list of mementos, and to the block's
2385 list of statements.
2387 Implements the post-error-checking part of
2388 gcc_jit_block_add_assignment. */
2390 void
2391 recording::block::add_assignment (recording::location *loc,
2392 recording::lvalue *lvalue,
2393 recording::rvalue *rvalue)
2395 statement *result = new assignment (this, loc, lvalue, rvalue);
2396 m_ctxt->record (result);
2397 m_statements.safe_push (result);
2400 /* Create a recording::assignment_op instance and add it to
2401 the block's context's list of mementos, and to the block's
2402 list of statements.
2404 Implements the post-error-checking part of
2405 gcc_jit_block_add_assignment_op. */
2407 void
2408 recording::block::add_assignment_op (recording::location *loc,
2409 recording::lvalue *lvalue,
2410 enum gcc_jit_binary_op op,
2411 recording::rvalue *rvalue)
2413 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2414 m_ctxt->record (result);
2415 m_statements.safe_push (result);
2418 /* Create a recording::comment instance and add it to
2419 the block's context's list of mementos, and to the block's
2420 list of statements.
2422 Implements the post-error-checking part of
2423 gcc_jit_block_add_comment. */
2425 void
2426 recording::block::add_comment (recording::location *loc,
2427 const char *text)
2429 statement *result = new comment (this, loc, new_string (text));
2430 m_ctxt->record (result);
2431 m_statements.safe_push (result);
2434 /* Create a recording::end_with_conditional instance and add it to
2435 the block's context's list of mementos, and to the block's
2436 list of statements.
2438 Implements the post-error-checking part of
2439 gcc_jit_block_end_with_conditional. */
2441 void
2442 recording::block::end_with_conditional (recording::location *loc,
2443 recording::rvalue *boolval,
2444 recording::block *on_true,
2445 recording::block *on_false)
2447 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2448 m_ctxt->record (result);
2449 m_statements.safe_push (result);
2450 m_has_been_terminated = true;
2453 /* Create a recording::end_with_jump instance and add it to
2454 the block's context's list of mementos, and to the block's
2455 list of statements.
2457 Implements the post-error-checking part of
2458 gcc_jit_block_end_with_jump. */
2460 void
2461 recording::block::end_with_jump (recording::location *loc,
2462 recording::block *target)
2464 statement *result = new jump (this, loc, target);
2465 m_ctxt->record (result);
2466 m_statements.safe_push (result);
2467 m_has_been_terminated = true;
2470 /* Create a recording::end_with_return instance and add it to
2471 the block's context's list of mementos, and to the block's
2472 list of statements.
2474 Implements the post-error-checking parts of
2475 gcc_jit_block_end_with_return and
2476 gcc_jit_block_end_with_void_return. */
2478 void
2479 recording::block::end_with_return (recording::location *loc,
2480 recording::rvalue *rvalue)
2482 /* This is used by both gcc_jit_function_add_return and
2483 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2484 the former and NULL for the latter. */
2485 statement *result = new return_ (this, loc, rvalue);
2486 m_ctxt->record (result);
2487 m_statements.safe_push (result);
2488 m_has_been_terminated = true;
2491 /* Override the default implementation of
2492 recording::memento::write_to_dump for blocks by writing
2493 an unindented block name as a label, followed by the indented
2494 statements:
2496 BLOCK_NAME:
2497 STATEMENT_1;
2498 STATEMENT_2;
2500 STATEMENT_N; */
2502 void
2503 recording::block::write_to_dump (dump &d)
2505 d.write ("%s:\n", get_debug_string ());
2507 int i;
2508 statement *s;
2509 FOR_EACH_VEC_ELT (m_statements, i, s)
2510 s->write_to_dump (d);
2513 /* Validate a block by ensuring that it has been terminated. */
2515 bool
2516 recording::block::validate ()
2518 if (!has_been_terminated ())
2520 statement *stmt = get_last_statement ();
2521 location *loc = stmt ? stmt->get_loc () : NULL;
2522 m_func->get_context ()->add_error (loc,
2523 "unterminated block in %s: %s",
2524 m_func->get_debug_string (),
2525 get_debug_string ());
2526 return false;
2529 return true;
2532 /* Get the source-location of a block by using that of the first
2533 statement within it, if any. */
2535 recording::location *
2536 recording::block::get_loc () const
2538 recording::statement *stmt = get_first_statement ();
2539 if (stmt)
2540 return stmt->get_loc ();
2541 else
2542 return NULL;
2545 /* Get the first statement within a block, if any. */
2547 recording::statement *
2548 recording::block::get_first_statement () const
2550 if (m_statements.length ())
2551 return m_statements[0];
2552 else
2553 return NULL;
2556 /* Get the last statement within a block, if any. */
2558 recording::statement *
2559 recording::block::get_last_statement () const
2561 if (m_statements.length ())
2562 return m_statements[m_statements.length () - 1];
2563 else
2564 return NULL;
2567 /* Assuming that this block has been terminated, get the number of
2568 successor blocks, which will be 0, 1 or 2, for return, unconditional
2569 jump, and conditional jump respectively.
2570 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2571 is written to NEXT1, and the second (if any) to NEXT2.
2573 Used when validating functions, and when dumping dot representations
2574 of them. */
2577 recording::block::get_successor_blocks (block **next1, block **next2) const
2579 gcc_assert (m_has_been_terminated);
2580 gcc_assert (next1);
2581 gcc_assert (next2);
2582 statement *last_statement = get_last_statement ();
2583 gcc_assert (last_statement);
2584 return last_statement->get_successor_blocks (next1, next2);
2587 /* Implementation of pure virtual hook recording::memento::replay_into
2588 for recording::block. */
2590 void
2591 recording::block::replay_into (replayer *)
2593 set_playback_obj (m_func->playback_function ()
2594 ->new_block (playback_string (m_name)));
2597 /* Implementation of recording::memento::make_debug_string for
2598 blocks. */
2600 recording::string *
2601 recording::block::make_debug_string ()
2603 if (m_name)
2604 return m_name;
2605 else
2606 return string::from_printf (m_ctxt,
2607 "<UNNAMED BLOCK %p>",
2608 (void *)this);
2611 /* Dump a block in graphviz form into PP, capturing the block name (if
2612 any) and the statements. */
2614 void
2615 recording::block::dump_to_dot (pretty_printer *pp)
2617 pp_printf (pp,
2618 ("\tblock_%d "
2619 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2620 m_index);
2621 pp_write_text_to_stream (pp);
2622 if (m_name)
2624 pp_string (pp, m_name->c_str ());
2625 pp_string (pp, ":");
2626 pp_newline (pp);
2627 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2630 int i;
2631 statement *s;
2632 FOR_EACH_VEC_ELT (m_statements, i, s)
2634 pp_string (pp, s->get_debug_string ());
2635 pp_newline (pp);
2636 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2639 pp_printf (pp,
2640 "}\"];\n\n");
2641 pp_flush (pp);
2644 /* Dump the out-edges of the block in graphviz form into PP. */
2646 void
2647 recording::block::dump_edges_to_dot (pretty_printer *pp)
2649 block *next[2];
2650 int num_succs = get_successor_blocks (&next[0], &next[1]);
2651 for (int i = 0; i < num_succs; i++)
2652 pp_printf (pp,
2653 "\tblock_%d:s -> block_%d:n;\n",
2654 m_index, next[i]->m_index);
2657 /* The implementation of class gcc::jit::recording::global. */
2659 /* Implementation of pure virtual hook recording::memento::replay_into
2660 for recording::global. */
2662 void
2663 recording::global::replay_into (replayer *r)
2665 set_playback_obj (r->new_global (playback_location (r, m_loc),
2666 m_type->playback_type (),
2667 playback_string (m_name)));
2670 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2672 /* Implementation of pure virtual hook recording::memento::replay_into
2673 for recording::memento_of_new_rvalue_from_int. */
2675 void
2676 recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
2678 set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
2679 m_value));
2682 /* Implementation of recording::memento::make_debug_string for
2683 rvalue_from_int, rendering it as
2684 (TYPE)LITERAL
2685 e.g.
2686 "(int)42". */
2688 recording::string *
2689 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2691 return string::from_printf (m_ctxt,
2692 "(%s)%i",
2693 m_type->get_debug_string (),
2694 m_value);
2697 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2699 /* Implementation of pure virtual hook recording::memento::replay_into
2700 for recording::memento_of_new_rvalue_from_double. */
2702 void
2703 recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
2705 set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
2706 m_value));
2709 /* Implementation of recording::memento::make_debug_string for
2710 rvalue_from_double, rendering it as
2711 (TYPE)LITERAL
2712 e.g.
2713 "(float)42.0". */
2715 recording::string *
2716 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2718 return string::from_printf (m_ctxt,
2719 "(%s)%f",
2720 m_type->get_debug_string (),
2721 m_value);
2724 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2726 /* Implementation of pure virtual hook recording::memento::replay_into
2727 for recording::memento_of_new_rvalue_from_ptr. */
2729 void
2730 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
2732 set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
2733 m_value));
2736 /* Implementation of recording::memento::make_debug_string for
2737 rvalue_from_ptr, rendering it as
2738 (TYPE)HEX
2739 e.g.
2740 "(int *)0xdeadbeef"
2742 Zero is rendered as NULL e.g.
2743 "(int *)NULL". */
2745 recording::string *
2746 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2748 if (m_value != NULL)
2749 return string::from_printf (m_ctxt,
2750 "(%s)%p",
2751 m_type->get_debug_string (), m_value);
2752 else
2753 return string::from_printf (m_ctxt,
2754 "(%s)NULL",
2755 m_type->get_debug_string ());
2758 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2760 /* Implementation of pure virtual hook recording::memento::replay_into
2761 for recording::memento_of_new_string_literal. */
2763 void
2764 recording::memento_of_new_string_literal::replay_into (replayer *r)
2766 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2769 /* Implementation of recording::memento::make_debug_string for
2770 string literals. */
2772 recording::string *
2773 recording::memento_of_new_string_literal::make_debug_string ()
2775 return string::from_printf (m_ctxt,
2776 m_value->get_debug_string ());
2779 /* The implementation of class gcc::jit::recording::unary_op. */
2781 /* Implementation of pure virtual hook recording::memento::replay_into
2782 for recording::unary_op. */
2784 void
2785 recording::unary_op::replay_into (replayer *r)
2787 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2788 m_op,
2789 get_type ()->playback_type (),
2790 m_a->playback_rvalue ()));
2793 /* Implementation of recording::memento::make_debug_string for
2794 unary ops. */
2796 static const char * const unary_op_strings[] = {
2797 "-", /* GCC_JIT_UNARY_OP_MINUS */
2798 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2799 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2802 recording::string *
2803 recording::unary_op::make_debug_string ()
2805 return string::from_printf (m_ctxt,
2806 "%s(%s)",
2807 unary_op_strings[m_op],
2808 m_a->get_debug_string ());
2811 /* The implementation of class gcc::jit::recording::binary_op. */
2813 /* Implementation of pure virtual hook recording::memento::replay_into
2814 for recording::binary_op. */
2816 void
2817 recording::binary_op::replay_into (replayer *r)
2819 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2820 m_op,
2821 get_type ()->playback_type (),
2822 m_a->playback_rvalue (),
2823 m_b->playback_rvalue ()));
2826 /* Implementation of recording::memento::make_debug_string for
2827 binary ops. */
2829 static const char * const binary_op_strings[] = {
2830 "+", /* GCC_JIT_BINARY_OP_PLUS */
2831 "-", /* GCC_JIT_BINARY_OP_MINUS */
2832 "*", /* GCC_JIT_BINARY_OP_MULT */
2833 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2834 "%", /* GCC_JIT_BINARY_OP_MODULO */
2835 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2836 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2837 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2838 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2839 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2840 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2841 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2844 recording::string *
2845 recording::binary_op::make_debug_string ()
2847 return string::from_printf (m_ctxt,
2848 "%s %s %s",
2849 m_a->get_debug_string (),
2850 binary_op_strings[m_op],
2851 m_b->get_debug_string ());
2854 /* The implementation of class gcc::jit::recording::comparison. */
2856 /* Implementation of recording::memento::make_debug_string for
2857 comparisons. */
2859 static const char * const comparison_strings[] =
2861 "==", /* GCC_JIT_COMPARISON_EQ */
2862 "!=", /* GCC_JIT_COMPARISON_NE */
2863 "<", /* GCC_JIT_COMPARISON_LT */
2864 "<=", /* GCC_JIT_COMPARISON_LE */
2865 ">", /* GCC_JIT_COMPARISON_GT */
2866 ">=", /* GCC_JIT_COMPARISON_GE */
2869 recording::string *
2870 recording::comparison::make_debug_string ()
2872 return string::from_printf (m_ctxt,
2873 "%s %s %s",
2874 m_a->get_debug_string (),
2875 comparison_strings[m_op],
2876 m_b->get_debug_string ());
2879 /* Implementation of pure virtual hook recording::memento::replay_into
2880 for recording::comparison. */
2882 void
2883 recording::comparison::replay_into (replayer *r)
2885 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2886 m_op,
2887 m_a->playback_rvalue (),
2888 m_b->playback_rvalue ()));
2891 /* Implementation of pure virtual hook recording::memento::replay_into
2892 for recording::cast. */
2894 void
2895 recording::cast::replay_into (replayer *r)
2897 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2898 m_rvalue->playback_rvalue (),
2899 get_type ()->playback_type ()));
2902 /* Implementation of recording::memento::make_debug_string for
2903 casts. */
2905 recording::string *
2906 recording::cast::make_debug_string ()
2908 return string::from_printf (m_ctxt,
2909 "(%s)%s",
2910 get_type ()->get_debug_string (),
2911 m_rvalue->get_debug_string ());
2914 /* The implementation of class gcc::jit::recording::call. */
2916 /* The constructor for gcc::jit::recording::call. */
2918 recording::call::call (recording::context *ctxt,
2919 recording::location *loc,
2920 recording::function *func,
2921 int numargs,
2922 rvalue **args)
2923 : rvalue (ctxt, loc, func->get_return_type ()),
2924 m_func (func),
2925 m_args ()
2927 for (int i = 0; i< numargs; i++)
2928 m_args.safe_push (args[i]);
2931 /* Implementation of pure virtual hook recording::memento::replay_into
2932 for recording::call. */
2934 void
2935 recording::call::replay_into (replayer *r)
2937 auto_vec<playback::rvalue *> playback_args;
2938 playback_args.create (m_args.length ());
2939 for (unsigned i = 0; i< m_args.length (); i++)
2940 playback_args.safe_push (m_args[i]->playback_rvalue ());
2942 set_playback_obj (r->new_call (playback_location (r, m_loc),
2943 m_func->playback_function (),
2944 &playback_args));
2947 /* Implementation of recording::memento::make_debug_string for
2948 function calls. */
2950 recording::string *
2951 recording::call::make_debug_string ()
2953 /* First, build a buffer for the arguments. */
2954 /* Calculate length of said buffer. */
2955 size_t sz = 1; /* nil terminator */
2956 for (unsigned i = 0; i< m_args.length (); i++)
2958 sz += strlen (m_args[i]->get_debug_string ());
2959 sz += 2; /* ", " separator */
2962 /* Now allocate and populate the buffer. */
2963 char *argbuf = new char[sz];
2964 size_t len = 0;
2966 for (unsigned i = 0; i< m_args.length (); i++)
2968 strcpy (argbuf + len, m_args[i]->get_debug_string ());
2969 len += strlen (m_args[i]->get_debug_string ());
2970 if (i + 1 < m_args.length ())
2972 strcpy (argbuf + len, ", ");
2973 len += 2;
2976 argbuf[len] = '\0';
2978 /* ...and use it to get the string for the call as a whole. */
2979 string *result = string::from_printf (m_ctxt,
2980 "%s (%s)",
2981 m_func->get_debug_string (),
2982 argbuf);
2984 delete[] argbuf;
2986 return result;
2989 /* The implementation of class gcc::jit::recording::call_through_ptr. */
2991 /* The constructor for recording::call_through_ptr. */
2993 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
2994 recording::location *loc,
2995 recording::rvalue *fn_ptr,
2996 int numargs,
2997 rvalue **args)
2998 : rvalue (ctxt, loc,
2999 fn_ptr->get_type ()->dereference ()
3000 ->as_a_function_type ()->get_return_type ()),
3001 m_fn_ptr (fn_ptr),
3002 m_args ()
3004 for (int i = 0; i< numargs; i++)
3005 m_args.safe_push (args[i]);
3008 /* Implementation of pure virtual hook recording::memento::replay_into
3009 for recording::call_through_ptr. */
3011 void
3012 recording::call_through_ptr::replay_into (replayer *r)
3014 auto_vec<playback::rvalue *> playback_args;
3015 playback_args.create (m_args.length ());
3016 for (unsigned i = 0; i< m_args.length (); i++)
3017 playback_args.safe_push (m_args[i]->playback_rvalue ());
3019 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
3020 m_fn_ptr->playback_rvalue (),
3021 &playback_args));
3024 /* Implementation of recording::memento::make_debug_string for
3025 calls through function ptrs. */
3027 recording::string *
3028 recording::call_through_ptr::make_debug_string ()
3030 /* First, build a buffer for the arguments. */
3031 /* Calculate length of said buffer. */
3032 size_t sz = 1; /* nil terminator */
3033 for (unsigned i = 0; i< m_args.length (); i++)
3035 sz += strlen (m_args[i]->get_debug_string ());
3036 sz += 2; /* ", " separator */
3039 /* Now allocate and populate the buffer. */
3040 char *argbuf = new char[sz];
3041 size_t len = 0;
3043 for (unsigned i = 0; i< m_args.length (); i++)
3045 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3046 len += strlen (m_args[i]->get_debug_string ());
3047 if (i + 1 < m_args.length ())
3049 strcpy (argbuf + len, ", ");
3050 len += 2;
3053 argbuf[len] = '\0';
3055 /* ...and use it to get the string for the call as a whole. */
3056 string *result = string::from_printf (m_ctxt,
3057 "%s (%s)",
3058 m_fn_ptr->get_debug_string (),
3059 argbuf);
3061 delete[] argbuf;
3063 return result;
3066 /* The implementation of class gcc::jit::recording::array_access. */
3068 /* Implementation of pure virtual hook recording::memento::replay_into
3069 for recording::array_access. */
3071 void
3072 recording::array_access::replay_into (replayer *r)
3074 set_playback_obj (
3075 r->new_array_access (playback_location (r, m_loc),
3076 m_ptr->playback_rvalue (),
3077 m_index->playback_rvalue ()));
3080 /* Implementation of recording::memento::make_debug_string for
3081 array accesses. */
3083 recording::string *
3084 recording::array_access::make_debug_string ()
3086 return string::from_printf (m_ctxt,
3087 "%s[%s]",
3088 m_ptr->get_debug_string (),
3089 m_index->get_debug_string ());
3092 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3094 /* Implementation of pure virtual hook recording::memento::replay_into
3095 for recording::access_field_of_lvalue. */
3097 void
3098 recording::access_field_of_lvalue::replay_into (replayer *r)
3100 set_playback_obj (
3101 m_lvalue->playback_lvalue ()
3102 ->access_field (playback_location (r, m_loc),
3103 m_field->playback_field ()));
3107 /* Implementation of recording::memento::make_debug_string for
3108 accessing a field of an lvalue. */
3110 recording::string *
3111 recording::access_field_of_lvalue::make_debug_string ()
3113 return string::from_printf (m_ctxt,
3114 "%s.%s",
3115 m_lvalue->get_debug_string (),
3116 m_field->get_debug_string ());
3119 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3121 /* Implementation of pure virtual hook recording::memento::replay_into
3122 for recording::access_field_rvalue. */
3124 void
3125 recording::access_field_rvalue::replay_into (replayer *r)
3127 set_playback_obj (
3128 m_rvalue->playback_rvalue ()
3129 ->access_field (playback_location (r, m_loc),
3130 m_field->playback_field ()));
3133 /* Implementation of recording::memento::make_debug_string for
3134 accessing a field of an rvalue. */
3136 recording::string *
3137 recording::access_field_rvalue::make_debug_string ()
3139 return string::from_printf (m_ctxt,
3140 "%s.%s",
3141 m_rvalue->get_debug_string (),
3142 m_field->get_debug_string ());
3145 /* The implementation of class
3146 gcc::jit::recording::dereference_field_rvalue. */
3148 /* Implementation of pure virtual hook recording::memento::replay_into
3149 for recording::dereference_field_rvalue. */
3151 void
3152 recording::dereference_field_rvalue::replay_into (replayer *r)
3154 set_playback_obj (
3155 m_rvalue->playback_rvalue ()->
3156 dereference_field (playback_location (r, m_loc),
3157 m_field->playback_field ()));
3160 /* Implementation of recording::memento::make_debug_string for
3161 dereferencing a field of an rvalue. */
3163 recording::string *
3164 recording::dereference_field_rvalue::make_debug_string ()
3166 return string::from_printf (m_ctxt,
3167 "%s->%s",
3168 m_rvalue->get_debug_string (),
3169 m_field->get_debug_string ());
3172 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3174 /* Implementation of pure virtual hook recording::memento::replay_into
3175 for recording::dereference_rvalue. */
3177 void
3178 recording::dereference_rvalue::replay_into (replayer *r)
3180 set_playback_obj (
3181 m_rvalue->playback_rvalue ()->
3182 dereference (playback_location (r, m_loc)));
3185 /* Implementation of recording::memento::make_debug_string for
3186 dereferencing an rvalue. */
3188 recording::string *
3189 recording::dereference_rvalue::make_debug_string ()
3191 return string::from_printf (m_ctxt,
3192 "*%s",
3193 m_rvalue->get_debug_string ());
3196 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3198 /* Implementation of pure virtual hook recording::memento::replay_into
3199 for recording::get_address_of_lvalue. */
3201 void
3202 recording::get_address_of_lvalue::replay_into (replayer *r)
3204 set_playback_obj (
3205 m_lvalue->playback_lvalue ()->
3206 get_address (playback_location (r, m_loc)));
3209 /* Implementation of recording::memento::make_debug_string for
3210 getting the address of an lvalue. */
3212 recording::string *
3213 recording::get_address_of_lvalue::make_debug_string ()
3215 return string::from_printf (m_ctxt,
3216 "&%s",
3217 m_lvalue->get_debug_string ());
3220 /* The implementation of class gcc::jit::recording::local. */
3222 /* Implementation of pure virtual hook recording::memento::replay_into
3223 for recording::local. */
3225 void
3226 recording::local::replay_into (replayer *r)
3228 set_playback_obj (
3229 m_func->playback_function ()
3230 ->new_local (playback_location (r, m_loc),
3231 m_type->playback_type (),
3232 playback_string (m_name)));
3235 /* Override the default implementation of
3236 recording::memento::write_to_dump for locals by writing
3237 TYPE NAME;
3238 for use at the top of the function body as if it were a
3239 declaration. */
3241 void
3242 recording::local::write_to_dump (dump &d)
3244 if (d.update_locations ())
3245 m_loc = d.make_location ();
3246 d.write(" %s %s;\n",
3247 m_type->get_debug_string (),
3248 get_debug_string ());
3251 /* The implementation of class gcc::jit::recording::statement. */
3253 /* We poison the default implementation of
3254 gcc::jit::recording::statement::get_successor_blocks
3255 since this vfunc must only ever be called on terminator
3256 statements. */
3259 recording::statement::get_successor_blocks (block **/*out_next1*/,
3260 block **/*out_next2*/) const
3262 /* The base class implementation is for non-terminating statements,
3263 and thus should never be called. */
3264 gcc_unreachable ();
3265 return 0;
3268 /* Extend the default implementation of
3269 recording::memento::write_to_dump for statements by (if requested)
3270 updating the location of the statement to the current location in
3271 the dumpfile. */
3273 void
3274 recording::statement::write_to_dump (dump &d)
3276 memento::write_to_dump (d);
3277 if (d.update_locations ())
3278 m_loc = d.make_location ();
3281 /* The implementation of class gcc::jit::recording::eval. */
3283 /* Implementation of pure virtual hook recording::memento::replay_into
3284 for recording::eval. */
3286 void
3287 recording::eval::replay_into (replayer *r)
3289 playback_block (get_block ())
3290 ->add_eval (playback_location (r),
3291 m_rvalue->playback_rvalue ());
3294 /* Implementation of recording::memento::make_debug_string for
3295 an eval statement. */
3297 recording::string *
3298 recording::eval::make_debug_string ()
3300 return string::from_printf (m_ctxt,
3301 "(void)%s;",
3302 m_rvalue->get_debug_string ());
3305 /* The implementation of class gcc::jit::recording::assignment. */
3307 /* Implementation of pure virtual hook recording::memento::replay_into
3308 for recording::assignment. */
3310 void
3311 recording::assignment::replay_into (replayer *r)
3313 playback_block (get_block ())
3314 ->add_assignment (playback_location (r),
3315 m_lvalue->playback_lvalue (),
3316 m_rvalue->playback_rvalue ());
3319 /* Implementation of recording::memento::make_debug_string for
3320 an assignment statement. */
3322 recording::string *
3323 recording::assignment::make_debug_string ()
3325 return string::from_printf (m_ctxt,
3326 "%s = %s;",
3327 m_lvalue->get_debug_string (),
3328 m_rvalue->get_debug_string ());
3331 /* The implementation of class gcc::jit::recording::assignment_op. */
3333 /* Implementation of pure virtual hook recording::memento::replay_into
3334 for recording::assignment_op. */
3336 void
3337 recording::assignment_op::replay_into (replayer *r)
3339 playback::type *result_type =
3340 m_lvalue->playback_lvalue ()->get_type ();
3342 playback::rvalue *binary_op =
3343 r->new_binary_op (playback_location (r),
3344 m_op,
3345 result_type,
3346 m_lvalue->playback_rvalue (),
3347 m_rvalue->playback_rvalue ());
3349 playback_block (get_block ())
3350 ->add_assignment (playback_location (r),
3351 m_lvalue->playback_lvalue (),
3352 binary_op);
3355 /* Implementation of recording::memento::make_debug_string for
3356 an assignment_op statement. */
3358 recording::string *
3359 recording::assignment_op::make_debug_string ()
3361 return string::from_printf (m_ctxt,
3362 "%s %s= %s;",
3363 m_lvalue->get_debug_string (),
3364 binary_op_strings[m_op],
3365 m_rvalue->get_debug_string ());
3368 /* The implementation of class gcc::jit::recording::comment. */
3370 /* Implementation of pure virtual hook recording::memento::replay_into
3371 for recording::comment. */
3373 void
3374 recording::comment::replay_into (replayer *r)
3376 playback_block (get_block ())
3377 ->add_comment (playback_location (r),
3378 m_text->c_str ());
3381 /* Implementation of recording::memento::make_debug_string for
3382 a comment "statement". */
3384 recording::string *
3385 recording::comment::make_debug_string ()
3387 return string::from_printf (m_ctxt,
3388 "/* %s */",
3389 m_text->c_str ());
3392 /* The implementation of class gcc::jit::recording::conditional. */
3394 /* Implementation of pure virtual hook recording::memento::replay_into
3395 for recording::conditional. */
3397 void
3398 recording::conditional::replay_into (replayer *r)
3400 playback_block (get_block ())
3401 ->add_conditional (playback_location (r),
3402 m_boolval->playback_rvalue (),
3403 playback_block (m_on_true),
3404 playback_block (m_on_false));
3407 /* Override the poisoned default implementation of
3408 gcc::jit::recording::statement::get_successor_blocks
3410 A conditional jump has 2 successor blocks. */
3413 recording::conditional::get_successor_blocks (block **out_next1,
3414 block **out_next2) const
3416 *out_next1 = m_on_true;
3417 *out_next2 = m_on_false;
3418 return 2;
3421 /* Implementation of recording::memento::make_debug_string for
3422 a conditional jump statement. */
3424 recording::string *
3425 recording::conditional::make_debug_string ()
3427 if (m_on_false)
3428 return string::from_printf (m_ctxt,
3429 "if (%s) goto %s; else goto %s;",
3430 m_boolval->get_debug_string (),
3431 m_on_true->get_debug_string (),
3432 m_on_false->get_debug_string ());
3433 else
3434 return string::from_printf (m_ctxt,
3435 "if (%s) goto %s;",
3436 m_boolval->get_debug_string (),
3437 m_on_true->get_debug_string ());
3440 /* The implementation of class gcc::jit::recording::jump. */
3442 /* Implementation of pure virtual hook recording::memento::replay_into
3443 for recording::jump. */
3445 void
3446 recording::jump::replay_into (replayer *r)
3448 playback_block (get_block ())
3449 ->add_jump (playback_location (r),
3450 m_target->playback_block ());
3453 /* Override the poisoned default implementation of
3454 gcc::jit::recording::statement::get_successor_blocks
3456 An unconditional jump has 1 successor block. */
3459 recording::jump::get_successor_blocks (block **out_next1,
3460 block **/*out_next2*/) const
3462 *out_next1 = m_target;
3463 return 1;
3466 /* Implementation of recording::memento::make_debug_string for
3467 a unconditional jump statement. */
3469 recording::string *
3470 recording::jump::make_debug_string ()
3472 return string::from_printf (m_ctxt,
3473 "goto %s;",
3474 m_target->get_debug_string ());
3477 /* The implementation of class gcc::jit::recording::return_. */
3479 /* Implementation of pure virtual hook recording::memento::replay_into
3480 for recording::return_. */
3482 void
3483 recording::return_::replay_into (replayer *r)
3485 playback_block (get_block ())
3486 ->add_return (playback_location (r),
3487 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3490 /* Override the poisoned default implementation of
3491 gcc::jit::recording::statement::get_successor_blocks
3493 A return statement has no successor block. */
3496 recording::return_::get_successor_blocks (block **/*out_next1*/,
3497 block **/*out_next2*/) const
3499 return 0;
3502 /* Implementation of recording::memento::make_debug_string for
3503 a return statement (covers both those with and without rvalues). */
3505 recording::string *
3506 recording::return_::make_debug_string ()
3508 if (m_rvalue)
3509 return string::from_printf (m_ctxt,
3510 "return %s;",
3511 m_rvalue->get_debug_string ());
3512 else
3513 return string::from_printf (m_ctxt,
3514 "return;");
3517 } // namespace gcc::jit
3519 } // namespace gcc