PR jit/64020: Fixes to handling of builtins
[official-gcc.git] / gcc / jit / jit-recording.c
blob82ec399f0b8faf81b118edd3e9f0955265264d8a
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 if (m_builtins_manager)
219 delete m_builtins_manager;
221 if (m_owns_first_error_str)
222 free (m_first_error_str);
225 /* Add the given mememto to the list of those tracked by this
226 gcc::jit::recording::context, so that e.g. it can be deleted
227 when this context is released. */
229 void
230 recording::context::record (memento *m)
232 gcc_assert (m);
234 m_mementos.safe_push (m);
237 /* Replay this context (and any parents) into the given replayer. */
239 void
240 recording::context::replay_into (replayer *r)
242 int i;
243 memento *m;
245 /* If we have a parent context, we must replay it. This will
246 recursively walk backwards up the historical tree, then replay things
247 forwards "in historical order", starting with the ultimate parent
248 context, until we reach the "this" context.
250 Note that we fully replay the parent, then fully replay the child,
251 which means that inter-context references can only exist from child
252 to parent, not the other way around.
254 All of this replaying is suboptimal - it would be better to do the
255 work for the parent context *once*, rather than replaying the parent
256 every time we replay each child. However, fixing this requires deep
257 surgery to lifetime-management: we'd need every context family tree
258 to have its own GC heap, and to initialize the GCC code to use that
259 heap (with a mutex on such a heap). */
260 if (m_parent_ctxt)
261 m_parent_ctxt->replay_into (r);
263 if (r->errors_occurred ())
264 return;
266 /* Replay this context's saved operations into r. */
267 FOR_EACH_VEC_ELT (m_mementos, i, m)
269 /* Disabled low-level debugging, here if we need it: print what
270 we're replaying.
271 Note that the calls to get_debug_string might lead to more
272 mementos being created for the strings.
273 This can also be used to exercise the debug_string
274 machinery. */
275 if (0)
276 printf ("context %p replaying (%p): %s\n",
277 (void *)this, (void *)m, m->get_debug_string ());
279 m->replay_into (r);
281 if (r->errors_occurred ())
282 return;
286 /* During a playback, we associate objects from the recording with
287 their counterparts during this playback.
289 For simplicity, we store this within the recording objects.
291 The following method cleans away these associations, to ensure that
292 we never have out-of-date associations lingering on subsequent
293 playbacks (the objects pointed to are GC-managed, but the
294 recording objects don't own refs to them). */
296 void
297 recording::context::disassociate_from_playback ()
299 int i;
300 memento *m;
302 if (m_parent_ctxt)
303 m_parent_ctxt->disassociate_from_playback ();
305 FOR_EACH_VEC_ELT (m_mementos, i, m)
307 m->set_playback_obj (NULL);
311 /* Create a recording::string instance and add it to this context's list
312 of mementos.
314 This creates a fresh copy of the given 0-terminated buffer. */
316 recording::string *
317 recording::context::new_string (const char *text)
319 if (!text)
320 return NULL;
322 recording::string *result = new string (this, text);
323 record (result);
324 return result;
327 /* Create a recording::location instance and add it to this context's
328 list of mementos.
330 Implements the post-error-checking part of
331 gcc_jit_context_new_location. */
333 recording::location *
334 recording::context::new_location (const char *filename,
335 int line,
336 int column)
338 recording::location *result =
339 new recording::location (this,
340 new_string (filename),
341 line, column);
342 record (result);
343 return result;
346 /* If we haven't seen this enum value yet, create a recording::type
347 instance and add it to this context's list of mementos.
349 If we have seen it before, reuse our cached value, so that repeated
350 calls on the context give the same object.
352 If we have a parent context, the cache is within the ultimate
353 ancestor context.
355 Implements the post-error-checking part of
356 gcc_jit_context_get_type. */
358 recording::type *
359 recording::context::get_type (enum gcc_jit_types kind)
361 if (!m_basic_types[kind])
363 if (m_parent_ctxt)
364 m_basic_types[kind] = m_parent_ctxt->get_type (kind);
365 else
367 recording::type *result = new memento_of_get_type (this, kind);
368 record (result);
369 m_basic_types[kind] = result;
373 return m_basic_types[kind];
376 /* Get a recording::type instance for the given size and signedness.
377 This is implemented in terms of recording::context::get_type
378 above.
380 Implements the post-error-checking part of
381 gcc_jit_context_get_int_type. */
383 recording::type *
384 recording::context::get_int_type (int num_bytes, int is_signed)
386 /* We can't use a switch here since some of the values are macros affected
387 by options; e.g. i386.h has
388 #define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD)
389 Compare with tree.c's make_or_reuse_type. Note that the _SIZE macros
390 are in bits, rather than bytes.
392 const int num_bits = num_bytes * 8;
393 if (num_bits == INT_TYPE_SIZE)
394 return get_type (is_signed
395 ? GCC_JIT_TYPE_INT
396 : GCC_JIT_TYPE_UNSIGNED_INT);
397 if (num_bits == CHAR_TYPE_SIZE)
398 return get_type (is_signed
399 ? GCC_JIT_TYPE_SIGNED_CHAR
400 : GCC_JIT_TYPE_UNSIGNED_CHAR);
401 if (num_bits == SHORT_TYPE_SIZE)
402 return get_type (is_signed
403 ? GCC_JIT_TYPE_SHORT
404 : GCC_JIT_TYPE_UNSIGNED_SHORT);
405 if (num_bits == LONG_TYPE_SIZE)
406 return get_type (is_signed
407 ? GCC_JIT_TYPE_LONG
408 : GCC_JIT_TYPE_UNSIGNED_LONG);
409 if (num_bits == LONG_LONG_TYPE_SIZE)
410 return get_type (is_signed
411 ? GCC_JIT_TYPE_LONG_LONG
412 : GCC_JIT_TYPE_UNSIGNED_LONG_LONG);
414 /* Some other size, not corresponding to the C int types. */
415 /* To be written: support arbitrary other sizes, sharing by
416 memoizing at the recording::context level? */
417 gcc_unreachable ();
420 /* Create a recording::type instance and add it to this context's list
421 of mementos.
423 Implements the post-error-checking part of
424 gcc_jit_context_new_array_type. */
426 recording::type *
427 recording::context::new_array_type (recording::location *loc,
428 recording::type *element_type,
429 int num_elements)
431 if (struct_ *s = element_type->dyn_cast_struct ())
432 if (!s->get_fields ())
434 add_error (NULL,
435 "cannot create an array of type %s"
436 " until the fields have been set",
437 s->get_name ()->c_str ());
438 return NULL;
440 recording::type *result =
441 new recording::array_type (this, loc, element_type, num_elements);
442 record (result);
443 return result;
446 /* Create a recording::field instance and add it to this context's list
447 of mementos.
449 Implements the post-error-checking part of
450 gcc_jit_context_new_field. */
452 recording::field *
453 recording::context::new_field (recording::location *loc,
454 recording::type *type,
455 const char *name)
457 recording::field *result =
458 new recording::field (this, loc, type, new_string (name));
459 record (result);
460 return result;
463 /* Create a recording::struct_ instance and add it to this context's
464 list of mementos and list of compound types.
466 Implements the post-error-checking part of
467 gcc_jit_context_new_struct_type. */
469 recording::struct_ *
470 recording::context::new_struct_type (recording::location *loc,
471 const char *name)
473 recording::struct_ *result = new struct_ (this, loc, new_string (name));
474 record (result);
475 m_compound_types.safe_push (result);
476 return result;
479 /* Create a recording::union_ instance and add it to this context's
480 list of mementos and list of compound types.
482 Implements the first post-error-checking part of
483 gcc_jit_context_new_union_type. */
485 recording::union_ *
486 recording::context::new_union_type (recording::location *loc,
487 const char *name)
489 recording::union_ *result = new union_ (this, loc, new_string (name));
490 record (result);
491 m_compound_types.safe_push (result);
492 return result;
495 /* Create a recording::function_type instance and add it to this context's
496 list of mementos.
498 Used by new_function_ptr_type and by builtins_manager::make_fn_type. */
500 recording::function_type *
501 recording::context::new_function_type (recording::type *return_type,
502 int num_params,
503 recording::type **param_types,
504 int is_variadic)
506 recording::function_type *fn_type
507 = new function_type (this,
508 return_type,
509 num_params,
510 param_types,
511 is_variadic);
512 record (fn_type);
513 return fn_type;
516 /* Create a recording::type instance and add it to this context's list
517 of mementos.
519 Implements the post-error-checking part of
520 gcc_jit_context_new_function_ptr_type. */
522 recording::type *
523 recording::context::new_function_ptr_type (recording::location *, /* unused loc */
524 recording::type *return_type,
525 int num_params,
526 recording::type **param_types,
527 int is_variadic)
529 recording::function_type *fn_type
530 = new_function_type (return_type,
531 num_params,
532 param_types,
533 is_variadic);
535 /* Return a pointer-type to the the function type. */
536 return fn_type->get_pointer ();
539 /* Create a recording::param instance and add it to this context's list
540 of mementos.
542 Implements the post-error-checking part of
543 gcc_jit_context_new_param. */
545 recording::param *
546 recording::context::new_param (recording::location *loc,
547 recording::type *type,
548 const char *name)
550 recording::param *result = new recording::param (this, loc, type, new_string (name));
551 record (result);
552 return result;
555 /* Create a recording::function instance and add it to this context's list
556 of mementos and list of functions.
558 Implements the post-error-checking part of
559 gcc_jit_context_new_function. */
561 recording::function *
562 recording::context::new_function (recording::location *loc,
563 enum gcc_jit_function_kind kind,
564 recording::type *return_type,
565 const char *name,
566 int num_params,
567 recording::param **params,
568 int is_variadic,
569 enum built_in_function builtin_id)
571 recording::function *result =
572 new recording::function (this,
573 loc, kind, return_type,
574 new_string (name),
575 num_params, params, is_variadic,
576 builtin_id);
577 record (result);
578 m_functions.safe_push (result);
580 return result;
583 /* Locate the builtins_manager (if any) for this family of contexts,
584 creating it if it doesn't exist already.
586 All of the recording contexts in a family share one builtins_manager:
587 if we have a child context, follow the parent links to get the
588 ultimate ancestor context, and look for it/store it there. */
590 builtins_manager *
591 recording::context::get_builtins_manager ()
593 if (m_parent_ctxt)
594 return m_parent_ctxt->get_builtins_manager ();
596 if (!m_builtins_manager)
597 m_builtins_manager = new builtins_manager (this);
599 return m_builtins_manager;
602 /* Get a recording::function instance, which is lazily-created and added
603 to the context's lists of mementos.
605 Implements the post-error-checking part of
606 gcc_jit_context_get_builtin_function. */
608 recording::function *
609 recording::context::get_builtin_function (const char *name)
611 builtins_manager *bm = get_builtins_manager ();
612 return bm->get_builtin_function (name);
615 /* Create a recording::global instance and add it to this context's list
616 of mementos.
618 Implements the post-error-checking part of
619 gcc_jit_context_new_global. */
621 recording::lvalue *
622 recording::context::new_global (recording::location *loc,
623 recording::type *type,
624 const char *name)
626 recording::lvalue *result =
627 new recording::global (this, loc, type, new_string (name));
628 record (result);
629 return result;
632 /* Create a recording::memento_of_new_rvalue_from_int instance and add
633 it to this context's list of mementos.
635 Implements the post-error-checking part of
636 gcc_jit_context_new_rvalue_from_int. */
638 recording::rvalue *
639 recording::context::new_rvalue_from_int (recording::type *type,
640 int value)
642 recording::rvalue *result =
643 new memento_of_new_rvalue_from_int (this, NULL, type, value);
644 record (result);
645 return result;
648 /* Create a recording::memento_of_new_rvalue_from_double instance and
649 add it to this context's list of mementos.
651 Implements the post-error-checking part of
652 gcc_jit_context_new_rvalue_from_double. */
654 recording::rvalue *
655 recording::context::new_rvalue_from_double (recording::type *type,
656 double value)
658 recording::rvalue *result =
659 new memento_of_new_rvalue_from_double (this, NULL, type, value);
660 record (result);
661 return result;
664 /* Create a recording::memento_of_new_rvalue_from_ptr instance and add
665 it to this context's list of mementos.
667 Implements the post-error-checking part of
668 gcc_jit_context_new_rvalue_from_ptr. */
670 recording::rvalue *
671 recording::context::new_rvalue_from_ptr (recording::type *type,
672 void *value)
674 recording::rvalue *result =
675 new memento_of_new_rvalue_from_ptr (this, NULL, type, value);
676 record (result);
677 return result;
680 /* Create a recording::memento_of_new_string_literal instance and add it
681 to this context's list of mementos.
683 Implements the post-error-checking part of
684 gcc_jit_context_new_string_literal. */
686 recording::rvalue *
687 recording::context::new_string_literal (const char *value)
689 recording::rvalue *result =
690 new memento_of_new_string_literal (this, NULL, new_string (value));
691 record (result);
692 return result;
695 /* Create a recording::unary_op instance and add it to this context's
696 list of mementos.
698 Implements the post-error-checking part of
699 gcc_jit_context_new_unary_op. */
701 recording::rvalue *
702 recording::context::new_unary_op (recording::location *loc,
703 enum gcc_jit_unary_op op,
704 recording::type *result_type,
705 recording::rvalue *a)
707 recording::rvalue *result =
708 new unary_op (this, loc, op, result_type, a);
709 record (result);
710 return result;
713 /* Create a recording::binary_op instance and add it to this context's
714 list of mementos.
716 Implements the post-error-checking part of
717 gcc_jit_context_new_binary_op. */
719 recording::rvalue *
720 recording::context::new_binary_op (recording::location *loc,
721 enum gcc_jit_binary_op op,
722 recording::type *result_type,
723 recording::rvalue *a,
724 recording::rvalue *b)
726 recording::rvalue *result =
727 new binary_op (this, loc, op, result_type, a, b);
728 record (result);
729 return result;
732 /* Create a recording::comparison instance and add it to this context's
733 list of mementos.
735 Implements the post-error-checking part of
736 gcc_jit_context_new_comparison. */
738 recording::rvalue *
739 recording::context::new_comparison (recording::location *loc,
740 enum gcc_jit_comparison op,
741 recording::rvalue *a,
742 recording::rvalue *b)
744 recording::rvalue *result = new comparison (this, loc, op, a, b);
745 record (result);
746 return result;
749 /* Create a recording::cast instance and add it to this context's list
750 of mementos.
752 Implements the post-error-checking part of
753 gcc_jit_context_new_cast. */
755 recording::rvalue *
756 recording::context::new_cast (recording::location *loc,
757 recording::rvalue *expr,
758 recording::type *type_)
760 recording::rvalue *result = new cast (this, loc, expr, type_);
761 record (result);
762 return result;
765 /* Create a recording::call instance and add it to this context's list
766 of mementos.
768 Implements the post-error-checking part of
769 gcc_jit_context_new_call. */
771 recording::rvalue *
772 recording::context::new_call (recording::location *loc,
773 function *func,
774 int numargs , recording::rvalue **args)
776 recording::rvalue *result = new call (this, loc, func, numargs, args);
777 record (result);
778 return result;
781 /* Create a recording::call_through_ptr instance and add it to this
782 context's list of mementos.
784 Implements the post-error-checking part of
785 gcc_jit_context_new_call_through_ptr. */
787 recording::rvalue *
788 recording::context::new_call_through_ptr (recording::location *loc,
789 recording::rvalue *fn_ptr,
790 int numargs,
791 recording::rvalue **args)
793 recording::rvalue *result = new call_through_ptr (this, loc, fn_ptr, numargs, args);
794 record (result);
795 return result;
798 /* Create a recording::array_access instance and add it to this context's list
799 of mementos.
801 Implements the post-error-checking part of
802 gcc_jit_context_new_array_access. */
804 recording::lvalue *
805 recording::context::new_array_access (recording::location *loc,
806 recording::rvalue *ptr,
807 recording::rvalue *index)
809 recording::lvalue *result = new array_access (this, loc, ptr, index);
810 record (result);
811 return result;
814 /* Set the given string option for this context, or add an error if
815 it's not recognized.
817 Implements the post-error-checking part of
818 gcc_jit_context_set_str_option. */
820 void
821 recording::context::set_str_option (enum gcc_jit_str_option opt,
822 const char *value)
824 if (opt < 0 || opt >= GCC_JIT_NUM_STR_OPTIONS)
826 add_error (NULL,
827 "unrecognized (enum gcc_jit_str_option) value: %i", opt);
828 return;
830 m_str_options[opt] = value;
833 /* Set the given integer option for this context, or add an error if
834 it's not recognized.
836 Implements the post-error-checking part of
837 gcc_jit_context_set_int_option. */
839 void
840 recording::context::set_int_option (enum gcc_jit_int_option opt,
841 int value)
843 if (opt < 0 || opt >= GCC_JIT_NUM_INT_OPTIONS)
845 add_error (NULL,
846 "unrecognized (enum gcc_jit_int_option) value: %i", opt);
847 return;
849 m_int_options[opt] = value;
852 /* Set the given boolean option for this context, or add an error if
853 it's not recognized.
855 Implements the post-error-checking part of
856 gcc_jit_context_set_bool_option. */
858 void
859 recording::context::set_bool_option (enum gcc_jit_bool_option opt,
860 int value)
862 if (opt < 0 || opt >= GCC_JIT_NUM_BOOL_OPTIONS)
864 add_error (NULL,
865 "unrecognized (enum gcc_jit_bool_option) value: %i", opt);
866 return;
868 m_bool_options[opt] = value ? true : false;
871 /* This mutex guards gcc::jit::recording::context::compile, so that only
872 one thread can be accessing the bulk of GCC's state at once. */
874 static pthread_mutex_t jit_mutex = PTHREAD_MUTEX_INITIALIZER;
876 /* Validate this context, and if it passes, compile it within a
877 mutex.
879 Implements the post-error-checking part of
880 gcc_jit_context_compile. */
882 result *
883 recording::context::compile ()
885 validate ();
887 if (errors_occurred ())
888 return NULL;
890 /* Acquire the big GCC mutex. */
891 pthread_mutex_lock (&jit_mutex);
892 gcc_assert (NULL == ::gcc::jit::active_playback_ctxt);
894 /* Set up a playback context. */
895 ::gcc::jit::playback::context replayer (this);
896 ::gcc::jit::active_playback_ctxt = &replayer;
898 result *result_obj = replayer.compile ();
900 /* Release the big GCC mutex. */
901 ::gcc::jit::active_playback_ctxt = NULL;
902 pthread_mutex_unlock (&jit_mutex);
904 return result_obj;
907 /* Format the given error using printf's conventions, print
908 it to stderr, and add it to the context. */
910 void
911 recording::context::add_error (location *loc, const char *fmt, ...)
913 va_list ap;
914 va_start (ap, fmt);
915 add_error_va (loc, fmt, ap);
916 va_end (ap);
919 /* Format the given error using printf's conventions, print
920 it to stderr, and add it to the context. */
922 void
923 recording::context::add_error_va (location *loc, const char *fmt, va_list ap)
925 char *malloced_msg;
926 const char *errmsg;
927 bool has_ownership;
929 vasprintf (&malloced_msg, fmt, ap);
930 if (malloced_msg)
932 errmsg = malloced_msg;
933 has_ownership = true;
935 else
937 errmsg = "out of memory generating error message";
938 has_ownership = false;
941 const char *ctxt_progname =
942 get_str_option (GCC_JIT_STR_OPTION_PROGNAME);
943 if (!ctxt_progname)
944 ctxt_progname = "libgccjit.so";
946 if (loc)
947 fprintf (stderr, "%s: %s: error: %s\n",
948 ctxt_progname,
949 loc->get_debug_string (),
950 errmsg);
951 else
952 fprintf (stderr, "%s: error: %s\n",
953 ctxt_progname,
954 errmsg);
956 if (!m_error_count)
958 m_first_error_str = const_cast <char *> (errmsg);
959 m_owns_first_error_str = has_ownership;
961 else
962 if (has_ownership)
963 free (malloced_msg);
965 m_error_count++;
968 /* Get the message for the first error that occurred on this context, or
969 NULL if no errors have occurred on it.
971 Implements the post-error-checking part of
972 gcc_jit_context_get_first_error. */
974 const char *
975 recording::context::get_first_error () const
977 return m_first_error_str;
980 /* Lazily generate and record a recording::type representing an opaque
981 struct named "FILE".
983 For use if client code tries to dereference the result of
984 get_type (GCC_JIT_TYPE_FILE_PTR). */
986 recording::type *
987 recording::context::get_opaque_FILE_type ()
989 if (!m_FILE_type)
990 m_FILE_type = new_struct_type (NULL, "FILE");
991 return m_FILE_type;
994 /* Dump a C-like representation of the given context to the given path.
995 If UPDATE_LOCATIONS is true, update the locations within the
996 context's mementos to point to the dumpfile.
998 Implements the post-error-checking part of
999 gcc_jit_context_dump_to_file. */
1001 void
1002 recording::context::dump_to_file (const char *path, bool update_locations)
1004 int i;
1005 dump d (*this, path, update_locations);
1007 /* Forward declaration of structs and unions. */
1008 compound_type *st;
1009 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1011 d.write ("%s;\n\n", st->get_debug_string ());
1014 /* Content of structs, where set. */
1015 FOR_EACH_VEC_ELT (m_compound_types, i, st)
1016 if (st->get_fields ())
1018 st->get_fields ()->write_to_dump (d);
1019 d.write ("\n");
1022 function *fn;
1023 FOR_EACH_VEC_ELT (m_functions, i, fn)
1025 fn->write_to_dump (d);
1029 /* This is a pre-compilation check for the context (and any parents).
1031 Detect errors within the context, adding errors if any are found. */
1033 void
1034 recording::context::validate ()
1036 if (m_parent_ctxt)
1037 m_parent_ctxt->validate ();
1039 int i;
1040 function *fn;
1041 FOR_EACH_VEC_ELT (m_functions, i, fn)
1042 fn->validate ();
1045 /* The implementation of class gcc::jit::recording::memento. */
1047 /* Get a (const char *) debug description of the given memento, by
1048 calling the pure-virtual make_debug_string hook, caching the
1049 result.
1051 It is intended that this should only be called in debugging and
1052 error-handling paths, so this doesn't need to be particularly
1053 optimized. */
1055 const char *
1056 recording::memento::get_debug_string ()
1058 if (!m_debug_string)
1059 m_debug_string = make_debug_string ();
1060 return m_debug_string->c_str ();
1063 /* Default implementation of recording::memento::write_to_dump, writing
1064 an indented form of the memento's debug string to the dump. */
1066 void
1067 recording::memento::write_to_dump (dump &d)
1069 d.write(" %s\n", get_debug_string ());
1072 /* The implementation of class gcc::jit::recording::string. */
1074 /* Constructor for gcc::jit::recording::string::string, allocating a
1075 copy of the given text using new char[]. */
1077 recording::string::string (context *ctxt, const char *text)
1078 : memento (ctxt)
1080 m_len = strlen (text);
1081 m_buffer = new char[m_len + 1];
1082 strcpy (m_buffer, text);
1085 /* Destructor for gcc::jit::recording::string::string. */
1087 recording::string::~string ()
1089 delete[] m_buffer;
1092 /* Function for making gcc::jit::recording::string instances on a
1093 context via printf-style formatting.
1095 It is intended that this should only be called in debugging and
1096 error-handling paths, so this doesn't need to be particularly
1097 optimized, hence the double-copy of the string is acceptable. */
1099 recording::string *
1100 recording::string::from_printf (context *ctxt, const char *fmt, ...)
1102 va_list ap;
1103 char *buf = NULL;
1104 recording::string *result;
1106 va_start (ap, fmt);
1107 vasprintf (&buf, fmt, ap);
1108 va_end (ap);
1110 if (!buf)
1112 ctxt->add_error (NULL, "malloc failure");
1113 return NULL;
1116 result = ctxt->new_string (buf);
1117 free (buf);
1118 return result;
1121 /* Implementation of recording::memento::make_debug_string for strings,
1122 wrapping the given string in quotes and escaping as necessary. */
1124 recording::string *
1125 recording::string::make_debug_string ()
1127 /* Hack to avoid infinite recursion into strings when logging all
1128 mementos: don't re-escape strings: */
1129 if (m_buffer[0] == '"')
1130 return this;
1132 /* Wrap in quotes and do escaping etc */
1134 size_t sz = (1 /* opening quote */
1135 + (m_len * 2) /* each char might get escaped */
1136 + 1 /* closing quote */
1137 + 1); /* nil termintator */
1138 char *tmp = new char[sz];
1139 size_t len = 0;
1141 #define APPEND(CH) do { gcc_assert (len < sz); tmp[len++] = (CH); } while (0)
1142 APPEND('"'); /* opening quote */
1143 for (size_t i = 0; i < m_len ; i++)
1145 char ch = m_buffer[i];
1146 if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"')
1147 APPEND('\\');
1148 APPEND(ch);
1150 APPEND('"'); /* closing quote */
1151 #undef APPEND
1152 tmp[len] = '\0'; /* nil termintator */
1154 string *result = m_ctxt->new_string (tmp);
1156 delete[] tmp;
1157 return result;
1160 /* The implementation of class gcc::jit::recording::location. */
1162 /* Implementation of recording::memento::replay_into for locations.
1164 Create a new playback::location and store it into the
1165 recording::location's m_playback_obj field. */
1167 void
1168 recording::location::replay_into (replayer *r)
1170 m_playback_obj = r->new_location (this,
1171 m_filename->c_str (),
1172 m_line,
1173 m_column);
1176 /* Implementation of recording::memento::make_debug_string for locations,
1177 turning them into the usual form:
1178 FILENAME:LINE:COLUMN
1179 like we do when emitting diagnostics. */
1181 recording::string *
1182 recording::location::make_debug_string ()
1184 return string::from_printf (m_ctxt,
1185 "%s:%i:%i",
1186 m_filename->c_str (), m_line, m_column);
1189 /* The implementation of class gcc::jit::recording::type. */
1191 /* Given a type T, get the type T*.
1193 If this doesn't already exist, generate a new memento_of_get_pointer
1194 instance and add it to this type's context's list of mementos.
1196 Otherwise, use the cached type.
1198 Implements the post-error-checking part of
1199 gcc_jit_type_get_pointer. */
1201 recording::type *
1202 recording::type::get_pointer ()
1204 if (!m_pointer_to_this_type)
1206 m_pointer_to_this_type = new memento_of_get_pointer (this);
1207 m_ctxt->record (m_pointer_to_this_type);
1209 return m_pointer_to_this_type;
1212 /* Given a type T, get the type const T.
1214 Implements the post-error-checking part of
1215 gcc_jit_type_get_const. */
1217 recording::type *
1218 recording::type::get_const ()
1220 recording::type *result = new memento_of_get_const (this);
1221 m_ctxt->record (result);
1222 return result;
1225 /* Given a type T, get the type volatile T.
1227 Implements the post-error-checking part of
1228 gcc_jit_type_get_volatile. */
1230 recording::type *
1231 recording::type::get_volatile ()
1233 recording::type *result = new memento_of_get_volatile (this);
1234 m_ctxt->record (result);
1235 return result;
1238 /* Implementation of pure virtual hook recording::type::dereference for
1239 recording::memento_of_get_type. */
1241 recording::type *
1242 recording::memento_of_get_type::dereference ()
1244 switch (m_kind)
1246 default: gcc_unreachable ();
1248 case GCC_JIT_TYPE_VOID:
1249 return NULL;
1251 case GCC_JIT_TYPE_VOID_PTR:
1252 return m_ctxt->get_type (GCC_JIT_TYPE_VOID);
1254 case GCC_JIT_TYPE_BOOL:
1255 case GCC_JIT_TYPE_CHAR:
1256 case GCC_JIT_TYPE_SIGNED_CHAR:
1257 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1258 case GCC_JIT_TYPE_SHORT:
1259 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1260 case GCC_JIT_TYPE_INT:
1261 case GCC_JIT_TYPE_UNSIGNED_INT:
1262 case GCC_JIT_TYPE_LONG:
1263 case GCC_JIT_TYPE_UNSIGNED_LONG:
1264 case GCC_JIT_TYPE_LONG_LONG:
1265 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1266 case GCC_JIT_TYPE_FLOAT:
1267 case GCC_JIT_TYPE_DOUBLE:
1268 case GCC_JIT_TYPE_LONG_DOUBLE:
1269 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1270 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1271 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1272 /* Not a pointer: */
1273 return NULL;
1275 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1276 return m_ctxt->get_type (GCC_JIT_TYPE_CHAR)->get_const ();
1278 case GCC_JIT_TYPE_SIZE_T:
1279 /* Not a pointer: */
1280 return NULL;
1282 case GCC_JIT_TYPE_FILE_PTR:
1283 /* Give the client code back an opaque "struct FILE". */
1284 return m_ctxt->get_opaque_FILE_type ();
1288 /* Implementation of pure virtual hook recording::type::is_int for
1289 recording::memento_of_get_type. */
1291 bool
1292 recording::memento_of_get_type::is_int () const
1294 switch (m_kind)
1296 default: gcc_unreachable ();
1298 case GCC_JIT_TYPE_VOID:
1299 return false;
1301 case GCC_JIT_TYPE_VOID_PTR:
1302 return false;
1304 case GCC_JIT_TYPE_BOOL:
1305 return false;
1307 case GCC_JIT_TYPE_CHAR:
1308 case GCC_JIT_TYPE_SIGNED_CHAR:
1309 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1310 case GCC_JIT_TYPE_SHORT:
1311 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1312 case GCC_JIT_TYPE_INT:
1313 case GCC_JIT_TYPE_UNSIGNED_INT:
1314 case GCC_JIT_TYPE_LONG:
1315 case GCC_JIT_TYPE_UNSIGNED_LONG:
1316 case GCC_JIT_TYPE_LONG_LONG:
1317 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1318 return true;
1320 case GCC_JIT_TYPE_FLOAT:
1321 case GCC_JIT_TYPE_DOUBLE:
1322 case GCC_JIT_TYPE_LONG_DOUBLE:
1323 return false;
1325 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1326 return false;
1328 case GCC_JIT_TYPE_SIZE_T:
1329 return true;
1331 case GCC_JIT_TYPE_FILE_PTR:
1332 return false;
1334 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1335 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1336 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1337 return false;
1341 /* Implementation of pure virtual hook recording::type::is_float for
1342 recording::memento_of_get_type. */
1344 bool
1345 recording::memento_of_get_type::is_float () const
1347 switch (m_kind)
1349 default: gcc_unreachable ();
1351 case GCC_JIT_TYPE_VOID:
1352 return false;
1354 case GCC_JIT_TYPE_VOID_PTR:
1355 return false;
1357 case GCC_JIT_TYPE_BOOL:
1358 return false;
1360 case GCC_JIT_TYPE_CHAR:
1361 case GCC_JIT_TYPE_SIGNED_CHAR:
1362 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1363 case GCC_JIT_TYPE_SHORT:
1364 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1365 case GCC_JIT_TYPE_INT:
1366 case GCC_JIT_TYPE_UNSIGNED_INT:
1367 case GCC_JIT_TYPE_LONG:
1368 case GCC_JIT_TYPE_UNSIGNED_LONG:
1369 case GCC_JIT_TYPE_LONG_LONG:
1370 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1371 return false;
1373 case GCC_JIT_TYPE_FLOAT:
1374 case GCC_JIT_TYPE_DOUBLE:
1375 case GCC_JIT_TYPE_LONG_DOUBLE:
1376 return true;
1378 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1379 return false;
1381 case GCC_JIT_TYPE_SIZE_T:
1382 return false;
1384 case GCC_JIT_TYPE_FILE_PTR:
1385 return false;
1387 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1388 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1389 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1390 return true;
1394 /* Implementation of pure virtual hook recording::type::is_bool for
1395 recording::memento_of_get_type. */
1397 bool
1398 recording::memento_of_get_type::is_bool () const
1400 switch (m_kind)
1402 default: gcc_unreachable ();
1404 case GCC_JIT_TYPE_VOID:
1405 return false;
1407 case GCC_JIT_TYPE_VOID_PTR:
1408 return false;
1410 case GCC_JIT_TYPE_BOOL:
1411 return true;
1413 case GCC_JIT_TYPE_CHAR:
1414 case GCC_JIT_TYPE_SIGNED_CHAR:
1415 case GCC_JIT_TYPE_UNSIGNED_CHAR:
1416 case GCC_JIT_TYPE_SHORT:
1417 case GCC_JIT_TYPE_UNSIGNED_SHORT:
1418 case GCC_JIT_TYPE_INT:
1419 case GCC_JIT_TYPE_UNSIGNED_INT:
1420 case GCC_JIT_TYPE_LONG:
1421 case GCC_JIT_TYPE_UNSIGNED_LONG:
1422 case GCC_JIT_TYPE_LONG_LONG:
1423 case GCC_JIT_TYPE_UNSIGNED_LONG_LONG:
1424 return false;
1426 case GCC_JIT_TYPE_FLOAT:
1427 case GCC_JIT_TYPE_DOUBLE:
1428 case GCC_JIT_TYPE_LONG_DOUBLE:
1429 return false;
1431 case GCC_JIT_TYPE_CONST_CHAR_PTR:
1432 return false;
1434 case GCC_JIT_TYPE_SIZE_T:
1435 return false;
1437 case GCC_JIT_TYPE_FILE_PTR:
1438 return false;
1440 case GCC_JIT_TYPE_COMPLEX_FLOAT:
1441 case GCC_JIT_TYPE_COMPLEX_DOUBLE:
1442 case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
1443 return false;
1447 /* Implementation of pure virtual hook recording::memento::replay_into
1448 for recording::memento_of_get_type. */
1450 void
1451 recording::memento_of_get_type::replay_into (replayer *r)
1453 set_playback_obj (r->get_type (m_kind));
1456 /* The implementation of class gcc::jit::recording::memento_of_get_type. */
1458 /* Descriptive strings for each of enum gcc_jit_types. */
1460 static const char * const get_type_strings[] = {
1461 "void", /* GCC_JIT_TYPE_VOID */
1462 "void *", /* GCC_JIT_TYPE_VOID_PTR */
1464 "bool", /* GCC_JIT_TYPE_BOOL */
1466 "char", /* GCC_JIT_TYPE_CHAR */
1467 "signed char", /* GCC_JIT_TYPE_SIGNED_CHAR */
1468 "unsigned char", /* GCC_JIT_TYPE_UNSIGNED_CHAR */
1470 "short", /* GCC_JIT_TYPE_SHORT */
1471 "unsigned short", /* GCC_JIT_TYPE_UNSIGNED_SHORT */
1473 "int", /* GCC_JIT_TYPE_INT */
1474 "unsigned int", /* GCC_JIT_TYPE_UNSIGNED_INT */
1476 "long", /* GCC_JIT_TYPE_LONG */
1477 "unsigned long", /* GCC_JIT_TYPE_UNSIGNED_LONG, */
1479 "long long", /* GCC_JIT_TYPE_LONG_LONG */
1480 "unsigned long long", /* GCC_JIT_TYPE_UNSIGNED_LONG_LONG */
1482 "float", /* GCC_JIT_TYPE_FLOAT */
1483 "double", /* GCC_JIT_TYPE_DOUBLE */
1484 "long double", /* GCC_JIT_TYPE_LONG_DOUBLE */
1486 "const char *", /* GCC_JIT_TYPE_CONST_CHAR_PTR */
1488 "size_t", /* GCC_JIT_TYPE_SIZE_T */
1490 "FILE *", /* GCC_JIT_TYPE_FILE_PTR */
1492 "complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
1493 "complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
1494 "complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
1498 /* Implementation of recording::memento::make_debug_string for
1499 results of get_type, using a simple table of type names. */
1501 recording::string *
1502 recording::memento_of_get_type::make_debug_string ()
1504 return m_ctxt->new_string (get_type_strings[m_kind]);
1507 /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */
1509 /* Override of default implementation of
1510 recording::type::accepts_writes_from for get_pointer.
1512 Require a pointer type, and allowing writes to
1513 (const T *) from a (T*), but not the other way around. */
1515 bool
1516 recording::memento_of_get_pointer::accepts_writes_from (type *rtype)
1518 /* Must be a pointer type: */
1519 type *rtype_points_to = rtype->is_pointer ();
1520 if (!rtype_points_to)
1521 return false;
1523 /* It's OK to assign to a (const T *) from a (T *). */
1524 return m_other_type->unqualified ()
1525 ->accepts_writes_from (rtype_points_to);
1528 /* Implementation of pure virtual hook recording::memento::replay_into
1529 for recording::memento_of_get_pointer. */
1531 void
1532 recording::memento_of_get_pointer::replay_into (replayer *)
1534 set_playback_obj (m_other_type->playback_type ()->get_pointer ());
1537 /* Implementation of recording::memento::make_debug_string for
1538 results of get_pointer, adding " *" to the underlying type,
1539 with special-casing to handle function pointer types. */
1541 recording::string *
1542 recording::memento_of_get_pointer::make_debug_string ()
1544 /* Special-case function pointer types, to put the "*" in parens between
1545 the return type and the params (for one level of dereferencing, at
1546 least). */
1547 if (function_type *fn_type = m_other_type->dyn_cast_function_type ())
1548 return fn_type->make_debug_string_with_ptr ();
1550 return string::from_printf (m_ctxt,
1551 "%s *", m_other_type->get_debug_string ());
1554 /* The implementation of class gcc::jit::recording::memento_of_get_const. */
1556 /* Implementation of pure virtual hook recording::memento::replay_into
1557 for recording::memento_of_get_const. */
1559 void
1560 recording::memento_of_get_const::replay_into (replayer *)
1562 set_playback_obj (m_other_type->playback_type ()->get_const ());
1565 /* Implementation of recording::memento::make_debug_string for
1566 results of get_const, prepending "const ". */
1568 recording::string *
1569 recording::memento_of_get_const::make_debug_string ()
1571 return string::from_printf (m_ctxt,
1572 "const %s", m_other_type->get_debug_string ());
1575 /* The implementation of class gcc::jit::recording::memento_of_get_volatile. */
1577 /* Implementation of pure virtual hook recording::memento::replay_into
1578 for recording::memento_of_get_volatile. */
1580 void
1581 recording::memento_of_get_volatile::replay_into (replayer *)
1583 set_playback_obj (m_other_type->playback_type ()->get_volatile ());
1586 /* Implementation of recording::memento::make_debug_string for
1587 results of get_volatile, prepending "volatile ". */
1589 recording::string *
1590 recording::memento_of_get_volatile::make_debug_string ()
1592 return string::from_printf (m_ctxt,
1593 "volatile %s", m_other_type->get_debug_string ());
1596 /* The implementation of class gcc::jit::recording::array_type */
1598 /* Implementation of pure virtual hook recording::type::dereference for
1599 recording::array_type. */
1601 recording::type *
1602 recording::array_type::dereference ()
1604 return m_element_type;
1607 /* Implementation of pure virtual hook recording::memento::replay_into
1608 for recording::array_type. */
1610 void
1611 recording::array_type::replay_into (replayer *r)
1613 set_playback_obj (r->new_array_type (playback_location (r, m_loc),
1614 m_element_type->playback_type (),
1615 m_num_elements));
1618 /* Implementation of recording::memento::make_debug_string for
1619 results of new_array_type. */
1621 recording::string *
1622 recording::array_type::make_debug_string ()
1624 return string::from_printf (m_ctxt,
1625 "%s[%d]",
1626 m_element_type->get_debug_string (),
1627 m_num_elements);
1630 /* The implementation of class gcc::jit::recording::function_type */
1632 /* Constructor for gcc::jit::recording::function_type. */
1634 recording::function_type::function_type (context *ctxt,
1635 type *return_type,
1636 int num_params,
1637 type **param_types,
1638 int is_variadic)
1639 : type (ctxt),
1640 m_return_type (return_type),
1641 m_param_types (),
1642 m_is_variadic (is_variadic)
1644 for (int i = 0; i< num_params; i++)
1645 m_param_types.safe_push (param_types[i]);
1648 /* Implementation of pure virtual hook recording::type::dereference for
1649 recording::function_type. */
1651 recording::type *
1652 recording::function_type::dereference ()
1654 return NULL;
1657 /* Implementation of pure virtual hook recording::memento::replay_into
1658 for recording::function_type. */
1660 void
1661 recording::function_type::replay_into (replayer *r)
1663 /* Convert m_param_types to a vec of playback type. */
1664 auto_vec <playback::type *> param_types;
1665 int i;
1666 recording::type *type;
1667 param_types.create (m_param_types.length ());
1668 FOR_EACH_VEC_ELT (m_param_types, i, type)
1669 param_types.safe_push (type->playback_type ());
1671 set_playback_obj (r->new_function_type (m_return_type->playback_type (),
1672 &param_types,
1673 m_is_variadic));
1676 /* Special-casing for make_debug_string for get_pointer results for
1677 handling (one level) of pointers to functions. */
1679 recording::string *
1680 recording::function_type::make_debug_string_with_ptr ()
1682 return make_debug_string_with ("(*) ");
1685 /* Implementation of recording::memento::make_debug_string for
1686 results of new_function_type. */
1688 recording::string *
1689 recording::function_type::make_debug_string ()
1691 return make_debug_string_with ("");
1694 /* Build a debug string representation of the form:
1696 RESULT_TYPE INSERT (PARAM_TYPES)
1698 for use when handling 0 and 1 level of indirection to this
1699 function type. */
1701 recording::string *
1702 recording::function_type::make_debug_string_with (const char *insert)
1704 /* First, build a buffer for the arguments. */
1705 /* Calculate length of said buffer. */
1706 size_t sz = 1; /* nil terminator */
1707 for (unsigned i = 0; i< m_param_types.length (); i++)
1709 sz += strlen (m_param_types[i]->get_debug_string ());
1710 sz += 2; /* ", " separator */
1712 if (m_is_variadic)
1713 sz += 5; /* ", ..." separator and ellipsis */
1715 /* Now allocate and populate the buffer. */
1716 char *argbuf = new char[sz];
1717 size_t len = 0;
1719 for (unsigned i = 0; i< m_param_types.length (); i++)
1721 strcpy (argbuf + len, m_param_types[i]->get_debug_string ());
1722 len += strlen (m_param_types[i]->get_debug_string ());
1723 if (i + 1 < m_param_types.length ())
1725 strcpy (argbuf + len, ", ");
1726 len += 2;
1729 if (m_is_variadic)
1731 if (m_param_types.length ())
1733 strcpy (argbuf + len, ", ");
1734 len += 2;
1736 strcpy (argbuf + len, "...");
1737 len += 3;
1739 argbuf[len] = '\0';
1741 /* ...and use it to get the string for the call as a whole. */
1742 string *result = string::from_printf (m_ctxt,
1743 "%s %s(%s)",
1744 m_return_type->get_debug_string (),
1745 insert,
1746 argbuf);
1748 delete[] argbuf;
1750 return result;
1753 /* The implementation of class gcc::jit::recording::field. */
1755 /* Implementation of pure virtual hook recording::memento::replay_into
1756 for recording::field. */
1758 void
1759 recording::field::replay_into (replayer *r)
1761 set_playback_obj (r->new_field (playback_location (r, m_loc),
1762 m_type->playback_type (),
1763 playback_string (m_name)));
1766 /* Override the default implementation of
1767 recording::memento::write_to_dump. Dump each field
1768 by dumping a line of the form:
1769 TYPE NAME;
1770 so that we can build up a struct/union field-byfield. */
1772 void
1773 recording::field::write_to_dump (dump &d)
1775 d.write (" %s %s;\n",
1776 m_type->get_debug_string (),
1777 m_name->c_str ());
1780 /* Implementation of recording::memento::make_debug_string for
1781 results of new_field. */
1783 recording::string *
1784 recording::field::make_debug_string ()
1786 return m_name;
1789 /* The implementation of class gcc::jit::recording::compound_type */
1791 /* The constructor for gcc::jit::recording::compound_type. */
1793 recording::compound_type::compound_type (context *ctxt,
1794 location *loc,
1795 string *name)
1796 : type (ctxt),
1797 m_loc (loc),
1798 m_name (name),
1799 m_fields (NULL)
1803 /* Set the fields of a compound type.
1805 Implements the post-error-checking part of
1806 gcc_jit_struct_set_fields, and is also used by
1807 gcc_jit_context_new_union_type. */
1809 void
1810 recording::compound_type::set_fields (location *loc,
1811 int num_fields,
1812 field **field_array)
1814 m_loc = loc;
1815 gcc_assert (NULL == m_fields);
1817 m_fields = new fields (this, num_fields, field_array);
1818 m_ctxt->record (m_fields);
1821 /* Implementation of pure virtual hook recording::type::dereference for
1822 recording::compound_type. */
1824 recording::type *
1825 recording::compound_type::dereference ()
1827 return NULL; /* not a pointer */
1830 /* The implementation of class gcc::jit::recording::struct_. */
1832 /* The constructor for gcc::jit::recording::struct_. */
1834 recording::struct_::struct_ (context *ctxt,
1835 location *loc,
1836 string *name)
1837 : compound_type (ctxt, loc, name)
1841 /* Implementation of pure virtual hook recording::memento::replay_into
1842 for recording::struct_. */
1844 void
1845 recording::struct_::replay_into (replayer *r)
1847 set_playback_obj (
1848 r->new_compound_type (playback_location (r, get_loc ()),
1849 get_name ()->c_str (),
1850 true /* is_struct */));
1853 /* Implementation of recording::memento::make_debug_string for
1854 structs. */
1856 recording::string *
1857 recording::struct_::make_debug_string ()
1859 return string::from_printf (m_ctxt,
1860 "struct %s", get_name ()->c_str ());
1863 /* The implementation of class gcc::jit::recording::union_. */
1865 /* The constructor for gcc::jit::recording::union_. */
1867 recording::union_::union_ (context *ctxt,
1868 location *loc,
1869 string *name)
1870 : compound_type (ctxt, loc, name)
1874 /* Implementation of pure virtual hook recording::memento::replay_into
1875 for recording::union_. */
1877 void
1878 recording::union_::replay_into (replayer *r)
1880 set_playback_obj (
1881 r->new_compound_type (playback_location (r, get_loc ()),
1882 get_name ()->c_str (),
1883 false /* is_struct */));
1886 /* Implementation of recording::memento::make_debug_string for
1887 unions. */
1889 recording::string *
1890 recording::union_::make_debug_string ()
1892 return string::from_printf (m_ctxt,
1893 "union %s", get_name ()->c_str ());
1896 /* The implementation of class gcc::jit::recording::fields. */
1898 /* The constructor for gcc::jit::recording::fields. */
1900 recording::fields::fields (compound_type *struct_or_union,
1901 int num_fields,
1902 field **fields)
1903 : memento (struct_or_union->m_ctxt),
1904 m_struct_or_union (struct_or_union),
1905 m_fields ()
1907 for (int i = 0; i < num_fields; i++)
1909 gcc_assert (fields[i]->get_container () == NULL);
1910 fields[i]->set_container (m_struct_or_union);
1911 m_fields.safe_push (fields[i]);
1915 /* Implementation of pure virtual hook recording::memento::replay_into
1916 for recording::fields. */
1918 void
1919 recording::fields::replay_into (replayer *)
1921 auto_vec<playback::field *> playback_fields;
1922 playback_fields.create (m_fields.length ());
1923 for (unsigned i = 0; i < m_fields.length (); i++)
1924 playback_fields.safe_push (m_fields[i]->playback_field ());
1925 m_struct_or_union->playback_compound_type ()->set_fields (&playback_fields);
1928 /* Override the default implementation of
1929 recording::memento::write_to_dump by writing a union/struct
1930 declaration of this form:
1932 struct/union NAME {
1933 TYPE_1 NAME_1;
1934 TYPE_2 NAME_2;
1935 ....
1936 TYPE_N NAME_N;
1939 to the dump. */
1941 void
1942 recording::fields::write_to_dump (dump &d)
1944 int i;
1945 field *f;
1947 d.write ("%s\n{\n", m_struct_or_union->get_debug_string ());
1948 FOR_EACH_VEC_ELT (m_fields, i, f)
1949 f->write_to_dump (d);
1950 d.write ("};\n");
1953 /* Implementation of recording::memento::make_debug_string for
1954 field tables. */
1956 recording::string *
1957 recording::fields::make_debug_string ()
1959 return string::from_printf (m_ctxt,
1960 "fields");
1963 /* The implementation of class gcc::jit::recording::rvalue. */
1965 /* Create a recording::access_field_rvalue instance and add it to
1966 the rvalue's context's list of mementos.
1968 Implements the post-error-checking part of
1969 gcc_jit_rvalue_access_field. */
1971 recording::rvalue *
1972 recording::rvalue::access_field (recording::location *loc,
1973 field *field)
1975 recording::rvalue *result =
1976 new access_field_rvalue (m_ctxt, loc, this, field);
1977 m_ctxt->record (result);
1978 return result;
1981 /* Create a recording::dereference_field_rvalue instance and add it to
1982 the rvalue's context's list of mementos.
1984 Implements the post-error-checking part of
1985 gcc_jit_rvalue_dereference_field. */
1987 recording::lvalue *
1988 recording::rvalue::dereference_field (recording::location *loc,
1989 field *field)
1991 recording::lvalue *result =
1992 new dereference_field_rvalue (m_ctxt, loc, this, field);
1993 m_ctxt->record (result);
1994 return result;
1997 /* Create a recording::dereference_rvalue instance and add it to the
1998 rvalue's context's list of mementos.
2000 Implements the post-error-checking part of
2001 gcc_jit_rvalue_dereference. */
2003 recording::lvalue *
2004 recording::rvalue::dereference (recording::location *loc)
2006 recording::lvalue *result =
2007 new dereference_rvalue (m_ctxt, loc, this);
2008 m_ctxt->record (result);
2009 return result;
2012 /* The implementation of class gcc::jit::recording::lvalue. */
2014 /* Create a recording::new_access_field_of_lvalue instance and add it to
2015 the lvalue's context's list of mementos.
2017 Implements the post-error-checking part of
2018 gcc_jit_lvalue_access_field. */
2020 recording::lvalue *
2021 recording::lvalue::access_field (recording::location *loc,
2022 field *field)
2024 recording::lvalue *result =
2025 new access_field_of_lvalue (m_ctxt, loc, this, field);
2026 m_ctxt->record (result);
2027 return result;
2030 /* Create a recording::get_address_of_lvalue instance and add it to
2031 the lvalue's context's list of mementos.
2033 Implements the post-error-checking part of
2034 gcc_jit_lvalue_get_address. */
2036 recording::rvalue *
2037 recording::lvalue::get_address (recording::location *loc)
2039 recording::rvalue *result =
2040 new get_address_of_lvalue (m_ctxt, loc, this);
2041 m_ctxt->record (result);
2042 return result;
2045 /* The implementation of class gcc::jit::recording::param. */
2047 /* Implementation of pure virtual hook recording::memento::replay_into
2048 for recording::param. */
2050 void
2051 recording::param::replay_into (replayer *r)
2053 set_playback_obj (r->new_param (playback_location (r, m_loc),
2054 m_type->playback_type (),
2055 m_name->c_str ()));
2059 /* The implementation of class gcc::jit::recording::function. */
2061 /* gcc::jit::recording::function's constructor. */
2063 recording::function::function (context *ctxt,
2064 recording::location *loc,
2065 enum gcc_jit_function_kind kind,
2066 type *return_type,
2067 recording::string *name,
2068 int num_params,
2069 recording::param **params,
2070 int is_variadic,
2071 enum built_in_function builtin_id)
2072 : memento (ctxt),
2073 m_loc (loc),
2074 m_kind (kind),
2075 m_return_type (return_type),
2076 m_name (name),
2077 m_params (),
2078 m_is_variadic (is_variadic),
2079 m_builtin_id (builtin_id),
2080 m_locals (),
2081 m_blocks ()
2083 for (int i = 0; i< num_params; i++)
2084 m_params.safe_push (params[i]);
2087 /* Implementation of pure virtual hook recording::memento::replay_into
2088 for recording::function. */
2090 void
2091 recording::function::replay_into (replayer *r)
2093 /* Convert m_params to a vec of playback param. */
2094 auto_vec <playback::param *> params;
2095 int i;
2096 recording::param *param;
2097 params.create (m_params.length ());
2098 FOR_EACH_VEC_ELT (m_params, i, param)
2099 params.safe_push (param->playback_param ());
2101 set_playback_obj (r->new_function (playback_location (r, m_loc),
2102 m_kind,
2103 m_return_type->playback_type (),
2104 m_name->c_str (),
2105 &params,
2106 m_is_variadic,
2107 m_builtin_id));
2110 /* Create a recording::local instance and add it to
2111 the functions's context's list of mementos, and to the function's
2112 list of locals.
2114 Implements the post-error-checking part of
2115 gcc_jit_function_new_local. */
2117 recording::lvalue *
2118 recording::function::new_local (recording::location *loc,
2119 type *type,
2120 const char *name)
2122 local *result = new local (this, loc, type, new_string (name));
2123 m_ctxt->record (result);
2124 m_locals.safe_push (result);
2125 return result;
2128 /* Create a recording::block instance and add it to
2129 the functions's context's list of mementos, and to the function's
2130 list of blocks.
2132 Implements the post-error-checking part of
2133 gcc_jit_function_new_block. */
2135 recording::block*
2136 recording::function::new_block (const char *name)
2138 gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED);
2140 recording::block *result =
2141 new recording::block (this, m_blocks.length (), new_string (name));
2142 m_ctxt->record (result);
2143 m_blocks.safe_push (result);
2144 return result;
2147 /* Override the default implementation of
2148 recording::memento::write_to_dump by dumping a C-like
2149 representation of the function; either like a prototype
2150 for GCC_JIT_FUNCTION_IMPORTED, or like a full definition for
2151 all other kinds of function. */
2153 void
2154 recording::function::write_to_dump (dump &d)
2156 switch (m_kind)
2158 default: gcc_unreachable ();
2159 case GCC_JIT_FUNCTION_EXPORTED:
2160 case GCC_JIT_FUNCTION_IMPORTED:
2161 d.write ("extern ");
2162 break;
2163 case GCC_JIT_FUNCTION_INTERNAL:
2164 d.write ("static ");
2165 break;
2166 case GCC_JIT_FUNCTION_ALWAYS_INLINE:
2167 d.write ("static inline ");
2168 break;
2170 d.write ("%s\n", m_return_type->get_debug_string ());
2172 if (d.update_locations ())
2173 m_loc = d.make_location ();
2175 d.write ("%s (", get_debug_string ());
2177 int i;
2178 recording::param *param;
2179 FOR_EACH_VEC_ELT (m_params, i, param)
2181 if (i > 0)
2182 d.write (", ");
2183 d.write ("%s %s",
2184 param->get_type ()->get_debug_string (),
2185 param->get_debug_string ());
2187 d.write (")");
2188 if (m_kind == GCC_JIT_FUNCTION_IMPORTED)
2190 d.write ("; /* (imported) */\n\n");
2192 else
2194 int i;
2195 local *var = NULL;
2196 block *b;
2197 d.write ("\n{\n");
2199 /* Write locals: */
2200 FOR_EACH_VEC_ELT (m_locals, i, var)
2201 var->write_to_dump (d);
2202 if (m_locals.length ())
2203 d.write ("\n");
2205 /* Write each block: */
2206 FOR_EACH_VEC_ELT (m_blocks, i, b)
2208 if (i > 0)
2209 d.write ("\n");
2210 b->write_to_dump (d);
2213 d.write ("}\n\n");
2217 /* Pre-compilation validation of a function, for those things we can't
2218 check until the context is (supposedly) fully-populated. */
2220 void
2221 recording::function::validate ()
2223 /* Complain about empty functions with non-void return type. */
2224 if (m_kind != GCC_JIT_FUNCTION_IMPORTED
2225 && m_return_type != m_ctxt->get_type (GCC_JIT_TYPE_VOID))
2226 if (0 == m_blocks.length ())
2227 m_ctxt->add_error (m_loc,
2228 "function %s returns non-void (type: %s)"
2229 " but has no blocks",
2230 get_debug_string (),
2231 m_return_type->get_debug_string ());
2233 /* Check that all blocks are terminated. */
2234 int num_invalid_blocks = 0;
2236 int i;
2237 block *b;
2239 FOR_EACH_VEC_ELT (m_blocks, i, b)
2240 if (!b->validate ())
2241 num_invalid_blocks++;
2244 /* Check that all blocks are reachable. */
2245 if (m_blocks.length () > 0 && 0 == num_invalid_blocks)
2247 /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
2248 flag, starting at the initial block. */
2249 auto_vec<block *> worklist (m_blocks.length ());
2250 worklist.safe_push (m_blocks[0]);
2251 while (worklist.length () > 0)
2253 block *b = worklist.pop ();
2254 b->m_is_reachable = true;
2256 /* Add successor blocks that aren't yet marked to the worklist. */
2257 /* We checked that each block has a terminating statement above . */
2258 block *next1, *next2;
2259 int n = b->get_successor_blocks (&next1, &next2);
2260 switch (n)
2262 default:
2263 gcc_unreachable ();
2264 case 2:
2265 if (!next2->m_is_reachable)
2266 worklist.safe_push (next2);
2267 /* fallthrough */
2268 case 1:
2269 if (!next1->m_is_reachable)
2270 worklist.safe_push (next1);
2271 break;
2272 case 0:
2273 break;
2277 /* Now complain about any blocks that haven't been marked. */
2279 int i;
2280 block *b;
2281 FOR_EACH_VEC_ELT (m_blocks, i, b)
2282 if (!b->m_is_reachable)
2283 m_ctxt->add_error (b->get_loc (),
2284 "unreachable block: %s",
2285 b->get_debug_string ());
2290 /* Implements the post-error-checking part of
2291 gcc_jit_function_dump_to_dot. */
2293 void
2294 recording::function::dump_to_dot (const char *path)
2296 FILE *fp = fopen (path, "w");
2297 if (!fp)
2298 return;
2300 pretty_printer the_pp;
2301 the_pp.buffer->stream = fp;
2303 pretty_printer *pp = &the_pp;
2305 pp_printf (pp,
2306 "digraph %s {\n", get_debug_string ());
2308 /* Blocks: */
2310 int i;
2311 block *b;
2312 FOR_EACH_VEC_ELT (m_blocks, i, b)
2313 b->dump_to_dot (pp);
2316 /* Edges: */
2318 int i;
2319 block *b;
2320 FOR_EACH_VEC_ELT (m_blocks, i, b)
2321 b->dump_edges_to_dot (pp);
2324 pp_printf (pp, "}\n");
2325 pp_flush (pp);
2326 fclose (fp);
2329 /* Implementation of recording::memento::make_debug_string for
2330 functions. */
2332 recording::string *
2333 recording::function::make_debug_string ()
2335 return m_name;
2338 /* The implementation of class gcc::jit::recording::block. */
2340 /* Create a recording::eval instance and add it to
2341 the block's context's list of mementos, and to the block's
2342 list of statements.
2344 Implements the post-error-checking part of
2345 gcc_jit_block_add_eval. */
2347 void
2348 recording::block::add_eval (recording::location *loc,
2349 recording::rvalue *rvalue)
2351 statement *result = new eval (this, loc, rvalue);
2352 m_ctxt->record (result);
2353 m_statements.safe_push (result);
2356 /* Create a recording::assignment instance and add it to
2357 the block's context's list of mementos, and to the block's
2358 list of statements.
2360 Implements the post-error-checking part of
2361 gcc_jit_block_add_assignment. */
2363 void
2364 recording::block::add_assignment (recording::location *loc,
2365 recording::lvalue *lvalue,
2366 recording::rvalue *rvalue)
2368 statement *result = new assignment (this, loc, lvalue, rvalue);
2369 m_ctxt->record (result);
2370 m_statements.safe_push (result);
2373 /* Create a recording::assignment_op instance and add it to
2374 the block's context's list of mementos, and to the block's
2375 list of statements.
2377 Implements the post-error-checking part of
2378 gcc_jit_block_add_assignment_op. */
2380 void
2381 recording::block::add_assignment_op (recording::location *loc,
2382 recording::lvalue *lvalue,
2383 enum gcc_jit_binary_op op,
2384 recording::rvalue *rvalue)
2386 statement *result = new assignment_op (this, loc, lvalue, op, rvalue);
2387 m_ctxt->record (result);
2388 m_statements.safe_push (result);
2391 /* Create a recording::comment instance and add it to
2392 the block's context's list of mementos, and to the block's
2393 list of statements.
2395 Implements the post-error-checking part of
2396 gcc_jit_block_add_comment. */
2398 void
2399 recording::block::add_comment (recording::location *loc,
2400 const char *text)
2402 statement *result = new comment (this, loc, new_string (text));
2403 m_ctxt->record (result);
2404 m_statements.safe_push (result);
2407 /* Create a recording::end_with_conditional instance and add it to
2408 the block's context's list of mementos, and to the block's
2409 list of statements.
2411 Implements the post-error-checking part of
2412 gcc_jit_block_end_with_conditional. */
2414 void
2415 recording::block::end_with_conditional (recording::location *loc,
2416 recording::rvalue *boolval,
2417 recording::block *on_true,
2418 recording::block *on_false)
2420 statement *result = new conditional (this, loc, boolval, on_true, on_false);
2421 m_ctxt->record (result);
2422 m_statements.safe_push (result);
2423 m_has_been_terminated = true;
2426 /* Create a recording::end_with_jump instance and add it to
2427 the block's context's list of mementos, and to the block's
2428 list of statements.
2430 Implements the post-error-checking part of
2431 gcc_jit_block_end_with_jump. */
2433 void
2434 recording::block::end_with_jump (recording::location *loc,
2435 recording::block *target)
2437 statement *result = new jump (this, loc, target);
2438 m_ctxt->record (result);
2439 m_statements.safe_push (result);
2440 m_has_been_terminated = true;
2443 /* Create a recording::end_with_return instance and add it to
2444 the block's context's list of mementos, and to the block's
2445 list of statements.
2447 Implements the post-error-checking parts of
2448 gcc_jit_block_end_with_return and
2449 gcc_jit_block_end_with_void_return. */
2451 void
2452 recording::block::end_with_return (recording::location *loc,
2453 recording::rvalue *rvalue)
2455 /* This is used by both gcc_jit_function_add_return and
2456 gcc_jit_function_add_void_return; rvalue will be non-NULL for
2457 the former and NULL for the latter. */
2458 statement *result = new return_ (this, loc, rvalue);
2459 m_ctxt->record (result);
2460 m_statements.safe_push (result);
2461 m_has_been_terminated = true;
2464 /* Override the default implementation of
2465 recording::memento::write_to_dump for blocks by writing
2466 an unindented block name as a label, followed by the indented
2467 statements:
2469 BLOCK_NAME:
2470 STATEMENT_1;
2471 STATEMENT_2;
2473 STATEMENT_N; */
2475 void
2476 recording::block::write_to_dump (dump &d)
2478 d.write ("%s:\n", get_debug_string ());
2480 int i;
2481 statement *s;
2482 FOR_EACH_VEC_ELT (m_statements, i, s)
2483 s->write_to_dump (d);
2486 /* Validate a block by ensuring that it has been terminated. */
2488 bool
2489 recording::block::validate ()
2491 if (!has_been_terminated ())
2493 statement *stmt = get_last_statement ();
2494 location *loc = stmt ? stmt->get_loc () : NULL;
2495 m_func->get_context ()->add_error (loc,
2496 "unterminated block in %s: %s",
2497 m_func->get_debug_string (),
2498 get_debug_string ());
2499 return false;
2502 return true;
2505 /* Get the source-location of a block by using that of the first
2506 statement within it, if any. */
2508 recording::location *
2509 recording::block::get_loc () const
2511 recording::statement *stmt = get_first_statement ();
2512 if (stmt)
2513 return stmt->get_loc ();
2514 else
2515 return NULL;
2518 /* Get the first statement within a block, if any. */
2520 recording::statement *
2521 recording::block::get_first_statement () const
2523 if (m_statements.length ())
2524 return m_statements[0];
2525 else
2526 return NULL;
2529 /* Get the last statement within a block, if any. */
2531 recording::statement *
2532 recording::block::get_last_statement () const
2534 if (m_statements.length ())
2535 return m_statements[m_statements.length () - 1];
2536 else
2537 return NULL;
2540 /* Assuming that this block has been terminated, get the number of
2541 successor blocks, which will be 0, 1 or 2, for return, unconditional
2542 jump, and conditional jump respectively.
2543 NEXT1 and NEXT2 must be non-NULL. The first successor block (if any)
2544 is written to NEXT1, and the second (if any) to NEXT2.
2546 Used when validating functions, and when dumping dot representations
2547 of them. */
2550 recording::block::get_successor_blocks (block **next1, block **next2) const
2552 gcc_assert (m_has_been_terminated);
2553 gcc_assert (next1);
2554 gcc_assert (next2);
2555 statement *last_statement = get_last_statement ();
2556 gcc_assert (last_statement);
2557 return last_statement->get_successor_blocks (next1, next2);
2560 /* Implementation of pure virtual hook recording::memento::replay_into
2561 for recording::block. */
2563 void
2564 recording::block::replay_into (replayer *)
2566 set_playback_obj (m_func->playback_function ()
2567 ->new_block (playback_string (m_name)));
2570 /* Implementation of recording::memento::make_debug_string for
2571 blocks. */
2573 recording::string *
2574 recording::block::make_debug_string ()
2576 if (m_name)
2577 return m_name;
2578 else
2579 return string::from_printf (m_ctxt,
2580 "<UNNAMED BLOCK %p>",
2581 (void *)this);
2584 /* Dump a block in graphviz form into PP, capturing the block name (if
2585 any) and the statements. */
2587 void
2588 recording::block::dump_to_dot (pretty_printer *pp)
2590 pp_printf (pp,
2591 ("\tblock_%d "
2592 "[shape=record,style=filled,fillcolor=white,label=\"{"),
2593 m_index);
2594 pp_write_text_to_stream (pp);
2595 if (m_name)
2597 pp_string (pp, m_name->c_str ());
2598 pp_string (pp, ":");
2599 pp_newline (pp);
2600 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2603 int i;
2604 statement *s;
2605 FOR_EACH_VEC_ELT (m_statements, i, s)
2607 pp_string (pp, s->get_debug_string ());
2608 pp_newline (pp);
2609 pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/);
2612 pp_printf (pp,
2613 "}\"];\n\n");
2614 pp_flush (pp);
2617 /* Dump the out-edges of the block in graphviz form into PP. */
2619 void
2620 recording::block::dump_edges_to_dot (pretty_printer *pp)
2622 block *next[2];
2623 int num_succs = get_successor_blocks (&next[0], &next[1]);
2624 for (int i = 0; i < num_succs; i++)
2625 pp_printf (pp,
2626 "\tblock_%d:s -> block_%d:n;\n",
2627 m_index, next[i]->m_index);
2630 /* The implementation of class gcc::jit::recording::global. */
2632 /* Implementation of pure virtual hook recording::memento::replay_into
2633 for recording::global. */
2635 void
2636 recording::global::replay_into (replayer *r)
2638 set_playback_obj (r->new_global (playback_location (r, m_loc),
2639 m_type->playback_type (),
2640 playback_string (m_name)));
2643 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_int. */
2645 /* Implementation of pure virtual hook recording::memento::replay_into
2646 for recording::memento_of_new_rvalue_from_int. */
2648 void
2649 recording::memento_of_new_rvalue_from_int::replay_into (replayer *r)
2651 set_playback_obj (r->new_rvalue_from_int (m_type->playback_type (),
2652 m_value));
2655 /* Implementation of recording::memento::make_debug_string for
2656 rvalue_from_int, rendering it as
2657 (TYPE)LITERAL
2658 e.g.
2659 "(int)42". */
2661 recording::string *
2662 recording::memento_of_new_rvalue_from_int::make_debug_string ()
2664 return string::from_printf (m_ctxt,
2665 "(%s)%i",
2666 m_type->get_debug_string (),
2667 m_value);
2670 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_double. */
2672 /* Implementation of pure virtual hook recording::memento::replay_into
2673 for recording::memento_of_new_rvalue_from_double. */
2675 void
2676 recording::memento_of_new_rvalue_from_double::replay_into (replayer *r)
2678 set_playback_obj (r->new_rvalue_from_double (m_type->playback_type (),
2679 m_value));
2682 /* Implementation of recording::memento::make_debug_string for
2683 rvalue_from_double, rendering it as
2684 (TYPE)LITERAL
2685 e.g.
2686 "(float)42.0". */
2688 recording::string *
2689 recording::memento_of_new_rvalue_from_double::make_debug_string ()
2691 return string::from_printf (m_ctxt,
2692 "(%s)%f",
2693 m_type->get_debug_string (),
2694 m_value);
2697 /* The implementation of class gcc::jit::recording::memento_of_new_rvalue_from_ptr. */
2699 /* Implementation of pure virtual hook recording::memento::replay_into
2700 for recording::memento_of_new_rvalue_from_ptr. */
2702 void
2703 recording::memento_of_new_rvalue_from_ptr::replay_into (replayer *r)
2705 set_playback_obj (r->new_rvalue_from_ptr (m_type->playback_type (),
2706 m_value));
2709 /* Implementation of recording::memento::make_debug_string for
2710 rvalue_from_ptr, rendering it as
2711 (TYPE)HEX
2712 e.g.
2713 "(int *)0xdeadbeef"
2715 Zero is rendered as NULL e.g.
2716 "(int *)NULL". */
2718 recording::string *
2719 recording::memento_of_new_rvalue_from_ptr::make_debug_string ()
2721 if (m_value != NULL)
2722 return string::from_printf (m_ctxt,
2723 "(%s)%p",
2724 m_type->get_debug_string (), m_value);
2725 else
2726 return string::from_printf (m_ctxt,
2727 "(%s)NULL",
2728 m_type->get_debug_string ());
2731 /* The implementation of class gcc::jit::recording::memento_of_new_string_literal. */
2733 /* Implementation of pure virtual hook recording::memento::replay_into
2734 for recording::memento_of_new_string_literal. */
2736 void
2737 recording::memento_of_new_string_literal::replay_into (replayer *r)
2739 set_playback_obj (r->new_string_literal (m_value->c_str ()));
2742 /* Implementation of recording::memento::make_debug_string for
2743 string literals. */
2745 recording::string *
2746 recording::memento_of_new_string_literal::make_debug_string ()
2748 return string::from_printf (m_ctxt,
2749 m_value->get_debug_string ());
2752 /* The implementation of class gcc::jit::recording::unary_op. */
2754 /* Implementation of pure virtual hook recording::memento::replay_into
2755 for recording::unary_op. */
2757 void
2758 recording::unary_op::replay_into (replayer *r)
2760 set_playback_obj (r->new_unary_op (playback_location (r, m_loc),
2761 m_op,
2762 get_type ()->playback_type (),
2763 m_a->playback_rvalue ()));
2766 /* Implementation of recording::memento::make_debug_string for
2767 unary ops. */
2769 static const char * const unary_op_strings[] = {
2770 "-", /* GCC_JIT_UNARY_OP_MINUS */
2771 "~", /* GCC_JIT_UNARY_OP_BITWISE_NEGATE */
2772 "!", /* GCC_JIT_UNARY_OP_LOGICAL_NEGATE */
2775 recording::string *
2776 recording::unary_op::make_debug_string ()
2778 return string::from_printf (m_ctxt,
2779 "%s(%s)",
2780 unary_op_strings[m_op],
2781 m_a->get_debug_string ());
2784 /* The implementation of class gcc::jit::recording::binary_op. */
2786 /* Implementation of pure virtual hook recording::memento::replay_into
2787 for recording::binary_op. */
2789 void
2790 recording::binary_op::replay_into (replayer *r)
2792 set_playback_obj (r->new_binary_op (playback_location (r, m_loc),
2793 m_op,
2794 get_type ()->playback_type (),
2795 m_a->playback_rvalue (),
2796 m_b->playback_rvalue ()));
2799 /* Implementation of recording::memento::make_debug_string for
2800 binary ops. */
2802 static const char * const binary_op_strings[] = {
2803 "+", /* GCC_JIT_BINARY_OP_PLUS */
2804 "-", /* GCC_JIT_BINARY_OP_MINUS */
2805 "*", /* GCC_JIT_BINARY_OP_MULT */
2806 "/", /* GCC_JIT_BINARY_OP_DIVIDE */
2807 "%", /* GCC_JIT_BINARY_OP_MODULO */
2808 "&", /* GCC_JIT_BINARY_OP_BITWISE_AND */
2809 "^", /* GCC_JIT_BINARY_OP_BITWISE_XOR */
2810 "|", /* GCC_JIT_BINARY_OP_BITWISE_OR */
2811 "&&", /* GCC_JIT_BINARY_OP_LOGICAL_AND */
2812 "||", /* GCC_JIT_BINARY_OP_LOGICAL_OR */
2813 "<<", /* GCC_JIT_BINARY_OP_LSHIFT */
2814 ">>", /* GCC_JIT_BINARY_OP_RSHIFT */
2817 recording::string *
2818 recording::binary_op::make_debug_string ()
2820 return string::from_printf (m_ctxt,
2821 "%s %s %s",
2822 m_a->get_debug_string (),
2823 binary_op_strings[m_op],
2824 m_b->get_debug_string ());
2827 /* The implementation of class gcc::jit::recording::comparison. */
2829 /* Implementation of recording::memento::make_debug_string for
2830 comparisons. */
2832 static const char * const comparison_strings[] =
2834 "==", /* GCC_JIT_COMPARISON_EQ */
2835 "!=", /* GCC_JIT_COMPARISON_NE */
2836 "<", /* GCC_JIT_COMPARISON_LT */
2837 "<=", /* GCC_JIT_COMPARISON_LE */
2838 ">", /* GCC_JIT_COMPARISON_GT */
2839 ">=", /* GCC_JIT_COMPARISON_GE */
2842 recording::string *
2843 recording::comparison::make_debug_string ()
2845 return string::from_printf (m_ctxt,
2846 "%s %s %s",
2847 m_a->get_debug_string (),
2848 comparison_strings[m_op],
2849 m_b->get_debug_string ());
2852 /* Implementation of pure virtual hook recording::memento::replay_into
2853 for recording::comparison. */
2855 void
2856 recording::comparison::replay_into (replayer *r)
2858 set_playback_obj (r->new_comparison (playback_location (r, m_loc),
2859 m_op,
2860 m_a->playback_rvalue (),
2861 m_b->playback_rvalue ()));
2864 /* Implementation of pure virtual hook recording::memento::replay_into
2865 for recording::cast. */
2867 void
2868 recording::cast::replay_into (replayer *r)
2870 set_playback_obj (r->new_cast (playback_location (r, m_loc),
2871 m_rvalue->playback_rvalue (),
2872 get_type ()->playback_type ()));
2875 /* Implementation of recording::memento::make_debug_string for
2876 casts. */
2878 recording::string *
2879 recording::cast::make_debug_string ()
2881 return string::from_printf (m_ctxt,
2882 "(%s)%s",
2883 get_type ()->get_debug_string (),
2884 m_rvalue->get_debug_string ());
2887 /* The implementation of class gcc::jit::recording::call. */
2889 /* The constructor for gcc::jit::recording::call. */
2891 recording::call::call (recording::context *ctxt,
2892 recording::location *loc,
2893 recording::function *func,
2894 int numargs,
2895 rvalue **args)
2896 : rvalue (ctxt, loc, func->get_return_type ()),
2897 m_func (func),
2898 m_args ()
2900 for (int i = 0; i< numargs; i++)
2901 m_args.safe_push (args[i]);
2904 /* Implementation of pure virtual hook recording::memento::replay_into
2905 for recording::call. */
2907 void
2908 recording::call::replay_into (replayer *r)
2910 auto_vec<playback::rvalue *> playback_args;
2911 playback_args.create (m_args.length ());
2912 for (unsigned i = 0; i< m_args.length (); i++)
2913 playback_args.safe_push (m_args[i]->playback_rvalue ());
2915 set_playback_obj (r->new_call (playback_location (r, m_loc),
2916 m_func->playback_function (),
2917 &playback_args));
2920 /* Implementation of recording::memento::make_debug_string for
2921 function calls. */
2923 recording::string *
2924 recording::call::make_debug_string ()
2926 /* First, build a buffer for the arguments. */
2927 /* Calculate length of said buffer. */
2928 size_t sz = 1; /* nil terminator */
2929 for (unsigned i = 0; i< m_args.length (); i++)
2931 sz += strlen (m_args[i]->get_debug_string ());
2932 sz += 2; /* ", " separator */
2935 /* Now allocate and populate the buffer. */
2936 char *argbuf = new char[sz];
2937 size_t len = 0;
2939 for (unsigned i = 0; i< m_args.length (); i++)
2941 strcpy (argbuf + len, m_args[i]->get_debug_string ());
2942 len += strlen (m_args[i]->get_debug_string ());
2943 if (i + 1 < m_args.length ())
2945 strcpy (argbuf + len, ", ");
2946 len += 2;
2949 argbuf[len] = '\0';
2951 /* ...and use it to get the string for the call as a whole. */
2952 string *result = string::from_printf (m_ctxt,
2953 "%s (%s)",
2954 m_func->get_debug_string (),
2955 argbuf);
2957 delete[] argbuf;
2959 return result;
2962 /* The implementation of class gcc::jit::recording::call_through_ptr. */
2964 /* The constructor for recording::call_through_ptr. */
2966 recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
2967 recording::location *loc,
2968 recording::rvalue *fn_ptr,
2969 int numargs,
2970 rvalue **args)
2971 : rvalue (ctxt, loc,
2972 fn_ptr->get_type ()->dereference ()
2973 ->as_a_function_type ()->get_return_type ()),
2974 m_fn_ptr (fn_ptr),
2975 m_args ()
2977 for (int i = 0; i< numargs; i++)
2978 m_args.safe_push (args[i]);
2981 /* Implementation of pure virtual hook recording::memento::replay_into
2982 for recording::call_through_ptr. */
2984 void
2985 recording::call_through_ptr::replay_into (replayer *r)
2987 auto_vec<playback::rvalue *> playback_args;
2988 playback_args.create (m_args.length ());
2989 for (unsigned i = 0; i< m_args.length (); i++)
2990 playback_args.safe_push (m_args[i]->playback_rvalue ());
2992 set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
2993 m_fn_ptr->playback_rvalue (),
2994 &playback_args));
2997 /* Implementation of recording::memento::make_debug_string for
2998 calls through function ptrs. */
3000 recording::string *
3001 recording::call_through_ptr::make_debug_string ()
3003 /* First, build a buffer for the arguments. */
3004 /* Calculate length of said buffer. */
3005 size_t sz = 1; /* nil terminator */
3006 for (unsigned i = 0; i< m_args.length (); i++)
3008 sz += strlen (m_args[i]->get_debug_string ());
3009 sz += 2; /* ", " separator */
3012 /* Now allocate and populate the buffer. */
3013 char *argbuf = new char[sz];
3014 size_t len = 0;
3016 for (unsigned i = 0; i< m_args.length (); i++)
3018 strcpy (argbuf + len, m_args[i]->get_debug_string ());
3019 len += strlen (m_args[i]->get_debug_string ());
3020 if (i + 1 < m_args.length ())
3022 strcpy (argbuf + len, ", ");
3023 len += 2;
3026 argbuf[len] = '\0';
3028 /* ...and use it to get the string for the call as a whole. */
3029 string *result = string::from_printf (m_ctxt,
3030 "%s (%s)",
3031 m_fn_ptr->get_debug_string (),
3032 argbuf);
3034 delete[] argbuf;
3036 return result;
3039 /* The implementation of class gcc::jit::recording::array_access. */
3041 /* Implementation of pure virtual hook recording::memento::replay_into
3042 for recording::array_access. */
3044 void
3045 recording::array_access::replay_into (replayer *r)
3047 set_playback_obj (
3048 r->new_array_access (playback_location (r, m_loc),
3049 m_ptr->playback_rvalue (),
3050 m_index->playback_rvalue ()));
3053 /* Implementation of recording::memento::make_debug_string for
3054 array accesses. */
3056 recording::string *
3057 recording::array_access::make_debug_string ()
3059 return string::from_printf (m_ctxt,
3060 "%s[%s]",
3061 m_ptr->get_debug_string (),
3062 m_index->get_debug_string ());
3065 /* The implementation of class gcc::jit::recording::access_field_of_lvalue. */
3067 /* Implementation of pure virtual hook recording::memento::replay_into
3068 for recording::access_field_of_lvalue. */
3070 void
3071 recording::access_field_of_lvalue::replay_into (replayer *r)
3073 set_playback_obj (
3074 m_lvalue->playback_lvalue ()
3075 ->access_field (playback_location (r, m_loc),
3076 m_field->playback_field ()));
3080 /* Implementation of recording::memento::make_debug_string for
3081 accessing a field of an lvalue. */
3083 recording::string *
3084 recording::access_field_of_lvalue::make_debug_string ()
3086 return string::from_printf (m_ctxt,
3087 "%s.%s",
3088 m_lvalue->get_debug_string (),
3089 m_field->get_debug_string ());
3092 /* The implementation of class gcc::jit::recording::access_field_rvalue. */
3094 /* Implementation of pure virtual hook recording::memento::replay_into
3095 for recording::access_field_rvalue. */
3097 void
3098 recording::access_field_rvalue::replay_into (replayer *r)
3100 set_playback_obj (
3101 m_rvalue->playback_rvalue ()
3102 ->access_field (playback_location (r, m_loc),
3103 m_field->playback_field ()));
3106 /* Implementation of recording::memento::make_debug_string for
3107 accessing a field of an rvalue. */
3109 recording::string *
3110 recording::access_field_rvalue::make_debug_string ()
3112 return string::from_printf (m_ctxt,
3113 "%s.%s",
3114 m_rvalue->get_debug_string (),
3115 m_field->get_debug_string ());
3118 /* The implementation of class
3119 gcc::jit::recording::dereference_field_rvalue. */
3121 /* Implementation of pure virtual hook recording::memento::replay_into
3122 for recording::dereference_field_rvalue. */
3124 void
3125 recording::dereference_field_rvalue::replay_into (replayer *r)
3127 set_playback_obj (
3128 m_rvalue->playback_rvalue ()->
3129 dereference_field (playback_location (r, m_loc),
3130 m_field->playback_field ()));
3133 /* Implementation of recording::memento::make_debug_string for
3134 dereferencing a field of an rvalue. */
3136 recording::string *
3137 recording::dereference_field_rvalue::make_debug_string ()
3139 return string::from_printf (m_ctxt,
3140 "%s->%s",
3141 m_rvalue->get_debug_string (),
3142 m_field->get_debug_string ());
3145 /* The implementation of class gcc::jit::recording::dereference_rvalue. */
3147 /* Implementation of pure virtual hook recording::memento::replay_into
3148 for recording::dereference_rvalue. */
3150 void
3151 recording::dereference_rvalue::replay_into (replayer *r)
3153 set_playback_obj (
3154 m_rvalue->playback_rvalue ()->
3155 dereference (playback_location (r, m_loc)));
3158 /* Implementation of recording::memento::make_debug_string for
3159 dereferencing an rvalue. */
3161 recording::string *
3162 recording::dereference_rvalue::make_debug_string ()
3164 return string::from_printf (m_ctxt,
3165 "*%s",
3166 m_rvalue->get_debug_string ());
3169 /* The implementation of class gcc::jit::recording::get_address_of_lvalue. */
3171 /* Implementation of pure virtual hook recording::memento::replay_into
3172 for recording::get_address_of_lvalue. */
3174 void
3175 recording::get_address_of_lvalue::replay_into (replayer *r)
3177 set_playback_obj (
3178 m_lvalue->playback_lvalue ()->
3179 get_address (playback_location (r, m_loc)));
3182 /* Implementation of recording::memento::make_debug_string for
3183 getting the address of an lvalue. */
3185 recording::string *
3186 recording::get_address_of_lvalue::make_debug_string ()
3188 return string::from_printf (m_ctxt,
3189 "&%s",
3190 m_lvalue->get_debug_string ());
3193 /* The implementation of class gcc::jit::recording::local. */
3195 /* Implementation of pure virtual hook recording::memento::replay_into
3196 for recording::local. */
3198 void
3199 recording::local::replay_into (replayer *r)
3201 set_playback_obj (
3202 m_func->playback_function ()
3203 ->new_local (playback_location (r, m_loc),
3204 m_type->playback_type (),
3205 playback_string (m_name)));
3208 /* Override the default implementation of
3209 recording::memento::write_to_dump for locals by writing
3210 TYPE NAME;
3211 for use at the top of the function body as if it were a
3212 declaration. */
3214 void
3215 recording::local::write_to_dump (dump &d)
3217 if (d.update_locations ())
3218 m_loc = d.make_location ();
3219 d.write(" %s %s;\n",
3220 m_type->get_debug_string (),
3221 get_debug_string ());
3224 /* The implementation of class gcc::jit::recording::statement. */
3226 /* We poison the default implementation of
3227 gcc::jit::recording::statement::get_successor_blocks
3228 since this vfunc must only ever be called on terminator
3229 statements. */
3232 recording::statement::get_successor_blocks (block **/*out_next1*/,
3233 block **/*out_next2*/) const
3235 /* The base class implementation is for non-terminating statements,
3236 and thus should never be called. */
3237 gcc_unreachable ();
3238 return 0;
3241 /* Extend the default implementation of
3242 recording::memento::write_to_dump for statements by (if requested)
3243 updating the location of the statement to the current location in
3244 the dumpfile. */
3246 void
3247 recording::statement::write_to_dump (dump &d)
3249 memento::write_to_dump (d);
3250 if (d.update_locations ())
3251 m_loc = d.make_location ();
3254 /* The implementation of class gcc::jit::recording::eval. */
3256 /* Implementation of pure virtual hook recording::memento::replay_into
3257 for recording::eval. */
3259 void
3260 recording::eval::replay_into (replayer *r)
3262 playback_block (get_block ())
3263 ->add_eval (playback_location (r),
3264 m_rvalue->playback_rvalue ());
3267 /* Implementation of recording::memento::make_debug_string for
3268 an eval statement. */
3270 recording::string *
3271 recording::eval::make_debug_string ()
3273 return string::from_printf (m_ctxt,
3274 "(void)%s;",
3275 m_rvalue->get_debug_string ());
3278 /* The implementation of class gcc::jit::recording::assignment. */
3280 /* Implementation of pure virtual hook recording::memento::replay_into
3281 for recording::assignment. */
3283 void
3284 recording::assignment::replay_into (replayer *r)
3286 playback_block (get_block ())
3287 ->add_assignment (playback_location (r),
3288 m_lvalue->playback_lvalue (),
3289 m_rvalue->playback_rvalue ());
3292 /* Implementation of recording::memento::make_debug_string for
3293 an assignment statement. */
3295 recording::string *
3296 recording::assignment::make_debug_string ()
3298 return string::from_printf (m_ctxt,
3299 "%s = %s;",
3300 m_lvalue->get_debug_string (),
3301 m_rvalue->get_debug_string ());
3304 /* The implementation of class gcc::jit::recording::assignment_op. */
3306 /* Implementation of pure virtual hook recording::memento::replay_into
3307 for recording::assignment_op. */
3309 void
3310 recording::assignment_op::replay_into (replayer *r)
3312 playback::type *result_type =
3313 m_lvalue->playback_lvalue ()->get_type ();
3315 playback::rvalue *binary_op =
3316 r->new_binary_op (playback_location (r),
3317 m_op,
3318 result_type,
3319 m_lvalue->playback_rvalue (),
3320 m_rvalue->playback_rvalue ());
3322 playback_block (get_block ())
3323 ->add_assignment (playback_location (r),
3324 m_lvalue->playback_lvalue (),
3325 binary_op);
3328 /* Implementation of recording::memento::make_debug_string for
3329 an assignment_op statement. */
3331 recording::string *
3332 recording::assignment_op::make_debug_string ()
3334 return string::from_printf (m_ctxt,
3335 "%s %s= %s;",
3336 m_lvalue->get_debug_string (),
3337 binary_op_strings[m_op],
3338 m_rvalue->get_debug_string ());
3341 /* The implementation of class gcc::jit::recording::comment. */
3343 /* Implementation of pure virtual hook recording::memento::replay_into
3344 for recording::comment. */
3346 void
3347 recording::comment::replay_into (replayer *r)
3349 playback_block (get_block ())
3350 ->add_comment (playback_location (r),
3351 m_text->c_str ());
3354 /* Implementation of recording::memento::make_debug_string for
3355 a comment "statement". */
3357 recording::string *
3358 recording::comment::make_debug_string ()
3360 return string::from_printf (m_ctxt,
3361 "/* %s */",
3362 m_text->c_str ());
3365 /* The implementation of class gcc::jit::recording::conditional. */
3367 /* Implementation of pure virtual hook recording::memento::replay_into
3368 for recording::conditional. */
3370 void
3371 recording::conditional::replay_into (replayer *r)
3373 playback_block (get_block ())
3374 ->add_conditional (playback_location (r),
3375 m_boolval->playback_rvalue (),
3376 playback_block (m_on_true),
3377 playback_block (m_on_false));
3380 /* Override the poisoned default implementation of
3381 gcc::jit::recording::statement::get_successor_blocks
3383 A conditional jump has 2 successor blocks. */
3386 recording::conditional::get_successor_blocks (block **out_next1,
3387 block **out_next2) const
3389 *out_next1 = m_on_true;
3390 *out_next2 = m_on_false;
3391 return 2;
3394 /* Implementation of recording::memento::make_debug_string for
3395 a conditional jump statement. */
3397 recording::string *
3398 recording::conditional::make_debug_string ()
3400 if (m_on_false)
3401 return string::from_printf (m_ctxt,
3402 "if (%s) goto %s; else goto %s;",
3403 m_boolval->get_debug_string (),
3404 m_on_true->get_debug_string (),
3405 m_on_false->get_debug_string ());
3406 else
3407 return string::from_printf (m_ctxt,
3408 "if (%s) goto %s;",
3409 m_boolval->get_debug_string (),
3410 m_on_true->get_debug_string ());
3413 /* The implementation of class gcc::jit::recording::jump. */
3415 /* Implementation of pure virtual hook recording::memento::replay_into
3416 for recording::jump. */
3418 void
3419 recording::jump::replay_into (replayer *r)
3421 playback_block (get_block ())
3422 ->add_jump (playback_location (r),
3423 m_target->playback_block ());
3426 /* Override the poisoned default implementation of
3427 gcc::jit::recording::statement::get_successor_blocks
3429 An unconditional jump has 1 successor block. */
3432 recording::jump::get_successor_blocks (block **out_next1,
3433 block **/*out_next2*/) const
3435 *out_next1 = m_target;
3436 return 1;
3439 /* Implementation of recording::memento::make_debug_string for
3440 a unconditional jump statement. */
3442 recording::string *
3443 recording::jump::make_debug_string ()
3445 return string::from_printf (m_ctxt,
3446 "goto %s;",
3447 m_target->get_debug_string ());
3450 /* The implementation of class gcc::jit::recording::return_. */
3452 /* Implementation of pure virtual hook recording::memento::replay_into
3453 for recording::return_. */
3455 void
3456 recording::return_::replay_into (replayer *r)
3458 playback_block (get_block ())
3459 ->add_return (playback_location (r),
3460 m_rvalue ? m_rvalue->playback_rvalue () : NULL);
3463 /* Override the poisoned default implementation of
3464 gcc::jit::recording::statement::get_successor_blocks
3466 A return statement has no successor block. */
3469 recording::return_::get_successor_blocks (block **/*out_next1*/,
3470 block **/*out_next2*/) const
3472 return 0;
3475 /* Implementation of recording::memento::make_debug_string for
3476 a return statement (covers both those with and without rvalues). */
3478 recording::string *
3479 recording::return_::make_debug_string ()
3481 if (m_rvalue)
3482 return string::from_printf (m_ctxt,
3483 "return %s;",
3484 m_rvalue->get_debug_string ());
3485 else
3486 return string::from_printf (m_ctxt,
3487 "return;");
3490 } // namespace gcc::jit
3492 } // namespace gcc