2014-12-12 Marc Glisse <marc.glisse@inria.fr>
[official-gcc.git] / gcc / jit / jit-recording.c
blob9d6d26a92a1bfe759808fcff22e01486ef9a2af7
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 Note that the first memcpy means copying pointers to strings. */
186 memcpy (m_str_options,
187 parent_ctxt->m_str_options,
188 sizeof (m_str_options));
189 memcpy (m_int_options,
190 parent_ctxt->m_int_options,
191 sizeof (m_int_options));
192 memcpy (m_bool_options,
193 parent_ctxt->m_bool_options,
194 sizeof (m_bool_options));
196 else
198 memset (m_str_options, 0, sizeof (m_str_options));
199 memset (m_int_options, 0, sizeof (m_int_options));
200 memset (m_bool_options, 0, sizeof (m_bool_options));
203 memset (m_basic_types, 0, sizeof (m_basic_types));
206 /* The destructor for gcc::jit::recording::context, implicitly used by
207 gcc_jit_context_release. */
209 recording::context::~context ()
211 int i;
212 memento *m;
213 FOR_EACH_VEC_ELT (m_mementos, i, m)
215 delete m;
218 for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
219 free (m_str_options[i]);
221 if (m_builtins_manager)
222 delete m_builtins_manager;
224 if (m_owns_first_error_str)
225 free (m_first_error_str);
228 /* Add the given mememto to the list of those tracked by this
229 gcc::jit::recording::context, so that e.g. it can be deleted
230 when this context is released. */
232 void
233 recording::context::record (memento *m)
235 gcc_assert (m);
237 m_mementos.safe_push (m);
240 /* Replay this context (and any parents) into the given replayer. */
242 void
243 recording::context::replay_into (replayer *r)
245 int i;
246 memento *m;
248 /* If we have a parent context, we must replay it. This will
249 recursively walk backwards up the historical tree, then replay things
250 forwards "in historical order", starting with the ultimate parent
251 context, until we reach the "this" context.
253 Note that we fully replay the parent, then fully replay the child,
254 which means that inter-context references can only exist from child
255 to parent, not the other way around.
257 All of this replaying is suboptimal - it would be better to do the
258 work for the parent context *once*, rather than replaying the parent
259 every time we replay each child. However, fixing this requires deep
260 surgery to lifetime-management: we'd need every context family tree
261 to have its own GC heap, and to initialize the GCC code to use that
262 heap (with a mutex on such a heap). */
263 if (m_parent_ctxt)
264 m_parent_ctxt->replay_into (r);
266 if (r->errors_occurred ())
267 return;
269 /* Replay this context's saved operations into r. */
270 FOR_EACH_VEC_ELT (m_mementos, i, m)
272 /* Disabled low-level debugging, here if we need it: print what
273 we're replaying.
274 Note that the calls to get_debug_string might lead to more
275 mementos being created for the strings.
276 This can also be used to exercise the debug_string
277 machinery. */
278 if (0)
279 printf ("context %p replaying (%p): %s\n",
280 (void *)this, (void *)m, m->get_debug_string ());
282 m->replay_into (r);
284 if (r->errors_occurred ())
285 return;
289 /* During a playback, we associate objects from the recording with
290 their counterparts during this playback.
292 For simplicity, we store this within the recording objects.
294 The following method cleans away these associations, to ensure that
295 we never have out-of-date associations lingering on subsequent
296 playbacks (the objects pointed to are GC-managed, but the
297 recording objects don't own refs to them). */
299 void
300 recording::context::disassociate_from_playback ()
302 int i;
303 memento *m;
305 if (m_parent_ctxt)
306 m_parent_ctxt->disassociate_from_playback ();
308 FOR_EACH_VEC_ELT (m_mementos, i, m)
310 m->set_playback_obj (NULL);
314 /* Create a recording::string instance and add it to this context's list
315 of mementos.
317 This creates a fresh copy of the given 0-terminated buffer. */
319 recording::string *
320 recording::context::new_string (const char *text)
322 if (!text)
323 return NULL;
325 recording::string *result = new string (this, text);
326 record (result);
327 return result;
330 /* Create a recording::location instance and add it to this context's
331 list of mementos.
333 Implements the post-error-checking part of
334 gcc_jit_context_new_location. */
336 recording::location *
337 recording::context::new_location (const char *filename,
338 int line,
339 int column)
341 recording::location *result =
342 new recording::location (this,
343 new_string (filename),
344 line, column);
345 record (result);
346 return result;
349 /* If we haven't seen this enum value yet, create a recording::type
350 instance and add it to this context's list of mementos.
352 If we have seen it before, reuse our cached value, so that repeated
353 calls on the context give the same object.
355 If we have a parent context, the cache is within the ultimate
356 ancestor context.
358 Implements the post-error-checking part of
359 gcc_jit_context_get_type. */
361 recording::type *
362 recording::context::get_type (enum gcc_jit_types kind)
364 if (!m_basic_types[kind])
366 if (m_parent_ctxt)
367 m_basic_types[kind] = m_parent_ctxt->get_type (kind);
368 else
370 recording::type *result = new memento_of_get_type (this, kind);
371 record (result);
372 m_basic_types[kind] = result;
376 return m_basic_types[kind];
379 /* Get a recording::type instance for the given size and signedness.
380 This is implemented in terms of recording::context::get_type
381 above.
383 Implements the post-error-checking part of
384 gcc_jit_context_get_int_type. */
386 recording::type *
387 recording::context::get_int_type (int num_bytes, int is_signed)
389 /* We can't use a switch here since some of the values are macros affected
390 by options; e.g. i386.h has
391 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
392 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
393 are in bits, rather than bytes.
395 const int num_bits = num_bytes * 8;
396 if (num_bits == INT_TYPE_SIZE)
397 return get_type (is_signed
398 ? GCC_JIT_TYPE_INT
399 : GCC_JIT_TYPE_UNSIGNED_INT);
400 if (num_bits == CHAR_TYPE_SIZE)
401 return get_type (is_signed
402 ? GCC_JIT_TYPE_SIGNED_CHAR
403 : GCC_JIT_TYPE_UNSIGNED_CHAR);
404 if (num_bits == SHORT_TYPE_SIZE)
405 return get_type (is_signed
406 ? GCC_JIT_TYPE_SHORT
407 : GCC_JIT_TYPE_UNSIGNED_SHORT);
408 if (num_bits == LONG_TYPE_SIZE)
409 return get_type (is_signed
410 ? GCC_JIT_TYPE_LONG
411 : GCC_JIT_TYPE_UNSIGNED_LONG);
412 if (num_bits == LONG_LONG_TYPE_SIZE)
413 return get_type (is_signed
414 ? GCC_JIT_TYPE_LONG_LONG
415 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
417 /* Some other size, not corresponding to the C int types. */
418 /* To be written: support arbitrary other sizes, sharing by
419 memoizing at the recording::context level? */
420 gcc_unreachable ();
423 /* Create a recording::type instance and add it to this context's list
424 of mementos.
426 Implements the post-error-checking part of
427 gcc_jit_context_new_array_type. */
429 recording::type *
430 recording::context::new_array_type (recording::location *loc,
431 recording::type *element_type,
432 int num_elements)
434 if (struct_ *s = element_type->dyn_cast_struct ())
435 if (!s->get_fields ())
437 add_error (NULL,
438 "cannot create an array of type %s"
439 " until the fields have been set",
440 s->get_name ()->c_str ());
441 return NULL;
443 recording::type *result =
444 new recording::array_type (this, loc, element_type, num_elements);
445 record (result);
446 return result;
449 /* Create a recording::field instance and add it to this context's list
450 of mementos.
452 Implements the post-error-checking part of
453 gcc_jit_context_new_field. */
455 recording::field *
456 recording::context::new_field (recording::location *loc,
457 recording::type *type,
458 const char *name)
460 recording::field *result =
461 new recording::field (this, loc, type, new_string (name));
462 record (result);
463 return result;
466 /* Create a recording::struct_ instance and add it to this context's
467 list of mementos and list of compound types.
469 Implements the post-error-checking part of
470 gcc_jit_context_new_struct_type. */
472 recording::struct_ *
473 recording::context::new_struct_type (recording::location *loc,
474 const char *name)
476 recording::struct_ *result = new struct_ (this, loc, new_string (name));
477 record (result);
478 m_compound_types.safe_push (result);
479 return result;
482 /* Create a recording::union_ instance and add it to this context's
483 list of mementos and list of compound types.
485 Implements the first post-error-checking part of
486 gcc_jit_context_new_union_type. */
488 recording::union_ *
489 recording::context::new_union_type (recording::location *loc,
490 const char *name)
492 recording::union_ *result = new union_ (this, loc, new_string (name));
493 record (result);
494 m_compound_types.safe_push (result);
495 return result;
498 /* Create a recording::function_type instance and add it to this context's
499 list of mementos.
501 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
503 recording::function_type *
504 recording::context::new_function_type (recording::type *return_type,
505 int num_params,
506 recording::type **param_types,
507 int is_variadic)
509 recording::function_type *fn_type
510 = new function_type (this,
511 return_type,
512 num_params,
513 param_types,
514 is_variadic);
515 record (fn_type);
516 return fn_type;
519 /* Create a recording::type instance and add it to this context's list
520 of mementos.
522 Implements the post-error-checking part of
523 gcc_jit_context_new_function_ptr_type. */
525 recording::type *
526 recording::context::new_function_ptr_type (recording::location *, /* unused loc */
527 recording::type *return_type,
528 int num_params,
529 recording::type **param_types,
530 int is_variadic)
532 recording::function_type *fn_type
533 = new_function_type (return_type,
534 num_params,
535 param_types,
536 is_variadic);
538 /* Return a pointer-type to the the function type. */
539 return fn_type->get_pointer ();
542 /* Create a recording::param instance and add it to this context's list
543 of mementos.
545 Implements the post-error-checking part of
546 gcc_jit_context_new_param. */
548 recording::param *
549 recording::context::new_param (recording::location *loc,
550 recording::type *type,
551 const char *name)
553 recording::param *result = new recording::param (this, loc, type, new_string (name));
554 record (result);
555 return result;
558 /* Create a recording::function instance and add it to this context's list
559 of mementos and list of functions.
561 Implements the post-error-checking part of
562 gcc_jit_context_new_function. */
564 recording::function *
565 recording::context::new_function (recording::location *loc,
566 enum gcc_jit_function_kind kind,
567 recording::type *return_type,
568 const char *name,
569 int num_params,
570 recording::param **params,
571 int is_variadic,
572 enum built_in_function builtin_id)
574 recording::function *result =
575 new recording::function (this,
576 loc, kind, return_type,
577 new_string (name),
578 num_params, params, is_variadic,
579 builtin_id);
580 record (result);
581 m_functions.safe_push (result);
583 return result;
586 /* Locate the builtins_manager (if any) for this family of contexts,
587 creating it if it doesn't exist already.
589 All of the recording contexts in a family share one builtins_manager:
590 if we have a child context, follow the parent links to get the
591 ultimate ancestor context, and look for it/store it there. */
593 builtins_manager *
594 recording::context::get_builtins_manager ()
596 if (m_parent_ctxt)
597 return m_parent_ctxt->get_builtins_manager ();
599 if (!m_builtins_manager)
600 m_builtins_manager = new builtins_manager (this);
602 return m_builtins_manager;
605 /* Get a recording::function instance, which is lazily-created and added
606 to the context's lists of mementos.
608 Implements the post-error-checking part of
609 gcc_jit_context_get_builtin_function. */
611 recording::function *
612 recording::context::get_builtin_function (const char *name)
614 builtins_manager *bm = get_builtins_manager ();
615 return bm->get_builtin_function (name);
618 /* Create a recording::global instance and add it to this context's list
619 of mementos.
621 Implements the post-error-checking part of
622 gcc_jit_context_new_global. */
624 recording::lvalue *
625 recording::context::new_global (recording::location *loc,
626 recording::type *type,
627 const char *name)
629 recording::lvalue *result =
630 new recording::global (this, loc, type, new_string (name));
631 record (result);
632 return result;
635 /* Create a recording::memento_of_new_rvalue_from_int instance and add
636 it to this context's list of mementos.
638 Implements the post-error-checking part of
639 gcc_jit_context_new_rvalue_from_int. */
641 recording::rvalue *
642 recording::context::new_rvalue_from_int (recording::type *type,
643 int value)
645 recording::rvalue *result =
646 new memento_of_new_rvalue_from_int (this, NULL, type, value);
647 record (result);
648 return result;
651 /* Create a recording::memento_of_new_rvalue_from_double instance and
652 add it to this context's list of mementos.
654 Implements the post-error-checking part of
655 gcc_jit_context_new_rvalue_from_double. */
657 recording::rvalue *
658 recording::context::new_rvalue_from_double (recording::type *type,
659 double value)
661 recording::rvalue *result =
662 new memento_of_new_rvalue_from_double (this, NULL, type, value);
663 record (result);
664 return result;
667 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
668 it to this context's list of mementos.
670 Implements the post-error-checking part of
671 gcc_jit_context_new_rvalue_from_ptr. */
673 recording::rvalue *
674 recording::context::new_rvalue_from_ptr (recording::type *type,
675 void *value)
677 recording::rvalue *result =
678 new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
679 record (result);
680 return result;
683 /* Create a recording::memento_of_new_string_literal instance and add it
684 to this context's list of mementos.
686 Implements the post-error-checking part of
687 gcc_jit_context_new_string_literal. */
689 recording::rvalue *
690 recording::context::new_string_literal (const char *value)
692 recording::rvalue *result =
693 new memento_of_new_string_literal (this, NULL, new_string (value));
694 record (result);
695 return result;
698 /* Create a recording::unary_op instance and add it to this context's
699 list of mementos.
701 Implements the post-error-checking part of
702 gcc_jit_context_new_unary_op. */
704 recording::rvalue *
705 recording::context::new_unary_op (recording::location *loc,
706 enum gcc_jit_unary_op op,
707 recording::type *result_type,
708 recording::rvalue *a)
710 recording::rvalue *result =
711 new unary_op (this, loc, op, result_type, a);
712 record (result);
713 return result;
716 /* Create a recording::binary_op instance and add it to this context's
717 list of mementos.
719 Implements the post-error-checking part of
720 gcc_jit_context_new_binary_op. */
722 recording::rvalue *
723 recording::context::new_binary_op (recording::location *loc,
724 enum gcc_jit_binary_op op,
725 recording::type *result_type,
726 recording::rvalue *a,
727 recording::rvalue *b)
729 recording::rvalue *result =
730 new binary_op (this, loc, op, result_type, a, b);
731 record (result);
732 return result;
735 /* Create a recording::comparison instance and add it to this context's
736 list of mementos.
738 Implements the post-error-checking part of
739 gcc_jit_context_new_comparison. */
741 recording::rvalue *
742 recording::context::new_comparison (recording::location *loc,
743 enum gcc_jit_comparison op,
744 recording::rvalue *a,
745 recording::rvalue *b)
747 recording::rvalue *result = new comparison (this, loc, op, a, b);
748 record (result);
749 return result;
752 /* Create a recording::cast instance and add it to this context's list
753 of mementos.
755 Implements the post-error-checking part of
756 gcc_jit_context_new_cast. */
758 recording::rvalue *
759 recording::context::new_cast (recording::location *loc,
760 recording::rvalue *expr,
761 recording::type *type_)
763 recording::rvalue *result = new cast (this, loc, expr, type_);
764 record (result);
765 return result;
768 /* Create a recording::call instance and add it to this context's list
769 of mementos.
771 Implements the post-error-checking part of
772 gcc_jit_context_new_call. */
774 recording::rvalue *
775 recording::context::new_call (recording::location *loc,
776 function *func,
777 int numargs , recording::rvalue **args)
779 recording::rvalue *result = new call (this, loc, func, numargs, args);
780 record (result);
781 return result;
784 /* Create a recording::call_through_ptr instance and add it to this
785 context's list of mementos.
787 Implements the post-error-checking part of
788 gcc_jit_context_new_call_through_ptr. */
790 recording::rvalue *
791 recording::context::new_call_through_ptr (recording::location *loc,
792 recording::rvalue *fn_ptr,
793 int numargs,
794 recording::rvalue **args)
796 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
797 record (result);
798 return result;
801 /* Create a recording::array_access instance and add it to this context's list
802 of mementos.
804 Implements the post-error-checking part of
805 gcc_jit_context_new_array_access. */
807 recording::lvalue *
808 recording::context::new_array_access (recording::location *loc,
809 recording::rvalue *ptr,
810 recording::rvalue *index)
812 recording::lvalue *result = new array_access (this, loc, ptr, index);
813 record (result);
814 return result;
817 /* Set the given string option for this context, or add an error if
818 it's not recognized.
820 Implements the post-error-checking part of
821 gcc_jit_context_set_str_option. */
823 void
824 recording::context::set_str_option (enum gcc_jit_str_option opt,
825 const char *value)
827 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
829 add_error (NULL,
830 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
831 return;
833 free (m_str_options[opt]);
834 m_str_options[opt] = xstrdup (value);
837 /* Set the given integer option for this context, or add an error if
838 it's not recognized.
840 Implements the post-error-checking part of
841 gcc_jit_context_set_int_option. */
843 void
844 recording::context::set_int_option (enum gcc_jit_int_option opt,
845 int value)
847 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
849 add_error (NULL,
850 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
851 return;
853 m_int_options[opt] = value;
856 /* Set the given boolean option for this context, or add an error if
857 it's not recognized.
859 Implements the post-error-checking part of
860 gcc_jit_context_set_bool_option. */
862 void
863 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
864 int value)
866 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
868 add_error (NULL,
869 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
870 return;
872 m_bool_options[opt] = value ? true : false;
875 /* Add the given dumpname/out_ptr pair to this context's list of requested
876 dumps.
878 Implements the post-error-checking part of
879 gcc_jit_context_enable_dump. */
881 void
882 recording::context::enable_dump (const char *dumpname,
883 char **out_ptr)
885 requested_dump d;
886 gcc_assert (dumpname);
887 gcc_assert (out_ptr);
889 d.m_dumpname = dumpname;
890 d.m_out_ptr = out_ptr;
891 *out_ptr = NULL;
892 m_requested_dumps.safe_push (d);
895 /* Validate this context, and if it passes, compile it within a
896 mutex.
898 Implements the post-error-checking part of
899 gcc_jit_context_compile. */
901 result *
902 recording::context::compile ()
904 validate ();
906 if (errors_occurred ())
907 return NULL;
909 /* Set up a playback context. */
910 ::gcc::jit::playback::context replayer (this);
912 /* Use it. */
913 result *result_obj = replayer.compile ();
915 return result_obj;
918 /* Format the given error using printf's conventions, print
919 it to stderr, and add it to the context. */
921 void
922 recording::context::add_error (location *loc, const char *fmt, ...)
924 va_list ap;
925 va_start (ap, fmt);
926 add_error_va (loc, fmt, ap);
927 va_end (ap);
930 /* Format the given error using printf's conventions, print
931 it to stderr, and add it to the context. */
933 void
934 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
936 char *malloced_msg;
937 const char *errmsg;
938 bool has_ownership;
940 vasprintf (&malloced_msg, fmt, ap);
941 if (malloced_msg)
943 errmsg = malloced_msg;
944 has_ownership = true;
946 else
948 errmsg = "out of memory generating error message";
949 has_ownership = false;
952 const char *ctxt_progname =
953 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
954 if (!ctxt_progname)
955 ctxt_progname = "libgccjit.so";
957 if (loc)
958 fprintf (stderr, "%s: %s: error: %s\n",
959 ctxt_progname,
960 loc->get_debug_string (),
961 errmsg);
962 else
963 fprintf (stderr, "%s: error: %s\n",
964 ctxt_progname,
965 errmsg);
967 if (!m_error_count)
969 m_first_error_str = const_cast <char *> (errmsg);
970 m_owns_first_error_str = has_ownership;
972 else
973 if (has_ownership)
974 free (malloced_msg);
976 m_error_count++;
979 /* Get the message for the first error that occurred on this context, or
980 NULL if no errors have occurred on it.
982 Implements the post-error-checking part of
983 gcc_jit_context_get_first_error. */
985 const char *
986 recording::context::get_first_error () const
988 return m_first_error_str;
991 /* Lazily generate and record a recording::type representing an opaque
992 struct named "FILE".
994 For use if client code tries to dereference the result of
995 get_type (GCC_JIT_TYPE_FILE_PTR). */
997 recording::type *
998 recording::context::get_opaque_FILE_type ()
1000 if (!m_FILE_type)
1001 m_FILE_type = new_struct_type (NULL, "FILE");
1002 return m_FILE_type;
1005 /* Dump a C-like representation of the given context to the given path.
1006 If UPDATE_LOCATIONS is true, update the locations within the
1007 context's mementos to point to the dumpfile.
1009 Implements the post-error-checking part of
1010 gcc_jit_context_dump_to_file. */
1012 void
1013 recording::context::dump_to_file (const char *path, bool update_locations)
1015 int i;
1016 dump d (*this, path, update_locations);
1018 /* Forward declaration of structs and unions. */
1019 compound_type *st;
1020 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1022 d.write ("%s;\n\n", st->get_debug_string ());
1025 /* Content of structs, where set. */
1026 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1027 if (st->get_fields ())
1029 st->get_fields ()->write_to_dump (d);
1030 d.write ("\n");
1033 function *fn;
1034 FOR_EACH_VEC_ELT (m_functions, i, fn)
1036 fn->write_to_dump (d);
1040 /* Copy the requested dumps within this context and all ancestors into
1041 OUT. */
1043 void
1044 recording::context::get_all_requested_dumps (vec <recording::requested_dump> *out)
1046 if (m_parent_ctxt)
1047 m_parent_ctxt->get_all_requested_dumps (out);
1049 out->reserve (m_requested_dumps.length ());
1050 out->splice (m_requested_dumps);
1053 /* This is a pre-compilation check for the context (and any parents).
1055 Detect errors within the context, adding errors if any are found. */
1057 void
1058 recording::context::validate ()
1060 if (m_parent_ctxt)
1061 m_parent_ctxt->validate ();
1063 int i;
1064 function *fn;
1065 FOR_EACH_VEC_ELT (m_functions, i, fn)
1066 fn->validate ();
1069 /* The implementation of class gcc::jit::recording::memento. */
1071 /* Get a (const char *) debug description of the given memento, by
1072 calling the pure-virtual make_debug_string hook, caching the
1073 result.
1075 It is intended that this should only be called in debugging and
1076 error-handling paths, so this doesn't need to be particularly
1077 optimized. */
1079 const char *
1080 recording::memento::get_debug_string ()
1082 if (!m_debug_string)
1083 m_debug_string = make_debug_string ();
1084 return m_debug_string->c_str ();
1087 /* Default implementation of recording::memento::write_to_dump, writing
1088 an indented form of the memento's debug string to the dump. */
1090 void
1091 recording::memento::write_to_dump (dump &d)
1093 d.write(" %s\n", get_debug_string ());
1096 /* The implementation of class gcc::jit::recording::string. */
1098 /* Constructor for gcc::jit::recording::string::string, allocating a
1099 copy of the given text using new char[]. */
1101 recording::string::string (context *ctxt, const char *text)
1102 : memento (ctxt)
1104 m_len = strlen (text);
1105 m_buffer = new char[m_len + 1];
1106 strcpy (m_buffer, text);
1109 /* Destructor for gcc::jit::recording::string::string. */
1111 recording::string::~string ()
1113 delete[] m_buffer;
1116 /* Function for making gcc::jit::recording::string instances on a
1117 context via printf-style formatting.
1119 It is intended that this should only be called in debugging and
1120 error-handling paths, so this doesn't need to be particularly
1121 optimized, hence the double-copy of the string is acceptable. */
1123 recording::string *
1124 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1126 va_list ap;
1127 char *buf = NULL;
1128 recording::string *result;
1130 va_start (ap, fmt);
1131 vasprintf (&buf, fmt, ap);
1132 va_end (ap);
1134 if (!buf)
1136 ctxt->add_error (NULL, "malloc failure");
1137 return NULL;
1140 result = ctxt->new_string (buf);
1141 free (buf);
1142 return result;
1145 /* Implementation of recording::memento::make_debug_string for strings,
1146 wrapping the given string in quotes and escaping as necessary. */
1148 recording::string *
1149 recording::string::make_debug_string ()
1151 /* Hack to avoid infinite recursion into strings when logging all
1152 mementos: don't re-escape strings: */
1153 if (m_buffer[0] == '"')
1154 return this;
1156 /* Wrap in quotes and do escaping etc */
1158 size_t sz = (1 /* opening quote */
1159 + (m_len * 2) /* each char might get escaped */
1160 + 1 /* closing quote */
1161 + 1); /* nil termintator */
1162 char *tmp = new char[sz];
1163 size_t len = 0;
1165 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1166 APPEND('"'); /* opening quote */
1167 for (size_t i = 0; i < m_len ; i++)
1169 char ch = m_buffer[i];
1170 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1171 APPEND('\\');
1172 APPEND(ch);
1174 APPEND('"'); /* closing quote */
1175 #undef APPEND
1176 tmp[len] = '\0'; /* nil termintator */
1178 string *result = m_ctxt->new_string (tmp);
1180 delete[] tmp;
1181 return result;
1184 /* The implementation of class gcc::jit::recording::location. */
1186 /* Implementation of recording::memento::replay_into for locations.
1188 Create a new playback::location and store it into the
1189 recording::location's m_playback_obj field. */
1191 void
1192 recording::location::replay_into (replayer *r)
1194 m_playback_obj = r->new_location (this,
1195 m_filename->c_str (),
1196 m_line,
1197 m_column);
1200 /* Implementation of recording::memento::make_debug_string for locations,
1201 turning them into the usual form:
1202 FILENAME:LINE:COLUMN
1203 like we do when emitting diagnostics. */
1205 recording::string *
1206 recording::location::make_debug_string ()
1208 return string::from_printf (m_ctxt,
1209 "%s:%i:%i",
1210 m_filename->c_str (), m_line, m_column);
1213 /* The implementation of class gcc::jit::recording::type. */
1215 /* Given a type T, get the type T*.
1217 If this doesn't already exist, generate a new memento_of_get_pointer
1218 instance and add it to this type's context's list of mementos.
1220 Otherwise, use the cached type.
1222 Implements the post-error-checking part of
1223 gcc_jit_type_get_pointer. */
1225 recording::type *
1226 recording::type::get_pointer ()
1228 if (!m_pointer_to_this_type)
1230 m_pointer_to_this_type = new memento_of_get_pointer (this);
1231 m_ctxt->record (m_pointer_to_this_type);
1233 return m_pointer_to_this_type;
1236 /* Given a type T, get the type const T.
1238 Implements the post-error-checking part of
1239 gcc_jit_type_get_const. */
1241 recording::type *
1242 recording::type::get_const ()
1244 recording::type *result = new memento_of_get_const (this);
1245 m_ctxt->record (result);
1246 return result;
1249 /* Given a type T, get the type volatile T.
1251 Implements the post-error-checking part of
1252 gcc_jit_type_get_volatile. */
1254 recording::type *
1255 recording::type::get_volatile ()
1257 recording::type *result = new memento_of_get_volatile (this);
1258 m_ctxt->record (result);
1259 return result;
1262 /* Implementation of pure virtual hook recording::type::dereference for
1263 recording::memento_of_get_type. */
1265 recording::type *
1266 recording::memento_of_get_type::dereference ()
1268 switch (m_kind)
1270 default: gcc_unreachable ();
1272 case GCC_JIT_TYPE_VOID:
1273 return NULL;
1275 case GCC_JIT_TYPE_VOID_PTR:
1276 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1278 case GCC_JIT_TYPE_BOOL:
1279 case GCC_JIT_TYPE_CHAR:
1280 case GCC_JIT_TYPE_SIGNED_CHAR:
1281 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1282 case GCC_JIT_TYPE_SHORT:
1283 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1284 case GCC_JIT_TYPE_INT:
1285 case GCC_JIT_TYPE_UNSIGNED_INT:
1286 case GCC_JIT_TYPE_LONG:
1287 case GCC_JIT_TYPE_UNSIGNED_LONG:
1288 case GCC_JIT_TYPE_LONG_LONG:
1289 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1290 case GCC_JIT_TYPE_FLOAT:
1291 case GCC_JIT_TYPE_DOUBLE:
1292 case GCC_JIT_TYPE_LONG_DOUBLE:
1293 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1294 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1295 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1296 /* Not a pointer: */
1297 return NULL;
1299 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1300 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1302 case GCC_JIT_TYPE_SIZE_T:
1303 /* Not a pointer: */
1304 return NULL;
1306 case GCC_JIT_TYPE_FILE_PTR:
1307 /* Give the client code back an opaque "struct FILE". */
1308 return m_ctxt->get_opaque_FILE_type ();
1312 /* Implementation of pure virtual hook recording::type::is_int for
1313 recording::memento_of_get_type. */
1315 bool
1316 recording::memento_of_get_type::is_int () const
1318 switch (m_kind)
1320 default: gcc_unreachable ();
1322 case GCC_JIT_TYPE_VOID:
1323 return false;
1325 case GCC_JIT_TYPE_VOID_PTR:
1326 return false;
1328 case GCC_JIT_TYPE_BOOL:
1329 return false;
1331 case GCC_JIT_TYPE_CHAR:
1332 case GCC_JIT_TYPE_SIGNED_CHAR:
1333 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1334 case GCC_JIT_TYPE_SHORT:
1335 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1336 case GCC_JIT_TYPE_INT:
1337 case GCC_JIT_TYPE_UNSIGNED_INT:
1338 case GCC_JIT_TYPE_LONG:
1339 case GCC_JIT_TYPE_UNSIGNED_LONG:
1340 case GCC_JIT_TYPE_LONG_LONG:
1341 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1342 return true;
1344 case GCC_JIT_TYPE_FLOAT:
1345 case GCC_JIT_TYPE_DOUBLE:
1346 case GCC_JIT_TYPE_LONG_DOUBLE:
1347 return false;
1349 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1350 return false;
1352 case GCC_JIT_TYPE_SIZE_T:
1353 return true;
1355 case GCC_JIT_TYPE_FILE_PTR:
1356 return false;
1358 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1359 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1360 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1361 return false;
1365 /* Implementation of pure virtual hook recording::type::is_float for
1366 recording::memento_of_get_type. */
1368 bool
1369 recording::memento_of_get_type::is_float () const
1371 switch (m_kind)
1373 default: gcc_unreachable ();
1375 case GCC_JIT_TYPE_VOID:
1376 return false;
1378 case GCC_JIT_TYPE_VOID_PTR:
1379 return false;
1381 case GCC_JIT_TYPE_BOOL:
1382 return false;
1384 case GCC_JIT_TYPE_CHAR:
1385 case GCC_JIT_TYPE_SIGNED_CHAR:
1386 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1387 case GCC_JIT_TYPE_SHORT:
1388 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1389 case GCC_JIT_TYPE_INT:
1390 case GCC_JIT_TYPE_UNSIGNED_INT:
1391 case GCC_JIT_TYPE_LONG:
1392 case GCC_JIT_TYPE_UNSIGNED_LONG:
1393 case GCC_JIT_TYPE_LONG_LONG:
1394 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1395 return false;
1397 case GCC_JIT_TYPE_FLOAT:
1398 case GCC_JIT_TYPE_DOUBLE:
1399 case GCC_JIT_TYPE_LONG_DOUBLE:
1400 return true;
1402 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1403 return false;
1405 case GCC_JIT_TYPE_SIZE_T:
1406 return false;
1408 case GCC_JIT_TYPE_FILE_PTR:
1409 return false;
1411 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1412 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1413 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1414 return true;
1418 /* Implementation of pure virtual hook recording::type::is_bool for
1419 recording::memento_of_get_type. */
1421 bool
1422 recording::memento_of_get_type::is_bool () const
1424 switch (m_kind)
1426 default: gcc_unreachable ();
1428 case GCC_JIT_TYPE_VOID:
1429 return false;
1431 case GCC_JIT_TYPE_VOID_PTR:
1432 return false;
1434 case GCC_JIT_TYPE_BOOL:
1435 return true;
1437 case GCC_JIT_TYPE_CHAR:
1438 case GCC_JIT_TYPE_SIGNED_CHAR:
1439 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1440 case GCC_JIT_TYPE_SHORT:
1441 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1442 case GCC_JIT_TYPE_INT:
1443 case GCC_JIT_TYPE_UNSIGNED_INT:
1444 case GCC_JIT_TYPE_LONG:
1445 case GCC_JIT_TYPE_UNSIGNED_LONG:
1446 case GCC_JIT_TYPE_LONG_LONG:
1447 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1448 return false;
1450 case GCC_JIT_TYPE_FLOAT:
1451 case GCC_JIT_TYPE_DOUBLE:
1452 case GCC_JIT_TYPE_LONG_DOUBLE:
1453 return false;
1455 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1456 return false;
1458 case GCC_JIT_TYPE_SIZE_T:
1459 return false;
1461 case GCC_JIT_TYPE_FILE_PTR:
1462 return false;
1464 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1465 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1466 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1467 return false;
1471 /* Implementation of pure virtual hook recording::memento::replay_into
1472 for recording::memento_of_get_type. */
1474 void
1475 recording::memento_of_get_type::replay_into (replayer *r)
1477 set_playback_obj (r->get_type (m_kind));
1480 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1482 /* Descriptive strings for each of enum gcc_jit_types. */
1484 static const char * const get_type_strings[] = {
1485 "void", /* GCC_JIT_TYPE_VOID */
1486 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1488 "bool", /* GCC_JIT_TYPE_BOOL */
1490 "char", /* GCC_JIT_TYPE_CHAR */
1491 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1492 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1494 "short", /* GCC_JIT_TYPE_SHORT */
1495 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1497 "int", /* GCC_JIT_TYPE_INT */
1498 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1500 "long", /* GCC_JIT_TYPE_LONG */
1501 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1503 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1504 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1506 "float", /* GCC_JIT_TYPE_FLOAT */
1507 "double", /* GCC_JIT_TYPE_DOUBLE */
1508 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1510 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1512 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1514 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1516 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1517 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1518 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1522 /* Implementation of recording::memento::make_debug_string for
1523 results of get_type, using a simple table of type names. */
1525 recording::string *
1526 recording::memento_of_get_type::make_debug_string ()
1528 return m_ctxt->new_string (get_type_strings[m_kind]);
1531 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1533 /* Override of default implementation of
1534 recording::type::accepts_writes_from for get_pointer.
1536 Require a pointer type, and allowing writes to
1537 (const T *) from a (T*), but not the other way around. */
1539 bool
1540 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1542 /* Must be a pointer type: */
1543 type *rtype_points_to = rtype->is_pointer ();
1544 if (!rtype_points_to)
1545 return false;
1547 /* It's OK to assign to a (const T *) from a (T *). */
1548 return m_other_type->unqualified ()
1549 ->accepts_writes_from (rtype_points_to);
1552 /* Implementation of pure virtual hook recording::memento::replay_into
1553 for recording::memento_of_get_pointer. */
1555 void
1556 recording::memento_of_get_pointer::replay_into (replayer *)
1558 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1561 /* Implementation of recording::memento::make_debug_string for
1562 results of get_pointer, adding " *" to the underlying type,
1563 with special-casing to handle function pointer types. */
1565 recording::string *
1566 recording::memento_of_get_pointer::make_debug_string ()
1568 /* Special-case function pointer types, to put the "*" in parens between
1569 the return type and the params (for one level of dereferencing, at
1570 least). */
1571 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1572 return fn_type->make_debug_string_with_ptr ();
1574 return string::from_printf (m_ctxt,
1575 "%s *", m_other_type->get_debug_string ());
1578 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1580 /* Implementation of pure virtual hook recording::memento::replay_into
1581 for recording::memento_of_get_const. */
1583 void
1584 recording::memento_of_get_const::replay_into (replayer *)
1586 set_playback_obj (m_other_type->playback_type ()->get_const ());
1589 /* Implementation of recording::memento::make_debug_string for
1590 results of get_const, prepending "const ". */
1592 recording::string *
1593 recording::memento_of_get_const::make_debug_string ()
1595 return string::from_printf (m_ctxt,
1596 "const %s", m_other_type->get_debug_string ());
1599 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1601 /* Implementation of pure virtual hook recording::memento::replay_into
1602 for recording::memento_of_get_volatile. */
1604 void
1605 recording::memento_of_get_volatile::replay_into (replayer *)
1607 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1610 /* Implementation of recording::memento::make_debug_string for
1611 results of get_volatile, prepending "volatile ". */
1613 recording::string *
1614 recording::memento_of_get_volatile::make_debug_string ()
1616 return string::from_printf (m_ctxt,
1617 "volatile %s", m_other_type->get_debug_string ());
1620 /* The implementation of class gcc::jit::recording::array_type */
1622 /* Implementation of pure virtual hook recording::type::dereference for
1623 recording::array_type. */
1625 recording::type *
1626 recording::array_type::dereference ()
1628 return m_element_type;
1631 /* Implementation of pure virtual hook recording::memento::replay_into
1632 for recording::array_type. */
1634 void
1635 recording::array_type::replay_into (replayer *r)
1637 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1638 m_element_type->playback_type (),
1639 m_num_elements));
1642 /* Implementation of recording::memento::make_debug_string for
1643 results of new_array_type. */
1645 recording::string *
1646 recording::array_type::make_debug_string ()
1648 return string::from_printf (m_ctxt,
1649 "%s[%d]",
1650 m_element_type->get_debug_string (),
1651 m_num_elements);
1654 /* The implementation of class gcc::jit::recording::function_type */
1656 /* Constructor for gcc::jit::recording::function_type. */
1658 recording::function_type::function_type (context *ctxt,
1659 type *return_type,
1660 int num_params,
1661 type **param_types,
1662 int is_variadic)
1663 : type (ctxt),
1664 m_return_type (return_type),
1665 m_param_types (),
1666 m_is_variadic (is_variadic)
1668 for (int i = 0; i< num_params; i++)
1669 m_param_types.safe_push (param_types[i]);
1672 /* Implementation of pure virtual hook recording::type::dereference for
1673 recording::function_type. */
1675 recording::type *
1676 recording::function_type::dereference ()
1678 return NULL;
1681 /* Implementation of pure virtual hook recording::memento::replay_into
1682 for recording::function_type. */
1684 void
1685 recording::function_type::replay_into (replayer *r)
1687 /* Convert m_param_types to a vec of playback type. */
1688 auto_vec <playback::type *> param_types;
1689 int i;
1690 recording::type *type;
1691 param_types.create (m_param_types.length ());
1692 FOR_EACH_VEC_ELT (m_param_types, i, type)
1693 param_types.safe_push (type->playback_type ());
1695 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1696 &param_types,
1697 m_is_variadic));
1700 /* Special-casing for make_debug_string for get_pointer results for
1701 handling (one level) of pointers to functions. */
1703 recording::string *
1704 recording::function_type::make_debug_string_with_ptr ()
1706 return make_debug_string_with ("(*) ");
1709 /* Implementation of recording::memento::make_debug_string for
1710 results of new_function_type. */
1712 recording::string *
1713 recording::function_type::make_debug_string ()
1715 return make_debug_string_with ("");
1718 /* Build a debug string representation of the form:
1720 RESULT_TYPE INSERT (PARAM_TYPES)
1722 for use when handling 0 and 1 level of indirection to this
1723 function type. */
1725 recording::string *
1726 recording::function_type::make_debug_string_with (const char *insert)
1728 /* First, build a buffer for the arguments. */
1729 /* Calculate length of said buffer. */
1730 size_t sz = 1; /* nil terminator */
1731 for (unsigned i = 0; i< m_param_types.length (); i++)
1733 sz += strlen (m_param_types[i]->get_debug_string ());
1734 sz += 2; /* ", " separator */
1736 if (m_is_variadic)
1737 sz += 5; /* ", ..." separator and ellipsis */
1739 /* Now allocate and populate the buffer. */
1740 char *argbuf = new char[sz];
1741 size_t len = 0;
1743 for (unsigned i = 0; i< m_param_types.length (); i++)
1745 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1746 len += strlen (m_param_types[i]->get_debug_string ());
1747 if (i + 1 < m_param_types.length ())
1749 strcpy (argbuf + len, ", ");
1750 len += 2;
1753 if (m_is_variadic)
1755 if (m_param_types.length ())
1757 strcpy (argbuf + len, ", ");
1758 len += 2;
1760 strcpy (argbuf + len, "...");
1761 len += 3;
1763 argbuf[len] = '\0';
1765 /* ...and use it to get the string for the call as a whole. */
1766 string *result = string::from_printf (m_ctxt,
1767 "%s %s(%s)",
1768 m_return_type->get_debug_string (),
1769 insert,
1770 argbuf);
1772 delete[] argbuf;
1774 return result;
1777 /* The implementation of class gcc::jit::recording::field. */
1779 /* Implementation of pure virtual hook recording::memento::replay_into
1780 for recording::field. */
1782 void
1783 recording::field::replay_into (replayer *r)
1785 set_playback_obj (r->new_field (playback_location (r, m_loc),
1786 m_type->playback_type (),
1787 playback_string (m_name)));
1790 /* Override the default implementation of
1791 recording::memento::write_to_dump. Dump each field
1792 by dumping a line of the form:
1793 TYPE NAME;
1794 so that we can build up a struct/union field-byfield. */
1796 void
1797 recording::field::write_to_dump (dump &d)
1799 d.write (" %s %s;\n",
1800 m_type->get_debug_string (),
1801 m_name->c_str ());
1804 /* Implementation of recording::memento::make_debug_string for
1805 results of new_field. */
1807 recording::string *
1808 recording::field::make_debug_string ()
1810 return m_name;
1813 /* The implementation of class gcc::jit::recording::compound_type */
1815 /* The constructor for gcc::jit::recording::compound_type. */
1817 recording::compound_type::compound_type (context *ctxt,
1818 location *loc,
1819 string *name)
1820 : type (ctxt),
1821 m_loc (loc),
1822 m_name (name),
1823 m_fields (NULL)
1827 /* Set the fields of a compound type.
1829 Implements the post-error-checking part of
1830 gcc_jit_struct_set_fields, and is also used by
1831 gcc_jit_context_new_union_type. */
1833 void
1834 recording::compound_type::set_fields (location *loc,
1835 int num_fields,
1836 field **field_array)
1838 m_loc = loc;
1839 gcc_assert (NULL == m_fields);
1841 m_fields = new fields (this, num_fields, field_array);
1842 m_ctxt->record (m_fields);
1845 /* Implementation of pure virtual hook recording::type::dereference for
1846 recording::compound_type. */
1848 recording::type *
1849 recording::compound_type::dereference ()
1851 return NULL; /* not a pointer */
1854 /* The implementation of class gcc::jit::recording::struct_. */
1856 /* The constructor for gcc::jit::recording::struct_. */
1858 recording::struct_::struct_ (context *ctxt,
1859 location *loc,
1860 string *name)
1861 : compound_type (ctxt, loc, name)
1865 /* Implementation of pure virtual hook recording::memento::replay_into
1866 for recording::struct_. */
1868 void
1869 recording::struct_::replay_into (replayer *r)
1871 set_playback_obj (
1872 r->new_compound_type (playback_location (r, get_loc ()),
1873 get_name ()->c_str (),
1874 true /* is_struct */));
1877 /* Implementation of recording::memento::make_debug_string for
1878 structs. */
1880 recording::string *
1881 recording::struct_::make_debug_string ()
1883 return string::from_printf (m_ctxt,
1884 "struct %s", get_name ()->c_str ());
1887 /* The implementation of class gcc::jit::recording::union_. */
1889 /* The constructor for gcc::jit::recording::union_. */
1891 recording::union_::union_ (context *ctxt,
1892 location *loc,
1893 string *name)
1894 : compound_type (ctxt, loc, name)
1898 /* Implementation of pure virtual hook recording::memento::replay_into
1899 for recording::union_. */
1901 void
1902 recording::union_::replay_into (replayer *r)
1904 set_playback_obj (
1905 r->new_compound_type (playback_location (r, get_loc ()),
1906 get_name ()->c_str (),
1907 false /* is_struct */));
1910 /* Implementation of recording::memento::make_debug_string for
1911 unions. */
1913 recording::string *
1914 recording::union_::make_debug_string ()
1916 return string::from_printf (m_ctxt,
1917 "union %s", get_name ()->c_str ());
1920 /* The implementation of class gcc::jit::recording::fields. */
1922 /* The constructor for gcc::jit::recording::fields. */
1924 recording::fields::fields (compound_type *struct_or_union,
1925 int num_fields,
1926 field **fields)
1927 : memento (struct_or_union->m_ctxt),
1928 m_struct_or_union (struct_or_union),
1929 m_fields ()
1931 for (int i = 0; i < num_fields; i++)
1933 gcc_assert (fields[i]->get_container () == NULL);
1934 fields[i]->set_container (m_struct_or_union);
1935 m_fields.safe_push (fields[i]);
1939 /* Implementation of pure virtual hook recording::memento::replay_into
1940 for recording::fields. */
1942 void
1943 recording::fields::replay_into (replayer *)
1945 auto_vec<playback::field *> playback_fields;
1946 playback_fields.create (m_fields.length ());
1947 for (unsigned i = 0; i < m_fields.length (); i++)
1948 playback_fields.safe_push (m_fields[i]->playback_field ());
1949 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1952 /* Override the default implementation of
1953 recording::memento::write_to_dump by writing a union/struct
1954 declaration of this form:
1956 struct/union NAME {
1957 TYPE_1 NAME_1;
1958 TYPE_2 NAME_2;
1959 ....
1960 TYPE_N NAME_N;
1963 to the dump. */
1965 void
1966 recording::fields::write_to_dump (dump &d)
1968 int i;
1969 field *f;
1971 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
1972 FOR_EACH_VEC_ELT (m_fields, i, f)
1973 f->write_to_dump (d);
1974 d.write ("};\n");
1977 /* Implementation of recording::memento::make_debug_string for
1978 field tables. */
1980 recording::string *
1981 recording::fields::make_debug_string ()
1983 return string::from_printf (m_ctxt,
1984 "fields");
1987 /* The implementation of class gcc::jit::recording::rvalue. */
1989 /* Create a recording::access_field_rvalue instance and add it to
1990 the rvalue's context's list of mementos.
1992 Implements the post-error-checking part of
1993 gcc_jit_rvalue_access_field. */
1995 recording::rvalue *
1996 recording::rvalue::access_field (recording::location *loc,
1997 field *field)
1999 recording::rvalue *result =
2000 new access_field_rvalue (m_ctxt, loc, this, field);
2001 m_ctxt->record (result);
2002 return result;
2005 /* Create a recording::dereference_field_rvalue instance and add it to
2006 the rvalue's context's list of mementos.
2008 Implements the post-error-checking part of
2009 gcc_jit_rvalue_dereference_field. */
2011 recording::lvalue *
2012 recording::rvalue::dereference_field (recording::location *loc,
2013 field *field)
2015 recording::lvalue *result =
2016 new dereference_field_rvalue (m_ctxt, loc, this, field);
2017 m_ctxt->record (result);
2018 return result;
2021 /* Create a recording::dereference_rvalue instance and add it to the
2022 rvalue's context's list of mementos.
2024 Implements the post-error-checking part of
2025 gcc_jit_rvalue_dereference. */
2027 recording::lvalue *
2028 recording::rvalue::dereference (recording::location *loc)
2030 recording::lvalue *result =
2031 new dereference_rvalue (m_ctxt, loc, this);
2032 m_ctxt->record (result);
2033 return result;
2036 /* The implementation of class gcc::jit::recording::lvalue. */
2038 /* Create a recording::new_access_field_of_lvalue instance and add it to
2039 the lvalue's context's list of mementos.
2041 Implements the post-error-checking part of
2042 gcc_jit_lvalue_access_field. */
2044 recording::lvalue *
2045 recording::lvalue::access_field (recording::location *loc,
2046 field *field)
2048 recording::lvalue *result =
2049 new access_field_of_lvalue (m_ctxt, loc, this, field);
2050 m_ctxt->record (result);
2051 return result;
2054 /* Create a recording::get_address_of_lvalue instance and add it to
2055 the lvalue's context's list of mementos.
2057 Implements the post-error-checking part of
2058 gcc_jit_lvalue_get_address. */
2060 recording::rvalue *
2061 recording::lvalue::get_address (recording::location *loc)
2063 recording::rvalue *result =
2064 new get_address_of_lvalue (m_ctxt, loc, this);
2065 m_ctxt->record (result);
2066 return result;
2069 /* The implementation of class gcc::jit::recording::param. */
2071 /* Implementation of pure virtual hook recording::memento::replay_into
2072 for recording::param. */
2074 void
2075 recording::param::replay_into (replayer *r)
2077 set_playback_obj (r->new_param (playback_location (r, m_loc),
2078 m_type->playback_type (),
2079 m_name->c_str ()));
2083 /* The implementation of class gcc::jit::recording::function. */
2085 /* gcc::jit::recording::function's constructor. */
2087 recording::function::function (context *ctxt,
2088 recording::location *loc,
2089 enum gcc_jit_function_kind kind,
2090 type *return_type,
2091 recording::string *name,
2092 int num_params,
2093 recording::param **params,
2094 int is_variadic,
2095 enum built_in_function builtin_id)
2096 : memento (ctxt),
2097 m_loc (loc),
2098 m_kind (kind),
2099 m_return_type (return_type),
2100 m_name (name),
2101 m_params (),
2102 m_is_variadic (is_variadic),
2103 m_builtin_id (builtin_id),
2104 m_locals (),
2105 m_blocks ()
2107 for (int i = 0; i< num_params; i++)
2108 m_params.safe_push (params[i]);
2111 /* Implementation of pure virtual hook recording::memento::replay_into
2112 for recording::function. */
2114 void
2115 recording::function::replay_into (replayer *r)
2117 /* Convert m_params to a vec of playback param. */
2118 auto_vec <playback::param *> params;
2119 int i;
2120 recording::param *param;
2121 params.create (m_params.length ());
2122 FOR_EACH_VEC_ELT (m_params, i, param)
2123 params.safe_push (param->playback_param ());
2125 set_playback_obj (r->new_function (playback_location (r, m_loc),
2126 m_kind,
2127 m_return_type->playback_type (),
2128 m_name->c_str (),
2129 &params,
2130 m_is_variadic,
2131 m_builtin_id));
2134 /* Create a recording::local instance and add it to
2135 the functions's context's list of mementos, and to the function's
2136 list of locals.
2138 Implements the post-error-checking part of
2139 gcc_jit_function_new_local. */
2141 recording::lvalue *
2142 recording::function::new_local (recording::location *loc,
2143 type *type,
2144 const char *name)
2146 local *result = new local (this, loc, type, new_string (name));
2147 m_ctxt->record (result);
2148 m_locals.safe_push (result);
2149 return result;
2152 /* Create a recording::block instance and add it to
2153 the functions's context's list of mementos, and to the function's
2154 list of blocks.
2156 Implements the post-error-checking part of
2157 gcc_jit_function_new_block. */
2159 recording::block*
2160 recording::function::new_block (const char *name)
2162 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2164 recording::block *result =
2165 new recording::block (this, m_blocks.length (), new_string (name));
2166 m_ctxt->record (result);
2167 m_blocks.safe_push (result);
2168 return result;
2171 /* Override the default implementation of
2172 recording::memento::write_to_dump by dumping a C-like
2173 representation of the function; either like a prototype
2174 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2175 all other kinds of function. */
2177 void
2178 recording::function::write_to_dump (dump &d)
2180 switch (m_kind)
2182 default: gcc_unreachable ();
2183 case GCC_JIT_FUNCTION_EXPORTED:
2184 case GCC_JIT_FUNCTION_IMPORTED:
2185 d.write ("extern ");
2186 break;
2187 case GCC_JIT_FUNCTION_INTERNAL:
2188 d.write ("static ");
2189 break;
2190 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2191 d.write ("static inline ");
2192 break;
2194 d.write ("%s\n", m_return_type->get_debug_string ());
2196 if (d.update_locations ())
2197 m_loc = d.make_location ();
2199 d.write ("%s (", get_debug_string ());
2201 int i;
2202 recording::param *param;
2203 FOR_EACH_VEC_ELT (m_params, i, param)
2205 if (i > 0)
2206 d.write (", ");
2207 d.write ("%s %s",
2208 param->get_type ()->get_debug_string (),
2209 param->get_debug_string ());
2211 d.write (")");
2212 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2214 d.write ("; /* (imported) */\n\n");
2216 else
2218 int i;
2219 local *var = NULL;
2220 block *b;
2221 d.write ("\n{\n");
2223 /* Write locals: */
2224 FOR_EACH_VEC_ELT (m_locals, i, var)
2225 var->write_to_dump (d);
2226 if (m_locals.length ())
2227 d.write ("\n");
2229 /* Write each block: */
2230 FOR_EACH_VEC_ELT (m_blocks, i, b)
2232 if (i > 0)
2233 d.write ("\n");
2234 b->write_to_dump (d);
2237 d.write ("}\n\n");
2241 /* Pre-compilation validation of a function, for those things we can't
2242 check until the context is (supposedly) fully-populated. */
2244 void
2245 recording::function::validate ()
2247 /* Complain about empty functions with non-void return type. */
2248 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2249 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2250 if (0 == m_blocks.length ())
2251 m_ctxt->add_error (m_loc,
2252 "function %s returns non-void (type: %s)"
2253 " but has no blocks",
2254 get_debug_string (),
2255 m_return_type->get_debug_string ());
2257 /* Check that all blocks are terminated. */
2258 int num_invalid_blocks = 0;
2260 int i;
2261 block *b;
2263 FOR_EACH_VEC_ELT (m_blocks, i, b)
2264 if (!b->validate ())
2265 num_invalid_blocks++;
2268 /* Check that all blocks are reachable. */
2269 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2271 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2272 flag, starting at the initial block. */
2273 auto_vec<block *> worklist (m_blocks.length ());
2274 worklist.safe_push (m_blocks[0]);
2275 while (worklist.length () > 0)
2277 block *b = worklist.pop ();
2278 b->m_is_reachable = true;
2280 /* Add successor blocks that aren't yet marked to the worklist. */
2281 /* We checked that each block has a terminating statement above . */
2282 block *next1, *next2;
2283 int n = b->get_successor_blocks (&next1, &next2);
2284 switch (n)
2286 default:
2287 gcc_unreachable ();
2288 case 2:
2289 if (!next2->m_is_reachable)
2290 worklist.safe_push (next2);
2291 /* fallthrough */
2292 case 1:
2293 if (!next1->m_is_reachable)
2294 worklist.safe_push (next1);
2295 break;
2296 case 0:
2297 break;
2301 /* Now complain about any blocks that haven't been marked. */
2303 int i;
2304 block *b;
2305 FOR_EACH_VEC_ELT (m_blocks, i, b)
2306 if (!b->m_is_reachable)
2307 m_ctxt->add_error (b->get_loc (),
2308 "unreachable block: %s",
2309 b->get_debug_string ());
2314 /* Implements the post-error-checking part of
2315 gcc_jit_function_dump_to_dot. */
2317 void
2318 recording::function::dump_to_dot (const char *path)
2320 FILE *fp = fopen (path, "w");
2321 if (!fp)
2322 return;
2324 pretty_printer the_pp;
2325 the_pp.buffer->stream = fp;
2327 pretty_printer *pp = &the_pp;
2329 pp_printf (pp,
2330 "digraph %s {\n", get_debug_string ());
2332 /* Blocks: */
2334 int i;
2335 block *b;
2336 FOR_EACH_VEC_ELT (m_blocks, i, b)
2337 b->dump_to_dot (pp);
2340 /* Edges: */
2342 int i;
2343 block *b;
2344 FOR_EACH_VEC_ELT (m_blocks, i, b)
2345 b->dump_edges_to_dot (pp);
2348 pp_printf (pp, "}\n");
2349 pp_flush (pp);
2350 fclose (fp);
2353 /* Implementation of recording::memento::make_debug_string for
2354 functions. */
2356 recording::string *
2357 recording::function::make_debug_string ()
2359 return m_name;
2362 /* The implementation of class gcc::jit::recording::block. */
2364 /* Create a recording::eval instance and add it to
2365 the block's context's list of mementos, and to the block's
2366 list of statements.
2368 Implements the post-error-checking part of
2369 gcc_jit_block_add_eval. */
2371 void
2372 recording::block::add_eval (recording::location *loc,
2373 recording::rvalue *rvalue)
2375 statement *result = new eval (this, loc, rvalue);
2376 m_ctxt->record (result);
2377 m_statements.safe_push (result);
2380 /* Create a recording::assignment instance and add it to
2381 the block's context's list of mementos, and to the block's
2382 list of statements.
2384 Implements the post-error-checking part of
2385 gcc_jit_block_add_assignment. */
2387 void
2388 recording::block::add_assignment (recording::location *loc,
2389 recording::lvalue *lvalue,
2390 recording::rvalue *rvalue)
2392 statement *result = new assignment (this, loc, lvalue, rvalue);
2393 m_ctxt->record (result);
2394 m_statements.safe_push (result);
2397 /* Create a recording::assignment_op instance and add it to
2398 the block's context's list of mementos, and to the block's
2399 list of statements.
2401 Implements the post-error-checking part of
2402 gcc_jit_block_add_assignment_op. */
2404 void
2405 recording::block::add_assignment_op (recording::location *loc,
2406 recording::lvalue *lvalue,
2407 enum gcc_jit_binary_op op,
2408 recording::rvalue *rvalue)
2410 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2411 m_ctxt->record (result);
2412 m_statements.safe_push (result);
2415 /* Create a recording::comment instance and add it to
2416 the block's context's list of mementos, and to the block's
2417 list of statements.
2419 Implements the post-error-checking part of
2420 gcc_jit_block_add_comment. */
2422 void
2423 recording::block::add_comment (recording::location *loc,
2424 const char *text)
2426 statement *result = new comment (this, loc, new_string (text));
2427 m_ctxt->record (result);
2428 m_statements.safe_push (result);
2431 /* Create a recording::end_with_conditional instance and add it to
2432 the block's context's list of mementos, and to the block's
2433 list of statements.
2435 Implements the post-error-checking part of
2436 gcc_jit_block_end_with_conditional. */
2438 void
2439 recording::block::end_with_conditional (recording::location *loc,
2440 recording::rvalue *boolval,
2441 recording::block *on_true,
2442 recording::block *on_false)
2444 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2445 m_ctxt->record (result);
2446 m_statements.safe_push (result);
2447 m_has_been_terminated = true;
2450 /* Create a recording::end_with_jump instance and add it to
2451 the block's context's list of mementos, and to the block's
2452 list of statements.
2454 Implements the post-error-checking part of
2455 gcc_jit_block_end_with_jump. */
2457 void
2458 recording::block::end_with_jump (recording::location *loc,
2459 recording::block *target)
2461 statement *result = new jump (this, loc, target);
2462 m_ctxt->record (result);
2463 m_statements.safe_push (result);
2464 m_has_been_terminated = true;
2467 /* Create a recording::end_with_return instance and add it to
2468 the block's context's list of mementos, and to the block's
2469 list of statements.
2471 Implements the post-error-checking parts of
2472 gcc_jit_block_end_with_return and
2473 gcc_jit_block_end_with_void_return. */
2475 void
2476 recording::block::end_with_return (recording::location *loc,
2477 recording::rvalue *rvalue)
2479 /* This is used by both gcc_jit_function_add_return and
2480 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2481 the former and NULL for the latter. */
2482 statement *result = new return_ (this, loc, rvalue);
2483 m_ctxt->record (result);
2484 m_statements.safe_push (result);
2485 m_has_been_terminated = true;
2488 /* Override the default implementation of
2489 recording::memento::write_to_dump for blocks by writing
2490 an unindented block name as a label, followed by the indented
2491 statements:
2493 BLOCK_NAME:
2494 STATEMENT_1;
2495 STATEMENT_2;
2497 STATEMENT_N; */
2499 void
2500 recording::block::write_to_dump (dump &d)
2502 d.write ("%s:\n", get_debug_string ());
2504 int i;
2505 statement *s;
2506 FOR_EACH_VEC_ELT (m_statements, i, s)
2507 s->write_to_dump (d);
2510 /* Validate a block by ensuring that it has been terminated. */
2512 bool
2513 recording::block::validate ()
2515 if (!has_been_terminated ())
2517 statement *stmt = get_last_statement ();
2518 location *loc = stmt ? stmt->get_loc () : NULL;
2519 m_func->get_context ()->add_error (loc,
2520 "unterminated block in %s: %s",
2521 m_func->get_debug_string (),
2522 get_debug_string ());
2523 return false;
2526 return true;
2529 /* Get the source-location of a block by using that of the first
2530 statement within it, if any. */
2532 recording::location *
2533 recording::block::get_loc () const
2535 recording::statement *stmt = get_first_statement ();
2536 if (stmt)
2537 return stmt->get_loc ();
2538 else
2539 return NULL;
2542 /* Get the first statement within a block, if any. */
2544 recording::statement *
2545 recording::block::get_first_statement () const
2547 if (m_statements.length ())
2548 return m_statements[0];
2549 else
2550 return NULL;
2553 /* Get the last statement within a block, if any. */
2555 recording::statement *
2556 recording::block::get_last_statement () const
2558 if (m_statements.length ())
2559 return m_statements[m_statements.length () - 1];
2560 else
2561 return NULL;
2564 /* Assuming that this block has been terminated, get the number of
2565 successor blocks, which will be 0, 1 or 2, for return, unconditional
2566 jump, and conditional jump respectively.
2567 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2568 is written to NEXT1, and the second (if any) to NEXT2.
2570 Used when validating functions, and when dumping dot representations
2571 of them. */
2574 recording::block::get_successor_blocks (block **next1, block **next2) const
2576 gcc_assert (m_has_been_terminated);
2577 gcc_assert (next1);
2578 gcc_assert (next2);
2579 statement *last_statement = get_last_statement ();
2580 gcc_assert (last_statement);
2581 return last_statement->get_successor_blocks (next1, next2);
2584 /* Implementation of pure virtual hook recording::memento::replay_into
2585 for recording::block. */
2587 void
2588 recording::block::replay_into (replayer *)
2590 set_playback_obj (m_func->playback_function ()
2591 ->new_block (playback_string (m_name)));
2594 /* Implementation of recording::memento::make_debug_string for
2595 blocks. */
2597 recording::string *
2598 recording::block::make_debug_string ()
2600 if (m_name)
2601 return m_name;
2602 else
2603 return string::from_printf (m_ctxt,
2604 "<UNNAMED BLOCK %p>",
2605 (void *)this);
2608 /* Dump a block in graphviz form into PP, capturing the block name (if
2609 any) and the statements. */
2611 void
2612 recording::block::dump_to_dot (pretty_printer *pp)
2614 pp_printf (pp,
2615 ("\tblock_%d "
2616 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2617 m_index);
2618 pp_write_text_to_stream (pp);
2619 if (m_name)
2621 pp_string (pp, m_name->c_str ());
2622 pp_string (pp, ":");
2623 pp_newline (pp);
2624 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2627 int i;
2628 statement *s;
2629 FOR_EACH_VEC_ELT (m_statements, i, s)
2631 pp_string (pp, s->get_debug_string ());
2632 pp_newline (pp);
2633 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2636 pp_printf (pp,
2637 "}\"];\n\n");
2638 pp_flush (pp);
2641 /* Dump the out-edges of the block in graphviz form into PP. */
2643 void
2644 recording::block::dump_edges_to_dot (pretty_printer *pp)
2646 block *next[2];
2647 int num_succs = get_successor_blocks (&next[0], &next[1]);
2648 for (int i = 0; i < num_succs; i++)
2649 pp_printf (pp,
2650 "\tblock_%d:s -> block_%d:n;\n",
2651 m_index, next[i]->m_index);
2654 /* The implementation of class gcc::jit::recording::global. */
2656 /* Implementation of pure virtual hook recording::memento::replay_into
2657 for recording::global. */
2659 void
2660 recording::global::replay_into (replayer *r)
2662 set_playback_obj (r->new_global (playback_location (r, m_loc),
2663 m_type->playback_type (),
2664 playback_string (m_name)));
2667 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2669 /* Implementation of pure virtual hook recording::memento::replay_into
2670 for recording::memento_of_new_rvalue_from_int. */
2672 void
2673 recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
2675 set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
2676 m_value));
2679 /* Implementation of recording::memento::make_debug_string for
2680 rvalue_from_int, rendering it as
2681 (TYPE)LITERAL
2682 e.g.
2683 "(int)42". */
2685 recording::string *
2686 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2688 return string::from_printf (m_ctxt,
2689 "(%s)%i",
2690 m_type->get_debug_string (),
2691 m_value);
2694 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2696 /* Implementation of pure virtual hook recording::memento::replay_into
2697 for recording::memento_of_new_rvalue_from_double. */
2699 void
2700 recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
2702 set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
2703 m_value));
2706 /* Implementation of recording::memento::make_debug_string for
2707 rvalue_from_double, rendering it as
2708 (TYPE)LITERAL
2709 e.g.
2710 "(float)42.0". */
2712 recording::string *
2713 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2715 return string::from_printf (m_ctxt,
2716 "(%s)%f",
2717 m_type->get_debug_string (),
2718 m_value);
2721 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2723 /* Implementation of pure virtual hook recording::memento::replay_into
2724 for recording::memento_of_new_rvalue_from_ptr. */
2726 void
2727 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
2729 set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
2730 m_value));
2733 /* Implementation of recording::memento::make_debug_string for
2734 rvalue_from_ptr, rendering it as
2735 (TYPE)HEX
2736 e.g.
2737 "(int *)0xdeadbeef"
2739 Zero is rendered as NULL e.g.
2740 "(int *)NULL". */
2742 recording::string *
2743 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2745 if (m_value != NULL)
2746 return string::from_printf (m_ctxt,
2747 "(%s)%p",
2748 m_type->get_debug_string (), m_value);
2749 else
2750 return string::from_printf (m_ctxt,
2751 "(%s)NULL",
2752 m_type->get_debug_string ());
2755 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2757 /* Implementation of pure virtual hook recording::memento::replay_into
2758 for recording::memento_of_new_string_literal. */
2760 void
2761 recording::memento_of_new_string_literal::replay_into (replayer *r)
2763 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2766 /* Implementation of recording::memento::make_debug_string for
2767 string literals. */
2769 recording::string *
2770 recording::memento_of_new_string_literal::make_debug_string ()
2772 return string::from_printf (m_ctxt,
2773 m_value->get_debug_string ());
2776 /* The implementation of class gcc::jit::recording::unary_op. */
2778 /* Implementation of pure virtual hook recording::memento::replay_into
2779 for recording::unary_op. */
2781 void
2782 recording::unary_op::replay_into (replayer *r)
2784 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2785 m_op,
2786 get_type ()->playback_type (),
2787 m_a->playback_rvalue ()));
2790 /* Implementation of recording::memento::make_debug_string for
2791 unary ops. */
2793 static const char * const unary_op_strings[] = {
2794 "-", /* GCC_JIT_UNARY_OP_MINUS */
2795 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2796 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2799 recording::string *
2800 recording::unary_op::make_debug_string ()
2802 return string::from_printf (m_ctxt,
2803 "%s(%s)",
2804 unary_op_strings[m_op],
2805 m_a->get_debug_string ());
2808 /* The implementation of class gcc::jit::recording::binary_op. */
2810 /* Implementation of pure virtual hook recording::memento::replay_into
2811 for recording::binary_op. */
2813 void
2814 recording::binary_op::replay_into (replayer *r)
2816 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2817 m_op,
2818 get_type ()->playback_type (),
2819 m_a->playback_rvalue (),
2820 m_b->playback_rvalue ()));
2823 /* Implementation of recording::memento::make_debug_string for
2824 binary ops. */
2826 static const char * const binary_op_strings[] = {
2827 "+", /* GCC_JIT_BINARY_OP_PLUS */
2828 "-", /* GCC_JIT_BINARY_OP_MINUS */
2829 "*", /* GCC_JIT_BINARY_OP_MULT */
2830 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2831 "%", /* GCC_JIT_BINARY_OP_MODULO */
2832 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2833 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2834 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2835 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2836 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2837 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2838 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2841 recording::string *
2842 recording::binary_op::make_debug_string ()
2844 return string::from_printf (m_ctxt,
2845 "%s %s %s",
2846 m_a->get_debug_string (),
2847 binary_op_strings[m_op],
2848 m_b->get_debug_string ());
2851 /* The implementation of class gcc::jit::recording::comparison. */
2853 /* Implementation of recording::memento::make_debug_string for
2854 comparisons. */
2856 static const char * const comparison_strings[] =
2858 "==", /* GCC_JIT_COMPARISON_EQ */
2859 "!=", /* GCC_JIT_COMPARISON_NE */
2860 "<", /* GCC_JIT_COMPARISON_LT */
2861 "<=", /* GCC_JIT_COMPARISON_LE */
2862 ">", /* GCC_JIT_COMPARISON_GT */
2863 ">=", /* GCC_JIT_COMPARISON_GE */
2866 recording::string *
2867 recording::comparison::make_debug_string ()
2869 return string::from_printf (m_ctxt,
2870 "%s %s %s",
2871 m_a->get_debug_string (),
2872 comparison_strings[m_op],
2873 m_b->get_debug_string ());
2876 /* Implementation of pure virtual hook recording::memento::replay_into
2877 for recording::comparison. */
2879 void
2880 recording::comparison::replay_into (replayer *r)
2882 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2883 m_op,
2884 m_a->playback_rvalue (),
2885 m_b->playback_rvalue ()));
2888 /* Implementation of pure virtual hook recording::memento::replay_into
2889 for recording::cast. */
2891 void
2892 recording::cast::replay_into (replayer *r)
2894 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2895 m_rvalue->playback_rvalue (),
2896 get_type ()->playback_type ()));
2899 /* Implementation of recording::memento::make_debug_string for
2900 casts. */
2902 recording::string *
2903 recording::cast::make_debug_string ()
2905 return string::from_printf (m_ctxt,
2906 "(%s)%s",
2907 get_type ()->get_debug_string (),
2908 m_rvalue->get_debug_string ());
2911 /* The implementation of class gcc::jit::recording::call. */
2913 /* The constructor for gcc::jit::recording::call. */
2915 recording::call::call (recording::context *ctxt,
2916 recording::location *loc,
2917 recording::function *func,
2918 int numargs,
2919 rvalue **args)
2920 : rvalue (ctxt, loc, func->get_return_type ()),
2921 m_func (func),
2922 m_args ()
2924 for (int i = 0; i< numargs; i++)
2925 m_args.safe_push (args[i]);
2928 /* Implementation of pure virtual hook recording::memento::replay_into
2929 for recording::call. */
2931 void
2932 recording::call::replay_into (replayer *r)
2934 auto_vec<playback::rvalue *> playback_args;
2935 playback_args.create (m_args.length ());
2936 for (unsigned i = 0; i< m_args.length (); i++)
2937 playback_args.safe_push (m_args[i]->playback_rvalue ());
2939 set_playback_obj (r->new_call (playback_location (r, m_loc),
2940 m_func->playback_function (),
2941 &playback_args));
2944 /* Implementation of recording::memento::make_debug_string for
2945 function calls. */
2947 recording::string *
2948 recording::call::make_debug_string ()
2950 /* First, build a buffer for the arguments. */
2951 /* Calculate length of said buffer. */
2952 size_t sz = 1; /* nil terminator */
2953 for (unsigned i = 0; i< m_args.length (); i++)
2955 sz += strlen (m_args[i]->get_debug_string ());
2956 sz += 2; /* ", " separator */
2959 /* Now allocate and populate the buffer. */
2960 char *argbuf = new char[sz];
2961 size_t len = 0;
2963 for (unsigned i = 0; i< m_args.length (); i++)
2965 strcpy (argbuf + len, m_args[i]->get_debug_string ());
2966 len += strlen (m_args[i]->get_debug_string ());
2967 if (i + 1 < m_args.length ())
2969 strcpy (argbuf + len, ", ");
2970 len += 2;
2973 argbuf[len] = '\0';
2975 /* ...and use it to get the string for the call as a whole. */
2976 string *result = string::from_printf (m_ctxt,
2977 "%s (%s)",
2978 m_func->get_debug_string (),
2979 argbuf);
2981 delete[] argbuf;
2983 return result;
2986 /* The implementation of class gcc::jit::recording::call_through_ptr. */
2988 /* The constructor for recording::call_through_ptr. */
2990 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
2991 recording::location *loc,
2992 recording::rvalue *fn_ptr,
2993 int numargs,
2994 rvalue **args)
2995 : rvalue (ctxt, loc,
2996 fn_ptr->get_type ()->dereference ()
2997 ->as_a_function_type ()->get_return_type ()),
2998 m_fn_ptr (fn_ptr),
2999 m_args ()
3001 for (int i = 0; i< numargs; i++)
3002 m_args.safe_push (args[i]);
3005 /* Implementation of pure virtual hook recording::memento::replay_into
3006 for recording::call_through_ptr. */
3008 void
3009 recording::call_through_ptr::replay_into (replayer *r)
3011 auto_vec<playback::rvalue *> playback_args;
3012 playback_args.create (m_args.length ());
3013 for (unsigned i = 0; i< m_args.length (); i++)
3014 playback_args.safe_push (m_args[i]->playback_rvalue ());
3016 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
3017 m_fn_ptr->playback_rvalue (),
3018 &playback_args));
3021 /* Implementation of recording::memento::make_debug_string for
3022 calls through function ptrs. */
3024 recording::string *
3025 recording::call_through_ptr::make_debug_string ()
3027 /* First, build a buffer for the arguments. */
3028 /* Calculate length of said buffer. */
3029 size_t sz = 1; /* nil terminator */
3030 for (unsigned i = 0; i< m_args.length (); i++)
3032 sz += strlen (m_args[i]->get_debug_string ());
3033 sz += 2; /* ", " separator */
3036 /* Now allocate and populate the buffer. */
3037 char *argbuf = new char[sz];
3038 size_t len = 0;
3040 for (unsigned i = 0; i< m_args.length (); i++)
3042 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3043 len += strlen (m_args[i]->get_debug_string ());
3044 if (i + 1 < m_args.length ())
3046 strcpy (argbuf + len, ", ");
3047 len += 2;
3050 argbuf[len] = '\0';
3052 /* ...and use it to get the string for the call as a whole. */
3053 string *result = string::from_printf (m_ctxt,
3054 "%s (%s)",
3055 m_fn_ptr->get_debug_string (),
3056 argbuf);
3058 delete[] argbuf;
3060 return result;
3063 /* The implementation of class gcc::jit::recording::array_access. */
3065 /* Implementation of pure virtual hook recording::memento::replay_into
3066 for recording::array_access. */
3068 void
3069 recording::array_access::replay_into (replayer *r)
3071 set_playback_obj (
3072 r->new_array_access (playback_location (r, m_loc),
3073 m_ptr->playback_rvalue (),
3074 m_index->playback_rvalue ()));
3077 /* Implementation of recording::memento::make_debug_string for
3078 array accesses. */
3080 recording::string *
3081 recording::array_access::make_debug_string ()
3083 return string::from_printf (m_ctxt,
3084 "%s[%s]",
3085 m_ptr->get_debug_string (),
3086 m_index->get_debug_string ());
3089 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3091 /* Implementation of pure virtual hook recording::memento::replay_into
3092 for recording::access_field_of_lvalue. */
3094 void
3095 recording::access_field_of_lvalue::replay_into (replayer *r)
3097 set_playback_obj (
3098 m_lvalue->playback_lvalue ()
3099 ->access_field (playback_location (r, m_loc),
3100 m_field->playback_field ()));
3104 /* Implementation of recording::memento::make_debug_string for
3105 accessing a field of an lvalue. */
3107 recording::string *
3108 recording::access_field_of_lvalue::make_debug_string ()
3110 return string::from_printf (m_ctxt,
3111 "%s.%s",
3112 m_lvalue->get_debug_string (),
3113 m_field->get_debug_string ());
3116 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3118 /* Implementation of pure virtual hook recording::memento::replay_into
3119 for recording::access_field_rvalue. */
3121 void
3122 recording::access_field_rvalue::replay_into (replayer *r)
3124 set_playback_obj (
3125 m_rvalue->playback_rvalue ()
3126 ->access_field (playback_location (r, m_loc),
3127 m_field->playback_field ()));
3130 /* Implementation of recording::memento::make_debug_string for
3131 accessing a field of an rvalue. */
3133 recording::string *
3134 recording::access_field_rvalue::make_debug_string ()
3136 return string::from_printf (m_ctxt,
3137 "%s.%s",
3138 m_rvalue->get_debug_string (),
3139 m_field->get_debug_string ());
3142 /* The implementation of class
3143 gcc::jit::recording::dereference_field_rvalue. */
3145 /* Implementation of pure virtual hook recording::memento::replay_into
3146 for recording::dereference_field_rvalue. */
3148 void
3149 recording::dereference_field_rvalue::replay_into (replayer *r)
3151 set_playback_obj (
3152 m_rvalue->playback_rvalue ()->
3153 dereference_field (playback_location (r, m_loc),
3154 m_field->playback_field ()));
3157 /* Implementation of recording::memento::make_debug_string for
3158 dereferencing a field of an rvalue. */
3160 recording::string *
3161 recording::dereference_field_rvalue::make_debug_string ()
3163 return string::from_printf (m_ctxt,
3164 "%s->%s",
3165 m_rvalue->get_debug_string (),
3166 m_field->get_debug_string ());
3169 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3171 /* Implementation of pure virtual hook recording::memento::replay_into
3172 for recording::dereference_rvalue. */
3174 void
3175 recording::dereference_rvalue::replay_into (replayer *r)
3177 set_playback_obj (
3178 m_rvalue->playback_rvalue ()->
3179 dereference (playback_location (r, m_loc)));
3182 /* Implementation of recording::memento::make_debug_string for
3183 dereferencing an rvalue. */
3185 recording::string *
3186 recording::dereference_rvalue::make_debug_string ()
3188 return string::from_printf (m_ctxt,
3189 "*%s",
3190 m_rvalue->get_debug_string ());
3193 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3195 /* Implementation of pure virtual hook recording::memento::replay_into
3196 for recording::get_address_of_lvalue. */
3198 void
3199 recording::get_address_of_lvalue::replay_into (replayer *r)
3201 set_playback_obj (
3202 m_lvalue->playback_lvalue ()->
3203 get_address (playback_location (r, m_loc)));
3206 /* Implementation of recording::memento::make_debug_string for
3207 getting the address of an lvalue. */
3209 recording::string *
3210 recording::get_address_of_lvalue::make_debug_string ()
3212 return string::from_printf (m_ctxt,
3213 "&%s",
3214 m_lvalue->get_debug_string ());
3217 /* The implementation of class gcc::jit::recording::local. */
3219 /* Implementation of pure virtual hook recording::memento::replay_into
3220 for recording::local. */
3222 void
3223 recording::local::replay_into (replayer *r)
3225 set_playback_obj (
3226 m_func->playback_function ()
3227 ->new_local (playback_location (r, m_loc),
3228 m_type->playback_type (),
3229 playback_string (m_name)));
3232 /* Override the default implementation of
3233 recording::memento::write_to_dump for locals by writing
3234 TYPE NAME;
3235 for use at the top of the function body as if it were a
3236 declaration. */
3238 void
3239 recording::local::write_to_dump (dump &d)
3241 if (d.update_locations ())
3242 m_loc = d.make_location ();
3243 d.write(" %s %s;\n",
3244 m_type->get_debug_string (),
3245 get_debug_string ());
3248 /* The implementation of class gcc::jit::recording::statement. */
3250 /* We poison the default implementation of
3251 gcc::jit::recording::statement::get_successor_blocks
3252 since this vfunc must only ever be called on terminator
3253 statements. */
3256 recording::statement::get_successor_blocks (block **/*out_next1*/,
3257 block **/*out_next2*/) const
3259 /* The base class implementation is for non-terminating statements,
3260 and thus should never be called. */
3261 gcc_unreachable ();
3262 return 0;
3265 /* Extend the default implementation of
3266 recording::memento::write_to_dump for statements by (if requested)
3267 updating the location of the statement to the current location in
3268 the dumpfile. */
3270 void
3271 recording::statement::write_to_dump (dump &d)
3273 memento::write_to_dump (d);
3274 if (d.update_locations ())
3275 m_loc = d.make_location ();
3278 /* The implementation of class gcc::jit::recording::eval. */
3280 /* Implementation of pure virtual hook recording::memento::replay_into
3281 for recording::eval. */
3283 void
3284 recording::eval::replay_into (replayer *r)
3286 playback_block (get_block ())
3287 ->add_eval (playback_location (r),
3288 m_rvalue->playback_rvalue ());
3291 /* Implementation of recording::memento::make_debug_string for
3292 an eval statement. */
3294 recording::string *
3295 recording::eval::make_debug_string ()
3297 return string::from_printf (m_ctxt,
3298 "(void)%s;",
3299 m_rvalue->get_debug_string ());
3302 /* The implementation of class gcc::jit::recording::assignment. */
3304 /* Implementation of pure virtual hook recording::memento::replay_into
3305 for recording::assignment. */
3307 void
3308 recording::assignment::replay_into (replayer *r)
3310 playback_block (get_block ())
3311 ->add_assignment (playback_location (r),
3312 m_lvalue->playback_lvalue (),
3313 m_rvalue->playback_rvalue ());
3316 /* Implementation of recording::memento::make_debug_string for
3317 an assignment statement. */
3319 recording::string *
3320 recording::assignment::make_debug_string ()
3322 return string::from_printf (m_ctxt,
3323 "%s = %s;",
3324 m_lvalue->get_debug_string (),
3325 m_rvalue->get_debug_string ());
3328 /* The implementation of class gcc::jit::recording::assignment_op. */
3330 /* Implementation of pure virtual hook recording::memento::replay_into
3331 for recording::assignment_op. */
3333 void
3334 recording::assignment_op::replay_into (replayer *r)
3336 playback::type *result_type =
3337 m_lvalue->playback_lvalue ()->get_type ();
3339 playback::rvalue *binary_op =
3340 r->new_binary_op (playback_location (r),
3341 m_op,
3342 result_type,
3343 m_lvalue->playback_rvalue (),
3344 m_rvalue->playback_rvalue ());
3346 playback_block (get_block ())
3347 ->add_assignment (playback_location (r),
3348 m_lvalue->playback_lvalue (),
3349 binary_op);
3352 /* Implementation of recording::memento::make_debug_string for
3353 an assignment_op statement. */
3355 recording::string *
3356 recording::assignment_op::make_debug_string ()
3358 return string::from_printf (m_ctxt,
3359 "%s %s= %s;",
3360 m_lvalue->get_debug_string (),
3361 binary_op_strings[m_op],
3362 m_rvalue->get_debug_string ());
3365 /* The implementation of class gcc::jit::recording::comment. */
3367 /* Implementation of pure virtual hook recording::memento::replay_into
3368 for recording::comment. */
3370 void
3371 recording::comment::replay_into (replayer *r)
3373 playback_block (get_block ())
3374 ->add_comment (playback_location (r),
3375 m_text->c_str ());
3378 /* Implementation of recording::memento::make_debug_string for
3379 a comment "statement". */
3381 recording::string *
3382 recording::comment::make_debug_string ()
3384 return string::from_printf (m_ctxt,
3385 "/* %s */",
3386 m_text->c_str ());
3389 /* The implementation of class gcc::jit::recording::conditional. */
3391 /* Implementation of pure virtual hook recording::memento::replay_into
3392 for recording::conditional. */
3394 void
3395 recording::conditional::replay_into (replayer *r)
3397 playback_block (get_block ())
3398 ->add_conditional (playback_location (r),
3399 m_boolval->playback_rvalue (),
3400 playback_block (m_on_true),
3401 playback_block (m_on_false));
3404 /* Override the poisoned default implementation of
3405 gcc::jit::recording::statement::get_successor_blocks
3407 A conditional jump has 2 successor blocks. */
3410 recording::conditional::get_successor_blocks (block **out_next1,
3411 block **out_next2) const
3413 *out_next1 = m_on_true;
3414 *out_next2 = m_on_false;
3415 return 2;
3418 /* Implementation of recording::memento::make_debug_string for
3419 a conditional jump statement. */
3421 recording::string *
3422 recording::conditional::make_debug_string ()
3424 if (m_on_false)
3425 return string::from_printf (m_ctxt,
3426 "if (%s) goto %s; else goto %s;",
3427 m_boolval->get_debug_string (),
3428 m_on_true->get_debug_string (),
3429 m_on_false->get_debug_string ());
3430 else
3431 return string::from_printf (m_ctxt,
3432 "if (%s) goto %s;",
3433 m_boolval->get_debug_string (),
3434 m_on_true->get_debug_string ());
3437 /* The implementation of class gcc::jit::recording::jump. */
3439 /* Implementation of pure virtual hook recording::memento::replay_into
3440 for recording::jump. */
3442 void
3443 recording::jump::replay_into (replayer *r)
3445 playback_block (get_block ())
3446 ->add_jump (playback_location (r),
3447 m_target->playback_block ());
3450 /* Override the poisoned default implementation of
3451 gcc::jit::recording::statement::get_successor_blocks
3453 An unconditional jump has 1 successor block. */
3456 recording::jump::get_successor_blocks (block **out_next1,
3457 block **/*out_next2*/) const
3459 *out_next1 = m_target;
3460 return 1;
3463 /* Implementation of recording::memento::make_debug_string for
3464 a unconditional jump statement. */
3466 recording::string *
3467 recording::jump::make_debug_string ()
3469 return string::from_printf (m_ctxt,
3470 "goto %s;",
3471 m_target->get_debug_string ());
3474 /* The implementation of class gcc::jit::recording::return_. */
3476 /* Implementation of pure virtual hook recording::memento::replay_into
3477 for recording::return_. */
3479 void
3480 recording::return_::replay_into (replayer *r)
3482 playback_block (get_block ())
3483 ->add_return (playback_location (r),
3484 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3487 /* Override the poisoned default implementation of
3488 gcc::jit::recording::statement::get_successor_blocks
3490 A return statement has no successor block. */
3493 recording::return_::get_successor_blocks (block **/*out_next1*/,
3494 block **/*out_next2*/) const
3496 return 0;
3499 /* Implementation of recording::memento::make_debug_string for
3500 a return statement (covers both those with and without rvalues). */
3502 recording::string *
3503 recording::return_::make_debug_string ()
3505 if (m_rvalue)
3506 return string::from_printf (m_ctxt,
3507 "return %s;",
3508 m_rvalue->get_debug_string ());
3509 else
3510 return string::from_printf (m_ctxt,
3511 "return;");
3514 } // namespace gcc::jit
3516 } // namespace gcc